diff --git a/project.godot b/project.godot index 836d9b3..3f18f3a 100644 --- a/project.godot +++ b/project.godot @@ -1116,6 +1116,16 @@ ballance_esc={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } +ballance_cmd={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":47,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +ballance_chat={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":84,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} [physics] diff --git a/resources/user_interface/styles/lineedit_borderless_style_deselect.tres b/resources/user_interface/styles/lineedit_borderless_style_deselect.tres new file mode 100644 index 0000000..bd998e6 --- /dev/null +++ b/resources/user_interface/styles/lineedit_borderless_style_deselect.tres @@ -0,0 +1,11 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://resources/user_interface/textures/lineedit_borderless_deselect.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 64, 32 ) +margin_left = 14.1409 +margin_right = 12.785 +margin_top = 13.5598 +margin_bottom = 13.3661 diff --git a/resources/user_interface/styles/lineedit_borderless_style_select.tres b/resources/user_interface/styles/lineedit_borderless_style_select.tres new file mode 100644 index 0000000..8738faa --- /dev/null +++ b/resources/user_interface/styles/lineedit_borderless_style_select.tres @@ -0,0 +1,11 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://resources/user_interface/textures/lineedit_borderless_select.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 64, 32 ) +margin_left = 14.1409 +margin_right = 12.785 +margin_top = 13.5598 +margin_bottom = 13.3661 diff --git a/resources/user_interface/textures/lineedit_borderless_deselect.png b/resources/user_interface/textures/lineedit_borderless_deselect.png new file mode 100644 index 0000000..6d4c431 Binary files /dev/null and b/resources/user_interface/textures/lineedit_borderless_deselect.png differ diff --git a/resources/user_interface/textures/lineedit_borderless_deselect.png.import b/resources/user_interface/textures/lineedit_borderless_deselect.png.import new file mode 100644 index 0000000..09b5d66 --- /dev/null +++ b/resources/user_interface/textures/lineedit_borderless_deselect.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/lineedit_borderless_deselect.png-5a57d2f0a83a0ea3163638365fbb072b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/user_interface/textures/lineedit_borderless_deselect.png" +dest_files=[ "res://.import/lineedit_borderless_deselect.png-5a57d2f0a83a0ea3163638365fbb072b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/resources/user_interface/textures/lineedit_borderless_select.png b/resources/user_interface/textures/lineedit_borderless_select.png new file mode 100644 index 0000000..5d9982f Binary files /dev/null and b/resources/user_interface/textures/lineedit_borderless_select.png differ diff --git a/resources/user_interface/textures/lineedit_borderless_select.png.import b/resources/user_interface/textures/lineedit_borderless_select.png.import new file mode 100644 index 0000000..98be483 --- /dev/null +++ b/resources/user_interface/textures/lineedit_borderless_select.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/lineedit_borderless_select.png-4aee58b7e500decf6960fa056582c12d.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/user_interface/textures/lineedit_borderless_select.png" +dest_files=[ "res://.import/lineedit_borderless_select.png-4aee58b7e500decf6960fa056582c12d.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/scenes/GameRoot.tscn b/scenes/GameRoot.tscn index 7d77d67..14fd0ad 100644 --- a/scenes/GameRoot.tscn +++ b/scenes/GameRoot.tscn @@ -3,15 +3,15 @@ [ext_resource path="res://scenes/stages/MenuManager.tscn" type="PackedScene" id=1] [ext_resource path="res://scenes/stages/StalkerCore.tscn" type="PackedScene" id=2] [ext_resource path="res://scripts/GameRoot.cs" type="Script" id=3] -[ext_resource path="res://scenes/stages/ShadowBallManager.tscn" type="PackedScene" id=4] +[ext_resource path="res://scenes/stages/ConsolePanel.tscn" type="PackedScene" id=4] [node name="GameRoot" type="Node"] script = ExtResource( 3 ) -[node name="UILayer" type="CanvasLayer" parent="."] +[node name="ConsolePanel" parent="." instance=ExtResource( 4 )] +visible = false -[node name="MenuManager" parent="UILayer" instance=ExtResource( 1 )] +[node name="MenuManager" parent="." instance=ExtResource( 1 )] +visible = false [node name="StalkerCore" parent="." instance=ExtResource( 2 )] - -[node name="ShadowBallManager" parent="." instance=ExtResource( 4 )] diff --git a/scenes/stages/ConsolePanel.tscn b/scenes/stages/ConsolePanel.tscn new file mode 100644 index 0000000..10ee439 --- /dev/null +++ b/scenes/stages/ConsolePanel.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://scenes/user_interface/LineEditBorderless.tscn" type="PackedScene" id=1] +[ext_resource path="res://scripts/stages/ConsolePanel.cs" type="Script" id=2] +[ext_resource path="res://resources/user_interface/default_theme.tres" type="Theme" id=3] + +[node name="ConsolePanel" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 3 ) +script = ExtResource( 2 ) + +[node name="CommandInput" parent="." instance=ExtResource( 1 )] +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_top = -44.0 +margin_right = 0.0 +margin_bottom = 0.0 +size_flags_vertical = 3 +placeholder_text = "Input your command here..." +placeholder_alpha = 0.3 +caret_blink = true + +[node name="ScrollSet" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_top = 24.0 +margin_right = -48.0 +margin_bottom = -64.0 + +[node name="ScrollBackground" type="ColorRect" parent="ScrollSet"] +anchor_right = 1.0 +anchor_bottom = 1.0 +color = Color( 0, 0, 0, 0.498039 ) + +[node name="Scrollbar" type="ScrollContainer" parent="ScrollSet"] +anchor_right = 1.0 +anchor_bottom = 1.0 +scroll_horizontal_enabled = false + +[node name="MessageContainer" type="VBoxContainer" parent="ScrollSet/Scrollbar"] +margin_right = 976.0 +margin_bottom = 680.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 diff --git a/scenes/stages/PlayerBall.tscn b/scenes/stages/ShadowBall.tscn similarity index 99% rename from scenes/stages/PlayerBall.tscn rename to scenes/stages/ShadowBall.tscn index 2559a6a..31344d0 100644 --- a/scenes/stages/PlayerBall.tscn +++ b/scenes/stages/ShadowBall.tscn @@ -3,7 +3,7 @@ [ext_resource path="res://resources/textures/Ball_Paper.bmp" type="Texture" id=1] [ext_resource path="res://resources/textures/Ball_Stone.bmp" type="Texture" id=2] [ext_resource path="res://resources/textures/Ball_Wood.bmp" type="Texture" id=3] -[ext_resource path="res://scripts/stages/PlayerBall.cs" type="Script" id=4] +[ext_resource path="res://scripts/stages/ShadowBall.cs" type="Script" id=4] [ext_resource path="res://scenes/user_interface/LabelNormal.tscn" type="PackedScene" id=5] [ext_resource path="res://resources/user_interface/player_pointer.png" type="Texture" id=6] @@ -112,16 +112,21 @@ margin_bottom = 16.0 rect_pivot_offset = Vector2( 16, 16 ) texture = ExtResource( 6 ) -[node name="Ball_Paper" type="MeshInstance" parent="."] +[node name="ModelArchor" type="Spatial" parent="."] + +[node name="Ball_Paper" type="MeshInstance" parent="ModelArchor"] visible = false mesh = SubResource( 4 ) +skeleton = NodePath("../..") material/0 = null -[node name="Ball_Stone" type="MeshInstance" parent="."] +[node name="Ball_Stone" type="MeshInstance" parent="ModelArchor"] visible = false mesh = SubResource( 5 ) +skeleton = NodePath("../..") material/0 = null -[node name="Ball_Wood" type="MeshInstance" parent="."] +[node name="Ball_Wood" type="MeshInstance" parent="ModelArchor"] mesh = SubResource( 6 ) +skeleton = NodePath("../..") material/0 = null diff --git a/scenes/stages/StalkerCamera.tscn b/scenes/stages/StalkerCamera.tscn index 371f98e..958d12c 100644 --- a/scenes/stages/StalkerCamera.tscn +++ b/scenes/stages/StalkerCamera.tscn @@ -8,7 +8,10 @@ script = ExtResource( 1 ) [node name="FreeCamOrigin" type="Spatial" parent="."] [node name="FreeCam" type="Camera" parent="."] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) fov = 58.0 near = 3.0 far = 1200.0 + +[node name="StaticCamOrigin" type="Spatial" parent="."] + +[node name="StaticCamTracking" type="Spatial" parent="StaticCamOrigin"] diff --git a/scenes/stages/StalkerCore.tscn b/scenes/stages/StalkerCore.tscn index 1bc03c2..0e95473 100644 --- a/scenes/stages/StalkerCore.tscn +++ b/scenes/stages/StalkerCore.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://scenes/levels/test.escn" type="PackedScene" id=1] [ext_resource path="res://scripts/stages/StalkerCore.cs" type="Script" id=2] [ext_resource path="res://scenes/stages/StalkerCamera.tscn" type="PackedScene" id=3] +[ext_resource path="res://scenes/stages/ShadowBallManager.tscn" type="PackedScene" id=4] [node name="StalkerCore" type="Spatial"] script = ExtResource( 2 ) @@ -12,4 +13,6 @@ transform = Transform( 0.920545, 0.275714, -0.276729, 0.0231072, 0.668731, 0.743 [node name="StalkerCamera" parent="." instance=ExtResource( 3 )] +[node name="ShadowBallManager" parent="." instance=ExtResource( 4 )] + [node name="test" parent="." instance=ExtResource( 1 )] diff --git a/scenes/user_interface/LabelConsole.tscn b/scenes/user_interface/LabelConsole.tscn new file mode 100644 index 0000000..b2aee46 --- /dev/null +++ b/scenes/user_interface/LabelConsole.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://resources/fonts/fontstyle_normal.tres" type="DynamicFont" id=1] +[ext_resource path="res://scripts/user_interface/LabelConsole.cs" type="Script" id=2] + +[node name="LabelConsole" type="Control"] +script = ExtResource( 2 ) + +[node name="RealLabel" type="Label" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_right = -12.0 +custom_fonts/font = ExtResource( 1 ) +autowrap = true diff --git a/scenes/user_interface/LineEditBorderless.tscn b/scenes/user_interface/LineEditBorderless.tscn new file mode 100644 index 0000000..b691164 --- /dev/null +++ b/scenes/user_interface/LineEditBorderless.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://resources/user_interface/styles/lineedit_borderless_style_select.tres" type="StyleBox" id=1] +[ext_resource path="res://resources/user_interface/styles/lineedit_borderless_style_deselect.tres" type="StyleBox" id=2] +[ext_resource path="res://resources/fonts/fontstyle_normal.tres" type="DynamicFont" id=3] + +[node name="LineEditBorderless" type="LineEdit"] +margin_right = 58.0 +margin_bottom = 24.0 +custom_fonts/font = ExtResource( 3 ) +custom_styles/read_only = ExtResource( 2 ) +custom_styles/focus = ExtResource( 1 ) +custom_styles/normal = ExtResource( 2 ) diff --git a/scripts/GameRoot.cs b/scripts/GameRoot.cs index 42d49de..8fe66f0 100644 --- a/scripts/GameRoot.cs +++ b/scripts/GameRoot.cs @@ -7,28 +7,43 @@ public class GameRoot : Node { StalkerCore mStalkerCore; public override void _Ready() { - mMenuManager = GetNode("UILayer/MenuManager"); + mMenuManager = GetNode("MenuManager"); mStalkerCore = GetNode("StalkerCore"); - mMenuManager.Connect(nameof(MenuManager.SetMouseCapture), this, nameof(Proc_MenuManager_SetMouseCapture)); + //mMenuManager.Connect(nameof(MenuManager.SetMouseCapture), this, nameof(Proc_MenuManager_SetMouseCapture)); mMenuManager.Connect(nameof(MenuManager.ExitGame), this, nameof(Proc_MenuManager_ExitGame)); - // raw executing this func - // to set proper status - Proc_MenuManager_SetMouseCapture(); + //// raw executing this func + //// to set proper status + //Proc_MenuManager_SetMouseCapture(); + BallanceStalkerCore.StalkerManager.Singleton.EventControllerChanged += Proc_StalkerManager_EventControllerChanged; + BallanceStalkerCore.StalkerManager.Singleton.SetEventController(BallanceStalkerCore.EventControllerSource.None); + } + + private void Proc_StalkerManager_EventControllerChanged(BallanceStalkerCore.EventControllerSource obj) { + switch (obj) { + case BallanceStalkerCore.EventControllerSource.None: + Input.SetMouseMode(Input.MouseMode.Captured); + break; + case BallanceStalkerCore.EventControllerSource.Menu: + case BallanceStalkerCore.EventControllerSource.Console: + case BallanceStalkerCore.EventControllerSource.Chat: + Input.SetMouseMode(Input.MouseMode.Visible); + break; + } } public override void _Input(InputEvent @event) { } - private void Proc_MenuManager_SetMouseCapture() { - if (mMenuManager.Visible) { - Input.SetMouseMode(Input.MouseMode.Visible); - } else { - Input.SetMouseMode(Input.MouseMode.Captured); - } - } + //private void Proc_MenuManager_SetMouseCapture() { + // if (mMenuManager.Visible) { + // Input.SetMouseMode(Input.MouseMode.Visible); + // } else { + // Input.SetMouseMode(Input.MouseMode.Captured); + // } + //} private void Proc_MenuManager_ExitGame() { GetTree().Notification(MainLoop.NotificationWmQuitRequest); } diff --git a/scripts/stages/ConsolePanel.cs b/scripts/stages/ConsolePanel.cs new file mode 100644 index 0000000..593f0cb --- /dev/null +++ b/scripts/stages/ConsolePanel.cs @@ -0,0 +1,98 @@ +using Godot; +using System; +using System.Collections.Generic; + +public enum LabelConsoleMessageType { + Normal, + Highlight, + Error +} + +public class ConsolePanel : Control { + private LineEdit mCmdInput; + private ScrollContainer mScrollbar; + private VBoxContainer mMessageContainer; + private PackedScene mTemplateLabelConsole; + private Queue mMessageQueue = new Queue(); + private readonly int QUEUE_MAX_SIZE = 100; + + public override void _Ready() { + mTemplateLabelConsole = ResourceLoader.Load("res://scenes/user_interface/LabelConsole.tscn"); + + mCmdInput = GetNode("CommandInput"); + mScrollbar = GetNode("ScrollSet/Scrollbar"); + mMessageContainer = GetNode("ScrollSet/Scrollbar/MessageContainer"); + mCmdInput.Connect("text_entered", this, nameof(Proc_LineEdit_TextEntered)); + + BallanceStalkerCore.StalkerManager.Singleton.EventControllerChanged += Proc_StalkerManager_EventControllerChanged; + } + + private void Proc_StalkerManager_EventControllerChanged(BallanceStalkerCore.EventControllerSource obj) { + if (obj == BallanceStalkerCore.EventControllerSource.Chat) { + this.Visible = true; + mCmdInput.GrabFocus(); + } else if (obj == BallanceStalkerCore.EventControllerSource.Console) { + // same process of chat + // but only add a extra preset charcater in cmd input + this.Visible = true; + mCmdInput.Text = "/"; + mCmdInput.CaretPosition = 1; + mCmdInput.GrabFocus(); + } else { + this.Visible = false; + } + } + + public override void _Input(InputEvent @event) { + if (!this.Visible) return; + + if (@event.IsActionPressed("ballance_esc")) { + // clean input + mCmdInput.Text = ""; + // back to camera + BallanceStalkerCore.StalkerManager.Singleton.SetEventController(BallanceStalkerCore.EventControllerSource.None); + // mark handled to prevent loop call + GetTree().SetInputAsHandled(); + } + } + + private void AddMessage(string strl, LabelConsoleMessageType t) { + LabelConsole target; + if (mMessageQueue.Count > QUEUE_MAX_SIZE) { + // popup last item and remove it from scene first + target = mMessageQueue.Dequeue(); + mMessageContainer.RemoveChild(target); + } else { + target = mTemplateLabelConsole.Instance(); + } + + // add into scene and queue + mMessageQueue.Enqueue(target); + mMessageContainer.AddChild(target); + + // set text + target.SetText(strl, t); + + // scroll to bottom + //var bar = mScrollbar.GetVScrollbar(); + //bar.Value = bar.MaxValue; + mScrollbar.ScrollVertical = (int)mScrollbar.GetVScrollbar().MaxValue; + } + + private void Proc_LineEdit_TextEntered(string new_strl) { + if (new_strl != string.Empty) { + // todo: finish cmd parse + if (new_strl.StartsWith("/")) { + AddMessage(new_strl, LabelConsoleMessageType.Highlight); + } else if (new_strl.StartsWith("!")) { + AddMessage(new_strl, LabelConsoleMessageType.Error); + } else { + AddMessage(new_strl, LabelConsoleMessageType.Normal); + } + + // clean cmd + mCmdInput.Text = ""; + } + } + +} diff --git a/scripts/stages/MenuManager.cs b/scripts/stages/MenuManager.cs index d490526..5770b78 100644 --- a/scripts/stages/MenuManager.cs +++ b/scripts/stages/MenuManager.cs @@ -12,8 +12,8 @@ public class MenuManager : Control { About } - [Signal] - public delegate void SetMouseCapture(); + //[Signal] + //public delegate void SetMouseCapture(); [Signal] public delegate void ExitGame(); @@ -28,18 +28,31 @@ public class MenuManager : Control { mMenuMain.Connect(nameof(MenuMain.MenuMain_GotoPage), this, nameof(Proc_MenuMain_GotoPage)); mMenuMain.Connect(nameof(MenuMain.MenuMain_Back), this, nameof(Proc_MenuMain_Back)); mMenuMain.Connect(nameof(MenuMain.MenuMain_Exit), this, nameof(Proc_MenuMain_Exit)); + + BallanceStalkerCore.StalkerManager.Singleton.EventControllerChanged += Proc_StalkerManager_EventControllerChanged; + } + + private void Proc_StalkerManager_EventControllerChanged(BallanceStalkerCore.EventControllerSource obj) { + if (obj == BallanceStalkerCore.EventControllerSource.Menu) { + this.Visible = true; + } else { + this.Visible = false; + } } public override void _Input(InputEvent @event) { - if (Input.IsActionJustPressed("ballance_esc")) { + if (!this.Visible) return; + + if (@event.IsActionPressed("ballance_esc")) { if (mCurrentPage == MenuPage.Main) { // we are in main menu, we need switch visible - this.Visible = !this.Visible; - EmitSignal(nameof(SetMouseCapture)); + BallanceStalkerCore.StalkerManager.Singleton.SetEventController(BallanceStalkerCore.EventControllerSource.None); } else { // otherwise, back from sub menu RefreshMenuPage(MenuPage.Main); } + // mark handled to prevent loop call + GetTree().SetInputAsHandled(); } } @@ -52,8 +65,7 @@ public class MenuManager : Control { RefreshMenuPage(menu_type); } private void Proc_MenuMain_Back() { - this.Visible = false; - EmitSignal(nameof(SetMouseCapture)); + BallanceStalkerCore.StalkerManager.Singleton.SetEventController(BallanceStalkerCore.EventControllerSource.None); } private void Proc_MenuMain_Exit() { EmitSignal(nameof(ExitGame)); diff --git a/scripts/stages/PlayerBall.cs b/scripts/stages/ShadowBall.cs similarity index 79% rename from scripts/stages/PlayerBall.cs rename to scripts/stages/ShadowBall.cs index 89a3cac..6375658 100644 --- a/scripts/stages/PlayerBall.cs +++ b/scripts/stages/ShadowBall.cs @@ -3,22 +3,26 @@ using System; // Reference: https://github.com/godotengine/godot-demo-projects/blob/master/3d/waypoints -public class PlayerBall : Spatial { +public enum ShadowBallType : UInt32 { + Stone, + Wood, + Paper +} + +public class ShadowBall : Spatial { static readonly float MARGIN = 16f; // set it as half of arrow image static readonly float TEXT_RADIUS = MARGIN + 16f; - public string Playername { - get { return mPlayername.Text; } - set { mPlayername.Text = value; } - } - public bool AlwaysTracking { get; set; } + private bool mAlwaysTracking = true; Control mCtl2D; - Spatial mTextArchor; + Spatial mTextArchor, mModelArchor; TextureRect mPlayerArrow; Label mPlayername; Camera mSpectatorCamera = null; + MeshInstance mMeshWood, mMeshStone, mMeshPaper; + ShadowBallType mOldState = ShadowBallType.Wood; public override void _Ready() { mCtl2D = GetNode("TextArchor/Ctl2D"); @@ -26,8 +30,45 @@ public class PlayerBall : Spatial { mPlayerArrow = GetNode("TextArchor/Ctl2D/PlayerArrow"); mPlayername = GetNode