diff --git a/worlds/apquest/client/ap_quest_client.py b/worlds/apquest/client/ap_quest_client.py index bd67cc55ca..e875da7b68 100644 --- a/worlds/apquest/client/ap_quest_client.py +++ b/worlds/apquest/client/ap_quest_client.py @@ -198,7 +198,7 @@ class APQuestContext(CommonContext): if self.ap_quest_game is None: raise RuntimeError("Tried to render before self.ap_quest_game was initialized.") - self.ui.render(self.ap_quest_game, self.player_sprite) + self.ui.render(self.ap_quest_game, self.player_sprite, self.hard_mode) self.handle_game_events() def location_checked_side_effects(self, location: int) -> None: diff --git a/worlds/apquest/client/game_manager.py b/worlds/apquest/client/game_manager.py index ed2793da36..7d40a36ee3 100644 --- a/worlds/apquest/client/game_manager.py +++ b/worlds/apquest/client/game_manager.py @@ -88,23 +88,23 @@ class APQuestManager(GameManager): self.game_view.force_focus() self.sound_manager.game_started = True - def render(self, game: Game, player_sprite: PlayerSprite) -> None: + def render(self, game: Game, player_sprite: PlayerSprite, hard_mode: bool) -> None: self.setup_game_grid_if_not_setup(game) # This calls game.render(), which needs to happen to update the state of math traps - self.render_gameboard(game, player_sprite) + self.render_gameboard(game, player_sprite, hard_mode) # Only now can we check whether a math problem is active self.render_background_game_grid(game.gameboard.size, game.active_math_problem is None) self.sound_manager.math_trap_active = game.active_math_problem is not None self.render_item_column(game) - def render_gameboard(self, game: Game, player_sprite: PlayerSprite) -> None: + def render_gameboard(self, game: Game, player_sprite: PlayerSprite, hard_mode: bool) -> None: rendered_gameboard = game.render() for gameboard_row, image_row in zip(rendered_gameboard, self.top_image_grid, strict=False): for graphic, image in zip(gameboard_row, image_row[:11], strict=False): - texture = get_texture(graphic, player_sprite) + texture = get_texture(graphic, player_sprite, hard_mode) if texture is None: image.opacity = 0 diff --git a/worlds/apquest/client/graphics.py b/worlds/apquest/client/graphics.py index 0e31218c6f..9acf7c9987 100644 --- a/worlds/apquest/client/graphics.py +++ b/worlds/apquest/client/graphics.py @@ -29,6 +29,7 @@ class RelatedTexture(NamedTuple): IMAGE_GRAPHICS: dict[Graphic, str | RelatedTexture] = { + # Inanimates Graphic.WALL: RelatedTexture("inanimates.png", 16, 32, 16, 16), Graphic.BREAKABLE_BLOCK: RelatedTexture("inanimates.png", 32, 32, 16, 16), Graphic.CHEST: RelatedTexture("inanimates.png", 0, 16, 16, 16), @@ -37,29 +38,25 @@ IMAGE_GRAPHICS: dict[Graphic, str | RelatedTexture] = { Graphic.BUTTON_NOT_ACTIVATED: RelatedTexture("inanimates.png", 0, 0, 16, 16), Graphic.BUTTON_ACTIVATED: RelatedTexture("inanimates.png", 16, 0, 16, 16), Graphic.BUTTON_DOOR: RelatedTexture("inanimates.png", 32, 0, 16, 16), - + # Enemies Graphic.NORMAL_ENEMY_1_HEALTH: RelatedTexture("normal_enemy.png", 0, 0, 16, 16), Graphic.NORMAL_ENEMY_2_HEALTH: RelatedTexture("normal_enemy.png", 16, 0, 16, 16), - Graphic.BOSS_5_HEALTH: RelatedTexture("boss.png", 16, 16, 16, 16), Graphic.BOSS_4_HEALTH: RelatedTexture("boss.png", 0, 16, 16, 16), Graphic.BOSS_3_HEALTH: RelatedTexture("boss.png", 32, 32, 16, 16), Graphic.BOSS_2_HEALTH: RelatedTexture("boss.png", 16, 32, 16, 16), Graphic.BOSS_1_HEALTH: RelatedTexture("boss.png", 0, 32, 16, 16), - + # Items Graphic.EMPTY_HEART: RelatedTexture("hearts.png", 0, 0, 16, 16), Graphic.HEART: RelatedTexture("hearts.png", 16, 0, 16, 16), Graphic.HALF_HEART: RelatedTexture("hearts.png", 32, 0, 16, 16), - Graphic.REMOTE_ITEM: RelatedTexture("items.png", 0, 16, 16, 16), Graphic.CONFETTI_CANNON: RelatedTexture("items.png", 16, 16, 16, 16), Graphic.HAMMER: RelatedTexture("items.png", 32, 16, 16, 16), Graphic.KEY: RelatedTexture("items.png", 0, 0, 16, 16), Graphic.SHIELD: RelatedTexture("items.png", 16, 0, 16, 16), Graphic.SWORD: RelatedTexture("items.png", 32, 0, 16, 16), - - Graphic.ITEMS_TEXT: "items_text.png", - + # Numbers Graphic.ZERO: RelatedTexture("numbers.png", 0, 16, 16, 16), Graphic.ONE: RelatedTexture("numbers.png", 16, 16, 16, 16), Graphic.TWO: RelatedTexture("numbers.png", 32, 16, 16, 16), @@ -70,26 +67,29 @@ IMAGE_GRAPHICS: dict[Graphic, str | RelatedTexture] = { Graphic.SEVEN: RelatedTexture("numbers.png", 32, 0, 16, 16), Graphic.EIGHT: RelatedTexture("numbers.png", 48, 0, 16, 16), Graphic.NINE: RelatedTexture("numbers.png", 64, 0, 16, 16), - + # Letters Graphic.LETTER_A: RelatedTexture("letters.png", 0, 16, 16, 16), Graphic.LETTER_E: RelatedTexture("letters.png", 16, 16, 16, 16), Graphic.LETTER_H: RelatedTexture("letters.png", 32, 16, 16, 16), Graphic.LETTER_I: RelatedTexture("letters.png", 0, 0, 16, 16), Graphic.LETTER_M: RelatedTexture("letters.png", 16, 0, 16, 16), Graphic.LETTER_T: RelatedTexture("letters.png", 32, 0, 16, 16), - + # Mathematical symbols Graphic.DIVIDE: RelatedTexture("symbols.png", 0, 16, 16, 16), Graphic.EQUALS: RelatedTexture("symbols.png", 16, 16, 16, 16), Graphic.MINUS: RelatedTexture("symbols.png", 32, 16, 16, 16), Graphic.PLUS: RelatedTexture("symbols.png", 0, 0, 16, 16), Graphic.TIMES: RelatedTexture("symbols.png", 16, 0, 16, 16), + # Other visual-only elements + Graphic.ITEMS_TEXT: "items_text.png", Graphic.NO: RelatedTexture("symbols.png", 32, 0, 16, 16), - Graphic.UNKNOWN: RelatedTexture("symbols.png", 32, 0, 16, 16), # Same as "No" } BACKGROUND_TILE = RelatedTexture("inanimates.png", 0, 32, 16, 16) +EASY_MODE_BOSS_2_HEALTH = RelatedTexture("boss.png", 16, 0, 16, 16) + class PlayerSprite(Enum): HUMAN = 0 @@ -160,13 +160,18 @@ def get_texture_by_identifier(texture_identifier: str | RelatedTexture) -> Textu return sub_texture -def get_texture(graphic: Graphic | Literal["Grass"], player_sprite: PlayerSprite | None = None) -> Texture | None: +def get_texture( + graphic: Graphic | Literal["Grass"], player_sprite: PlayerSprite | None = None, hard_mode: bool = False +) -> Texture | None: if graphic == Graphic.EMPTY: return None if graphic == "Grass": return get_texture_by_identifier(BACKGROUND_TILE) + if graphic == Graphic.BOSS_2_HEALTH and not hard_mode: + return get_texture_by_identifier(EASY_MODE_BOSS_2_HEALTH) + if graphic in IMAGE_GRAPHICS: return get_texture_by_identifier(IMAGE_GRAPHICS[graphic]) diff --git a/worlds/apquest/game/gameboard.py b/worlds/apquest/game/gameboard.py index 77688c2929..e034b3f71c 100644 --- a/worlds/apquest/game/gameboard.py +++ b/worlds/apquest/game/gameboard.py @@ -246,7 +246,7 @@ def create_gameboard(hard_mode: bool, hammer_exists: bool, extra_chest: bool) -> breakable_block = BreakableBlock() if hammer_exists else Empty() normal_enemy = EnemyWithLoot(2 if hard_mode else 1, Location.ENEMY_DROP) - boss = FinalBoss(5 if hard_mode else 3) + boss = FinalBoss(5 if hard_mode else 2) gameboard = ( (Empty(), Empty(), Empty(), Wall(), Empty(), Empty(), Empty(), Wall(), Empty(), Empty(), Empty()), diff --git a/worlds/apquest/game/graphics/boss.png b/worlds/apquest/game/graphics/boss.png index dbcda31048..07a9af35c0 100644 Binary files a/worlds/apquest/game/graphics/boss.png and b/worlds/apquest/game/graphics/boss.png differ