diff --git a/Audio/midi/Song1.mid b/Audio/midi/Song1.mid index 3330b86a..8cabb595 100644 Binary files a/Audio/midi/Song1.mid and b/Audio/midi/Song1.mid differ diff --git a/Audio/midi/Song2.mid b/Audio/midi/Song2.mid index 8464b138..49e3e6de 100644 Binary files a/Audio/midi/Song2.mid and b/Audio/midi/Song2.mid differ diff --git a/Audio/midi/Song3.mid b/Audio/midi/Song3.mid index 58e53a49..831fb61f 100644 Binary files a/Audio/midi/Song3.mid and b/Audio/midi/Song3.mid differ diff --git a/Classes/MidiMaestro/MidiMaestro.cs b/Classes/MidiMaestro/MidiMaestro.cs index dfc0b6e1..57e6fca8 100644 --- a/Classes/MidiMaestro/MidiMaestro.cs +++ b/Classes/MidiMaestro/MidiMaestro.cs @@ -4,24 +4,29 @@ using Godot; using Melanchall.DryWetMidi.Core; using Melanchall.DryWetMidi.Interaction; -using Melanchall.DryWetMidi.Multimedia; +/** + MidiMaestro: Manages reading midi file into lane note information. + + */ public partial class MidiMaestro : Resource { private MidiFile _midiFile; - public static TempoMap TempoMap; - public static TimeSignature TimeSignature; + public static TempoMap TempoMap { get; private set; } + public static TimeSignature TimeSignature { get; private set; } //The four note rows that we care about - private midiNoteInfo[] _upNotes; - private midiNoteInfo[] _downNotes; - private midiNoteInfo[] _leftNotes; - private midiNoteInfo[] _rightNotes; + private readonly MidiNoteInfo[] _upNotes; + private readonly MidiNoteInfo[] _downNotes; + private readonly MidiNoteInfo[] _leftNotes; + private readonly MidiNoteInfo[] _rightNotes; //private MidiFile strippedSong; - - //The path relative to the Audio folder. Will change later + /** + * Constructor loads midi file and populates lane note arrays with midiNoteInfo + * A string file path to a valid midi file + */ public MidiMaestro(string filePath) { if (!OS.HasFeature("editor")) @@ -42,9 +47,9 @@ public MidiMaestro(string filePath) foreach (var track in _midiFile.GetTrackChunks()) { string trackName = track.Events.OfType().FirstOrDefault()?.Text; - midiNoteInfo[] noteEvents = track + MidiNoteInfo[] noteEvents = track .GetNotes() - .Select(note => new midiNoteInfo(note)) + .Select(note => new MidiNoteInfo(note)) .ToArray(); switch (trackName) @@ -65,7 +70,10 @@ public MidiMaestro(string filePath) } } - public midiNoteInfo[] GetNotes(ArrowType arrowType) + /** + * Gets midiNoteInfo by lane. + */ + public MidiNoteInfo[] GetNotes(ArrowType arrowType) { return arrowType switch { @@ -79,11 +87,11 @@ public midiNoteInfo[] GetNotes(ArrowType arrowType) } //A facade to wrap the midi notes. This is a simple class that wraps a Note object from the DryWetMidi library. -public class midiNoteInfo +public class MidiNoteInfo { private readonly Melanchall.DryWetMidi.Interaction.Note _note; - public midiNoteInfo(Melanchall.DryWetMidi.Interaction.Note note) + public MidiNoteInfo(Melanchall.DryWetMidi.Interaction.Note note) { _note = note; } @@ -100,7 +108,16 @@ public float GetStartTimeSeconds() => _note.TimeAs(MidiMaestro.TempoMap).Milliseconds / 1000f + _note.TimeAs(MidiMaestro.TempoMap).Seconds; - public long GetEndTime() => _note.EndTime; + public long GetEndTime() => _note.EndTime; //ticks + + public long GetDuration() => _note.Length; //ticks - public long GetDuration() => _note.Length; + public long GetDurationBeats() + { + var beatsBar = TimeConverter.ConvertTo( + _note.Length, + MidiMaestro.TempoMap + ); + return beatsBar.Bars * MidiMaestro.TimeSignature.Numerator + beatsBar.Beats; + } } diff --git a/Classes/MidiMaestro/SongTemplate.cs b/Classes/MidiMaestro/SongTemplate.cs index bf63c2b9..bb967a59 100644 --- a/Classes/MidiMaestro/SongTemplate.cs +++ b/Classes/MidiMaestro/SongTemplate.cs @@ -1,11 +1,14 @@ namespace FunkEngine.Classes.MidiMaestro; -public partial class SongTemplate +/** + * SongTemplate: Generic class to represent a rhythm battle. + */ +public struct SongTemplate { public string Name; - public string AudioLocation; + public readonly string AudioLocation; public string MIDILocation; - public string EnemyScenePath; + public readonly string EnemyScenePath; public SongData SongData; public SongTemplate( diff --git a/Classes/Notes/assets/single_note.png b/Classes/Notes/Assets/Note_PlayerBasic.png similarity index 100% rename from Classes/Notes/assets/single_note.png rename to Classes/Notes/Assets/Note_PlayerBasic.png diff --git a/Classes/Notes/assets/single_note.png.import b/Classes/Notes/Assets/Note_PlayerBasic.png.import similarity index 69% rename from Classes/Notes/assets/single_note.png.import rename to Classes/Notes/Assets/Note_PlayerBasic.png.import index 63160ba7..11064758 100644 --- a/Classes/Notes/assets/single_note.png.import +++ b/Classes/Notes/Assets/Note_PlayerBasic.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://c3chrsxrulapd" -path="res://.godot/imported/single_note.png-edadc3d6779f4cc26ac823d186717719.ctex" +path="res://.godot/imported/Note_PlayerBasic.png-8e39c4aa6664f4092d3fb2ac9f14cce6.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Notes/assets/single_note.png" -dest_files=["res://.godot/imported/single_note.png-edadc3d6779f4cc26ac823d186717719.ctex"] +source_file="res://Classes/Notes/Assets/Note_PlayerBasic.png" +dest_files=["res://.godot/imported/Note_PlayerBasic.png-8e39c4aa6664f4092d3fb2ac9f14cce6.ctex"] [params] diff --git a/Classes/Notes/assets/double_note.png b/Classes/Notes/Assets/Note_PlayerDouble.png similarity index 100% rename from Classes/Notes/assets/double_note.png rename to Classes/Notes/Assets/Note_PlayerDouble.png diff --git a/Classes/Notes/assets/double_note.png.import b/Classes/Notes/Assets/Note_PlayerDouble.png.import similarity index 69% rename from Classes/Notes/assets/double_note.png.import rename to Classes/Notes/Assets/Note_PlayerDouble.png.import index ea62f194..c1b01c08 100644 --- a/Classes/Notes/assets/double_note.png.import +++ b/Classes/Notes/Assets/Note_PlayerDouble.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://caw70lr5e1yiq" -path="res://.godot/imported/double_note.png-1b788aee0b7f76d502303d178d821d3b.ctex" +path="res://.godot/imported/Note_PlayerDouble.png-9f112bc39494bd9420dfe4ce034039fa.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Notes/assets/double_note.png" -dest_files=["res://.godot/imported/double_note.png-1b788aee0b7f76d502303d178d821d3b.ctex"] +source_file="res://Classes/Notes/Assets/Note_PlayerDouble.png" +dest_files=["res://.godot/imported/Note_PlayerDouble.png-9f112bc39494bd9420dfe4ce034039fa.ctex"] [params] diff --git a/Classes/Notes/assets/heal_note.png b/Classes/Notes/Assets/Note_PlayerHeal.png similarity index 100% rename from Classes/Notes/assets/heal_note.png rename to Classes/Notes/Assets/Note_PlayerHeal.png diff --git a/Classes/Notes/assets/heal_note.png.import b/Classes/Notes/Assets/Note_PlayerHeal.png.import similarity index 69% rename from Classes/Notes/assets/heal_note.png.import rename to Classes/Notes/Assets/Note_PlayerHeal.png.import index 22f3a997..f83e8a2e 100644 --- a/Classes/Notes/assets/heal_note.png.import +++ b/Classes/Notes/Assets/Note_PlayerHeal.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cdf3g3174du4r" -path="res://.godot/imported/heal_note.png-09ca289a296eee82d33c64101a4e593a.ctex" +path="res://.godot/imported/Note_PlayerHeal.png-5679ecbd30dd234cfea43cc6fb83ee76.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Notes/assets/heal_note.png" -dest_files=["res://.godot/imported/heal_note.png-09ca289a296eee82d33c64101a4e593a.ctex"] +source_file="res://Classes/Notes/Assets/Note_PlayerHeal.png" +dest_files=["res://.godot/imported/Note_PlayerHeal.png-5679ecbd30dd234cfea43cc6fb83ee76.ctex"] [params] diff --git a/Classes/Notes/assets/quarter_note.png b/Classes/Notes/Assets/Note_PlayerQuarter.png similarity index 100% rename from Classes/Notes/assets/quarter_note.png rename to Classes/Notes/Assets/Note_PlayerQuarter.png diff --git a/Classes/Notes/assets/quarter_note.png.import b/Classes/Notes/Assets/Note_PlayerQuarter.png.import similarity index 68% rename from Classes/Notes/assets/quarter_note.png.import rename to Classes/Notes/Assets/Note_PlayerQuarter.png.import index 0729e611..7e54973a 100644 --- a/Classes/Notes/assets/quarter_note.png.import +++ b/Classes/Notes/Assets/Note_PlayerQuarter.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://uksjoqp7p0gq" -path="res://.godot/imported/quarter_note.png-2b4c9985d99038807abfd63e553c2d6a.ctex" +path="res://.godot/imported/Note_PlayerQuarter.png-b678f5b1b075ececef380edabf9dfb63.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Notes/assets/quarter_note.png" -dest_files=["res://.godot/imported/quarter_note.png-2b4c9985d99038807abfd63e553c2d6a.ctex"] +source_file="res://Classes/Notes/Assets/Note_PlayerQuarter.png" +dest_files=["res://.godot/imported/Note_PlayerQuarter.png-b678f5b1b075ececef380edabf9dfb63.ctex"] [params] diff --git a/Classes/Notes/assets/vampire_note.png b/Classes/Notes/Assets/Note_PlayerVampire.png similarity index 100% rename from Classes/Notes/assets/vampire_note.png rename to Classes/Notes/Assets/Note_PlayerVampire.png diff --git a/Classes/Notes/assets/vampire_note.png.import b/Classes/Notes/Assets/Note_PlayerVampire.png.import similarity index 68% rename from Classes/Notes/assets/vampire_note.png.import rename to Classes/Notes/Assets/Note_PlayerVampire.png.import index 65be637e..5a6fd8d5 100644 --- a/Classes/Notes/assets/vampire_note.png.import +++ b/Classes/Notes/Assets/Note_PlayerVampire.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dg0lmu0pip4lr" -path="res://.godot/imported/vampire_note.png-4331f817a6feee1f1066a9e9f95934c8.ctex" +path="res://.godot/imported/Note_PlayerVampire.png-038429e14b819cbb968ff50682ccabc6.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Notes/assets/vampire_note.png" -dest_files=["res://.godot/imported/vampire_note.png-4331f817a6feee1f1066a9e9f95934c8.ctex"] +source_file="res://Classes/Notes/Assets/Note_PlayerVampire.png" +dest_files=["res://.godot/imported/Note_PlayerVampire.png-038429e14b819cbb968ff50682ccabc6.ctex"] [params] diff --git a/Classes/Notes/Note.cs b/Classes/Notes/Note.cs index 87f35cf2..ef8bf758 100644 --- a/Classes/Notes/Note.cs +++ b/Classes/Notes/Note.cs @@ -3,8 +3,7 @@ using Godot; /** - * @class Note - * @brief Data structure class for holding data and methods for a battle time note. WIP + * Note: Data structure class for holding data and methods for a battle time note. */ public partial class Note : Resource, IDisplayable { @@ -15,6 +14,8 @@ public partial class Note : Resource, IDisplayable public float CostModifier { get; private set; } private Action NoteEffect; + public const double TimingMax = 0.5d; //The max range for a note to be timed is its beat +/- this const + public string Tooltip { get; set; } public Texture2D Texture { get; set; } @@ -35,9 +36,9 @@ public Note( NoteEffect = noteEffect ?? ( - (BD, source, Timing) => + (BD, source, timing) => { - BD.GetTarget(this).TakeDamage((int)Timing * source._baseVal); + BD.GetTarget(this).TakeDamage((int)timing * source._baseVal); } ); _baseVal = baseVal; @@ -68,6 +69,11 @@ public Note Clone() return newNote; } + public bool IsPlayerNote() + { + return Name.Contains("Player"); + } + public int GetBaseVal() { return _baseVal; diff --git a/Classes/Relics/assets/Auroboros.png b/Classes/Relics/Assets/Relic_Auroboros.png similarity index 100% rename from Classes/Relics/assets/Auroboros.png rename to Classes/Relics/Assets/Relic_Auroboros.png diff --git a/Classes/Relics/assets/Auroboros.png.import b/Classes/Relics/Assets/Relic_Auroboros.png.import similarity index 69% rename from Classes/Relics/assets/Auroboros.png.import rename to Classes/Relics/Assets/Relic_Auroboros.png.import index d0051264..48224195 100644 --- a/Classes/Relics/assets/Auroboros.png.import +++ b/Classes/Relics/Assets/Relic_Auroboros.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cqlrv1vra4mbn" -path="res://.godot/imported/Auroboros.png-27bfe2114f3955a0f6ef5ceb4e65adbf.ctex" +path="res://.godot/imported/Relic_Auroboros.png-c5b164882e0cc6b4eae662aec80abbce.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Relics/assets/Auroboros.png" -dest_files=["res://.godot/imported/Auroboros.png-27bfe2114f3955a0f6ef5ceb4e65adbf.ctex"] +source_file="res://Classes/Relics/Assets/Relic_Auroboros.png" +dest_files=["res://.godot/imported/Relic_Auroboros.png-c5b164882e0cc6b4eae662aec80abbce.ctex"] [params] diff --git a/Classes/Relics/assets/Colorboros.png b/Classes/Relics/Assets/Relic_Colorboros.png similarity index 100% rename from Classes/Relics/assets/Colorboros.png rename to Classes/Relics/Assets/Relic_Colorboros.png diff --git a/Classes/Relics/assets/Colorboros.png.import b/Classes/Relics/Assets/Relic_Colorboros.png.import similarity index 69% rename from Classes/Relics/assets/Colorboros.png.import rename to Classes/Relics/Assets/Relic_Colorboros.png.import index 81d7b2ea..ed1f3403 100644 --- a/Classes/Relics/assets/Colorboros.png.import +++ b/Classes/Relics/Assets/Relic_Colorboros.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://ccd6pskxcwpxg" -path="res://.godot/imported/Colorboros.png-56197d792c620150c773fb4ecce6289c.ctex" +path="res://.godot/imported/Relic_Colorboros.png-406af684be0b51f2232e99d2ace4dff9.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Relics/assets/Colorboros.png" -dest_files=["res://.godot/imported/Colorboros.png-56197d792c620150c773fb4ecce6289c.ctex"] +source_file="res://Classes/Relics/Assets/Relic_Colorboros.png" +dest_files=["res://.godot/imported/Relic_Colorboros.png-406af684be0b51f2232e99d2ace4dff9.ctex"] [params] diff --git a/Classes/Relics/RelicEffect.cs b/Classes/Relics/RelicEffect.cs index c5a52109..bb2cedf3 100644 --- a/Classes/Relics/RelicEffect.cs +++ b/Classes/Relics/RelicEffect.cs @@ -2,6 +2,9 @@ using FunkEngine; using Godot; +/** + * RelicEffect: BattleDirector effect as handled by a player passive relic. + */ public partial class RelicEffect : IBattleEvent { private BattleEffectTrigger Trigger { get; set; } diff --git a/Classes/Relics/RelicTemplate.cs b/Classes/Relics/RelicTemplate.cs index 13dee51c..3e51c656 100644 --- a/Classes/Relics/RelicTemplate.cs +++ b/Classes/Relics/RelicTemplate.cs @@ -1,10 +1,12 @@ -using System; using FunkEngine; using Godot; +/** + * RelicTemplate: Generic class representing a player passive relic. + */ public partial class RelicTemplate : Resource, IDisplayable { - public RelicEffect[] Effects; + public readonly RelicEffect[] Effects; public int Id; public string Name { get; set; } diff --git a/Classes/Relics/assets/relic_Breakfast.png.import b/Classes/Relics/assets/relic_Breakfast.png.import index 6a21aa03..afa89070 100644 --- a/Classes/Relics/assets/relic_Breakfast.png.import +++ b/Classes/Relics/assets/relic_Breakfast.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://csjx2hb4tdlw8" -path="res://.godot/imported/relic_Breakfast.png-c1b968058adbb855fcf957a2aec74dc2.ctex" +path="res://.godot/imported/Relic_Breakfast.png-71ab89b12909df408626427d83246628.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Relics/assets/relic_Breakfast.png" -dest_files=["res://.godot/imported/relic_Breakfast.png-c1b968058adbb855fcf957a2aec74dc2.ctex"] +source_file="res://Classes/Relics/Assets/Relic_Breakfast.png" +dest_files=["res://.godot/imported/Relic_Breakfast.png-71ab89b12909df408626427d83246628.ctex"] [params] diff --git a/Classes/Relics/assets/relic_GoodVibes.png.import b/Classes/Relics/assets/relic_GoodVibes.png.import index c2ff344d..ea4e6399 100644 --- a/Classes/Relics/assets/relic_GoodVibes.png.import +++ b/Classes/Relics/assets/relic_GoodVibes.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dg4tnp7plxmp7" -path="res://.godot/imported/relic_GoodVibes.png-cd102b29bb163411bb7ce8cf724ef0c0.ctex" +path="res://.godot/imported/Relic_GoodVibes.png-01d38d3d6a79fe959565a2bfe43c64ca.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Classes/Relics/assets/relic_GoodVibes.png" -dest_files=["res://.godot/imported/relic_GoodVibes.png-cd102b29bb163411bb7ce8cf724ef0c0.ctex"] +source_file="res://Classes/Relics/Assets/Relic_GoodVibes.png" +dest_files=["res://.godot/imported/Relic_GoodVibes.png-01d38d3d6a79fe959565a2bfe43c64ca.ctex"] [params] diff --git a/Funk Engine.csproj b/Funk Engine.csproj index e6707425..79bf1b7c 100644 --- a/Funk Engine.csproj +++ b/Funk Engine.csproj @@ -7,9 +7,11 @@ FunkEngine - + + + diff --git a/Globals/BgAudioPlayer/BgAudioPlayer.cs b/Globals/BgAudioPlayer/BgAudioPlayer.cs index 35f17e75..13c791f2 100644 --- a/Globals/BgAudioPlayer/BgAudioPlayer.cs +++ b/Globals/BgAudioPlayer/BgAudioPlayer.cs @@ -1,9 +1,20 @@ using Godot; +/** + * BgAudioPlayer: Autoload to play scene persistant music. + */ public partial class BgAudioPlayer : AudioStreamPlayer { - private readonly AudioStream _levelMusic = (AudioStream) - ResourceLoader.Load("res://scenes/SceneTransitions/assets/titleSong.ogg"); + private readonly AudioStream _levelMusic = ResourceLoader.Load( + "res://Scenes/UI/TitleScreen/Assets/TitleSong.ogg" + ); + + public static BgAudioPlayer LiveInstance { get; private set; } + + public override void _EnterTree() + { + LiveInstance = this; + } private void PlayMusic(AudioStream music, float volume) { diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index fc70a91a..34c03684 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -5,6 +5,10 @@ namespace FunkEngine; +#region Structs +/** + * SongData: Basic information defining the statistics of an in-battle song. + */ public struct SongData { public int Bpm; @@ -12,7 +16,10 @@ public struct SongData public int NumLoops; } -public struct ArrowData +/** + * ArrowData: Data representing the necessary information for each arrow checker. + */ +public struct CheckerData { public Color Color; public string Key; @@ -20,6 +27,184 @@ public struct ArrowData public ArrowType Type; } +/** + * BattleConfig: Necessary data for a battle. + */ +public struct BattleConfig +{ + public Stages RoomType; + public MapGrid.Room BattleRoom; + public string EnemyScenePath; + public SongTemplate CurSong; +} + +/** + * NoteArrowData: Data To be stored and transmitted to represent a NoteArrow. + */ +public struct ArrowData : IEquatable, IComparable +{ + public ArrowData(ArrowType type, Beat beat, Note note, double length = 0) + { + Beat = beat; + Type = type; + NoteRef = note; + Length = length; + } + + public Beat Beat; + public readonly double Length; //in beats, should never be >= loop + public readonly ArrowType Type; + public readonly Note NoteRef = null; + + public static ArrowData Placeholder { get; private set; } = + new(default, default, new Note(-1, "", "")); + + public ArrowData BeatFromLength() + { + Beat += Length; + return this; + } + + public bool Equals(ArrowData other) + { + return Beat.Equals(other.Beat) && Type == other.Type; + } + + public override bool Equals(object obj) + { + return obj is ArrowData other && Equals(other); + } + + public static bool operator ==(ArrowData left, ArrowData right) + { + return left.Equals(right); + } + + public static bool operator !=(ArrowData left, ArrowData right) + { + return !(left == right); + } + + public override int GetHashCode() + { + return HashCode.Combine(Beat, (int)Type); + } + + public int CompareTo(ArrowData data) //Only care about beat for comparison + { + if ((int)Beat.BeatPos == (int)data.Beat.BeatPos && Beat.Loop == data.Beat.Loop) + { + if (Type == data.Type) + { + return Beat.CompareTo(data.Beat); + } + return Type.CompareTo(data.Type); + } + + return Beat.CompareTo(data.Beat); + } +} + +/** + * Beat: Data representing a beat and its loop num. + */ +public struct Beat : IEquatable, IComparable +{ + public int Loop = 0; + public double BeatPos = 0; + public static readonly Beat One = new Beat(1); + public static readonly Beat Zero = new Beat(0); + + public Beat(double beat) + { + Loop = (int)(beat / TimeKeeper.BeatsPerLoop); + BeatPos = beat % TimeKeeper.BeatsPerLoop; + } + + public Beat(double beat, int loop) + { + Loop = loop; + BeatPos = beat % TimeKeeper.BeatsPerLoop; + } + + public double GetBeatInSong() + { + return BeatPos + Loop * TimeKeeper.BeatsPerLoop % TimeKeeper.BeatsPerSong; + } + + public Beat IncDecLoop(int amount) + { + Loop += amount; + return this; + } + + public Beat RoundBeat() + { + BeatPos = (int)Math.Round(BeatPos); //This can technically overflow, but causes no bugs yet. + return this; + } + + public override string ToString() + { + return $"Beat: {BeatPos}, Loop: {Loop}"; + } + + public static bool operator >(Beat beat1, Beat beat2) + { + return beat1.Loop > beat2.Loop + || (beat1.Loop == beat2.Loop && beat1.BeatPos > beat2.BeatPos); + } + + public static bool operator <(Beat beat1, Beat beat2) + { + return beat1.Loop < beat2.Loop + || (beat1.Loop == beat2.Loop && beat1.BeatPos < beat2.BeatPos); + } + + public static bool operator <=(Beat beat1, Beat beat2) + { + return beat1.Equals(beat2) || beat1 < beat2; + } + + public static bool operator >=(Beat beat1, Beat beat2) + { + return beat1.Equals(beat2) || beat1 > beat2; + } + + public static Beat operator +(Beat beat1, double beatInc) + { + return new Beat(beat1.BeatPos + beatInc).IncDecLoop(beat1.Loop); + } + + public static Beat operator -(Beat beat1, double beatDec) + { + return new Beat(beat1.BeatPos - beatDec).IncDecLoop(beat1.Loop); + } + + public static Beat operator -(Beat beat1, Beat beat2) + { + return new Beat(beat1.BeatPos - beat2.BeatPos).IncDecLoop(beat1.Loop - beat2.Loop); + } + + public bool Equals(Beat other) + { + return Loop == other.Loop && BeatPos.Equals(other.BeatPos); + } + + public override int GetHashCode() + { + return HashCode.Combine(Loop, BeatPos); + } + + public int CompareTo(Beat other) + { + var loopComparison = Loop.CompareTo(other.Loop); + return loopComparison != 0 ? loopComparison : BeatPos.CompareTo(other.BeatPos); + } +} +#endregion + +#region Enums public enum ArrowType { Up = 0, @@ -37,14 +222,6 @@ public enum Timing Perfect = 4, } -public struct BattleConfig -{ - public Stages RoomType; - public MapGrid.Room BattleRoom; - public string EnemyScenePath; - public SongTemplate CurSong; -} - public enum BattleEffectTrigger { NotePlaced, @@ -64,12 +241,18 @@ public enum Stages Map, Load, } +#endregion +/** + * MapGrid: Map as data. + * Essentially a width by height grid. Valid rooms are determined by choosing a random starting room at height: 0, and makes random walks to height: height. + * Walks go from x,y to {x/x+1/x-1},y+1 + */ public class MapGrid { private int[,] _map; private Room[] _rooms; - private int _curIdx = 0; + private int _curIdx; public Room[] GetRooms() { @@ -104,6 +287,9 @@ public void AddChild(int newIdx) } } + /** + * Initializes the map with max width, max height, and with number of paths. + */ public void InitMapGrid(int width, int height, int paths) { _curIdx = 0; @@ -123,7 +309,7 @@ public void InitMapGrid(int width, int height, int paths) AddBossRoom(width, height); } - //Start at x, y, assume prev room exists. Picks new x pos within +/- 1, attaches recursively + /**Start at x, y, assume prev room exists. Picks new x pos within +/- 1, attaches recursively*/ private void GeneratePath_r(int x, int y, int width, int height) { int nextX = StageProducer.GlobalRng.RandiRange( @@ -185,6 +371,10 @@ private void AddBossRoom(int width, int height) } } +#region Interfaces +/** + * A BattleDirector driven battle event. Needs an enum defined trigger. + */ public interface IBattleEvent { void OnTrigger(BattleDirector BD); @@ -197,3 +387,13 @@ public interface IDisplayable string Tooltip { get; set; } Texture2D Texture { get; set; } } + +public interface IFocusableMenu +{ + IFocusableMenu Prev { get; set; } + void OpenMenu(IFocusableMenu parentMenu); + void PauseFocus(); + void ResumeFocus(); + void ReturnToPrev(); +} +#endregion diff --git a/SaveData/SaveSystem.cs b/Globals/SaveSystem.cs similarity index 83% rename from SaveData/SaveSystem.cs rename to Globals/SaveSystem.cs index d3a65d03..de754cfb 100644 --- a/SaveData/SaveSystem.cs +++ b/Globals/SaveSystem.cs @@ -1,18 +1,18 @@ -using System; -using System.Collections.Generic; -using System.IO; using System.Linq; using System.Text.Json; using Godot; using FileAccess = Godot.FileAccess; +/** + * SaveSystem: Manages FileI/O of configs and save files. + */ public static class SaveSystem { #region Config private const string UserConfigPath = "user://Options.cfg"; private static ConfigFile _curConfigData; - private const float DefaultVolume = 80f; + private const float DefaultVolume = 1f; private const string DefaultInput = "WASD"; private const string DefaultLanguage = "en"; private const bool DefaultHighCon = false; @@ -25,7 +25,9 @@ public enum ConfigSettings HighContrast, } - //Initializes a new Config and saves it + /** + * Overwrites any file at UserConfigPath + */ private static void InitConfig() { _curConfigData = new ConfigFile(); @@ -35,14 +37,12 @@ private static void InitConfig() UpdateConfig(ConfigSettings.HighContrast, DefaultHighCon); } - //Saves config private static void SaveConfig() { AssertConfigFile(); _curConfigData.Save(UserConfigPath); } - //Update a config of relevant setting and saves public static void UpdateConfig(ConfigSettings setting, Variant value) { AssertConfigFile(); @@ -67,7 +67,8 @@ public static void UpdateConfig(ConfigSettings setting, Variant value) SaveConfig(); } - //Verifies a config file is currently loaded. + /**Either returns, loads current config, or if no config found inits one. + */ private static void AssertConfigFile() { if (_curConfigData == null) @@ -76,8 +77,8 @@ private static void AssertConfigFile() } } - //Really naive approach to verifying config integrity, could I have just changed back to JSON? yes. But I'm a real programmer. - //In theory ConfigFiles should be more stable across any version changes. + /**Really naive approach to verifying config integrity, could I have just changed back to JSON? yes. But I'm a real programmer. + In theory ConfigFiles should be more stable across any version changes.*/ private static void VerifyConfig() { if (!FileAccess.FileExists(UserConfigPath)) @@ -99,7 +100,6 @@ private static void VerifyConfig() InitConfig(); } - // This method loads the entire save data private static void LoadConfigData() { _curConfigData = new ConfigFile(); @@ -111,7 +111,6 @@ private static void LoadConfigData() SaveConfig(); } - //Gets config value public static Variant GetConfigValue(ConfigSettings setting) { AssertConfigFile(); @@ -126,9 +125,7 @@ public static Variant GetConfigValue(ConfigSettings setting) case ConfigSettings.HighContrast: return _curConfigData.GetValue("Options", "HighContrast", DefaultHighCon); default: - GD.PushError( - "SaveSystem.GetConfigValue: Invalid config setting passed. " + setting - ); + GD.PushError("Invalid config setting passed. " + setting); return float.MinValue; } } @@ -138,20 +135,15 @@ public static Variant GetConfigValue(ConfigSettings setting) private const string UserSavePath = "user://MidnighRiff.save"; - /* - * Values to save: - * Globals: rng seed, rng state, current room (hopefully id) - * Player: Id's of relics, id's of notes, current health - */ public class SaveFile { - public ulong RngSeed { get; set; } - public ulong RngState { get; set; } - public int LastRoomIdx { get; set; } + public ulong RngSeed { get; init; } + public ulong RngState { get; init; } + public int LastRoomIdx { get; init; } - public int[] NoteIds { get; set; } - public int[] RelicIds { get; set; } - public int PlayerHealth { get; set; } + public int[] NoteIds { get; init; } + public int[] RelicIds { get; init; } + public int PlayerHealth { get; init; } public SaveFile( ulong rngSeed, @@ -191,6 +183,9 @@ public static void SaveGame() file.Close(); } + /** + * Returns null if invalid save or save 404's. + */ public static SaveFile LoadGame() { if (!FileAccess.FileExists(UserSavePath)) diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index cc9c2a14..526a60a0 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -1,11 +1,10 @@ -using System; using System.Linq; using FunkEngine; using FunkEngine.Classes.MidiMaestro; using Godot; /** - * Global for storing defined data, e.g. Notes and Relic Dictionaries. + * Catch all for storing defined data. Catch all as single source of truth for items and battles. */ public partial class Scribe : Node { @@ -27,7 +26,7 @@ public partial class Scribe : Node 1, "PlayerBase", "Basic player note, deals damage to enemy.", - GD.Load("res://Classes/Notes/assets/single_note.png"), + GD.Load("res://Classes/Notes/Assets/Note_PlayerBasic.png"), null, 1, (director, note, timing) => @@ -41,7 +40,7 @@ public partial class Scribe : Node 2, "PlayerDouble", "Basic player note, deals double damage to enemy.", - GD.Load("res://Classes/Notes/assets/double_note.png"), + GD.Load("res://Classes/Notes/Assets/Note_PlayerDouble.png"), null, 2, (director, note, timing) => @@ -55,7 +54,7 @@ public partial class Scribe : Node 3, "PlayerHeal", "Basic player note, heals player.", - GD.Load("res://Classes/Notes/assets/heal_note.png"), + GD.Load("res://Classes/Notes/Assets/Note_PlayerHeal.png"), null, 1, (director, note, timing) => @@ -69,7 +68,7 @@ public partial class Scribe : Node 4, "PlayerVampire", "Steals health from enemy.", - GD.Load("res://Classes/Notes/assets/vampire_note.png"), + GD.Load("res://Classes/Notes/Assets/Note_PlayerVampire.png"), null, 1, (director, note, timing) => @@ -84,7 +83,7 @@ public partial class Scribe : Node 5, "PlayerQuarter", "Basic note at a quarter of the cost.", - GD.Load("res://Classes/Notes/assets/quarter_note.png"), + GD.Load("res://Classes/Notes/Assets/Note_PlayerQuarter.png"), null, 1, (director, note, timing) => @@ -103,7 +102,7 @@ public partial class Scribe : Node 0, "Breakfast", //Reference ha ha, Item to give when relic pool is empty. "Increases max hp.", //TODO: Description can include the relics values? - GD.Load("res://Classes/Relics/assets/relic_Breakfast.png"), + GD.Load("res://Classes/Relics/Assets/Relic_Breakfast.png"), new RelicEffect[] { new RelicEffect( @@ -121,7 +120,7 @@ public partial class Scribe : Node 1, "Good Vibes", "Heals the player whenever they place a note.", - GD.Load("res://Classes/Relics/assets/relic_GoodVibes.png"), + GD.Load("res://Classes/Relics/Assets/Relic_GoodVibes.png"), new RelicEffect[] { new RelicEffect( @@ -138,7 +137,7 @@ public partial class Scribe : Node 2, "Auroboros", "Bigger number, better person. Increases combo multiplier every riff.", - GD.Load("res://Classes/Relics/assets/Auroboros.png"), + GD.Load("res://Classes/Relics/Assets/Relic_Auroboros.png"), new RelicEffect[] { new RelicEffect( @@ -146,7 +145,7 @@ public partial class Scribe : Node 1, (director, self, val) => { - director.NotePlacementBar.IncreaseBonusMult(val); + director.NPB.IncreaseBonusMult(val); self.Value++; } ), @@ -156,16 +155,16 @@ public partial class Scribe : Node 3, "Colorboros", "Taste the rainbow. Charges the freestyle bar every riff.", - GD.Load("res://Classes/Relics/assets/Colorboros.png"), + GD.Load("res://Classes/Relics/Assets/Relic_Colorboros.png"), new RelicEffect[] { new RelicEffect( BattleEffectTrigger.OnLoop, - 20, + 10, (director, self, val) => { - director.NotePlacementBar.IncreaseCharge(val); - self.Value++; + director.NPB.IncreaseCharge(val); + self.Value += 5; } ), } @@ -183,7 +182,7 @@ public partial class Scribe : Node }, "Song1", "Audio/Song1.ogg", - "Audio/midi/Song1.mid" + "Audio/Midi/Song1.mid" ), new SongTemplate( new SongData @@ -194,8 +193,8 @@ public partial class Scribe : Node }, "Song2", "Audio/Song2.ogg", - "Audio/midi/Song2.mid", - "res://scenes/Puppets/Enemies/Parasifly/Parasifly.tscn" + "Audio/Midi/Song2.mid", + P_Parasifly.LoadPath ), new SongTemplate( new SongData @@ -206,21 +205,24 @@ public partial class Scribe : Node }, "Song3", "Audio/Song3.ogg", - "Audio/midi/Song3.mid", - "res://scenes/Puppets/Enemies/TheGWS/GWS.tscn" + "Audio/Midi/Song3.mid", + P_TheGWS.LoadPath ), }; //TODO: Item pool(s) - public static RelicTemplate[] GetRandomRelics(RelicTemplate[] ownedRelics, int count) + public static RelicTemplate[] GetRandomRelics(RelicTemplate[] excludedRelics, int count) { var availableRelics = Scribe - .RelicDictionary.Where(r => ownedRelics.All(o => o.Name != r.Name)) + .RelicDictionary.Where(r => excludedRelics.All(o => o.Name != r.Name)) .ToArray(); + RandomNumberGenerator lootRng = new RandomNumberGenerator(); + lootRng.SetSeed(StageProducer.GlobalRng.Seed + (ulong)StageProducer.CurRoom); + availableRelics = availableRelics - .OrderBy(_ => StageProducer.GlobalRng.Randi()) + .OrderBy(_ => lootRng.Randi()) .Take(count) .Select(r => r.Clone()) .ToArray(); @@ -238,8 +240,11 @@ public static Note[] GetRandomRewardNotes(int count) .NoteDictionary.Where(r => r.Name.Contains("Player")) //TODO: Classifications/pools .ToArray(); + RandomNumberGenerator lootRng = new RandomNumberGenerator(); + lootRng.SetSeed(StageProducer.GlobalRng.Seed + (ulong)StageProducer.CurRoom); + availableNotes = availableNotes - .OrderBy(_ => StageProducer.GlobalRng.Randi()) + .OrderBy(_ => lootRng.Randi()) .Take(count) .Select(r => r.Clone()) .ToArray(); diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs index 7c1a9682..64de9178 100644 --- a/Globals/StageProducer.cs +++ b/Globals/StageProducer.cs @@ -1,32 +1,37 @@ using System; -using System.Linq; +using System.Threading.Tasks; using FunkEngine; using Godot; +/** + * StageProducer: Handles scene transitions and persistent gameplay data. + */ public partial class StageProducer : Node { - //Generate a map, starting as a width x height grid, pick a starting spot and do (path) paths from that to the last - //row, connecting the path, then connect all at the end to the boss room. - public static RandomNumberGenerator GlobalRng = new RandomNumberGenerator(); + public static StageProducer LiveInstance { get; private set; } public static bool IsInitialized; + public static readonly RandomNumberGenerator GlobalRng = new(); + + public static Vector2I MapSize { get; } = new(7, 6); //For now, make width an odd number + public static MapGrid Map { get; } = new(); private Stages _curStage = Stages.Title; - private Node _curScene; public static int CurRoom { get; private set; } - public static Vector2I MapSize { get; private set; } = new Vector2I(7, 6); //For now, make width an odd number - public static MapGrid Map { get; } = new MapGrid(); + private Node _curScene; + private Node _preloadStage; - public static BattleConfig Config; + public static BattleConfig Config { get; private set; } - //Hold here to persist between changes - public static PlayerStats PlayerStats; + public static PlayerStats PlayerStats { get; private set; } //Hold here to persist between changes - public static CanvasLayer ContrastFilter; + public static CanvasLayer ContrastFilter { get; private set; } + #region Initialization public override void _EnterTree() { InitFromCfg(); + LiveInstance = this; } private void InitFromCfg() @@ -45,17 +50,24 @@ private void InitFromCfg() GetTree().Root.CallDeferred("add_child", ContrastFilter); } - public void StartGame() + private void GenerateMapConsistent() + { + GlobalRng.State = GlobalRng.Seed << 5 / 2; //Fudge seed state, to get consistent maps across new/loaded games + Map.InitMapGrid(MapSize.X, MapSize.Y, 3); + } + + private void StartNewGame() { GlobalRng.Randomize(); GenerateMapConsistent(); + PlayerStats = new PlayerStats(); CurRoom = Map.GetRooms()[0].Idx; IsInitialized = true; } - public bool LoadGame() + private bool LoadGame() { SaveSystem.SaveFile sv = SaveSystem.LoadGame(); if (sv == null) @@ -82,26 +94,49 @@ public bool LoadGame() IsInitialized = true; return true; } - - private void GenerateMapConsistent() - { - GlobalRng.State = GlobalRng.Seed << 5 / 2; - Map.InitMapGrid(MapSize.X, MapSize.Y, 3); - } + #endregion public static MapGrid.Room GetCurRoom() { return Map.GetRooms()[CurRoom]; } - public static void ChangeCurRoom(int room) + #region Transitions + public void TransitionFromRoom(int nextRoomIdx) { - CurRoom = room; + TransitionStage(Map.GetRooms()[nextRoomIdx].Type, nextRoomIdx); } - public void TransitionFromRoom(int nextRoomIdx) + private Task _loadTask; + + /** + * To be used from Cartographer. Preloads the scene during transition animation. + * This removes the occasionally noticeable load time for the scene change. + */ + public void PreloadScene(int nextRoomIdx) { - TransitionStage(Map.GetRooms()[nextRoomIdx].Type, nextRoomIdx); + Stages nextStage = Map.GetRooms()[nextRoomIdx].Type; + Config = MakeBattleConfig(nextStage, nextRoomIdx); + switch (nextStage) + { + case Stages.Battle: + case Stages.Boss: + _loadTask = Task.Run(() => + { + _preloadStage = GD.Load(BattleDirector.LoadPath) + .Instantiate(); + }); + break; + case Stages.Chest: + _loadTask = Task.Run(() => + { + _preloadStage = GD.Load(ChestScene.LoadPath).Instantiate(); + }); + break; + default: + GD.PushError($"Error Scene Transition is {nextStage}"); + break; + } } public void TransitionStage(Stages nextStage, int nextRoomIdx = -1) @@ -111,31 +146,27 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1) { case Stages.Title: IsInitialized = false; - GetTree().ChangeSceneToFile("res://scenes/SceneTransitions/TitleScreen.tscn"); - break; - case Stages.Battle: - Config = MakeConfig(nextStage, nextRoomIdx); - GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn"); - break; - case Stages.Boss: - Config = MakeConfig(nextStage, nextRoomIdx); - GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn"); + GetTree().ChangeSceneToFile(TitleScreen.LoadPath); break; + case Stages.Battle: //Currently these are only ever entered from map. Be aware if we change + case Stages.Boss: //this, scenes either need to be preloaded first, or a different setup is needed. case Stages.Chest: - Config = MakeConfig(nextStage, nextRoomIdx); - GetTree().ChangeSceneToFile("res://scenes/ChestScene/ChestScene.tscn"); + _loadTask.Wait(); //Should always finish by the time it gets here, this guarantees it. + GetTree().GetCurrentScene().Free(); + GetTree().Root.AddChild(_preloadStage); + GetTree().SetCurrentScene(_preloadStage); break; case Stages.Map: - GetTree().ChangeSceneToFile("res://scenes/Maps/cartographer.tscn"); + GetTree().ChangeSceneToFile(Cartographer.LoadPath); if (!IsInitialized) { - StartGame(); + StartNewGame(); } break; case Stages.Load: if (!LoadGame()) - StartGame(); - GetTree().ChangeSceneToFile("res://scenes/Maps/cartographer.tscn"); + StartNewGame(); + GetTree().ChangeSceneToFile(Cartographer.LoadPath); break; case Stages.Quit: GetTree().Quit(); @@ -145,29 +176,40 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1) break; } + _preloadStage = null; //Apply grayscale shader to all scenes GetTree().Root.AddChild(ContrastFilter); _curStage = nextStage; } + #endregion - private BattleConfig MakeConfig(Stages nextRoom, int nextRoomIdx) + private BattleConfig MakeBattleConfig(Stages nextRoom, int nextRoomIdx) { - BattleConfig result = new BattleConfig(); - result.BattleRoom = Map.GetRooms()[nextRoomIdx]; - result.RoomType = nextRoom; + BattleConfig result = new BattleConfig + { + BattleRoom = Map.GetRooms()[nextRoomIdx], + RoomType = nextRoom, + }; + RandomNumberGenerator stageRng = new RandomNumberGenerator(); + stageRng.SetSeed(GlobalRng.Seed + (ulong)nextRoomIdx); switch (nextRoom) { case Stages.Battle: - int songIdx = GlobalRng.RandiRange(1, 2); + int songIdx = stageRng.RandiRange(1, 2); result.CurSong = Scribe.SongDictionary[songIdx]; result.EnemyScenePath = Scribe.SongDictionary[songIdx].EnemyScenePath; break; case Stages.Boss: - result.EnemyScenePath = "res://scenes/Puppets/Enemies/BossBlood/Boss1.tscn"; + result.EnemyScenePath = P_BossBlood.LoadPath; result.CurSong = Scribe.SongDictionary[0]; break; + case Stages.Chest: + break; + default: + GD.PushError($"Error making Battle Config for invalid room type: {nextRoom}"); + break; } - + CurRoom = nextRoomIdx; return result; } } diff --git a/Globals/TimeKeeper.cs b/Globals/TimeKeeper.cs index 6db364ef..f3800547 100644 --- a/Globals/TimeKeeper.cs +++ b/Globals/TimeKeeper.cs @@ -1,12 +1,49 @@ -using System; +using FunkEngine; using Godot; +/** + * TimeKeeper: Global scale current song position. + */ public partial class TimeKeeper : Node { - public static double CurrentTime = 0; - public static float ChartLength; - public static float LoopLength; + public static double CurrentTime; //sec + public static double SongLength; //sec public static float Bpm; + public static int LoopsPerSong; + public static double ChartWidth; //px + + public const int SecondsPerMinute = 60; + + public static double LoopLength => SongLength / LoopsPerSong; //sec + public static double BeatsPerLoop => LoopLength / (SecondsPerMinute / Bpm); + public static double BeatsPerSong => SongLength / (SecondsPerMinute / Bpm); + + public static Beat LastBeat { get; set; } + + public static void InitVals(float bpm) + { + CurrentTime = 0; + Bpm = bpm; + LastBeat = new Beat(); + } + + public static Beat GetBeatFromTime(double timeSecs) + { + double beatPos = timeSecs / (60 / (double)Bpm); + Beat result = new Beat(beatPos, LastBeat.Loop); + //If beatPos has returned to effectively < last beat pos, a loop has happened. IDK if there's a better way to handle this + return result.BeatPos < LastBeat.BeatPos ? result.IncDecLoop(1) : result; + } + + public static double GetTimeOfBeat(Beat beat) + { + return beat.GetBeatInSong() / BeatsPerSong * SongLength; + } + + public static double GetPosOfBeat(Beat beat) + { + return beat.GetBeatInSong() / BeatsPerSong * (ChartWidth * LoopsPerSong); + } public static double PosMod(double i, double mod) { diff --git a/Globals/Translations/translations.csv.import b/Globals/Translations/translations.csv.import index eeffcdc3..b1ceb83a 100644 --- a/Globals/Translations/translations.csv.import +++ b/Globals/Translations/translations.csv.import @@ -6,10 +6,10 @@ uid="uid://drjnsd6mqpxqh" [deps] -files=["res://Globals/Translations/translations.en.translation", "res://Globals/Translations/translations.cn.translation"] +files=["res://Globals/Translations/Translations.en.translation", "res://Globals/Translations/Translations.cn.translation"] -source_file="res://Globals/Translations/translations.csv" -dest_files=["res://Globals/Translations/translations.en.translation", "res://Globals/Translations/translations.cn.translation"] +source_file="res://Globals/Translations/Translations.csv" +dest_files=["res://Globals/Translations/Translations.en.translation", "res://Globals/Translations/Translations.cn.translation"] [params] diff --git a/scenes/BattleDirector/assets/temp_note_queue.png b/Scenes/BattleDirector/Assets/NoteQueue_Frame.png similarity index 100% rename from scenes/BattleDirector/assets/temp_note_queue.png rename to Scenes/BattleDirector/Assets/NoteQueue_Frame.png diff --git a/scenes/BattleDirector/assets/temp_note_queue.png.import b/Scenes/BattleDirector/Assets/NoteQueue_Frame.png.import similarity index 69% rename from scenes/BattleDirector/assets/temp_note_queue.png.import rename to Scenes/BattleDirector/Assets/NoteQueue_Frame.png.import index cf432095..ac8fbec5 100644 --- a/scenes/BattleDirector/assets/temp_note_queue.png.import +++ b/Scenes/BattleDirector/Assets/NoteQueue_Frame.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cnyr5usjdv0ni" -path="res://.godot/imported/temp_note_queue.png-b6e43682068ed18b8bf4cd7cd8229404.ctex" +path="res://.godot/imported/NoteQueue_Frame.png-e9e1fc727e2cde6812934bdfe5d051a7.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/BattleDirector/assets/temp_note_queue.png" -dest_files=["res://.godot/imported/temp_note_queue.png-b6e43682068ed18b8bf4cd7cd8229404.ctex"] +source_file="res://Scenes/BattleDirector/Assets/NoteQueue_Frame.png" +dest_files=["res://.godot/imported/NoteQueue_Frame.png-e9e1fc727e2cde6812934bdfe5d051a7.ctex"] [params] diff --git a/scenes/BattleDirector/test_battle_scene.tscn b/Scenes/BattleDirector/BattleScene.tscn similarity index 64% rename from scenes/BattleDirector/test_battle_scene.tscn rename to Scenes/BattleDirector/BattleScene.tscn index 991d04c6..6af6318e 100644 --- a/scenes/BattleDirector/test_battle_scene.tscn +++ b/Scenes/BattleDirector/BattleScene.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=10 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="Script" path="res://scenes/UI/scripts/MenuModule.cs" id="3_8hff6"] -[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://scenes/BattleDirector/assets/bgupdate.png" id="4_13o87"] -[ext_resource type="Texture2D" uid="uid://dbjotl0v1ymia" path="res://scenes/BattleDirector/assets/BattleFrame1.png" id="6_0ak0g"] -[ext_resource type="PackedScene" uid="uid://duhiilcv4tat3" path="res://scenes/BattleDirector/NotePlacementBar.tscn" id="7_3ko4g"] +[ext_resource type="Script" path="res://Scenes/BattleDirector/Scripts/BattleDirector.cs" id="1_jmdo1"] +[ext_resource type="Script" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_ka0ws"] +[ext_resource type="Script" path="res://Scenes/BattleDirector/Scripts/Conductor.cs" id="3_elcaj"] +[ext_resource type="PackedScene" uid="uid://duhiilcv4tat3" path="res://Scenes/BattleDirector/NotePlacementBar.tscn" id="4_qk7om"] +[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://Scenes/ChartViewport/ChartViewport.tscn" id="5_r2xh0"] +[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="6_0jtpx"] +[ext_resource type="Texture2D" uid="uid://dbjotl0v1ymia" path="res://SharedAssets/BattleFrame1.png" id="7_klvil"] [sub_resource type="Gradient" id="Gradient_8uy3a"] offsets = PackedFloat32Array(0, 0.766234, 1) @@ -17,26 +17,27 @@ gradient = SubResource("Gradient_8uy3a") fill_from = Vector2(1, 0) fill_to = Vector2(0.738532, 1) -[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CM", "NotePlacementBar", "CD", "Audio", "_focusedButton")] +[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CD", "CM", "NPB", "Audio", "_focusedButton")] process_mode = 1 -script = ExtResource("1_cwqqr") -CM = NodePath("SubViewport") -NotePlacementBar = NodePath("NotePlacementBar") +script = ExtResource("1_jmdo1") CD = NodePath("Conductor") +CM = NodePath("SubViewport") +NPB = NodePath("NotePlacementBar") Audio = NodePath("AudioStreamPlayer") _focusedButton = NodePath("StartButton") metadata/_edit_lock_ = true [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] -[node name="UILayer" type="CanvasLayer" parent="."] -script = ExtResource("3_8hff6") +[node name="UILayer" type="CanvasLayer" parent="." node_paths=PackedStringArray("CurSceneNode")] +script = ExtResource("2_ka0ws") +CurSceneNode = NodePath("..") [node name="Conductor" type="Node" parent="." node_paths=PackedStringArray("CM")] -script = ExtResource("2_pcp76") +script = ExtResource("3_elcaj") CM = NodePath("../SubViewport") -[node name="NotePlacementBar" parent="." instance=ExtResource("7_3ko4g")] +[node name="NotePlacementBar" parent="." instance=ExtResource("4_qk7om")] offset_top = 183.0 offset_bottom = 183.0 @@ -47,7 +48,7 @@ offset_right = 81.0 offset_bottom = 175.0 texture = SubResource("GradientTexture2D_bajwn") -[node name="SubViewport" parent="." instance=ExtResource("2_cupb3")] +[node name="SubViewport" parent="." instance=ExtResource("5_r2xh0")] offset_left = 80.0 offset_top = 180.0 offset_right = 560.0 @@ -57,14 +58,14 @@ offset_bottom = 360.0 z_index = -1 offset_right = 640.0 offset_bottom = 178.0 -texture = ExtResource("4_13o87") +texture = ExtResource("6_0jtpx") [node name="BattleFrame" type="TextureRect" parent="."] z_index = 1 offset_top = 178.0 offset_right = 640.0 offset_bottom = 360.0 -texture = ExtResource("6_0ak0g") +texture = ExtResource("7_klvil") [node name="StartButton" type="Button" parent="."] modulate = Color(5, 5, 5, 1) diff --git a/scenes/ChartViewport/hit_particles.tscn b/Scenes/ChartViewport/HitParticles.tscn similarity index 71% rename from scenes/ChartViewport/hit_particles.tscn rename to Scenes/ChartViewport/HitParticles.tscn index 30a4f3ec..1a9315fe 100644 --- a/scenes/ChartViewport/hit_particles.tscn +++ b/Scenes/ChartViewport/HitParticles.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://bcf6vs4aqoxr5"] -[ext_resource type="Script" path="res://scenes/ChartViewport/scripts/HitParticles.cs" id="1_tr2t2"] +[ext_resource type="Script" path="res://Scenes/ChartViewport/Scripts/HitParticles.cs" id="1_7gkj5"] [node name="HitParticles" type="CPUParticles2D"] z_index = -1 @@ -14,4 +14,4 @@ gravity = Vector2(0, 0) initial_velocity_min = 50.0 initial_velocity_max = 200.0 scale_amount_max = 2.0 -script = ExtResource("1_tr2t2") +script = ExtResource("1_7gkj5") diff --git a/Scenes/NoteManager/Assets/Arrow_Trail.png b/Scenes/NoteManager/Assets/Arrow_Trail.png new file mode 100644 index 00000000..671b8f18 Binary files /dev/null and b/Scenes/NoteManager/Assets/Arrow_Trail.png differ diff --git a/Scenes/NoteManager/Assets/Arrow_Trail.png.import b/Scenes/NoteManager/Assets/Arrow_Trail.png.import new file mode 100644 index 00000000..6c2cb9d9 --- /dev/null +++ b/Scenes/NoteManager/Assets/Arrow_Trail.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbnvl0gbhl5b4" +path="res://.godot/imported/Arrow_Trail.png-384f0409031c318aa6fa51abecfd35b2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Scenes/NoteManager/Assets/Arrow_Trail.png" +dest_files=["res://.godot/imported/Arrow_Trail.png-384f0409031c318aa6fa51abecfd35b2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Scenes/NoteManager/HoldArrow.tscn b/Scenes/NoteManager/HoldArrow.tscn new file mode 100644 index 00000000..32978d70 --- /dev/null +++ b/Scenes/NoteManager/HoldArrow.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=5 format=3 uid="uid://b3owchvgq1l87"] + +[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://Scenes/NoteManager/Assets/New_Arrow.png" id="1_nn8ao"] +[ext_resource type="Script" path="res://Scenes/NoteManager/Scripts/HoldArrow.cs" id="2_hehcu"] +[ext_resource type="Texture2D" uid="uid://cgq2ar3pdmkac" path="res://Scenes/NoteManager/Assets/Arrow_Outline.png" id="3_pvvea"] +[ext_resource type="Texture2D" uid="uid://dbnvl0gbhl5b4" path="res://Scenes/NoteManager/Assets/Arrow_Trail.png" id="4_xgcwb"] + +[node name="Right-arrow" type="Sprite2D" node_paths=PackedStringArray("_trail", "OutlineSprite", "IconSprite")] +z_index = 2 +rotation = 3.14159 +texture = ExtResource("1_nn8ao") +script = ExtResource("2_hehcu") +_trail = NodePath("CometTail/TrailRemote/Trail") +OutlineSprite = NodePath("Outline") +IconSprite = NodePath("Icon") + +[node name="Outline" type="Sprite2D" parent="."] +texture = ExtResource("3_pvvea") + +[node name="Icon" type="Sprite2D" parent="."] + +[node name="TrailTransform2D" type="RemoteTransform2D" parent="."] +remote_path = NodePath("../CometTail/TrailRemote") +update_rotation = false +update_scale = false + +[node name="CometTail" type="Node" parent="."] + +[node name="TrailRemote" type="Node2D" parent="CometTail"] +rotation = 3.14159 + +[node name="Trail" type="NinePatchRect" parent="CometTail/TrailRemote"] +z_index = 1 +offset_left = -5.0 +offset_top = -4.0 +offset_right = 5.0 +offset_bottom = 4.0 +rotation = -3.14159 +pivot_offset = Vector2(5, 4) +texture = ExtResource("4_xgcwb") +patch_margin_right = 9 +axis_stretch_horizontal = 2 +axis_stretch_vertical = 2 diff --git a/scenes/NoteManager/note.tscn b/Scenes/NoteManager/NoteArrow.tscn similarity index 75% rename from scenes/NoteManager/note.tscn rename to Scenes/NoteManager/NoteArrow.tscn index cedada14..c1daacb8 100644 --- a/scenes/NoteManager/note.tscn +++ b/Scenes/NoteManager/NoteArrow.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=4 format=3 uid="uid://ck3bfqy30rjbq"] -[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://scenes/NoteManager/assets/new_arrow.png" id="1_wq1hy"] -[ext_resource type="Script" path="res://scenes/NoteManager/scripts/NoteArrow.cs" id="2_lbl4b"] -[ext_resource type="Texture2D" uid="uid://cgq2ar3pdmkac" path="res://scenes/NoteManager/assets/arrow_outline.png" id="3_5g4ja"] +[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://Scenes/NoteManager/Assets/New_Arrow.png" id="1_wq1hy"] +[ext_resource type="Script" path="res://Scenes/NoteManager/Scripts/NoteArrow.cs" id="2_lbl4b"] +[ext_resource type="Texture2D" uid="uid://cgq2ar3pdmkac" path="res://Scenes/NoteManager/Assets/Arrow_Outline.png" id="3_5g4ja"] [node name="Right-arrow" type="Sprite2D" node_paths=PackedStringArray("OutlineSprite", "IconSprite")] texture = ExtResource("1_wq1hy") diff --git a/scenes/NoteManager/note_manager.tscn b/Scenes/NoteManager/NoteManager.tscn similarity index 89% rename from scenes/NoteManager/note_manager.tscn rename to Scenes/NoteManager/NoteManager.tscn index 8db5a94e..00a8f0cc 100644 --- a/scenes/NoteManager/note_manager.tscn +++ b/Scenes/NoteManager/NoteManager.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=7 format=3 uid="uid://bn8txx53xlguw"] -[ext_resource type="Script" path="res://scenes/NoteManager/scripts/InputHandler.cs" id="1_2oeuf"] -[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://scenes/NoteManager/assets/new_arrow.png" id="2_pb1qk"] -[ext_resource type="Script" path="res://scenes/NoteManager/scripts/NoteChecker.cs" id="3_0cioe"] -[ext_resource type="Texture2D" uid="uid://cgq2ar3pdmkac" path="res://scenes/NoteManager/assets/arrow_outline.png" id="4_3mttx"] +[ext_resource type="Script" path="res://Scenes/NoteManager/Scripts/InputHandler.cs" id="1_2oeuf"] +[ext_resource type="Texture2D" uid="uid://hfxynr5jdgsp" path="res://Scenes/NoteManager/Assets/New_Arrow.png" id="2_pb1qk"] +[ext_resource type="Script" path="res://Scenes/NoteManager/Scripts/NoteChecker.cs" id="3_0cioe"] +[ext_resource type="Texture2D" uid="uid://cgq2ar3pdmkac" path="res://Scenes/NoteManager/Assets/Arrow_Outline.png" id="4_3mttx"] [ext_resource type="Texture2D" uid="uid://b0tvsewgnf2x7" path="res://icon.svg" id="4_foklt"] -[ext_resource type="PackedScene" uid="uid://bcf6vs4aqoxr5" path="res://scenes/ChartViewport/hit_particles.tscn" id="5_jv1tr"] +[ext_resource type="PackedScene" uid="uid://bcf6vs4aqoxr5" path="res://Scenes/ChartViewport/HitParticles.tscn" id="5_jv1tr"] [node name="noteManager" type="Node2D"] script = ExtResource("1_2oeuf") diff --git a/Scenes/NoteManager/Scripts/HoldArrow.cs b/Scenes/NoteManager/Scripts/HoldArrow.cs new file mode 100644 index 00000000..1bde8924 --- /dev/null +++ b/Scenes/NoteManager/Scripts/HoldArrow.cs @@ -0,0 +1,74 @@ +using System; +using FunkEngine; +using Godot; + +public partial class HoldArrow : NoteArrow +{ + public new const string LoadPath = "res://Scenes/NoteManager/HoldArrow.tscn"; + + [Export] + private NinePatchRect _trail; + + private double Length => Data.Length; + public Beat EndBeat => Data.Beat + Data.Length; + private bool _isReleased; + + public override void Init(CheckerData parentChecker, ArrowData arrowData, double beatTime) + { + base.Init(parentChecker, arrowData, beatTime); + _trail.Size = new Vector2( + (float)(Length / TimeKeeper.BeatsPerLoop * TimeKeeper.ChartWidth), + _trail.Size.Y + ); + _trail.Modulate = parentChecker.Color; + } + + public override void Recycle() + { + base.Recycle(); + if (_isReleased) + _trail.Modulate /= .7f; + _isReleased = false; + } + + public void NoteRelease() + { + if (_isReleased) + return; + _trail.Modulate *= .7f; + _isReleased = true; + } + + protected override void CheckMissed() + { + if (_isReleased) + return; //Released => fully handled, let it kill itself + if (!IsHit && (TimeKeeper.LastBeat - Beat > Beat.One)) //not hit, mostly normal miss handling + { + NoteRelease(); + RaiseMissed(this); + } + if (IsHit && (TimeKeeper.LastBeat - EndBeat > new Beat(Note.TimingMax))) //hit, only miss if held too long, handle timing on end beat + { + NoteRelease(); + RaiseMissed(this); + } + } + + protected override void PosChecks() + { + if (Position.X < LeftBound - _trail.Size.X || TimeKeeper.LastBeat - EndBeat > BeatBound) //i hate that we have to do this for now + { + if (!IsHit) + RaiseMissed(this); + NoteRelease(); + RaiseKill(this); + } + } + + public override bool IsInRange(Beat incomingBeat) + { + return (int)Math.Round(incomingBeat.BeatPos) >= (int)Math.Round(Beat.BeatPos) + && (int)Math.Round(incomingBeat.BeatPos) <= (int)Math.Round(EndBeat.BeatPos); + } +} diff --git a/scenes/BattleDirector/assets/Enemy1.png b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png similarity index 100% rename from scenes/BattleDirector/assets/Enemy1.png rename to Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png diff --git a/scenes/BattleDirector/assets/Enemy1.png.import b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png.import similarity index 70% rename from scenes/BattleDirector/assets/Enemy1.png.import rename to Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png.import index a6b8781d..f2bc0a6e 100644 --- a/scenes/BattleDirector/assets/Enemy1.png.import +++ b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://veedngaorx3l" -path="res://.godot/imported/Enemy1.png-fb95639d1545a326b6c39640343f3786.ctex" +path="res://.godot/imported/Boss1.png-b7a923dff8e0511e19fb7a3737126295.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/BattleDirector/assets/Enemy1.png" -dest_files=["res://.godot/imported/Enemy1.png-fb95639d1545a326b6c39640343f3786.ctex"] +source_file="res://Scenes/Puppets/Enemies/BossBlood/Assets/Boss1.png" +dest_files=["res://.godot/imported/Boss1.png-b7a923dff8e0511e19fb7a3737126295.ctex"] [params] diff --git a/scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png similarity index 100% rename from scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png rename to Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png diff --git a/scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png.import b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png.import similarity index 67% rename from scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png.import rename to Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png.import index e6e2721d..4a9075e9 100644 --- a/scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png.import +++ b/Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://b5jpi2i502lw5" -path="res://.godot/imported/Enemy1EmissionShape.png-b52ecd60b2d507b2c2133463b0dcbc08.ctex" +path="res://.godot/imported/Boss1EmissionShape.png-890f34e921959a3e1822c95f4278eab7.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Puppets/Enemies/BossBlood/assets/Enemy1EmissionShape.png" -dest_files=["res://.godot/imported/Enemy1EmissionShape.png-b52ecd60b2d507b2c2133463b0dcbc08.ctex"] +source_file="res://Scenes/Puppets/Enemies/BossBlood/Assets/Boss1EmissionShape.png" +dest_files=["res://.godot/imported/Boss1EmissionShape.png-890f34e921959a3e1822c95f4278eab7.ctex"] [params] diff --git a/scenes/UI/assets/combobar.png b/Scenes/UI/Assets/HowToPlay_Combo_Bar.png similarity index 100% rename from scenes/UI/assets/combobar.png rename to Scenes/UI/Assets/HowToPlay_Combo_Bar.png diff --git a/scenes/UI/assets/combobar.png.import b/Scenes/UI/Assets/HowToPlay_Combo_Bar.png.import similarity index 68% rename from scenes/UI/assets/combobar.png.import rename to Scenes/UI/Assets/HowToPlay_Combo_Bar.png.import index 9ab338bd..9c786e63 100644 --- a/scenes/UI/assets/combobar.png.import +++ b/Scenes/UI/Assets/HowToPlay_Combo_Bar.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dp3vkn65j4o3s" -path="res://.godot/imported/combobar.png-c835d811fb05e4fd220a08e5b5cab683.ctex" +path="res://.godot/imported/HowToPlay_Combo_Bar.png-0ad8e532b66f13ea35fafafcb5e4b1e4.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/UI/assets/combobar.png" -dest_files=["res://.godot/imported/combobar.png-c835d811fb05e4fd220a08e5b5cab683.ctex"] +source_file="res://Scenes/UI/Assets/HowToPlay_Combo_Bar.png" +dest_files=["res://.godot/imported/HowToPlay_Combo_Bar.png-0ad8e532b66f13ea35fafafcb5e4b1e4.ctex"] [params] diff --git a/scenes/UI/display_button.tscn b/Scenes/UI/DisplayButton.tscn similarity index 80% rename from scenes/UI/display_button.tscn rename to Scenes/UI/DisplayButton.tscn index 3dc408b8..10fad649 100644 --- a/scenes/UI/display_button.tscn +++ b/Scenes/UI/DisplayButton.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://cymo26khpw4m1"] -[ext_resource type="Script" path="res://scenes/UI/scripts/DisplayButton.cs" id="1_7lpm6"] +[ext_resource type="Script" path="res://Scenes/UI/Scripts/DisplayButton.cs" id="1_7lpm6"] [node name="DisplayButton" type="Button"] anchors_preset = 15 diff --git a/scenes/UI/HowToPlay.tscn b/Scenes/UI/Options/HowToPlay.tscn similarity index 90% rename from scenes/UI/HowToPlay.tscn rename to Scenes/UI/Options/HowToPlay.tscn index d7adbc4d..f1e539ae 100644 --- a/scenes/UI/HowToPlay.tscn +++ b/Scenes/UI/Options/HowToPlay.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=8 format=3 uid="uid://cavxn51vwbew3"] -[ext_resource type="Script" path="res://scenes/UI/scripts/HowToPlay.cs" id="1_kqayr"] -[ext_resource type="Texture2D" uid="uid://xtygvpk7s8e4" path="res://scenes/NoteManager/assets/outline_white.png" id="2_4i384"] -[ext_resource type="Texture2D" uid="uid://dp3vkn65j4o3s" path="res://scenes/UI/assets/combobar.png" id="3_7006y"] -[ext_resource type="Texture2D" uid="uid://caw70lr5e1yiq" path="res://Classes/Notes/assets/double_note.png" id="4_m6low"] -[ext_resource type="Texture2D" uid="uid://cdf3g3174du4r" path="res://Classes/Notes/assets/heal_note.png" id="5_8kiq2"] -[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://Classes/Notes/assets/single_note.png" id="6_uonw3"] -[ext_resource type="Texture2D" uid="uid://dg0lmu0pip4lr" path="res://Classes/Notes/assets/vampire_note.png" id="7_rbdrm"] +[ext_resource type="Script" path="res://Scenes/UI/Options/Scripts/HowToPlay.cs" id="1_kqayr"] +[ext_resource type="Texture2D" uid="uid://xtygvpk7s8e4" path="res://SharedAssets/NoteArrow_Black_Outline.png" id="2_4i384"] +[ext_resource type="Texture2D" uid="uid://dp3vkn65j4o3s" path="res://Scenes/UI/Assets/HowToPlay_Combo_Bar.png" id="3_7006y"] +[ext_resource type="Texture2D" uid="uid://caw70lr5e1yiq" path="res://Classes/Notes/Assets/Note_PlayerDouble.png" id="4_m6low"] +[ext_resource type="Texture2D" uid="uid://cdf3g3174du4r" path="res://Classes/Notes/Assets/Note_PlayerHeal.png" id="5_8kiq2"] +[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://Classes/Notes/Assets/Note_PlayerBasic.png" id="6_uonw3"] +[ext_resource type="Texture2D" uid="uid://dg0lmu0pip4lr" path="res://Classes/Notes/Assets/Note_PlayerVampire.png" id="7_rbdrm"] [node name="CanvasLayer" type="Node2D" node_paths=PackedStringArray("_returnButton")] process_mode = 3 @@ -20,11 +20,13 @@ offset_right = 40.0 offset_bottom = 40.0 [node name="ColorRect" type="ColorRect" parent="Control"] +layout_mode = 0 offset_right = 640.0 offset_bottom = 360.0 color = Color(0.133333, 0.133333, 0.133333, 1) [node name="Label" type="Label" parent="Control"] +layout_mode = 0 offset_top = 16.0 offset_right = 642.0 offset_bottom = 39.0 @@ -32,6 +34,7 @@ text = "HOW_TO_PLAY" horizontal_alignment = 1 [node name="ReturnButton" type="Button" parent="Control"] +layout_mode = 0 offset_left = 202.5 offset_top = 314.0 offset_right = 437.5 diff --git a/scenes/Options/OptionsMenu.tscn b/Scenes/UI/Options/OptionsMenu.tscn similarity index 94% rename from scenes/Options/OptionsMenu.tscn rename to Scenes/UI/Options/OptionsMenu.tscn index 5f429a9b..c64dcb08 100644 --- a/scenes/Options/OptionsMenu.tscn +++ b/Scenes/UI/Options/OptionsMenu.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=3 format=3 uid="uid://buejv62lwtymc"] -[ext_resource type="Script" path="res://scenes/Options/scripts/LanguageSelection.cs" id="1_qyvkw"] -[ext_resource type="Script" path="res://scenes/Options/OptionsMenu.cs" id="1_yjq7i"] +[ext_resource type="Script" path="res://Scenes/UI/Options/Scripts/LanguageSelection.cs" id="1_qyvkw"] +[ext_resource type="Script" path="res://Scenes/UI/Options/Scripts/OptionsMenu.cs" id="1_yjq7i"] [node name="OptionsMenu" type="CanvasLayer" node_paths=PackedStringArray("_focused", "_volumeSlider", "_closeButton", "_controlsButton", "_highContrastToggle", "_howToPlayButton")] process_mode = 3 script = ExtResource("1_yjq7i") -_focused = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/LanguageSelection") +_focused = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/CheckBox") _volumeSlider = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/Container/Volume") _closeButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/TitleButton") _controlsButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/ControlsButton") @@ -96,9 +96,9 @@ horizontal_alignment = 1 [node name="Volume" type="HSlider" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/Container"] layout_mode = 2 tooltip_text = "OPTIONS_VOLUME_LABEL" -min_value = 50.0 -max_value = 80.0 -value = 80.0 +max_value = 1.0 +step = 0.01 +value = 1.0 [node name="LanguageSelection" type="OptionButton" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"] unique_name_in_owner = true diff --git a/Scenes/UI/Options/Scripts/HowToPlay.cs b/Scenes/UI/Options/Scripts/HowToPlay.cs new file mode 100644 index 00000000..c3d49285 --- /dev/null +++ b/Scenes/UI/Options/Scripts/HowToPlay.cs @@ -0,0 +1,50 @@ +using FunkEngine; +using Godot; + +public partial class HowToPlay : Node2D, IFocusableMenu +{ + public static readonly string LoadPath = "res://Scenes/UI/Options/HowToPlay.tscn"; + + [Export] + private Button _returnButton; + + public IFocusableMenu Prev { get; set; } + + public override void _Ready() + { + _returnButton.Pressed += ReturnToPrev; + } + + public void ResumeFocus() + { + ProcessMode = ProcessModeEnum.Inherit; + _returnButton.GrabFocus(); + } + + public void PauseFocus() + { + ProcessMode = ProcessModeEnum.Disabled; + } + + public void OpenMenu(IFocusableMenu prev) + { + Prev = prev; + Prev.PauseFocus(); + _returnButton.GrabFocus(); + } + + public void ReturnToPrev() + { + Prev.ResumeFocus(); + QueueFree(); + } + + public override void _Input(InputEvent @event) + { + if (@event.IsActionPressed("ui_cancel")) + { + ReturnToPrev(); + GetViewport().SetInputAsHandled(); + } + } +} diff --git a/scenes/Options/scripts/LanguageSelection.cs b/Scenes/UI/Options/Scripts/LanguageSelection.cs similarity index 98% rename from scenes/Options/scripts/LanguageSelection.cs rename to Scenes/UI/Options/Scripts/LanguageSelection.cs index 5f5e9ec5..5e14c224 100644 --- a/scenes/Options/scripts/LanguageSelection.cs +++ b/Scenes/UI/Options/Scripts/LanguageSelection.cs @@ -1,4 +1,3 @@ -using System; using Godot; public partial class LanguageSelection : OptionButton diff --git a/scenes/Options/OptionsMenu.cs b/Scenes/UI/Options/Scripts/OptionsMenu.cs similarity index 62% rename from scenes/Options/OptionsMenu.cs rename to Scenes/UI/Options/Scripts/OptionsMenu.cs index aaa5de41..ee8bbc29 100644 --- a/scenes/Options/OptionsMenu.cs +++ b/Scenes/UI/Options/Scripts/OptionsMenu.cs @@ -1,9 +1,11 @@ -using System; +using FunkEngine; using Godot; -public partial class OptionsMenu : CanvasLayer +public partial class OptionsMenu : CanvasLayer, IFocusableMenu { - private Node _previousScene; + public static readonly string LoadPath = "res://Scenes/UI/Options/OptionsMenu.tscn"; + + public IFocusableMenu Prev { get; set; } [Export] private Control _focused; @@ -24,14 +26,14 @@ public partial class OptionsMenu : CanvasLayer [Export] private Button _howToPlayButton; - private const float MinVolumeVal = 50f; + private const float MinVolumeVal = 0f; public override void _Ready() { - _focused.GrabFocus(); - _volumeSlider.MinValue = MinVolumeVal; - _volumeSlider.Value = AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("Master")) + 80; + _volumeSlider.Value = Mathf.DbToLinear( + AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("Master")) + ); _highContrastToggle.ButtonPressed = SaveSystem .GetConfigValue(SaveSystem.ConfigSettings.HighContrast) @@ -40,46 +42,50 @@ public override void _Ready() _volumeSlider.DragEnded += VolumeChanged; _volumeSlider.ValueChanged += ChangeVolume; - _closeButton.Pressed += CloseMenu; + _closeButton.Pressed += ReturnToPrev; _controlsButton.Pressed += OpenControls; _highContrastToggle.Toggled += HighContrastChanged; _howToPlayButton.Pressed += OpenHowToPlay; } - //TODO: Menu subclass/interface - public override void _Process(double delta) - { - if (GetViewport().GuiGetFocusOwner() == null) - { - _focused.GrabFocus(); - } - } - public override void _Input(InputEvent @event) { if (@event.IsActionPressed("ui_cancel")) { - CloseMenu(); + ReturnToPrev(); GetViewport().SetInputAsHandled(); } } - public void OpenMenu(Node prevScene) + public void ResumeFocus() { - _previousScene = prevScene; - _previousProcessMode = _previousScene.GetProcessMode(); - prevScene.ProcessMode = ProcessModeEnum.Disabled; + ProcessMode = _previousProcessMode; + _focused.GrabFocus(); + } + + public void PauseFocus() + { + _focused = GetViewport().GuiGetFocusOwner(); + _previousProcessMode = ProcessMode; + ProcessMode = ProcessModeEnum.Disabled; + } + + public void OpenMenu(IFocusableMenu prev) + { + Prev = prev; + Prev.PauseFocus(); + _focused.GrabFocus(); } - private void CloseMenu() + public void ReturnToPrev() { - _previousScene.ProcessMode = _previousProcessMode; + Prev.ResumeFocus(); QueueFree(); } private void OpenControls() { - ControlSettings controlSettings = GD.Load("res://scenes/Remapping/Remap.tscn") + ControlSettings controlSettings = GD.Load(ControlSettings.LoadPath) .Instantiate(); AddChild(controlSettings); controlSettings.OpenMenu(this); @@ -95,10 +101,9 @@ private void VolumeChanged(bool valueChanged) public static void ChangeVolume(double value) { - AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), (float)value - 80); - AudioServer.SetBusMute( + AudioServer.SetBusVolumeDb( AudioServer.GetBusIndex("Master"), - Math.Abs(value - MinVolumeVal) < .1 + (float)Mathf.LinearToDb(value) ); } @@ -110,8 +115,7 @@ private void HighContrastChanged(bool toggled) private void OpenHowToPlay() { - HowToPlay howtoPlay = GD.Load("res://scenes/UI/HowToPlay.tscn") - .Instantiate(); + HowToPlay howtoPlay = GD.Load(HowToPlay.LoadPath).Instantiate(); AddChild(howtoPlay); howtoPlay.OpenMenu(this); } diff --git a/scenes/Remapping/assets/A_Key_Light.png b/Scenes/UI/Remapping/Assets/A_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/A_Key_Light.png rename to Scenes/UI/Remapping/Assets/A_Key_Light.png diff --git a/scenes/Remapping/assets/A_Key_Light.png.import b/Scenes/UI/Remapping/Assets/A_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/A_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/A_Key_Light.png.import index 94679e9c..9ec28787 100644 --- a/scenes/Remapping/assets/A_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/A_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://ucxkeg8mkugt" -path="res://.godot/imported/A_Key_Light.png-fbe7cdabcae01011395303e3e2b90c6d.ctex" +path="res://.godot/imported/A_Key_Light.png-7329269aa31c1a16ab62d73e21666a01.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/A_Key_Light.png" -dest_files=["res://.godot/imported/A_Key_Light.png-fbe7cdabcae01011395303e3e2b90c6d.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/A_Key_Light.png" +dest_files=["res://.godot/imported/A_Key_Light.png-7329269aa31c1a16ab62d73e21666a01.ctex"] [params] diff --git a/scenes/Remapping/assets/Arrow_Down_Key_Light.png b/Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/Arrow_Down_Key_Light.png rename to Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png diff --git a/scenes/Remapping/assets/Arrow_Down_Key_Light.png.import b/Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png.import similarity index 67% rename from scenes/Remapping/assets/Arrow_Down_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png.import index 55ccf7e3..b6f8778a 100644 --- a/scenes/Remapping/assets/Arrow_Down_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://q14p8ypgc43t" -path="res://.godot/imported/Arrow_Down_Key_Light.png-e0ef5c9d79e6985f1ac46da1618982ac.ctex" +path="res://.godot/imported/Arrow_Down_Key_Light.png-719d0f6b968006bdbddc6b92a5b89472.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Arrow_Down_Key_Light.png" -dest_files=["res://.godot/imported/Arrow_Down_Key_Light.png-e0ef5c9d79e6985f1ac46da1618982ac.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png" +dest_files=["res://.godot/imported/Arrow_Down_Key_Light.png-719d0f6b968006bdbddc6b92a5b89472.ctex"] [params] diff --git a/scenes/Remapping/assets/Arrow_Left_Key_Light.png b/Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/Arrow_Left_Key_Light.png rename to Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png diff --git a/scenes/Remapping/assets/Arrow_Left_Key_Light.png.import b/Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png.import similarity index 67% rename from scenes/Remapping/assets/Arrow_Left_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png.import index 1f4fdce6..2a215c28 100644 --- a/scenes/Remapping/assets/Arrow_Left_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cr6wtf6j6dcfg" -path="res://.godot/imported/Arrow_Left_Key_Light.png-e169ba7507bfaa6b4f35f05316273b88.ctex" +path="res://.godot/imported/Arrow_Left_Key_Light.png-4b95da442c5418f20e689be8c3098aed.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Arrow_Left_Key_Light.png" -dest_files=["res://.godot/imported/Arrow_Left_Key_Light.png-e169ba7507bfaa6b4f35f05316273b88.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png" +dest_files=["res://.godot/imported/Arrow_Left_Key_Light.png-4b95da442c5418f20e689be8c3098aed.ctex"] [params] diff --git a/scenes/Remapping/assets/Arrow_Right_Key_Light.png b/Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/Arrow_Right_Key_Light.png rename to Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png diff --git a/scenes/Remapping/assets/Arrow_Right_Key_Light.png.import b/Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png.import similarity index 67% rename from scenes/Remapping/assets/Arrow_Right_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png.import index 4ce68c7d..43a85ae3 100644 --- a/scenes/Remapping/assets/Arrow_Right_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dvlekute37smy" -path="res://.godot/imported/Arrow_Right_Key_Light.png-fa1d82f1bcfbe9d1648003c2340eecdb.ctex" +path="res://.godot/imported/Arrow_Right_Key_Light.png-90ea699d64bb15c43a7dbd41c0df8ee5.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Arrow_Right_Key_Light.png" -dest_files=["res://.godot/imported/Arrow_Right_Key_Light.png-fa1d82f1bcfbe9d1648003c2340eecdb.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png" +dest_files=["res://.godot/imported/Arrow_Right_Key_Light.png-90ea699d64bb15c43a7dbd41c0df8ee5.ctex"] [params] diff --git a/scenes/Remapping/assets/Arrow_Up_Key_Light.png b/Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/Arrow_Up_Key_Light.png rename to Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png diff --git a/scenes/Remapping/assets/Arrow_Up_Key_Light.png.import b/Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png.import similarity index 68% rename from scenes/Remapping/assets/Arrow_Up_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png.import index 79603d2e..111faaaa 100644 --- a/scenes/Remapping/assets/Arrow_Up_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://p06451gq2ujc" -path="res://.godot/imported/Arrow_Up_Key_Light.png-bf1ea837bf449129e38ab4c936cefed9.ctex" +path="res://.godot/imported/Arrow_Up_Key_Light.png-79a4f7cad3b102d463ad42f32589fc98.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Arrow_Up_Key_Light.png" -dest_files=["res://.godot/imported/Arrow_Up_Key_Light.png-bf1ea837bf449129e38ab4c936cefed9.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png" +dest_files=["res://.godot/imported/Arrow_Up_Key_Light.png-79a4f7cad3b102d463ad42f32589fc98.ctex"] [params] diff --git a/scenes/Remapping/assets/D_Key_Light.png b/Scenes/UI/Remapping/Assets/D_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/D_Key_Light.png rename to Scenes/UI/Remapping/Assets/D_Key_Light.png diff --git a/scenes/Remapping/assets/D_Key_Light.png.import b/Scenes/UI/Remapping/Assets/D_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/D_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/D_Key_Light.png.import index 93aafc69..f7c65e6e 100644 --- a/scenes/Remapping/assets/D_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/D_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bpic7oh05r5fp" -path="res://.godot/imported/D_Key_Light.png-995095be28da5643c5e7f9883a58c599.ctex" +path="res://.godot/imported/D_Key_Light.png-43d954deafcad31923243ddcf3dd23cd.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/D_Key_Light.png" -dest_files=["res://.godot/imported/D_Key_Light.png-995095be28da5643c5e7f9883a58c599.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/D_Key_Light.png" +dest_files=["res://.godot/imported/D_Key_Light.png-43d954deafcad31923243ddcf3dd23cd.ctex"] [params] diff --git a/scenes/Remapping/assets/E_Key_Light.png b/Scenes/UI/Remapping/Assets/E_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/E_Key_Light.png rename to Scenes/UI/Remapping/Assets/E_Key_Light.png diff --git a/scenes/Remapping/assets/E_Key_Light.png.import b/Scenes/UI/Remapping/Assets/E_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/E_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/E_Key_Light.png.import index f72162e3..01d43d93 100644 --- a/scenes/Remapping/assets/E_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/E_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bvbvmvtgkjtj" -path="res://.godot/imported/E_Key_Light.png-76be9736ab1b806a4318ec1bcce69c05.ctex" +path="res://.godot/imported/E_Key_Light.png-9fe72c49193260a50b1ed18d45117b1f.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/E_Key_Light.png" -dest_files=["res://.godot/imported/E_Key_Light.png-76be9736ab1b806a4318ec1bcce69c05.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/E_Key_Light.png" +dest_files=["res://.godot/imported/E_Key_Light.png-9fe72c49193260a50b1ed18d45117b1f.ctex"] [params] diff --git a/scenes/Remapping/assets/Positional_Prompts_Down.png b/Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png similarity index 100% rename from scenes/Remapping/assets/Positional_Prompts_Down.png rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png diff --git a/scenes/Remapping/assets/Positional_Prompts_Down.png.import b/Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png.import similarity index 74% rename from scenes/Remapping/assets/Positional_Prompts_Down.png.import rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png.import index 00f28579..a31d40f7 100644 --- a/scenes/Remapping/assets/Positional_Prompts_Down.png.import +++ b/Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d2228hw1busi" -path="res://.godot/imported/Positional_Prompts_Down.png-b3e15455423619c63428f07cb50299dc.ctex" +path="res://.godot/imported/Positional_Prompts_Down.png-b855260def89b120ff1fbf0bcc76916c.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Positional_Prompts_Down.png" -dest_files=["res://.godot/imported/Positional_Prompts_Down.png-b3e15455423619c63428f07cb50299dc.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png" +dest_files=["res://.godot/imported/Positional_Prompts_Down.png-b855260def89b120ff1fbf0bcc76916c.ctex"] [params] diff --git a/scenes/Remapping/assets/Positional_Prompts_Left.png b/Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png similarity index 100% rename from scenes/Remapping/assets/Positional_Prompts_Left.png rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png diff --git a/scenes/Remapping/assets/Positional_Prompts_Left.png.import b/Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png.import similarity index 67% rename from scenes/Remapping/assets/Positional_Prompts_Left.png.import rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png.import index 55caa19a..986944b1 100644 --- a/scenes/Remapping/assets/Positional_Prompts_Left.png.import +++ b/Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dhnaqfw7ev076" -path="res://.godot/imported/Positional_Prompts_Left.png-a65d4cc25e7277af3c038537e36204a9.ctex" +path="res://.godot/imported/Positional_Prompts_Left.png-b56f95c01de276535d499cf8e52a2dd6.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Positional_Prompts_Left.png" -dest_files=["res://.godot/imported/Positional_Prompts_Left.png-a65d4cc25e7277af3c038537e36204a9.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png" +dest_files=["res://.godot/imported/Positional_Prompts_Left.png-b56f95c01de276535d499cf8e52a2dd6.ctex"] [params] diff --git a/scenes/Remapping/assets/Positional_Prompts_Right.png b/Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png similarity index 100% rename from scenes/Remapping/assets/Positional_Prompts_Right.png rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png diff --git a/scenes/Remapping/assets/Positional_Prompts_Right.png.import b/Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png.import similarity index 74% rename from scenes/Remapping/assets/Positional_Prompts_Right.png.import rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png.import index 5e3c9a34..3eb4b865 100644 --- a/scenes/Remapping/assets/Positional_Prompts_Right.png.import +++ b/Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bm2i63ejobjdb" -path="res://.godot/imported/Positional_Prompts_Right.png-7a91b0b4600d650c6bfcac6dd3e771e5.ctex" +path="res://.godot/imported/Positional_Prompts_Right.png-c530b7bc66d02f666feeec64f52e6b06.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Positional_Prompts_Right.png" -dest_files=["res://.godot/imported/Positional_Prompts_Right.png-7a91b0b4600d650c6bfcac6dd3e771e5.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png" +dest_files=["res://.godot/imported/Positional_Prompts_Right.png-c530b7bc66d02f666feeec64f52e6b06.ctex"] [params] diff --git a/scenes/Remapping/assets/Positional_Prompts_Up.png b/Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png similarity index 100% rename from scenes/Remapping/assets/Positional_Prompts_Up.png rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png diff --git a/scenes/Remapping/assets/Positional_Prompts_Up.png.import b/Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png.import similarity index 67% rename from scenes/Remapping/assets/Positional_Prompts_Up.png.import rename to Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png.import index c1def7b1..8c122004 100644 --- a/scenes/Remapping/assets/Positional_Prompts_Up.png.import +++ b/Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dlj21le4bp7cw" -path="res://.godot/imported/Positional_Prompts_Up.png-7d12b23f22144d5032611d5d3d789658.ctex" +path="res://.godot/imported/Positional_Prompts_Up.png-239e554233dd2fd0b22ef9ebefbc3b5d.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Positional_Prompts_Up.png" -dest_files=["res://.godot/imported/Positional_Prompts_Up.png-7d12b23f22144d5032611d5d3d789658.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png" +dest_files=["res://.godot/imported/Positional_Prompts_Up.png-239e554233dd2fd0b22ef9ebefbc3b5d.ctex"] [params] diff --git a/scenes/Remapping/assets/Q_Key_Light.png b/Scenes/UI/Remapping/Assets/Q_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/Q_Key_Light.png rename to Scenes/UI/Remapping/Assets/Q_Key_Light.png diff --git a/scenes/Remapping/assets/Q_Key_Light.png.import b/Scenes/UI/Remapping/Assets/Q_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/Q_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/Q_Key_Light.png.import index fa1691ee..8b3d8f7d 100644 --- a/scenes/Remapping/assets/Q_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/Q_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dn2snw6ibyn78" -path="res://.godot/imported/Q_Key_Light.png-f755c500c9aa3485b97fe1ab3ad96157.ctex" +path="res://.godot/imported/Q_Key_Light.png-dd437257d3d8fd0495a1334ffc31bac8.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/Q_Key_Light.png" -dest_files=["res://.godot/imported/Q_Key_Light.png-f755c500c9aa3485b97fe1ab3ad96157.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/Q_Key_Light.png" +dest_files=["res://.godot/imported/Q_Key_Light.png-dd437257d3d8fd0495a1334ffc31bac8.ctex"] [params] diff --git a/scenes/Remapping/assets/R_Key_Light.png b/Scenes/UI/Remapping/Assets/R_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/R_Key_Light.png rename to Scenes/UI/Remapping/Assets/R_Key_Light.png diff --git a/scenes/Remapping/assets/R_Key_Light.png.import b/Scenes/UI/Remapping/Assets/R_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/R_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/R_Key_Light.png.import index 488c218a..dbd80ba6 100644 --- a/scenes/Remapping/assets/R_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/R_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d3sdo7e5n6qkn" -path="res://.godot/imported/R_Key_Light.png-469a158a72ae0eb478eaa17b8e8eca8d.ctex" +path="res://.godot/imported/R_Key_Light.png-5f8abebbfccbe9a5417f1ebed1e3a199.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/R_Key_Light.png" -dest_files=["res://.godot/imported/R_Key_Light.png-469a158a72ae0eb478eaa17b8e8eca8d.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/R_Key_Light.png" +dest_files=["res://.godot/imported/R_Key_Light.png-5f8abebbfccbe9a5417f1ebed1e3a199.ctex"] [params] diff --git a/scenes/Remapping/assets/S_Key_Light.png b/Scenes/UI/Remapping/Assets/S_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/S_Key_Light.png rename to Scenes/UI/Remapping/Assets/S_Key_Light.png diff --git a/scenes/Remapping/assets/S_Key_Light.png.import b/Scenes/UI/Remapping/Assets/S_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/S_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/S_Key_Light.png.import index 73764c99..22ff5a3f 100644 --- a/scenes/Remapping/assets/S_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/S_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bhjl3xnuwauu0" -path="res://.godot/imported/S_Key_Light.png-9d95010f1d46b091380147634a677962.ctex" +path="res://.godot/imported/S_Key_Light.png-0b94f3ef8198c961a4767f9f25627e55.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/S_Key_Light.png" -dest_files=["res://.godot/imported/S_Key_Light.png-9d95010f1d46b091380147634a677962.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/S_Key_Light.png" +dest_files=["res://.godot/imported/S_Key_Light.png-0b94f3ef8198c961a4767f9f25627e55.ctex"] [params] diff --git a/scenes/Remapping/assets/T_Key_Light.png b/Scenes/UI/Remapping/Assets/T_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/T_Key_Light.png rename to Scenes/UI/Remapping/Assets/T_Key_Light.png diff --git a/scenes/Remapping/assets/T_Key_Light.png.import b/Scenes/UI/Remapping/Assets/T_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/T_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/T_Key_Light.png.import index 8de3232e..acbc5a5a 100644 --- a/scenes/Remapping/assets/T_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/T_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://7v6wwa5trbkf" -path="res://.godot/imported/T_Key_Light.png-aaa37b7abd7eacd88af5f1aa9c56ca90.ctex" +path="res://.godot/imported/T_Key_Light.png-5f9653ef3045ac239de1426add148130.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/T_Key_Light.png" -dest_files=["res://.godot/imported/T_Key_Light.png-aaa37b7abd7eacd88af5f1aa9c56ca90.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/T_Key_Light.png" +dest_files=["res://.godot/imported/T_Key_Light.png-5f9653ef3045ac239de1426add148130.ctex"] [params] diff --git a/scenes/Remapping/assets/W_Key_Light.png b/Scenes/UI/Remapping/Assets/W_Key_Light.png similarity index 100% rename from scenes/Remapping/assets/W_Key_Light.png rename to Scenes/UI/Remapping/Assets/W_Key_Light.png diff --git a/scenes/Remapping/assets/W_Key_Light.png.import b/Scenes/UI/Remapping/Assets/W_Key_Light.png.import similarity index 70% rename from scenes/Remapping/assets/W_Key_Light.png.import rename to Scenes/UI/Remapping/Assets/W_Key_Light.png.import index 9e08ca76..dcd286a9 100644 --- a/scenes/Remapping/assets/W_Key_Light.png.import +++ b/Scenes/UI/Remapping/Assets/W_Key_Light.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://e4dr0lk7ll0e" -path="res://.godot/imported/W_Key_Light.png-8bf0c815e1230db9cd269b81ebd9f71f.ctex" +path="res://.godot/imported/W_Key_Light.png-0a27e3b3ab7dcb396c91bfe71e08d0f2.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://scenes/Remapping/assets/W_Key_Light.png" -dest_files=["res://.godot/imported/W_Key_Light.png-8bf0c815e1230db9cd269b81ebd9f71f.ctex"] +source_file="res://Scenes/UI/Remapping/Assets/W_Key_Light.png" +dest_files=["res://.godot/imported/W_Key_Light.png-0a27e3b3ab7dcb396c91bfe71e08d0f2.ctex"] [params] diff --git a/scenes/Remapping/ControlSettings.cs b/Scenes/UI/Remapping/ControlSettings.cs similarity index 52% rename from scenes/Remapping/ControlSettings.cs rename to Scenes/UI/Remapping/ControlSettings.cs index aaf99269..972c2657 100644 --- a/scenes/Remapping/ControlSettings.cs +++ b/Scenes/UI/Remapping/ControlSettings.cs @@ -1,28 +1,74 @@ -using System; +using System.Collections.Generic; +using FunkEngine; using Godot; -public partial class ControlSettings : Node2D +public partial class ControlSettings : Node2D, IFocusableMenu { + public static readonly string LoadPath = "res://Scenes/UI/Remapping/Remap.tscn"; + [Export] - public Sprite2D leftKey; + public Sprite2D LeftKey; [Export] - public Sprite2D rightKey; + public Sprite2D RightKey; [Export] - public Sprite2D upKey; + public Sprite2D UpKey; [Export] - public Sprite2D downKey; + public Sprite2D DownKey; - private Node _previousScene; - private ProcessModeEnum _previousProcessMode; + public IFocusableMenu Prev { get; set; } [Export] private Button _closeButton; private Button _controllerButton; + private static readonly Dictionary> SpriteMappings = new() + { + { + "WASD", + new Dictionary + { + { "left", "res://Scenes/UI/Remapping/Assets/A_Key_Light.png" }, + { "right", "res://Scenes/UI/Remapping/Assets/D_Key_Light.png" }, + { "up", "res://Scenes/UI/Remapping/Assets/W_Key_Light.png" }, + { "down", "res://Scenes/UI/Remapping/Assets/S_Key_Light.png" }, + } + }, + { + "ARROWS", + new Dictionary + { + { "left", "res://Scenes/UI/Remapping/Assets/Arrow_Left_Key_Light.png" }, + { "right", "res://Scenes/UI/Remapping/Assets/Arrow_Right_Key_Light.png" }, + { "up", "res://Scenes/UI/Remapping/Assets/Arrow_Up_Key_Light.png" }, + { "down", "res://Scenes/UI/Remapping/Assets/Arrow_Down_Key_Light.png" }, + } + }, + { + "QWERT", + new Dictionary + { + { "left", "res://Scenes/UI/Remapping/Assets/Q_Key_Light.png" }, + { "right", "res://Scenes/UI/Remapping/Assets/R_Key_Light.png" }, + { "up", "res://Scenes/UI/Remapping/Assets/W_Key_Light.png" }, + { "down", "res://Scenes/UI/Remapping/Assets/E_Key_Light.png" }, + } + }, + { + "CONTROLLER", + new Dictionary + { + { "left", "res://Scenes/UI/Remapping/Assets/Positional_Prompts_Left.png" }, + { "right", "res://Scenes/UI/Remapping/Assets/Positional_Prompts_Right.png" }, + { "up", "res://Scenes/UI/Remapping/Assets/Positional_Prompts_Up.png" }, + { "down", "res://Scenes/UI/Remapping/Assets/Positional_Prompts_Down.png" }, + } + }, + }; + public override void _Ready() { GetNode