Пример #1
0
    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter,
                    player_entity: WorldEntity, is_player_invisible: bool,
                    time_passed: Millis):

        if self.quest_timer.update_and_check_if_ready(time_passed):
            player_state = game_state.player_state
            if player_state.has_quest(QUEST_ID):
                if player_state.item_inventory.has_item_in_inventory(
                        item_id_key()):
                    npc.quest_giver_state = QuestGiverState.CAN_COMPLETE_QUEST
                else:
                    npc.quest_giver_state = QuestGiverState.WAITING_FOR_PLAYER
            elif player_state.has_completed_quest(QUEST_ID):
                npc.quest_giver_state = None
            elif _is_player_eligible_for_quest(game_state):
                npc.quest_giver_state = QuestGiverState.CAN_GIVE_NEW_QUEST
            else:
                npc.quest_giver_state = None

        if self.timer.update_and_check_if_ready(time_passed):
            if random.random() < 0.8:
                npc.world_entity.set_not_moving()
            else:
                direction = random.choice(get_all_directions())
                npc.world_entity.set_moving_in_dir(direction)
Пример #2
0
 def apply_player_summon_collision(self, npc: NonPlayerCharacter,
                                   game_state: GameState,
                                   projectile: Projectile):
     deal_npc_damage_to_npc(game_state, npc, 1)
     npc.gain_buff_effect(
         get_buff_effect(BuffType.ENEMY_GOBLIN_WARLOCK_BURNT), Millis(5000))
     game_state.visual_effects.append(
         VisualCircle((180, 50, 50), npc.world_entity.get_center_position(),
                      25, 50, Millis(100), 0))
     projectile.has_collided_and_should_be_removed = True
 def control_npc(self, game_state: GameState, npc: NonPlayerCharacter, player_entity: WorldEntity,
                 is_player_invisible: bool, time_passed: Millis):
     super().control_npc(game_state, npc, player_entity, is_player_invisible, time_passed)
     self.sprint_cooldown_remaining -= time_passed
     sprint_distance_limit = 250
     if self.sprint_cooldown_remaining <= 0:
         is_far_away = get_manhattan_distance(
             npc.world_entity.get_position(), player_entity.get_position()) > sprint_distance_limit
         if is_far_away:
             npc.gain_buff_effect(get_buff_effect(BuffType.ENEMY_GOBLIN_SPEARMAN_SPRINT), Millis(2500))
             self.sprint_cooldown_remaining = self.random_cooldown()
 def apply_enemy_collision(self, npc: NonPlayerCharacter, game_state: GameState, projectile: Projectile):
     damage_was_dealt = deal_player_damage_to_enemy(game_state, npc, 1, DamageType.MAGIC)
     if damage_was_dealt:
         npc.gain_buff_effect(get_buff_effect(BUFF_TYPE), DEBUFF_DURATION)
         victim_center_pos = npc.world_entity.get_center_position()
         visual_effect_pos = (victim_center_pos[0] - ENTANGLING_ROOTS_SIZE[0] // 2,
                              victim_center_pos[1] - ENTANGLING_ROOTS_SIZE[1] // 2)
         debuff_visual_effect = VisualSprite(Sprite.DECORATION_ENTANGLING_ROOTS_EFFECT, visual_effect_pos,
                                             DEBUFF_DURATION, npc.world_entity)
         game_state.game_world.visual_effects.append(debuff_visual_effect)
         play_sound(SoundId.ABILITY_ENTANGLING_ROOTS_HIT)
     projectile.has_collided_and_should_be_removed = True
Пример #5
0
 def apply_enemy_collision(self, npc: NonPlayerCharacter,
                           game_state: GameState, projectile: Projectile):
     damage_amount: float = MIN_DMG + random.random() * (MAX_DMG - MIN_DMG)
     deal_player_damage_to_enemy(game_state, npc, damage_amount,
                                 DamageType.MAGIC)
     _create_visual_splash(npc.world_entity.get_center_position(),
                           game_state)
     has_burn_upgrade = game_state.player_state.has_upgrade(
         HeroUpgradeId.ABILITY_FIREBALL_BURN)
     if has_burn_upgrade:
         npc.gain_buff_effect(get_buff_effect(BUFF_TYPE),
                              FIREBALL_TALENT_BURN_DURATION)
     play_sound(SoundId.ABILITY_FIREBALL_HIT)
     projectile.has_collided_and_should_be_removed = True
Пример #6
0
def create_npc(npc_type: NpcType, pos: Tuple[int, int]) -> NonPlayerCharacter:
    data: NpcData = NON_PLAYER_CHARACTERS[npc_type]
    entity = WorldEntity(pos, data.size, data.sprite, Direction.LEFT, data.speed)
    npc_mind = create_npc_mind(npc_type, global_path_finder)
    health_resource = HealthOrManaResource(data.max_health, data.health_regen)
    return NonPlayerCharacter(npc_type, entity, health_resource, npc_mind,
                              data.npc_category, data.enemy_loot_table, data.death_sound_id,
                              data.max_distance_allowed_from_start_position, is_boss=data.is_boss)
Пример #7
0
    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
        super().control_npc(game_state, npc, player_entity, is_player_invisible, time_passed)

        self._time_since_state_change += time_passed

        if self._state == State.BASE:
            if self._time_since_state_change > NpcMind.STATE_DURATION_BASE:
                self._time_since_state_change -= NpcMind.STATE_DURATION_BASE
                self._state = State.FIRING

                npc.gain_buff_effect(get_buff_effect(BUFF_STUNNED),
                                     Millis(NpcMind.STATE_DURATION_FIRING))
                return
        elif self._state == State.FIRING:
            if self._time_since_state_change > NpcMind.STATE_DURATION_FIRING:
                self._time_since_state_change -= NpcMind.STATE_DURATION_FIRING
                self._state = State.BASE
                return
            self._time_since_fired += time_passed
            if self._time_since_fired > NpcMind.FIRE_COOLDOWN:
                self._time_since_fired -= NpcMind.FIRE_COOLDOWN
                directions_to_player = get_directions_to_position(npc.world_entity, player_entity.get_position())
                new_direction = directions_to_player[0]
                if random.random() < 0.1 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.3
                projectile_entity = WorldEntity(projectile_pos, PROJECTILE_SIZE, Sprite.NONE,
                                                npc.world_entity.direction, projectile_speed)
                projectile = Projectile(projectile_entity, create_projectile_controller(PROJECTILE_TYPE))
                game_state.game_world.projectile_entities.append(projectile)
                play_sound(SoundId.ENEMY_MAGIC_SKELETON_BOSS)
Пример #8
0
    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))
Пример #9
0
 def apply_end_effect(self, game_state: GameState,
                      buffed_entity: WorldEntity,
                      buffed_npc: NonPlayerCharacter):
     buffed_npc.invulnerable = False