From 12416006c39bc5049b6f86bfb487c7e24769adc6 Mon Sep 17 00:00:00 2001 From: Rmojarro1 <48000819+Rmojarro1@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:16:58 -0800 Subject: [PATCH 1/2] Rough version of reward made a static rewards class that should assign a new relic, made minor changes to battle director to check health of puppets and change the apporpiate bool when they die, added a debug function to instantly kill the enemy to make testing the reward drop easier, added dummy relic --- Globals/Scribe.cs | 14 ++++++ Reward.cs | 49 +++++++++++++++++++ .../BattleDirector/scripts/BattleDirector.cs | 45 +++++++++++++++++ scenes/Puppets/scripts/PlayerStats.cs | 1 + scenes/Puppets/scripts/PuppetTemplate.cs | 7 ++- 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 Reward.cs diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index b1b9884a..249f4556 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -45,5 +45,19 @@ public partial class Scribe : Node ), } ), + new RelicTemplate( + "Dummy Item", + new RelicEffect[] + { + new RelicEffect( + BattleEffectTrigger.NotePlaced, + 100, + (director, val) => + { + director.Player.Heal(val); + } + ), + } + ), }; } diff --git a/Reward.cs b/Reward.cs new file mode 100644 index 00000000..b31df00c --- /dev/null +++ b/Reward.cs @@ -0,0 +1,49 @@ +using System; +using System.Linq; +using Godot; + +public static class Reward +{ + private static readonly Random _rng = new Random(); + + public static void GiveRandomRelic(PlayerStats player) + { + RelicTemplate newRelic = GetRandomRelic(player.CurRelics); + + if (newRelic != null) + { + AddRelic(player, newRelic); + GD.Print("Relic added: " + newRelic.Name); + } + else + { + GD.Print("No new relic to collect"); + } + } + + public static RelicTemplate GetRandomRelic(RelicTemplate[] ownedRelics) + { + var availableRelics = Scribe + .RelicDictionary.Where(r => !ownedRelics.Any(o => o.Name == r.Name)) + .ToArray(); + + if (availableRelics.Length == 0) + { + return null; // No new relics available + } + + int index = _rng.Next(availableRelics.Length); + return availableRelics[index].Clone(); + } + + public static void AddRelic(PlayerStats player, RelicTemplate relic) + { + if (player.CurRelics.Any(r => r.Name == relic.Name)) + { + GD.Print("Relic already in inventory: " + relic.Name); + return; + } + player.CurRelics = player.CurRelics.Append(relic).ToArray(); + GD.Print("Adding relic: " + relic.Name); + } +} diff --git a/scenes/BattleDirector/scripts/BattleDirector.cs b/scenes/BattleDirector/scripts/BattleDirector.cs index 7cc0f3ca..6053d5e0 100644 --- a/scenes/BattleDirector/scripts/BattleDirector.cs +++ b/scenes/BattleDirector/scripts/BattleDirector.cs @@ -32,6 +32,9 @@ public partial class BattleDirector : Node2D private SongData _curSong; + private bool battleLost = false; + private bool battleWon = false; + #endregion #region Note Handling @@ -116,8 +119,13 @@ private void Begin() public override void _Process(double delta) { + if (!battleLost || !battleWon) + { + CheckBattleStatus(); + } TimeKeeper.CurrentTime = Audio.GetPlaybackPosition(); CD.CheckMiss(); + //CheckBattleStatus(); } #endregion @@ -125,6 +133,14 @@ public override void _Process(double delta) public override void _UnhandledInput(InputEvent @event) { + if (@event is InputEventKey eventKey && eventKey.Pressed && !eventKey.Echo) + { + if (eventKey.Keycode == Key.Key0) // Adjust if you prefer a different key code. + { + DebugKillEnemy(); + } + } + if (@event.IsActionPressed("Pause")) { var pauseMenu = GD.Load("res://scenes/UI/Pause.tscn"); @@ -209,4 +225,33 @@ private void EventizeRelics() } } #endregion + + + private void CheckBattleStatus() + { + if (battleLost || battleWon) + return; + + if (Player.GetCurrentHealth() <= 0) + { + GD.Print("Player is Dead"); + battleLost = true; + return; + } + + if (Enemy.GetCurrentHealth() <= 0) + { + GD.Print("Enemy is dead"); + battleWon = true; + + Reward.GiveRandomRelic(Player.Stats); + EventizeRelics(); //literally just here for debugging, ignore later + return; + } + } + + private void DebugKillEnemy() + { + Enemy.TakeDamage(1000); + } } diff --git a/scenes/Puppets/scripts/PlayerStats.cs b/scenes/Puppets/scripts/PlayerStats.cs index c788ff59..b8fc20cf 100644 --- a/scenes/Puppets/scripts/PlayerStats.cs +++ b/scenes/Puppets/scripts/PlayerStats.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Godot; public partial class PlayerStats : Resource diff --git a/scenes/Puppets/scripts/PuppetTemplate.cs b/scenes/Puppets/scripts/PuppetTemplate.cs index 249638a9..28b40e73 100644 --- a/scenes/Puppets/scripts/PuppetTemplate.cs +++ b/scenes/Puppets/scripts/PuppetTemplate.cs @@ -36,11 +36,16 @@ public void Init(Texture2D texture, string name) public void TakeDamage(int amount) { - _healthBar.ChangeHP(-amount); + _currentHealth = _healthBar.ChangeHP(-amount); } public void Heal(int amount) { _healthBar.ChangeHP(amount); } + + public int GetCurrentHealth() + { + return _currentHealth; + } } From 91eb416d82be3d7d1460eb6cfb6dc38b9257407c Mon Sep 17 00:00:00 2001 From: Rmojarro1 <48000819+Rmojarro1@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:04:12 -0800 Subject: [PATCH 2/2] Reward menu approach New approach that allows for player to choose from a selection of relics after the battle is won --- Reward.cs | 17 ++++++++ RewardSelect.cs | 41 +++++++++++++++++++ RewardSelectionUI.tscn | 18 ++++++++ .../BattleDirector/scripts/BattleDirector.cs | 25 +++++++++-- 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 RewardSelect.cs create mode 100644 RewardSelectionUI.tscn diff --git a/Reward.cs b/Reward.cs index b31df00c..07c61a2c 100644 --- a/Reward.cs +++ b/Reward.cs @@ -2,6 +2,8 @@ using System.Linq; using Godot; +//it's very messy, feel free to clean up as much as necessary + public static class Reward { private static readonly Random _rng = new Random(); @@ -46,4 +48,19 @@ public static void AddRelic(PlayerStats player, RelicTemplate relic) player.CurRelics = player.CurRelics.Append(relic).ToArray(); GD.Print("Adding relic: " + relic.Name); } + + public static RelicTemplate[] GetMultipleRelics(RelicTemplate[] ownedRelics, int count) + { + var availableRelics = Scribe + .RelicDictionary.Where(r => !ownedRelics.Any(o => o.Name == r.Name)) + .ToArray(); + if (availableRelics.Length == 0) + return new RelicTemplate[0]; + + return availableRelics + .OrderBy(_ => _rng.Next()) + .Take(count) + .Select(r => r.Clone()) + .ToArray(); + } } diff --git a/RewardSelect.cs b/RewardSelect.cs new file mode 100644 index 00000000..ec2de7b9 --- /dev/null +++ b/RewardSelect.cs @@ -0,0 +1,41 @@ +using System; +using System.Linq; +using Godot; + +public partial class RewardSelect : CanvasLayer +{ + [Export] + public VBoxContainer ButtonContainer; + + private PlayerStats _player; + private RelicTemplate[] _choices; + + public void Initialize(PlayerStats player) + { + _player = player; + GenerateRelicChoices(); + } + + private void GenerateRelicChoices() + { + //should probably change this so that the amount of relics offered can be changed when BD calls it + //i.e less options when killing trash mobs/basic/weak enemies + _choices = Reward.GetMultipleRelics(_player.CurRelics, 3); + + foreach (var relic in _choices) + { + var button = new Button(); + button.Text = relic.Name; + button.Pressed += () => OnRelicSelected(relic); + ButtonContainer.AddChild(button); + } + } + + private void OnRelicSelected(RelicTemplate choiceRelic) + { + Reward.AddRelic(_player, choiceRelic); + GD.Print("Relic selected: " + choiceRelic.Name); + + QueueFree(); + } +} diff --git a/RewardSelectionUI.tscn b/RewardSelectionUI.tscn new file mode 100644 index 00000000..a514446a --- /dev/null +++ b/RewardSelectionUI.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://c6icx2yriud6y"] + +[ext_resource type="Script" path="res://RewardSelect.cs" id="1_ts2x3"] + +[node name="CanvasLayer" type="CanvasLayer" node_paths=PackedStringArray("ButtonContainer")] +script = ExtResource("1_ts2x3") +ButtonContainer = NodePath("PanelContainer/VBoxContainer") + +[node name="PanelContainer" type="PanelContainer" parent="."] +offset_left = 34.0 +offset_top = 67.0 +offset_right = 600.0 +offset_bottom = 264.0 + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="RewardSelect" type="Node2D" parent="."] diff --git a/scenes/BattleDirector/scripts/BattleDirector.cs b/scenes/BattleDirector/scripts/BattleDirector.cs index 6053d5e0..89412268 100644 --- a/scenes/BattleDirector/scripts/BattleDirector.cs +++ b/scenes/BattleDirector/scripts/BattleDirector.cs @@ -119,13 +119,14 @@ private void Begin() public override void _Process(double delta) { + //check if either one is dead until one is true, feel free to remove if we have a more efficent way of checking + //alternatively, stop the other process since the battle is over if (!battleLost || !battleWon) { CheckBattleStatus(); } TimeKeeper.CurrentTime = Audio.GetPlaybackPosition(); CD.CheckMiss(); - //CheckBattleStatus(); } #endregion @@ -133,9 +134,10 @@ public override void _Process(double delta) public override void _UnhandledInput(InputEvent @event) { + //this one is for calling a debug key to insta-kill the enemy if (@event is InputEventKey eventKey && eventKey.Pressed && !eventKey.Echo) { - if (eventKey.Keycode == Key.Key0) // Adjust if you prefer a different key code. + if (eventKey.Keycode == Key.Key0) { DebugKillEnemy(); } @@ -239,13 +241,20 @@ private void CheckBattleStatus() return; } + //will have to adjust this to account for when we have multiple enemies at once if (Enemy.GetCurrentHealth() <= 0) { GD.Print("Enemy is dead"); battleWon = true; - Reward.GiveRandomRelic(Player.Stats); - EventizeRelics(); //literally just here for debugging, ignore later + //below, old method that just adds a random relic to the inventory + //Reward.GiveRandomRelic(Player.Stats); + //EventizeRelics(); //literally just here to force the ui to update and see if it was added, remove with the proper ui update + //probably won't even need it since we'll be loading to seperate scene anyways + + //new method that allows player to choose a relic + ShowRewardSelection(); + return; } } @@ -254,4 +263,12 @@ private void DebugKillEnemy() { Enemy.TakeDamage(1000); } + + private void ShowRewardSelection() + { + var rewardUI = GD.Load("res://RewardSelectionUI.tscn") + .Instantiate(); + AddChild(rewardUI); + rewardUI.Initialize(Player.Stats); + } }