예제 #1
0
 def apply_start_effect(self, game_state: GameState,
                        buffed_entity: WorldEntity,
                        buffed_npc: NonPlayerCharacter):
     buffed_npc.stun_status.add_one()
     buffed_entity.set_not_moving()
     game_state.visual_effects.append(
         create_visual_stun_text(buffed_entity))
예제 #2
0
    def update_path_towards_target(self, agent_entity: WorldEntity,
                                   game_state: GameState,
                                   target_entity: WorldEntity):
        agent_cell = _translate_world_position_to_cell(
            agent_entity.get_position(), game_state.entire_world_area)
        target_cell = _translate_world_position_to_cell(
            target_entity.get_position(), game_state.entire_world_area)

        agent_cell_size = (
            agent_entity.pygame_collision_rect.w // GRID_CELL_WIDTH + 1,
            agent_entity.pygame_collision_rect.h // GRID_CELL_WIDTH + 1)
        self.global_path_finder.register_entity_size(agent_cell_size)
        path_with_cells = self.global_path_finder.run(agent_cell_size,
                                                      agent_cell, target_cell)
        if path_with_cells:
            # Note: Cells are expressed in non-negative values (and need to be translated to game world coordinates)
            path = [
                _translate_cell_to_world_position(cell,
                                                  game_state.entire_world_area)
                for cell in path_with_cells
            ]
            if DEBUG_RENDER_PATHFINDING:
                _add_visual_lines_along_path(game_state, path)
            self.path = path
        else:
            self.path = None
예제 #3
0
 def apply_start_effect(self, game_state: GameState,
                        buffed_entity: WorldEntity,
                        buffed_npc: NonPlayerCharacter):
     visual_effect = VisualCircle((220, 220, 50),
                                  buffed_entity.get_center_position(), 9,
                                  16, Millis(250), 2)
     game_state.visual_effects.append(visual_effect)
     game_state.visual_effects.append(
         create_visual_stun_text(buffed_entity))
     buffed_npc.stun_status.add_one()
     buffed_entity.set_not_moving()
    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

        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)
                if random.random() < 0.5 and direction:
                    direction = random.choice(get_perpendicular_directions(direction))
                _move_in_dir(enemy_entity, direction)
            else:
                enemy_entity.set_not_moving()

        if self._time_since_attack > self._attack_interval:
            self._time_since_attack = 0
            self._update_attack_interval()
            directions_to_player = get_directions_to_position(npc.world_entity, player_entity.get_position())
            new_direction = directions_to_player[0]
            if random.random() < 0.3 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.11
            projectile_entity = WorldEntity(projectile_pos, PROJECTILE_SIZE, PROJECTILE_SPRITE,
                                            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_GOBLIN_WARLOCK)
예제 #5
0
    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_healing += time_passed
        self._time_since_shoot += time_passed
        if self._time_since_healing > self._healing_cooldown:
            self._time_since_healing = 0
            self._healing_cooldown = self._random_healing_cooldown()
            if not npc.health_resource.is_at_max():
                healing_amount = random.randint(10, 20)
                npc.health_resource.gain(healing_amount)
                circle_effect = VisualCircle(
                    (80, 200, 150), npc.world_entity.get_center_position(), 30,
                    50, Millis(350), 3)
                game_state.visual_effects.append(circle_effect)
                number_effect = create_visual_healing_text(
                    npc.world_entity, healing_amount)
                game_state.visual_effects.append(number_effect)
                play_sound(SoundId.ENEMY_SKELETON_MAGE_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_SKELETON_MAGE)

        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()
예제 #6
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.player_entity.set_not_moving()
     game_state.visual_effects += create_teleport_effects(
         buffed_entity.get_center_position())
     game_state.player_entity.visible = False
예제 #7
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)
예제 #8
0
def create_money_pile_on_ground(amount: int, pos: Tuple[int, int]) -> MoneyPileOnGround:
    if amount == 1:
        sprite = Sprite.COINS_1
    elif amount == 2:
        sprite = Sprite.COINS_2
    else:
        sprite = Sprite.COINS_5
    return MoneyPileOnGround(WorldEntity(pos, ITEM_ENTITY_SIZE, sprite), amount)
예제 #9
0
 def apply_middle_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.timer.update_and_check_if_ready(time_passed):
         deal_player_damage_to_enemy(game_state, buffed_npc, DAMAGE_PER_TICK, DamageType.PHYSICAL)
         if self.should_stun:
             effect_position = buffed_entity.get_center_position()
             game_state.visual_effects.append(
                 VisualRect((250, 250, 50), effect_position, 30, 40, Millis(100), 1, buffed_entity))
예제 #10
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)
예제 #11
0
def deal_npc_damage(damage_amount: float, damage_type: DamageType, game_state: GameState, attacker_entity: WorldEntity,
                    attacker_npc: NonPlayerCharacter, target: EnemyTarget):
    attacker_position = attacker_entity.get_center_position()
    game_state.visual_effects.append(
        VisualRect((200, 0, 0), attacker_position, 50, 50, Millis(200), 3, attacker_entity))
    if target.non_enemy_npc:
        deal_npc_damage_to_npc(game_state, target.non_enemy_npc, damage_amount)
    else:
        deal_damage_to_player(game_state, damage_amount, damage_type, attacker_npc)
예제 #12
0
 def apply_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.timer.update_and_check_if_ready(time_passed):
         visual_effect = VisualCircle((250, 150, 250),
                                      buffed_entity.get_center_position(),
                                      18, 25, Millis(220), 1, buffed_entity)
         game_state.visual_effects.append(visual_effect)
예제 #13
0
def _get_entity_text_positions(
        entity: WorldEntity, text_y_travel_distance: int
) -> Tuple[Tuple[int, int], Tuple[int, int]]:
    sprite_size = ENTITY_SPRITE_SIZES[entity.sprite]
    y_start = entity.y + entity.pygame_collision_rect.h - sprite_size[1]
    random_x_offset = random.randint(-10, 10)
    x = entity.get_center_position()[0] - 5 + random_x_offset
    start_position = (x, y_start)
    end_position = (x, y_start - text_y_travel_distance)
    return start_position, end_position
예제 #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]
예제 #15
0
 def apply_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     self._time_since_graphics += time_passed
     if self._time_since_graphics > 800:
         game_state.visual_effects.append(
             VisualRect((0, 100, 200), buffed_entity.get_center_position(),
                        50, 50, Millis(400), 1, buffed_entity))
         self._time_since_graphics = 0
예제 #16
0
 def apply_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.timer.update_and_check_if_ready(time_passed):
         deal_player_damage_to_enemy(game_state, buffed_npc, 1,
                                     DamageType.MAGIC)
         game_state.visual_effects.append(
             VisualCircle((0, 150, 0), buffed_entity.get_center_position(),
                          30, 55, Millis(150), 2, buffed_entity))
예제 #17
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_spawn_happened and self.time_since_start > DELAY / 2:
         self.has_spawn_happened = True
         game_state.visual_effects += create_teleport_effects(
             buffed_entity.get_center_position())
         play_sound(SoundId.ABILITY_TELEPORT)
예제 #18
0
 def apply_middle_effect(self, game_state: GameState, buffed_entity: WorldEntity, buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.timer.update_and_check_if_ready(time_passed):
         player_center_position = game_state.player_entity.get_center_position()
         projectile_pos = get_position_from_center_position(player_center_position, PROJECTILE_SIZE)
         entity = WorldEntity(projectile_pos, PROJECTILE_SIZE, Sprite.PROJECTILE_PLAYER_ARCANE_FIRE,
                              game_state.player_entity.direction, PROJECTILE_SPEED)
         projectile = Projectile(entity, create_projectile_controller(ProjectileType.PLAYER_ARCANE_FIRE))
         game_state.projectile_entities.append(projectile)
         game_state.visual_effects.append(VisualRect((250, 0, 250), player_center_position, 45, 60, Millis(250), 1))
예제 #19
0
    def render_world(self, all_entities_to_render: List[WorldEntity], decorations_to_render: List[DecorationEntity],
                     camera_world_area, non_player_characters: List[NonPlayerCharacter], is_player_invisible: bool,
                     player_active_buffs: List[BuffWithDuration],
                     player_entity: WorldEntity, visual_effects, render_hit_and_collision_boxes, player_health,
                     player_max_health, entire_world_area: Rect, entity_action_text: Optional[EntityActionText]):
        self.camera_world_area = camera_world_area

        self.screen_render.fill(COLOR_BACKGROUND)
        self._world_ground(entire_world_area)

        all_entities_to_render.sort(key=lambda entry: (-entry.view_z, entry.y))

        for decoration_entity in decorations_to_render:
            self._world_entity(decoration_entity)

        for entity in all_entities_to_render:
            self._world_entity(entity)
            if entity == player_entity and is_player_invisible:
                self.world_render.rect((200, 100, 250), player_entity.rect(), 2)

        player_sprite_y_relative_to_entity = \
            ENTITY_SPRITE_INITIALIZERS[player_entity.sprite][Direction.DOWN].position_relative_to_entity[1]
        if player_entity.visible:
            self._stat_bar_for_world_entity(player_entity, 5, player_sprite_y_relative_to_entity - 5,
                                            player_health / player_max_health, (100, 200, 0))

        # Buffs related to channeling something are rendered above player's head with progress from left to right
        for buff in player_active_buffs:
            if buff.buff_effect.get_buff_type() in CHANNELING_BUFFS:
                ratio = 1 - buff.get_ratio_duration_remaining()
                self._stat_bar_for_world_entity(player_entity, 3, player_sprite_y_relative_to_entity - 11, ratio,
                                                (150, 150, 250))

        if render_hit_and_collision_boxes:
            for entity in all_entities_to_render:
                # hit box
                self.world_render.rect((250, 250, 250), entity.rect(), 1)

        for npc in non_player_characters:
            healthbar_color = COLOR_RED if npc.is_enemy else (250, 250, 0)
            npc_sprite_y_relative_to_entity = \
                ENTITY_SPRITE_INITIALIZERS[npc.world_entity.sprite][Direction.DOWN].position_relative_to_entity[1]
            if not npc.is_neutral:
                self._stat_bar_for_world_entity(npc.world_entity, 3, npc_sprite_y_relative_to_entity - 5,
                                                npc.health_resource.get_partial(), healthbar_color)
            if npc.active_buffs:
                buff = npc.active_buffs[0]
                if buff.should_duration_be_visualized_on_enemies():
                    self._stat_bar_for_world_entity(npc.world_entity, 2, npc_sprite_y_relative_to_entity - 9,
                                                    buff.get_ratio_duration_remaining(), (250, 250, 250))
        for visual_effect in visual_effects:
            self._visual_effect(visual_effect)

        if entity_action_text:
            self._entity_action_text(entity_action_text)
 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_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.graphics_timer.update_and_check_if_ready(time_passed):
         position = buffed_entity.get_center_position()
         visual_effect1 = VisualCircle((0, 40, 100), position, 9, 16,
                                       Millis(400), 2, buffed_entity)
         visual_effect2 = VisualCircle((0, 90, 180), position, 9, 16,
                                       Millis(500), 2, buffed_entity)
         game_state.visual_effects.append(visual_effect1)
         game_state.visual_effects.append(visual_effect2)
예제 #22
0
 def apply_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis) -> bool:
     if self.timer.update_and_check_if_ready(time_passed):
         visual_effect = VisualCircle(
             (250, 250, 250), buffed_entity.get_center_position(),
             self.graphics_size, self.graphics_size + 10, Millis(70), 2,
             None)
         self.graphics_size -= 7
         game_state.visual_effects.append(visual_effect)
     return False
예제 #23
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
예제 #24
0
def get_target(agent_entity: WorldEntity, game_state: GameState) -> EnemyTarget:
    # Enemies should prioritize attacking a summon over attacking the player
    player_summons = [npc for npc in game_state.non_player_characters
                      if npc.npc_category == NpcCategory.PLAYER_SUMMON]
    if player_summons:
        player_summon = player_summons[0]
        agent_position = agent_entity.get_position()
        distance_to_npc_target = get_manhattan_distance(player_summon.world_entity.get_position(),
                                                        agent_position)
        distance_to_player = get_manhattan_distance(game_state.player_entity.get_position(), agent_position)
        if distance_to_npc_target < distance_to_player:
            return EnemyTarget.npc(player_summon.world_entity, player_summon)
    return EnemyTarget.player(game_state.player_entity)
예제 #25
0
    def handle_nearby_entities(self, player_entity: WorldEntity,
                               game_state: GameState, game_engine: GameEngine):
        self.entity_to_interact_with = None
        player_position = player_entity.get_position()
        distance_to_closest_entity = sys.maxsize

        for npc in game_state.non_player_characters:
            if has_npc_dialog(npc.npc_type):
                close_to_player = is_x_and_y_within_distance(
                    player_position, npc.world_entity.get_position(), 75)
                distance = get_manhattan_distance_between_rects(
                    player_entity.rect(), npc.world_entity.rect())
                if close_to_player and distance < distance_to_closest_entity:
                    self.entity_to_interact_with = npc
                    distance_to_closest_entity = distance

        lootables_on_ground: List[LootableOnGround] = list(
            game_state.items_on_ground)
        lootables_on_ground += game_state.consumables_on_ground
        for lootable in lootables_on_ground:
            if boxes_intersect(player_entity.rect(),
                               lootable.world_entity.rect()):
                self.entity_to_interact_with = lootable
                distance_to_closest_entity = 0

        for portal in game_state.portals:
            close_to_player = is_x_and_y_within_distance(
                player_position, portal.world_entity.get_position(), 75)
            distance = get_manhattan_distance_between_rects(
                player_entity.rect(), portal.world_entity.rect())
            if close_to_player:
                game_engine.handle_being_close_to_portal(portal)
            if close_to_player and distance < distance_to_closest_entity:
                self.entity_to_interact_with = portal
                distance_to_closest_entity = distance

        for warp_point in game_state.warp_points:
            close_to_player = is_x_and_y_within_distance(
                player_position, warp_point.world_entity.get_position(), 75)
            distance = get_manhattan_distance_between_rects(
                player_entity.rect(), warp_point.world_entity.rect())
            if close_to_player and distance < distance_to_closest_entity:
                self.entity_to_interact_with = warp_point
                distance_to_closest_entity = distance

        for chest in game_state.chests:
            close_to_player = is_x_and_y_within_distance(
                player_position, chest.world_entity.get_position(), 75)
            distance = get_manhattan_distance_between_rects(
                player_entity.rect(), chest.world_entity.rect())
            if close_to_player and distance < distance_to_closest_entity:
                self.entity_to_interact_with = chest
                distance_to_closest_entity = distance
예제 #26
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
예제 #27
0
 def apply_middle_effect(self, game_state: GameState,
                         buffed_entity: WorldEntity,
                         buffed_npc: NonPlayerCharacter,
                         time_passed: Millis):
     if self.dmg_timer.update_and_check_if_ready(time_passed):
         deal_player_damage_to_enemy(game_state,
                                     buffed_npc,
                                     1,
                                     DamageType.MAGIC,
                                     damage_source=DAMAGE_SOURCE)
     if self.graphics_timer.update_and_check_if_ready(time_passed):
         position = buffed_entity.get_center_position()
         visual_effect1 = VisualCircle((0, 100, 40), position, 9, 16,
                                       Millis(400), 2, buffed_entity)
         visual_effect2 = VisualCircle((0, 180, 90), position, 9, 16,
                                       Millis(500), 2, buffed_entity)
         game_state.visual_effects.append(visual_effect1)
         game_state.visual_effects.append(visual_effect2)
예제 #28
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity
    distance_from_player = 35
    projectile_pos = translate_in_direction(
        get_position_from_center_position(player_entity.get_center_position(),
                                          PROJECTILE_SIZE),
        player_entity.direction, distance_from_player)
    projectile_speed = 0.2
    entity = WorldEntity(projectile_pos, PROJECTILE_SIZE, PROJECTILE_SPRITE,
                         player_entity.direction, projectile_speed)
    projectile = Projectile(entity,
                            create_projectile_controller(PROJECTILE_TYPE))
    game_state.projectile_entities.append(projectile)
    effect_position = (projectile_pos[0] + PROJECTILE_SIZE[0] // 2,
                       projectile_pos[1] + PROJECTILE_SIZE[1] // 2)
    game_state.visual_effects.append(
        VisualCircle((250, 150, 50), effect_position, 9, 18, Millis(80), 0))
    return AbilityWasUsedSuccessfully()
예제 #29
0
    def get_next_waypoint_along_path(
            self, agent_entity: WorldEntity) -> Optional[Tuple[int, int]]:
        if self.path:
            # -----------------------------------------------
            # 1: Remove first waypoint if close enough to it
            # -----------------------------------------------
            # TODO: Does this cause problems for specific entity sizes / movement speeds?
            closeness_margin = 50
            if is_x_and_y_within_distance(agent_entity.get_position(),
                                          self.path[0], closeness_margin):
                # print("Popping " + str(self.path[0]) + " as I'm so close to it.")
                self.path.pop(0)
                if self.path:
                    # print("After popping, returning " + str(self.path[0]))
                    return self.path[0]
                else:
                    # print("no path after popping. stopping.")
                    return None

            # -----------------------------------------------
            # 2: Remove first waypoint if it's opposite direction of second waypoint
            # -----------------------------------------------
            if len(self.path) >= 2:
                dir_to_waypoint_0 = get_directions_to_position(
                    agent_entity, self.path[0])[0]
                dir_to_waypoint_1 = get_directions_to_position(
                    agent_entity, self.path[1])[0]
                if dir_to_waypoint_0 == get_opposite_direction(
                        dir_to_waypoint_1):
                    # print("Not gonna go back. Popping " + str(self.path[0]))
                    self.path.pop(0)
                    # print("Popped first position. Next waypoint: " + str(self.path[0]))
                    return self.path[0]
                if self.path:
                    return self.path[0]
        else:
            # print("no path found. stopping.")
            return None
        # print("Leaked through. returning none")
        return None
예제 #30
0
def _apply_ability(game_state: GameState) -> AbilityResult:
    player_entity = game_state.player_entity
    distance_from_player = 35
    projectile_pos = translate_in_direction(
        get_position_from_center_position(player_entity.get_center_position(),
                                          PROJECTILE_SIZE),
        player_entity.direction, distance_from_player)
    projectile_speed = 0.3
    entity = WorldEntity(projectile_pos, PROJECTILE_SIZE,
                         Sprite.PROJECTILE_PLAYER_FIREBALL,
                         player_entity.direction, projectile_speed)
    projectile = Projectile(
        entity, create_projectile_controller(ProjectileType.PLAYER_FIREBALL))
    game_state.projectile_entities.append(projectile)
    effect_position = (projectile_pos[0] + PROJECTILE_SIZE[0] // 2,
                       projectile_pos[1] + PROJECTILE_SIZE[1] // 2)
    game_state.visual_effects.append(
        VisualCircle((250, 150, 50), effect_position, 15, 5, Millis(300), 0))
    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()