From c8ed5a93f3270e6d3fa02fbb98f093702c57ae82 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Mon, 21 Apr 2025 15:23:27 -0700 Subject: [PATCH 1/5] Added MapConfig Struct --- Globals/FunkEngineNameSpace.cs | 48 +++++++++++++++++++++++++++ Globals/Translations/Translations.csv | 6 ++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index a280d737..23dd0c49 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using FunkEngine.Classes.MidiMaestro; using Godot; @@ -308,6 +309,53 @@ public void AddChild(int newIdx) } } + public struct MapConfig + { + public int Width { get; private set; } + public int Height { get; private set; } + public int Paths { get; private set; } + + /// + /// Rooms that exist at set levels, only one room can be set per y-level. + /// + public Dictionary SetRooms { get; private set; } = + new() + { + { 0, Stages.Battle }, //The first, e.g. y = 0 room, should always be a battle. + }; + + public const int NumStages = 2; + + public static readonly Stages[] StagsToRoll = new[] { Stages.Battle, Stages.Chest }; + + /// + /// The odds for each stage to appear in a non-set room position. + /// + public float[] StageOdds = new float[2]; + + public MapConfig(int width, int height, int paths, float[] odds) + { + Width = width; + Height = height; + Paths = paths; + for (int i = 0; i < NumStages; i++) + { + StageOdds[i] = odds[i]; + } + } + + /// + /// Adds a set room type to be generated guaranteed. Additional entries in the same y-level are ignored. + /// + /// The y-level of the rooms + /// The room type to be set. + public MapConfig AddSetRoom(int height, Stages roomType) + { + SetRooms.TryAdd(height, roomType); + return this; + } + } + /** * Initializes the map with max width, max height, and with number of paths. */ diff --git a/Globals/Translations/Translations.csv b/Globals/Translations/Translations.csv index 81994a67..0424d412 100644 --- a/Globals/Translations/Translations.csv +++ b/Globals/Translations/Translations.csv @@ -65,15 +65,15 @@ RELIC_COLORBOROS_TOOLTIP,"Taste the rainbow. Charges the freestyle bar every rif RELIC_CHIPS_NAME,"Chips",薯片 RELIC_CHIPS_TOOLTIP,"Hitting a note deals a bit of damage.","击中音符会造成少量伤害。" RELIC_PAPERCUT_NAME,Paper Cut,纸割伤 -RELIC_PAPERCUT_TOOLTIP,"Deals damage each loop.","每轮造成伤害" +RELIC_PAPERCUT_TOOLTIP,"Deals damage each riff.","每轮造成伤害" RELIC_ENERGYDRINK_NAME,Energy Drink,"能量饮料" RELIC_ENERGYDRINK_TOOLTIP,"Take a chance to cool down and sip an energy drink to increase your max energy bar.","碰碰运气,喝一口能量饮料来冷静下来并增加你的最大能量条。" RELIC_BANDAGE_NAME,Bandage,"绷带" RELIC_BANDAGE_TOOLTIP,"A clean strip of cloth. Use it after a fight to patch up and feel better.","一块干净的布条,战斗后使用来包扎并恢复一些健康。" RELIC_MEDKIT_NAME,Medkit,"急救包" -RELIC_MEDKIT_TOOLTIP,"A small kit with medical supplies. Heals you a bit after each loop.","包含一些医疗用品的小包,每次循环后恢复少量生命。" +RELIC_MEDKIT_TOOLTIP,"A small kit with medical supplies. Heals you a bit after each riff.","包含一些医疗用品的小包,每次循环后恢复少量生命。" RELIC_VINYLRECORD_NAME,Vinyl Record,"黑胶唱片" -RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All loop effects trigger twice.","把我转起来,把我转起来。所有循环效果触发两次。" +RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All riff effects trigger twice.","把我转起来,把我转起来。所有循环效果触发两次。" INVENTORY_TAB_NOTES,Notes,乐谱 INVENTORY_TAB_RELICS,Relics,遗物 OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置 From 9105d3f154f703d40c8971ce8e90e4d9d86c5b78 Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Mon, 21 Apr 2025 15:43:22 -0700 Subject: [PATCH 2/5] Reworked map systems to use configs --- Globals/FunkEngineNameSpace.cs | 43 ++++++++++++++++------------- Globals/StageProducer.cs | 10 +++++-- Scenes/Maps/Scripts/Cartographer.cs | 2 +- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index 23dd0c49..0047a0e2 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -309,6 +309,7 @@ public void AddChild(int newIdx) } } + //TODO: Make odds for rooms based on y-level, e.g. elites only spawn on y > 3 public struct MapConfig { public int Width { get; private set; } @@ -359,56 +360,60 @@ public MapConfig AddSetRoom(int height, Stages roomType) /** * Initializes the map with max width, max height, and with number of paths. */ - public void InitMapGrid(int width, int height, int paths) + public void InitMapGrid(MapConfig curConfig) { _curIdx = 0; - _rooms = Array.Empty(); - _map = new int[width, height]; //x,y + _rooms = []; + _map = new int[curConfig.Width, curConfig.Height]; //x,y - int startX = (width / 2); + int startX = (curConfig.Width / 2); _rooms = _rooms.Append(new Room(_curIdx, startX, 0)).ToArray(); _rooms[0].SetType(Stages.Battle); _map[startX, 0] = _curIdx++; - for (int i = 0; i < paths; i++) + for (int i = 0; i < curConfig.Paths; i++) { - GeneratePath_r(startX, 0, width, height); + GeneratePath_r(startX, 0, curConfig); } - CreateCommonChildren(width, height); - AddBossRoom(width, height); + CreateCommonChildren(curConfig.Width, curConfig.Height); + AddBossRoom(curConfig.Width, curConfig.Height); } /**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) + private void GeneratePath_r(int x, int y, MapConfig curConfig) { int nextX = StageProducer.GlobalRng.RandiRange( Math.Max(x - 1, 0), - Math.Min(x + 1, width - 1) + Math.Min(x + 1, curConfig.Width - 1) ); if (_map[nextX, y + 1] == 0) { _rooms = _rooms.Append(new Room(_curIdx, nextX, y + 1)).ToArray(); _map[nextX, y + 1] = _curIdx; _rooms[_map[x, y]].AddChild(_curIdx++); - _rooms[^1].SetType(PickRoomType(x, y)); + _rooms[^1].SetType(PickRoomType(x, y, curConfig)); } else { _rooms[_map[x, y]].AddChild(_map[nextX, y + 1]); } - if (y < height - 2) + if (y < curConfig.Height - 2) { - GeneratePath_r(nextX, y + 1, width, height); + GeneratePath_r(nextX, y + 1, curConfig); } } - private Stages PickRoomType(int x, int y) + private Stages PickRoomType(int x, int y, MapConfig curConfig) { - if (y % 3 == 0) - return Stages.Chest; - if (StageProducer.GlobalRng.Randf() < .08) - return Stages.Chest; - return Stages.Battle; + //If the y has a set room return it. + if (curConfig.SetRooms.TryGetValue(y, out Stages result)) + { + return result; + } + + //Random roll for the room type. + int idx = (int)StageProducer.GlobalRng.RandWeighted(curConfig.StageOdds); + return MapConfig.StagsToRoll[idx]; } //Asserts that if there is a room at the same x, but y+1 they are connected diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs index 97770b5a..5b2fa1a6 100644 --- a/Globals/StageProducer.cs +++ b/Globals/StageProducer.cs @@ -13,7 +13,13 @@ public partial class StageProducer : Node public static readonly RandomNumberGenerator GlobalRng = new(); - public static Vector2I MapSize { get; } = new(7, 6); //For now, make width an odd number + private static readonly MapGrid.MapConfig FirstMapConfig = new MapGrid.MapConfig( + 7, + 6, + 3, + [10, 1] + ).AddSetRoom(3, Stages.Chest); + public static MapGrid Map { get; } = new(); private Stages _curStage = Stages.Title; public static int CurRoom { get; private set; } @@ -53,7 +59,7 @@ private void InitFromCfg() 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); + Map.InitMapGrid(FirstMapConfig); } private void StartNewGame() diff --git a/Scenes/Maps/Scripts/Cartographer.cs b/Scenes/Maps/Scripts/Cartographer.cs index ae82b875..5400b54c 100644 --- a/Scenes/Maps/Scripts/Cartographer.cs +++ b/Scenes/Maps/Scripts/Cartographer.cs @@ -51,7 +51,7 @@ public override void _EnterTree() private Vector2 GetPosition(int x, int y) { - return new Vector2((float)x * 640 / StageProducer.MapSize.X - 1 + 64, y * 48 + 16); + return new Vector2((float)x * 640 / 6 + 64, y * 48 + 16); } private void DrawMap() From 43c2781a7d82a1381e2f216735a4a346eff1efbc Mon Sep 17 00:00:00 2001 From: LifeHckr Date: Mon, 21 Apr 2025 19:38:29 -0700 Subject: [PATCH 3/5] Added handling for new areas Important scenes' backgrounds change based on area. Added a transitional scene between areas MapConfigs set for each area Ability to generate new map for new area. Map in Cartographer to better show nearby map rooms. --- Globals/FunkEngineNameSpace.cs | 7 +++ Globals/StageProducer.cs | 55 +++++++++++++++++-- Globals/Translations/Translations.csv | 1 + Scenes/BattleDirector/BattleScene.tscn | 3 +- .../BattleDirector/Scripts/BattleDirector.cs | 10 ++++ Scenes/ChestScene/ChestScene.cs | 10 ++++ Scenes/ChestScene/ChestScene.tscn | 3 +- Scenes/Maps/Cartographer.tscn | 11 +++- Scenes/Maps/InBetween.tscn | 24 ++++++++ Scenes/Maps/Scripts/Cartographer.cs | 38 ++++++++++++- 10 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 Scenes/Maps/InBetween.tscn diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs index 0047a0e2..c73800f6 100644 --- a/Globals/FunkEngineNameSpace.cs +++ b/Globals/FunkEngineNameSpace.cs @@ -252,6 +252,13 @@ public enum Stages Quit, Map, Load, + Continue, +} + +public enum Area +{ + Forest = 0, + City = 1, } public enum Rarity diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs index 5b2fa1a6..81010ad0 100644 --- a/Globals/StageProducer.cs +++ b/Globals/StageProducer.cs @@ -20,9 +20,25 @@ public partial class StageProducer : Node [10, 1] ).AddSetRoom(3, Stages.Chest); - public static MapGrid Map { get; } = new(); + private static readonly MapGrid.MapConfig TestMapConfig = new MapGrid.MapConfig( + 10, + 10, + 5, + [10, 2] + ) + .AddSetRoom(3, Stages.Chest) + .AddSetRoom(6, Stages.Chest); + + private static readonly MapGrid.MapConfig[] MapConfigs = new[] + { + FirstMapConfig, + TestMapConfig, + }; + + public static MapGrid Map { get; private set; } = new(); private Stages _curStage = Stages.Title; public static int CurRoom { get; private set; } + public static Area CurArea { get; private set; } = Area.Forest; private Node _curScene; private Node _preloadStage; @@ -59,12 +75,13 @@ private void InitFromCfg() private void GenerateMapConsistent() { GlobalRng.State = GlobalRng.Seed << 5 / 2; //Fudge seed state, to get consistent maps across new/loaded games - Map.InitMapGrid(FirstMapConfig); + Map.InitMapGrid(MapConfigs[(int)CurArea]); } private void StartNewGame() { GlobalRng.Randomize(); + CurArea = Area.Forest; GenerateMapConsistent(); PlayerStats = new PlayerStats(); @@ -118,10 +135,10 @@ 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. - */ + /// + /// To be used from Cartographer. Preloads the scene during transition animation. This removes the occasionally noticeable load time for the scene change. + /// + /// Index of the next room in the map to get the stage from. public void PreloadScene(int nextRoomIdx) { Stages nextStage = Map.GetRooms()[nextRoomIdx].Type; @@ -180,6 +197,10 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1) case Stages.Quit: GetTree().Quit(); return; + case Stages.Continue: + ProgressAreas(); + GetTree().ChangeSceneToFile("res://Scenes/Maps/InBetween.tscn"); + break; default: GD.PushError($"Error Scene Transition is {nextStage}"); break; @@ -233,4 +254,26 @@ public override void _Input(InputEvent @event) return; } } + + #region Area Management + + /// + /// There should always be a mapconfig for each area. It's preferable to crash later if there isn't even a placeholder config. + /// + /// True if there is another area. + public static bool IsMoreAreas() + { + return (int)CurArea + 1 < MapConfigs.Length; + } + + public void ProgressAreas() + { + CurArea += 1; + + Map = new(); + GenerateMapConsistent(); + CurRoom = Map.GetRooms()[0].Idx; + } + + #endregion } diff --git a/Globals/Translations/Translations.csv b/Globals/Translations/Translations.csv index 0424d412..1aecaf4f 100644 --- a/Globals/Translations/Translations.csv +++ b/Globals/Translations/Translations.csv @@ -20,6 +20,7 @@ CONTROLS_CHOOSE_BUTTON,Choose new button,选择输入按钮 ESCAPE_MENU_RESUME,Resume,继续 ESCAPE_MENU_QUIT,Quit,退出 ESCAPE_MENU_TITLE,Quit to Title,返回标题 +INBETWEEN_CONTINUE,Continue,(TODO) CHEST_ROOM_REWARDS,Reward Selection!,奖励! CHEST_ROOM_SKIP,Skip,跳过 CHEST_ROOM_ACCEPT,Accept,接受 diff --git a/Scenes/BattleDirector/BattleScene.tscn b/Scenes/BattleDirector/BattleScene.tscn index 40024205..6247e337 100644 --- a/Scenes/BattleDirector/BattleScene.tscn +++ b/Scenes/BattleDirector/BattleScene.tscn @@ -18,9 +18,10 @@ gradient = SubResource("Gradient_8uy3a") fill_from = Vector2(1, 0) fill_to = Vector2(0.738532, 1) -[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")] +[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("BackgroundRect", "PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")] process_mode = 1 script = ExtResource("1_jmdo1") +BackgroundRect = NodePath("BackGround") PuppetMarkers = [NodePath("PlayerMarker"), NodePath("Enemy1Marker"), NodePath("Enemy2Marker"), NodePath("Enemy3Marker")] CD = NodePath("Conductor") CM = NodePath("SubViewport") diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs index 6a83124c..42f83fda 100644 --- a/Scenes/BattleDirector/Scripts/BattleDirector.cs +++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs @@ -15,6 +15,9 @@ public partial class BattleDirector : Node2D public PlayerPuppet Player; private EnemyPuppet[] _enemies; + [Export] + public TextureRect BackgroundRect; + [Export] public Marker2D[] PuppetMarkers = new Marker2D[4]; //[0] is always player @@ -57,6 +60,13 @@ private void BeginPlayback() public override void _Ready() { + BackgroundRect.Texture = StageProducer.CurArea switch + { + Area.Forest => GD.Load("res://SharedAssets/BackGround_Full.png"), + Area.City => GD.Load("res://icon.svg"), + _ => null, + }; + SongData curSong = StageProducer.Config.CurSong.SongData; Audio.SetStream(GD.Load(StageProducer.Config.CurSong.AudioLocation)); if (curSong.SongLength <= 0) diff --git a/Scenes/ChestScene/ChestScene.cs b/Scenes/ChestScene/ChestScene.cs index 8d32acbf..d36c8929 100644 --- a/Scenes/ChestScene/ChestScene.cs +++ b/Scenes/ChestScene/ChestScene.cs @@ -15,8 +15,18 @@ public partial class ChestScene : Node2D [Export] public Marker2D PlayerMarker; + [Export] + public TextureRect BackgroundRect; + public override void _Ready() { + BackgroundRect.Texture = StageProducer.CurArea switch //TODO: Standardized BG changing behaviour. + { + Area.Forest => GD.Load("res://SharedAssets/BackGround_Full.png"), + Area.City => GD.Load("res://icon.svg"), + _ => null, + }; + _player = GD.Load(PlayerPuppet.LoadPath).Instantiate(); PlayerMarker.AddChild(_player); diff --git a/Scenes/ChestScene/ChestScene.tscn b/Scenes/ChestScene/ChestScene.tscn index 96281b84..fc4279c6 100644 --- a/Scenes/ChestScene/ChestScene.tscn +++ b/Scenes/ChestScene/ChestScene.tscn @@ -16,11 +16,12 @@ shader_parameter/bg_bottom_color = Vector4(0.028, 0.008, 0.184, 0) shader_parameter/gradient_ratio = 1.0 shader_parameter/time_scale = 1.0 -[node name="ChestScene" type="Node2D" node_paths=PackedStringArray("ChestButton", "PlayerMarker")] +[node name="ChestScene" type="Node2D" node_paths=PackedStringArray("ChestButton", "PlayerMarker", "BackgroundRect")] process_mode = 1 script = ExtResource("1_ardd2") ChestButton = NodePath("CenterContainer/VBoxContainer/ChestButton") PlayerMarker = NodePath("PlayerMarker") +BackgroundRect = NodePath("BackGround") [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] stream = ExtResource("2_x78jo") diff --git a/Scenes/Maps/Cartographer.tscn b/Scenes/Maps/Cartographer.tscn index f492aa8e..fa337ae6 100644 --- a/Scenes/Maps/Cartographer.tscn +++ b/Scenes/Maps/Cartographer.tscn @@ -6,11 +6,18 @@ [ext_resource type="Theme" uid="uid://bcejp4llrb3m0" path="res://Scenes/UI/Assets/EmptyButton.tres" id="2_rnj1y"] [ext_resource type="Texture2D" uid="uid://cmc7gcplqnebx" path="res://SharedAssets/Player.png" id="3_qiprp"] -[node name="Cartographer" type="Node2D" node_paths=PackedStringArray("PlayerSprite")] +[node name="Cartographer" type="Node2D" node_paths=PackedStringArray("BackgroundSprite", "PlayerSprite", "Camera")] process_mode = 1 script = ExtResource("1_u4q3n") +BackgroundSprite = NodePath("BG") PlayerSprite = NodePath("Player") ButtonTheme = ExtResource("2_rnj1y") +Camera = NodePath("TheView") + +[node name="TheView" type="Camera2D" parent="."] +top_level = true +anchor_mode = 0 +limit_top = -10 [node name="UI" type="CanvasLayer" parent="." node_paths=PackedStringArray("CurSceneNode")] script = ExtResource("2_cl7v0") @@ -18,7 +25,7 @@ CurSceneNode = NodePath("..") [node name="BG" type="Sprite2D" parent="."] modulate = Color(0.462, 0.462, 0.66, 1) -position = Vector2(-10, 229) +position = Vector2(175, 240) scale = Vector2(3, 3) texture = ExtResource("2_5g6at") diff --git a/Scenes/Maps/InBetween.tscn b/Scenes/Maps/InBetween.tscn new file mode 100644 index 00000000..d425f862 --- /dev/null +++ b/Scenes/Maps/InBetween.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=4 format=3 uid="uid://djlperv5n75y1"] + +[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="1_74aj5"] +[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="2_dapxv"] +[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="3_35xdc"] + +[node name="Inbetween" type="Node2D"] + +[node name="Sprite2D" type="Sprite2D" parent="."] +position = Vector2(197, 86) +rotation = 3.72628 +scale = Vector2(3.81, 3.81) +texture = ExtResource("1_74aj5") + +[node name="Button" type="Button" parent="."] +offset_left = 263.0 +offset_top = 276.0 +offset_right = 271.0 +offset_bottom = 284.0 +theme = ExtResource("2_dapxv") +text = "INBETWEEN_CONTINUE" +script = ExtResource("3_35xdc") +ScenePath = 5 +_startFocused = true diff --git a/Scenes/Maps/Scripts/Cartographer.cs b/Scenes/Maps/Scripts/Cartographer.cs index 5400b54c..e143b44f 100644 --- a/Scenes/Maps/Scripts/Cartographer.cs +++ b/Scenes/Maps/Scripts/Cartographer.cs @@ -11,12 +11,18 @@ public partial class Cartographer : Node2D { public static readonly string LoadPath = "res://Scenes/Maps/Cartographer.tscn"; + [Export] + public Sprite2D BackgroundSprite; + [Export] public Sprite2D PlayerSprite; [Export] public Theme ButtonTheme; + [Export] + public Camera2D Camera; + private Button[] _validButtons = Array.Empty