From c3377cf665c4d45191b7d1ae5bf973baafc5fca6 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Sun, 4 May 2025 17:44:09 -0700 Subject: [PATCH 1/7] Simplify note owner This never needs to be in the constructor Added SetOwner function --- Classes/Notes/Note.cs | 19 +++++++------------ Globals/Scribe.cs | 10 ---------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/Classes/Notes/Note.cs b/Classes/Notes/Note.cs index 59cfabdb..3dc196e3 100644 --- a/Classes/Notes/Note.cs +++ b/Classes/Notes/Note.cs @@ -22,7 +22,6 @@ public Note( int id, string name, Texture2D texture = null, - PuppetTemplate owner = null, int baseVal = 1, Action noteEffect = null, float costModifier = 1.0f, @@ -31,7 +30,6 @@ public Note( { Id = id; Name = name; - Owner = owner; NoteEffect = noteEffect; _baseVal = baseVal; Texture = texture; @@ -44,20 +42,17 @@ public void OnHit(BattleDirector BD, Timing timing) NoteEffect(BD, this, timing); } + public Note SetOwner(PuppetTemplate owner) + { + Owner = owner; + return this; + } + public Note Clone() { //Eventually could look into something more robust, but for now shallow copy is preferable. //We only would want val and name to be copied by value - Note newNote = new Note( - Id, - Name, - Texture, - Owner, - _baseVal, - NoteEffect, - CostModifier, - TargetType - ); + Note newNote = new Note(Id, Name, Texture, _baseVal, NoteEffect, CostModifier, TargetType); return newNote; } diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index e0f1eef9..e6cdd161 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -17,7 +17,6 @@ public partial class Scribe : Node 0, "EnemyBase", null, - null, 1, (director, note, timing) => { @@ -29,7 +28,6 @@ public partial class Scribe : Node 1, "PlayerBase", GD.Load("res://Classes/Notes/Assets/Note_PlayerBasic.png"), - null, 4, (director, note, timing) => { @@ -42,7 +40,6 @@ public partial class Scribe : Node 2, "PlayerDouble", GD.Load("res://Classes/Notes/Assets/Note_PlayerDouble.png"), - null, 8, (director, note, timing) => { @@ -55,7 +52,6 @@ public partial class Scribe : Node 3, "PlayerHeal", GD.Load("res://Classes/Notes/Assets/Note_PlayerHeal.png"), - null, 1, (director, note, timing) => { @@ -68,7 +64,6 @@ public partial class Scribe : Node 4, "PlayerVampire", GD.Load("res://Classes/Notes/Assets/Note_PlayerVampire.png"), - null, 3, (director, note, timing) => { @@ -83,7 +78,6 @@ public partial class Scribe : Node 5, "PlayerQuarter", GD.Load("res://Classes/Notes/Assets/Note_PlayerQuarter.png"), - null, 3, (director, note, timing) => { @@ -97,7 +91,6 @@ public partial class Scribe : Node 6, "PlayerBlock", GD.Load("res://Classes/Notes/Assets/Note_PlayerBlock.png"), - null, 1, (director, note, timing) => { @@ -110,7 +103,6 @@ public partial class Scribe : Node 7, "PlayerExplosive", GD.Load("res://Classes/Notes/Assets/Note_PlayerExplosive.png"), - null, 4, (director, note, timing) => { @@ -125,7 +117,6 @@ public partial class Scribe : Node 8, "PlayerEcho", GD.Load("res://Classes/Notes/Assets/Note_PlayerEcho.png"), - null, 4, (director, note, timing) => { @@ -139,7 +130,6 @@ public partial class Scribe : Node 9, "PlayerPoison", GD.Load("res://Classes/Notes/Assets/Note_PlayerPoison.png"), - null, 1, (director, note, timing) => { From a783ad3d5f93f87796b7a8ef6afba07aaece66ec Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Sun, 4 May 2025 19:29:43 -0700 Subject: [PATCH 2/7] Separate Adding Note logic Player notes now are sorted correctly Scaffolding AddConcurrentNote --- Globals/FunkEngineNameSpace.cs | 6 + .../BattleDirector/Scripts/BattleDirector.cs | 2 +- Scenes/BattleDirector/Scripts/Conductor.cs | 116 ++++++++++++++++-- 3 files changed, 112 insertions(+), 12 deletions(-) diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index b5a4f214..f8b8a28d 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -66,6 +66,12 @@ public ArrowData BeatFromLength() return this; } + public ArrowData IncDecLoop(int amount) + { + Beat.IncDecLoop(amount); + return this; + } + public bool Equals(ArrowData other) { return Beat.Equals(other.Beat) && Type == other.Type; diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs index f0a59fc0..f6a6e631 100644 --- a/Scenes/BattleDirector/Scripts/BattleDirector.cs +++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs @@ -214,7 +214,7 @@ public bool PlayerAddNote(ArrowType type, Beat beat) Note noteToPlace = NPB.NotePlaced(); noteToPlace.OnHit(this, Timing.Okay); - CD.AddPlayerNote(noteToPlace, type, beat); + CD.AddPlayerNote(noteToPlace.SetOwner(Player), type, beat); Harbinger.Instance.InvokeNotePlaced(new ArrowData(type, beat, noteToPlace)); Harbinger.Instance.InvokeNoteHit(noteToPlace, Timing.Okay); //TODO: test how this feels? maybe take it out later return true; diff --git a/Scenes/BattleDirector/Scripts/Conductor.cs b/Scenes/BattleDirector/Scripts/Conductor.cs index 146bba7a..4fce3fa5 100644 --- a/Scenes/BattleDirector/Scripts/Conductor.cs +++ b/Scenes/BattleDirector/Scripts/Conductor.cs @@ -66,22 +66,66 @@ private void ReceiveNoteInput(ArrowData data) } #endregion + //Ignores sorting, use sparingly + private void AddNoteData(ArrowData data, int index) + { + if (index == -1) + { + GD.PushWarning( + "Specific invalid index attempted to be passed (is -1): " + + data.Type + + " " + + data.Beat + ); + return; + } + + if (index < -1 || index > _noteData.Count) + { + GD.PushWarning( + "Invalid index passed is: " + index + " data: " + data.Type + " " + data.Beat + ); + return; + } + _noteData.Insert(index, data); + } + private int AddNoteData(Note noteRef, ArrowType type, Beat beat, double length = 0) { ArrowData result = new ArrowData(type, beat, noteRef, length); + return AddNoteData(result); + } + + private int AddNoteData(ArrowData data) + { if (_noteData.Count == 0) { - _noteData.Add(result); + _noteData.Add(data); return 0; } - int index = _noteData.BinarySearch(result); //TODO: This sorts correctly, but we don't take advantage yet. + int index = GetIndexOfData(data); + if (index == -1) + { + GD.PushWarning( + "Attempted to add duplicate note! Current note: " + data.Type + " " + data.Beat + ); + return -1; + } + + _noteData.Insert(index, data); + return index; + } + + private int GetIndexOfData(ArrowData data) + { + int index = _noteData.BinarySearch(data); if (index > 0) { - GD.PushWarning("Duplicate note attempted add " + type + " " + beat); + GD.PushWarning(index + " Invalid index for: " + data.Type + " " + data.Beat); return -1; } - _noteData.Insert(~index, result); + return ~index; } @@ -102,19 +146,69 @@ private void SpawnNotesAtBeat(Beat beat) private void SpawnNote(int index, bool newPlayerNote = false) { CM.AddNoteArrow(_noteData[index], newPlayerNote); - _noteData[index] = new ArrowData( - _noteData[index].Type, - _noteData[index].Beat.IncDecLoop(1), - _noteData[index].NoteRef, - _noteData[index].Length - ); //Structs make me sad sometimes + _noteData[index] = _noteData[index].IncDecLoop(1); + } + + /// + /// Attempts to add the new specified beat to current chart.

+ /// Should only be used from On Loop effects

+ /// EXPERIMENTAL - Currently does not check for: Hold note overlap whether placing or preexisting. + /// Notes that are far past when they should have been placed. And notes that will come around far in the future. + ///
+ /// Current time, should be the beat of the about to happen new loop. + /// What type of note + /// The lane + /// Beat to spawn new note at. Should be within a loop, but outside _beatSpawnOffset buffer. + /// Length of note, may get removed. + /// Whether placement was successful + public bool AddConcurrentNote( + Beat currentTime, + Note noteRef, + ArrowType type, + Beat beat, + float length = 0 + ) + { + if (beat < currentTime + _beatSpawnOffset) + { + GD.PushWarning( + "Attempted note far in past. Current beat: " + + currentTime + + " notedata: " + + type + + " " + + beat + ); + return false; + } + if (beat > currentTime.IncDecLoop(1) + _beatSpawnOffset) + { + GD.PushWarning( + "Attempted note too far in future. Current beat: " + + currentTime + + " notedata: " + + type + + " " + + beat + ); + return false; + } + //Beat should now be guaranteed to be coming up, at some point, from ProgressiveSpawnNote + int index = AddNoteData(noteRef, type, beat, length); + if (index == -1) + return false; //Assumption: Dupe note. + return true; } public void AddPlayerNote(Note noteRef, ArrowType type, Beat beat) { - int index = AddNoteData(noteRef, type, beat); //Currently player notes aren't sorted correctly + Beat compBeat = new Beat(beat.BeatPos, beat.Loop + 1); + int index = GetIndexOfData(new ArrowData(type, compBeat, null)); //Player notes should sorted based on immediately incrementing loop if (index != -1) + { + AddNoteData(new ArrowData(type, beat, noteRef), index); SpawnNote(index, true); + } else GD.PushError("Duplicate player note was attempted. (This should be stopped by CM)"); } From 7e7e4435de65df7f6128efd8c0fb6f2320ff3333 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Sun, 4 May 2025 20:30:14 -0700 Subject: [PATCH 3/7] Refactored placement to take advantage of sorting Consider this change experimental, not 100% sure the SpawnNotesAtBeat loop works exactly as intended. --- Scenes/BattleDirector/Scripts/Conductor.cs | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Scenes/BattleDirector/Scripts/Conductor.cs b/Scenes/BattleDirector/Scripts/Conductor.cs index 4fce3fa5..2fb1726f 100644 --- a/Scenes/BattleDirector/Scripts/Conductor.cs +++ b/Scenes/BattleDirector/Scripts/Conductor.cs @@ -51,6 +51,7 @@ private void AddInitialNotes() private void SpawnInitialNotes() { + _noteData.Sort(); //Isn't inherently necessary, but sort for safety for (int i = 1; i <= _beatSpawnOffset; i++) { SpawnNotesAtBeat(new Beat(i)); @@ -129,24 +130,29 @@ private int GetIndexOfData(ArrowData data) return ~index; } - //TODO: Beat spawn redundancy checking, efficiency + //Assumes beat has beatPos floor'd private void SpawnNotesAtBeat(Beat beat) { - for (int i = 0; i < _noteData.Count; i++) + int startIdx = _noteData.BinarySearch(new ArrowData(ArrowType.Up, beat, null)); //first arrow of beat + if (startIdx < 0) + startIdx = ~startIdx; + for (int i = 0; i <= 40 && (int)_noteData[startIdx].Beat.BeatPos == (int)beat.BeatPos; i++) { - if ( - _noteData[i].Beat.Loop != beat.Loop - || (int)_noteData[i].Beat.BeatPos != (int)beat.BeatPos - ) - continue; - SpawnNote(i); - } + SpawnNote(startIdx); //Spawn pops notes, so stay in same idx + } //A tiny bit of defensive programming. I don't like this much more than the old way of looping and checking everything. + //Could be a while loop, but just in case have a safety counter, iterations per beat should max at 40, 4 directions * 10 increments per beat (0.1 accuracy for beatPos tracking) } private void SpawnNote(int index, bool newPlayerNote = false) { CM.AddNoteArrow(_noteData[index], newPlayerNote); - _noteData[index] = _noteData[index].IncDecLoop(1); + if (newPlayerNote) //Player notes are presorted + { + _noteData[index] = _noteData[index].IncDecLoop(1); + return; + } + _noteData.Add(_noteData[index].IncDecLoop(1)); + _noteData.RemoveAt(index); } /// @@ -193,7 +199,7 @@ public bool AddConcurrentNote( ); return false; } - //Beat should now be guaranteed to be coming up, at some point, from ProgressiveSpawnNote + //Beat should now be guaranteed to be coming up, at some point, from ProgressiveSpawnNote, does NOT need manual spawn int index = AddNoteData(noteRef, type, beat, length); if (index == -1) return false; //Assumption: Dupe note. From 1b9c963c99344762531a87106c616741cba44863 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Sun, 4 May 2025 21:18:26 -0700 Subject: [PATCH 4/7] Enemies can add concurrent notes Temperamental conditions Notes in the first visible parts of the chart have to be added on battle start, with a 1 loop offset Otherwise, they HAVE to be added OnLoop, with beatPos set and loop 0 They cannot overwrite player notes, will throw a completely safe warning --- .../BattleDirector/Scripts/BattleDirector.cs | 7 ++++++ Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs index f6a6e631..f304f967 100644 --- a/Scenes/BattleDirector/Scripts/BattleDirector.cs +++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs @@ -220,6 +220,13 @@ public bool PlayerAddNote(ArrowType type, Beat beat) return true; } + public bool EnemyAddNote(ArrowType type, Beat beat, Note noteRef, float len, EnemyPuppet enemy) + { + noteRef.SetOwner(enemy); + Beat realBeat = TimeKeeper.GetBeatFromTime(Audio.GetPlaybackPosition()); + return CD.AddConcurrentNote(realBeat, noteRef, type, beat.IncDecLoop(realBeat.Loop), len); + } + //Only called from CD signal when a note is processed private void OnTimedInput(ArrowData data, double beatDif) { diff --git a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs index 9f0e237d..3bc36504 100644 --- a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs +++ b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs @@ -1,4 +1,5 @@ using System; +using FunkEngine; using Godot; public partial class P_TheGWS : EnemyPuppet @@ -18,5 +19,27 @@ public override void _Ready() enemTween.SetEase(Tween.EaseType.InOut); enemTween.SetLoops(); enemTween.Play(); + + BattleEvents = new EnemyEffect[] + { + new EnemyEffect( + this, + BattleEffectTrigger.OnBattleStart, + 1, + (e, eff, val) => + { + if (val == 0) + return; + e.BD.EnemyAddNote( + ArrowType.Up, + new Beat(3, 1), + Scribe.NoteDictionary[0].Clone(), + 0, + eff.Owner + ); + eff.Value = 0; + } + ), + }; } } From b88377c4c5378cdd9b9c3c21549181b3adaed18a Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Tue, 6 May 2025 13:50:29 -0700 Subject: [PATCH 5/7] Implemented sample GWS note --- Classes/Notes/Assets/Note_GWS.png | Bin 0 -> 607 bytes Classes/Notes/Assets/Note_GWS.png.import | 34 ++++++++++++++++++++++ Globals/Scribe.cs | 13 +++++++++ Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs | 9 +++++- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Classes/Notes/Assets/Note_GWS.png create mode 100644 Classes/Notes/Assets/Note_GWS.png.import diff --git a/Classes/Notes/Assets/Note_GWS.png b/Classes/Notes/Assets/Note_GWS.png new file mode 100644 index 0000000000000000000000000000000000000000..be47556ea39dd180cc29d6f9a6c77997e7a3a78a GIT binary patch literal 607 zcmV-l0-*hgP)Px%8A(JzR9J@y>?elRgl{N1$+Qz zAq_L6hCfpB075cF@_REJQ6}t=_ugy$&bj6_em*_{0B9?FF|Zq)nrJp4qb4GF?{|Zx zzHI@sthFGbaQ~$Sa{J37q5$QqF(xw7bzL;4l&P=t0K^wje1c z4mEhI(#T0PmIlfep_W2c8bvMgl2!&7{CqyI2LE|`127j|YDB_w);)mE7&tL6n}J_1 zFL*wm1GFSrBLv`jy{hBr;bAr|`*Jl<+5!d~kH^r*S;;-mDVu@42aL5A_xoLir{@I# z9QY`Qit3D tl-rK4)W7NfoPpQrq88(4vQmOdy#sAR$})*dKFR<9002ovPDHLkV1j~W5H("res://Classes/Notes/Assets/Note_GWS.png"), + 1, + (director, note, timing) => + { + int dmg = 2 * (3 - (int)timing) * note.GetBaseVal() + TimeKeeper.LastBeat.Loop; //Double an enemy base plus the loop num, unless perfect + if (timing == Timing.Perfect) + dmg = 0; + director.DealDamage(Targetting.Player, dmg, note.Owner); + } + ), }; public static readonly RelicTemplate[] RelicDictionary = new[] diff --git a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs index 3bc36504..8b1d2c30 100644 --- a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs +++ b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs @@ -33,7 +33,14 @@ public override void _Ready() e.BD.EnemyAddNote( ArrowType.Up, new Beat(3, 1), - Scribe.NoteDictionary[0].Clone(), + Scribe.NoteDictionary[10].Clone(), + 0, + eff.Owner + ); + e.BD.EnemyAddNote( + ArrowType.Up, + new Beat(26), + Scribe.NoteDictionary[10].Clone(), 0, eff.Owner ); From 35096372ba1e9f7268c65d5be8f80084a75e57d6 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Tue, 6 May 2025 14:39:07 -0700 Subject: [PATCH 6/7] Added Applying note types Any puppet can apply note types to base notes Limitations: Notes are only applied to notes that had EnemyBase. Notes can only be applied randomly. --- Globals/FunkEngineNameSpace.cs | 8 +++- .../BattleDirector/Scripts/BattleDirector.cs | 9 +++- Scenes/BattleDirector/Scripts/Conductor.cs | 42 ++++++++++++++++++- Scenes/Puppets/Enemies/EnemyPuppet.cs | 1 + Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs | 2 + 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index f8b8a28d..7c754e79 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -55,7 +55,7 @@ public ArrowData(ArrowType type, Beat beat, Note note, double length = 0) public Beat Beat; public readonly double Length; //in beats, should never be >= loop public readonly ArrowType Type; - public readonly Note NoteRef = null; + public Note NoteRef { get; private set; } = null; public static ArrowData Placeholder { get; private set; } = new(default, default, new Note(-1, "")); @@ -66,6 +66,12 @@ public ArrowData BeatFromLength() return this; } + public static ArrowData SetNote(ArrowData arrowData, Note note) + { + arrowData.NoteRef = note; + return arrowData; + } + public ArrowData IncDecLoop(int amount) { Beat.IncDecLoop(amount); diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs index f304f967..8e74ab92 100644 --- a/Scenes/BattleDirector/Scripts/BattleDirector.cs +++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs @@ -96,7 +96,7 @@ public override void _Ready() InitPlayer(); InitEnemies(); InitScoringGuide(); - CD.Initialize(curSong); + CD.Initialize(curSong, _enemies); CD.NoteInputEvent += OnTimedInput; FocusedButton.GrabFocus(); @@ -227,6 +227,13 @@ public bool EnemyAddNote(ArrowType type, Beat beat, Note noteRef, float len, Ene return CD.AddConcurrentNote(realBeat, noteRef, type, beat.IncDecLoop(realBeat.Loop), len); } + public void RandApplyNote(PuppetTemplate owner, int noteId, int amount) + { + if (owner == null || noteId > Scribe.NoteDictionary.Length || amount < 1) + return; + CD.SetRandBaseNoteToType(owner, (noteId, amount)); + } + //Only called from CD signal when a note is processed private void OnTimedInput(ArrowData data, double beatDif) { diff --git a/Scenes/BattleDirector/Scripts/Conductor.cs b/Scenes/BattleDirector/Scripts/Conductor.cs index 2fb1726f..edde73f1 100644 --- a/Scenes/BattleDirector/Scripts/Conductor.cs +++ b/Scenes/BattleDirector/Scripts/Conductor.cs @@ -18,7 +18,7 @@ public partial class Conductor : Node private bool _initialized; #region Initialization - public void Initialize(SongData curSong) + public void Initialize(SongData curSong, EnemyPuppet[] enemies = null) { if (_initialized) return; @@ -33,6 +33,8 @@ public void Initialize(SongData curSong) CM.Size.X / TimeKeeper.ChartWidth * TimeKeeper.BeatsPerLoop ); AddInitialNotes(); + AddInitialEnemyNotes(enemies); + SpawnInitialNotes(); _initialized = true; } @@ -46,7 +48,17 @@ private void AddInitialNotes() AddNoteData(Scribe.NoteDictionary[0], type, new Beat((int)Note.Beat), Note.Length); } } - SpawnInitialNotes(); + } + + private void AddInitialEnemyNotes(EnemyPuppet[] enemies) + { + if (enemies == null) + return; + foreach (EnemyPuppet enemy in enemies) + { + if (enemy.InitialNote.Amount > 0) + SetRandBaseNoteToType(enemy, enemy.InitialNote); + } } private void SpawnInitialNotes() @@ -155,6 +167,32 @@ private void SpawnNote(int index, bool newPlayerNote = false) _noteData.RemoveAt(index); } + public void SetRandBaseNoteToType(PuppetTemplate owner, (int noteid, int amount) noteOfAmount) + { + RandomNumberGenerator noteRng = new RandomNumberGenerator(); + noteRng.Seed = StageProducer.GlobalRng.Seed; + noteRng.State = StageProducer.GlobalRng.State; + + for (int i = noteOfAmount.amount; i > 0; i--) + { + int iterationsLeft = 5; + while (iterationsLeft > 0) + { + int idx = noteRng.RandiRange(0, _noteData.Count); + if (_noteData[idx].NoteRef.Id == 0) + { + Note newNoteRef = Scribe + .NoteDictionary[noteOfAmount.noteid] + .Clone() + .SetOwner(owner); + _noteData[idx] = ArrowData.SetNote(_noteData[idx], newNoteRef); + iterationsLeft = -1; + } + iterationsLeft--; + } + } + } + /// /// Attempts to add the new specified beat to current chart.

/// Should only be used from On Loop effects

diff --git a/Scenes/Puppets/Enemies/EnemyPuppet.cs b/Scenes/Puppets/Enemies/EnemyPuppet.cs index 5301476c..4a9d245d 100644 --- a/Scenes/Puppets/Enemies/EnemyPuppet.cs +++ b/Scenes/Puppets/Enemies/EnemyPuppet.cs @@ -4,6 +4,7 @@ public partial class EnemyPuppet : PuppetTemplate { protected EnemyEffect[] BattleEvents = Array.Empty(); public int BaseMoney { get; protected set; } = 0; + public (int NoteId, int Amount) InitialNote = (0, 0); public virtual EnemyEffect[] GetBattleEvents() { diff --git a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs index 8b1d2c30..3cd877e8 100644 --- a/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs +++ b/Scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs @@ -11,6 +11,7 @@ public override void _Ready() MaxHealth = 150; CurrentHealth = MaxHealth; BaseMoney = 10; + InitialNote = (10, 5); base._Ready(); var enemTween = CreateTween(); enemTween.TweenProperty(Sprite, "position", Vector2.Down * 10, 3f).AsRelative(); @@ -28,6 +29,7 @@ public override void _Ready() 1, (e, eff, val) => { + e.BD.RandApplyNote(eff.Owner, 10, 2); if (val == 0) return; e.BD.EnemyAddNote( From 3b8f15731488d3661c476c2f6fe113b88ca7b1be Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Tue, 6 May 2025 15:03:28 -0700 Subject: [PATCH 7/7] Index OOB fix --- Scenes/BattleDirector/Scripts/Conductor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scenes/BattleDirector/Scripts/Conductor.cs b/Scenes/BattleDirector/Scripts/Conductor.cs index edde73f1..e8ff1331 100644 --- a/Scenes/BattleDirector/Scripts/Conductor.cs +++ b/Scenes/BattleDirector/Scripts/Conductor.cs @@ -178,7 +178,7 @@ public void SetRandBaseNoteToType(PuppetTemplate owner, (int noteid, int amount) int iterationsLeft = 5; while (iterationsLeft > 0) { - int idx = noteRng.RandiRange(0, _noteData.Count); + int idx = noteRng.RandiRange(0, _noteData.Count - 1); if (_noteData[idx].NoteRef.Id == 0) { Note newNoteRef = Scribe