diff --git a/Audio/District_Four.ogg b/Audio/District_Four.ogg new file mode 100644 index 00000000..d6cba76b Binary files /dev/null and b/Audio/District_Four.ogg differ diff --git a/Audio/District_Four.ogg.import b/Audio/District_Four.ogg.import new file mode 100644 index 00000000..a603eea4 --- /dev/null +++ b/Audio/District_Four.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://bffy1ysxfrte6" +path="res://.godot/imported/District_Four.ogg-f8fbac641cef73b68aacab4d4b38fbd8.oggvorbisstr" + +[deps] + +source_file="res://Audio/District_Four.ogg" +dest_files=["res://.godot/imported/District_Four.ogg-f8fbac641cef73b68aacab4d4b38fbd8.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/Audio/TutorialSong.ogg b/Audio/TutorialSong.ogg new file mode 100644 index 00000000..f872fab5 Binary files /dev/null and b/Audio/TutorialSong.ogg differ diff --git a/Audio/TutorialSong.ogg.import b/Audio/TutorialSong.ogg.import new file mode 100644 index 00000000..a031031e --- /dev/null +++ b/Audio/TutorialSong.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cr3ehxww3eg5o" +path="res://.godot/imported/TutorialSong.ogg-00527cc92390b837058f07c9a386e555.oggvorbisstr" + +[deps] + +source_file="res://Audio/TutorialSong.ogg" +dest_files=["res://.godot/imported/TutorialSong.ogg-00527cc92390b837058f07c9a386e555.oggvorbisstr"] + +[params] + +loop=true +loop_offset=0.0 +bpm=0.0 +beat_count=0 +bar_beats=4 diff --git a/Audio/songMaps/TutorialBoss176_7.tres b/Audio/songMaps/TutorialBoss176_7.tres new file mode 100644 index 00000000..b90c3588 --- /dev/null +++ b/Audio/songMaps/TutorialBoss176_7.tres @@ -0,0 +1,296 @@ +[gd_resource type="Resource" load_steps=60 format=3] + +[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_w1u0b"] +[ext_resource type="Script" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_gbai3"] + +[sub_resource type="Resource" id="Resource_sxt82"] +script = ExtResource("1_w1u0b") +Beat = 64.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_j5ca6"] +script = ExtResource("1_w1u0b") +Beat = 72.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_cfyig"] +script = ExtResource("1_w1u0b") +Beat = 48.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_oq2fs"] +script = ExtResource("1_w1u0b") +Beat = 16.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_bv13m"] +script = ExtResource("1_w1u0b") +Beat = 17.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_lg6ov"] +script = ExtResource("1_w1u0b") +Beat = 40.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_eg7rs"] +script = ExtResource("1_w1u0b") +Beat = 33.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_x3k65"] +script = ExtResource("1_w1u0b") +Beat = 41.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_d5g7d"] +script = ExtResource("1_w1u0b") +Beat = 56.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_1cpsm"] +script = ExtResource("1_w1u0b") +Beat = 28.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_giltv"] +script = ExtResource("1_w1u0b") +Beat = 86.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_oqa5e"] +script = ExtResource("1_w1u0b") +Beat = 32.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_kk6vq"] +script = ExtResource("1_w1u0b") +Beat = 48.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_3scxn"] +script = ExtResource("1_w1u0b") +Beat = 33.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_p5ohh"] +script = ExtResource("1_w1u0b") +Beat = 41.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_dxorp"] +script = ExtResource("1_w1u0b") +Beat = 57.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_pm5wf"] +script = ExtResource("1_w1u0b") +Beat = 80.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_biar7"] +script = ExtResource("1_w1u0b") +Beat = 28.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_bnjg0"] +script = ExtResource("1_w1u0b") +Beat = 87.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_7gvq1"] +script = ExtResource("1_w1u0b") +Beat = 49.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_pgga6"] +script = ExtResource("1_w1u0b") +Beat = 63.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_gr1jk"] +script = ExtResource("1_w1u0b") +Beat = 40.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_w2pru"] +script = ExtResource("1_w1u0b") +Beat = 70.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_wgekv"] +script = ExtResource("1_w1u0b") +Beat = 71.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_qsagv"] +script = ExtResource("1_w1u0b") +Beat = 32.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_gmjq8"] +script = ExtResource("1_w1u0b") +Beat = 33.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_35mcn"] +script = ExtResource("1_w1u0b") +Beat = 49.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_pwkkg"] +script = ExtResource("1_w1u0b") +Beat = 56.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_gks01"] +script = ExtResource("1_w1u0b") +Beat = 57.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_vp8wv"] +script = ExtResource("1_w1u0b") +Beat = 79.0 +Length = 3.0 + +[sub_resource type="Resource" id="Resource_ur61o"] +script = ExtResource("1_w1u0b") +Beat = 18.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_71lt2"] +script = ExtResource("1_w1u0b") +Beat = 26.0 +Length = 2.0 + +[sub_resource type="Resource" id="Resource_w1u0b"] +script = ExtResource("1_w1u0b") +Beat = 8.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_gbai3"] +script = ExtResource("1_w1u0b") +Beat = 9.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_bcwc6"] +script = ExtResource("1_w1u0b") +Beat = 16.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_0k2f6"] +script = ExtResource("1_w1u0b") +Beat = 17.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_tgoco"] +script = ExtResource("1_w1u0b") +Beat = 24.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_x1j4d"] +script = ExtResource("1_w1u0b") +Beat = 25.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_e76xg"] +script = ExtResource("1_w1u0b") +Beat = 32.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_vhygb"] +script = ExtResource("1_w1u0b") +Beat = 40.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_unq76"] +script = ExtResource("1_w1u0b") +Beat = 41.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_cn75w"] +script = ExtResource("1_w1u0b") +Beat = 48.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_3pobr"] +script = ExtResource("1_w1u0b") +Beat = 49.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_43v1q"] +script = ExtResource("1_w1u0b") +Beat = 56.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_2i0ix"] +script = ExtResource("1_w1u0b") +Beat = 57.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_eo1b6"] +script = ExtResource("1_w1u0b") +Beat = 64.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_ehfsr"] +script = ExtResource("1_w1u0b") +Beat = 65.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_05gdy"] +script = ExtResource("1_w1u0b") +Beat = 72.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_b164v"] +script = ExtResource("1_w1u0b") +Beat = 73.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_86j1n"] +script = ExtResource("1_w1u0b") +Beat = 80.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_p6bp3"] +script = ExtResource("1_w1u0b") +Beat = 81.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_7erhr"] +script = ExtResource("1_w1u0b") +Beat = 88.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_n6xrx"] +script = ExtResource("1_w1u0b") +Beat = 89.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_75ujr"] +script = ExtResource("1_w1u0b") +Beat = 96.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_mlxr3"] +script = ExtResource("1_w1u0b") +Beat = 97.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_5vw1o"] +script = ExtResource("1_w1u0b") +Beat = 29.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_suuru"] +script = ExtResource("1_w1u0b") +Beat = 30.0 +Length = 0.0 + +[resource] +script = ExtResource("2_gbai3") +UpLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_w1u0b"), SubResource("Resource_gbai3"), SubResource("Resource_bcwc6"), SubResource("Resource_0k2f6"), SubResource("Resource_tgoco"), SubResource("Resource_x1j4d"), SubResource("Resource_e76xg"), SubResource("Resource_vhygb"), SubResource("Resource_unq76"), SubResource("Resource_cn75w"), SubResource("Resource_3pobr"), SubResource("Resource_43v1q"), SubResource("Resource_2i0ix"), SubResource("Resource_eo1b6"), SubResource("Resource_ehfsr"), SubResource("Resource_05gdy"), SubResource("Resource_b164v"), SubResource("Resource_86j1n"), SubResource("Resource_p6bp3"), SubResource("Resource_7erhr"), SubResource("Resource_n6xrx"), SubResource("Resource_75ujr"), SubResource("Resource_mlxr3"), SubResource("Resource_5vw1o"), SubResource("Resource_suuru")]) +DownLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_sxt82"), SubResource("Resource_j5ca6"), SubResource("Resource_cfyig"), SubResource("Resource_oq2fs"), SubResource("Resource_bv13m"), SubResource("Resource_lg6ov"), SubResource("Resource_eg7rs"), SubResource("Resource_x3k65"), SubResource("Resource_d5g7d"), SubResource("Resource_1cpsm"), SubResource("Resource_giltv")]) +LeftLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_oqa5e"), SubResource("Resource_kk6vq"), SubResource("Resource_3scxn"), SubResource("Resource_p5ohh"), SubResource("Resource_dxorp"), SubResource("Resource_pm5wf"), SubResource("Resource_biar7"), SubResource("Resource_bnjg0"), SubResource("Resource_7gvq1")]) +RightLaneData = Array[ExtResource("1_w1u0b")]([SubResource("Resource_pgga6"), SubResource("Resource_gr1jk"), SubResource("Resource_w2pru"), SubResource("Resource_wgekv"), SubResource("Resource_qsagv"), SubResource("Resource_gmjq8"), SubResource("Resource_35mcn"), SubResource("Resource_pwkkg"), SubResource("Resource_gks01"), SubResource("Resource_vp8wv"), SubResource("Resource_ur61o"), SubResource("Resource_71lt2")]) diff --git a/Audio/songMaps/TutorialSong.tres b/Audio/songMaps/TutorialSong.tres new file mode 100644 index 00000000..a24d6ee3 --- /dev/null +++ b/Audio/songMaps/TutorialSong.tres @@ -0,0 +1,111 @@ +[gd_resource type="Resource" load_steps=23 format=3 uid="uid://1ag6pnhqf2v1"] + +[ext_resource type="Script" uid="uid://bhbpcmtr6e6pk" path="res://Classes/MidiMaestro/NoteInfo.cs" id="1_roxhp"] +[ext_resource type="Script" uid="uid://bnpnavb5lwobj" path="res://Classes/MidiMaestro/NoteChart.cs" id="2_bsw0b"] + +[sub_resource type="Resource" id="Resource_a0ovt"] +script = ExtResource("1_roxhp") +Beat = 3.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_ahash"] +script = ExtResource("1_roxhp") +Beat = 7.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_6gc2p"] +script = ExtResource("1_roxhp") +Beat = 11.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_tjsh3"] +script = ExtResource("1_roxhp") +Beat = 15.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_s18ys"] +script = ExtResource("1_roxhp") +Beat = 17.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_wcsgu"] +script = ExtResource("1_roxhp") +Beat = 21.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_r81qg"] +script = ExtResource("1_roxhp") +Beat = 25.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_roxhp"] +script = ExtResource("1_roxhp") +Beat = 29.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_ifw8a"] +script = ExtResource("1_roxhp") +Beat = 18.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_d0m6p"] +script = ExtResource("1_roxhp") +Beat = 22.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_owwlp"] +script = ExtResource("1_roxhp") +Beat = 26.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_bnbk2"] +script = ExtResource("1_roxhp") +Beat = 2.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_t2mc0"] +script = ExtResource("1_roxhp") +Beat = 6.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_xl4h8"] +script = ExtResource("1_roxhp") +Beat = 10.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_7i220"] +script = ExtResource("1_roxhp") +Beat = 14.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_txc3y"] +script = ExtResource("1_roxhp") +Beat = 16.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_iixj3"] +script = ExtResource("1_roxhp") +Beat = 20.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_5o1tj"] +script = ExtResource("1_roxhp") +Beat = 24.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_l3ivu"] +script = ExtResource("1_roxhp") +Beat = 28.0 +Length = 0.0 + +[sub_resource type="Resource" id="Resource_d6d5y"] +script = ExtResource("1_roxhp") +Beat = 30.0 +Length = 0.0 + +[resource] +script = ExtResource("2_bsw0b") +UpLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_bnbk2"), SubResource("Resource_t2mc0"), SubResource("Resource_xl4h8"), SubResource("Resource_7i220"), SubResource("Resource_txc3y"), SubResource("Resource_iixj3"), SubResource("Resource_5o1tj"), SubResource("Resource_l3ivu"), SubResource("Resource_d6d5y")]) +DownLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_a0ovt"), SubResource("Resource_ahash"), SubResource("Resource_6gc2p"), SubResource("Resource_tjsh3"), SubResource("Resource_s18ys"), SubResource("Resource_wcsgu"), SubResource("Resource_r81qg"), SubResource("Resource_roxhp")]) +LeftLaneData = Array[ExtResource("1_roxhp")]([SubResource("Resource_ifw8a"), SubResource("Resource_d0m6p"), SubResource("Resource_owwlp")]) +RightLaneData = Array[ExtResource("1_roxhp")]([]) diff --git a/Classes/MapAreas/MapLevels.cs b/Classes/MapAreas/MapLevels.cs index 6287ada7..16d7fa2e 100644 --- a/Classes/MapAreas/MapLevels.cs +++ b/Classes/MapAreas/MapLevels.cs @@ -107,7 +107,7 @@ private MapLevels( private static readonly MapLevels[] PresetLevels = new[] { - new MapLevels(0, TutorialMapConfig, [0], [], [3], 1), + new MapLevels(0, TutorialMapConfig, [4], [], [5], 1), new MapLevels(1, FirstMapConfig, [1, 2, 3], [], [0], -1), }; #endregion diff --git a/Globals/SaveSystem.cs b/Globals/SaveSystem.cs index d78f27df..f5551751 100644 --- a/Globals/SaveSystem.cs +++ b/Globals/SaveSystem.cs @@ -14,7 +14,7 @@ public static class SaveSystem private static ConfigFile _curConfigData; private const float DefaultVolume = 1f; - private const string DefaultInputType = "WASD"; + private const string DefaultInputType = "WASD"; //WASD or CONTROLLER private const int DefaultInputKeyboardUp = 87; //W private const int DefaultInputKeyboardLeft = 65; //A private const int DefaultInputKeyboardDown = 83; //S @@ -29,6 +29,7 @@ public static class SaveSystem private const int DefaultInputControllerInventory = 4; //back button private const string DefaultLanguage = "en"; private const bool DefaultHighCon = false; + private const bool DefaultFirstTime = true; public enum ConfigSettings { @@ -48,6 +49,7 @@ public enum ConfigSettings InputControllerInventory, LanguageKey, HighContrast, + FirstTime, } /** @@ -72,6 +74,7 @@ private static void InitConfig() UpdateConfig(ConfigSettings.InputControllerInventory, DefaultInputControllerInventory); UpdateConfig(ConfigSettings.LanguageKey, DefaultLanguage); UpdateConfig(ConfigSettings.HighContrast, DefaultHighCon); + UpdateConfig(ConfigSettings.FirstTime, DefaultFirstTime); } private static void SaveConfig() @@ -133,6 +136,9 @@ public static void UpdateConfig(ConfigSettings setting, Variant value) case ConfigSettings.HighContrast: _curConfigData.SetValue("Options", "HighContrast", value); break; + case ConfigSettings.FirstTime: + _curConfigData.SetValue("Game", "FirstTime", value); + break; default: GD.PushError("SaveSystem.UpdateConfig: Invalid config setting passed. " + setting); break; @@ -270,6 +276,8 @@ public static Variant GetConfigValue(ConfigSettings setting) return _curConfigData.GetValue("Options", "LanguageKey", DefaultLanguage); case ConfigSettings.HighContrast: return _curConfigData.GetValue("Options", "HighContrast", DefaultHighCon); + case ConfigSettings.FirstTime: + return _curConfigData.GetValue("Game", "FirstTime", DefaultFirstTime); default: GD.PushError("Invalid config setting passed. " + setting); return float.MinValue; diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index e15a8b97..f7d37396 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -404,6 +404,30 @@ public partial class Scribe : Node "Audio/songMaps/Song3.tres", [P_TheGWS.LoadPath] ), + new SongTemplate( + new SongData + { + Bpm = 90, + SongLength = -1, + NumLoops = 1, + }, + "TutorialSong", + "Audio/TutorialSong.ogg", + "Audio/songMaps/TutorialSong.tres", + [P_Strawman.LoadPath] + ), + new SongTemplate( + new SongData + { + Bpm = 176, + SongLength = -1, + NumLoops = 7, + }, + "YouWillDie:)", + "Audio/District_Four.ogg", + "Audio/songMaps/TutorialBoss176_7.tres", + [P_Effigy.LoadPath] + ), }; //Needs to be strictly maintained based on what the player has obtained. diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs index 9379c1c5..5be42be8 100644 --- a/Globals/StageProducer.cs +++ b/Globals/StageProducer.cs @@ -62,7 +62,10 @@ private void GenerateMapConsistent() private void StartNewGame() { GlobalRng.Randomize(); - CurLevel = MapLevels.GetLevelFromId(1); + if ((bool)SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.FirstTime)) + CurLevel = MapLevels.GetLevelFromId(0); + else + CurLevel = MapLevels.GetLevelFromId(1); GenerateMapConsistent(); PlayerStats = new PlayerStats(); diff --git a/Globals/Translations/Translations.csv b/Globals/Translations/Translations.csv index 042755e3..294cefca 100644 --- a/Globals/Translations/Translations.csv +++ b/Globals/Translations/Translations.csv @@ -15,6 +15,7 @@ CONTROLS_KEYBOARD,Keyboard,键盘 CONTROLS_QWER_BUTTON,QWER,QWER CONTROLS_ARROW_BUTTON,Arrow Keys,箭头键 CONTROLS_RETURN_BUTTON,Return,返回 +CONTROLS_TUTORIAL_BUTTON,Tutorial,教程 CONTROLS_CHOOSE_SCHEME,Choose Control Scheme,选择控制方式 CONTROLS_CHOOSE_BUTTON,Choose new button,选择输入按钮 CONTROLS_CHOOSE_TEXT_KEYBOARD,"Press Escape to close","按下 Escape 键关闭" @@ -86,4 +87,24 @@ OPTIONS_CONTRAST_LABEL,High Contrast,高对比度模式 HOW_TO_PLAY,How to Play,如何游玩 HOW_TO_PLAY_BLOCK1,"Hit notes to\nbuild combo","点击音符\n以建立连击" HOW_TO_PLAY_BLOCK2,"Place notes when\ncombo is full","当连击满\n时放置音符" -HOW_TO_PLAY_BLOCK3,"Only placed notes\nhave effects","只有已放置\n的音符才有效" \ No newline at end of file +HOW_TO_PLAY_BLOCK3,"Only placed notes\nhave effects","只有已放置\n的音符才有效" +TUTORIAL_NODYING,"No dying during a tutorial!",(TODO) +TUTORIAL_DIALOGUE_1,"Hello, welcome to Midnight Riff!",(TODO) +TUTORIAL_DIALOGUE_2,"This is a rhythm game where notes more right to left.",(TODO) +TUTORIAL_DIALOGUE_3,"Press the right button as the notes line up to hit the note. The closer they line up, the better your timing, and the better you'll do.",(TODO) +TUTORIAL_DIALOGUE_4,"What are the right buttons? I'll help you out and show you. And, just so you know, these can be customized later in the menu. Once you press continue we can get started!",(TODO) +TUTORIAL_LOOP_1,"At set intervals the chart loops! This means all notes on the chart repeat. You know a loop is coming up when this symbol scrolls by.",(TODO) +TUTORIAL_LOOP_2,"Hopefully by now you've noticed some other things like these on the left side. This is your note queue, don't worry about it too much yet, but keep it in mind.",(TODO) +TUTORIAL_LOOP_3,"This is the combo multiplier, as you hit notes successfully, your combo rises and as your combo rises, so will your multiplier. If you miss a note, your multiplier gets reset to 1.",(TODO) +TUTORIAL_LOOP_4,"This is the freestyle bar, as you hit notes successfully, the freestyle bar fills. The higher your multiplier, the more the bar fills. If you miss a note the bar doesn't change. You can know the bar is full when it starts to shake.",(TODO) +TUTORIAL_LOOP_5,"By now you've probably taken damage, even though this battle isn't very difficult. These aren't just cozy songs, these are battles! You take damage when you miss or hit notes with bad timing, or from enemy effects. How do you deal damage to enemies? Fill up the bar and I'll tell you.",(TODO) +TUTORIAL_PLACE_1,"Okay, now that the bar is full, you will be able to press this button to place your own notes on the track. All your notes have special effects. These range from dealing damage to applying status effects! Placing notes consumes the freestyle bar.",(TODO) +TUTORIAL_PLACE_2,"You can check what each note does by checking them in your inventory. You can check how to open your inventory in the controls menu.",(TODO) +TUTORIAL_PLACE_3,"Your notes can be placed anywhere a note doesn't already exist, and that isn't over the loop marker. But be careful, if you try to place a note while the bar isn't full you may miss a note!",(TODO) +TUTORIAL_PLACE_4,"The note you'll place is indicated in the top of the note queue. You can place the note in the bottom of the note queue by holding your secondary button while you place a note. I don't want to confuse you, so don't worry about that secondary placement for now.",(TODO) +TUTORIAL_PLACE_5,"Placed notes are automatically hit when you place them, so you don't need to worry about timing, and they are always placed on the closest beat. Though they come back around when the chart loops, so you need to time hitting them then.",(TODO) +TUTORIAL_PLACE_6,"Now go ahead, place a note in the bottom lane!",(TODO) +TUTORIAL_FINAL_1,"Good job, you placed a note! You either healed yourself, or dealt damage. I can't tell I'm just a Strawman.",(TODO) +TUTORIAL_FINAL_2,"As a refresher: Hit notes to build a combo and fill the bar. When the bar is full, press one of your buttons for a lane that doesn't have a note at the current beat. Notes in the chart will loop around. Keep it up to win.",(TODO) +TUTORIAL_FINAL_3,"Good luck! I believe in you.",(TODO) +TUTORIAL_BOSS,"This may take some getting used to, but death is ok in the grand scheme of things. Just have some patience with yourself, you'll learn in the end.",(TODO) \ No newline at end of file diff --git a/README.md b/README.md index daeef2f7..55c28f92 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,16 @@ We now have a Steam page! - **Boss Song 1**: [gameMusic – Magntron](https://freesound.org/people/Magntron/sounds/335571/) - **Battle Song 1**: [Piano loops 181 – josefpres](https://freesound.org/people/josefpres/sounds/789998/) - **Battle Song 2**: [Dark loops 220 – josefpres](https://freesound.org/people/josefpres/sounds/620230/) +- **Tutorial Song**: [Mute bass 002 – josefpres](https://freesound.org/people/josefpres/sounds/792389/) ### Images - **Input Buttons**: [inputKeys – Nicolae (Xelu) Berbece](https://thoseawesomeguys.com/prompts/) - **Light Map Texture**: [Godot Engine Docs – Godot Foundation](https://docs.godotengine.org/en/stable/tutorials/2d/2d_lights_and_shadows.html) - **Title Screen Font**: [04B-30 – Yuji Oshimoto](http://04.jp.org/) - **Main System Font**: [Fibberish - nathan scott](https://caffinate.itch.io/fibberish/) +"District Four" Kevin MacLeod ([incompetech.com](https://incompetech.com/)) +Licensed under Creative Commons: By Attribution 4.0 License +[http://creativecommons.org/licenses/by/4.0/](http://creativecommons.org/licenses/by/4.0/) --- diff --git a/Scenes/BattleDirector/BattleScene.tscn b/Scenes/BattleDirector/BattleScene.tscn index 647e287b..c135a47e 100644 --- a/Scenes/BattleDirector/BattleScene.tscn +++ b/Scenes/BattleDirector/BattleScene.tscn @@ -19,15 +19,16 @@ 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("PuppetMarkers", "_countdownLabel", "CD", "CM", "NPB", "Audio", "FocusedButton")] process_mode = 1 script = ExtResource("1_jmdo1") PuppetMarkers = [NodePath("PlayerMarker"), NodePath("Enemy1Marker"), NodePath("Enemy2Marker"), NodePath("Enemy3Marker")] +_countdownLabel = NodePath("CountInControl/Countdown") CD = NodePath("Conductor") CM = NodePath("SubViewport") NPB = NodePath("NotePlacementBar") Audio = NodePath("AudioStreamPlayer") -_focusedButton = NodePath("StartButton") +FocusedButton = NodePath("StartButton") metadata/_edit_lock_ = true [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] @@ -90,3 +91,39 @@ offset_right = 443.0 offset_bottom = 267.0 theme = ExtResource("8_62qim") text = "BATTLE_ROOM_BEGIN_BUTTON" + +[node name="CountInControl" type="Control" parent="."] +z_index = 1 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = 640.0 +offset_bottom = 360.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +size_flags_stretch_ratio = 0.0 +mouse_filter = 2 + +[node name="Countdown" type="Label" parent="CountInControl"] +visible = false +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -0.5 +offset_top = -6.0 +offset_right = 0.5 +offset_bottom = 6.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_shadow_color = Color(0, 0, 0, 1) +theme_override_constants/shadow_offset_x = 3 +theme_override_constants/shadow_offset_y = 3 +theme_override_constants/shadow_outline_size = 3 +theme_override_font_sizes/font_size = 64 +text = "5" diff --git a/Scenes/BattleDirector/Scripts/BattleDirector.cs b/Scenes/BattleDirector/Scripts/BattleDirector.cs index 1e73b94f..f0a59fc0 100644 --- a/Scenes/BattleDirector/Scripts/BattleDirector.cs +++ b/Scenes/BattleDirector/Scripts/BattleDirector.cs @@ -8,7 +8,6 @@ public partial class BattleDirector : Node2D { #region Declarations - public static readonly string LoadPath = "res://Scenes/BattleDirector/BattleScene.tscn"; public PlayerPuppet Player; @@ -17,6 +16,9 @@ public partial class BattleDirector : Node2D [Export] public Marker2D[] PuppetMarkers = new Marker2D[4]; //[0] is always player + [Export] + private Label _countdownLabel; + [Export] private Conductor CD; @@ -30,7 +32,7 @@ public partial class BattleDirector : Node2D private AudioStreamPlayer Audio; [Export] - private Button _focusedButton; //Initial start button + public Button FocusedButton; //Initial start button private double _timingInterval = .1; //in beats, maybe make note/bpm dependent @@ -39,18 +41,44 @@ public partial class BattleDirector : Node2D #endregion #region Initialization + Timer _countdownTimer; //TODO: Make in time with bpm + public bool HasPlayed; //TODO: Disable input during countdown + + public void StartCountdown() + { + CM.ArrowTween?.Pause(); + Audio.SetStreamPaused(true); + if (_countdownTimer == null) + { + _countdownTimer = new Timer(); + AddChild(_countdownTimer); + _countdownTimer.Timeout += SyncStartWithMix; + } + _countdownTimer.Start(3); + _countdownLabel.Visible = true; + } + private void SyncStartWithMix() { + _countdownTimer.Stop(); var timer = GetTree().CreateTimer(AudioServer.GetTimeToNextMix()); timer.Timeout += BeginPlayback; - _focusedButton.QueueFree(); - _focusedButton = null; } private void BeginPlayback() { - CM.BeginTweens(); - Audio.Play(); + _countdownLabel.Visible = false; + if (HasPlayed) + { + Audio.SetStreamPaused(false); + CM.ArrowTween?.Play(); + } + else + { + CM.BeginTweens(); + Audio.Play(); + } + HasPlayed = true; _initializedPlaying = true; } @@ -71,8 +99,15 @@ public override void _Ready() CD.Initialize(curSong); CD.NoteInputEvent += OnTimedInput; - _focusedButton.GrabFocus(); - _focusedButton.Pressed += SyncStartWithMix; + FocusedButton.GrabFocus(); + FocusedButton.Pressed += () => + { + FocusedButton.QueueFree(); + FocusedButton = null; + StartCountdown(); + }; + + Harbinger.Instance.InvokeBattleStarted(); } private ScoringScreen.ScoreGuide _battleScore; @@ -84,7 +119,6 @@ private void InitScoringGuide() { baseMoney += enem.BaseMoney; } - _battleScore = new ScoringScreen.ScoreGuide(baseMoney, Player.GetCurrentHealth()); Harbinger.Instance.NotePlaced += (_) => { @@ -131,6 +165,8 @@ private void InitEnemies() public override void _Process(double delta) { + if (_countdownTimer != null) + _countdownLabel.Text = ((int)_countdownTimer.TimeLeft + 1).ToString(); TimeKeeper.CurrentTime = Audio.GetPlaybackPosition(); Beat realBeat = TimeKeeper.GetBeatFromTime(Audio.GetPlaybackPosition()); UpdateBeat(realBeat); @@ -145,6 +181,8 @@ private void UpdateBeat(Beat beat) } if (beat.Loop > TimeKeeper.LastBeat.Loop) { + if (beat.Loop % TimeKeeper.LoopsPerSong == 0) + CM.BeginTweens(); //current hack to improve sync arrow tween Harbinger.Instance.InvokeChartLoop(beat.Loop, false); } TimeKeeper.LastBeat = beat; @@ -168,7 +206,7 @@ public override void _UnhandledInput(InputEvent @event) } } - private bool PlayerAddNote(ArrowType type, Beat beat) + public bool PlayerAddNote(ArrowType type, Beat beat) { if (!NPB.CanPlaceNote()) return false; @@ -189,7 +227,10 @@ private void OnTimedInput(ArrowData data, double beatDif) return; //An inactive note was passed, for now do nothing, could force miss. if (data.NoteRef == null) //An empty beat { - if ((int)data.Beat.BeatPos % (int)TimeKeeper.BeatsPerLoop == 0) + if ( + (int)data.Beat.BeatPos % (int)TimeKeeper.BeatsPerLoop == 0 + || (int)data.Beat.BeatPos > TimeKeeper.BeatsPerLoop + ) return; //We never ever try to place at 0 if (PlayerAddNote(data.Type, data.Beat)) return; //Exit handling for a placed note @@ -236,25 +277,22 @@ private Timing CheckTiming(double beatDif) #region Battle End private void CheckBattleStatus(PuppetTemplate puppet) //Called when a puppet dies { + var tween = CreateTween(); + tween.TweenProperty(puppet, "modulate:a", 0, 2f); if (puppet == Player) { - OnBattleLost(); + CM.ProcessMode = ProcessModeEnum.Disabled; + tween.TweenCallback(Callable.From(OnBattleLost)); return; } if (puppet is EnemyPuppet) { - if (IsBattleWon()) - { - CM.ProcessMode = ProcessModeEnum.Disabled; - var tween = CreateTween(); - tween.TweenProperty(puppet, "modulate:a", 0, 2f); - tween.TweenCallback(Callable.From(OnBattleWon)); - } - else - { - puppet.Visible = false; - } + if (!IsBattleWon()) + return; + Harbinger.Instance.InvokeBattleEnded(); + CM.ProcessMode = ProcessModeEnum.Disabled; + tween.TweenCallback(Callable.From(OnBattleWon)); } } @@ -310,12 +348,7 @@ public void DealDamage(Note note, int damage, PuppetTemplate source) } } - public void DealDamage( - Targetting targetting, - int damage, - PuppetTemplate source, - bool targetPlayer = false - ) + public void DealDamage(Targetting targetting, int damage, PuppetTemplate source) { PuppetTemplate[] targets = GetTargets(targetting); foreach (PuppetTemplate target in targets) @@ -392,6 +425,9 @@ private void AddEvent(IBattleEvent bEvent) case BattleEffectTrigger.OnDamageInstance: Harbinger.Instance.OnDamageInstance += bEvent.OnTrigger; break; + case BattleEffectTrigger.OnBattleStart: + Harbinger.Instance.BattleStarted += bEvent.OnTrigger; + break; } } @@ -414,6 +450,9 @@ private void RemoveEvent(IBattleEvent bEvent) case BattleEffectTrigger.OnDamageInstance: Harbinger.Instance.OnDamageInstance -= bEvent.OnTrigger; break; + case BattleEffectTrigger.OnBattleStart: + Harbinger.Instance.BattleStarted -= bEvent.OnTrigger; + break; } } @@ -532,6 +571,14 @@ public void InvokeBattleEnded() BattleEnded?.Invoke(new BattleEventArgs(_curDirector)); } + internal delegate void BattleStartedHandler(BattleEventArgs e); + internal event BattleStartedHandler BattleStarted; + + public void InvokeBattleStarted() + { + BattleStarted?.Invoke(new BattleEventArgs(_curDirector)); + } + /// /// Event Args to handle a damage instance being dealt. Happens before taking damage. /// This allows damage to be intercepted, to be reduced/increased, to counter, or heal based on incoming damage. diff --git a/Scenes/BattleDirector/Tutorial/Toriel.cs b/Scenes/BattleDirector/Tutorial/Toriel.cs new file mode 100644 index 00000000..93ad1c14 --- /dev/null +++ b/Scenes/BattleDirector/Tutorial/Toriel.cs @@ -0,0 +1,357 @@ +using System; +using FunkEngine; +using Godot; + +public partial class Toriel : CanvasLayer +{ + public static string LoadPath { get; private set; } = + "res://Scenes/BattleDirector/Tutorial/Toriel.tscn"; + private BattleDirector _currentDirector; + + [Export] + private Label _dialogueLabel; + + [Export] + private Control _dialogueBox; + + [Export] + private Button _nextButton; + + [Export] + private Sprite2D[] _inputSprites = new Sprite2D[4]; //In enum order + + [Export] + private Marker2D _noteQueueMarker; + + [Export] + private Marker2D _comboMarker; + + [Export] + private Marker2D _barMarker; + + [Export] + private Marker2D _noteMarker; + + [Export] + private Marker2D _loopMarker; + + [Export] + private NinePatchRect _selector; + + public static Toriel AttachNewToriel(BattleDirector director) + { + Toriel result = GD.Load(LoadPath).Instantiate(); + result._currentDirector = director; + director.AddChild(result); + return result; + } + + public override void _EnterTree() + { + UpdateInputSprites(); + } + + public override void _Process(double delta) + { + if (GetViewport().GuiGetFocusOwner() == null) + { + _nextButton?.GrabFocus(); + } + UpdateInputSprites(); + string scheme = SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.InputType).As(); + if (_waitingForPlace && Input.IsActionPressed(scheme + "_arrowRight")) + { + GetViewport().SetInputAsHandled(); + FirstNotePlaced(); + } + } + + private void UpdateInputSprites() + { + string prefix = SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.InputType).ToString(); + _inputSprites[0].Texture = GD.Load( + ControlSettings.GetTextureForInput(prefix + "_arrowUp") + ); + _inputSprites[1].Texture = GD.Load( + ControlSettings.GetTextureForInput(prefix + "_arrowDown") + ); + _inputSprites[2].Texture = GD.Load( + ControlSettings.GetTextureForInput(prefix + "_arrowLeft") + ); + _inputSprites[3].Texture = GD.Load( + ControlSettings.GetTextureForInput(prefix + "_arrowRight") + ); + } + + private SceneTreeTimer _timer; + + public void NoDying() + { + _dialogueBox.Visible = true; + _nextButton.Visible = false; + _dialogueLabel.Text = Tr("TUTORIAL_NODYING"); + _timer = GetTree().CreateTimer(3); + _timer.Timeout += () => + { + _dialogueBox.Visible = false; + _nextButton.Visible = true; + }; + } + + #region IntroDialogues + public void IntroDialogue() + { + _dialogueBox.Visible = true; + GetTree().SetPause(true); + _currentDirector.FocusedButton.Visible = false; + _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_1"); + _nextButton.GrabFocus(); + _nextButton.Pressed += Dialogue2; + } + + public void Dialogue2() + { + _nextButton.Pressed -= Dialogue2; + _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_2"); + _selector.Visible = true; + _selector.Position = _noteMarker.Position - _selector.Size / 2; + _nextButton.Pressed += Dialogue3; + } + + public void Dialogue3() + { + _nextButton.Pressed -= Dialogue3; + _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_3"); + _selector.Position = _inputSprites[(int)ArrowType.Down].Position - _selector.Size / 2; + _nextButton.Pressed += Dialogue4; + } + + public void Dialogue4() + { + _nextButton.Pressed -= Dialogue4; + _dialogueLabel.Text = Tr("TUTORIAL_DIALOGUE_4"); + _selector.Visible = false; + _inputSprites[0].Visible = true; + _inputSprites[1].Visible = true; + _inputSprites[2].Visible = true; + _inputSprites[3].Visible = true; + _nextButton.Pressed += Dialogue5; + } + + public void Dialogue5() + { + _nextButton.Pressed -= Dialogue5; + _dialogueBox.Visible = false; + GetTree().SetPause(false); + _currentDirector.FocusedButton.Visible = true; + _currentDirector.FocusedButton.GrabFocus(); + } + #endregion + + #region Loop Dialogue + public void LoopDialogue() + { + _timer?.SetTimeLeft(0); + _dialogueBox.Visible = true; + _nextButton.Visible = true; + + _inputSprites[0].Visible = false; + _inputSprites[1].Visible = false; + _inputSprites[2].Visible = false; + _inputSprites[3].Visible = false; + + _selector.Visible = true; + _selector.Position = _loopMarker.Position - _selector.Size / 2; + + _dialogueLabel.Text = Tr("TUTORIAL_LOOP_1"); + GetTree().SetPause(true); + _nextButton.GrabFocus(); + _nextButton.Pressed += LoopDialogue2; + } + + public void LoopDialogue2() + { + _nextButton.Pressed -= LoopDialogue2; + _inputSprites[0].Visible = true; + _inputSprites[1].Visible = true; + _inputSprites[2].Visible = true; + _inputSprites[3].Visible = true; + + _dialogueLabel.Text = Tr("TUTORIAL_LOOP_2"); + _selector.Position = _noteQueueMarker.Position - _selector.Size / 2; + _nextButton.Pressed += LoopDialogue3; + } + + public void LoopDialogue3() + { + _nextButton.Pressed -= LoopDialogue3; + _dialogueLabel.Text = Tr("TUTORIAL_LOOP_3"); + _selector.Position = _comboMarker.Position - _selector.Size / 2; + _nextButton.Pressed += LoopDialogue4; + } + + public void LoopDialogue4() + { + _nextButton.Pressed -= LoopDialogue4; + _dialogueLabel.Text = Tr("TUTORIAL_LOOP_4"); + _selector.Position = _barMarker.Position - _selector.Size / 2; + _nextButton.Pressed += LoopDialogue5; + } + + public void LoopDialogue5() + { + _nextButton.Pressed -= LoopDialogue5; + _dialogueLabel.Text = Tr("TUTORIAL_LOOP_5"); + _selector.Visible = false; + _nextButton.Pressed += LoopDialogue6; + } + + public void LoopDialogue6() + { + _nextButton.Pressed -= LoopDialogue6; + _dialogueBox.Visible = false; + GetTree().SetPause(false); + } + #endregion + + #region Placed Dialogue + public void PlaceDialogue1() + { + _dialogueBox.Visible = true; + GetTree().SetPause(true); + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_1"); + _nextButton.GrabFocus(); + _selector.Visible = true; + _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2; + _nextButton.Pressed += PlaceDialogue2; + } + + public void PlaceDialogue2() + { + _nextButton.Pressed -= PlaceDialogue2; + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_2"); + _selector.Position = _noteQueueMarker.Position - _selector.Size / 2; + _nextButton.Pressed += PlaceDialogue3; + } + + public void PlaceDialogue3() + { + _nextButton.Pressed -= PlaceDialogue3; + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_3"); + _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2; + _nextButton.Pressed += PlaceDialogue4; + } + + public void PlaceDialogue4() + { + _nextButton.Pressed -= PlaceDialogue4; + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_4"); + _selector.Position = _noteQueueMarker.Position - _selector.Size / 2; + _nextButton.Pressed += PlaceDialogue5; + } + + public void PlaceDialogue5() + { + _nextButton.Pressed -= PlaceDialogue5; + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_5"); + _nextButton.Pressed += PlaceDialogue6; + } + + public void PlaceDialogue6() + { + _nextButton.Pressed -= PlaceDialogue6; + _dialogueLabel.Text = Tr("TUTORIAL_PLACE_6"); + _selector.Position = _inputSprites[(int)ArrowType.Right].Position - _selector.Size / 2; + _waitingForPlace = true; + _nextButton.Visible = false; + } + + private bool _waitingForPlace = false; + + public void FirstNotePlaced() + { + _waitingForPlace = false; + _dialogueBox.Visible = false; + _selector.Visible = false; + GetTree().SetPause(false); + _currentDirector.PlayerAddNote(ArrowType.Right, TimeKeeper.LastBeat.RoundBeat()); + _finalDialogue = true; + } + #endregion + + #region OnPlace Dialogue + bool _finalDialogue = false; + + public void OnPlaceDialogue1() + { + if (!_finalDialogue) + return; + _finalDialogue = false; + + _dialogueBox.Visible = true; + _nextButton.Visible = true; + + _dialogueLabel.Text = Tr("TUTORIAL_FINAL_1"); + GetTree().SetPause(true); + _nextButton.GrabFocus(); + _nextButton.Pressed += OnPlaceDialogue2; + } + + public void OnPlaceDialogue2() + { + _nextButton.Pressed -= OnPlaceDialogue2; + _dialogueLabel.Text = Tr("TUTORIAL_FINAL_2"); + _selector.Visible = true; + _selector.Position = _barMarker.Position - _selector.Size / 2; + _nextButton.Pressed += OnPlaceDialogue3; + } + + public bool FromBoss; + + public void OnPlaceDialogue3() + { + if (FromBoss) + { + _dialogueBox.Visible = true; + _nextButton.Visible = true; + GetTree().SetPause(true); + _nextButton.GrabFocus(); + } + else + { + _nextButton.Pressed -= OnPlaceDialogue3; + _selector.Visible = false; + } + _dialogueLabel.Text = Tr("TUTORIAL_FINAL_3"); + _nextButton.Pressed += OnPlaceDialogue4; + } + + public void OnPlaceDialogue4() + { + _nextButton.Pressed -= OnPlaceDialogue4; + _dialogueBox.Visible = false; + GetTree().SetPause(false); + } + #endregion + + #region Boss Dialogue + public void BossDialogue() + { + _dialogueBox.Visible = true; + GetTree().SetPause(true); + _currentDirector.FocusedButton.Visible = false; + _dialogueLabel.Text = Tr("TUTORIAL_BOSS"); + _nextButton.GrabFocus(); + _nextButton.Pressed += BossDialogueReady; + } + + public void BossDialogueReady() + { + _nextButton.Pressed -= BossDialogueReady; + _dialogueBox.Visible = false; + GetTree().SetPause(false); + _currentDirector.FocusedButton.Visible = true; + _currentDirector.FocusedButton.GrabFocus(); + } + #endregion +} diff --git a/Scenes/BattleDirector/Tutorial/Toriel.cs.uid b/Scenes/BattleDirector/Tutorial/Toriel.cs.uid new file mode 100644 index 00000000..8c66f452 --- /dev/null +++ b/Scenes/BattleDirector/Tutorial/Toriel.cs.uid @@ -0,0 +1 @@ +uid://bwj1pl3srf8q3 diff --git a/Scenes/BattleDirector/Tutorial/Toriel.tscn b/Scenes/BattleDirector/Tutorial/Toriel.tscn new file mode 100644 index 00000000..cfb1a582 --- /dev/null +++ b/Scenes/BattleDirector/Tutorial/Toriel.tscn @@ -0,0 +1,149 @@ +[gd_scene load_steps=6 format=3 uid="uid://dv36qdfq1oqna"] + +[ext_resource type="Script" uid="uid://bwj1pl3srf8q3" path="res://Scenes/BattleDirector/Tutorial/Toriel.cs" id="1_mf0nq"] +[ext_resource type="Texture2D" uid="uid://djd6iw2g84bba" path="res://Scenes/UI/Assets/UI_CenterFrame.png" id="2_3a4m1"] +[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="3_3a4m1"] +[ext_resource type="Texture2D" uid="uid://cegasble5d7uw" path="res://Scenes/UI/Assets/UI_Selection.png" id="3_oxyw8"] +[ext_resource type="Texture2D" uid="uid://6jqhilmyy163" path="res://Scenes/UI/Remapping/Assets/1.png" id="4_d6o7n"] + +[node name="Toriel" type="CanvasLayer" node_paths=PackedStringArray("_dialogueLabel", "_dialogueBox", "_nextButton", "_inputSprites", "_noteQueueMarker", "_comboMarker", "_barMarker", "_noteMarker", "_loopMarker", "_selector")] +process_mode = 3 +layer = 0 +script = ExtResource("1_mf0nq") +_dialogueLabel = NodePath("Control/CenterContainer/VBoxContainer/NinePatchRect/MarginContainer/TextLabel") +_dialogueBox = NodePath("Control") +_nextButton = NodePath("Control/CenterContainer/VBoxContainer/MarginContainer2/NextButton") +_inputSprites = [NodePath("Up"), NodePath("Down"), NodePath("Left"), NodePath("Right")] +_noteQueueMarker = NodePath("NoteQueueMarker") +_comboMarker = NodePath("ComboMarker") +_barMarker = NodePath("BarMarker") +_noteMarker = NodePath("NoteMarker") +_loopMarker = NodePath("LoopMarker") +_selector = NodePath("Selector") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="CenterContainer" type="CenterContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="Control/CenterContainer"] +layout_mode = 2 + +[node name="NinePatchRect" type="NinePatchRect" parent="Control/CenterContainer/VBoxContainer"] +custom_minimum_size = Vector2(250, 150) +layout_mode = 2 +texture = ExtResource("2_3a4m1") +patch_margin_left = 8 +patch_margin_top = 8 +patch_margin_right = 8 +patch_margin_bottom = 8 + +[node name="MarginContainer" type="MarginContainer" parent="Control/CenterContainer/VBoxContainer/NinePatchRect"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_constants/margin_left = 6 +theme_override_constants/margin_top = 6 +theme_override_constants/margin_right = 6 +theme_override_constants/margin_bottom = 6 + +[node name="TextLabel" type="Label" parent="Control/CenterContainer/VBoxContainer/NinePatchRect/MarginContainer"] +layout_mode = 2 +size_flags_vertical = 1 +autowrap_mode = 2 +clip_text = true +text_overrun_behavior = 4 + +[node name="MarginContainer2" type="MarginContainer" parent="Control/CenterContainer/VBoxContainer"] +process_mode = 3 +layout_mode = 2 +theme_override_constants/margin_left = 35 +theme_override_constants/margin_top = -3 +theme_override_constants/margin_right = 35 +theme_override_constants/margin_bottom = 6 + +[node name="NextButton" type="Button" parent="Control/CenterContainer/VBoxContainer/MarginContainer2"] +layout_mode = 2 +theme = ExtResource("3_3a4m1") +text = "INBETWEEN_CONTINUE" + +[node name="Selector" type="NinePatchRect" parent="."] +visible = false +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -368.0 +offset_top = -228.0 +offset_right = -324.0 +offset_bottom = -184.0 +grow_horizontal = 2 +grow_vertical = 2 +pivot_offset = Vector2(22, 22) +texture = ExtResource("3_oxyw8") +patch_margin_left = 22 +patch_margin_top = 22 +patch_margin_right = 22 +patch_margin_bottom = 22 + +[node name="NoteQueueMarker" type="Marker2D" parent="."] +position = Vector2(22, 249) + +[node name="ComboMarker" type="Marker2D" parent="."] +position = Vector2(35, 202) + +[node name="BarMarker" type="Marker2D" parent="."] +position = Vector2(59, 266) + +[node name="NoteMarker" type="Marker2D" parent="."] +position = Vector2(364, 294) + +[node name="LoopMarker" type="Marker2D" parent="."] +position = Vector2(129, 270) + +[node name="Up" type="Sprite2D" parent="."] +visible = false +self_modulate = Color(1, 1, 1, 0.45) +position = Vector2(129, 248) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_d6o7n") + +[node name="Down" type="Sprite2D" parent="."] +visible = false +self_modulate = Color(1, 1, 1, 0.45) +position = Vector2(129, 292) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_d6o7n") + +[node name="Left" type="Sprite2D" parent="."] +visible = false +self_modulate = Color(1, 1, 1, 0.45) +position = Vector2(129, 210) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_d6o7n") + +[node name="Right" type="Sprite2D" parent="."] +visible = false +self_modulate = Color(1, 1, 1, 0.45) +position = Vector2(129, 330) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_d6o7n") diff --git a/Scenes/ChartViewport/Scripts/ChartManager.cs b/Scenes/ChartViewport/Scripts/ChartManager.cs index d53165c7..f5764de2 100644 --- a/Scenes/ChartViewport/Scripts/ChartManager.cs +++ b/Scenes/ChartViewport/Scripts/ChartManager.cs @@ -58,11 +58,15 @@ public void Initialize(SongData songData) _initialized = true; } + public Tween ArrowTween; + public void BeginTweens() { + if (ArrowTween != null) + this.ArrowTween.Kill(); //This could be good as a function to call on something, to have many things animated to the beat. - var tween = CreateTween(); - tween + ArrowTween = CreateTween(); + ArrowTween .TweenMethod( Callable.From((Vector2 scale) => TweenArrows(scale)), Vector2.One * .8f, @@ -71,13 +75,13 @@ public void BeginTweens() ) .SetEase(Tween.EaseType.Out) .SetTrans(Tween.TransitionType.Elastic); - tween.TweenMethod( + ArrowTween.TweenMethod( Callable.From((Vector2 scale) => TweenArrows(scale)), Vector2.One, Vector2.One * .8f, 60f / TimeKeeper.Bpm / 2 ); - tween.SetLoops().Play(); + ArrowTween.SetLoops().Play(); } private void TweenArrows(Vector2 scale) diff --git a/Scenes/Maps/InBetween.tscn b/Scenes/Maps/InBetween.tscn index 10f2cf20..7d57aa3f 100644 --- a/Scenes/Maps/InBetween.tscn +++ b/Scenes/Maps/InBetween.tscn @@ -20,5 +20,5 @@ offset_bottom = 284.0 theme = ExtResource("2_dapxv") text = "INBETWEEN_CONTINUE" script = ExtResource("3_35xdc") -ScenePath = 6 +ScenePath = 4 _startFocused = true diff --git a/Scenes/Puppets/Enemies/Effigy/Effigy.tscn b/Scenes/Puppets/Enemies/Effigy/Effigy.tscn new file mode 100644 index 00000000..9b32a36c --- /dev/null +++ b/Scenes/Puppets/Enemies/Effigy/Effigy.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=5 format=3 uid="uid://djob0b8d65u44"] + +[ext_resource type="Script" uid="uid://bopwk08hbiuej" path="res://Scenes/Puppets/Enemies/Effigy/P_Effigy.cs" id="1_80cpv"] +[ext_resource type="Texture2D" uid="uid://1uwfu07p38c6" path="res://Scenes/Puppets/Enemies/Strawman/Strawman.png" id="2_5xvmn"] +[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_j2tnq"] +[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_akap3"] + +[node name="Strawman" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")] +script = ExtResource("1_80cpv") +HealthBar = NodePath("ProgressBar") +Sprite = NodePath("Sprite") +_statusContainer = NodePath("StatusContainer") + +[node name="Sprite" type="Sprite2D" parent="."] +self_modulate = Color(0.190283, 0.000433802, 0.432638, 1) +texture = ExtResource("2_5xvmn") + +[node name="ProgressBar" parent="." instance=ExtResource("3_j2tnq")] +offset_left = -50.0 +offset_top = 32.0 +offset_right = 50.0 +offset_bottom = 52.0 + +[node name="StatusContainer" parent="." instance=ExtResource("4_akap3")] diff --git a/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs new file mode 100644 index 00000000..25e06bc3 --- /dev/null +++ b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs @@ -0,0 +1,72 @@ +using System; +using FunkEngine; +using Godot; + +public partial class P_Effigy : EnemyPuppet +{ + public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/Effigy/Effigy.tscn"; + private static Toriel _tutorialInstance; + + public override void _Ready() + { + MaxHealth = 99; + BaseMoney = 99; + CurrentHealth = MaxHealth; + base._Ready(); + + BattleEvents = new EnemyEffect[] + { + new EnemyEffect( + this, + BattleEffectTrigger.OnDamageInstance, + 1, + (e, eff, val) => + { + if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs) + return; + if (dArgs.Dmg.Target != this) + return; + dArgs.Dmg.ModifyDamage(-dArgs.Dmg.Damage + 1); + dArgs.Dmg.Source.TakeDamage(new DamageInstance(1, null, dArgs.Dmg.Source)); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnBattleEnd, + 1, + (e, eff, val) => + { + e.BD.DealDamage(Targetting.Player, e.BD.Player.GetCurrentHealth() - 1, null); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnBattleStart, + 1, + (e, eff, val) => + { + _tutorialInstance = Toriel.AttachNewToriel(e.BD); + _tutorialInstance.BossDialogue(); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnDamageInstance, + 2, + (e, eff, val) => + { + if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs) + return; + if ( + dArgs.Dmg.Target == dArgs.BD.Player + && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage + ) + { + _tutorialInstance.FromBoss = true; + _tutorialInstance.OnPlaceDialogue3(); + } + } + ), + }; + } +} diff --git a/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid new file mode 100644 index 00000000..dcc907db --- /dev/null +++ b/Scenes/Puppets/Enemies/Effigy/P_Effigy.cs.uid @@ -0,0 +1 @@ +uid://bopwk08hbiuej diff --git a/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs new file mode 100644 index 00000000..35d9b64b --- /dev/null +++ b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs @@ -0,0 +1,110 @@ +using System; +using FunkEngine; +using Godot; + +public partial class P_Strawman : EnemyPuppet +{ + public static new readonly string LoadPath = + "res://Scenes/Puppets/Enemies/Strawman/Strawman.tscn"; + + private static Toriel _tutorialInstance; + + public override void _Ready() + { + CurrentHealth = 15; + MaxHealth = 15; + BaseMoney = 1; + base._Ready(); + + BattleEvents = new EnemyEffect[] + { + new EnemyEffect( + this, + BattleEffectTrigger.OnBattleStart, + 1, + (e, eff, val) => + { + _tutorialInstance = Toriel.AttachNewToriel(e.BD); + _tutorialInstance.IntroDialogue(); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnDamageInstance, + 2, + (e, eff, val) => + { + if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs) + return; + if ( + dArgs.Dmg.Target == dArgs.BD.Player + && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage + 1 + ) + { + dArgs.Dmg.Target.Heal(999); + if (eff.Value == 0) + return; + _tutorialInstance.NoDying(); + eff.Value--; + } + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnLoop, + 1, + (e, eff, val) => + { + if (e is not BattleDirector.Harbinger.LoopEventArgs lArgs) + return; + if (lArgs.Loop == 1) + { + _tutorialInstance.LoopDialogue(); + } + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.NoteHit, + 1, + (e, eff, val) => + { + if (eff.Value == 0) + return; + if (e is not BattleDirector.Harbinger.NoteHitArgs nArgs) + return; + if (!nArgs.BD.NPB.CanPlaceNote() || TimeKeeper.LastBeat.Loop < 1) + return; + eff.Value = 0; + _tutorialInstance.PlaceDialogue1(); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.NotePlaced, + 1, + (e, eff, val) => + { + _tutorialInstance.CallDeferred(nameof(_tutorialInstance.OnPlaceDialogue1)); + } + ), + new EnemyEffect( + this, + BattleEffectTrigger.OnDamageInstance, + 1, + (e, eff, val) => + { + if (e is not BattleDirector.Harbinger.OnDamageInstanceArgs dArgs) + return; + if ( + dArgs.Dmg.Target == this + && dArgs.Dmg.Target.GetCurrentHealth() <= dArgs.Dmg.Damage + ) + { + SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.FirstTime, false); + } + } + ), + }; + } +} diff --git a/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid new file mode 100644 index 00000000..c0db8633 --- /dev/null +++ b/Scenes/Puppets/Enemies/Strawman/P_Strawman.cs.uid @@ -0,0 +1 @@ +uid://cd3rrwk2hhkux diff --git a/Scenes/Puppets/Enemies/Strawman/Strawman.png b/Scenes/Puppets/Enemies/Strawman/Strawman.png new file mode 100644 index 00000000..4fa29a06 Binary files /dev/null and b/Scenes/Puppets/Enemies/Strawman/Strawman.png differ diff --git a/Scenes/Puppets/Enemies/Strawman/Strawman.png.import b/Scenes/Puppets/Enemies/Strawman/Strawman.png.import new file mode 100644 index 00000000..86b5e995 --- /dev/null +++ b/Scenes/Puppets/Enemies/Strawman/Strawman.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1uwfu07p38c6" +path="res://.godot/imported/Strawman.png-45d47585ab4c69863f411f8c0ec14e04.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Scenes/Puppets/Enemies/Strawman/Strawman.png" +dest_files=["res://.godot/imported/Strawman.png-45d47585ab4c69863f411f8c0ec14e04.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/Puppets/Enemies/Strawman/Strawman.tscn b/Scenes/Puppets/Enemies/Strawman/Strawman.tscn new file mode 100644 index 00000000..49f59a7b --- /dev/null +++ b/Scenes/Puppets/Enemies/Strawman/Strawman.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=5 format=3 uid="uid://dh3a7hyhlukgx"] + +[ext_resource type="Script" uid="uid://cd3rrwk2hhkux" path="res://Scenes/Puppets/Enemies/Strawman/P_Strawman.cs" id="1_8sxmx"] +[ext_resource type="Texture2D" uid="uid://1uwfu07p38c6" path="res://Scenes/Puppets/Enemies/Strawman/Strawman.png" id="2_451oy"] +[ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="3_a3xgy"] +[ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="4_bktfx"] + +[node name="Strawman" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")] +script = ExtResource("1_8sxmx") +HealthBar = NodePath("ProgressBar") +Sprite = NodePath("Sprite") +_statusContainer = NodePath("StatusContainer") + +[node name="Sprite" type="Sprite2D" parent="."] +texture = ExtResource("2_451oy") + +[node name="ProgressBar" parent="." instance=ExtResource("3_a3xgy")] +offset_left = -50.0 +offset_top = 32.0 +offset_right = 50.0 +offset_bottom = 52.0 + +[node name="StatusContainer" parent="." instance=ExtResource("4_bktfx")] diff --git a/Scenes/UI/Options/HowToPlay.tscn b/Scenes/UI/Options/HowToPlay.tscn index a67584e8..1883ffcf 100644 --- a/Scenes/UI/Options/HowToPlay.tscn +++ b/Scenes/UI/Options/HowToPlay.tscn @@ -11,10 +11,11 @@ [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")] +[node name="CanvasLayer" type="Node2D" node_paths=PackedStringArray("_returnButton", "_tutorialButton")] process_mode = 3 script = ExtResource("1_kqayr") -_returnButton = NodePath("Control/ReturnButton") +_returnButton = NodePath("Control/HBoxContainer/ReturnButton") +_tutorialButton = NodePath("Control/HBoxContainer/TutorialButton") [node name="Background" type="NinePatchRect" parent="."] offset_right = 640.0 @@ -41,15 +42,23 @@ theme_override_font_sizes/font_size = 32 text = "HOW_TO_PLAY" horizontal_alignment = 1 -[node name="ReturnButton" type="Button" parent="Control"] +[node name="HBoxContainer" type="HBoxContainer" parent="Control"] layout_mode = 0 -offset_left = 202.5 offset_top = 314.0 -offset_right = 437.5 -offset_bottom = 345.0 +offset_right = 640.0 +offset_bottom = 354.0 +alignment = 1 + +[node name="ReturnButton" type="Button" parent="Control/HBoxContainer"] +layout_mode = 2 theme = ExtResource("3_xqve7") text = "CONTROLS_RETURN_BUTTON" +[node name="TutorialButton" type="Button" parent="Control/HBoxContainer"] +layout_mode = 2 +theme = ExtResource("3_xqve7") +text = "CONTROLS_TUTORIAL_BUTTON" + [node name="MarginContainer" type="Control" parent="Control"] anchors_preset = 0 offset_left = 10.0 diff --git a/Scenes/UI/Options/Scripts/HowToPlay.cs b/Scenes/UI/Options/Scripts/HowToPlay.cs index cc49e553..8e157664 100644 --- a/Scenes/UI/Options/Scripts/HowToPlay.cs +++ b/Scenes/UI/Options/Scripts/HowToPlay.cs @@ -8,11 +8,16 @@ public partial class HowToPlay : Node2D, IFocusableMenu [Export] private Button _returnButton; + [Export] + private Button _tutorialButton; + public IFocusableMenu Prev { get; set; } public override void _Ready() { _returnButton.Pressed += ReturnToPrev; + _tutorialButton.Pressed += DoTutorial; + _tutorialButton.Visible = !StageProducer.IsInitialized; } public void ResumeFocus() @@ -39,6 +44,12 @@ public void ReturnToPrev() QueueFree(); } + private void DoTutorial() + { + SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.FirstTime, true); + StageProducer.LiveInstance.TransitionStage(Stages.Map); + } + public override void _Input(InputEvent @event) { if (!GetWindow().HasFocus()) diff --git a/Scenes/UI/Pause.tscn b/Scenes/UI/Pause.tscn index 24f7b5d4..2ca7b9aa 100644 --- a/Scenes/UI/Pause.tscn +++ b/Scenes/UI/Pause.tscn @@ -6,7 +6,7 @@ [ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="4_lw4m2"] [node name="PauseMenu" type="Control" node_paths=PackedStringArray("PauseButtons")] -process_mode = 1 +process_mode = 3 layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 diff --git a/Scenes/UI/Remapping/ControlSettings.cs b/Scenes/UI/Remapping/ControlSettings.cs index 78dbb994..fad7176b 100644 --- a/Scenes/UI/Remapping/ControlSettings.cs +++ b/Scenes/UI/Remapping/ControlSettings.cs @@ -387,6 +387,22 @@ private static readonly Dictionary< }, }; + public static string GetTextureForInput(string inputMapName) + { + var events = InputMap.ActionGetEvents(inputMapName); + if (events.Count <= 0) + return null; + string textureName = events[0].AsText(); + + // Clean up the texture name + if (inputMapName.StartsWith(KeyboardPrefix)) + textureName = CleanKeyboardText(textureName); + else + textureName = textureName.Replace("/", ""); + + return $"{IconPath}{textureName}.png"; + } + /// /// Saves the key to the input based on its input name into the correct config setting. /// diff --git a/Scenes/UI/Scripts/MenuModule.cs b/Scenes/UI/Scripts/MenuModule.cs index 9e39b307..1af6a348 100644 --- a/Scenes/UI/Scripts/MenuModule.cs +++ b/Scenes/UI/Scripts/MenuModule.cs @@ -24,6 +24,8 @@ public override void _Ready() public void ResumeFocus() { CurSceneNode.ProcessMode = ProcessModeEnum.Inherit; + if (CurSceneNode is BattleDirector { HasPlayed: true } bd && !GetTree().IsPaused()) + bd.StartCountdown(); _lastFocused?.GrabFocus(); } diff --git a/Scenes/UI/TitleScreen/SceneChange.tscn b/Scenes/UI/TitleScreen/SceneChange.tscn deleted file mode 100644 index b1d179da..00000000 --- a/Scenes/UI/TitleScreen/SceneChange.tscn +++ /dev/null @@ -1,31 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://dbeplni2du158"] - -[ext_resource type="Script" uid="uid://cahjluc6v7ked" path="res://Scenes/UI/TitleScreen/Scripts/SceneChange.cs" id="1_n6d5u"] - -[node name="Control" type="Control"] -layout_mode = 3 -anchors_preset = 0 -offset_right = 40.0 -offset_bottom = 40.0 - -[node name="Node2D" type="Node2D" parent="."] - -[node name="StartButton" type="Button" parent="."] -layout_mode = 0 -offset_left = 120.0 -offset_top = 56.0 -offset_right = 128.0 -offset_bottom = 64.0 -scale = Vector2(2.48, 2.48) -text = "start battle" -script = ExtResource("1_n6d5u") - -[node name="ExitButton" type="Button" parent="."] -layout_mode = 0 -offset_left = 471.0 -offset_top = 95.0 -offset_right = 508.0 -offset_bottom = 126.0 -scale = Vector2(2.56, 2.56) -text = "exit" -script = ExtResource("1_n6d5u")