コード例 #1
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)
コード例 #2
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.game_world.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.game_world.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.game_world.visual_effects.append(
        VisualRect((150, 150, 75), slash_center_pos, rect_w, int(rect_w * 0.7),
                   Millis(200), 2, None))
    game_state.game_world.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()
コード例 #3
0
def _get_random() -> Tuple[AbstractBuffEffect, str]:
    return random.choice([
        (get_buff_effect(BUFF_DAMAGE),
         "You feel powerful! (Damage increased)"),
        (get_buff_effect(BUFF_ARMOR), "You feel protected! (Armor increased)"),
        (get_buff_effect(BUFF_MAGIC_RESIST),
         "You feel the spirits' presence! (Resistance increased)"),
        (get_buff_effect(BUFF_MOVE_SPEED), "You feel swift! (Speed increased)")
    ])
コード例 #4
0
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")
コード例 #5
0
def _apply(game_state: GameState):
    player_state = game_state.player_state
    if not (player_state.health_resource.is_at_max() and player_state.mana_resource.is_at_max()):
        player_state.gain_buff_effect(get_buff_effect(BUFF_TYPE), BUFF_DURATION)
        return ConsumableWasConsumed()
    else:
        return ConsumableFailedToBeConsumed("Already at full health and mana!")
コード例 #6
0
 def item_handle_event(self, event: Event, game_state: GameState):
     if isinstance(event, PlayerDamagedEnemy):
         if random.random() < PROC_CHANCE:
             # Compare "source" to prevent the debuff from renewing itself indefinitely
             if event.damage_source != DAMAGE_SOURCE:
                 event.enemy_npc.gain_buff_effect(
                     get_buff_effect(BUFF_TYPE), Millis(6000))
コード例 #7
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")
コード例 #8
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_state = game_state.player_state
    if player_state.health_resource.value <= ABILITY_HEALTH_LOSS:
        return AbilityFailedToExecute("Using this would kill you!")
    player_state.health_resource.lose(ABILITY_HEALTH_LOSS)
    player_state.gain_buff_effect(get_buff_effect(BUFF_TYPE), DURATION)
    return AbilityWasUsedSuccessfully()
コード例 #9
0
 def apply_player_collision(self, game_state: GameState, projectile: Projectile):
     deal_damage_to_player(game_state, 1, DamageType.MAGIC, None)
     game_state.player_state.gain_buff_effect(get_buff_effect(BuffType.ENEMY_GOBLIN_WARLOCK_BURNT), Millis(5000))
     game_state.game_world.visual_effects.append(
         VisualCircle((180, 50, 50), game_state.game_world.player_entity.get_center_position(),
                      25, 50, Millis(100), 0))
     projectile.has_collided_and_should_be_removed = True
コード例 #10
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.game_world.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.game_world.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.game_world.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()
コード例 #11
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
        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.game_world.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))
                    ]
                    chance_to_resist_slow = game_state.player_state.get_effective_movement_impairing_resist_chance(
                    )
                    # TODO It's error-prone that we have to check this for every negative debuff that can slow player
                    if random.random() > chance_to_resist_slow:
                        game_state.player_state.gain_buff_effect(
                            get_buff_effect(SLOW_BUFF_TYPE), Millis(1500))
コード例 #12
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    game_state.player_state.force_cancel_all_buffs()
    has_speed_upgrade = game_state.player_state.has_upgrade(
        HeroUpgradeId.ABILITY_STEALTH_MOVEMENT_SPEED)
    speed_decrease = MOVEMENT_SPEED_DECREASE if not has_speed_upgrade else 0
    game_state.player_state.gain_buff_effect(
        get_buff_effect(BUFF_STEALTH, speed_decrease), DURATION_STEALTH)
    return AbilityWasUsedSuccessfully()
コード例 #13
0
 def on_startup(self, new_hero_was_created: bool):
     self.game_state.player_state.gain_buff_effect(
         get_buff_effect(BuffType.BEING_SPAWNED), Millis(1000))
     self.ui_view.info_message.set_message(
         "Fight through all enemies to get out!")
     self.ui_view.update_game_mode_string(
         "Dungeon %i" %
         self.game_state.player_state.dungeon_difficulty_level)
コード例 #14
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
コード例 #15
0
def _apply(game_state: GameState):
    # TODO Verify that the destination is clear from collisions
    destination = translate_in_direction(game_state.player_spawn_position,
                                         Direction.DOWN, 50)
    teleport_buff_effect: AbstractBuffEffect = get_buff_effect(
        BuffType.TELEPORTING_WITH_WARP_STONE, destination)
    game_state.player_state.gain_buff_effect(teleport_buff_effect,
                                             PORTAL_DELAY)
    return ConsumableWasConsumed()
コード例 #16
0
 def use_warp_point(self, warp_point: WarpPoint):
     destination_warp_point = [
         w for w in self.game_state.warp_points if w != warp_point
     ][0]
     # It's safe to teleport to warp point's position as hero and warp point entities are the exact same size
     teleport_buff_effect: AbstractBuffEffect = get_buff_effect(
         BuffType.TELEPORTING_WITH_WARP_POINT,
         destination_warp_point.world_entity.get_position())
     self.game_state.player_state.gain_buff_effect(teleport_buff_effect,
                                                   PORTAL_DELAY)
コード例 #17
0
 def handle_event(self, event: EngineEvent) -> Optional[SceneTransition]:
     if event == EngineEvent.PLAYER_DIED:
         self.game_state.player_entity.set_position(self.game_state.player_spawn_position)
         self.game_state.player_state.health_resource.set_to_partial_of_max(0.5)
         self.game_state.player_state.lose_exp_from_death()
         self.game_state.player_state.force_cancel_all_buffs()
         self.info_message.set_message("Lost exp from dying")
         play_sound(SoundId.EVENT_PLAYER_DIED)
         self.game_state.player_state.gain_buff_effect(get_buff_effect(BuffType.BEING_SPAWNED), Millis(1000))
     return None
コード例 #18
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
コード例 #19
0
 def on_startup(self, new_hero_was_created: bool):
     self.game_state.player_state.gain_buff_effect(get_buff_effect(BuffType.BEING_SPAWNED), Millis(1000))
     self.info_message.set_message("Hint: " + get_random_hint())
     if new_hero_was_created:
         self.game_state.player_state.consumable_inventory.add_consumable(ConsumableType.HEALTH_LESSER)
         self.game_state.player_state.consumable_inventory.add_consumable(ConsumableType.HEALTH_LESSER)
         self.game_state.player_state.consumable_inventory.add_consumable(ConsumableType.MANA_LESSER)
         self.game_state.player_state.consumable_inventory.add_consumable(ConsumableType.MANA_LESSER)
         for item_type in HEROES[self.game_state.player_state.hero_id].initial_player_state.starting_items:
             self.add_starting_item(item_type)
コード例 #20
0
 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()
コード例 #21
0
 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
コード例 #22
0
def _apply(game_state: GameState):
    pos = game_state.game_world.player_entity.get_center_position()
    effect1 = VisualCircle((100, 150, 100), pos, 40, 120, Millis(2200), 2)
    effect2 = VisualCircle((100, 150, 100), pos, 40, 130, Millis(2000), 1)
    game_state.game_world.visual_effects += [effect1, effect2]

    affected_enemies = game_state.game_world.get_enemies_within_x_y_distance_of(
        120, pos)
    for enemy in affected_enemies:
        enemy.gain_buff_effect(get_buff_effect(BUFF_TYPE), DEBUFF_DURATION)

    return ConsumableWasConsumed()
コード例 #23
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
コード例 #24
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    hero_center_pos = game_state.game_world.player_entity.get_center_position()
    distance = 60
    affected_enemies = game_state.game_world.get_enemies_within_x_y_distance_of(
        distance, hero_center_pos)
    game_state.game_world.visual_effects.append(
        VisualRect((50, 50, 100), hero_center_pos, distance * 2,
                   int(distance * 2.1), Millis(200), 2, None))
    game_state.game_world.visual_effects.append(
        VisualRect((150, 150, 200), hero_center_pos, distance, distance * 2,
                   Millis(150), 3, None))
    for enemy in affected_enemies:
        enemy.gain_buff_effect(get_buff_effect(BUFF_TYPE_STUNNED),
                               STUN_DURATION)
    return AbilityWasUsedSuccessfully()
コード例 #25
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()
コード例 #26
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.game_world.player_entity

    player_center_pos = player_entity.get_center_position()
    game_state.game_world.visual_effects.append(
        VisualCircle((150, 150, 250), player_center_pos, 95, 190, Millis(200), 3))
    affected_enemies = game_state.game_world.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.game_world.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()
コード例 #27
0
 def interact_with_portal(self, portal: Portal):
     if portal.is_enabled:
         destination_portal = [
             p for p in self.game_state.portals
             if p.portal_id == portal.leads_to
         ][0]
         destination_portal.activate(portal.world_entity.sprite)
         destination = translate_in_direction(
             destination_portal.world_entity.get_position(), Direction.DOWN,
             50)
         teleport_buff_effect: AbstractBuffEffect = get_buff_effect(
             BuffType.TELEPORTING_WITH_PORTAL, destination)
         delay = PORTALS[portal.portal_id].teleport_delay
         self.game_state.player_state.gain_buff_effect(
             teleport_buff_effect, delay)
     else:
         self.info_message.set_message("Hmm... Looks suspicious!")
コード例 #28
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.game_world.player_entity
    aoe_center_pos = translate_in_direction(
        player_entity.get_center_position(), player_entity.direction, 60)
    aoe_pos = get_position_from_center_position(aoe_center_pos,
                                                PROJECTILE_SIZE)
    projectile_speed = 0.1
    entity = WorldEntity(aoe_pos, PROJECTILE_SIZE, PROJECTILE_SPRITE,
                         player_entity.direction, projectile_speed)
    projectile = Projectile(entity,
                            create_projectile_controller(PROJECTILE_TYPE))
    game_state.game_world.projectile_entities.append(projectile)
    has_lightfooted_upgrade = game_state.player_state.has_upgrade(
        HeroUpgradeId.MAGE_LIGHT_FOOTED)
    if not has_lightfooted_upgrade:
        game_state.player_state.gain_buff_effect(
            get_buff_effect(BuffType.RECOVERING_AFTER_ABILITY), Millis(300))
    return AbilityWasUsedSuccessfully()
コード例 #29
0
    def on_startup(self, new_hero_was_created: bool):
        self.game_state.player_state.gain_buff_effect(get_buff_effect(BuffType.BEING_SPAWNED), Millis(1000))
        self.info_message.set_message("Challenge starting...")
        if new_hero_was_created:
            self.game_state.player_state.modify_money(100)
            self.game_engine.gain_levels(4)

            consumables = [ConsumableType.HEALTH,
                           ConsumableType.HEALTH,
                           ConsumableType.MANA,
                           ConsumableType.MANA,
                           ConsumableType.SPEED,
                           ConsumableType.POWER]
            for consumable_type in consumables:
                self.game_state.player_state.consumable_inventory.add_consumable(consumable_type)
            items = [ItemType.LEATHER_COWL, ItemType.LEATHER_ARMOR, ItemType.WOODEN_SWORD, ItemType.WOODEN_SHIELD]
            for item_type in items:
                self._equip_item_on_startup(item_type)
コード例 #30
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)