Exemple #1
0
    def findpath(self):
        start = self.locator.pos()
        goal = self.target.getpos()

        if self.range is None and self.target.isent():
            self.range = self.target.ent.locator.r + self.locator.r
        else:
            self.range = 0#self.locator.r
        
        path = self.pathfinder.findpath(start, goal, self.walk, self.range)
        if path:
            # waypoints list is backwards
            # popping off completed points from the end is cheaper
            self.waypoints[:] = list(reversed(path))

            # if len(self.waypoints) > 1:
            #     # the first point is just the centre of the current cell,
            #     # so if we have more than one point we skip this
            #     self.waypoints.pop()

            # if self.range == 0:
            #     # for an exact target we don't want the centre of the destination
            #     # cell, so replace it with the actual goal
            #     self.waypoints[0] = goal
        else:
            warn('no path to', self.target)
            self.stop()
Exemple #2
0
    def deduct_cost(self, ent):
        if self.cost.is_town_cost():
            if not ent.has('town'):
                warn('ignoring out of town cost')
                return

            res = ent.town.town.resources
            res.deduct(self.cost)

        if self.cost.is_entity_cost():
            ent.variables['mana'] -= self.cost.mana
Exemple #3
0
    def give(self, action):
        ''' Cancel all actions and do this instead '''
        action.ent = self.ent

        if self.queue:
            if not self.queue[-1].interruptible():
                warn('action is not interruptible!')
                return

            self.queue[-1].suspend()
            for ac in self.queue:
                ac.stop()

        del self.queue[:]

        self.queue.append(action)
        action.start()
Exemple #4
0
    def loadsector(self, sx, sy):
        try:
            return self.sectors[sx, sy]
        except KeyError:
            # TODO - hack - check for sectors existing
            try:
                self.datasrc.getmapsector(sx, sy)
                s = self.components.construct('sector', sx, sy)
            except KeyError:
                warn(f"sector {sx},{sy} doesn't exist")
                s = None

            self.sectors[sx, sy] = s
            if s is not None:
                self.dirty.add(s)
                self.onsectorloaded.emit(s)
            return s
Exemple #5
0
    def check_cost(self, ent):
        if self.cost.is_town_cost():
            if not ent.has('town'):
                warn('ignoring out of town cost')
                return True

            res = ent.town.town.resources
            if not res.sufficient(self.cost):
                return False

        if self.cost.is_entity_cost():
            if not ent.has('variables'):
                return False
            vars = ent.variables
            if 'mana' not in vars or vars['mana'] < self.cost.mana:
                return False

        return True
Exemple #6
0
    def select(self, ents, add):
        ''' Select ents or add ents to the current selection '''
        lp = self.local.player
        myents = set(e for e in ents if e.ownedby(lp))

        if not myents:
            # select highest ranked enemy ent
            rank = min(e.rank for e in ents)
            selection = [e for e in ents
                         if e.rank == rank
                         and e.appearance.visible_to(lp.tidmask)][:1]
        else:
            # select only my ents
            if add:
                # adding to the selection, use the tier of already selected ents
                myents = myents | set(self.selection)
                tier = self.selection[0].tier
            else:
                # new selection, use the highest tier
                tier = min(e.tier for e in myents)

            selection = [e for e in myents if e.tier == tier]

        if not selection:
            # no valid entities selected, so don't change selection
            warn('no entities were selected')
            return

        selection.sort(key=lambda e: e.rank)

        for s in self.selection:
            if s.has('appearance'):
                s.appearance.selected(False)

        self.selection = selection

        for s in self.selection:
            if s.has('appearance'):
                s.appearance.selected(True)

        self.onselectionchange.emit()
Exemple #7
0
    def activate(self, idx, target, add):
        ainst = self[idx]

        if ainst.cooldown > 0:
            warn('not ready - ability activate checked it')
            return False  # not ready

        if not ainst.ability.check_cost(self.ent):
            warn('cannot pay cost - ability activate checked it')
            return False

        if ainst.ability.queue:
            assert self.ent.has(
                'queue'), 'entity needs a queue for this ability'
            self.ent.queue.add(ainst, target)
            ainst.ability.deduct_cost(self.ent)
            return True
        else:
            if ainst.wait > 0:
                warn('already doing this - ability activate checked it')
                return False  # not ready

            action = AbilityAction(ainst, target)
            if add:
                self.actions.now(action)
            else:
                self.actions.give(action)
            return True
Exemple #8
0
        def check_ability(eid):
            e = self.engine.entities.get(eid)

            if not e.has('abilities'):
                error('entity has no abilities')
                return False

            try:
                ainst = e.abilities[idx]
            except IndexError:
                error('index out of bounds - entity doesn\'t havethis ability')
                return False

            if e.proto.epid != ent.proto.epid:
                warn('entity does not have ability {0}', ability.name)
                return False

            if ainst.cooldown > 0:
                warn('not ready - game checked it')
                return False

            if not ability.queue and ainst.wait > 0:
                warn('already doing this - game checked it')
                return False

            #if not ability.check_cost(e):
            #    warn('cannot pay cost - game checked it')
            #    return False

            return True
Exemple #9
0
    def ability(self, idx, add):
        info(f'trying to do ability {idx}')
        ''' Do the ability at idx for the currently selected entities '''
        if not self.selection:
            # nothing selected
            warn('no selection')
            return

        # grab the ability - defined by the first entity in the selection
        ent = self.selection[0]
        if not ent.has('abilities'):
            # no abilities
            warn('entity has no abilities')
            return

        if not ent.ownedby(self.local.player):
            # should never happen, player doesn't own the entity
            warn('entity not owned by local player')
            return

        try:
            ability = ent.abilities[idx].ability
        except IndexError:
            error('index out of bounds')
            return

        # get the ents - non group abilities cannot be done by
        # multiple entities so we pick the first
        if not ability.group:
            entids = [ent.eid]
        else:
            entids = [e.eid for e in self.selection]

        # verify if there are any entities in the selection that can actually
        # do the ability right now
        #  * do they have the same ability - for now we compare the protos
        #  * enough resourcea
        #  * cooldowns not active
        # NOTE this is a Game check, the Engine will check again when activating
        def check_ability(eid):
            e = self.engine.entities.get(eid)

            if not e.has('abilities'):
                error('entity has no abilities')
                return False

            try:
                ainst = e.abilities[idx]
            except IndexError:
                error('index out of bounds - entity doesn\'t havethis ability')
                return False

            if e.proto.epid != ent.proto.epid:
                warn('entity does not have ability {0}', ability.name)
                return False

            if ainst.cooldown > 0:
                warn('not ready - game checked it')
                return False

            if not ability.queue and ainst.wait > 0:
                warn('already doing this - game checked it')
                return False

            #if not ability.check_cost(e):
            #    warn('cannot pay cost - game checked it')
            #    return False

            return True

        entids = [eid for eid in entids if check_ability(eid)]
        if not entids:
            warn('no entities can do the ability now')
            self.gamelog.log('No units can do this ability right now')
            return
        
        # create the order
        order = AbilityOrder(entids, idx, add)

        # based on ability type we either issue an order
        # or enter a new mode
        if ability.type == ability.INSTANT:
            order.add = True  # instants never interrupt the current action
            self.order(order)
        elif ability.type == ability.ACTIVITY:
            self.order(order)
        elif ability.type == ability.TARGETED:
            self.modes.push_mode('targetingmode', order, allowpos=False)
        elif ability.type == ability.BUILD:
            proto = ent.team.getproto(ability.proto)
            self.modes.push_mode('buildmode', order, proto)
        elif ability.type == ability.AREA_OF_EFFECT:
            self.modes.push_mode('targetingmode', order)
        elif ability.type == ability.STATIC:
            pass  # do nothing
        else:
            raise RuntimeError('unknown ability type!')
Exemple #10
0
 def destroy(self):
     warn('TODO - unfootprint')
Exemple #11
0
 def close(self):
     warn('closing Lua interp')
     self.lua.lua_close(self.L)