From befc6bbe9259b93076dc2e8e6fde75a6e0de68c0 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 20 Sep 2025 20:48:08 -0400 Subject: [PATCH] Updated level creation documentation. Fixed a couple bugs in weapon overrides. --- levels/README.md | 27 +++++++++++++++++++++++++++ src/level.py | 32 +++++++++++++++++++++----------- src/player.py | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/levels/README.md b/levels/README.md index 6b19d1a..1d8ed29 100644 --- a/levels/README.md +++ b/levels/README.md @@ -422,6 +422,33 @@ Override weapon sounds and names globally for an entire level: - `attack_sound`: Sound played when attacking - `hit_sound`: Sound played when hitting an enemy +**Weapon Override Persistence:** +Weapon overrides set in **level 1** automatically persist throughout the entire level pack! You only need to define `weapon_sound_overrides` in your first level (1.json) and all subsequent levels will inherit these themed weapon names. + +```json +// In levels/Wicked Christmas/1.json - Sets theme for entire pack +{ + "level_id": 1, + "weapon_sound_overrides": { + "rusty_shovel": { "name": "rusty snow shovel" }, + "witch_broom": { "name": "decorated witch's broom" }, + "nunchucks": { "name": "candy cane nunchucks" } + } +} + +// In levels/Wicked Christmas/2.json - No overrides needed! +{ + "level_id": 2, + // Weapons automatically use themed names from level 1 +} +``` + +**How it works:** +- Level 1 overrides persist across all levels in the same play session +- Switching to a different level pack resets weapons to their original names +- Later levels can still override weapons if you want to change themes mid-pack +- The system stores the original weapon names internally for proper lookups + #### Object Sound Overrides Override sounds for individual objects in your level: diff --git a/src/level.py b/src/level.py index fdc7428..8f34519 100644 --- a/src/level.py +++ b/src/level.py @@ -41,9 +41,12 @@ class Level: # Pass footstep sound to player self.player.set_footstep_sound(self.footstepSound) - # Apply weapon sound overrides if specified - if "weapon_sound_overrides" in levelData: - self._apply_weapon_overrides(levelData["weapon_sound_overrides"]) + # Store and apply weapon sound overrides if specified + self.weaponOverrides = levelData.get("weapon_sound_overrides", {}) + if self.weaponOverrides: + self._apply_weapon_overrides(self.weaponOverrides) + # Give player access to overrides for newly added weapons + self.player.set_weapon_overrides(self.weaponOverrides) # Level intro message (skip for survival mode) if levelData["level_id"] != 999: # 999 is survival mode @@ -578,19 +581,26 @@ class Level: def _apply_weapon_overrides(self, weaponOverrides): """Apply sound and name overrides to player weapons based on level pack theme.""" for weapon in self.player.weapons: - if weapon.name in weaponOverrides: - overrides = weaponOverrides[weapon.name] + # Check if weapon needs override (use originalName if available, fallback to current name) + weaponKey = getattr(weapon, 'originalName', weapon.name) - # Override weapon name if specified - if "name" in overrides: + if weaponKey in weaponOverrides: + overrides = weaponOverrides[weaponKey] + + # Store original name on first override to enable future lookups + if not hasattr(weapon, 'originalName'): + weapon.originalName = weapon.name + + # Override weapon name if specified and different from current + if "name" in overrides and weapon.name != overrides["name"]: weapon.name = overrides["name"] - # Override attack sound if specified - if "attack_sound" in overrides: + # Override attack sound if specified and different from current + if "attack_sound" in overrides and hasattr(weapon, 'attackSound') and weapon.attackSound != overrides["attack_sound"]: weapon.attackSound = overrides["attack_sound"] - # Override hit sound if specified - if "hit_sound" in overrides: + # Override hit sound if specified and different from current + if "hit_sound" in overrides and hasattr(weapon, 'hitSound') and weapon.hitSound != overrides["hit_sound"]: weapon.hitSound = overrides["hit_sound"] def _apply_object_sound_overrides(self, obj, soundOverrides): diff --git a/src/player.py b/src/player.py index 34a3278..7d9b017 100644 --- a/src/player.py +++ b/src/player.py @@ -62,6 +62,9 @@ class Player: # Death state tracking (to prevent revival after death in same frame) self.diedThisFrame = False + # Weapon override storage + self.weaponOverrides = {} + # Initialize starting weapon (rusty shovel) self.add_weapon( Weapon( @@ -270,6 +273,9 @@ class Player: def add_weapon(self, weapon): """Add a new weapon to inventory and equip if first weapon""" + # Apply weapon overrides if they exist + self._apply_weapon_override(weapon) + self.weapons.append(weapon) if len(self.weapons) == 1: # If this is our first weapon, equip it self.equip_weapon(weapon) @@ -289,7 +295,9 @@ class Player: # Find the weapon in player's inventory for weapon in self.weapons: - if weapon.originalName == targetWeaponName: + # Check original name if it exists, fallback to current name + weaponKey = getattr(weapon, 'originalName', weapon.name) + if weaponKey == targetWeaponName: self.equip_weapon(weapon) speak(weapon.name.replace("_", " ")) return True @@ -297,6 +305,37 @@ class Player: # Weapon not found in inventory return False + def set_weapon_overrides(self, weaponOverrides): + """Store weapon overrides for applying to newly added weapons""" + self.weaponOverrides = weaponOverrides + + def _apply_weapon_override(self, weapon): + """Apply weapon overrides to a single weapon""" + if not hasattr(self, 'weaponOverrides') or not self.weaponOverrides: + return + + # Check if weapon needs override (use originalName if available, fallback to current name) + weaponKey = getattr(weapon, 'originalName', weapon.name) + + if weaponKey in self.weaponOverrides: + overrides = self.weaponOverrides[weaponKey] + + # Store original name on first override to enable future lookups + if not hasattr(weapon, 'originalName'): + weapon.originalName = weapon.name + + # Override weapon name if specified and different from current + if "name" in overrides and weapon.name != overrides["name"]: + weapon.name = overrides["name"] + + # Override attack sound if specified and different from current + if "attack_sound" in overrides and hasattr(weapon, 'attackSound') and weapon.attackSound != overrides["attack_sound"]: + weapon.attackSound = overrides["attack_sound"] + + # Override hit sound if specified and different from current + if "hit_sound" in overrides and hasattr(weapon, 'hitSound') and weapon.hitSound != overrides["hit_sound"]: + weapon.hitSound = overrides["hit_sound"] + def add_item(self, item): """Add an item to inventory""" self.inventory.append(item)