def __init__(self, global_path_finder: GlobalPathFinder):
     super().__init__(global_path_finder)
     self._update_attack_interval()
     self._time_since_attack = 0
     self._update_path_interval = 900
     self._time_since_updated_path = random.randint(0, self._update_path_interval)
     self.pathfinder = NpcPathfinder(global_path_finder)
     self.next_waypoint = None
     self._reevaluate_next_waypoint_direction_interval = 1000
     self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
예제 #2
0
class NpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder):
        super().__init__(global_path_finder)
        self._attack_interval = 1000
        self._time_since_attack = self._attack_interval
        self._update_path_interval = 900
        self._time_since_updated_path = random.randint(0, self._update_path_interval)
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter, player_entity: WorldEntity,
                    is_player_invisible: bool, time_passed: Millis):
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed
        self._time_since_attack += time_passed

        summon_entity = npc.world_entity

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            nearby_enemies = game_state.game_world.get_enemies_within_x_y_distance_of(300,
                                                                                      npc.world_entity.get_position())
            if nearby_enemies:
                target_entity = nearby_enemies[0].world_entity
            else:
                target_entity = game_state.game_world.player_entity
            self.pathfinder.update_path_towards_target(summon_entity, game_state, target_entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(summon_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, summon_entity, self.next_waypoint)
                _move_in_dir(summon_entity, direction)
            else:
                summon_entity.set_not_moving()
        if self._time_since_attack > self._attack_interval:
            self._time_since_attack = 0
            nearby_enemies = game_state.game_world.get_enemies_within_x_y_distance_of(100, summon_entity.get_position())
            if nearby_enemies:
                damage_amount = 3
                target = nearby_enemies[0]
                deal_npc_damage_to_npc(game_state, target, damage_amount)
                game_state.game_world.visual_effects.append(
                    VisualLine((220, 0, 0), summon_entity.get_center_position(),
                               target.world_entity.get_center_position(), Millis(100), damage_amount))
예제 #3
0
 def __init__(self, global_path_finder: GlobalPathFinder):
     super().__init__(global_path_finder)
     self._update_path_interval = 900
     self._time_since_updated_path = random.randint(0, self._update_path_interval)
     self.pathfinder = NpcPathfinder(global_path_finder)
     self.next_waypoint = None
     self._reevaluate_next_waypoint_direction_interval = 1000
     self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
     self._shoot_fireball_trait = EnemyShootProjectileTrait(
         create_projectile=create_projectile,
         projectile_size=PROJECTILE_SIZE,
         cooldown_interval=(Millis(500), Millis(5000)),
         chance_to_shoot_other_direction=0.3,
         sound_id=SoundId.ENEMY_ATTACK_GOBLIN_WARLOCK)
예제 #4
0
class NpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder):
        super().__init__(global_path_finder)
        self._update_path_interval = 900
        self._time_since_updated_path = random.randint(0, self._update_path_interval)
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
        self._shoot_fireball_trait = EnemyShootProjectileTrait(
            create_projectile=create_projectile,
            projectile_size=PROJECTILE_SIZE,
            cooldown_interval=(Millis(500), Millis(5000)),
            chance_to_shoot_other_direction=0.3,
            sound_id=SoundId.ENEMY_ATTACK_GOBLIN_WARLOCK)

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter, player_entity: WorldEntity,
                    is_player_invisible: bool, time_passed: Millis):
        if npc.stun_status.is_stunned():
            return
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed

        enemy_entity = npc.world_entity
        target: EnemyTarget = get_target(enemy_entity, game_state)

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            if not is_player_invisible:
                self.pathfinder.update_path_towards_target(enemy_entity, game_state, target.entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(enemy_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, enemy_entity, self.next_waypoint)
                if random.random() < 0.5 and direction:
                    direction = random.choice(get_perpendicular_directions(direction))
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        self._shoot_fireball_trait.update(npc, game_state, time_passed)
예제 #5
0
 def __init__(self, global_path_finder: GlobalPathFinder,
              attack_interval: Millis, damage_amount: int,
              chance_to_stray_from_path: float,
              update_path_interval: Millis):
     super().__init__(global_path_finder)
     self._base_attack_interval = attack_interval
     self._attack_interval = None
     self.randomize_attack_interval()
     self._time_since_attack = self._attack_interval
     self._update_path_interval = update_path_interval
     self._time_since_updated_path = self._update_path_interval
     self.pathfinder = NpcPathfinder(global_path_finder)
     self.next_waypoint = None
     self._reevaluate_next_waypoint_direction_interval = 1000
     self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
     self.damage_amount = damage_amount
     self.chance_to_stray_from_path = chance_to_stray_from_path
     self._is_in_melee_with_target = False
예제 #6
0
class NpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder):
        super().__init__(global_path_finder)
        self._base_attack_interval = 3000
        self._attack_interval = None
        self.randomize_attack_interval()
        self._time_since_attack = self._attack_interval
        self._update_path_interval = 600
        self._time_since_updated_path = self._update_path_interval
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval

    def randomize_attack_interval(self):
        self._attack_interval = self._base_attack_interval + random.randint(
            -250, 250)

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter,
                    player_entity: WorldEntity, is_player_invisible: bool,
                    time_passed: Millis):
        self._time_since_attack += time_passed
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed

        enemy_entity = npc.world_entity
        target: EnemyTarget = get_target(enemy_entity, game_state)

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            if not is_player_invisible:
                self.pathfinder.update_path_towards_target(
                    enemy_entity, game_state, target.entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(
            enemy_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, enemy_entity, self.next_waypoint)
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        if self._time_since_attack > self._attack_interval:
            if not is_player_invisible:
                enemy_position = enemy_entity.get_center_position()
                target_center_pos = target.entity.get_center_position()
                if is_x_and_y_within_distance(enemy_position,
                                              target_center_pos, 200):
                    self._time_since_attack = 0
                    self.randomize_attack_interval()
                    play_sound(SoundId.ENEMY_ATTACK_ICE_WITCH)
                    damage = random.randint(DAMAGE_MIN, DAMAGE_MAX)
                    deal_npc_damage(damage, DamageType.MAGIC, game_state,
                                    enemy_entity, npc, target)
                    game_state.visual_effects += [
                        (VisualLine((100, 100, 200), enemy_position,
                                    target_center_pos, Millis(120), 3)),
                        (VisualLine((150, 150, 250), enemy_position,
                                    target_center_pos, Millis(240), 2))
                    ]
                    game_state.player_state.gain_buff_effect(
                        get_buff_effect(SLOW_BUFF_TYPE), Millis(1500))
예제 #7
0
class NpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder):
        super().__init__(global_path_finder)
        self._attack_interval = 1000
        self._time_since_attack = self._attack_interval
        self._update_path_interval = 900
        self._time_since_updated_path = random.randint(
            0, self._update_path_interval)
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
        self._shield_interval = 13000
        self._shield_duration = 5000
        self._time_since_shield = 7000

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter,
                    player_entity: WorldEntity, is_player_invisible: bool,
                    time_passed: Millis):
        self._time_since_attack += time_passed
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed
        self._time_since_shield += time_passed

        enemy_entity = npc.world_entity

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            self.pathfinder.update_path_towards_target(
                enemy_entity, game_state, game_state.player_entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(
            enemy_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, enemy_entity, self.next_waypoint)
                if random.random() < 0.1 and direction:
                    direction = random.choice(
                        get_perpendicular_directions(direction))
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        enemy_center_pos = enemy_entity.get_center_position()

        if self._time_since_attack > self._attack_interval:
            self._time_since_attack = 0
            game_state.visual_effects.append(
                VisualCircle((100, 100, 100), enemy_center_pos, 180, 180,
                             Millis(self._attack_interval), 1, enemy_entity))
            if not is_player_invisible:
                player_center_pos = game_state.player_entity.get_center_position(
                )
                if is_x_and_y_within_distance(enemy_center_pos,
                                              player_center_pos, 160):
                    deal_damage_to_player(game_state, 3, DamageType.MAGIC, npc)
                    game_state.visual_effects += [
                        VisualCircle((0, 0, 0), enemy_center_pos, 25, 50,
                                     Millis(200), 2, enemy_entity),
                        VisualLine((0, 100, 0), enemy_center_pos,
                                   player_center_pos, Millis(200), 2),
                        VisualCircle((0, 100, 0), player_center_pos, 20, 40,
                                     Millis(150), 2, player_entity),
                        VisualCircle((0, 150, 0), player_center_pos, 25, 50,
                                     Millis(200), 2, player_entity),
                        VisualCircle((0, 200, 0), player_center_pos, 30, 60,
                                     Millis(300), 2, player_entity),
                    ]

        if self._time_since_shield > self._shield_interval:
            self._time_since_shield = 0

            game_state.visual_effects.append(
                VisualCircle((0, 0, 150), enemy_center_pos, 60, 20,
                             Millis(self._shield_duration), 2, enemy_entity))
            npc.gain_buff_effect(get_buff_effect(BUFF_TYPE_INVULN),
                                 Millis(self._shield_duration))
예제 #8
0
class NpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder):
        super().__init__(global_path_finder)
        self._update_attack_interval()
        self._time_since_attack = 0
        self._update_path_interval = 900
        self._time_since_updated_path = random.randint(
            0, self._update_path_interval)
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter,
                    player_entity: WorldEntity, is_player_invisible: bool,
                    time_passed: Millis):
        self._time_since_attack += time_passed
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed

        enemy_entity = npc.world_entity
        target: EnemyTarget = get_target(enemy_entity, game_state)

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            if not is_player_invisible:
                self.pathfinder.update_path_towards_target(
                    enemy_entity, game_state, target.entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(
            enemy_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, enemy_entity, self.next_waypoint)
                if random.random() < 0.5 and direction:
                    direction = random.choice(
                        get_perpendicular_directions(direction))
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        if self._time_since_attack > self._attack_interval:
            self._time_since_attack = 0
            self._update_attack_interval()
            directions_to_player = get_directions_to_position(
                npc.world_entity, player_entity.get_position())
            new_direction = directions_to_player[0]
            if random.random() < 0.3 and directions_to_player[1] is not None:
                new_direction = directions_to_player[1]
            npc.world_entity.direction = new_direction
            npc.world_entity.set_not_moving()
            center_position = npc.world_entity.get_center_position()
            distance_from_enemy = 35
            projectile_pos = translate_in_direction(
                get_position_from_center_position(center_position,
                                                  PROJECTILE_SIZE),
                npc.world_entity.direction, distance_from_enemy)
            projectile_speed = 0.11
            projectile_entity = WorldEntity(projectile_pos, PROJECTILE_SIZE,
                                            PROJECTILE_SPRITE,
                                            npc.world_entity.direction,
                                            projectile_speed)
            projectile = Projectile(
                projectile_entity,
                create_projectile_controller(PROJECTILE_TYPE))
            game_state.projectile_entities.append(projectile)
            play_sound(SoundId.ENEMY_ATTACK_GOBLIN_WARLOCK)

    def _update_attack_interval(self):
        self._attack_interval = 500 + random.random() * 4500
예제 #9
0
class MeleeEnemyNpcMind(AbstractNpcMind):
    def __init__(self, global_path_finder: GlobalPathFinder,
                 attack_interval: Millis, damage_amount: int,
                 chance_to_stray_from_path: float,
                 update_path_interval: Millis):
        super().__init__(global_path_finder)
        self._base_attack_interval = attack_interval
        self._attack_interval = None
        self.randomize_attack_interval()
        self._time_since_attack = self._attack_interval
        self._update_path_interval = update_path_interval
        self._time_since_updated_path = self._update_path_interval
        self.pathfinder = NpcPathfinder(global_path_finder)
        self.next_waypoint = None
        self._reevaluate_next_waypoint_direction_interval = 1000
        self._time_since_reevaluated = self._reevaluate_next_waypoint_direction_interval
        self.damage_amount = damage_amount
        self.chance_to_stray_from_path = chance_to_stray_from_path
        self._is_in_melee_with_target = False

    def randomize_attack_interval(self):
        self._attack_interval = self._base_attack_interval + random.randint(
            -250, 250)

    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter,
                    player_entity: WorldEntity, is_player_invisible: bool,
                    time_passed: Millis):
        self._time_since_attack += time_passed
        self._time_since_updated_path += time_passed
        self._time_since_reevaluated += time_passed

        enemy_entity = npc.world_entity
        target: EnemyTarget = get_target(enemy_entity, game_state)

        if self._time_since_updated_path > self._update_path_interval:
            self._time_since_updated_path = 0
            if not is_player_invisible:
                self.pathfinder.update_path_towards_target(
                    enemy_entity, game_state, target.entity)

        new_next_waypoint = self.pathfinder.get_next_waypoint_along_path(
            enemy_entity)

        should_update_waypoint = self.next_waypoint != new_next_waypoint
        if self._time_since_reevaluated > self._reevaluate_next_waypoint_direction_interval:
            self._time_since_reevaluated = 0
            should_update_waypoint = True

        if should_update_waypoint:
            self.next_waypoint = new_next_waypoint
            if self.next_waypoint:
                direction = self.pathfinder.get_dir_towards_considering_collisions(
                    game_state, enemy_entity, self.next_waypoint)
                if random.random(
                ) < self.chance_to_stray_from_path and direction:
                    direction = random.choice(
                        get_perpendicular_directions(direction))
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        if self._time_since_attack > self._attack_interval:
            if not is_player_invisible:
                enemy_position = enemy_entity.get_center_position()
                target_center_pos = target.entity.get_center_position()
                if is_x_and_y_within_distance(enemy_position,
                                              target_center_pos, 80):
                    self._time_since_attack = 0
                    self.randomize_attack_interval()
                    deal_npc_damage(self.damage_amount, DamageType.PHYSICAL,
                                    game_state, enemy_entity, npc, target)