Example #1
0
def _generate_npc_4(x: int, y: int) -> Optional[NonPlayerCharacter]:
    valid_enemy_types = [
        NpcType.SKELETON_BOSS, NpcType.GOBLIN_WARRIOR, NpcType.WARRIOR_KING
    ]
    if random.random() < 0.3:
        npc_type = random.choice(valid_enemy_types)
        return create_npc(npc_type, (x, y))
Example #2
0
def _apply_scroll(game_state: GameState):
    player_entity = game_state.game_world.player_entity

    summon_size = NON_PLAYER_CHARACTERS[NpcType.PLAYER_SUMMON_DRAGON].size
    player_size = game_state.game_world.player_entity.pygame_collision_rect.w, game_state.game_world.player_entity.h
    candidate_relative_positions = [
        (0, - summon_size[1]),  # top
        (player_size[0], - summon_size[1]),  # top right
        (player_size[0], 0),  # right
        (player_size[0], player_size[1]),  # down right
        (0, player_size[1]),  # down
        (-summon_size[0], player_size[1]),  # down left
        (-summon_size[0], 0),  # left
        (-summon_size[0], -summon_size[1])  # top left
    ]
    for relative_pos in candidate_relative_positions:
        summon_pos = sum_of_vectors(player_entity.get_position(), relative_pos)
        summon = create_npc(NpcType.PLAYER_SUMMON_DRAGON, summon_pos)
        is_valid_pos = not game_state.game_world.would_entity_collide_if_new_pos(summon.world_entity, summon_pos)
        if is_valid_pos:
            game_state.game_world.remove_all_player_summons()
            game_state.game_world.add_non_player_character(summon)
            summon.gain_buff_effect(get_buff_effect(BuffType.SUMMON_DIE_AFTER_DURATION), DURATION_SUMMON)
            game_state.game_world.visual_effects.append(
                VisualCircle((200, 200, 30), player_entity.get_position(), 40, 70, Millis(140), 3))
            game_state.game_world.visual_effects.append(
                VisualCircle((200, 200, 30), summon_pos, 40, 70, Millis(140), 3))
            return ConsumableWasConsumed("Summoned dragon")
    return ConsumableFailedToBeConsumed("No space to summon dragon")
Example #3
0
def _generate_npc_3(x: int, y: int) -> Optional[NonPlayerCharacter]:
    valid_enemy_types = [
        NpcType.HUMAN_SUMMONER, NpcType.ICE_WITCH, NpcType.VETERAN
    ]
    if random.random() < 0.5:
        npc_type = random.choice(valid_enemy_types)
        return create_npc(npc_type, (x, y))
 def npc(npc_type: NpcType):
     entity = create_npc(npc_type, (0, 0)).world_entity
     e = MapEditorWorldEntity(
         entity.sprite,
         (entity.pygame_collision_rect.w, entity.pygame_collision_rect.h))
     e.npc_type = npc_type
     return e
Example #5
0
def _generate_npc_1(x: int, y: int) -> Optional[NonPlayerCharacter]:
    valid_enemy_types = [
        NpcType.GOBLIN_SPEARMAN_ELITE, NpcType.SKELETON_MAGE,
        NpcType.ZOMBIE_FAST, NpcType.NECROMANCER
    ]
    if random.random() < 0.3:
        npc_type = random.choice(valid_enemy_types)
        return create_npc(npc_type, (x, y))
Example #6
0
def _add_npc(npc_type, game_state: GameState, snapped_mouse_world_position):
    already_has_npc = any([
        x for x in game_state.non_player_characters
        if x.world_entity.get_position() == snapped_mouse_world_position
    ])
    if not already_has_npc:
        npc = create_npc(npc_type, snapped_mouse_world_position)
        game_state.add_non_player_character(npc)
Example #7
0
def generate_npc(x: int, y: int) -> Optional[NonPlayerCharacter]:
    npc_types = list(NpcType.__members__.values())
    valid_enemy_types = [
        npc_type for npc_type in npc_types
        if NON_PLAYER_CHARACTERS[npc_type].npc_category == NpcCategory.ENEMY
        and npc_type != NpcType.DARK_REAPER
    ]
    if random.random() < 0.2:
        npc_type = random.choice(valid_enemy_types)
        return create_npc(npc_type, (x, y))
Example #8
0
def generate_npcs(rooms: List[Rect], start_room: Rect):
    # TODO Check collisions, use more rules to spawn sensible enemy groups
    npcs = []
    npc_types = list(NpcType.__members__.values())
    valid_enemy_types = [
        npc_type for npc_type in npc_types
        if NON_PLAYER_CHARACTERS[npc_type].npc_category == NpcCategory.ENEMY
        and npc_type != NpcType.DARK_REAPER
    ]
    for room in [r for r in rooms if r != start_room]:
        xmid, ymid = get_room_center(room)
        distance = CELL_SIZE * 2
        for x in range(xmid - distance, xmid + distance * 2, distance):
            for y in range(ymid - distance, ymid + distance * 2, distance):
                if random.random() < 0.2:
                    npc_type = random.choice(valid_enemy_types)
                    npc = create_npc(npc_type, (x, y))
                    npcs.append(npc)
    return npcs
Example #9
0
 def deserialize(data) -> NonPlayerCharacter:
     return create_npc(NpcType[data["npc_type"]], data["position"])
    def control_npc(self, game_state: GameState, npc: NonPlayerCharacter, player_entity: WorldEntity,
                    _is_player_invisible: bool, time_passed: Millis):
        self._time_since_decision += time_passed
        self._time_since_summoning += time_passed
        self._time_since_healing += time_passed
        self._time_since_shoot += time_passed
        if self._time_since_summoning > self._summoning_cooldown:
            necro_center_pos = npc.world_entity.get_center_position()
            self._time_since_summoning = 0
            self._alive_summons = [summon for summon in self._alive_summons
                                   if summon in game_state.non_player_characters]
            if len(self._alive_summons) < 3:
                relative_pos_from_summoner = (random.randint(-150, 150), random.randint(-150, 150))
                summon_center_pos = sum_of_vectors(necro_center_pos, relative_pos_from_summoner)
                summon_type = random.choice([NpcType.ZOMBIE, NpcType.MUMMY])
                summon_size = NON_PLAYER_CHARACTERS[summon_type].size
                summon_pos = game_state.get_within_world(
                    get_position_from_center_position(summon_center_pos, summon_size), summon_size)
                summon_enemy = create_npc(summon_type, summon_pos)
                is_wall_blocking = game_state.walls_state.does_rect_intersect_with_wall(
                    rect_from_corners(necro_center_pos, summon_center_pos))
                is_position_blocked = game_state.would_entity_collide_if_new_pos(summon_enemy.world_entity, summon_pos)
                if not is_wall_blocking and not is_position_blocked:
                    self._summoning_cooldown = self._random_summoning_cooldown()
                    game_state.add_non_player_character(summon_enemy)
                    self._alive_summons.append(summon_enemy)
                    game_state.visual_effects.append(
                        VisualCircle((80, 150, 100), necro_center_pos, 40, 70, Millis(120), 3))
                    game_state.visual_effects.append(
                        VisualCircle((80, 150, 100), summon_center_pos, 40, 70, Millis(120), 3))
                    play_sound(SoundId.ENEMY_NECROMANCER_SUMMON)
                else:
                    # Failed to summon, so try again without waiting full duration
                    self._summoning_cooldown = 500
            else:
                self._summoning_cooldown = self._random_summoning_cooldown()

        if self._time_since_healing > self._healing_cooldown:
            self._time_since_healing = 0
            self._healing_cooldown = self._random_healing_cooldown()
            necro_center_pos = npc.world_entity.get_center_position()
            nearby_hurt_enemies = [
                e for e in game_state.non_player_characters
                if e.is_enemy
                   and is_x_and_y_within_distance(necro_center_pos, e.world_entity.get_center_position(), 200)
                   and e != npc and not e.health_resource.is_at_max()
            ]
            if nearby_hurt_enemies:
                healing_target = nearby_hurt_enemies[0]
                healing_target.health_resource.gain(5)
                healing_target_pos = healing_target.world_entity.get_center_position()
                visual_line = VisualLine((80, 200, 150), necro_center_pos, healing_target_pos, Millis(350), 3)
                game_state.visual_effects.append(visual_line)
                play_sound(SoundId.ENEMY_NECROMANCER_HEAL)

        if self._time_since_shoot > self._shoot_cooldown:
            self._time_since_shoot = 0
            self._shoot_cooldown = self._random_shoot_cooldown()
            npc.world_entity.direction = get_directions_to_position(npc.world_entity, player_entity.get_position())[0]
            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.2
            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.projectile_entities.append(projectile)
            play_sound(SoundId.ENEMY_ATTACK_NECRO)

        if self._time_since_decision > self._decision_interval:
            self._time_since_decision = 0
            if random.random() < 0.2:
                direction = random_direction()
                npc.world_entity.set_moving_in_dir(direction)
            else:
                npc.world_entity.set_not_moving()