def get_tech_map(self, explo, chara, attack_positions):
        """Return the attack positions and hotmap for this character."""
        comba = explo.camp.fight
        avoid_positions = set()
        comfy_positions = set()
        if self.AVOID_THREAT:
            expensive_points = comba.get_threatened_area(chara)
        else:
            expensive_points = set()
        # 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)
            elif isinstance(m, enchantments.Field) and self.AVOID_FIELDS:
                expensive_points.add(m.pos)
            if chara.is_enemy(
                    explo.camp,
                    m) and m in explo.camp.fight.active and not m.hidden:
                avoid_positions.add(m.pos)
            elif chara.is_ally(
                    explo.camp, m
            ) and m is not chara and m in explo.camp.fight.active and not m.hidden:
                comfy_positions.add(m.pos)

        hmap = hotmaps.HotMap(explo.scene,
                              attack_positions,
                              avoid_models=True,
                              expensive=expensive_points)
        hmap.mix(hotmaps.AvoidMap(explo.scene, avoid_positions),
                 self.avoid_enemies)
        hmap.mix(hotmaps.HotMap(explo.scene, comfy_positions),
                 self.approach_allies)
        return hmap
Example #2
0
    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 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)