Skip to content

Commit 6132f32

Browse files
authored
Merge pull request #140 from Project-Funk-Engine/MultiEnemyFights
Handle Multiple Enemies
2 parents 04c2172 + 9201ab6 commit 6132f32

14 files changed

Lines changed: 150 additions & 66 deletions

File tree

Classes/MidiMaestro/SongTemplate.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ public struct SongTemplate
88
public string Name;
99
public readonly string AudioLocation;
1010
public string MIDILocation;
11-
public readonly string EnemyScenePath;
11+
public readonly string[] EnemyScenePath;
1212
public SongData SongData;
1313

1414
public SongTemplate(
1515
SongData songData,
1616
string name = "",
1717
string audioLocation = "",
1818
string midiLocation = "",
19-
string enemyScenePath = ""
19+
string[] enemyScenePath = null
2020
)
2121
{
2222
Name = name;

Classes/Notes/Note.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public partial class Note : Resource, IDisplayable
1212
public string Name { get; set; }
1313
private int _baseVal;
1414
public float CostModifier { get; private set; }
15+
public Targetting TargetType { get; private set; }
1516
private Action<BattleDirector, Note, Timing> NoteEffect;
1617

1718
public const double TimingMax = 0.5d; //The max range for a note to be timed is its beat +/- this const
@@ -27,7 +28,8 @@ public Note(
2728
PuppetTemplate owner = null,
2829
int baseVal = 1,
2930
Action<BattleDirector, Note, Timing> noteEffect = null,
30-
float costModifier = 1.0f
31+
float costModifier = 1.0f,
32+
Targetting targetType = Targetting.First
3133
)
3234
{
3335
Id = id;
@@ -38,13 +40,17 @@ public Note(
3840
?? (
3941
(BD, source, timing) =>
4042
{
41-
BD.GetTarget(this).TakeDamage((int)timing * source._baseVal);
43+
Array.ForEach(
44+
BD.GetTargets(source), //Ok, sure
45+
enemy => enemy.TakeDamage((int)timing * source._baseVal)
46+
);
4247
}
4348
);
4449
_baseVal = baseVal;
4550
Texture = texture;
4651
Tooltip = tooltip;
4752
CostModifier = costModifier;
53+
TargetType = targetType;
4854
}
4955

5056
public void OnHit(BattleDirector BD, Timing timing)

Globals/FunkEngineNameSpace.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public struct BattleConfig
3434
{
3535
public Stages RoomType;
3636
public MapGrid.Room BattleRoom;
37-
public string EnemyScenePath;
37+
public string[] EnemyScenePath;
3838
public SongTemplate CurSong;
3939
}
4040

@@ -222,6 +222,12 @@ public enum Timing
222222
Perfect = 4,
223223
}
224224

225+
public enum Targetting
226+
{
227+
First,
228+
All,
229+
}
230+
225231
public enum BattleEffectTrigger
226232
{
227233
NotePlaced,
@@ -262,7 +268,7 @@ public Room[] GetRooms()
262268
public class Room
263269
{
264270
public int Idx { get; private set; }
265-
public int[] Children { get; private set; } = Array.Empty<int>();
271+
public int[] Children { get; private set; } = [];
266272
public int X { get; private set; }
267273
public int Y { get; private set; }
268274
public Stages Type { get; private set; }

Globals/Scribe.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public partial class Scribe : Node
3333
{
3434
if (timing == Timing.Miss)
3535
return;
36-
director.Enemy.TakeDamage((int)timing * note.GetBaseVal());
36+
director.GetFirstEnemy()?.TakeDamage((int)timing * note.GetBaseVal());
3737
}
3838
),
3939
new Note(
@@ -47,7 +47,7 @@ public partial class Scribe : Node
4747
{
4848
if (timing == Timing.Miss)
4949
return;
50-
director.Enemy.TakeDamage(note.GetBaseVal() * (int)timing);
50+
director.GetFirstEnemy()?.TakeDamage(note.GetBaseVal() * (int)timing);
5151
}
5252
),
5353
new Note(
@@ -76,7 +76,7 @@ public partial class Scribe : Node
7676
if (timing == Timing.Miss)
7777
return;
7878
director.Player.Heal((int)timing * note.GetBaseVal());
79-
director.Enemy.TakeDamage((int)timing * note.GetBaseVal());
79+
director.GetFirstEnemy()?.TakeDamage((int)timing * note.GetBaseVal());
8080
}
8181
),
8282
new Note(
@@ -90,7 +90,7 @@ public partial class Scribe : Node
9090
{
9191
if (timing == Timing.Miss)
9292
return;
93-
director.Enemy.TakeDamage((int)timing + note.GetBaseVal());
93+
director.GetFirstEnemy()?.TakeDamage((int)timing + note.GetBaseVal());
9494
},
9595
0.25f
9696
),
@@ -171,7 +171,7 @@ public partial class Scribe : Node
171171
),
172172
};
173173

174-
public static readonly SongTemplate[] SongDictionary = new[]
174+
public static readonly SongTemplate[] SongDictionary = new[] //Generalize and make pools for areas/room types
175175
{
176176
new SongTemplate(
177177
new SongData
@@ -182,7 +182,8 @@ public partial class Scribe : Node
182182
},
183183
"Song1",
184184
"Audio/Song1.ogg",
185-
"Audio/Midi/Song1.mid"
185+
"Audio/Midi/Song1.mid",
186+
[P_BossBlood.LoadPath]
186187
),
187188
new SongTemplate(
188189
new SongData
@@ -194,7 +195,19 @@ public partial class Scribe : Node
194195
"Song2",
195196
"Audio/Song2.ogg",
196197
"Audio/Midi/Song2.mid",
197-
P_Parasifly.LoadPath
198+
[P_Parasifly.LoadPath]
199+
),
200+
new SongTemplate(
201+
new SongData
202+
{
203+
Bpm = 60,
204+
SongLength = -1,
205+
NumLoops = 1,
206+
},
207+
"Song2",
208+
"Audio/Song2.ogg",
209+
"Audio/Midi/Song2.mid",
210+
[P_Parasifly.LoadPath, P_Parasifly.LoadPath]
198211
),
199212
new SongTemplate(
200213
new SongData
@@ -206,7 +219,7 @@ public partial class Scribe : Node
206219
"Song3",
207220
"Audio/Song3.ogg",
208221
"Audio/Midi/Song3.mid",
209-
P_TheGWS.LoadPath
222+
[P_TheGWS.LoadPath]
210223
),
211224
};
212225

Globals/StageProducer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,12 @@ private BattleConfig MakeBattleConfig(Stages nextRoom, int nextRoomIdx)
195195
switch (nextRoom)
196196
{
197197
case Stages.Battle:
198-
int songIdx = stageRng.RandiRange(1, 2);
198+
int songIdx = stageRng.RandiRange(1, 3);
199199
result.CurSong = Scribe.SongDictionary[songIdx];
200200
result.EnemyScenePath = Scribe.SongDictionary[songIdx].EnemyScenePath;
201201
break;
202202
case Stages.Boss:
203-
result.EnemyScenePath = P_BossBlood.LoadPath;
203+
result.EnemyScenePath = Scribe.SongDictionary[0].EnemyScenePath;
204204
result.CurSong = Scribe.SongDictionary[0];
205205
break;
206206
case Stages.Chest:

Scenes/BattleDirector/BattleScene.tscn

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[gd_scene load_steps=10 format=3 uid="uid://b0mrgr7h0ty1y"]
22

3-
[ext_resource type="Script" path="res://Scenes/BattleDirector/Scripts/BattleDirector.cs" id="1_jmdo1"]
4-
[ext_resource type="Script" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_ka0ws"]
5-
[ext_resource type="Script" path="res://Scenes/BattleDirector/Scripts/Conductor.cs" id="3_elcaj"]
3+
[ext_resource type="Script" uid="uid://bttu0wmy2fp64" path="res://Scenes/BattleDirector/Scripts/BattleDirector.cs" id="1_jmdo1"]
4+
[ext_resource type="Script" uid="uid://pl57giqyhckb" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_ka0ws"]
5+
[ext_resource type="Script" uid="uid://tg14hkh1n7iv" path="res://Scenes/BattleDirector/Scripts/Conductor.cs" id="3_elcaj"]
66
[ext_resource type="PackedScene" uid="uid://duhiilcv4tat3" path="res://Scenes/BattleDirector/NotePlacementBar.tscn" id="4_qk7om"]
77
[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://Scenes/ChartViewport/ChartViewport.tscn" id="5_r2xh0"]
88
[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="6_0jtpx"]
@@ -17,9 +17,10 @@ gradient = SubResource("Gradient_8uy3a")
1717
fill_from = Vector2(1, 0)
1818
fill_to = Vector2(0.738532, 1)
1919

20-
[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CD", "CM", "NPB", "Audio", "_focusedButton")]
20+
[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")]
2121
process_mode = 1
2222
script = ExtResource("1_jmdo1")
23+
PuppetMarkers = [NodePath("PlayerMarker"), NodePath("Enemy1Marker"), NodePath("Enemy2Marker"), NodePath("Enemy3Marker")]
2324
CD = NodePath("Conductor")
2425
CM = NodePath("SubViewport")
2526
NPB = NodePath("NotePlacementBar")
@@ -37,6 +38,18 @@ CurSceneNode = NodePath("..")
3738
script = ExtResource("3_elcaj")
3839
CM = NodePath("../SubViewport")
3940

41+
[node name="PlayerMarker" type="Marker2D" parent="."]
42+
position = Vector2(158, 125)
43+
44+
[node name="Enemy1Marker" type="Marker2D" parent="."]
45+
position = Vector2(350, 125)
46+
47+
[node name="Enemy2Marker" type="Marker2D" parent="."]
48+
position = Vector2(450, 125)
49+
50+
[node name="Enemy3Marker" type="Marker2D" parent="."]
51+
position = Vector2(550, 125)
52+
4053
[node name="NotePlacementBar" parent="." instance=ExtResource("4_qk7om")]
4154
offset_top = 183.0
4255
offset_bottom = 183.0

Scenes/BattleDirector/Scripts/BattleDirector.cs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using FunkEngine;
34
using Godot;
45
using Melanchall.DryWetMidi.Interaction;
@@ -12,7 +13,10 @@ public partial class BattleDirector : Node2D
1213
public static readonly string LoadPath = "res://Scenes/BattleDirector/BattleScene.tscn";
1314

1415
public PlayerPuppet Player;
15-
public EnemyPuppet Enemy;
16+
private EnemyPuppet[] _enemies;
17+
18+
[Export]
19+
public Marker2D[] PuppetMarkers = new Marker2D[4]; //[0] is always player
1620

1721
[Export]
1822
private Conductor CD;
@@ -49,14 +53,31 @@ private bool PlayerAddNote(ArrowType type, Beat beat)
4953
return true;
5054
}
5155

52-
public PuppetTemplate GetTarget(Note note)
56+
public PuppetTemplate[] GetTargets(Note note)
57+
{
58+
if (!note.IsPlayerNote())
59+
return [Player];
60+
switch (note.TargetType)
61+
{
62+
case Targetting.First:
63+
if (GetFirstEnemy() != null)
64+
return [GetFirstEnemy()];
65+
return [];
66+
case Targetting.All:
67+
return _enemies.Where(x => x.GetCurrentHealth() > 0).ToArray();
68+
}
69+
return null;
70+
}
71+
72+
public PuppetTemplate GetFirstEnemy()
5373
{
54-
if (note.Owner == Player)
74+
foreach (var enemy in _enemies)
5575
{
56-
return Enemy;
76+
if (enemy.GetCurrentHealth() > 0)
77+
return enemy;
5778
}
5879

59-
return Player;
80+
return null;
6081
}
6182
#endregion
6283

@@ -99,7 +120,7 @@ public override void _Ready()
99120
private void InitPlayer()
100121
{
101122
Player = GD.Load<PackedScene>(PlayerPuppet.LoadPath).Instantiate<PlayerPuppet>();
102-
AddChild(Player);
123+
PuppetMarkers[0].AddChild(Player);
103124
Player.Defeated += CheckBattleStatus;
104125
EventizeRelics();
105126
NPB.Setup(StageProducer.PlayerStats);
@@ -108,11 +129,19 @@ private void InitPlayer()
108129
private void InitEnemies()
109130
{
110131
//TODO: Refine
111-
Enemy = GD.Load<PackedScene>(StageProducer.Config.EnemyScenePath)
112-
.Instantiate<EnemyPuppet>();
113-
AddChild(Enemy);
114-
Enemy.Defeated += CheckBattleStatus;
115-
AddEnemyEffects();
132+
_enemies = new EnemyPuppet[StageProducer.Config.EnemyScenePath.Length];
133+
for (int i = 0; i < StageProducer.Config.EnemyScenePath.Length; i++)
134+
{
135+
EnemyPuppet enemy = GD.Load<PackedScene>(StageProducer.Config.EnemyScenePath[0])
136+
.Instantiate<EnemyPuppet>();
137+
if (_enemies.Length == 1)
138+
PuppetMarkers[2].AddChild(enemy);
139+
else
140+
PuppetMarkers[i + 1].AddChild(enemy);
141+
enemy.Defeated += CheckBattleStatus;
142+
_enemies[i] = enemy;
143+
AddEnemyEffects(enemy);
144+
}
116145
}
117146

118147
public override void _Process(double delta)
@@ -207,10 +236,15 @@ private void CheckBattleStatus(PuppetTemplate puppet) //Called when a puppet die
207236
OnBattleLost();
208237
return;
209238
}
210-
if (puppet == Enemy)
239+
if (puppet is EnemyPuppet && IsBattleWon())
211240
OnBattleWon(); //will have to adjust this to account for when we have multiple enemies at once
212241
}
213242

243+
private bool IsBattleWon()
244+
{
245+
return GetFirstEnemy() == null;
246+
}
247+
214248
private void OnBattleWon()
215249
{
216250
Audio.StreamPaused = true;
@@ -258,9 +292,9 @@ private void AddEvent(IBattleEvent bEvent)
258292
}
259293
}
260294

261-
private void AddEnemyEffects()
295+
private void AddEnemyEffects(EnemyPuppet enemy)
262296
{
263-
foreach (var effect in Enemy.GetBattleEvents())
297+
foreach (var effect in enemy.GetBattleEvents())
264298
{
265299
AddEvent(effect);
266300
}
@@ -347,6 +381,9 @@ public void InvokeChartLoop(int incLoop)
347381

348382
private void DebugKillEnemy()
349383
{
350-
Enemy.TakeDamage(1000);
384+
foreach (EnemyPuppet enemy in _enemies)
385+
{
386+
enemy.TakeDamage(1000);
387+
}
351388
}
352389
}

Scenes/ChestScene/ChestScene.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ public partial class ChestScene : Node2D
1212
[Export]
1313
public Button ChestButton;
1414

15+
[Export]
16+
public Marker2D PlayerMarker;
17+
1518
public override void _Ready()
1619
{
1720
_player = GD.Load<PackedScene>(PlayerPuppet.LoadPath).Instantiate<PlayerPuppet>();
18-
AddChild(_player);
21+
PlayerMarker.AddChild(_player);
1922

2023
ChestButton.Pressed += GetLoot;
2124
}

0 commit comments

Comments
 (0)