예제 #1
0
    def __call__(self, battle, unit, turns):
        map_ = battle.map()
        unitCopy = copy.copy(unit)

        # Get a list of targets, sorted by lowest HP.
        targets = []
        for t in battle.units():
            if (t.alive() and 
                Faction.friendly(unit.faction(), t.faction()) and
                t.hp() < t.mhp()):
                targets.append(t)
        targets.sort(lambda x,y: cmp(x.hp(), y.hp()))
        
        # Get all turns that heal the weakest possible target
        
        # FIXME: could optimize by keeping a map from units -> attacks
        # that hit that unit
        bestTurns = []
        for target in targets:
            for turn in turns:
                action = turn.action()
                if action == None:
                    continue
                # FIXME: more general way of filtering abilities
                # FIXME: we don't consider FRIENDLY_AND_HOSTILE yet
                if action.targetType() != Ability.FRIENDLY:
                    continue   
                heals = False
                for e in action.effects():    
                    if issubclass(e.__class__, Effect.Healing):
                        heals = True
                        break
                if not heals:
                    continue

                # FIXME: modifying map == ugly
                # Temporarily modify the map for our new
                # position... have to make sure to roll this back!
                if turn.moveTarget() != None:
                    (mtx, mty) = turn.moveTarget()
                else:
                    (mtx, mty) = unit.posn()
                map_.squares[unit.x()][unit.y()].unit = None
                map_.squares[mtx][mty].unit = unit
                unitCopy.setPosn(mtx, mty, map_.squares[mtx][mty].z)
                
                # Find out who's affected
                affected = action.affectedUnits(map_,
                                                unitCopy,
                                                turn.actionTarget())
               
                # Roll back the map modification
                map_.squares[mtx][mty].unit = None
                map_.squares[unit.x()][unit.y()].unit = unit               
                
                if target in affected:
                    bestTurns.append(turn)
            if bestTurns:
                return bestTurns
        return bestTurns
예제 #2
0
    def __call__(self, battle, unit, turns):
        map_ = battle.map()

        # Get a list of targets, sorted by lowest HP.
        targets = []
        for t in battle.units():
            if t.alive() and Faction.hostile(unit.faction(), t.faction()):
                targets.append(t)
        targets.sort(lambda x,y: cmp(x.hp(), y.hp()))

        # Get as close as possible to the weakest target
        map_.fillDistances(unit, targets[0].posn())
        bestDistance = 1000000
        bestTurns = []
        for turn in turns:
            move = turn.moveTarget()
            action = turn.action()
            if move == None or action != None:
                continue
            search = map_.squares[move[0]][move[1]].search
            if search == None:
                continue
            distance = search[0]
            if distance < bestDistance:
                bestDistance = distance
                bestTurns = [turn]
            elif distance == bestDistance:
                bestTurns.append(turn)
        return bestTurns
예제 #3
0
    def affect(self, source, target):
        if not target.alive():
            return [MissResult(target)]

        if Faction.friendly(source.faction(), target.faction()):
            (attack, defense) = self.calcAttackAndDefense(source, target)

            # Heal target and display results
            healing = self.calcDamage(attack, attack,
                                      target.mhp() - target.hp())
            target.damageHP(-healing, HEALING)
            return [HealResult(target, healing)]
        elif Faction.hostile(source.faction(), target.faction()):
            target = self.getDefenders(target)
            (attack, defense) = self.calcAttackAndDefense(source, target)

            # Check if the target evades the attack
            if random.random() < target.evade():
                return [MissResult(target)]

            # Damage target and display results
            damage = self.calcDamage(attack, defense, target.hp())
            target.damageHP(damage, self._damageType)
            return [DamageResult(target, damage)]
예제 #4
0
    def affect(self, source, target):
        if not target.alive():
            return [MissResult(target)]

        if Faction.friendly(source.faction(), target.faction()):
            (attack, defense) = self.calcAttackAndDefense(source, target)
            
            # Heal target and display results
            healing = self.calcDamage(attack, attack,
                                      target.mhp() - target.hp())
            target.damageHP(-healing, HEALING)
            return [HealResult(target, healing)]
        elif Faction.hostile(source.faction(), target.faction()):
            target = self.getDefenders(target)
            (attack, defense) = self.calcAttackAndDefense(source, target)

            # Check if the target evades the attack
            if random.random() < target.evade():
                return [MissResult(target)]

            # Damage target and display results
            damage = self.calcDamage(attack, defense, target.hp())
            target.damageHP(damage, self._damageType)
            return [DamageResult(target, damage)]
예제 #5
0
    def getFacing(self, battle, moveTarget):
        u = self._unit
        if moveTarget == None:
            moveTarget = (u.x(), u.y())
        
        # Calculate the centroid of enemy units
        targets = []
        for t in battle.units():
            if t.alive() and Faction.hostile(u.faction(), t.faction()):
                targets.append(t)
        centroidX = 0.0
        centroidY = 0.0
        for t in targets:
            centroidX += t.x()
            centroidY += t.y()
        centroidX /= len(targets)
        centroidY /= len(targets)

        # Face toward the centroid
        dx = centroidX - moveTarget[0]
        dy = centroidY - moveTarget[1]
        total = abs(dx)+abs(dy)
        if total == 0.0:
            return None
        rnd = random.uniform(0.0, total)
        if rnd < dx:
            # Face based on X-coord
            if dx > 0:
                return Constants.E
            else:
                return Constants.W
        else:
            if dy > 0:
                return Constants.S
            else:
                return Constants.N
예제 #6
0
    def draw(self):
        #glDisable(GL_DEPTH_TEST)
        if self._color[3] < 0.0:
            return

        glDisable(GL_LIGHTING)
        glDepthFunc(GL_LEQUAL)
        glPushMatrix()
        GLUtil.mapTrans(self.x, self.y, self.z)

        # Draw the circle around the unit's feet
        (r, g, b) = Faction.color(self.__unit.faction())
        none = Resources.texture("none")
        glBindTexture(GL_TEXTURE_2D, none)
        glPushMatrix()
        if self.__unit.facing() == Constants.E:
            glRotate(-90.0, 0.0, 0.0, 1.0)
        elif self.__unit.facing() == Constants.S:
            glRotate(180.0, 0.0, 0.0, 1.0)
        elif self.__unit.facing() == Constants.W:
            glRotate(90.0, 0.0, 0.0, 1.0)
        glColor4f(r, g, b, 1.0 * self._color[3])
        glBegin(GL_TRIANGLES)
        glVertex3f(0.0, 0.0, 0.0)
        glVertex3f(-0.15, 0.35, 0.0)
        glVertex3f(0.15, 0.35, 0.0)
        glEnd()
        glPopMatrix()
        quad = gluNewQuadric()
        gluDisk(quad, 0.3, 0.4, 32, 1)
        gluDeleteQuadric(quad)

        # Checking for texture and color status
        unitStatus = self.__unit.statusEffects()
        if len(unitStatus.texture()) == 0:
            self._textureStatus = -1
        else:
            if time.time() > self._textureTime:
                self._textureTime = time.time() + 1.1
                self._textureStatus += 1
                if self._textureStatus >= len(unitStatus.texture()):
                    self._textureStatus = 0
            try:
                if engine.Effect.Status.effectTextures[unitStatus.texture()[
                        self._textureStatus]] != None:
                    GLUtil.makeStatus(
                        engine.Effect.Status.effectTextures[
                            unitStatus.texture()[self._textureStatus]],
                        self._color)
            except:
                # when the status is over this can happen
                pass

        statuscolor = None
        if len(unitStatus.color()) == 0:
            self._colorStatus = -1
        else:
            if time.time() > self._colorTime:
                self._colorTime = time.time() + 1.3
                self._colorStatus += 1
                if self._colorStatus >= len(unitStatus.color()):
                    self._colorStatus = 0
            try:
                if engine.Effect.Status.effectTextures[unitStatus.color()[
                        self._colorStatus]] != None:
                    statuscolor = engine.Effect.Status.effectTextures[
                        unitStatus.color()[self._colorStatus]]
            except:
                pass

        if statuscolor == None:
            if self.isActing() == True:
                self._unitStatusColor = self._color
            else:
                GLUtil.makeUnit(texture=self.__texture,
                                wtexture=self.__wtexture,
                                otexture=self.__otexture,
                                color=self._color,
                                weaponGrip=self.__weaponGrip,
                                unitHand=self.__unitHand)
        else:
            if self.isActing() == True:
                self._unitStatusColor = statuscolor
            else:
                GLUtil.makeUnit(texture=self.__texture,
                                wtexture=self.__wtexture,
                                otexture=self.__otexture,
                                color=statuscolor,
                                weaponGrip=self.__weaponGrip,
                                unitHand=self.__unitHand)

        for a in self._animations:
            a.draw()

        glPopMatrix()
        glDepthFunc(GL_LESS)
        glEnable(GL_LIGHTING)
예제 #7
0
    def __call__(self, battle, unit, turns):
        map_ = battle.map()

        # Get a list of targets, sorted by lowest HP.
        targets = []
        for t in battle.units():
            if t.alive() and Faction.hostile(unit.faction(), t.faction()):
                targets.append(t)
        targets.sort(lambda x,y: cmp(x.hp(), y.hp()))
        
        # Get all turns that hit the weakest possible target
        
        # FIXME: could optimize by keeping a map from units -> attacks
        # that hit that unit
        bestTurns = []
        for target in targets:
            for turn in turns:
                action = turn.action()
                if action == None:
                    continue
                # FIXME: more general way of filtering abilities
                # FIXME: we don't consider FRIENDLY_AND_HOSTILE yet
                if action.targetType() != Ability.HOSTILE:
                    continue
                doesDamage = False
                for e in action.effects():    
                    if (issubclass(e.__class__, Effect.Damage) or
                        issubclass(e.__class__, Effect.DrainLife) or
                        issubclass(e.__class__,
                                   Effect.HealFriendlyDamageHostile)):
                        doesDamage = True
                        break
                if not doesDamage:
                    continue
                
                affected = action.affectedUnits(map_,
                                                unit,
                                                turn.actionTarget())
                if target in affected:
                    bestTurns.append(turn)
            if bestTurns:
                # We have some candidate turns, now evaluate them to
                # see which does the most total damage
                maxDamage = 0.1
                newBestTurns = []
                unitCopy = copy.copy(unit)
                for turn in bestTurns:
                    if turn.moveTarget() != None:
                        (mtx, mty) = turn.moveTarget()
                    else:
                        (mtx, mty) = unitCopy.posn()
                    unitCopy.setPosn(mtx, mty, map_.squares[mtx][mty].z)
                    action = turn.action()
                    damage = 0
                    affected = action.affectedUnits(map_,
                                                    unitCopy,
                                                    turn.actionTarget())
                    for target in affected:
                        for e in action.effects():
                            if issubclass(e.__class__, Effect.Damage):
                                (att, df) = e.calcAttackAndDefense(unitCopy,
                                                                   target)
                                dmg = e.estimateDamage(att, df)
                                damage += dmg
                    if damage > maxDamage:
                        maxDamage = damage
                        newBestTurns = [turn]
                    elif damage == maxDamage:
                        newBestTurns.append(turn)
                if newBestTurns:
                    # Filter again - prefer turns with the lowest SP cost
                    newNewBestTurns = []
                    lowestCost = 1000000
                    for turn in newBestTurns:
                        if turn.action().cost() < lowestCost:
                            lowestCost = turn.action().cost()
                            newNewBestTurns = [turn]
                        elif turn.action().cost() == lowestCost:
                            newNewBestTurns.append(turn)
                    # Filter again - prefer a turn with no move
                    for turn in newNewBestTurns:
                        if turn.moveTarget() == None:
                            return [turn]
                    return newNewBestTurns
        return bestTurns
예제 #8
0
    def draw(self):
        #glDisable(GL_DEPTH_TEST)
        if self._color[3] < 0.0:
            return
        
        glDisable(GL_LIGHTING)
        glDepthFunc(GL_LEQUAL)
        glPushMatrix()
        GLUtil.mapTrans(self.x, self.y, self.z)

        # Draw the circle around the unit's feet
        (r, g, b) = Faction.color(self.__unit.faction())
        none = Resources.texture("none")
        glBindTexture(GL_TEXTURE_2D, none)
        glPushMatrix()
        if self.__unit.facing() == Constants.E:
            glRotate(-90.0, 0.0, 0.0, 1.0)
        elif self.__unit.facing() == Constants.S:
            glRotate(180.0, 0.0, 0.0, 1.0)
        elif self.__unit.facing() == Constants.W:
            glRotate(90.0, 0.0, 0.0, 1.0)           
        glColor4f(r, g, b, 1.0 * self._color[3])
        glBegin(GL_TRIANGLES)
        glVertex3f(0.0, 0.0, 0.0)
        glVertex3f(-0.15, 0.35, 0.0)
        glVertex3f(0.15, 0.35, 0.0)
        glEnd()
        glPopMatrix()
        quad = gluNewQuadric()
        gluDisk(quad, 0.3, 0.4, 32, 1)
        gluDeleteQuadric(quad)

        # Checking for texture and color status
        unitStatus = self.__unit.statusEffects()
        if len(unitStatus.texture()) == 0 :
            self._textureStatus = -1
        else:
            if time.time() > self._textureTime:
                self._textureTime = time.time() +1.1
                self._textureStatus += 1
                if self._textureStatus >= len(unitStatus.texture()):
                    self._textureStatus = 0
            try:
                if engine.Effect.Status.effectTextures[unitStatus.texture()[self._textureStatus]] != None:
                    GLUtil.makeStatus(engine.Effect.Status.effectTextures[unitStatus.texture()[self._textureStatus]], self._color)
            except:
                # when the status is over this can happen
                pass

        statuscolor = None
        if len(unitStatus.color()) == 0 :
            self._colorStatus = -1
        else:
            if time.time() > self._colorTime:
                self._colorTime = time.time() +1.3
                self._colorStatus += 1
                if self._colorStatus >= len(unitStatus.color()):
                    self._colorStatus = 0
            try:
                if engine.Effect.Status.effectTextures[unitStatus.color()[self._colorStatus]] != None:
                    statuscolor = engine.Effect.Status.effectTextures[unitStatus.color()[self._colorStatus]]
            except :
                pass

        if statuscolor == None :
            if self.isActing() == True:
                self._unitStatusColor = self._color
            else:
                GLUtil.makeUnit(texture = self.__texture,
                                wtexture = self.__wtexture,
                                otexture = self.__otexture, 
                                color = self._color,
                                weaponGrip = self.__weaponGrip,
                                unitHand = self.__unitHand)
        else:
            if self.isActing() == True:
                self._unitStatusColor = statuscolor
            else:
                GLUtil.makeUnit(texture = self.__texture,
                                wtexture = self.__wtexture,
                                otexture = self.__otexture, 
                                color = statuscolor,
                                weaponGrip = self.__weaponGrip,
                                unitHand = self.__unitHand)
                
        for a in self._animations:
            a.draw()

        glPopMatrix()
        glDepthFunc(GL_LESS)
        glEnable(GL_LIGHTING)