feat: Establish initial game structure including lobby, UI, and core gameplay managers.

This commit is contained in:
Yogi Wiguna
2026-02-02 15:01:30 +08:00
parent 9201c99d42
commit 66d34d0d29
21 changed files with 1688 additions and 1475 deletions
+7 -1
View File
@@ -1,3 +1,9 @@
{ {
"godotTools.editorPath.godot4": "/home/beng/Godot/Editors/4.5.1-stable/Godot_v4.5.1-stable_linux.x86_64" "godotTools.editorPath.godot4": "C:\\Users\\Dev-Danchie\\Godot\\Editors\\.editor_config\\tekton-local\\Godot_v4.6-stable_win64.exe",
"editor.tabSize": 4,
"editor.insertSpaces": false,
"files.eol": "\n",
"files.exclude": {
"**/*.gd.uid": true
}
} }
@@ -1,4 +1,4 @@
[gd_resource type="MeshLibrary" load_steps=19 format=4 uid="uid://kcv6ans86ug7"] [gd_resource type="MeshLibrary" format=4 uid="uid://kcv6ans86ug7"]
[ext_resource type="ArrayMesh" uid="uid://cr70nmk8djc1i" path="res://assets/models/meshes/tiles_armagedon_a3.res" id="1_ptqbt"] [ext_resource type="ArrayMesh" uid="uid://cr70nmk8djc1i" path="res://assets/models/meshes/tiles_armagedon_a3.res" id="1_ptqbt"]
[ext_resource type="ArrayMesh" uid="uid://dspusnbkr74hg" path="res://assets/models/meshes/hover.res" id="2_p5epg"] [ext_resource type="ArrayMesh" uid="uid://dspusnbkr74hg" path="res://assets/models/meshes/hover.res" id="2_p5epg"]
+1 -2
View File
@@ -1,4 +1,4 @@
[gd_resource type="Environment" load_steps=3 format=3 uid="uid://jbptgqvstei3"] [gd_resource type="Environment" format=3 uid="uid://jbptgqvstei3"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_lg8b7"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_lg8b7"]
sky_horizon_color = Color(0.67451, 0.682353, 0.698039, 1) sky_horizon_color = Color(0.67451, 0.682353, 0.698039, 1)
@@ -26,5 +26,4 @@ sdfgi_cascades = 1
sdfgi_energy = 0.5 sdfgi_energy = 0.5
glow_levels/2 = 0.6 glow_levels/2 = 0.6
glow_levels/3 = 0.6 glow_levels/3 = 0.6
glow_levels/5 = 0.0
glow_intensity = 2.0 glow_intensity = 2.0
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=4 format=4 uid="uid://b5ta7tcw0iscd"] [gd_resource type="ArrayMesh" format=4 uid="uid://b5ta7tcw0iscd"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_po712"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_po712"]
load_path = "res://.godot/imported/tile_coin.png-07bdc9862d055beeb72a967a0094a5c7.s3tc.ctex" load_path = "res://.godot/imported/tile_coin.png-07bdc9862d055beeb72a967a0094a5c7.s3tc.ctex"
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=3 format=4 uid="uid://dr80txgr61irt"] [gd_resource type="ArrayMesh" format=4 uid="uid://dr80txgr61irt"]
[ext_resource type="Texture2D" uid="uid://dpkx1a780pvwv" path="res://assets/textures/tile_diamond.png" id="1_fck33"] [ext_resource type="Texture2D" uid="uid://dpkx1a780pvwv" path="res://assets/textures/tile_diamond.png" id="1_fck33"]
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=4 format=4 uid="uid://hwj23u2j561a"] [gd_resource type="ArrayMesh" format=4 uid="uid://hwj23u2j561a"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_mwj80"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_mwj80"]
load_path = "res://.godot/imported/tile_diamond_holo.png-e0c28a726d94831c5180dcc0376d012c.s3tc.ctex" load_path = "res://.godot/imported/tile_diamond_holo.png-e0c28a726d94831c5180dcc0376d012c.s3tc.ctex"
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=4 format=4 uid="uid://brevl3ab0tdqe"] [gd_resource type="ArrayMesh" format=4 uid="uid://brevl3ab0tdqe"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_txrgg"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_txrgg"]
load_path = "res://.godot/imported/tile_heart_holo.png-5c92e04305de5aaa054336f0ec160274.s3tc.ctex" load_path = "res://.godot/imported/tile_heart_holo.png-5c92e04305de5aaa054336f0ec160274.s3tc.ctex"
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=4 format=4 uid="uid://cv4bedhida00g"] [gd_resource type="ArrayMesh" format=4 uid="uid://cv4bedhida00g"]
[ext_resource type="Texture2D" uid="uid://dqpr1nug528ml" path="res://assets/textures/tile_star_holo.png" id="1_max3p"] [ext_resource type="Texture2D" uid="uid://dqpr1nug528ml" path="res://assets/textures/tile_star_holo.png" id="1_max3p"]
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="ArrayMesh" load_steps=4 format=4 uid="uid://bqvqj3fhf5x51"] [gd_resource type="ArrayMesh" format=4 uid="uid://bqvqj3fhf5x51"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_7uoqg"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_7uoqg"]
load_path = "res://.godot/imported/tile_star_holo.png-4aade3ef0db71672f9bd2143ab924c6e.s3tc.ctex" load_path = "res://.godot/imported/tile_star_holo.png-4aade3ef0db71672f9bd2143ab924c6e.s3tc.ctex"
+1 -1
View File
@@ -1,4 +1,4 @@
[gd_resource type="Theme" load_steps=17 format=3 uid="uid://da337sh5qxi0s"] [gd_resource type="Theme" format=3 uid="uid://da337sh5qxi0s"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button_disabled"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button_disabled"]
content_margin_left = 16.0 content_margin_left = 16.0
+12 -3
View File
@@ -8,16 +8,20 @@
config_version=5 config_version=5
[animation]
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application] [application]
config/name="tekton-local" config/name="tekton-local"
run/main_scene="uid://dxn87yj8qnfpp" run/main_scene="uid://dxn87yj8qnfpp"
config/features=PackedStringArray("4.5", "Forward Plus") config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[autoload] [autoload]
Nakama="*res://addons/com.heroiclabs.nakama/Nakama.gd" Nakama="*uid://bueyqhhvxe0tx"
NakamaManager="*res://scripts/nakama_manager.gd" NakamaManager="*res://scripts/nakama_manager.gd"
AuthManager="*res://scripts/managers/auth_manager.gd" AuthManager="*res://scripts/managers/auth_manager.gd"
LobbyManager="*res://scripts/managers/lobby_manager.gd" LobbyManager="*res://scripts/managers/lobby_manager.gd"
@@ -28,7 +32,7 @@ TurnManager="*res://scripts/managers/turn_manager.gd"
GoalManager="*res://scripts/managers/goal_manager.gd" GoalManager="*res://scripts/managers/goal_manager.gd"
PlayerManager="*res://scripts/managers/player_manager.gd" PlayerManager="*res://scripts/managers/player_manager.gd"
GoalsCycleManager="*res://scripts/managers/goals_cycle_manager.gd" GoalsCycleManager="*res://scripts/managers/goals_cycle_manager.gd"
Satori="*res://addons/com.heroiclabs.nakama/Satori.gd" Satori="*uid://b8vev00s34b7"
[display] [display]
@@ -104,3 +108,8 @@ action_put={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
] ]
} }
use_powerup={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
]
}
+106 -106
View File
@@ -1,11 +1,11 @@
[gd_scene load_steps=5 format=3 uid="uid://b7nxt2hc4kqp8"] [gd_scene format=3 uid="uid://b7nxt2hc4kqp8"]
[ext_resource type="Script" uid="uid://b5q6yekyk0tld" path="res://scenes/lobby.gd" id="1_lp6xi"] [ext_resource type="Script" uid="uid://b5q6yekyk0tld" path="res://scenes/lobby.gd" id="1_lp6xi"]
[ext_resource type="Theme" uid="uid://da337sh5qxi0s" path="res://assets/themes/ui_theme.tres" id="2_theme"] [ext_resource type="Theme" uid="uid://da337sh5qxi0s" path="res://assets/themes/ui_theme.tres" id="2_theme"]
[ext_resource type="Texture2D" uid="uid://2d1ks5pmblc7" path="res://assets/graphics/main_menu/bg_back.png" id="3_q60fs"] [ext_resource type="Texture2D" uid="uid://2d1ks5pmblc7" path="res://assets/graphics/main_menu/bg_back.png" id="3_q60fs"]
[ext_resource type="Texture2D" uid="uid://dvp0as6yyudco" path="res://assets/graphics/main_menu/bg_illust.png" id="4_nqcc7"] [ext_resource type="Texture2D" uid="uid://dvp0as6yyudco" path="res://assets/graphics/main_menu/bg_illust.png" id="4_nqcc7"]
[node name="Lobby" type="Control"] [node name="Lobby" type="Control" unique_id=1490767889]
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@@ -15,7 +15,7 @@ grow_vertical = 2
theme = ExtResource("2_theme") theme = ExtResource("2_theme")
script = ExtResource("1_lp6xi") script = ExtResource("1_lp6xi")
[node name="Background" type="TextureRect" parent="."] [node name="Background" type="TextureRect" parent="." unique_id=767675801]
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@@ -25,7 +25,7 @@ grow_vertical = 2
texture = ExtResource("3_q60fs") texture = ExtResource("3_q60fs")
expand_mode = 2 expand_mode = 2
[node name="Background2" type="TextureRect" parent="."] [node name="Background2" type="TextureRect" parent="." unique_id=783164473]
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@@ -35,7 +35,7 @@ grow_vertical = 2
texture = ExtResource("4_nqcc7") texture = ExtResource("4_nqcc7")
expand_mode = 2 expand_mode = 2
[node name="MainMenuPanel" type="PanelContainer" parent="."] [node name="MainMenuPanel" type="PanelContainer" parent="." unique_id=19191862]
layout_mode = 1 layout_mode = 1
anchors_preset = 8 anchors_preset = 8
anchor_left = 0.5 anchor_left = 0.5
@@ -49,15 +49,15 @@ offset_bottom = 240.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MainMenuPanel"] [node name="VBoxContainer" type="VBoxContainer" parent="MainMenuPanel" unique_id=590789898]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 18 theme_override_constants/separation = 18
[node name="TitleContainer" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer"] [node name="TitleContainer" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer" unique_id=187177999]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 4 theme_override_constants/separation = 4
[node name="Title" type="Label" parent="MainMenuPanel/VBoxContainer/TitleContainer"] [node name="Title" type="Label" parent="MainMenuPanel/VBoxContainer/TitleContainer" unique_id=612210089]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
theme_override_font_sizes/font_size = 44 theme_override_font_sizes/font_size = 44
@@ -65,55 +65,55 @@ text = "TEKTON DASH"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="Subtitle" type="Label" parent="MainMenuPanel/VBoxContainer/TitleContainer"] [node name="Subtitle" type="Label" parent="MainMenuPanel/VBoxContainer/TitleContainer" unique_id=670350843]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "ARMAGEDDON VERSION" text = "ARMAGEDDON VERSION"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="Separator" type="HSeparator" parent="MainMenuPanel/VBoxContainer"] [node name="Separator" type="HSeparator" parent="MainMenuPanel/VBoxContainer" unique_id=126990892]
layout_mode = 2 layout_mode = 2
[node name="InputSection" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer"] [node name="InputSection" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer" unique_id=1865748579]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 10 theme_override_constants/separation = 10
[node name="PlayerNameLabel" type="Label" parent="MainMenuPanel/VBoxContainer/InputSection"] [node name="PlayerNameLabel" type="Label" parent="MainMenuPanel/VBoxContainer/InputSection" unique_id=1017736748]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 13 theme_override_font_sizes/font_size = 13
text = "YOUR NAME" text = "YOUR NAME"
[node name="PlayerNameInput" type="LineEdit" parent="MainMenuPanel/VBoxContainer/InputSection"] [node name="PlayerNameInput" type="LineEdit" parent="MainMenuPanel/VBoxContainer/InputSection" unique_id=1668571796]
custom_minimum_size = Vector2(0, 44) custom_minimum_size = Vector2(0, 44)
layout_mode = 2 layout_mode = 2
text = "Player" text = "Player"
placeholder_text = "Enter your name..." placeholder_text = "Enter your name..."
[node name="ButtonSection" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer"] [node name="ButtonSection" type="VBoxContainer" parent="MainMenuPanel/VBoxContainer" unique_id=793290187]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 12 theme_override_constants/separation = 12
[node name="CreateRoomBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection"] [node name="CreateRoomBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection" unique_id=750714]
custom_minimum_size = Vector2(0, 48) custom_minimum_size = Vector2(0, 48)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "CREATE ROOM" text = "CREATE ROOM"
[node name="BrowseRoomsBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection"] [node name="BrowseRoomsBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection" unique_id=2135081425]
custom_minimum_size = Vector2(0, 48) custom_minimum_size = Vector2(0, 48)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "BROWSE ROOMS" text = "BROWSE ROOMS"
[node name="ProfileBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection"] [node name="ProfileBtn" type="Button" parent="MainMenuPanel/VBoxContainer/ButtonSection" unique_id=1640960506]
custom_minimum_size = Vector2(0, 36) custom_minimum_size = Vector2(0, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 14 theme_override_font_sizes/font_size = 14
text = "PROFILE" text = "PROFILE"
[node name="RoomListPanel" type="PanelContainer" parent="."] [node name="RoomListPanel" type="PanelContainer" parent="." unique_id=1782359692]
visible = false visible = false
layout_mode = 1 layout_mode = 1
anchors_preset = 8 anchors_preset = 8
@@ -128,68 +128,68 @@ offset_bottom = 260.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="RoomListPanel"] [node name="VBoxContainer" type="VBoxContainer" parent="RoomListPanel" unique_id=159201826]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 14 theme_override_constants/separation = 14
[node name="Header" type="Label" parent="RoomListPanel/VBoxContainer"] [node name="Header" type="Label" parent="RoomListPanel/VBoxContainer" unique_id=911540555]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
theme_override_font_sizes/font_size = 28 theme_override_font_sizes/font_size = 28
text = "SERVER BROWSER" text = "SERVER BROWSER"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="RoomListPanel/VBoxContainer"] [node name="HSeparator" type="HSeparator" parent="RoomListPanel/VBoxContainer" unique_id=1359536044]
layout_mode = 2 layout_mode = 2
[node name="MatchIdLabel" type="Label" parent="RoomListPanel/VBoxContainer"] [node name="MatchIdLabel" type="Label" parent="RoomListPanel/VBoxContainer" unique_id=1208643238]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "DIRECT CONNECT (MATCH ID)" text = "DIRECT CONNECT (MATCH ID)"
[node name="MatchIdInput" type="LineEdit" parent="RoomListPanel/VBoxContainer"] [node name="MatchIdInput" type="LineEdit" parent="RoomListPanel/VBoxContainer" unique_id=425559636]
custom_minimum_size = Vector2(0, 44) custom_minimum_size = Vector2(0, 44)
layout_mode = 2 layout_mode = 2
placeholder_text = "Paste match ID here..." placeholder_text = "Paste match ID here..."
[node name="RoomListLabel" type="Label" parent="RoomListPanel/VBoxContainer"] [node name="RoomListLabel" type="Label" parent="RoomListPanel/VBoxContainer" unique_id=1579554712]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "AVAILABLE SERVERS" text = "AVAILABLE SERVERS"
[node name="RoomList" type="ItemList" parent="RoomListPanel/VBoxContainer"] [node name="RoomList" type="ItemList" parent="RoomListPanel/VBoxContainer" unique_id=1747575999]
custom_minimum_size = Vector2(0, 200) custom_minimum_size = Vector2(0, 200)
layout_mode = 2 layout_mode = 2
allow_reselect = true allow_reselect = true
[node name="ButtonContainer" type="HBoxContainer" parent="RoomListPanel/VBoxContainer"] [node name="ButtonContainer" type="HBoxContainer" parent="RoomListPanel/VBoxContainer" unique_id=181847289]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 14 theme_override_constants/separation = 14
alignment = 1 alignment = 1
[node name="RefreshBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer"] [node name="RefreshBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer" unique_id=586598199]
custom_minimum_size = Vector2(110, 44) custom_minimum_size = Vector2(110, 44)
layout_mode = 2 layout_mode = 2
text = "REFRESH" text = "REFRESH"
[node name="JoinBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer"] [node name="JoinBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer" unique_id=1079497597]
custom_minimum_size = Vector2(130, 44) custom_minimum_size = Vector2(130, 44)
layout_mode = 2 layout_mode = 2
text = "JOIN SERVER" text = "JOIN SERVER"
[node name="BackBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer"] [node name="BackBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer" unique_id=1786784033]
custom_minimum_size = Vector2(110, 44) custom_minimum_size = Vector2(110, 44)
layout_mode = 2 layout_mode = 2
text = "BACK" text = "BACK"
[node name="ProfileBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer"] [node name="ProfileBtn" type="Button" parent="RoomListPanel/VBoxContainer/ButtonContainer" unique_id=1473526002]
custom_minimum_size = Vector2(80, 44) custom_minimum_size = Vector2(80, 44)
layout_mode = 2 layout_mode = 2
text = "PROFILE" text = "PROFILE"
[node name="LobbyPanel" type="Control" parent="."] [node name="LobbyPanel" type="Control" parent="." unique_id=1745714811]
visible = false visible = false
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
@@ -198,7 +198,7 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="LobbyBackground" type="ColorRect" parent="LobbyPanel"] [node name="LobbyBackground" type="ColorRect" parent="LobbyPanel" unique_id=1549298772]
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@@ -207,7 +207,7 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
color = Color(0.06, 0.08, 0.12, 1) color = Color(0.06, 0.08, 0.12, 1)
[node name="TopBar" type="HBoxContainer" parent="LobbyPanel"] [node name="TopBar" type="HBoxContainer" parent="LobbyPanel" unique_id=1388322915]
layout_mode = 1 layout_mode = 1
anchors_preset = 10 anchors_preset = 10
anchor_right = 1.0 anchor_right = 1.0
@@ -218,57 +218,57 @@ offset_bottom = 50.0
grow_horizontal = 2 grow_horizontal = 2
theme_override_constants/separation = 20 theme_override_constants/separation = 20
[node name="ProfileSection" type="HBoxContainer" parent="LobbyPanel/TopBar"] [node name="ProfileSection" type="HBoxContainer" parent="LobbyPanel/TopBar" unique_id=558544234]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 10 theme_override_constants/separation = 10
[node name="ProfileBtn" type="Button" parent="LobbyPanel/TopBar/ProfileSection"] [node name="ProfileBtn" type="Button" parent="LobbyPanel/TopBar/ProfileSection" unique_id=1726139031]
custom_minimum_size = Vector2(80, 32) custom_minimum_size = Vector2(80, 32)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "Profile" text = "Profile"
[node name="LogoutBtn" type="Button" parent="LobbyPanel/TopBar/ProfileSection"] [node name="LogoutBtn" type="Button" parent="LobbyPanel/TopBar/ProfileSection" unique_id=1221873519]
custom_minimum_size = Vector2(70, 32) custom_minimum_size = Vector2(70, 32)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "Logout" text = "Logout"
[node name="Spacer" type="Control" parent="LobbyPanel/TopBar"] [node name="Spacer" type="Control" parent="LobbyPanel/TopBar" unique_id=379952578]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="MatchIdContainer" type="HBoxContainer" parent="LobbyPanel/TopBar"] [node name="MatchIdContainer" type="HBoxContainer" parent="LobbyPanel/TopBar" unique_id=2124757758]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="MatchIdDisplay" type="Label" parent="LobbyPanel/TopBar/MatchIdContainer"] [node name="MatchIdDisplay" type="Label" parent="LobbyPanel/TopBar/MatchIdContainer" unique_id=1918774593]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.955211, 0.955297, 0.962624, 1) theme_override_colors/font_color = Color(0.955211, 0.955297, 0.962624, 1)
theme_override_font_sizes/font_size = 10 theme_override_font_sizes/font_size = 10
text = "Match ID: " text = "Match ID: "
[node name="CopyIdBtn" type="Button" parent="LobbyPanel/TopBar/MatchIdContainer"] [node name="CopyIdBtn" type="Button" parent="LobbyPanel/TopBar/MatchIdContainer" unique_id=1663928449]
custom_minimum_size = Vector2(60, 28) custom_minimum_size = Vector2(60, 28)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 10 theme_override_font_sizes/font_size = 10
text = "COPY" text = "COPY"
[node name="Spacer2" type="Control" parent="LobbyPanel/TopBar"] [node name="Spacer2" type="Control" parent="LobbyPanel/TopBar" unique_id=580427042]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="SettingsSection" type="HBoxContainer" parent="LobbyPanel/TopBar"] [node name="SettingsSection" type="HBoxContainer" parent="LobbyPanel/TopBar" unique_id=1115962195]
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="DurationLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection"] [node name="DurationLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1072635610]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "Duration:" text = "Duration:"
[node name="DurationOption" type="OptionButton" parent="LobbyPanel/TopBar/SettingsSection"] [node name="DurationOption" type="OptionButton" parent="LobbyPanel/TopBar/SettingsSection" unique_id=448675775]
custom_minimum_size = Vector2(90, 28) custom_minimum_size = Vector2(90, 28)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
@@ -285,48 +285,48 @@ popup/item_3/id = 3
popup/item_4/text = "10 min" popup/item_4/text = "10 min"
popup/item_4/id = 4 popup/item_4/id = 4
[node name="DurationTextLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection"] [node name="DurationTextLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1917308134]
visible = false visible = false
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "3 min" text = "3 min"
[node name="SpawnSpacer" type="Control" parent="LobbyPanel/TopBar/SettingsSection"] [node name="SpawnSpacer" type="Control" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1046796297]
custom_minimum_size = Vector2(15, 0) custom_minimum_size = Vector2(15, 0)
layout_mode = 2 layout_mode = 2
[node name="RandomSpawnCheck" type="CheckButton" parent="LobbyPanel/TopBar/SettingsSection"] [node name="RandomSpawnCheck" type="CheckButton" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1259096465]
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
button_pressed = true button_pressed = true
text = "Random Spawn" text = "Random Spawn"
[node name="RandomSpawnLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection"] [node name="RandomSpawnLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection" unique_id=287278537]
visible = false visible = false
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "Random ✓" text = "Random ✓"
[node name="TimerSpacer" type="Control" parent="LobbyPanel/TopBar/SettingsSection"] [node name="TimerSpacer" type="Control" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1261893791]
custom_minimum_size = Vector2(15, 0) custom_minimum_size = Vector2(15, 0)
layout_mode = 2 layout_mode = 2
[node name="EnableTimerCheck" type="CheckButton" parent="LobbyPanel/TopBar/SettingsSection"] [node name="EnableTimerCheck" type="CheckButton" parent="LobbyPanel/TopBar/SettingsSection" unique_id=417182829]
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
button_pressed = true button_pressed = true
text = "Enable Timer" text = "Enable Timer"
[node name="EnableTimerLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection"] [node name="EnableTimerLabel" type="Label" parent="LobbyPanel/TopBar/SettingsSection" unique_id=1100225622]
visible = false visible = false
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "Timer ✓" text = "Timer ✓"
[node name="HostBanner" type="PanelContainer" parent="LobbyPanel"] [node name="HostBanner" type="PanelContainer" parent="LobbyPanel" unique_id=1670701936]
layout_mode = 1 layout_mode = 1
anchors_preset = 5 anchors_preset = 5
anchor_left = 0.5 anchor_left = 0.5
@@ -337,7 +337,7 @@ offset_right = 150.0
offset_bottom = 159.0 offset_bottom = 159.0
grow_horizontal = 2 grow_horizontal = 2
[node name="HostBannerLabel" type="Label" parent="LobbyPanel/HostBanner"] [node name="HostBannerLabel" type="Label" parent="LobbyPanel/HostBanner" unique_id=1011182924]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.1, 0.1, 0.1, 1) theme_override_colors/font_color = Color(0.1, 0.1, 0.1, 1)
theme_override_font_sizes/font_size = 20 theme_override_font_sizes/font_size = 20
@@ -345,7 +345,7 @@ text = "HOST"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="RoomNameHeader" type="Label" parent="LobbyPanel"] [node name="RoomNameHeader" type="Label" parent="LobbyPanel" unique_id=1556811338]
layout_mode = 1 layout_mode = 1
anchors_preset = 5 anchors_preset = 5
anchor_left = 0.5 anchor_left = 0.5
@@ -360,7 +360,7 @@ theme_override_font_sizes/font_size = 20
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="PlayersContainer" type="HBoxContainer" parent="LobbyPanel"] [node name="PlayersContainer" type="HBoxContainer" parent="LobbyPanel" unique_id=1404488292]
layout_mode = 1 layout_mode = 1
anchors_preset = 8 anchors_preset = 8
anchor_left = 0.5 anchor_left = 0.5
@@ -376,37 +376,37 @@ grow_vertical = 2
theme_override_constants/separation = 30 theme_override_constants/separation = 30
alignment = 1 alignment = 1
[node name="PlayerSlot1" type="VBoxContainer" parent="LobbyPanel/PlayersContainer"] [node name="PlayerSlot1" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=92376672]
custom_minimum_size = Vector2(180, 0) custom_minimum_size = Vector2(180, 0)
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
alignment = 1 alignment = 1
[node name="PlayerName1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1"] [node name="PlayerName1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1" unique_id=19773465]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "Player 1" text = "Player 1"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="CharacterPreview1" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot1"] [node name="CharacterPreview1" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot1" unique_id=755621155]
custom_minimum_size = Vector2(140, 140) custom_minimum_size = Vector2(140, 140)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
expand_mode = 1 expand_mode = 1
stretch_mode = 5 stretch_mode = 5
[node name="CharacterNav1" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot1"] [node name="CharacterNav1" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot1" unique_id=2051013338]
layout_mode = 2 layout_mode = 2
alignment = 1 alignment = 1
[node name="CharLeftBtn1" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1"] [node name="CharLeftBtn1" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1" unique_id=1065844890]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "◀" text = "◀"
[node name="CharacterName1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1"] [node name="CharacterName1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1" unique_id=1384965097]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -415,13 +415,13 @@ text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="CharRightBtn1" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1"] [node name="CharRightBtn1" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot1/CharacterNav1" unique_id=737265649]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "▶" text = "▶"
[node name="CharacterNameLabel1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1"] [node name="CharacterNameLabel1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1" unique_id=1107739187]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -429,46 +429,46 @@ theme_override_font_sizes/font_size = 14
text = "Bob" text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="ReadyStatus1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1"] [node name="ReadyStatus1" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot1" unique_id=1382214476]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "NOT READY" text = "NOT READY"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="PlayerSlot2" type="VBoxContainer" parent="LobbyPanel/PlayersContainer"] [node name="PlayerSlot2" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=1012954493]
visible = false visible = false
custom_minimum_size = Vector2(180, 0) custom_minimum_size = Vector2(180, 0)
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
alignment = 1 alignment = 1
[node name="PlayerName2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2"] [node name="PlayerName2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2" unique_id=878869724]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "Player 2" text = "Player 2"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="CharacterPreview2" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot2"] [node name="CharacterPreview2" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot2" unique_id=776724044]
custom_minimum_size = Vector2(140, 140) custom_minimum_size = Vector2(140, 140)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
expand_mode = 1 expand_mode = 1
stretch_mode = 5 stretch_mode = 5
[node name="CharacterNav2" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot2"] [node name="CharacterNav2" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot2" unique_id=1767191604]
visible = false visible = false
layout_mode = 2 layout_mode = 2
alignment = 1 alignment = 1
[node name="CharLeftBtn2" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2"] [node name="CharLeftBtn2" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2" unique_id=1010021890]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "◀" text = "◀"
[node name="CharacterName2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2"] [node name="CharacterName2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2" unique_id=539481206]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -477,13 +477,13 @@ text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="CharRightBtn2" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2"] [node name="CharRightBtn2" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot2/CharacterNav2" unique_id=1180092400]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "▶" text = "▶"
[node name="CharacterNameLabel2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2"] [node name="CharacterNameLabel2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2" unique_id=1167438266]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -491,46 +491,46 @@ theme_override_font_sizes/font_size = 14
text = "Bob" text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="ReadyStatus2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2"] [node name="ReadyStatus2" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot2" unique_id=1248116760]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "NOT READY" text = "NOT READY"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="PlayerSlot3" type="VBoxContainer" parent="LobbyPanel/PlayersContainer"] [node name="PlayerSlot3" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=1033758492]
visible = false visible = false
custom_minimum_size = Vector2(180, 0) custom_minimum_size = Vector2(180, 0)
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
alignment = 1 alignment = 1
[node name="PlayerName3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3"] [node name="PlayerName3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3" unique_id=1647715021]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "Player 3" text = "Player 3"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="CharacterPreview3" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot3"] [node name="CharacterPreview3" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot3" unique_id=403530031]
custom_minimum_size = Vector2(140, 140) custom_minimum_size = Vector2(140, 140)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
expand_mode = 1 expand_mode = 1
stretch_mode = 5 stretch_mode = 5
[node name="CharacterNav3" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot3"] [node name="CharacterNav3" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot3" unique_id=123399758]
visible = false visible = false
layout_mode = 2 layout_mode = 2
alignment = 1 alignment = 1
[node name="CharLeftBtn3" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3"] [node name="CharLeftBtn3" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3" unique_id=1176396171]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "◀" text = "◀"
[node name="CharacterName3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3"] [node name="CharacterName3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3" unique_id=1507567643]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -539,13 +539,13 @@ text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="CharRightBtn3" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3"] [node name="CharRightBtn3" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot3/CharacterNav3" unique_id=1782180564]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "▶" text = "▶"
[node name="CharacterNameLabel3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3"] [node name="CharacterNameLabel3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3" unique_id=1700371004]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -553,46 +553,46 @@ theme_override_font_sizes/font_size = 14
text = "Bob" text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="ReadyStatus3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3"] [node name="ReadyStatus3" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot3" unique_id=822843162]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "NOT READY" text = "NOT READY"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="PlayerSlot4" type="VBoxContainer" parent="LobbyPanel/PlayersContainer"] [node name="PlayerSlot4" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=62963750]
visible = false visible = false
custom_minimum_size = Vector2(180, 0) custom_minimum_size = Vector2(180, 0)
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
alignment = 1 alignment = 1
[node name="PlayerName4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4"] [node name="PlayerName4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4" unique_id=601920855]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
text = "Player 4" text = "Player 4"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="CharacterPreview4" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot4"] [node name="CharacterPreview4" type="TextureRect" parent="LobbyPanel/PlayersContainer/PlayerSlot4" unique_id=1413323802]
custom_minimum_size = Vector2(140, 140) custom_minimum_size = Vector2(140, 140)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
expand_mode = 1 expand_mode = 1
stretch_mode = 5 stretch_mode = 5
[node name="CharacterNav4" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot4"] [node name="CharacterNav4" type="HBoxContainer" parent="LobbyPanel/PlayersContainer/PlayerSlot4" unique_id=1446657254]
visible = false visible = false
layout_mode = 2 layout_mode = 2
alignment = 1 alignment = 1
[node name="CharLeftBtn4" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4"] [node name="CharLeftBtn4" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4" unique_id=1004737490]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "◀" text = "◀"
[node name="CharacterName4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4"] [node name="CharacterName4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4" unique_id=1644341872]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -601,13 +601,13 @@ text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="CharRightBtn4" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4"] [node name="CharRightBtn4" type="Button" parent="LobbyPanel/PlayersContainer/PlayerSlot4/CharacterNav4" unique_id=1065247855]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "▶" text = "▶"
[node name="CharacterNameLabel4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4"] [node name="CharacterNameLabel4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4" unique_id=1051481010]
custom_minimum_size = Vector2(80, 0) custom_minimum_size = Vector2(80, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1) theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
@@ -615,14 +615,14 @@ theme_override_font_sizes/font_size = 14
text = "Bob" text = "Bob"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="ReadyStatus4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4"] [node name="ReadyStatus4" type="Label" parent="LobbyPanel/PlayersContainer/PlayerSlot4" unique_id=1335401655]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "NOT READY" text = "NOT READY"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="AreaSelector" type="HBoxContainer" parent="LobbyPanel"] [node name="AreaSelector" type="HBoxContainer" parent="LobbyPanel" unique_id=696178336]
clip_contents = true clip_contents = true
layout_mode = 1 layout_mode = 1
anchors_preset = 7 anchors_preset = 7
@@ -637,19 +637,19 @@ offset_bottom = -87.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 0 grow_vertical = 0
[node name="AreaLabel" type="Label" parent="LobbyPanel/AreaSelector"] [node name="AreaLabel" type="Label" parent="LobbyPanel/AreaSelector" unique_id=1925038296]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 13 theme_override_font_sizes/font_size = 13
text = "AREA: " text = "AREA: "
[node name="AreaLeftBtn" type="Button" parent="LobbyPanel/AreaSelector"] [node name="AreaLeftBtn" type="Button" parent="LobbyPanel/AreaSelector" unique_id=285538854]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "◀" text = "◀"
[node name="AreaName" type="Label" parent="LobbyPanel/AreaSelector"] [node name="AreaName" type="Label" parent="LobbyPanel/AreaSelector" unique_id=178083908]
custom_minimum_size = Vector2(100, 0) custom_minimum_size = Vector2(100, 0)
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1) theme_override_colors/font_color = Color(0.647, 0.996, 0.224, 1)
@@ -658,13 +658,13 @@ text = "Desert"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="AreaRightBtn" type="Button" parent="LobbyPanel/AreaSelector"] [node name="AreaRightBtn" type="Button" parent="LobbyPanel/AreaSelector" unique_id=1602714055]
custom_minimum_size = Vector2(40, 36) custom_minimum_size = Vector2(40, 36)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 18 theme_override_font_sizes/font_size = 18
text = "▶" text = "▶"
[node name="BottomBar" type="HBoxContainer" parent="LobbyPanel"] [node name="BottomBar" type="HBoxContainer" parent="LobbyPanel" unique_id=1285858966]
layout_mode = 1 layout_mode = 1
anchors_preset = 12 anchors_preset = 12
anchor_top = 1.0 anchor_top = 1.0
@@ -678,31 +678,31 @@ grow_horizontal = 2
grow_vertical = 0 grow_vertical = 0
theme_override_constants/separation = 20 theme_override_constants/separation = 20
[node name="LeaveBtn" type="Button" parent="LobbyPanel/BottomBar"] [node name="LeaveBtn" type="Button" parent="LobbyPanel/BottomBar" unique_id=1447825960]
custom_minimum_size = Vector2(120, 44) custom_minimum_size = Vector2(120, 44)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 14 theme_override_font_sizes/font_size = 14
text = "LEAVE" text = "LEAVE"
[node name="Spacer" type="Control" parent="LobbyPanel/BottomBar"] [node name="Spacer" type="Control" parent="LobbyPanel/BottomBar" unique_id=1050617828]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="ReadyBtn" type="Button" parent="LobbyPanel/BottomBar"] [node name="ReadyBtn" type="Button" parent="LobbyPanel/BottomBar" unique_id=2026272478]
custom_minimum_size = Vector2(140, 50) custom_minimum_size = Vector2(140, 50)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
toggle_mode = true toggle_mode = true
text = "READY" text = "READY"
[node name="StartGameBtn" type="Button" parent="LobbyPanel/BottomBar"] [node name="StartGameBtn" type="Button" parent="LobbyPanel/BottomBar" unique_id=121485973]
custom_minimum_size = Vector2(140, 50) custom_minimum_size = Vector2(140, 50)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 16 theme_override_font_sizes/font_size = 16
disabled = true disabled = true
text = "MATCH" text = "MATCH"
[node name="StatusLabel" type="Label" parent="LobbyPanel"] [node name="StatusLabel" type="Label" parent="LobbyPanel" unique_id=1206438822]
layout_mode = 1 layout_mode = 1
anchors_preset = 7 anchors_preset = 7
anchor_left = 0.5 anchor_left = 0.5
@@ -719,13 +719,13 @@ theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
horizontal_alignment = 1 horizontal_alignment = 1
[node name="PlayerList" type="ItemList" parent="LobbyPanel"] [node name="PlayerList" type="ItemList" parent="LobbyPanel" unique_id=1932007905]
visible = false visible = false
layout_mode = 0 layout_mode = 0
offset_right = 40.0 offset_right = 40.0
offset_bottom = 40.0 offset_bottom = 40.0
[node name="StatusBar" type="PanelContainer" parent="."] [node name="StatusBar" type="PanelContainer" parent="." unique_id=1333732958]
layout_mode = 1 layout_mode = 1
anchors_preset = 12 anchors_preset = 12
anchor_top = 1.0 anchor_top = 1.0
@@ -738,14 +738,14 @@ offset_bottom = -44.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 0 grow_vertical = 0
[node name="ConnectionStatus" type="Label" parent="StatusBar"] [node name="ConnectionStatus" type="Label" parent="StatusBar" unique_id=1991909918]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1) theme_override_colors/font_color = Color(0.69, 0.529, 0.357, 1)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "NOT CONNECTED" text = "NOT CONNECTED"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="VersionLabel" type="Label" parent="."] [node name="VersionLabel" type="Label" parent="." unique_id=351711152]
layout_mode = 1 layout_mode = 1
anchors_preset = 3 anchors_preset = 3
anchor_left = 1.0 anchor_left = 1.0
+1334 -1328
View File
File diff suppressed because one or more lines are too long
+13
View File
@@ -22,6 +22,9 @@ var original_movement_range: int = 1
var is_attack_mode: bool = false: var is_attack_mode: bool = false:
set(value): set(value):
if is_attack_mode == value:
return # Prevent infinite recursion / redundant updates
is_attack_mode = value is_attack_mode = value
# Visual feedback for attack mode (Red Tint) # Visual feedback for attack mode (Red Tint)
if is_attack_mode: if is_attack_mode:
@@ -29,6 +32,16 @@ var is_attack_mode: bool = false:
else: else:
_apply_tint_recursive(self, Color.WHITE) _apply_tint_recursive(self, Color.WHITE)
# Sync to others if we are the authority
if is_multiplayer_authority():
rpc("sync_attack_mode", is_attack_mode)
@rpc("any_peer", "call_local", "reliable")
func sync_attack_mode(state: bool):
# We WANT to trigger the setter to apply visuals on clients
# Using self.var triggers setter in GDScript
self.is_attack_mode = state
@export var is_bot: bool = false @export var is_bot: bool = false
@export var enhanced_gridmap_path: NodePath = "/root/Main/EnhancedGridMap" @export var enhanced_gridmap_path: NodePath = "/root/Main/EnhancedGridMap"
+80 -3
View File
@@ -130,6 +130,13 @@ func _run_ai_tick():
print("[BotController] Action Taken: Put (Priority)") print("[BotController] Action Taken: Put (Priority)")
return return
# Priority 0: Attack Mode (Aggressive Chase)
if actor.get("is_attack_mode"):
print("[BotController] Attack Mode Active! Hunting targets...")
if await _try_attack_chase():
print("[BotController] Action Taken: Attack Pursuit")
return
# Priority 1: Use power-up sabotage if conditions are met # Priority 1: Use power-up sabotage if conditions are met
if await _try_use_powerup(): if await _try_use_powerup():
print("[BotController] Action Taken: PowerUp") print("[BotController] Action Taken: PowerUp")
@@ -176,6 +183,10 @@ func _try_use_powerup() -> bool:
if not powerup_manager or not powerup_manager.can_use_special(): if not powerup_manager or not powerup_manager.can_use_special():
return false return false
# PREVENT LOOP: If already in Attack Mode, do not try to use it again
if actor.get("is_attack_mode"):
return false
# Evaluate sabotage opportunity # Evaluate sabotage opportunity
var eval = strategic_planner.evaluate_sabotage_opportunity() var eval = strategic_planner.evaluate_sabotage_opportunity()
if not eval.should_sabotage: if not eval.should_sabotage:
@@ -185,7 +196,21 @@ func _try_use_powerup() -> bool:
_is_processing_action = true _is_processing_action = true
_current_action = "sabotaging" _current_action = "sabotaging"
var success = powerup_manager.use_special_effect() # 50/50 Chance: Attack Mode vs Spawn Item
var success = false
if rng.randf() > 0.5:
# Attack Mode
success = powerup_manager.use_special_effect()
print("[BotController] %s chose ATTACK MODE." % actor.name)
else:
# Spawn Item (if supported)
if powerup_manager.has_method("spawn_boost_reward"):
success = powerup_manager.spawn_boost_reward()
print("[BotController] %s chose SPAWN ITEM." % actor.name)
else:
# Fallback to attack mode if method missing
success = powerup_manager.use_special_effect()
if success: if success:
print("[BotController] %s used power-up (reason: %s)" % [actor.name, eval.reason]) print("[BotController] %s used power-up (reason: %s)" % [actor.name, eval.reason])
NotificationManager.send_message(actor, NotificationManager.MESSAGES.USED_SPECIAL_POWER, NotificationManager.MessageType.POWERUP) NotificationManager.send_message(actor, NotificationManager.MESSAGES.USED_SPECIAL_POWER, NotificationManager.MessageType.POWERUP)
@@ -197,6 +222,58 @@ func _try_use_powerup() -> bool:
_current_action = "idle" _current_action = "idle"
return success return success
# =============================================================================
# Attack Mode Logic (Aggressive Chase)
# =============================================================================
func _try_attack_chase() -> bool:
"""Find nearest player and move towards them to RAM them."""
var victim = _find_nearest_victim()
if not victim:
# No victim found? Just behave normally (grab tiles etc)
return false
# Pathfind to victim
var path = enhanced_gridmap.find_path(
Vector2(actor.current_position),
Vector2(victim.current_position),
0,
false,
false
)
if path.size() >= 2:
var next_step = Vector2i(path[1].x, path[1].y)
# Move to next step (If occupied by victim, movement_manager will trigger PUSH)
if actor.movement_manager.simple_move_to(next_step):
_is_processing_action = true
_current_action = "attacking"
await _wait_with_variance(action_delay) # Shorter delay for attacks? perhaos
if not is_instance_valid(self): return true
_is_processing_action = false
_current_action = "idle"
return true
return false
func _find_nearest_victim() -> Node3D:
var best_dist = 9999.0
var best_victim = null
var players = get_tree().get_nodes_in_group("Players")
for p in players:
if p == actor or p.is_in_group("Spectators"):
continue
# Dist check
var dist = abs(p.current_position.x - actor.current_position.x) + abs(p.current_position.y - actor.current_position.y)
if dist < best_dist:
best_dist = dist
best_victim = p
return best_victim
# ============================================================================= # =============================================================================
# Grab Tiles # Grab Tiles
# ============================================================================= # =============================================================================
@@ -550,8 +627,8 @@ func _handle_goal_completion():
goals_cycle_manager.on_goal_completed(actor, time_remaining) goals_cycle_manager.on_goal_completed(actor, time_remaining)
var powerup_manager = actor.get_node_or_null("PowerUpManager") var powerup_manager = actor.get_node_or_null("PowerUpManager")
if powerup_manager: # if powerup_manager:
powerup_manager.add_goal_completion_reward() # powerup_manager.add_goal_completion_reward()
print("[BotController] %s COMPLETED GOAL!" % actor.name) print("[BotController] %s COMPLETED GOAL!" % actor.name)
@@ -0,0 +1 @@
uid://c2n4v6brcjtwn
+7 -4
View File
@@ -133,12 +133,15 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
# Wall/Blocked -> Stagger in place # Wall/Blocked -> Stagger in place
other_player.rpc("apply_stagger", 1.5) other_player.rpc("apply_stagger", 1.5)
# 4. Consume Boost # 4. Consume Boost (Full) - One hit per charge
if player.powerup_manager: if player.powerup_manager:
player.powerup_manager.reset_boost() # Consume all available boost to force a full recharge cycle
player.powerup_manager.consume_boost(100.0)
# 5. Reset Attack Mode # 5. Attack Mode Persistence
player.is_attack_mode = false # logic moved to consume_boost: checks if <= 0 then disables.
# So we do NOT force disable here.
# player.is_attack_mode = false
return true return true
+1 -1
View File
@@ -683,7 +683,7 @@ func _check_goal_completion():
if player.race_manager.check_pattern_match(): if player.race_manager.check_pattern_match():
print("[PlayerboardManager] Goal completed for player %s!" % player.name) print("[PlayerboardManager] Goal completed for player %s!" % player.name)
# Award power-up bar for goal completion # Level up boost difficulty on goal completion
var powerup_manager = player.get_node_or_null("PowerUpManager") var powerup_manager = player.get_node_or_null("PowerUpManager")
if powerup_manager: if powerup_manager:
powerup_manager.add_goal_completion_reward() powerup_manager.add_goal_completion_reward()
+63 -13
View File
@@ -3,13 +3,17 @@ extends Node
# PowerUpManager - Handles Boost Meter (Time-based logic) # PowerUpManager - Handles Boost Meter (Time-based logic)
# Note: Inventory logic is now in SpecialTilesManager + PlayerboardManager # Note: Inventory logic is now in SpecialTilesManager + PlayerboardManager
const MAX_BOOST: float = 100.0 const MAX_BOOST: float = 100.0 # Fills to 100. Activation requires FULL bar (>= 100).
const BASE_FILL_RATE: float = 4.0 # 4 points per second baseline (25s to full) const BASE_FILL_RATE: float = 10.0 # 10 points per second (10s to full) - user requested faster/simpler
var player: Node3D var player: Node3D
var enhanced_gridmap: Node var enhanced_gridmap: Node
var goal_manager: Node var goal_manager: Node
# Progressive Difficulty Settings
const FILL_TIMES: Array = [2.0, 3.0, 4.0, 5.0, 6.0, 7.5, 8.5, 10.0] # Seconds to full for Lvl 1-8 (2s to 10s)
var current_level: int = 1
# Boost State # Boost State
var current_boost: float = 0.0 var current_boost: float = 0.0
@@ -49,7 +53,13 @@ func _process(delta):
# Use authority ID for lookup # Use authority ID for lookup
multiplier = goal_manager.get_boost_multiplier(player.get_multiplayer_authority()) multiplier = goal_manager.get_boost_multiplier(player.get_multiplayer_authority())
current_boost += BASE_FILL_RATE * multiplier * delta # Calculate Dynamic Fill Rate based on Level
# Level 1 (Index 0) -> Level 8 (Index 7)
var level_idx = clamp(current_level - 1, 0, FILL_TIMES.size() - 1)
var fill_time = FILL_TIMES[level_idx]
var current_rate = MAX_BOOST / fill_time # e.g. 100/10 = 10/s, 100/60 = 1.66/s
current_boost += current_rate * multiplier * delta
current_boost = min(current_boost, MAX_BOOST) current_boost = min(current_boost, MAX_BOOST)
# Update UI (Cast to int for compatibility with existing UI slider/bar) # Update UI (Cast to int for compatibility with existing UI slider/bar)
@@ -59,7 +69,7 @@ func _process(delta):
_on_boost_full() _on_boost_full()
func _on_boost_full(): func _on_boost_full():
player.is_attack_mode = true # player.is_attack_mode = true # Removed auto-activate
emit_signal("bar_filled") emit_signal("bar_filled")
NotificationManager.send_message(player, NotificationManager.MESSAGES.ATTACK_MODE_READY, NotificationManager.MessageType.POWERUP) NotificationManager.send_message(player, NotificationManager.MESSAGES.ATTACK_MODE_READY, NotificationManager.MessageType.POWERUP)
print("[PowerUp] Player %s Boost Full! Entering Attack Mode." % player.name) print("[PowerUp] Player %s Boost Full! Entering Attack Mode." % player.name)
@@ -69,7 +79,7 @@ func _on_boost_full():
func reset_boost(): func reset_boost():
current_boost = 0.0 current_boost = 0.0
player.is_attack_mode = false # player.is_attack_mode = false # Do not auto-disable here, managed by usage
emit_signal("points_changed", 0, int(MAX_BOOST)) emit_signal("points_changed", 0, int(MAX_BOOST))
emit_signal("boost_reset") emit_signal("boost_reset")
@@ -104,16 +114,52 @@ func get_fill_percentage() -> float:
return current_boost / MAX_BOOST return current_boost / MAX_BOOST
func can_use_special() -> bool: func can_use_special() -> bool:
return current_boost >= MAX_BOOST # Use small epsilon for float comparison to avoid "99.999" issues
return current_boost >= (MAX_BOOST - 0.1)
func enable_attack_mode():
"""Enable Attack Mode without consuming boost."""
player.is_attack_mode = true
NotificationManager.send_message(player, NotificationManager.MESSAGES.ATTACK_MODE_READY, NotificationManager.MessageType.POWERUP)
print("[PowerUp] Attack Mode Enabled (Free).")
func use_special_effect() -> bool: func use_special_effect() -> bool:
if not can_use_special(): if not can_use_special():
return false return false
# Consume boost # Enable Attack Mode explicitly
reset_boost() player.is_attack_mode = true
# Do NOT consume boost here. Boost acts as "fuel" for the attacks.
# Notification check handled by caller or signal
return true return true
func consume_boost(amount: float):
"""Consume a specific amount of boost."""
current_boost -= amount
if current_boost <= 0:
current_boost = 0.0
player.is_attack_mode = false # Out of fuel
emit_signal("boost_reset") # UI update for empty
print("[PowerUp] Boost depleted. Attack Mode OFF.")
emit_signal("points_changed", int(current_boost), int(MAX_BOOST))
if player.is_multiplayer_authority():
rpc("sync_boost", current_boost)
func spawn_boost_reward() -> bool:
"""Alternative Boost Usage: Spawn a PowerUp Tile properly."""
if not can_use_special():
return false
if player.special_tiles_manager and player.special_tiles_manager.has_method("spawn_powerups_around"):
player.special_tiles_manager.spawn_powerups_around(player.current_position)
reset_boost() # Consumes full bar
print("[PowerUp] %s used Boost to SPAWN ITEM." % player.name)
return true
return false
func acquire_smash_bonus(): func acquire_smash_bonus():
current_boost += 25.0 # Add 25% boost current_boost += 25.0 # Add 25% boost
current_boost = min(current_boost, MAX_BOOST) current_boost = min(current_boost, MAX_BOOST)
@@ -122,8 +168,12 @@ func acquire_smash_bonus():
_on_boost_full() _on_boost_full()
func add_goal_completion_reward(): func add_goal_completion_reward():
current_boost += 50.0 # Reward for completing goal """Called when player completes a goal board. Increases difficulty level."""
current_boost = min(current_boost, MAX_BOOST) current_level += 1
emit_signal("points_changed", int(current_boost), int(MAX_BOOST)) if current_level > 8:
if current_boost >= MAX_BOOST: current_level = 8
_on_boost_full()
var level_idx = clamp(current_level - 1, 0, FILL_TIMES.size() - 1)
print("[PowerUp] Player %s Completed Goal. Boost Level Up! Now: %d (Fill Time: %.1fs)" % [player.name, current_level, FILL_TIMES[level_idx]])
# Optional: Notify user of difficulty increase?
+49 -4
View File
@@ -11,6 +11,7 @@ var virtual_joystick: Control
var grab_button: Button var grab_button: Button
var put_button: Button var put_button: Button
var special_button: Button var special_button: Button
var spawn_boost_button: Button
var settings_button: Button var settings_button: Button
# Settings - persisted to config file # Settings - persisted to config file
@@ -23,7 +24,8 @@ var joystick_position: Vector2 = Vector2(120, -120) # Relative to bottom-left
var button_positions: Dictionary = { var button_positions: Dictionary = {
"grab": Vector2(-200, -240), # Relative to bottom-right "grab": Vector2(-200, -240), # Relative to bottom-right
"put": Vector2(-120, -160), "put": Vector2(-120, -160),
"special": Vector2(-200, -80) "special": Vector2(-200, -80),
"spawn_boost": Vector2(-120, -80)
} }
var button_scale: float = 1.0 var button_scale: float = 1.0
@@ -93,6 +95,7 @@ func _create_touch_ui():
grab_button = _find_or_create_action_button(container, "Grab", "👋", button_positions.grab) grab_button = _find_or_create_action_button(container, "Grab", "👋", button_positions.grab)
put_button = _find_or_create_action_button(container, "Put", "📦", button_positions.put) put_button = _find_or_create_action_button(container, "Put", "📦", button_positions.put)
special_button = _find_or_create_action_button(container, "Special", "", button_positions.special) special_button = _find_or_create_action_button(container, "Special", "", button_positions.special)
spawn_boost_button = _find_or_create_action_button(container, "SpawnBoost", "🚀", button_positions.spawn_boost)
# Create settings button (top-right corner) # Create settings button (top-right corner)
settings_button = container.get_node_or_null("SettingsBtn") settings_button = container.get_node_or_null("SettingsBtn")
@@ -203,6 +206,7 @@ func _on_button_pressed(button_name: String):
"Grab": btn = grab_button "Grab": btn = grab_button
"Put": btn = put_button "Put": btn = put_button
"Special": btn = special_button "Special": btn = special_button
"SpawnBoost": btn = spawn_boost_button
if btn: if btn:
var tween = create_tween() var tween = create_tween()
@@ -221,8 +225,32 @@ func _on_button_pressed(button_name: String):
"Special": "Special":
emit_signal("special_pressed") emit_signal("special_pressed")
var powerup_mgr = local_player.get_node_or_null("PowerUpManager") var powerup_mgr = local_player.get_node_or_null("PowerUpManager")
if powerup_mgr and powerup_mgr.has_method("use_special_effect"): if powerup_mgr:
powerup_mgr.use_special_effect() # Require Full Boost to Activate (User Request: "Connect to boost bar")
var can_use = powerup_mgr.can_use_special()
var boost_val = powerup_mgr.current_boost
print("[TouchControls] Special Pressed. Boost: %s, CanUse: %s" % [boost_val, can_use])
if can_use:
powerup_mgr.use_special_effect() # Sets is_attack_mode=true, Does NOT consume boost yet
else:
# Optional feedback for not ready?
pass
else:
print("[TouchControls] PowerUpManager missing on player")
"SpawnBoost":
var powerup_mgr = local_player.get_node_or_null("PowerUpManager")
if powerup_mgr:
var can_use = powerup_mgr.can_use_special()
var boost_val = powerup_mgr.current_boost
print("[TouchControls] SpawnBoost Pressed. Boost: %s, CanUse: %s" % [boost_val, can_use])
if can_use: # Check if boost is full
if local_player.special_tiles_manager and local_player.special_tiles_manager.has_method("spawn_powerups_around"):
local_player.special_tiles_manager.spawn_powerups_around(local_player.current_position)
powerup_mgr.reset_boost() # Consume the boost manually since we bypassed use_special_effect
else:
print("[TouchControls] PowerUpManager missing on player")
func _on_button_released(button_name: String): func _on_button_released(button_name: String):
var btn: Button var btn: Button
@@ -230,6 +258,7 @@ func _on_button_released(button_name: String):
"Grab": btn = grab_button "Grab": btn = grab_button
"Put": btn = put_button "Put": btn = put_button
"Special": btn = special_button "Special": btn = special_button
"SpawnBoost": btn = spawn_boost_button
if btn: if btn:
var tween = create_tween() var tween = create_tween()
@@ -268,7 +297,8 @@ func _load_settings():
var grab_pos = config.get_value("touch_controls", "grab_position", Vector2(-200, -240)) var grab_pos = config.get_value("touch_controls", "grab_position", Vector2(-200, -240))
var put_pos = config.get_value("touch_controls", "put_position", Vector2(-120, -160)) var put_pos = config.get_value("touch_controls", "put_position", Vector2(-120, -160))
var special_pos = config.get_value("touch_controls", "special_position", Vector2(-200, -80)) var special_pos = config.get_value("touch_controls", "special_position", Vector2(-200, -80))
button_positions = {"grab": grab_pos, "put": put_pos, "special": special_pos} var spawn_boost_pos = config.get_value("touch_controls", "spawn_boost_position", Vector2(-120, -80))
button_positions = {"grab": grab_pos, "put": put_pos, "special": special_pos, "spawn_boost": spawn_boost_pos}
# Apply loaded settings # Apply loaded settings
_apply_settings() _apply_settings()
@@ -286,6 +316,7 @@ func _save_settings():
config.set_value("touch_controls", "grab_position", button_positions.grab) config.set_value("touch_controls", "grab_position", button_positions.grab)
config.set_value("touch_controls", "put_position", button_positions.put) config.set_value("touch_controls", "put_position", button_positions.put)
config.set_value("touch_controls", "special_position", button_positions.special) config.set_value("touch_controls", "special_position", button_positions.special)
config.set_value("touch_controls", "spawn_boost_position", button_positions.spawn_boost)
var err = config.save(CONFIG_PATH) var err = config.save(CONFIG_PATH)
if err != OK: if err != OK:
@@ -331,6 +362,14 @@ func _apply_settings():
special_button.offset_right = button_positions.special.x + button_size special_button.offset_right = button_positions.special.x + button_size
special_button.offset_bottom = button_positions.special.y + button_size special_button.offset_bottom = button_positions.special.y + button_size
if spawn_boost_button:
spawn_boost_button.visible = buttons_visible
spawn_boost_button.scale = Vector2(button_scale, button_scale)
spawn_boost_button.offset_left = button_positions.spawn_boost.x
spawn_boost_button.offset_top = button_positions.spawn_boost.y
spawn_boost_button.offset_right = button_positions.spawn_boost.x + button_size
spawn_boost_button.offset_bottom = button_positions.spawn_boost.y + button_size
# Force layer update # Force layer update
visible = true visible = true
@@ -375,6 +414,12 @@ func set_button_position(button_name: String, new_position: Vector2):
special_button.offset_top = new_position.y special_button.offset_top = new_position.y
special_button.offset_right = new_position.x + button_size special_button.offset_right = new_position.x + button_size
special_button.offset_bottom = new_position.y + button_size special_button.offset_bottom = new_position.y + button_size
"spawn_boost":
if spawn_boost_button:
spawn_boost_button.offset_left = new_position.x
spawn_boost_button.offset_top = new_position.y
spawn_boost_button.offset_right = new_position.x + button_size
spawn_boost_button.offset_bottom = new_position.y + button_size
func get_button_positions() -> Dictionary: func get_button_positions() -> Dictionary:
"""Get current button positions for settings UI.""" """Get current button positions for settings UI."""
+6 -2
View File
@@ -271,7 +271,10 @@ func setup_powerup_bar_ui(main_node):
func update_powerup_bar(current_points: int, _max_points: int): func update_powerup_bar(current_points: int, _max_points: int):
"""Update battery segments based on current power-up points.""" """Update battery segments based on current power-up points."""
var bars_filled = current_points / 4 # 4 points per bar # 4 Segments total. Max Boost is 100. So each segment represents 25 points.
# Was previously dividing by 4, causing it to fill at 16 points!
var points_per_segment = _max_points / 4.0
var bars_filled = int(current_points / points_per_segment)
for i in range(powerup_segments.size()): for i in range(powerup_segments.size()):
var segment = powerup_segments[i] var segment = powerup_segments[i]
@@ -289,7 +292,8 @@ func update_powerup_bar(current_points: int, _max_points: int):
var _previous_bars: int = 0 var _previous_bars: int = 0
func _on_powerup_points_changed(current: int, max_points: int): func _on_powerup_points_changed(current: int, max_points: int):
var new_bars = current / 4 # Calculate based on max points (100) / 4 segments = 25 points per segment
var new_bars = int(current / 25.0)
# Detect if a new bar was filled # Detect if a new bar was filled
if new_bars > _previous_bars and powerup_bar: if new_bars > _previous_bars and powerup_bar: