Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Funk Engine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>FunkEngine</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Content Include="SaveData\SaveData.json" />
</ItemGroup>
<Target Name="Husky" BeforeTargets="Restore;CollectPackageReferences" Condition="'$(HUSKY)' != 0">
<Exec Command="dotnet tool restore" StandardOutputImportance="Low" StandardErrorImportance="High" />
<Exec Command="dotnet husky install" StandardOutputImportance="Low" StandardErrorImportance="High" WorkingDirectory="." />
Expand Down
11 changes: 11 additions & 0 deletions Globals/Scribe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ public partial class Scribe : Node
director.Enemy.TakeDamage((int)timing);
}
),
new Note(
"PlayerDouble",
null,
1,
(director, note, timing) =>
{
// can change later, but I want it like this instead of changing base
// in case we have some relic that messes with timing
director.Enemy.TakeDamage(2 * (int)timing);
}
),
};

public static readonly RelicTemplate[] RelicDictionary = new[]
Expand Down
9 changes: 9 additions & 0 deletions SaveData/SaveData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"AccountName": null,
"Notes": {
"PlayerBase": 2,
"PlayerDouble": 1
},
"Relics": {},
"Settings": {}
}
48 changes: 48 additions & 0 deletions SaveData/SaveSystem.cs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using Godot;

// TODO: implement saving

public static class SaveSystem
{
private static string SavePath => "res://SaveData/SaveData.json"; // Update if needed

// Loads only the notes section
public static Dictionary<string, int> LoadNotes()
{
var saveData = LoadSaveData();
if (saveData != null && saveData.Notes != null)
{
return saveData.Notes;
}
else
{
return new Dictionary<string, int>();
}
}

// This method loads the entire save data
public static SaveData LoadSaveData()
{
string path = ProjectSettings.GlobalizePath(SavePath);
if (!File.Exists(path))
{
GD.PrintErr("Can't load save game");
return null;
}

string json = File.ReadAllText(path);
SaveData data = JsonSerializer.Deserialize<SaveData>(json);
return data;
}
}

public class SaveData
{
public string AccountName { get; set; }
public Dictionary<string, int> Notes { get; set; } = new Dictionary<string, int>();
public Dictionary<string, object> Relics { get; set; } = new Dictionary<string, object>();
public Dictionary<string, float> Settings { get; set; } = new Dictionary<string, float>();
}
16 changes: 14 additions & 2 deletions scenes/BattleDirector/scripts/BattleDirector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,31 @@ public partial class BattleDirector : Node2D

private SongData _curSong;

[Export]
private NoteQueue NQ;

#endregion

#region Note Handling
private void PlayerAddNote(ArrowType type, int beat)
{
GD.Print($"Player trying to place {type} typed note at beat: " + beat);
//TODO: note that should be added from the queue
Note note = NQ.GetCurrentNote();
if (note == null)
{
GD.Print("No notes in queue");
return;
}

GD.Print($"Player trying to place {note.Name}:{type} typed note at beat: " + beat);
if (!NotePlacementBar.CanPlaceNote())
return;
if (CD.AddNoteToLane(type, beat % CM.BeatsPerLoop, false))
if (CD.AddNoteToLane(type, beat % CM.BeatsPerLoop, note, false))
{
NotePlacementBar.PlacedNote();
NotePlaced?.Invoke(this);
GD.Print("Note Placed.");
NQ.DequeueNote();
}
}

Expand Down
20 changes: 13 additions & 7 deletions scenes/BattleDirector/scripts/Conductor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private bool IsNoteActive(ArrowType type, int beat)
return _laneData[(int)type][beat] != null && _laneData[(int)type][beat].IsActive;
}

public bool AddNoteToLane(ArrowType type, int beat, bool isActive = true)
public bool AddNoteToLane(ArrowType type, int beat, Note note, bool isActive = true)
{
beat %= CM.BeatsPerLoop;
//Don't add dupe notes //Beat at 0 is too messy.
Expand All @@ -54,12 +54,18 @@ public bool AddNoteToLane(ArrowType type, int beat, bool isActive = true)
NoteArrow arrow;
if (isActive)
{
arrow = CM.AddArrowToLane(type, beat, Notes.Length - 1);
arrow = CM.AddArrowToLane(type, beat, Notes.Length - 1, note);
arrow.NoteIdx = 1;
}
else
{
arrow = CM.AddArrowToLane(type, beat, Notes.Length - 1, new Color(1, 0.43f, 0.26f));
arrow = CM.AddArrowToLane(
type,
beat,
Notes.Length - 1,
note,
new Color(1, 0.43f, 0.26f)
);
arrow.NoteIdx = 0;
}

Expand All @@ -85,22 +91,22 @@ private void AddExampleNotes()
GD.Print(CM.BeatsPerLoop);
for (int i = 1; i < 15; i++)
{
AddNoteToLane(ArrowType.Up, i * 4);
AddNoteToLane(ArrowType.Up, i * 4, Scribe.NoteDictionary[0]);
}

for (int i = 1; i < 15; i++)
{
AddNoteToLane(ArrowType.Left, 4 * i + 1);
AddNoteToLane(ArrowType.Left, 4 * i + 1, Scribe.NoteDictionary[0]);
}

for (int i = 0; i < 10; i++)
{
AddNoteToLane(ArrowType.Right, 3 * i + 32);
AddNoteToLane(ArrowType.Right, 3 * i + 32, Scribe.NoteDictionary[0]);
}

for (int i = 0; i < 3; i++)
{
AddNoteToLane(ArrowType.Down, 8 * i + 16);
AddNoteToLane(ArrowType.Down, 8 * i + 16, Scribe.NoteDictionary[0]);
}
}

Expand Down
17 changes: 15 additions & 2 deletions scenes/BattleDirector/test_battle_scene.tscn
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
[gd_scene load_steps=7 format=3 uid="uid://b0mrgr7h0ty1y"]
[gd_scene load_steps=9 format=3 uid="uid://b0mrgr7h0ty1y"]

[ext_resource type="Script" path="res://scenes/BattleDirector/scripts/BattleDirector.cs" id="1_cwqqr"]
[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://scenes/ChartViewport/ChartViewport.tscn" id="2_cupb3"]
[ext_resource type="Script" path="res://scenes/BattleDirector/scripts/Conductor.cs" id="2_pcp76"]
[ext_resource type="Texture2D" uid="uid://ci0g72j8q4ec2" path="res://scenes/BattleDirector/assets/CoolBG.jpg" id="4_13o87"]
[ext_resource type="PackedScene" uid="uid://duhiilcv4tat3" path="res://scenes/BattleDirector/NotePlacementBar.tscn" id="7_3ko4g"]
[ext_resource type="PackedScene" uid="uid://bvhpon5liybd1" path="res://scenes/CustomNotes/NoteQueue.tscn" id="8_7wwxo"]
[ext_resource type="AudioStream" uid="uid://cv6lqjj6lu36h" path="res://Audio/335571__magntron__gamemusic_120bpm.mp3" id="8_caqms"]

[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CM", "NotePlacementBar", "CD", "Audio")]
[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CM", "NotePlacementBar", "CD", "Audio", "NQ")]
process_mode = 1
script = ExtResource("1_cwqqr")
CM = NodePath("SubViewport")
NotePlacementBar = NodePath("NotePlacementBar")
CD = NodePath("Conductor")
Audio = NodePath("AudioStreamPlayer")
NQ = NodePath("NoteQueue")

[node name="UILayer" type="CanvasLayer" parent="."]

Expand Down Expand Up @@ -58,3 +60,14 @@ offset_right = 613.0
offset_bottom = 188.0
theme_override_font_sizes/font_size = 10
text = "Relics:"

[node name="NoteQueue" parent="." instance=ExtResource("8_7wwxo")]
anchors_preset = 0
anchor_right = 0.0
anchor_bottom = 0.0
offset_left = 100.0
offset_top = 140.0
offset_right = 100.0
offset_bottom = 140.0
grow_horizontal = 1
grow_vertical = 1
9 changes: 5 additions & 4 deletions scenes/ChartViewport/ChartManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,12 @@ public NoteArrow AddArrowToLane(
ArrowType type,
int beat,
int noteIdx,
Note note,
Color colorOverride = default
)
{
var newNote = CreateNote(type, beat);
var loopArrow = CreateNote(type, beat + BeatsPerLoop); //Create a dummy arrow for looping visuals
var newNote = CreateNote(type, note, beat);
var loopArrow = CreateNote(type, note, beat + BeatsPerLoop); //Create a dummy arrow for looping visuals
if (colorOverride != default)
{
newNote.Modulate = colorOverride;
Expand All @@ -116,11 +117,11 @@ public NoteArrow AddArrowToLane(
return newNote;
}

private NoteArrow CreateNote(ArrowType arrow, int beat = 0)
private NoteArrow CreateNote(ArrowType arrow, Note note, int beat = 0)
{
var noteScene = ResourceLoader.Load<PackedScene>("res://scenes/NoteManager/note.tscn");
NoteArrow newArrow = noteScene.Instantiate<NoteArrow>();
newArrow.Init(IH.Arrows[(int)arrow], beat);
newArrow.Init(IH.Arrows[(int)arrow], beat, note);

_arrowGroup.AddChild(newArrow);
newArrow.Bounds = (float)((double)beat / BeatsPerLoop * (ChartLength / 2));
Expand Down
122 changes: 122 additions & 0 deletions scenes/CustomNotes/NoteQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using Godot;

public partial class NoteQueue : Node
{
[Export]
private Sprite2D _currentNote;

[Export]
private Sprite2D _nextNote;

private Queue<Note> _noteQueue = new Queue<Note>();
private Dictionary<string, Texture2D> _noteSprites = new Dictionary<string, Texture2D>();

public override void _Ready()
{
_noteSprites["PlayerBase"] = GD.Load<Texture2D>(
"res://scenes/CustomNotes/assets/single_note.png"
);
_noteSprites["PlayerDouble"] = GD.Load<Texture2D>(
"res://scenes/CustomNotes/assets/double_note.png"
);

LoadQueueFromSave();
ScrambleQueue();
UpdateQueue();
}

// Loads the notes from SaveData.json, and adds them to the queue
public void LoadQueueFromSave()
{
Dictionary<string, int> savedNotes = SaveSystem.LoadNotes();
foreach (var noteEntry in savedNotes)
{
string noteName = noteEntry.Key;
int numNotes = noteEntry.Value;

for (int i = 0; i < numNotes; i++)
{
GD.Print($"Creating note from noteName: {noteName}");
AddNoteToQueue(CreateNoteFromName(noteName));
}
}
}

// Creates a note from a string of the note's name.
private Note CreateNoteFromName(string noteName)
{
if (noteName == "PlayerBase")
return Scribe.NoteDictionary[1];

if (noteName == "PlayerDouble")
return Scribe.NoteDictionary[2];

GD.Print($"Failed to create not from noteName: {noteName}");
return null;
}

public void AddNoteToQueue(Note noteType)
{
_noteQueue.Enqueue(noteType);
UpdateQueue();
}

// Returns current note, and removes it from the queue
public Note GetCurrentNote()
{
if (_noteQueue.Count > 0)
{
return _noteQueue.Peek();
}
return null;
}

public void DequeueNote()
{
_noteQueue.Dequeue();
UpdateQueue();
}

// Updates the queue's graphics
private void UpdateQueue()
{
if (_noteQueue.Count > 0 && _noteSprites.ContainsKey(_noteQueue.Peek().Name))
_currentNote.Texture = _noteSprites[_noteQueue.Peek().Name];
else
_currentNote.Texture = null;

if (_noteQueue.Count > 1)
{
Note[] notes = _noteQueue.ToArray();
if (_noteSprites.ContainsKey(notes[1].Name))
_nextNote.Texture = _noteSprites[notes[1].Name];
else
_nextNote.Texture = null;
}
else
{
_nextNote.Texture = null;
}
}

// Fisher-Yates shuffle from: https://stackoverflow.com/a/1262619
public void ScrambleQueue()
{
List<Note> tempList = new List<Note>(_noteQueue);
Random rng = new Random();

int n = tempList.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
(tempList[k], tempList[n]) = (tempList[n], tempList[k]);
}

_noteQueue = new Queue<Note>(tempList);
}

//TODO: MAYBE? implement saving the notequeue to savedata
}
28 changes: 28 additions & 0 deletions scenes/CustomNotes/NoteQueue.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[gd_scene load_steps=5 format=3 uid="uid://bvhpon5liybd1"]

[ext_resource type="Script" path="res://scenes/CustomNotes/NoteQueue.cs" id="1_jeqam"]
[ext_resource type="Texture2D" uid="uid://cnyr5usjdv0ni" path="res://scenes/CustomNotes/assets/temp_note_queue.png" id="2_0p21a"]
[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://scenes/CustomNotes/assets/single_note.png" id="3_ewo1s"]
[ext_resource type="Texture2D" uid="uid://caw70lr5e1yiq" path="res://scenes/CustomNotes/assets/double_note.png" id="4_7sgy6"]

[node name="NoteQueue" type="Control" node_paths=PackedStringArray("_currentNote", "_nextNote")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_jeqam")
_currentNote = NodePath("CurrentNote")
_nextNote = NodePath("NextNote")

[node name="NoteQueueSprite" type="Sprite2D" parent="."]
texture = ExtResource("2_0p21a")

[node name="CurrentNote" type="Sprite2D" parent="."]
position = Vector2(-14, -1)
texture = ExtResource("3_ewo1s")

[node name="NextNote" type="Sprite2D" parent="."]
position = Vector2(16, -2)
texture = ExtResource("4_7sgy6")
Binary file added scenes/CustomNotes/assets/double_note.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading