diff --git a/Classes/Notes/Note.cs b/Classes/Notes/Note.cs index 817fa917..96c425a9 100644 --- a/Classes/Notes/Note.cs +++ b/Classes/Notes/Note.cs @@ -37,7 +37,7 @@ public Note( ?? ( (BD, source, Timing) => { - BD.GetTarget(this).TakeDamage(source._baseVal); + BD.GetTarget(this).TakeDamage((int)Timing * source._baseVal); } ); _baseVal = baseVal; @@ -67,4 +67,9 @@ public Note Clone() ); return newNote; } + + public int GetBaseVal() + { + return _baseVal; + } } diff --git a/Globals/Scribe.cs b/Globals/Scribe.cs index e2ff94dd..cc9c2a14 100644 --- a/Globals/Scribe.cs +++ b/Globals/Scribe.cs @@ -20,7 +20,7 @@ public partial class Scribe : Node 1, (director, note, timing) => { - director.Player.TakeDamage(3 - (int)timing); + director.Player.TakeDamage((3 - (int)timing) * note.GetBaseVal()); } ), new Note( @@ -32,7 +32,9 @@ public partial class Scribe : Node 1, (director, note, timing) => { - director.Enemy.TakeDamage((int)timing); + if (timing == Timing.Miss) + return; + director.Enemy.TakeDamage((int)timing * note.GetBaseVal()); } ), new Note( @@ -41,12 +43,12 @@ public partial class Scribe : Node "Basic player note, deals double damage to enemy.", GD.Load("res://Classes/Notes/assets/double_note.png"), null, - 1, + 2, (director, note, timing) => { - // can change later, but I want it like this instead of changing base - // in case we have some relic that messes with timing - director.Enemy.TakeDamage(2 * (int)timing); + if (timing == Timing.Miss) + return; + director.Enemy.TakeDamage(note.GetBaseVal() * (int)timing); } ), new Note( @@ -58,7 +60,9 @@ public partial class Scribe : Node 1, (director, note, timing) => { - director.Player.Heal((int)timing); + if (timing == Timing.Miss) + return; + director.Player.Heal((int)timing * note.GetBaseVal()); } ), new Note( @@ -70,8 +74,10 @@ public partial class Scribe : Node 1, (director, note, timing) => { - director.Player.Heal((int)timing); - director.Enemy.TakeDamage((int)timing); + if (timing == Timing.Miss) + return; + director.Player.Heal((int)timing * note.GetBaseVal()); + director.Enemy.TakeDamage((int)timing * note.GetBaseVal()); } ), new Note( @@ -83,7 +89,9 @@ public partial class Scribe : Node 1, (director, note, timing) => { - director.Enemy.TakeDamage((int)timing); + if (timing == Timing.Miss) + return; + director.Enemy.TakeDamage((int)timing + note.GetBaseVal()); }, 0.25f ), diff --git a/Globals/translations.csv b/Globals/translations.csv index 03ae918b..36684621 100644 --- a/Globals/translations.csv +++ b/Globals/translations.csv @@ -54,3 +54,7 @@ INVENTORY_TAB_NOTES,Notes,乐谱 INVENTORY_TAB_RELICS,Relics,遗物 OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置 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 diff --git a/project.godot b/project.godot index 79c32531..ebf3de32 100644 --- a/project.godot +++ b/project.godot @@ -37,9 +37,6 @@ window/stretch/scale_mode="integer" project/assembly_name="Funk Engine" -[game] - - [input] ui_accept={ diff --git a/scenes/BattleDirector/scripts/BattleDirector.cs b/scenes/BattleDirector/scripts/BattleDirector.cs index 7438a6f7..a3d62ca2 100644 --- a/scenes/BattleDirector/scripts/BattleDirector.cs +++ b/scenes/BattleDirector/scripts/BattleDirector.cs @@ -43,7 +43,14 @@ private bool PlayerAddNote(ArrowType type, int beat) { if (!NotePlacementBar.CanPlaceNote()) return false; - if (!CD.AddNoteToLane(type, beat % CM.BeatsPerLoop, NotePlacementBar.PlacedNote(), false)) + if ( + !CD.AddNoteToLane( + type, + beat % CM.BeatsPerLoop, + NotePlacementBar.PlacedNote(this), + false + ) + ) //TODO: Remove passing BD into NPB return false; NotePlaced?.Invoke(this); return true; diff --git a/scenes/BattleDirector/scripts/Conductor.cs b/scenes/BattleDirector/scripts/Conductor.cs index 3a19b10e..2a5e010f 100644 --- a/scenes/BattleDirector/scripts/Conductor.cs +++ b/scenes/BattleDirector/scripts/Conductor.cs @@ -45,11 +45,11 @@ public bool AddNoteToLane(ArrowType type, int beat, Note note, bool isActive = t { beat %= CM.BeatsPerLoop; Note newNote = note.Clone(); - if (beat == 0 || _laneData[(int)type][beat] != null) + if (beat == 0 || _laneData[(int)type][beat] != null) //TODO: Double check if this is still necessary, doesn't seem to matter for player placed notes return false; NoteArrow arrow; - if (isActive) //Currently an enemy note. + if (isActive) //Currently isActive means an enemy note. { arrow = CM.AddArrowToLane(type, beat, newNote); } diff --git a/scenes/BattleDirector/scripts/NotePlacementBar.cs b/scenes/BattleDirector/scripts/NotePlacementBar.cs index 3c61b2a2..e05d64dc 100644 --- a/scenes/BattleDirector/scripts/NotePlacementBar.cs +++ b/scenes/BattleDirector/scripts/NotePlacementBar.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FunkEngine; using Godot; public partial class NotePlacementBar : Node @@ -183,13 +184,16 @@ public void IncreaseCharge(int amount = 1) } // Placing a note resets the note placement bar - public Note PlacedNote() + public Note PlacedNote(BattleDirector BD) { _currentBarValue -= (int)(_currentNoteInstance.CostModifier * MaxValue); UpdateNotePlacementBar(_currentBarValue); //fullBarParticles.Emitting = false; - return GetNote(Input.IsActionPressed("Secondary")); + + Note placedNote = GetNote(Input.IsActionPressed("Secondary")); + placedNote?.OnHit(BD, Timing.Okay); //Hardcode for now, eventually the note itself could have its default + return placedNote; } public bool CanPlaceNote() diff --git a/scenes/Options/OptionsMenu.cs b/scenes/Options/OptionsMenu.cs index a245ea9a..f02c7090 100644 --- a/scenes/Options/OptionsMenu.cs +++ b/scenes/Options/OptionsMenu.cs @@ -21,6 +21,9 @@ public partial class OptionsMenu : CanvasLayer [Export] private CheckBox _highContrastToggle; + [Export] + private Button _howToPlayButton; + private const float MinVolumeVal = 50f; public override void _Ready() @@ -36,6 +39,7 @@ public override void _Ready() _closeButton.Pressed += CloseMenu; _controlsButton.Pressed += OpenControls; _highContrastToggle.Toggled += HighContrastChanged; + _howToPlayButton.Pressed += OpenHowToPlay; } public override void _Process(double delta) //TODO: Better method for returning focus @@ -98,4 +102,12 @@ private void HighContrastChanged(bool toggled) StageProducer.ContrastFilter.Visible = toggled; SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.HighContrast, toggled); } + + private void OpenHowToPlay() + { + HowToPlay howtoPlay = GD.Load("res://scenes/UI/HowToPlay.tscn") + .Instantiate(); + AddChild(howtoPlay); + howtoPlay.OpenMenu(this); + } } diff --git a/scenes/Options/OptionsMenu.tscn b/scenes/Options/OptionsMenu.tscn index f6e3859f..5f429a9b 100644 --- a/scenes/Options/OptionsMenu.tscn +++ b/scenes/Options/OptionsMenu.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" path="res://scenes/Options/scripts/LanguageSelection.cs" id="1_qyvkw"] [ext_resource type="Script" path="res://scenes/Options/OptionsMenu.cs" id="1_yjq7i"] -[node name="OptionsMenu" type="CanvasLayer" node_paths=PackedStringArray("_focused", "_volumeSlider", "_closeButton", "_controlsButton", "_highContrastToggle")] +[node name="OptionsMenu" type="CanvasLayer" node_paths=PackedStringArray("_focused", "_volumeSlider", "_closeButton", "_controlsButton", "_highContrastToggle", "_howToPlayButton")] process_mode = 3 script = ExtResource("1_yjq7i") _focused = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/LanguageSelection") @@ -11,6 +11,7 @@ _volumeSlider = NodePath("Control/CenterContainer/MarginContainer/MarginContaine _closeButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/TitleButton") _controlsButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/ControlsButton") _highContrastToggle = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/CheckBox") +_howToPlayButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HowToPlayButton") [node name="Control" type="Control" parent="."] layout_mode = 3 @@ -59,7 +60,7 @@ theme_override_constants/margin_bottom = 10 custom_minimum_size = Vector2(240, 0) layout_mode = 2 size_flags_horizontal = 0 -theme_override_constants/separation = 25 +theme_override_constants/separation = 18 alignment = 1 [node name="Title" type="Label" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"] @@ -112,6 +113,10 @@ script = ExtResource("1_qyvkw") layout_mode = 2 text = "TITLE_CONTROLS" +[node name="HowToPlayButton" type="Button" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "HOW_TO_PLAY" + [node name="TitleButton" type="Button" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"] layout_mode = 2 text = "CONTROLS_RETURN_BUTTON" diff --git a/scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs b/scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs index 0ab6b111..c7b05480 100644 --- a/scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs +++ b/scenes/Puppets/Enemies/BossBlood/P_BossBlood.cs @@ -7,6 +7,8 @@ public partial class P_BossBlood : EnemyPuppet { public override void _Ready() { + _currentHealth = 100; + _maxHealth = 100; base._Ready(); var enemTween = CreateTween(); enemTween.TweenProperty(Sprite, "position", Vector2.Down * 5, 1f).AsRelative(); diff --git a/scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs b/scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs index 388d6f2f..5ca1681f 100644 --- a/scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs +++ b/scenes/Puppets/Enemies/Parasifly/P_Parasifly.cs @@ -5,6 +5,8 @@ public partial class P_Parasifly : EnemyPuppet { public override void _Ready() { + _currentHealth = 50; + _maxHealth = 50; base._Ready(); var enemTween = CreateTween(); enemTween.TweenProperty(Sprite, "position", Vector2.Down * 2, 2f).AsRelative(); diff --git a/scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs b/scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs index 491d447c..353063e7 100644 --- a/scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs +++ b/scenes/Puppets/Enemies/TheGWS/P_TheGWS.cs @@ -5,6 +5,8 @@ public partial class P_TheGWS : EnemyPuppet { public override void _Ready() { + _currentHealth = 75; + _maxHealth = 75; base._Ready(); var enemTween = CreateTween(); enemTween.TweenProperty(Sprite, "position", Vector2.Down * 10, 3f).AsRelative(); diff --git a/scenes/UI/HowToPlay.cs b/scenes/UI/HowToPlay.cs new file mode 100644 index 00000000..cc3e813f --- /dev/null +++ b/scenes/UI/HowToPlay.cs @@ -0,0 +1,42 @@ +using System; +using Godot; + +public partial class HowToPlay : Node2D +{ + [Export] + private Button _returnButton; + + private Node _previousScene; + private ProcessModeEnum _previousProcessMode; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + _returnButton.Pressed += CloseMenu; + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) { } + + public void OpenMenu(Node prevScene) + { + _previousScene = prevScene; + _previousProcessMode = _previousScene.GetProcessMode(); + prevScene.ProcessMode = ProcessModeEnum.Disabled; + } + + private void CloseMenu() + { + _previousScene.ProcessMode = _previousProcessMode; + QueueFree(); + } + + public override void _Input(InputEvent @event) + { + if (@event.IsActionPressed("ui_cancel")) + { + CloseMenu(); + GetViewport().SetInputAsHandled(); + } + } +} diff --git a/scenes/UI/HowToPlay.tscn b/scenes/UI/HowToPlay.tscn new file mode 100644 index 00000000..6cc2abbe --- /dev/null +++ b/scenes/UI/HowToPlay.tscn @@ -0,0 +1,161 @@ +[gd_scene load_steps=8 format=3 uid="uid://cavxn51vwbew3"] + +[ext_resource type="Script" path="res://scenes/UI/HowToPlay.cs" id="1_kqayr"] +[ext_resource type="Texture2D" uid="uid://xtygvpk7s8e4" path="res://scenes/NoteManager/assets/outline_white.png" id="2_4i384"] +[ext_resource type="Texture2D" uid="uid://dp3vkn65j4o3s" path="res://scenes/UI/assets/combobar.png" id="3_7006y"] +[ext_resource type="Texture2D" uid="uid://caw70lr5e1yiq" path="res://Classes/Notes/assets/double_note.png" id="4_m6low"] +[ext_resource type="Texture2D" uid="uid://cdf3g3174du4r" path="res://Classes/Notes/assets/heal_note.png" id="5_8kiq2"] +[ext_resource type="Texture2D" uid="uid://c3chrsxrulapd" path="res://Classes/Notes/assets/single_note.png" id="6_uonw3"] +[ext_resource type="Texture2D" uid="uid://dg0lmu0pip4lr" path="res://Classes/Notes/assets/vampire_note.png" id="7_rbdrm"] + +[node name="CanvasLayer" type="Node2D" node_paths=PackedStringArray("_returnButton")] +process_mode = 3 +script = ExtResource("1_kqayr") +_returnButton = NodePath("Control/ReturnButton") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="ColorRect" type="ColorRect" parent="Control"] +offset_right = 640.0 +offset_bottom = 360.0 +color = Color(0.133333, 0.133333, 0.133333, 1) + +[node name="Label" type="Label" parent="Control"] +offset_top = 16.0 +offset_right = 642.0 +offset_bottom = 39.0 +text = "HOW_TO_PLAY" +horizontal_alignment = 1 + +[node name="ReturnButton" type="Button" parent="Control"] +offset_left = 202.5 +offset_top = 314.0 +offset_right = 437.5 +offset_bottom = 345.0 +text = "CONTROLS_RETURN_BUTTON" + +[node name="MarginContainer" type="Control" parent="Control"] +anchors_preset = 0 +offset_left = 10.0 +offset_top = 60.0 +offset_right = 210.0 +offset_bottom = 310.0 + +[node name="ColorRect" type="ColorRect" parent="Control/MarginContainer"] +layout_mode = 2 +offset_right = 200.0 +offset_bottom = 250.0 +color = Color(0.239216, 0.239216, 0.239216, 0.854902) + +[node name="Left" type="Sprite2D" parent="Control/MarginContainer"] +position = Vector2(27.0001, 62) +rotation = -3.14159 +texture = ExtResource("2_4i384") + +[node name="Up" type="Sprite2D" parent="Control/MarginContainer"] +position = Vector2(27.0001, 102) +rotation = -1.5708 +texture = ExtResource("2_4i384") + +[node name="Down" type="Sprite2D" parent="Control/MarginContainer"] +position = Vector2(27.0001, 145) +rotation = 1.5708 +texture = ExtResource("2_4i384") + +[node name="Right" type="Sprite2D" parent="Control/MarginContainer"] +position = Vector2(27.0001, 186) +texture = ExtResource("2_4i384") + +[node name="Label" type="Label" parent="Control/MarginContainer"] +layout_mode = 2 +offset_left = 54.0 +offset_top = 114.0 +offset_right = 254.0 +offset_bottom = 137.0 +text = "HOW_TO_PLAY_BLOCK1" + +[node name="MarginContainer2" type="Control" parent="Control"] +anchors_preset = 0 +offset_left = 220.0 +offset_top = 60.0 +offset_right = 420.0 +offset_bottom = 310.0 + +[node name="ColorRect" type="ColorRect" parent="Control/MarginContainer2"] +layout_mode = 2 +offset_right = 200.0 +offset_bottom = 250.0 +color = Color(0.239216, 0.239216, 0.239216, 0.854902) + +[node name="Label" type="Label" parent="Control/MarginContainer2"] +layout_mode = 2 +offset_left = 54.0 +offset_top = 114.0 +offset_right = 254.0 +offset_bottom = 137.0 +text = "HOW_TO_PLAY_BLOCK2" + +[node name="Combobar" type="Sprite2D" parent="Control/MarginContainer2"] +position = Vector2(28, 125) +scale = Vector2(1, 1.59184) +texture = ExtResource("3_7006y") + +[node name="MarginContainer3" type="Control" parent="Control"] +anchors_preset = 0 +offset_left = 430.0 +offset_top = 60.0 +offset_right = 630.0 +offset_bottom = 310.0 + +[node name="ColorRect" type="ColorRect" parent="Control/MarginContainer3"] +layout_mode = 2 +offset_right = 200.0 +offset_bottom = 250.0 +color = Color(0.239216, 0.239216, 0.239216, 0.854902) + +[node name="Label" type="Label" parent="Control/MarginContainer3"] +layout_mode = 2 +offset_left = 54.0 +offset_top = 114.0 +offset_right = 254.0 +offset_bottom = 137.0 +text = "HOW_TO_PLAY_BLOCK3" + +[node name="Left" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(27.0001, 62) +rotation = -3.14159 +texture = ExtResource("2_4i384") + +[node name="Up" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(27.0001, 102) +rotation = -1.5708 +texture = ExtResource("2_4i384") + +[node name="Down" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(27.0001, 145) +rotation = 1.5708 +texture = ExtResource("2_4i384") + +[node name="Right" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(27.0001, 186) +texture = ExtResource("2_4i384") + +[node name="DoubleNote" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(27, 60) +texture = ExtResource("4_m6low") + +[node name="HealNote" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(29, 100) +texture = ExtResource("5_8kiq2") + +[node name="SingleNote" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(29, 146) +texture = ExtResource("6_uonw3") + +[node name="VampireNote" type="Sprite2D" parent="Control/MarginContainer3"] +position = Vector2(28, 187) +texture = ExtResource("7_rbdrm") diff --git a/scenes/UI/assets/combobar.png b/scenes/UI/assets/combobar.png new file mode 100644 index 00000000..b4e98539 Binary files /dev/null and b/scenes/UI/assets/combobar.png differ diff --git a/scenes/UI/assets/combobar.png.import b/scenes/UI/assets/combobar.png.import new file mode 100644 index 00000000..9ab338bd --- /dev/null +++ b/scenes/UI/assets/combobar.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dp3vkn65j4o3s" +path="res://.godot/imported/combobar.png-c835d811fb05e4fd220a08e5b5cab683.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/UI/assets/combobar.png" +dest_files=["res://.godot/imported/combobar.png-c835d811fb05e4fd220a08e5b5cab683.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