diff --git a/Classes/Notes/Note.cs b/Classes/Notes/Note.cs index 9c16e50f..8795cf42 100644 --- a/Classes/Notes/Note.cs +++ b/Classes/Notes/Note.cs @@ -13,21 +13,20 @@ public partial class Note : Resource private int _baseVal; private Action NoteEffect; //TODO: Where/How to deal with timing. + public string Tooltip; public Texture2D Texture; - //public string Tooltip; - public Note( string name, - PuppetTemplate owner = null, + string tooltip, Texture2D texture = null, + PuppetTemplate owner = null, int baseVal = 1, Action noteEffect = null ) { Name = name; Owner = owner; - Texture = texture; NoteEffect = noteEffect ?? ( @@ -37,6 +36,8 @@ public Note( } ); _baseVal = baseVal; + Texture = texture; + Tooltip = tooltip; } public void OnHit(BattleDirector BD, Timing timing) @@ -48,6 +49,7 @@ public Note Clone() { //Eventually could look into something more robust, but for now shallow copy is preferable. //We only would want val and name to be copied by value - return (Note)MemberwiseClone(); + Note newNote = new Note(Name, Tooltip, Texture, Owner, _baseVal, NoteEffect); + return newNote; } } diff --git a/Classes/Relics/RelicTemplate.cs b/Classes/Relics/RelicTemplate.cs index 892e1bdf..f0a117cc 100644 --- a/Classes/Relics/RelicTemplate.cs +++ b/Classes/Relics/RelicTemplate.cs @@ -7,16 +7,25 @@ public partial class RelicTemplate : Resource public RelicEffect[] Effects; public string Name; - //public Texture2D Texture - //public string Tooltip - public RelicTemplate(string Name = "", RelicEffect[] EffectTags = null) + public Texture2D Texture; + public string Tooltip; + + public RelicTemplate( + string name = "", + string tooltip = "", + Texture2D texture = null, + RelicEffect[] EffectTags = null + ) { Effects = EffectTags; - this.Name = Name; + Name = name; + Tooltip = tooltip; + Texture = texture; } public RelicTemplate Clone() { - return (RelicTemplate)MemberwiseClone(); + RelicTemplate newRelic = new RelicTemplate(Name, Tooltip, Texture, Effects); + return newRelic; } } diff --git a/Classes/Relics/assets/relic_Breakfast.png b/Classes/Relics/assets/relic_Breakfast.png new file mode 100644 index 00000000..1c6bbe1d Binary files /dev/null and b/Classes/Relics/assets/relic_Breakfast.png differ diff --git a/Classes/Relics/assets/relic_Breakfast.png.import b/Classes/Relics/assets/relic_Breakfast.png.import new file mode 100644 index 00000000..6a21aa03 --- /dev/null +++ b/Classes/Relics/assets/relic_Breakfast.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://csjx2hb4tdlw8" +path="res://.godot/imported/relic_Breakfast.png-c1b968058adbb855fcf957a2aec74dc2.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"] + +[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/Classes/Relics/assets/relic_GoodVibes.png b/Classes/Relics/assets/relic_GoodVibes.png new file mode 100644 index 00000000..3ab27727 Binary files /dev/null and b/Classes/Relics/assets/relic_GoodVibes.png differ diff --git a/Classes/Relics/assets/relic_GoodVibes.png.import b/Classes/Relics/assets/relic_GoodVibes.png.import new file mode 100644 index 00000000..c2ff344d --- /dev/null +++ b/Classes/Relics/assets/relic_GoodVibes.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dg4tnp7plxmp7" +path="res://.godot/imported/relic_GoodVibes.png-cd102b29bb163411bb7ce8cf724ef0c0.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"] + +[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/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index 6bf17004..7d422ea6 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -15,6 +15,7 @@ public enum BattleEffectTrigger NotePlaced, NoteHit, SelfNoteHit, + OnPickup, } public enum Timing diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index 7a7d4775..45bc8588 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -12,7 +12,8 @@ public partial class Scribe : Node { new Note( "EnemyBase", - null, + "Basic enemy note, deals damage to player.", + GD.Load("res://scenes/BattleDirector/assets/Character1.png"), null, 1, (director, note, timing) => @@ -22,8 +23,9 @@ public partial class Scribe : Node ), new Note( "PlayerBase", - null, + "Basic player note, deals damage to enemy", GD.Load("res://Classes/Notes/assets/single_note.png"), + null, 1, (director, note, timing) => { @@ -32,8 +34,9 @@ public partial class Scribe : Node ), new Note( "PlayerDouble", - null, + "Basic player note, deals double damage to enemy", GD.Load("res://Classes/Notes/assets/double_note.png"), + null, 1, (director, note, timing) => { @@ -48,39 +51,30 @@ public partial class Scribe : Node { new RelicTemplate( "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"), new RelicEffect[] { new RelicEffect( - BattleEffectTrigger.NotePlaced, - 1, + BattleEffectTrigger.OnPickup, + 10, (director, val) => { - director.Player.Heal(val); + StageProducer.PlayerStats.MaxHealth += val; + StageProducer.PlayerStats.CurrentHealth += val; } ), } ), new RelicTemplate( "Good Vibes", + "Good vibes, heals the player whenever they place a note.", //TODO: Description can include the relics values? + GD.Load("res://Classes/Relics/assets/relic_GoodVibes.png"), new RelicEffect[] { new RelicEffect( BattleEffectTrigger.NotePlaced, - 5, - (director, val) => - { - director.Player.Heal(val); - } - ), - } - ), - new RelicTemplate( - "Dummy Item", - new RelicEffect[] - { - new RelicEffect( - BattleEffectTrigger.NotePlaced, - 100, + 1, (director, val) => { director.Player.Heal(val); diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs index b72c7656..d304eaaa 100644 --- a/Globals/StageProducer.cs +++ b/Globals/StageProducer.cs @@ -10,11 +10,14 @@ public partial class StageProducer : Node public static RandomNumberGenerator GlobalRng = new RandomNumberGenerator(); private ulong _seed; private ulong _lastRngState; + private bool _isInitialized = false; private Stages _curStage = Stages.Title; private Node _curScene; + public static MapGrid.Room CurRoom { get; private set; } + public static Vector2I MapSize { get; private set; } = new Vector2I(7, 6); //For now, make width an odd number - private MapGrid _map = new MapGrid(); + public static MapGrid Map { get; } = new MapGrid(); //Hold here to persist between changes //TODO: Allow for permanent changes and battle temporary stat changes. @@ -27,6 +30,11 @@ public class MapGrid private int _curIdx = 0; private int _curRoom = 0; + public Room[] GetRooms() + { + return _rooms; + } + public class Room { public Room(int idx, int x, int y) @@ -48,10 +56,10 @@ public void AddChild(int newIdx) Children = Children.Append(newIdx).ToArray(); } - private int Idx; - private int[] Children = Array.Empty(); - private int X; - private int Y; + public int Idx { get; private set; } + public int[] Children { get; private set; } = Array.Empty(); + public int X { get; private set; } + public int Y { get; private set; } private string Type; } @@ -61,7 +69,7 @@ public void InitMapGrid(int width, int height, int paths) _rooms = Array.Empty(); _map = new int[width, height]; //x,y - int startX = GlobalRng.RandiRange(0, width - 1); //TODO: Replace with seeding + int startX = (width / 2); _rooms = _rooms.Append(new Room(_curIdx, startX, 0)).ToArray(); _map[startX, 0] = _curIdx++; @@ -69,7 +77,7 @@ public void InitMapGrid(int width, int height, int paths) { GeneratePath_r(startX, 0, width, height); } - + CreateCommonChildren(width, height); AddBossRoom(width, height); } @@ -93,9 +101,25 @@ private void GeneratePath_r(int x, int y, int width, int height) } } + //Asserts that if there is a room at the same x, but y+1 they are connected + private void CreateCommonChildren(int width, int height) + { + foreach (Room room in _rooms) + { + Vector2I curPos = new Vector2I(room.X, room.Y); + if (room.Y + 1 >= height) + continue; + if (_map[curPos.X, curPos.Y + 1] == 0) + continue; + GD.Print("Added child on same X."); + room.AddChild(_map[curPos.X, curPos.Y + 1]); + } + } + + //Adds a boss room at the end of rooms, all max height rooms connect to it. private void AddBossRoom(int width, int height) { - _rooms = _rooms.Append(new Room(_curIdx, 0, height)).ToArray(); + _rooms = _rooms.Append(new Room(_curIdx, width / 2, height)).ToArray(); _rooms[_curIdx].SetType("Boss"); for (int i = 0; i < width; i++) //Attach all last rooms to a boss room { @@ -109,10 +133,19 @@ private void AddBossRoom(int width, int height) public void StartGame() { - _map.InitMapGrid(2, 2, 1); + Map.InitMapGrid(MapSize.X, MapSize.Y, 3); _seed = GlobalRng.Seed; _lastRngState = GlobalRng.State; PlayerStats = new PlayerStats(); + + CurRoom = Map.GetRooms()[0]; + _isInitialized = true; + } + + public void TransitionFromRoom(int nextRoomIdx) + { + //CurRoom = Map.GetRooms()[nextRoomIdx]; + TransitionStage(Stages.Battle); } public void TransitionStage(Stages nextStage) @@ -121,12 +154,19 @@ public void TransitionStage(Stages nextStage) switch (nextStage) { case Stages.Title: + _isInitialized = false; GetTree().ChangeSceneToFile("res://scenes/SceneTransitions/TitleScreen.tscn"); break; case Stages.Battle: - StartGame(); GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn"); break; + case Stages.Map: + GetTree().ChangeSceneToFile("res://scenes/Maps/cartographer.tscn"); + if (!_isInitialized) + { + StartGame(); + } + break; case Stages.Quit: GD.Print("Exiting game"); GetTree().Quit(); diff --git a/project.godot b/project.godot index 7258ddc5..94e0cab0 100644 --- a/project.godot +++ b/project.godot @@ -63,6 +63,11 @@ Pause={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +Inventory={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":73,"key_label":0,"unicode":105,"location":0,"echo":false,"script":null) +] +} [rendering] diff --git a/scenes/BattleDirector/NotePlacementBar.tscn b/scenes/BattleDirector/NotePlacementBar.tscn index cd1003de..7f1133c2 100644 --- a/scenes/BattleDirector/NotePlacementBar.tscn +++ b/scenes/BattleDirector/NotePlacementBar.tscn @@ -13,12 +13,12 @@ gradient = SubResource("Gradient_0u6yv") width = 26 height = 100 -[sub_resource type="Gradient" id="Gradient_lyd0l"] +[sub_resource type="Gradient" id="Gradient_xvck1"] offsets = PackedFloat32Array(0, 0.485915, 0.739437, 1) colors = PackedColorArray(0, 1, 0, 1, 0.68, 0, 0.272, 1, 0, 0.64, 0.608, 1, 0.4, 0, 0, 1) -[sub_resource type="GradientTexture2D" id="GradientTexture2D_k7kvy"] -gradient = SubResource("Gradient_lyd0l") +[sub_resource type="GradientTexture2D" id="GradientTexture2D_0bqho"] +gradient = SubResource("Gradient_xvck1") width = 24 height = 98 fill_to = Vector2(0, 1) @@ -42,7 +42,7 @@ offset_right = 26.0 offset_bottom = 100.0 fill_mode = 3 texture_under = SubResource("GradientTexture2D_hhds4") -texture_progress = SubResource("GradientTexture2D_k7kvy") +texture_progress = SubResource("GradientTexture2D_0bqho") texture_progress_offset = Vector2(1, 1) [node name="TextEdit" type="TextEdit" parent="."] diff --git a/scenes/BattleDirector/scripts/BattleDirector.cs b/scenes/BattleDirector/scripts/BattleDirector.cs index 524b712d..9a0822c1 100644 --- a/scenes/BattleDirector/scripts/BattleDirector.cs +++ b/scenes/BattleDirector/scripts/BattleDirector.cs @@ -32,6 +32,8 @@ public partial class BattleDirector : Node2D private SongData _curSong; + private bool _battleEnd; + #endregion #region Note Handling @@ -60,6 +62,7 @@ public PuppetTemplate GetTarget(Note note) #region Initialization public override void _Ready() { + //TODO: Should come from transition into battle _curSong = new SongData { Bpm = 120, @@ -80,10 +83,18 @@ public override void _Ready() AddChild(Enemy); Enemy.Defeated += CheckBattleStatus; Enemy.Init(GD.Load("res://scenes/BattleDirector/assets/Enemy1.png"), "Enemy"); - Enemy.Sprite.Scale *= 2; - var timer = GetTree().CreateTimer(AudioServer.GetTimeToNextMix()); - timer.Timeout += Begin; + //TODO: This is a temporary measure + Button startButton = new Button(); + startButton.Text = "Start"; + startButton.Position = GetViewportRect().Size / 2; + AddChild(startButton); + startButton.Pressed += () => + { + var timer = GetTree().CreateTimer(AudioServer.GetTimeToNextMix()); + timer.Timeout += Begin; + startButton.QueueFree(); + }; } //TODO: This will all change @@ -93,7 +104,8 @@ private void Begin() CD.Prep(); CD.TimedInput += OnTimedInput; - //TEMP TODO: Make enemies, can put this in an enemy subclass + //TODO: Make enemies, can put this in an enemy subclass + Enemy.Sprite.Scale *= 2; var enemTween = CreateTween(); enemTween.TweenProperty(Enemy.Sprite, "position", Vector2.Down * 5, 1f).AsRelative(); enemTween.TweenProperty(Enemy.Sprite, "position", Vector2.Up * 5, 1f).AsRelative(); @@ -112,6 +124,8 @@ public override void _Process(double delta) { TimeKeeper.CurrentTime = Audio.GetPlaybackPosition(); CD.CheckMiss(); + if (_battleEnd) + GetNode("/root/StageProducer").TransitionStage(Stages.Map); } #endregion @@ -124,7 +138,7 @@ public override void _UnhandledInput(InputEvent @event) { if (eventKey.Keycode == Key.Key0) { - DebugKillEnemy(); + //DebugKillEnemy(); } } @@ -134,6 +148,14 @@ public override void _UnhandledInput(InputEvent @event) GetNode("UILayer").AddChild(pauseMenu.Instantiate()); GetTree().Paused = true; } + if (@event.IsActionPressed("Inventory")) + { + var invenMenu = GD.Load("res://scenes/UI/inventory.tscn") + .Instantiate(); + GetNode("UILayer").AddChild(invenMenu); + invenMenu.Display(Player.Stats); + GetTree().Paused = true; + } } private void OnNotePressed(ArrowType type) @@ -151,9 +173,8 @@ private void OnTimedInput(Note note, ArrowType arrowType, int beat, double beatD PlayerAddNote(arrowType, beat); return; } - //TODO: Evaluate Timing as a function + Timing timed = CheckTiming(beatDif); - GD.Print(timed); if (timed == Timing.Miss) { @@ -193,6 +214,7 @@ private void CheckBattleStatus(PuppetTemplate puppet) if (puppet == Player) { GD.Print("Player is Dead"); + GetNode("/root/StageProducer").TransitionStage(Stages.Title); return; } @@ -201,6 +223,7 @@ private void CheckBattleStatus(PuppetTemplate puppet) { GD.Print("Enemy is dead"); ShowRewardSelection(3); + _battleEnd = true; } } @@ -224,7 +247,6 @@ private void EventizeRelics() { foreach (var relic in Player.Stats.CurRelics) { - GetNode