def move_to_attack( self, explo, chara, target, redraw=None ): result = None if not redraw: redraw = explo.view explo.view.overlays.clear() if self.scene.on_the_map( *target.pos ): attack_positions = pfov.AttackReach( self.scene, target.pos[0], target.pos[1], chara.get_attack_reach() ).tiles # Remove the positions of models from the goal tiles, so they will be avoided. for m in self.scene.contents: if self.scene.is_model(m) and m.pos in attack_positions and m is not chara: attack_positions.remove( m.pos ) hmap = hotmaps.HotMap( self.scene, attack_positions, avoid_models=True ) while self.ap_spent[ chara ] < chara.get_move(): result = self.step( explo, chara, hmap ) if chara in self.camp.party: self.scene.update_party_position( explo.camp.party ) if result: break redraw( explo.screen ) pygame.display.flip() pygwrap.anim_delay() if chara.pos in attack_positions: # Close enough to attack. Make it so. self.attack( explo, chara, target, redraw ) return result
def get_attack_map(self, explo, chara, reach): """Return the attack positions and hotmap for this character.""" comba = explo.camp.fight attack_positions = set() if self.AVOID_THREAT: expensive_points = comba.get_threatened_area(chara) else: expensive_points = set() # Add the targets. for m in explo.scene.contents: if chara.is_enemy(explo.camp, m) and m.is_alright() and not m.hidden: attack_positions.update( pfov.AttackReach(explo.scene, m.pos[0], m.pos[1], reach).tiles) elif isinstance(m, enchantments.Field) and self.AVOID_FIELDS: expensive_points.add(m.pos) # Remove models from goal squares to prevent weird behavior. for m in explo.scene.contents: if explo.scene.is_model( m) and m.pos in attack_positions and m is not chara: attack_positions.remove(m.pos) hmap = hotmaps.HotMap(explo.scene, attack_positions, avoid_models=True, expensive=expensive_points) return (attack_positions, hmap)
def calc_positions( self, camp, user, reach ): # Perform the calculation to generate a list of positions from which # to invoke this technique. attack_positions = set() # Add the targets. for m in camp.scene.contents: if self.get_targetability( camp, user, m ) > 0 and not m.hidden: attack_positions.update( pfov.AttackReach( camp.scene, m.pos[0], m.pos[1], reach ).tiles ) attack_positions.add( m.pos ) return attack_positions
def get_return_pos(explo): x0, y0 = explo.camp.first_living_pc().pos dist = 3 while dist <= 12: entry_points = pfov.AttackReach(explo.scene, x0, y0, dist, True).tiles for m in explo.scene.contents: if explo.scene.is_model(m) and m.pos in entry_points: entry_points.remove(m.pos) if entry_points: return random.choice(list(entry_points)) dist *= 2 return (x0, y0)
def get_attack_map(self, explo, chara, reach): """Return the attack positions and hotmap for this character.""" comba = explo.camp.fight attack_positions = set() if self.AVOID_THREAT: expensive_points = comba.get_threatened_area(chara) else: expensive_points = set() # Get a list of targets. enemies = list() for m in explo.scene.contents: if chara.is_enemy(explo.camp, m) and m.is_alright() and not m.hidden: enemies.append(m) elif isinstance(m, enchantments.Field) and self.AVOID_FIELDS: expensive_points.add(m.pos) # Remove models from goal squares to prevent weird behavior. banned = set() for m in explo.scene.contents: if explo.scene.is_model( m) and m.pos in attack_positions and m is not chara: banned.add(m.pos) # Convert the list of enemies + list of banned squares into a proper set # of goals. Really, monster, what are you planning to do with your short # life? Have you really thought this through? Do you think you can earn # a living just blindly charging at the nearest player character? Do you? attack_positions = set() hmap_goals = set() enemies.sort(key=self.get_target_heat) m_heat = 0 for m in enemies: m_goal = pfov.AttackReach(explo.scene, m.pos[0], m.pos[1], reach).tiles for p in m_goal: if p not in banned: attack_positions.add(p) hmap_goals.add(p + (m_heat, )) if m_heat < self.HEAT_MAX: m_heat = min(m_heat + self.HEAT_STEP, self.HEAT_MAX) hmap = hotmaps.HotMap(explo.scene, hmap_goals, avoid_models=True, expensive=expensive_points) return (attack_positions, hmap)
def place_party( self ): """Stick the party close to the waypoint.""" x0,y0 = self.entrance.pos entry_points = list( pfov.AttackReach( self.scene, x0, y0, 3, True ).tiles ) for m in self.scene.contents: if self.scene.is_model(m) and m.pos in entry_points: entry_points.remove( m.pos ) for pc in self.party: if pc.is_alright(): if entry_points: pos = random.choice( entry_points ) entry_points.remove( pos ) else: pos = self.entrance.pos pc.pos = pos self.scene.contents.append( pc ) pfov.PCPointOfView( self.scene, pos[0], pos[1], 15 )