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()
예제 #2
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()
예제 #3
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
예제 #4
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()
예제 #5
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