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
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
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)]
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
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)
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
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)