diff --git a/src/YodaStoriesNG.Engine/Game/GameEngine.cs b/src/YodaStoriesNG.Engine/Game/GameEngine.cs index 4a40020..aa19a26 100644 --- a/src/YodaStoriesNG.Engine/Game/GameEngine.cs +++ b/src/YodaStoriesNG.Engine/Game/GameEngine.cs @@ -53,6 +53,34 @@ public unsafe class GameEngine : IDisposable /// public bool IsBotRunning => _bot?.IsRunning ?? false; + // Weapon tile constants for 15-mission progression + private const int TILE_BASIC_LIGHTSABER = 18; // Starting weapon + private const int TILE_UPGRADED_LIGHTSABER = 510; // After 5 missions + private const int TILE_THE_FORCE = 511; // After 10 missions + + /// + /// Gets the appropriate weapon for the player's mission count. + /// + private static int GetWeaponForMissionCount(int missionsCompleted) + { + if (missionsCompleted >= 10) return TILE_THE_FORCE; + if (missionsCompleted >= 5) return TILE_UPGRADED_LIGHTSABER; + return TILE_BASIC_LIGHTSABER; + } + + /// + /// Upgrades the player's weapon, replacing the old one. + /// + private void UpgradeWeapon(int newWeaponTile) + { + // Remove old weapons and add the new one + _state.Weapons.Clear(); + _state.Weapons.Add(newWeaponTile); + _state.CurrentWeaponIndex = 0; + _state.SelectedWeapon = newWeaponTile; + Console.WriteLine($"[Weapon] Upgraded to tile {newWeaponTile}"); + } + public GameEngine(string dataPath) { _dataPath = dataPath; @@ -410,11 +438,14 @@ public unsafe class GameEngine : IDisposable if (_actionExecutor != null) _actionExecutor.SuppressDialogue = true; - // Give player starting weapon - lightsaber is always available at game start - const int LIGHTSABER_TILE = 510; // Lightsaber tile at atlas position 1291x338 - _state.Weapons.Add(LIGHTSABER_TILE); + // Give player starting weapon based on missions completed + // Tile 18 = Basic lightsaber (start) + // Tile 510 = Upgraded lightsaber (after 5 missions) + // Tile 511 = The Force (after 10 missions) + int startingWeapon = GetWeaponForMissionCount(_state.GamesWon); + _state.Weapons.Add(startingWeapon); _state.CurrentWeaponIndex = 0; - _state.SelectedWeapon = LIGHTSABER_TILE; + _state.SelectedWeapon = startingWeapon; // Generate the world with selected size _worldGenerator = new WorldGenerator(_gameData!); @@ -2264,12 +2295,42 @@ public unsafe class GameEngine : IDisposable // Check if mission is complete if (mission != null && mission.IsCompleted) { - // Mission complete! Congratulate the player + // Mission complete! Increment counter _state.GamesWon++; - _state.IsGameWon = true; - _messages.ShowDialogue("Yoda", $"Completed the mission, you have! Strong with the Force, you are. {_state.GamesWon} missions completed."); - _messages.ShowMessage("YOU WIN! Press R to start a new mission.", MessageType.System); _sounds?.PlaySound(SoundManager.SoundPickup); + + // Check for 15-mission cycle milestones + if (_state.GamesWon >= 15) + { + // All 15 missions complete! Show victory screen + _state.IsGameWon = true; + _messages.ShowDialogue("Yoda", "A true Jedi, you have become! All 15 missions completed. Proud of you, I am."); + _messages.ShowMessage("CONGRATULATIONS! You've completed all 15 missions!", MessageType.System); + _messages.ShowMessage("Press R to start a new 15-mission cycle.", MessageType.Info); + } + else if (_state.GamesWon == 10) + { + // Give The Force upgrade at mission 10 + UpgradeWeapon(TILE_THE_FORCE); + _messages.ShowDialogue("Yoda", "Completed 10 missions, you have! Master of the Force, you are becoming. This power, I give to you."); + _messages.ShowMessage("Received: The Force! You can now attack from a distance.", MessageType.Pickup); + _messages.ShowMessage($"Mission {_state.GamesWon}/15 complete. Press R to continue.", MessageType.System); + } + else if (_state.GamesWon == 5) + { + // Give upgraded lightsaber at mission 5 + UpgradeWeapon(TILE_UPGRADED_LIGHTSABER); + _messages.ShowDialogue("Yoda", "Completed 5 missions, you have! Growing stronger, you are. A better lightsaber, you have earned."); + _messages.ShowMessage("Received: Upgraded Lightsaber!", MessageType.Pickup); + _messages.ShowMessage($"Mission {_state.GamesWon}/15 complete. Press R to continue.", MessageType.System); + } + else + { + // Regular mission complete + _messages.ShowDialogue("Yoda", $"Completed the mission, you have! Strong with the Force, you are. {_state.GamesWon}/15 missions completed."); + _messages.ShowMessage($"Mission {_state.GamesWon}/15 complete. Press R to continue.", MessageType.System); + } + _state.IsGameWon = true; // Allows pressing R to restart } // Give the starting item if player doesn't have it yet else if (world.StartingItemId.HasValue && !_state.HasItem(world.StartingItemId.Value)) @@ -2347,15 +2408,23 @@ public unsafe class GameEngine : IDisposable private void PerformAttack() { // Determine weapon type - bool isRangedWeapon = false; - if (_state.SelectedWeapon.HasValue && _state.SelectedWeapon.Value > 0 && - _state.SelectedWeapon.Value < _gameData!.Tiles.Count) + bool isRanged = false; + if (_state.SelectedWeapon.HasValue && _state.SelectedWeapon.Value > 0) { - var weaponTile = _gameData.Tiles[_state.SelectedWeapon.Value]; - isRangedWeapon = (weaponTile.Flags & (TileFlags.WeaponLightBlaster | TileFlags.WeaponHeavyBlaster)) != 0; + // Check if it's The Force (special ranged weapon) + if (_state.SelectedWeapon.Value == TILE_THE_FORCE) + { + isRanged = true; + } + // Check tile flags for blasters + else if (_state.SelectedWeapon.Value < _gameData!.Tiles.Count) + { + var weaponTile = _gameData.Tiles[_state.SelectedWeapon.Value]; + isRanged = (weaponTile.Flags & (TileFlags.WeaponLightBlaster | TileFlags.WeaponHeavyBlaster)) != 0; + } } - if (isRangedWeapon) + if (isRanged) { // Ranged attack - spawn projectile PerformRangedAttack(); @@ -3601,11 +3670,22 @@ public unsafe class GameEngine : IDisposable private int GetWeaponCharacterIndex(int weaponTileId) { // Map weapon tile IDs to character indices - // These are approximate - weapons are stored as characters 9-14 - if (weaponTileId == 510) return 14; // Lightsaber -> Character 14 "Light Saber" + // Lightsabers use Character 14 "Light Saber" for attack animation + if (weaponTileId == TILE_BASIC_LIGHTSABER) return 14; // Basic lightsaber (tile 18) + if (weaponTileId == TILE_UPGRADED_LIGHTSABER) return 14; // Upgraded lightsaber (tile 510) + if (weaponTileId == TILE_THE_FORCE) return 14; // The Force (tile 511) - uses same animation return -1; } + /// + /// Checks if the given weapon is a ranged weapon (can attack from a distance). + /// + private bool IsRangedWeapon(int weaponTileId) + { + // The Force allows attacking from a distance + return weaponTileId == TILE_THE_FORCE; + } + /// /// Gets the weapon attack tile for a direction. /// Luke's lightsaber attack frames at atlas 241x1472 = tile 2122+ diff --git a/webfun-reference b/webfun-reference new file mode 160000 index 0000000..2a16d74 --- /dev/null +++ b/webfun-reference @@ -0,0 +1 @@ +Subproject commit 2a16d749372980138e2823511d62d896cf1cfe49