Exemple #1
0
def _apply_scroll(game_state: GameState):
    player_entity = game_state.player_entity

    summon_size = NON_PLAYER_CHARACTERS[NpcType.PLAYER_SUMMON_DRAGON].size
    player_size = game_state.player_entity.pygame_collision_rect.w, game_state.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.would_entity_collide_if_new_pos(summon.world_entity, summon_pos)
        if is_valid_pos:
            game_state.remove_all_player_summons()
            game_state.add_non_player_character(summon)
            summon.gain_buff_effect(get_buff_effect(BuffType.SUMMON_DIE_AFTER_DURATION), DURATION_SUMMON)
            game_state.visual_effects.append(
                VisualCircle((200, 200, 30), player_entity.get_position(), 40, 70, Millis(140), 3))
            game_state.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")
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity
    rect_w = 28
    slash_center_pos = translate_in_direction(
        player_entity.get_center_position(), player_entity.direction,
        rect_w / 2 + PLAYER_ENTITY_SIZE[0] * 0.25)
    slash_rect = Rect(int(slash_center_pos[0] - rect_w / 2),
                      int(slash_center_pos[1] - rect_w / 2), rect_w, rect_w)
    affected_enemies = game_state.get_enemy_intersecting_rect(slash_rect)
    if not affected_enemies:
        return AbilityFailedToExecute(reason="No targets")

    # Note: Dependency on other ability 'stealth'
    should_stun = game_state.player_state.has_active_buff(BuffType.STEALTHING)
    if should_stun:
        game_state.camera_shake = CameraShake(Millis(50), Millis(150), 4)
    buff_effect = get_buff_effect(DEBUFF, should_stun)
    affected_enemies[0].gain_buff_effect(buff_effect, DEBUFF_DURATION)

    game_state.visual_effects.append(
        VisualRect((150, 150, 75), slash_center_pos, rect_w, int(rect_w * 0.7),
                   Millis(200), 2, None))
    game_state.visual_effects.append(
        VisualCross((100, 100, 70), slash_center_pos, 6, Millis(100), 2))
    game_state.player_state.gain_buff_effect(
        get_buff_effect(BuffType.RECOVERING_AFTER_ABILITY), Millis(250))
    return AbilityWasUsedSuccessfully()
Exemple #3
0
 def apply_end_effect(self, game_state: GameState,
                      buffed_entity: WorldEntity,
                      buffed_npc: NonPlayerCharacter):
     game_state.player_state.stun_status.remove_one()
     hero_center_pos = game_state.player_entity.get_center_position()
     distance = 80
     affected_enemies = game_state.get_enemies_within_x_y_distance_of(
         distance, hero_center_pos)
     game_state.visual_effects.append(
         VisualRect((50, 50, 50), hero_center_pos, distance * 2,
                    int(distance * 2.1), Millis(200), 2, None))
     game_state.visual_effects.append(
         VisualRect((150, 150, 0), hero_center_pos, distance, distance * 2,
                    Millis(150), 3, None))
     game_state.visual_effects.append(
         VisualRect((250, 250, 0), hero_center_pos, distance, distance * 2,
                    Millis(100), 4, None))
     for enemy in affected_enemies:
         damage: float = MIN_DMG + random.random() * (MAX_DMG - MIN_DMG)
         deal_player_damage_to_enemy(game_state, enemy, damage,
                                     DamageType.PHYSICAL)
         enemy.gain_buff_effect(get_buff_effect(STUNNED_BY_STOMP),
                                STUN_DURATION)
     game_state.player_state.gain_buff_effect(
         get_buff_effect(BuffType.RECOVERING_AFTER_ABILITY), Millis(300))
     play_sound(SoundId.ABILITY_STOMP_HIT)
     game_state.camera_shake = CameraShake(Millis(50), Millis(200), 12)
Exemple #4
0
 def apply_start_effect(self, game_state: GameState,
                        buffed_entity: WorldEntity,
                        buffed_npc: NonPlayerCharacter):
     game_state.player_state.stun_status.add_one()
     game_state.modify_hero_stat(HeroStat.MOVEMENT_SPEED,
                                 BONUS_SPEED_MULTIPLIER)
     game_state.game_world.player_entity.set_moving_in_dir(
         game_state.game_world.player_entity.direction)
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)
Exemple #6
0
def _would_collide_with_dir(direction: Direction, agent_entity: WorldEntity,
                            game_state: GameState):
    # TODO Is this too naive to work?
    future_time = Millis(100)
    future_pos = agent_entity.get_new_position_according_to_other_dir_and_speed(
        direction, future_time)
    future_pos_within_world = game_state.get_within_world(
        future_pos, (agent_entity.pygame_collision_rect.w,
                     agent_entity.pygame_collision_rect.h))
    would_collide = game_state.would_entity_collide_if_new_pos(
        agent_entity, future_pos_within_world)
    return would_collide
Exemple #7
0
 def _set_game_world(self, game_world: GameWorldState,
                     player_spawn_position: Tuple[int, int]):
     enabled_portals = {
         portal.portal_id: portal.world_entity.sprite
         for portal in game_world.portals if portal.is_enabled
     }
     player_state = create_player_state_as_initial(HERO_ID, enabled_portals)
     self.game_state = GameState(game_world, CAMERA_SIZE, player_state,
                                 False, player_spawn_position)
     self.game_state.game_world.player_entity = create_hero_world_entity(
         HERO_ID, player_spawn_position)
     self.game_state.center_camera_on_position(player_spawn_position)
     self.game_state.snap_camera_to_grid(self.grid_cell_size)
     if self.ui_view:  # UI view may not have been created yet at this time
         self._notify_ui_of_new_wall_positions()
Exemple #8
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity
    rect_w = 28
    slash_center_pos = translate_in_direction(
        player_entity.get_center_position(), player_entity.direction,
        rect_w / 2 + PLAYER_ENTITY_SIZE[0] * 0.25)

    slash_rect = Rect(int(slash_center_pos[0] - rect_w / 2),
                      int(slash_center_pos[1] - rect_w / 2), rect_w, rect_w)
    affected_enemies = game_state.get_enemy_intersecting_rect(slash_rect)
    is_stealthed = game_state.player_state.has_active_buff(BuffType.STEALTHING)
    if is_stealthed:
        play_sound(SoundId.ABILITY_SHIV_STEALTHED)
    else:
        play_sound(SoundId.ABILITY_SHIV)
    for enemy in affected_enemies:
        damage: float = MIN_DMG + random.random() * (MAX_DMG - MIN_DMG)

        # Note: Dependency on other ability 'stealth'
        if is_stealthed:
            # Talent: increase the damage bonus that Shiv gets from being used while stealthing
            has_damage_upgrade = game_state.player_state.has_upgrade(
                HeroUpgradeId.ABILITY_SHIV_SNEAK_BONUS_DAMAGE)
            damage *= SHIV_UPGRADED_STEALTH_DAMAGE_MULTIPLIER if has_damage_upgrade else SHIV_STEALTH_DAMAGE_MULTIPLIER
            game_state.camera_shake = CameraShake(Millis(50), Millis(150), 4)
        else:
            # Talent: if attacking an enemy that's at 100% health while not stealthing, deal bonus damage
            has_damage_upgrade = game_state.player_state.has_upgrade(
                HeroUpgradeId.ABILITY_SHIV_FULL_HEALTH_BONUS_DAMAGE)
            if has_damage_upgrade and enemy.health_resource.is_at_max():
                damage *= SHIV_TALENT_FULL_HEALTH_DAMAGE_MULTIPLIER

        deal_player_damage_to_enemy(game_state,
                                    enemy,
                                    damage,
                                    DamageType.PHYSICAL,
                                    visual_emphasis=is_stealthed)
        break

    game_state.visual_effects.append(
        VisualRect((150, 150, 75), slash_center_pos, rect_w, int(rect_w * 0.7),
                   Millis(200), 2, None))
    game_state.visual_effects.append(
        VisualCross((100, 100, 70), slash_center_pos, 6, Millis(100), 2))

    game_state.player_state.gain_buff_effect(
        get_buff_effect(BuffType.RECOVERING_AFTER_ABILITY), Millis(250))
    return AbilityWasUsedSuccessfully()
Exemple #9
0
def create_dungeon_game_state(player_state: PlayerState,
                              camera_size: Tuple[int, int],
                              difficulty_level: int) -> GameState:
    dungeon = _generate_dungeon(difficulty_level)
    player_entity = create_hero_world_entity(player_state.hero_id,
                                             dungeon.player_position)
    game_world = GameWorldState(
        player_entity=player_entity,
        non_player_characters=dungeon.npcs,
        consumables_on_ground=[],
        items_on_ground=[],
        money_piles_on_ground=[],
        walls=dungeon.walls,
        entire_world_area=dungeon.world_area,
        decoration_entities=dungeon.decorations,
        portals=[],
        chests=[],
        shrines=[],
        dungeon_entrances=[],
    )
    return GameState(game_world=game_world,
                     camera_size=camera_size,
                     player_state=player_state,
                     is_dungeon=True,
                     player_spawn_position=dungeon.player_position)
Exemple #10
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity
    rect_w = 36
    # Note: We assume that this ability is used by this specific hero
    hero_entity_size = HEROES[HeroId.WARRIOR].entity_size
    slash_pos = translate_in_direction(player_entity.get_center_position(),
                                       player_entity.direction,
                                       rect_w / 2 + hero_entity_size[0] * 0.25)

    slash_rect = Rect(int(slash_pos[0] - rect_w / 2),
                      int(slash_pos[1] - rect_w / 2), rect_w, rect_w)
    affected_enemies = game_state.get_enemy_intersecting_rect(slash_rect)
    has_aoe_upgrade = game_state.player_state.has_upgrade(
        HeroUpgradeId.ABILITY_SLASH_AOE_BONUS_DAMAGE)
    hit_multiple_enemies = len(affected_enemies) > 1
    for enemy in affected_enemies:
        if has_aoe_upgrade and hit_multiple_enemies:
            damage: float = MAX_DMG
        else:
            damage: float = MIN_DMG + random.random() * (MAX_DMG - MIN_DMG)
        deal_player_damage_to_enemy(game_state, enemy, damage,
                                    DamageType.PHYSICAL)

    game_state.visual_effects.append(
        VisualRect((100, 0, 0), slash_pos, rect_w, int(rect_w * 0.7),
                   Millis(200), 2, None))
    game_state.player_state.gain_buff_effect(
        get_buff_effect(BuffType.RECOVERING_AFTER_ABILITY), Millis(300))
    return AbilityWasUsedSuccessfully()
Exemple #11
0
 def deserialize(data, player_state: PlayerState,
                 camera_size: Tuple[int, int]) -> GameState:
     return GameState(
         player_entity=PlayerJson.deserialize(player_state.hero_id,
                                              data["player"]),
         consumables_on_ground=[
             ConsumableJson.deserialize(p)
             for p in data.get("consumables_on_ground", [])
         ],
         items_on_ground=[
             ItemJson.deserialize(i)
             for i in data.get("items_on_ground", [])
         ],
         money_piles_on_ground=[
             MoneyJson.deserialize(p)
             for p in data.get("money_piles_on_ground", [])
         ],
         non_player_characters=[
             NpcJson.deserialize(e)
             for e in data.get("non_player_characters", [])
         ],
         walls=[WallJson.deserialize(w) for w in data.get("walls", [])],
         camera_size=camera_size,
         entire_world_area=WorldAreaJson.deserialize(
             data["entire_world_area"]),
         player_state=player_state,
         decoration_entities=[
             DecorationJson.deserialize(d)
             for d in data.get("decorations", [])
         ],
         portals=[
             PortalJson.deserialize(p) for p in data.get("portals", [])
         ],
         chests=[ChestJson.deserialize(c) for c in data.get("chests", [])])
Exemple #12
0
    def apply_middle_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter,
                            time_passed: Millis) -> Optional[bool]:

        self.time_since_start += time_passed

        charger_center_pos = buffed_entity.get_center_position()

        if self.graphics_timer.update_and_check_if_ready(time_passed):
            visual_circle = VisualCircle((250, 250, 250), charger_center_pos, 15, 25, Millis(120), 2, None)
            game_state.visual_effects.append(visual_circle)

        rect_w = 32
        # NOTE: We assume that this ability is used by this specific hero
        hero_entity_size = HEROES[HeroId.WARRIOR].entity_size
        impact_pos = translate_in_direction(
            charger_center_pos, buffed_entity.direction, rect_w / 2 + hero_entity_size[0] / 2)

        impact_rect = Rect(int(impact_pos[0] - rect_w / 2), int(impact_pos[1] - rect_w / 2), rect_w, rect_w)
        affected_enemies = game_state.get_enemy_intersecting_rect(impact_rect)
        for enemy in affected_enemies:
            visual_impact_pos = get_middle_point(charger_center_pos, enemy.world_entity.get_center_position())
            damage = MIN_DMG
            # Talent: Apply damage bonus even if using charge in melee range
            has_melee_upgrade = game_state.player_state.has_upgrade(HeroUpgradeId.ABILITY_CHARGE_MELEE)
            damage_increased = self.time_since_start > float(CHARGE_DURATION) * 0.3 or has_melee_upgrade
            if damage_increased:
                # TODO Stun target as a bonus here
                damage = MAX_DMG
            deal_player_damage_to_enemy(game_state, enemy, damage, DamageType.PHYSICAL,
                                        visual_emphasis=damage_increased)
            game_state.visual_effects.append(
                VisualRect((250, 170, 0), visual_impact_pos, 45, 25, IMPACT_STUN_DURATION, 2, None))
            game_state.visual_effects.append(
                VisualRect((150, 0, 0), visual_impact_pos, 35, 20, IMPACT_STUN_DURATION, 2, None))
            game_state.player_state.gain_buff_effect(get_buff_effect(BUFF_TYPE_STUNNED), IMPACT_STUN_DURATION)
            enemy.gain_buff_effect(get_buff_effect(BUFF_TYPE_STUNNED), IMPACT_STUN_DURATION)
            game_state.camera_shake = CameraShake(Millis(50), Millis(150), 12)
            play_sound(SoundId.ABILITY_CHARGE_HIT)
            has_stomp_cooldown_upgrade = game_state.player_state.has_upgrade(
                HeroUpgradeId.ABILITY_CHARGE_RESET_STOMP_COOLDOWN)
            if has_stomp_cooldown_upgrade:
                game_state.player_state.set_ability_cooldown_to_zero(AbilityType.STOMP)
            # The buff should end upon impact
            return True
        return False
Exemple #13
0
 def apply_middle_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     self.time_since_start += time_passed
     if not self.has_teleport_happened and self.time_since_start > PORTAL_DELAY / 2:
         self.has_teleport_happened = True
         game_state.warp_points = []
         game_state.player_entity.set_position(self.destination)
         game_state.visual_effects += create_teleport_effects(buffed_entity.get_center_position())
         play_sound(SoundId.WARP)
Exemple #14
0
 def apply_start_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter):
     game_state.player_state.stun_status.add_one()
     player_entity = game_state.player_entity
     player_entity.set_not_moving()
     player_entity.visible = False
     game_state.visual_effects += create_teleport_effects(buffed_entity.get_center_position())
     player_collision_rect = (player_entity.pygame_collision_rect.w, player_entity.pygame_collision_rect.h)
     home_warp_point = create_warp_point(game_state.player_spawn_position, player_collision_rect)
     remote_warp_point = create_warp_point(player_entity.get_center_position(), player_collision_rect)
     game_state.warp_points = [home_warp_point, remote_warp_point]
Exemple #15
0
    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.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.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.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.visual_effects.append(
                    VisualLine((220, 0, 0), summon_entity.get_center_position(),
                               target.world_entity.get_center_position(), Millis(100), damage_amount))
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.game_world.player_entity
    previous_position = player_entity.get_center_position()

    used_from_stealth = game_state.player_state.has_active_buff(
        BuffType.STEALTHING)

    for distance in range(40, 200, 10):
        new_position = translate_in_direction(
            (player_entity.x, player_entity.y), player_entity.direction,
            distance)
        if game_state.game_world.is_position_within_game_world(new_position) \
                and not game_state.game_world.would_entity_collide_if_new_pos(player_entity, new_position):
            if _would_collide_with_wall(game_state, player_entity, distance):
                return AbilityFailedToExecute(reason="Wall is blocking")
            should_regain_mana_and_cd = False
            enemy_hit = _get_enemy_that_was_hit(game_state, player_entity,
                                                distance)
            if enemy_hit:
                game_state.camera_shake = CameraShake(Millis(50), Millis(150),
                                                      4)
                deal_player_damage_to_enemy(game_state, enemy_hit, DAMAGE,
                                            DamageType.MAGIC)
                has_reset_upgrade = game_state.player_state.has_upgrade(
                    HeroUpgradeId.ABILITY_DASH_KILL_RESET)
                enemy_died = enemy_hit.health_resource.is_at_or_below_zero()
                if has_reset_upgrade and enemy_died:
                    should_regain_mana_and_cd = True

            player_entity.set_position(new_position)
            new_center_position = player_entity.get_center_position()
            color = (250, 140, 80)
            game_state.game_world.visual_effects.append(
                VisualCircle(color, previous_position, 17, 35, Millis(150), 1))
            game_state.game_world.visual_effects.append(
                VisualLine(color, previous_position, new_center_position,
                           Millis(250), 2))
            game_state.game_world.visual_effects.append(
                VisualRect(color, previous_position, 37, 46, Millis(150), 1))
            game_state.game_world.visual_effects.append(
                VisualCircle(color, new_center_position, 25, 40, Millis(300),
                             1, player_entity))
            has_speed_upgrade = game_state.player_state.has_upgrade(
                HeroUpgradeId.ABILITY_DASH_MOVEMENT_SPEED)
            if has_speed_upgrade:
                game_state.player_state.gain_buff_effect(
                    get_buff_effect(BUFF_SPEED), BUFF_SPEED_DURATION)
            if used_from_stealth:
                game_state.player_state.gain_buff_effect(
                    get_buff_effect(BUFF_FROM_STEALTH),
                    BUFF_FROM_STEALTH_DURATION)
            return AbilityWasUsedSuccessfully(
                should_regain_mana_and_cd=should_regain_mana_and_cd)
    return AbilityFailedToExecute(reason="No space")
Exemple #17
0
def register_game_state_observers(game_state: GameState, ui_view: GameUiView, include_player_state: bool):
    game_state.game_world.player_movement_speed_was_updated.register_observer(ui_view.on_player_movement_speed_updated)
    game_state.game_world.notify_movement_speed_observers()  # Must notify the initial state
    game_state.game_world.player_entity.movement_changed = Observable()
    game_state.game_world.player_entity.movement_changed.register_observer(play_or_stop_footstep_sounds)
    game_state.game_world.player_entity.position_changed = Observable()
    game_state.game_world.player_entity.position_changed.register_observer(ui_view.on_player_position_updated)
    game_state.game_world.player_entity.position_changed.register_observer(
        lambda _: ui_view.on_walls_seen([w.get_position() for w in game_state.get_walls_in_sight_of_player()]))
    game_state.game_world.player_entity.notify_position_observers()  # Must notify the initial state

    if include_player_state:
        _register_player_state_observers(game_state.player_state, ui_view)
Exemple #18
0
def _get_enemy_that_was_hit(game_state: GameState, player_entity: WorldEntity, distance_jumped: int) \
        -> Optional[NonPlayerCharacter]:
    previous_position = (player_entity.x, player_entity.y)
    partial_distance = 10
    while partial_distance < distance_jumped:
        intermediate_position = translate_in_direction(previous_position, player_entity.direction, partial_distance)
        enemies_hit = game_state.get_enemy_intersecting_rect(
            Rect(intermediate_position[0], intermediate_position[1], player_entity.pygame_collision_rect.w,
                 player_entity.pygame_collision_rect.h))
        if enemies_hit:
            return enemies_hit[0]
        partial_distance += 10
    return None
Exemple #19
0
    def deserialize(data, player_state: PlayerState,
                    camera_size: Tuple[int, int]) -> MapData:
        game_state = GameState(
            player_entity=PlayerJson.deserialize(player_state.hero_id,
                                                 data["player"]),
            consumables_on_ground=[
                ConsumableJson.deserialize(p)
                for p in data.get("consumables_on_ground", [])
            ],
            items_on_ground=[
                ItemJson.deserialize(i)
                for i in data.get("items_on_ground", [])
            ],
            money_piles_on_ground=[
                MoneyJson.deserialize(p)
                for p in data.get("money_piles_on_ground", [])
            ],
            non_player_characters=[
                NpcJson.deserialize(e)
                for e in data.get("non_player_characters", [])
            ],
            walls=[WallJson.deserialize(w) for w in data.get("walls", [])],
            camera_size=camera_size,
            entire_world_area=WorldAreaJson.deserialize(
                data["entire_world_area"]),
            player_state=player_state,
            decoration_entities=[
                DecorationJson.deserialize(d)
                for d in data.get("decorations", [])
            ],
            portals=[
                PortalJson.deserialize(p) for p in data.get("portals", [])
            ],
            chests=[ChestJson.deserialize(c) for c in data.get("chests", [])],
            shrines=[
                ShrineJson.deserialize(s) for s in data.get("shrines", [])
            ])

        map_editor_config = MapEditorConfig(
            disable_smart_grid=data.get("disable_smart_grid", False))
        grid_string = data.get("grid", None)

        return MapData(game_state, map_editor_config, grid_string)
 def apply_middle_effect(self, game_state: GameState, time_passed: Millis):
     if self.timer.update_and_check_if_ready(time_passed):
         player_entity = game_state.player_entity
         player_center_position = player_entity.get_center_position()
         close_enemies = game_state.get_enemies_within_x_y_distance_of(
             140, player_center_position)
         if close_enemies:
             damage_amount: float = self.min_dmg + random.random() * (
                 self.max_dmg - self.min_dmg)
             deal_player_damage_to_enemy(game_state, close_enemies[0],
                                         damage_amount, DamageType.MAGIC)
             enemy_center_position = close_enemies[
                 0].world_entity.get_center_position()
             game_state.visual_effects.append(
                 VisualCircle((250, 250, 0), player_center_position, 50,
                              140, Millis(100), 1, player_entity))
             game_state.visual_effects.append(
                 VisualLine((250, 250, 0), player_center_position,
                            enemy_center_position, Millis(80), 3))
Exemple #21
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity

    player_center_pos = player_entity.get_center_position()
    game_state.visual_effects.append(
        VisualCircle((150, 150, 250), player_center_pos, 95, 190, Millis(200),
                     3))
    affected_enemies = game_state.get_enemies_within_x_y_distance_of(
        180, player_center_pos)
    effect_position = get_position_from_center_position(
        player_center_pos, EFFECT_SPRITE_SIZE)
    game_state.visual_effects.append(
        VisualSprite(Sprite.EFFECT_ABILITY_FROST_NOVA, effect_position,
                     Millis(200), player_entity))
    for enemy in affected_enemies:
        damage_was_dealt = deal_player_damage_to_enemy(game_state, enemy, 5,
                                                       DamageType.MAGIC)
        if damage_was_dealt:
            enemy.gain_buff_effect(
                get_buff_effect(BuffType.REDUCED_MOVEMENT_SPEED), Millis(4000))
    return AbilityWasUsedSuccessfully()
Exemple #22
0
 def apply_end_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter):
     game_state.player_state.stun_status.remove_one()
     game_state.modify_hero_stat(HeroStat.MOVEMENT_SPEED, -BONUS_SPEED_MULTIPLIER)
Exemple #23
0
def _upgrade_mana_regen(game_state: GameState):
    game_state.modify_hero_stat(HeroStat.MANA_REGEN, 0.5)
 def apply_start_effect(self, game_state: GameState,
                        buffed_entity: WorldEntity,
                        buffed_npc: NonPlayerCharacter):
     game_state.player_state.stun_status.add_one()
     game_state.game_world.player_entity.set_not_moving()
     game_state.camera_shake = CameraShake(Millis(50), CHANNEL_DURATION, 5)
Exemple #25
0
 def apply_end_effect(self, game_state: GameState):
     for modifier in self.stat_modifiers:
         game_state.modify_hero_stat(modifier.hero_stat, -modifier.delta)
 def apply_end_effect(self, game_state: GameState):
     for stat, delta in self.stat_modifiers.items():
         game_state.modify_hero_stat(stat, -delta)
    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()
Exemple #28
0
 def apply(self, game_state: GameState):
     game_state.modify_hero_stat(self.hero_stat, self.amount)
Exemple #29
0
 def revert(self, game_state: GameState):
     game_state.modify_hero_stat(self.hero_stat, -self.amount)
Exemple #30
0
 def apply_end_effect(self, game_state: GameState,
                      buffed_entity: WorldEntity,
                      buffed_npc: NonPlayerCharacter):
     for stat, delta in self.stat_modifiers.items():
         game_state.modify_hero_stat(stat, -delta)