Beispiel #1
0
    def equip(self, itemType):
        '''
        Equip an item of the given enumerated type from this agent's inventory. Returns true if the agent successfully equips the item,
        false otherwise.

            Preconditions:
                - The agent has an item of the given type
        '''
        # Check action override
        if self.__shouldPerformActionOverride(self.equip):
            return self.__actionOverride.function(*self.__actionOverride.args)

        # Preconditions
        if not self.__checkPreconditions(
            self.inventory.amountOfItem(itemType) >= 1):
            return False

        # Obtain a reference to the item we will equip
        inventoryItem = self.inventory.getItem(itemType)
        oldIndex = self.inventory.getItemIndex(itemType)
        if inventoryItem == None or oldIndex == None:
            return False

        # If item is already in the hotbar...
        if oldIndex < 9:
            self.__host.sendCommand("hotbar.{} 1".format(oldIndex + 1))
            self.__host.sendCommand("hotbar.{} 0".format(oldIndex + 1))
            self.__logReports.append(LogUtils.EquipReport(inventoryItem))
            return True

        # If there is an available hotbar slot...
        newIndex = self.inventory.nextUnusedHotbarIndex()
        if newIndex != None:
            self.__host.sendCommand("swapInventoryItems {} {}".format(newIndex, oldIndex))
            self.__host.sendCommand("hotbar.{} 1".format(newIndex + 1))
            self.__host.sendCommand("hotbar.{} 0".format(newIndex + 1))
            self.__logReports.append(LogUtils.EquipReport(inventoryItem))
            return True

        # Swap item in overflow w/ item in hotbar
        newIndex = self.inventory.equippedIndex()
        if newIndex != -1:
            self.__host.sendCommand("swapInventoryItems {} {}".format(newIndex, oldIndex))
            self.__host.sendCommand("hotbar.{} 1".format(newIndex + 1))
            self.__host.sendCommand("hotbar.{} 0".format(newIndex + 1))
            self.__logReports.append(LogUtils.EquipReport(inventoryItem))
            return True
        
        return False
Beispiel #2
0
    def __attackCleanup(self, mob):
        '''
        Perform additional cleanup work and logging as a result of an agent having killed the given mob.
        '''
        # Get any items that were immediately picked up
        itemsPickedUp, _ = self.inventory.sync()
        
        # Get any items that were dropped to the ground (register their IDs w/ Inventory class to preserve them)
        nearbyEntities = self.nearbyEntities()
        itemsDropped = [x for x in nearbyEntities if Items.All.isMember(x.type)]
        for item in itemsDropped:
            for i in range(0, item.quantity):
                Inventory.registerDropItem(item)
        
        # Create the log report for the attack
        self.__logReports.append(LogUtils.AttackReport(mob, True, itemsDropped, itemsPickedUp))

        # Trigger a log report for new closest mobs of this mob's type for all agents
        allAgents = list(Agent.allAgents.values())
        for agent in allAgents:
            if Mobs.All.isMember(mob.type):
                agent.closestMob()
            if Mobs.Peaceful.isMember(mob.type):
                agent.closestMob(Mobs.Peaceful)
            if Mobs.Hostile.isMember(mob.type):
                agent.closestMob(Mobs.Hostile)
            if Mobs.Food.isMember(mob.type):
                agent.closestMob(Mobs.Food)
Beispiel #3
0
    def craft(self, itemType, recipe):
        '''
        Craft an item of the given enumerated type using a list of RecipeItems. Returns true if successful, and
        false otherwise.

            Preconditions:
                - The agent has enough of each recipe item
        '''
        # Check for override
        if self.__shouldPerformActionOverride(self.craft):
            return self.__actionOverride.function(*self.__actionOverride.args)

        # Preconditions
        hasAllItems = True
        for recipeItem in recipe:
            if self.inventory.amountOfItem(recipeItem) < recipeItem.quantity:
                hasAllItems = False
                break
        if not self.__checkPreconditions(hasAllItems):
            return False

        # Remove each recipe item from the inventory
        consumedItems = []
        for recipeItem in recipe:
            for i in range(0, recipeItem.quantity):
                consumedItems.append(self.inventory.removeItem(recipeItem.type))
        
        # Add the crafted item to the inventory
        craftedItem = self.inventory.addItem(itemType)

        # Action
        self.__host.sendCommand("craft {}".format(itemType.value))
        time.sleep(0.5)
        self.__logReports.append(LogUtils.CraftReport(craftedItem, recipeItem))
        return True
Beispiel #4
0
    def attackMob(self, mob):
        '''
        Direct this agent to attack a mob using the currently equipped item. Returns true if the agent successfully
        swung, false otherwise.

            Preconditions:
                - The given entity is a mob
                - The agent is looking at the mob
                - The agent is at the mob
        '''
        # Check action override
        if self.__shouldPerformActionOverride(self.attackMob):
            return self.__actionOverride.function(*self.__actionOverride.args)

        # Preconditions
        if not self.__checkPreconditions(
            Mobs.All.isMember(mob.type),
            self.__isLookingAt(mob.position),
            self.__isAt(mob.position)):
            self.stopMoving()
            return False

        # Action
        oldMobsKilled = self.__mobsKilled()
        self.__startAttacking()
        self.stopMoving()
        time.sleep(0.7)
        newMobsKilled = self.__mobsKilled()

        if newMobsKilled > oldMobsKilled:
            self.__attackCleanup(mob)
        else:
            self.__logReports.append(LogUtils.AttackReport(mob, False, [], []))

        return True
Beispiel #5
0
    def __pickUpItem(self, item, previousInventoryAmt):
        '''
        Internal lockdown action for continuously moving an agent towards an item until it has been picked up and
        shows up in the agent's inventory. Requires the previous amount of that item in the agent's inventory to be
        passed in as a parameter.
        '''
        # Do not check for action override. Otherwise, we'd get stuck in an infinite loop!
        # Do not check any preconditions - we assume that if we locked down on this override that preconditions remain satisfied

        # Move to the position, slowing down as we approach
        self.__moveToPosition(item.position, 0, PICK_UP_ITEM_LOCKDOWN_DISTANCE, False)

        # Make sure we log that we picked up all kinds of items, regardless of what they are
        newInventoryItems, _ = self.inventory.sync()
        for item in newInventoryItems:
            self.__logReports.append(LogUtils.PickUpItemReport(item))

        # Only report true when we picked up the target item
        newInventoryAmt = self.inventory.amountOfItem(item.type)
        if newInventoryAmt > previousInventoryAmt:
            # Avoid stopMoving() function since it checks for action override
            self.__stopTurning()
            self.__stopWalking()
            self.__stopAttacking()
            self.__actionOverride = None
            return True
        return False
Beispiel #6
0
    def lookAt(self, entity):
        '''
        Begin moving the agent's POV up/down and left/right to face the given entity.
        Returns true if the agent is facing the entity, false otherwise.

            Preconditions:
                None
        '''
        # Check for override
        if self.__shouldPerformActionOverride(self.lookAt):
            return self.__actionOverride.function(*self.__actionOverride.args)

        # If entity is an agent, represent it as an entity
        if isinstance(entity, Agent):
            entity = Entity(entity.id, "agent", entity.__position(), 1)

        # Preconditions - None

        # Action
        pitchRate = self.__calculateTargetPitchRate(entity.position)
        yawRate = self.__calculateTargetYawRate(entity.position)
        if self.__isLookingAt(entity.position, pitchRate, yawRate):
            self.__stopTurning()
            if not Items.All.isMember(entity.type):  # Items are a special case for which we do not log
                self.__logReports.append(LogUtils.LookAtReport(entity))
            return True
        else:
            self.__startChangingPitch(pitchRate)
            self.__startChangingYaw(yawRate)
            return False
Beispiel #7
0
    def closestItem(self, variant=Items.All):
        '''
        Get the closest item on the ground to this agent. Optionally specify additional modifiers for filtering
        items by an enumerated type. Returns None if no item was found nearby to this agent.
        '''
        # Check for override
        if self.__shouldPerformActionOverride(self.closestItem):
            self.__actionOverride.function(*self.__actionOverride.args)
            return None

        aPos = self.__position()
        nearbyEntities = self.nearbyEntities()
        if variant == Items.All:
            comparator = Items.All.isMember
        elif variant == Items.Food:
            comparator = Items.Food.isMember
        else:
            raise Exception("Closest item variant must be an enumerated type")

        closestDistance = 1000000.0
        closestItem = None
        for entity in nearbyEntities:
            if comparator(entity.type):
                ePos = entity.position
                distance = MathUtils.distanceBetweenPoints(aPos, ePos)
                if distance < closestDistance:
                    closestDistance = distance
                    closestItem = entity
        self.__logReports.append(LogUtils.ClosestItemReport(variant, closestItem))
        return closestItem
Beispiel #8
0
    def moveTo(self, entity):
        '''
        Begin moving the agent to the given entity. Returns true if the agent is at the entity,
        false otherwise.

            Preconditions:
                - The agent is looking at the entity
        '''
        # Check for override
        if self.__shouldPerformActionOverride(self.moveTo):
            return self.__actionOverride.function(*self.__actionOverride.args)

        minTol = 0.0
        maxTol = STRIKING_DISTANCE

        # If entity is an agent, represent it as an entity
        if isinstance(entity, Agent):
            entity = Entity(entity.id, "agent", entity.__position(), 1)
            minTol = 2.0
            maxTol = GIVING_DISTANCE

        # Preconditions
        if not self.__checkPreconditions(self.__isLookingAt(entity.position)):
            self.stopMoving()
            return False

        # Items are a special case since they can be picked up. Once close, lock down on the pickUpItem action.
        if Items.All.isMember(entity.type):
            distanceToItem = MathUtils.distanceBetweenPointsXZ(self.__position(), entity.position)
            if distanceToItem <= PICK_UP_ITEM_LOCKDOWN_DISTANCE:
                currentInventoryAmt = self.inventory.amountOfItem(entity.type)
                self.__actionOverride = Agent.ActionOverride(self.__pickUpItem, [entity, currentInventoryAmt])
                return self.__pickUpItem(entity, currentInventoryAmt)

        # Action
        if self.__moveToPosition(entity.position, minTol, maxTol):
            self.__stopWalking()
            self.__logReports.append(LogUtils.MoveToReport(entity))
            return True
        else:
            return False
Beispiel #9
0
    def giveItem(self, itemType, agent):
        '''
        Give an item of the given enumerated type to another agent. Returns true if successful, false otherwise.

            Preconditions:
                - The agent has an item of the given type
                - The agent has that item currently equipped
                - The agent is looking at the agent to give the item to
                - The agent is at the agent to give the item to
        '''
        # Check action override
        if self.__shouldPerformActionOverride(self.giveItem):
            return self.__actionOverride.function(*self.__actionOverride.args)

        # Stop moving before going any further...
        self.stopMoving()

        # Preconditions
        equippedItem = self.inventory.equippedItem()
        if not self.__checkPreconditions(
            equippedItem != None,
            equippedItem.type == itemType.value,
            self.__isLookingAt(agent.__position()),
            self.__isAt(agent.__position(), 2, GIVING_DISTANCE)
        ):
            return False

        # Record the exchange in each agent's inventory
        toGive = self.inventory.removeItem(itemType)
        agent.inventory.addItem(itemType, toGive.id)  # Preserve the ID

        # Action
        self.__throwItem()
        time.sleep(2.8)
        self.__logReports.append(LogUtils.GiveItemReport(toGive, agent))
        return True