feat : mobile input controller

This commit is contained in:
2026-04-13 18:15:49 +08:00
parent a478e3fc2e
commit a592eb1de0
25 changed files with 771 additions and 2058 deletions
@@ -14,18 +14,30 @@
[ext_resource type="Texture2D" uid="uid://dpkx1a780pvwv" path="res://assets/textures/tile_diamond.png" id="10_sx8rm"]
[ext_resource type="BoxMesh" uid="uid://fy4bhoeii40c" path="res://addons/enhanced_gridmap/meshlibrary/tile_safe_zone.tres" id="10_uwjsj"]
[ext_resource type="BoxMesh" uid="uid://b5cc3prem52r6" path="res://addons/enhanced_gridmap/meshlibrary/tile_freeze.tres" id="11_pgnbl"]
[ext_resource type="BoxMesh" path="res://addons/enhanced_gridmap/meshlibrary/tile_non_walkable.tres" id="11_uwjsj"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_5d0gc"]
load_path = "res://.godot/imported/tile_heart.png-deeef50755ca225f028608dfd16900e6.s3tc.ctex"
[ext_resource type="BoxMesh" uid="uid://dcjdwbffgtutt" path="res://addons/enhanced_gridmap/meshlibrary/tile_non_walkable.tres" id="11_uwjsj"]
[ext_resource type="Texture2D" uid="uid://cdnxwlysxnujd" path="res://assets/textures/tile_heart.png" id="12_heart_tex"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uxput"]
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_texture = SubResource("CompressedTexture2D_5d0gc")
albedo_texture = ExtResource("12_heart_tex")
[sub_resource type="ArrayMesh" id="ArrayMesh_pgnbl"]
[sub_resource type="ArrayMesh" id="ArrayMesh_r2l4m"]
_surfaces = [{
"aabb": AABB(-0.282176, -0.000324821, -0.282176, 0.564351, 0.050792, 0.564351),
"format": 34896613377,
"index_count": 36,
"index_data": PackedByteArray("BwAEAAUABwAGAAQABQACAAMABQAEAAIAAAAEAAYAAAACAAQABQABAAcABQADAAEAAgABAAMAAgAAAAEAAQAGAAcAAQAAAAYA"),
"name": "boost",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 8,
"vertex_data": PackedByteArray("AAD/////AAAAAP7/AAAAAP///////wAA///+/wAAAAD//wAA//8AAP//AAAAAAAAAAAAAP//AAAAAAAAAAAAAA==")
}]
blend_shape_mode = 0
[sub_resource type="ArrayMesh" id="ArrayMesh_uwjsj"]
resource_name = "tile_heart"
_surfaces = [{
"aabb": AABB(-0.282176, -0.000324821, -0.282176, 0.564351, 0.050792, 0.564351),
@@ -41,6 +53,7 @@ _surfaces = [{
"vertex_data": PackedByteArray("AAD//////78AAP//////vwAA/////6oqAAD+/wAAAAAAAP7/AAD/vwAA/v8AAKoq/////////7//////////v//////////////+/wAAAAD///7/AAD/v////v8AAP////8AAP///7///wAA////P///AAD///////8AAAAAAAD//wAAAAD/P///AAAAAP//AAAAAP///78AAAAA////PwAAAAD//6oqAAAAAAAAAAAAAAAAAAD/PwAAAAAAAKoq/////////39U1VTV/7//v////39U1VTV/////////3//v/9//7//v////3//v/9//////wAA/3//v/9//7//vwAA/3//v/9//////wAA/39U1VTV/7//vwAA/39U1VTV")
}]
blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_r2l4m")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2vf4e"]
resource_name = "boost"
@@ -116,7 +129,7 @@ item/6/shapes = []
item/6/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
item/6/navigation_layers = 1
item/7/name = "tile_heart"
item/7/mesh = SubResource("ArrayMesh_pgnbl")
item/7/mesh = SubResource("ArrayMesh_uwjsj")
item/7/mesh_transform = Transform3D(0.9, 0, 0, 0, 0.9, 0, 0, 0, 0.9, 0, 0.1, 0)
item/7/mesh_cast_shadow = 1
item/7/shapes = []
+1 -2
View File
@@ -1,4 +1,4 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://dkve87aabsr81"]
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dkve87aabsr81"]
[ext_resource type="Texture2D" uid="uid://dkr3oes2jk8ar" path="res://assets/textures/tile_coin.png" id="1_5v71j"]
@@ -6,5 +6,4 @@
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_color = Color(0.91, 0.91, 0.91, 0.45098)
albedo_texture = ExtResource("1_5v71j")
+1 -2
View File
@@ -1,4 +1,4 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://47fnj6ims3ro"]
[gd_resource type="StandardMaterial3D" format=3 uid="uid://47fnj6ims3ro"]
[ext_resource type="Texture2D" uid="uid://cdnxwlysxnujd" path="res://assets/textures/tile_heart.png" id="1_mmk6n"]
@@ -6,5 +6,4 @@
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_color = Color(0.91, 0.91, 0.91, 0.45098)
albedo_texture = ExtResource("1_mmk6n")
+1 -2
View File
@@ -1,4 +1,4 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://r3o6mc6xbon"]
[gd_resource type="StandardMaterial3D" format=3 uid="uid://r3o6mc6xbon"]
[ext_resource type="Texture2D" uid="uid://ho2ba1pl835k" path="res://assets/textures/tile_star.png" id="1_l62is"]
@@ -6,5 +6,4 @@
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_color = Color(0.91, 0.91, 0.91, 0.45098)
albedo_texture = ExtResource("1_l62is")
+2 -3
View File
@@ -1,13 +1,12 @@
[gd_resource type="ArrayMesh" format=4 uid="uid://b5ta7tcw0iscd"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_po712"]
load_path = "res://.godot/imported/tile_coin.png-07bdc9862d055beeb72a967a0094a5c7.s3tc.ctex"
[ext_resource type="Texture2D" uid="uid://dkr3oes2jk8ar" path="res://assets/textures/tile_coin.png" id="1_coin_tex"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7ya48"]
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_texture = SubResource("CompressedTexture2D_po712")
albedo_texture = ExtResource("1_coin_tex")
[resource]
resource_name = "tile_diamond"
+2 -4
View File
@@ -1,14 +1,12 @@
[gd_resource type="ArrayMesh" format=4 uid="uid://36tgon3b60db"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_5d0gc"]
load_path = "res://.godot/imported/tile_heart.png-deeef50755ca225f028608dfd16900e6.s3tc.ctex"
[ext_resource type="Texture2D" uid="uid://cdnxwlysxnujd" path="res://assets/textures/tile_heart.png" id="1_heart_tex"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uxput"]
resource_name = "boost"
transparency = 1
cull_mode = 2
albedo_color = Color(0.91, 0.91, 0.91, 0.45098)
albedo_texture = SubResource("CompressedTexture2D_5d0gc")
albedo_texture = ExtResource("1_heart_tex")
[sub_resource type="ArrayMesh" id="ArrayMesh_r2l4m"]
_surfaces = [{
@@ -1,4 +1,6 @@
[gd_resource type="CompressedTexture2D" format=3 uid="uid://b41afev4wfdrf"]
[gd_resource type="Texture" format=3 uid="uid://b41afev4wfdrf"]
[ext_resource type="Texture2D" path="res://assets/textures/player_board_and_blue_print/tiles_slot.png" id="1"]
[resource]
load_path = "res://.godot/imported/tiles_slot.png-e539385cf7c9354d657e81e23ace6c2b.s3tc.ctex"
load_path = "res://assets/textures/player_board_and_blue_print/tiles_slot.png"
+5 -5
View File
@@ -80,7 +80,7 @@ custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="build/tekton-dash-armageddon-v.2.1.apk"
export_path="build/tekton-dash-armageddon-v.2.1.3.apk"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
@@ -111,7 +111,7 @@ architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=2
version/name="2.1"
version/name="2.1.2"
package/unique_name="com.danchiego.$genname"
package/name="Tekton Dash Armageddon"
package/signed=true
@@ -148,7 +148,7 @@ permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_media_location=false
permissions/access_mock_location=false
permissions/access_network_state=false
permissions/access_network_state=true
permissions/access_surface_flinger=false
permissions/access_wifi_state=false
permissions/account_manager=false
@@ -166,7 +166,7 @@ permissions/bind_remoteviews=false
permissions/bind_text_service=false
permissions/bind_vpn_service=false
permissions/bind_wallpaper=false
permissions/bluetooth=false
permissions/bluetooth=true
permissions/bluetooth_admin=false
permissions/bluetooth_privileged=false
permissions/brick=false
@@ -209,7 +209,7 @@ permissions/install_location_provider=false
permissions/install_packages=false
permissions/install_shortcut=false
permissions/internal_system_window=false
permissions/internet=false
permissions/internet=true
permissions/kill_background_processes=false
permissions/location_hardware=false
permissions/manage_accounts=false
+63
View File
@@ -0,0 +1,63 @@
import sys
import re
file_path = 'c:/Users/beng/Godot/Projects/tekton-enet/scenes/main.tscn'
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
interaction_idx = -1
for i, line in enumerate(lines):
if line.startswith('[node name="InteractionBtn" type="VBoxContainer"'):
interaction_idx = i
break
if interaction_idx != -1:
for i in range(interaction_idx, interaction_idx + 10):
if lines[i].startswith('offset_bottom = '):
lines[i] = 'offset_bottom = 282.9999\n'
break
power_btn_start = -1
power_btn_end = -1
for i, line in enumerate(lines):
if line.startswith('[node name="PowerUpBtn" type="Button" parent="TouchLayer/TouchControls/PowerUpInventoryUI"'):
power_btn_start = i
# Need to check original parent too in case the earlier modification didn't change this string perfectly, wait!
# Ah, PowerUpBtn parent was originally "PowerUpInventoryUI". I did change PowerUpInventoryUI's parent... but did I change PowerUpBtn's parent text in `.tscn`? NO! PowerUpBtn is still `parent="PowerUpInventoryUI"`.
if line.startswith('[node name="PowerUpBtn" type="Button" parent="PowerUpInventoryUI"'):
power_btn_start = i
if power_btn_start != -1:
for i in range(power_btn_start+1, len(lines)):
if lines[i].startswith('[node '):
power_btn_end = i
break
if power_btn_end == -1:
power_btn_end = len(lines)
insert_target_start = -1
if interaction_idx != -1:
for i in range(interaction_idx + 1, len(lines)):
if lines[i].startswith('[node '):
if 'parent="TouchLayer/TouchControls/InteractionBtn"' in lines[i]:
pass
else:
insert_target_start = i
break
if power_btn_start != -1 and insert_target_start != -1:
block = lines[power_btn_start:power_btn_end]
block[0] = block[0].replace('parent="PowerUpInventoryUI"', 'parent="TouchLayer/TouchControls/InteractionBtn"')
del lines[power_btn_start:power_btn_end]
if insert_target_start > power_btn_end:
insert_target_start -= (power_btn_end - power_btn_start)
lines = lines[:insert_target_start] + block + lines[insert_target_start:]
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(lines)
print('Successfully moved PowerUpBtn and resized InteractionBtn')
else:
print(f'Failed to find targets: btn_start={power_btn_start}, insert_target={insert_target_start}, interaction_idx={interaction_idx}')
+49
View File
@@ -0,0 +1,49 @@
import sys
file_path = 'c:/Users/beng/Godot/Projects/tekton-enet/scenes/main.tscn'
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
power_up_ui_start = -1
power_up_ui_end = -1
touch_controls_idx = -1
for i, line in enumerate(lines):
if line.startswith('[node name="PowerUpInventoryUI"'):
power_up_ui_start = i
elif power_up_ui_start != -1 and line.startswith('[node ') and power_up_ui_end == -1:
if 'parent="PowerUpInventoryUI"' not in line:
power_up_ui_end = i
if line.startswith('[node name="TouchControls" type="Control" parent="TouchLayer"'):
touch_controls_idx = i
if power_up_ui_end == -1:
power_up_ui_end = len(lines)
if power_up_ui_start != -1 and touch_controls_idx != -1:
# Extract the block
block = lines[power_up_ui_start:power_up_ui_end]
# Modify the parent
block[0] = block[0].replace('parent="."', 'parent="TouchLayer/TouchControls"')
# Remove from original location
del lines[power_up_ui_start:power_up_ui_end]
# Adjust touch_controls_idx if it was after the removed block
if touch_controls_idx > power_up_ui_end:
touch_controls_idx -= (power_up_ui_end - power_up_ui_start)
# Find end of TouchControls block/properties to insert
insert_idx = touch_controls_idx + 1
while insert_idx < len(lines) and not lines[insert_idx].startswith('['):
insert_idx += 1
lines = lines[:insert_idx] + block + lines[insert_idx:]
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(lines)
print('Successfully moved PowerUpInventoryUI to TouchLayer/TouchControls')
else:
print(f'Failed to find nodes: star={power_up_ui_start}, touch={touch_controls_idx}')
+6 -3
View File
@@ -15,7 +15,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application]
config/name="Tekton Dash Armageddon"
config/version="2.1"
config/version="2.1.2"
run/main_scene="res://scenes/ui/login_screen.tscn"
config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg"
@@ -43,8 +43,6 @@ AdminManager="*res://scripts/managers/admin_manager.gd"
window/size/viewport_width=1366
window/size/viewport_height=720
window/size/window_width_override=1024
window/size/window_height_override=576
window/stretch/mode="viewport"
[editor_plugins]
@@ -112,26 +110,31 @@ move_southwest={
action_grab={
"deadzone": 0.5,
"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":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
action_put={
"deadzone": 0.5,
"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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
]
}
action_grab_tekton={
"deadzone": 0.5,
"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":71,"physical_keycode":0,"key_label":0,"unicode":103,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":5,"pressure":0.0,"pressed":false,"script":null)
]
}
action_knock_tekton={
"deadzone": 0.5,
"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":66,"physical_keycode":0,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
}
+1 -1
View File
@@ -714,7 +714,7 @@ func _setup_client_game():
print("Client: Configured local player ", my_id)
# ALWAYS setup PowerUpUI when we have the local player, just in case
var powerup_ui = get_node_or_null("PowerUpInventoryUI")
var powerup_ui = get_node_or_null("TouchLayer/TouchControls/PowerUpInventoryUI")
if powerup_ui:
powerup_ui.setup(player_character)
print("Client: PowerUpInventoryUI setup forced for ", my_id)
+47 -51
View File
@@ -113,7 +113,7 @@ auto_randomize = true
start_item = 2
end_item = 3
immutable_items = Array[int]([4])
metadata/_editor_floor_ = Vector3(0, 0, 0)
metadata/_editor_floor_ = Vector3(0, 5, 0)
[node name="Camera3D200" type="Camera3D" parent="." unique_id=1763366951]
transform = Transform3D(1, 0, 0, 0, 0.5077037, 0.86153173, 0, -0.86153173, 0.5077037, 7, 32.3, 25.8)
@@ -1245,13 +1245,13 @@ clip_contents = true
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -285.99988
offset_top = 96.000015
offset_right = 174.00012
offset_bottom = 611.0
offset_left = -252.0
offset_top = 90.0
offset_right = 208.0
offset_bottom = 733.0
grow_horizontal = 0
rotation = 0.10297442
scale = Vector2(0.6, 0.6)
scale = Vector2(0.5, 0.5)
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxEmpty_c6pm6")
@@ -1609,8 +1609,23 @@ layout_mode = 2
custom_minimum_size = Vector2(25, 25)
layout_mode = 2
[node name="PowerUpInventoryUI" type="Control" parent="." unique_id=1105620089]
[node name="TouchLayer" type="CanvasLayer" parent="." unique_id=1234512345]
layer = 103
[node name="TouchControls" type="Control" parent="TouchLayer" unique_id=1539594058]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = 318.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme = ExtResource("18_pm3ni")
script = ExtResource("touch_manager")
[node name="PowerUpInventoryUI" type="Control" parent="TouchLayer/TouchControls" unique_id=1105620089]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
@@ -1626,54 +1641,25 @@ rotation = -0.10297442
theme = ExtResource("18_pm3ni")
script = ExtResource("powerup_ui_script")
[node name="PowerUpBtn" type="Button" parent="PowerUpInventoryUI" unique_id=1549270030]
layout_mode = 0
offset_left = 0.78915405
offset_top = 2.0920486
offset_right = 76.5548
offset_bottom = 79.51765
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("26_2f3dj")
flat = true
icon_alignment = 1
expand_icon = true
[node name="TouchLayer" type="CanvasLayer" parent="." unique_id=1234512345]
[node name="TouchControls" type="Control" parent="TouchLayer" unique_id=1539594058]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = 318.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme = ExtResource("18_pm3ni")
script = ExtResource("touch_manager")
[node name="VirtualJoystick" type="Control" parent="TouchLayer/TouchControls" unique_id=1983608919]
visible = false
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 120.0
offset_top = -280.0
offset_right = 280.0
offset_bottom = -120.0
offset_left = 58.0
offset_top = -285.0
offset_right = 311.0
offset_bottom = -32.0
grow_vertical = 0
script = ExtResource("virtual_joystick")
[node name="PowerBarBtn" type="VBoxContainer" parent="TouchLayer/TouchControls" unique_id=278736451]
layout_mode = 0
offset_left = 56.0
offset_top = 117.44364
offset_right = 138.0
offset_bottom = 284.44363
rotation = -0.10297442
offset_left = 1084.0
offset_top = 169.00003
offset_right = 1166.0
offset_bottom = 336.00003
rotation = 0.10297442
theme_override_constants/separation = 10
[node name="AttackModeBtn" type="Button" parent="TouchLayer/TouchControls/PowerBarBtn" unique_id=1380511463]
@@ -1697,11 +1683,11 @@ expand_icon = true
[node name="InteractionBtn" type="VBoxContainer" parent="TouchLayer/TouchControls" unique_id=1738242916]
layout_mode = 0
offset_left = 138.0
offset_top = 116.0
offset_right = 215.3921
offset_bottom = 190.84177
rotation = -0.10297442
offset_left = 1187.9999
offset_top = 179.0
offset_right = 1265.392
offset_bottom = 345.9999
rotation = 0.10297442
theme_override_constants/separation = 10
[node name="GrabBtn" type="Button" parent="TouchLayer/TouchControls/InteractionBtn" unique_id=914810452]
@@ -1725,6 +1711,16 @@ flat = true
icon_alignment = 1
expand_icon = true
[node name="PowerUpBtn" type="Button" parent="TouchLayer/TouchControls/InteractionBtn" unique_id=1549270030]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("26_2f3dj")
flat = true
icon_alignment = 1
expand_icon = true
[node name="PauseMenu" type="CanvasLayer" parent="." unique_id=181131829]
process_mode = 3
layer = 1002
@@ -1818,7 +1814,7 @@ text = "Quit Match"
[node name="HowToPlayPanel" type="CanvasLayer" parent="." unique_id=123456789]
process_mode = 3
layer = 11
layer = 102
visible = false
[node name="Background" type="ColorRect" parent="HowToPlayPanel" unique_id=123456790]
-1888
View File
@@ -1,1888 +0,0 @@
[gd_scene format=3 uid="uid://dxn87yj8qnfpp"]
[ext_resource type="MeshLibrary" uid="uid://kcv6ans86ug7" path="res://addons/enhanced_gridmap/meshlibrary/default.tres" id="1_110wo"]
[ext_resource type="Script" uid="uid://co1ads72by6na" path="res://scenes/main.gd" id="1_xcpe3"]
[ext_resource type="Script" uid="uid://bja8ixryvthu0" path="res://addons/enhanced_gridmap/enhanced_gridmap.gd" id="2_hbe1v"]
[ext_resource type="Environment" uid="uid://jbptgqvstei3" path="res://assets/main-environment.tres" id="4_ky38j"]
[ext_resource type="Shader" uid="uid://b4jor2qt7hwxn" path="res://assets/shaders/tilt_shader.gdshader" id="5_dgi5k"]
[ext_resource type="StyleBox" uid="uid://dlw1ogamn741n" path="res://assets/styles/box_flat.tres" id="5_dvx6y"]
[ext_resource type="Texture2D" uid="uid://2yrc6rl4dmd8" path="res://assets/textures/player_board_and_blue_print/tile_null.tres" id="6_2vy7d"]
[ext_resource type="Texture2D" uid="uid://cwxgdi7b4ps40" path="res://assets/textures/Hilight.png" id="7_2nq2l"]
[ext_resource type="Texture2D" uid="uid://c2bj21abtgda1" path="res://assets/models/pboard/HighlightRect.tres" id="7_vv0nt"]
[ext_resource type="Texture2D" uid="uid://0wjk16jlgfq" path="res://assets/models/pboard/SelectRect.tres" id="8_8meci"]
[ext_resource type="Texture2D" uid="uid://dojnv8o6we4ey" path="res://assets/textures/Selected.png" id="8_b18m4"]
[ext_resource type="Texture2D" uid="uid://68x88jj25yxg" path="res://assets/textures/Adjacent.png" id="9_6gcb6"]
[ext_resource type="Texture2D" uid="uid://dasaeaytvhll0" path="res://assets/models/pboard/AdjacentRect.tres" id="9_aspsw"]
[ext_resource type="FontFile" uid="uid://xnjx058n4tsw" path="res://assets/fonts/Nougat-ExtraBlack.ttf" id="13_j8jky"]
[ext_resource type="Texture2D" uid="uid://ba80xnybpixw2" path="res://assets/graphics/touch_control/take_tile.png" id="25_qkpxi"]
[ext_resource type="Texture2D" uid="uid://bsgqrjx2ity4c" path="res://assets/graphics/touch_control/speed.png" id="26_2f3dj"]
[ext_resource type="Texture2D" uid="uid://pwxo4lb87yi" path="res://assets/graphics/touch_control/put_tile.png" id="26_5q0nq"]
[ext_resource type="Texture2D" uid="uid://umw3e8nfe3vr" path="res://assets/graphics/touch_control/attack_mode.png" id="27_dgi5k"]
[ext_resource type="Texture2D" uid="uid://cupfmb5m15kmf" path="res://assets/graphics/touch_control/wall.png" id="27_yq6so"]
[ext_resource type="Texture2D" uid="uid://3up2su2e0lfa" path="res://assets/graphics/touch_control/freeze_area.png" id="28_fv21b"]
[ext_resource type="Texture2D" uid="uid://ckhdyxnho6sjp" path="res://assets/graphics/touch_control/spawn_tile.png" id="28_j8jky"]
[ext_resource type="Texture2D" uid="uid://b2vhatfmufn3d" path="res://assets/graphics/touch_control/ghost.png" id="33_5q0nq"]
[ext_resource type="Texture2D" uid="uid://biun2yvglxgij" path="res://assets/graphics/touch_control/grab_tekton.png" id="36_pibwh"]
[ext_resource type="Texture2D" uid="uid://u6igejwdutv1" path="res://assets/graphics/level_bg/level_bg_colloseum.jpg" id="37_fuf3a"]
[ext_resource type="Script" uid="uid://86ikh0wuqk7v" path="res://scripts/ui/powerup_inventory_ui.gd" id="powerup_ui_script"]
[ext_resource type="Script" uid="uid://b54tfa0n6kogi" path="res://scripts/managers/touch_controls.gd" id="touch_manager"]
[ext_resource type="Script" uid="uid://djiml4sh61dc1" path="res://scripts/ui/virtual_joystick.gd" id="virtual_joystick"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_j8jky"]
shader = ExtResource("5_dgi5k")
shader_parameter/top_left = Vector2(0, 0)
shader_parameter/top_right = Vector2(0, 0)
shader_parameter/bottom_left = Vector2(0, 0)
shader_parameter/bottom_right = Vector2(0, 0)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_playerboard"]
content_margin_left = 8.0
content_margin_top = 8.0
content_margin_right = 8.0
content_margin_bottom = 8.0
bg_color = Color(0.08, 0.08, 0.12, 0.9)
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color(0.3, 0.3, 0.4, 0.8)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1cewu"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kmb1v"]
content_margin_left = 16.0
content_margin_top = 16.0
content_margin_right = 16.0
content_margin_bottom = 16.0
bg_color = Color(0, 0, 0, 0.49803922)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.992, 0.796, 0.047, 1)
corner_radius_top_left = 36
corner_radius_top_right = 36
corner_radius_bottom_right = 36
corner_radius_bottom_left = 36
corner_detail = 12
[node name="Main" type="Node3D" unique_id=1566673391]
script = ExtResource("1_xcpe3")
[node name="EnhancedGridMap" type="GridMap" parent="." unique_id=1838552857]
mesh_library = ExtResource("1_110wo")
cell_size = Vector3(1, 0.2, 1)
data = {
"cells": PackedInt32Array(0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 1, 0, 0, 1, 1, 0, 1, 2, 0, 1, 3, 0, 1, 4, 0, 1, 5, 0, 1, 6, 0, 1, 7, 0, 1, 8, 0, 1, 9, 0, 1, 10, 0, 1, 11, 0, 1, 12, 0, 1, 13, 0, 2, 0, 0, 2, 1, 0, 2, 2, 0, 2, 3, 0, 2, 4, 0, 2, 5, 0, 2, 6, 0, 2, 7, 0, 2, 8, 0, 2, 9, 0, 2, 10, 0, 2, 11, 0, 2, 12, 0, 2, 13, 0, 3, 0, 0, 3, 1, 0, 3, 2, 0, 3, 3, 0, 3, 4, 0, 3, 5, 0, 3, 6, 0, 3, 7, 0, 3, 8, 0, 3, 9, 0, 3, 10, 0, 3, 11, 0, 3, 12, 0, 3, 13, 0, 4, 0, 0, 4, 1, 0, 4, 2, 0, 4, 3, 0, 4, 4, 0, 4, 5, 0, 4, 6, 0, 4, 7, 0, 4, 8, 0, 4, 9, 0, 4, 10, 0, 4, 11, 0, 4, 12, 0, 4, 13, 0, 5, 0, 0, 5, 1, 0, 5, 2, 0, 5, 3, 0, 5, 4, 0, 5, 5, 0, 5, 6, 0, 5, 7, 0, 5, 8, 0, 5, 9, 0, 5, 10, 0, 5, 11, 0, 5, 12, 0, 5, 13, 0, 6, 0, 0, 6, 1, 0, 6, 2, 0, 6, 3, 0, 6, 4, 0, 6, 5, 0, 6, 6, 0, 6, 7, 0, 6, 8, 0, 6, 9, 0, 6, 10, 0, 6, 11, 0, 6, 12, 0, 6, 13, 0, 7, 0, 0, 7, 1, 0, 7, 2, 0, 7, 3, 0, 7, 4, 0, 7, 5, 0, 7, 6, 0, 7, 7, 0, 7, 8, 0, 7, 9, 0, 7, 10, 0, 7, 11, 0, 7, 12, 0, 7, 13, 0, 8, 0, 0, 8, 1, 0, 8, 2, 0, 8, 3, 0, 8, 4, 0, 8, 5, 0, 8, 6, 0, 8, 7, 0, 8, 8, 0, 8, 9, 0, 8, 10, 0, 8, 11, 0, 8, 12, 0, 8, 13, 0, 9, 0, 0, 9, 1, 0, 9, 2, 0, 9, 3, 0, 9, 4, 0, 9, 5, 0, 9, 6, 0, 9, 7, 0, 9, 8, 0, 9, 9, 0, 9, 10, 0, 9, 11, 0, 9, 12, 0, 9, 13, 0, 10, 0, 0, 10, 1, 0, 10, 2, 0, 10, 3, 0, 10, 4, 0, 10, 5, 0, 10, 6, 0, 10, 7, 0, 10, 8, 0, 10, 9, 0, 10, 10, 0, 10, 11, 0, 10, 12, 0, 10, 13, 0, 11, 0, 0, 11, 1, 0, 11, 2, 0, 11, 3, 0, 11, 4, 0, 11, 5, 0, 11, 6, 0, 11, 7, 0, 11, 8, 0, 11, 9, 0, 11, 10, 0, 11, 11, 0, 11, 12, 0, 11, 13, 0, 12, 0, 0, 12, 1, 0, 12, 2, 0, 12, 3, 0, 12, 4, 0, 12, 5, 0, 12, 6, 0, 12, 7, 0, 12, 8, 0, 12, 9, 0, 12, 10, 0, 12, 11, 0, 12, 12, 0, 12, 13, 0, 13, 0, 0, 13, 1, 0, 13, 2, 0, 13, 3, 0, 13, 4, 0, 13, 5, 0, 13, 6, 0, 13, 7, 0, 13, 8, 0, 13, 9, 0, 13, 10, 0, 13, 11, 0, 13, 12, 0, 13, 13, 0, 65537, 0, 10, 65537, 1, 8, 65537, 2, 11, 65537, 3, 8, 65537, 4, 10, 65537, 5, 11, 65537, 6, 9, 65537, 7, 9, 65537, 8, 10, 65537, 9, 8, 65537, 10, 12, 65537, 11, 10, 65537, 12, 10, 65537, 13, 10, 65538, 0, 12, 65538, 1, 11, 65538, 2, 10, 65538, 3, 10, 65538, 4, 11, 65538, 5, 9, 65538, 6, 10, 65538, 7, 12, 65538, 8, 10, 65538, 9, 8, 65538, 10, 12, 65538, 11, 11, 65538, 12, 10, 65538, 13, 10, 65539, 0, 9, 65539, 1, 10, 65539, 2, 10, 65539, 3, 11, 65539, 4, 11, 65539, 5, 8, 65539, 6, 9, 65539, 7, 11, 65539, 8, 12, 65539, 9, 11, 65539, 10, 8, 65539, 11, 10, 65539, 12, 8, 65539, 13, 8, 65540, 0, 12, 65540, 1, 8, 65540, 2, 9, 65540, 3, 8, 65540, 4, 9, 65540, 5, 11, 65540, 6, 9, 65540, 7, 9, 65540, 8, 8, 65540, 9, 9, 65540, 10, 10, 65540, 11, 8, 65540, 12, 12, 65540, 13, 12, 65541, 0, 8, 65541, 1, 8, 65541, 2, 10, 65541, 3, 12, 65541, 4, 8, 65541, 5, 8, 65541, 6, 12, 65541, 7, 8, 65541, 8, 8, 65541, 9, 11, 65541, 10, 12, 65541, 11, 9, 65541, 12, 11, 65541, 13, 11, 65542, 0, 12, 65542, 1, 8, 65542, 2, 10, 65542, 3, 12, 65542, 4, 12, 65542, 5, 11, 65542, 6, 10, 65542, 7, 11, 65542, 8, 9, 65542, 9, 9, 65542, 10, 8, 65542, 11, 11, 65542, 12, 11, 65542, 13, 9, 65543, 0, 8, 65543, 1, 9, 65543, 2, 8, 65543, 3, 8, 65543, 4, 10, 65543, 5, 9, 65543, 6, 12, 65543, 7, 8, 65543, 8, 10, 65543, 9, 8, 65543, 10, 9, 65543, 11, 12, 65543, 12, 9, 65543, 13, 9, 65544, 0, 12, 65544, 1, 8, 65544, 2, 8, 65544, 3, 10, 65544, 4, 10, 65544, 5, 12, 65544, 6, 12, 65544, 7, 10, 65544, 8, 9, 65544, 9, 9, 65544, 10, 10, 65544, 11, 10, 65544, 12, 9, 65544, 13, 11, 65545, 0, 10, 65545, 1, 8, 65545, 2, 10, 65545, 3, 10, 65545, 4, 11, 65545, 5, 11, 65545, 6, 9, 65545, 7, 9, 65545, 8, 10, 65545, 9, 12, 65545, 10, 9, 65545, 11, 8, 65545, 12, 8, 65545, 13, 12, 65546, 0, 10, 65546, 1, 10, 65546, 2, 12, 65546, 3, 12, 65546, 4, 9, 65546, 5, 9, 65546, 6, 10, 65546, 7, 8, 65546, 8, 8, 65546, 9, 10, 65546, 10, 12, 65546, 11, 11, 65546, 12, 12, 65546, 13, 10, 65547, 0, 10, 65547, 1, 9, 65547, 2, 8, 65547, 3, 10, 65547, 4, 8, 65547, 5, 11, 65547, 6, 9, 65547, 7, 8, 65547, 8, 11, 65547, 9, 9, 65547, 10, 8, 65547, 11, 12, 65547, 12, 8, 65547, 13, 10, 65548, 0, 11, 65548, 1, 12, 65548, 2, 8, 65548, 3, 9, 65548, 4, 9, 65548, 5, 9, 65548, 6, 10, 65548, 7, 10, 65548, 8, 12, 65548, 9, 9, 65548, 10, 11, 65548, 11, 11, 65548, 12, 11, 65548, 13, 10, 65536, 0, 2031628, 65536, 1, 2031627, 65536, 2, 2031626, 65536, 3, 2031625, 65536, 4, 2031628, 65536, 5, 2031627, 65536, 6, 2031626, 65536, 7, 2031627, 65536, 8, 2031628, 65536, 9, 2031628, 65536, 10, 2031628, 65536, 11, 2031627, 65536, 12, 2031626, 65536, 13, 2031624, 65549, 0, 2031627, 65549, 1, 2031624, 65549, 2, 2031624, 65549, 3, 2031628, 65549, 4, 2031626, 65549, 5, 2031625, 65549, 6, 2031627, 65549, 7, 2031628, 65549, 8, 2031624, 65549, 9, 2031628, 65549, 10, 2031627, 65549, 11, 2031628, 65549, 12, 2031625, 65549, 13, 2031626)
}
script = ExtResource("2_hbe1v")
columns = 14
rows = 14
floors = 2
auto_randomize = true
start_item = 2
end_item = 3
immutable_items = Array[int]([4])
metadata/_editor_floor_ = Vector3(0, 0, 0)
[node name="Camera3D" type="Camera3D" parent="." unique_id=1200003163]
transform = Transform3D(1, 0, 0, 0, 0.422618, 0.906308, 0, -0.906308, 0.422618, 7, 22.925, 18.4489)
environment = ExtResource("4_ky38j")
current = true
fov = 35.5
[node name="Camera3D200" type="Camera3D" parent="." unique_id=1763366951]
transform = Transform3D(1, 0, 0, 0, 0.5077037, 0.86153173, 0, -0.86153173, 0.5077037, 7, 32.3, 25.8)
environment = ExtResource("4_ky38j")
current = true
fov = 21.0
size = 15.0
[node name="PlayerboardPanel" type="PanelContainer" parent="." unique_id=1098203639]
material = SubResource("ShaderMaterial_j8jky")
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 63.731766
offset_top = -200.62561
offset_right = 214.42894
offset_bottom = -15.877472
grow_vertical = 2
rotation = -0.10297442
theme_override_styles/panel = SubResource("StyleBoxFlat_playerboard")
[node name="PlayerboardUI" type="GridContainer" parent="." unique_id=48093356]
clip_contents = true
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 34.000004
offset_top = -190.23553
offset_right = 250.0
offset_bottom = 25.764465
grow_vertical = 2
rotation = -0.10297442
scale = Vector2(1.08, 1.08)
size_flags_horizontal = 3
columns = 5
[node name="Slot1" type="TextureRect" parent="PlayerboardUI" unique_id=1399081516]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot1" unique_id=73796370]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_vv0nt")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot1" unique_id=1419479429]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_8meci")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot1" unique_id=280168514]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_aspsw")
[node name="Slot2" type="TextureRect" parent="PlayerboardUI" unique_id=462730820]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot2" unique_id=1975520133]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot2" unique_id=1608039666]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot2" unique_id=34878910]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot3" type="TextureRect" parent="PlayerboardUI" unique_id=1883039379]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot3" unique_id=128555296]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot3" unique_id=1985613689]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot3" unique_id=1744577453]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot4" type="TextureRect" parent="PlayerboardUI" unique_id=162585145]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot4" unique_id=1878819233]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot4" unique_id=1292098113]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot4" unique_id=1504241456]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot5" type="TextureRect" parent="PlayerboardUI" unique_id=1644684927]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot5" unique_id=64305041]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot5" unique_id=1190668306]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot5" unique_id=222315602]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot6" type="TextureRect" parent="PlayerboardUI" unique_id=481932710]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot6" unique_id=191595590]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot6" unique_id=928765606]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot6" unique_id=294354992]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot7" type="TextureRect" parent="PlayerboardUI" unique_id=1184367354]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot7" unique_id=2112625734]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot7" unique_id=1761236766]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot7" unique_id=874391367]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot8" type="TextureRect" parent="PlayerboardUI" unique_id=1244318204]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot8" unique_id=755408237]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot8" unique_id=640314117]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot8" unique_id=1529176319]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot9" type="TextureRect" parent="PlayerboardUI" unique_id=2073068517]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot9" unique_id=733008534]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot9" unique_id=288656621]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot9" unique_id=857038803]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot10" type="TextureRect" parent="PlayerboardUI" unique_id=1184621406]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot10" unique_id=7279465]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot10" unique_id=1097751170]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot10" unique_id=1699961786]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot11" type="TextureRect" parent="PlayerboardUI" unique_id=1688573384]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot11" unique_id=226280733]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot11" unique_id=1998225844]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot11" unique_id=1180311453]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot12" type="TextureRect" parent="PlayerboardUI" unique_id=644780641]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot12" unique_id=652930136]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot12" unique_id=1699088104]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot12" unique_id=1072407377]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot13" type="TextureRect" parent="PlayerboardUI" unique_id=591046129]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot13" unique_id=797546522]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot13" unique_id=1767468123]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot13" unique_id=366226154]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot14" type="TextureRect" parent="PlayerboardUI" unique_id=238780074]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot14" unique_id=1273869281]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot14" unique_id=1037905262]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot14" unique_id=944771687]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot15" type="TextureRect" parent="PlayerboardUI" unique_id=1663725669]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot15" unique_id=1891754186]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot15" unique_id=93476819]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot15" unique_id=609689370]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot16" type="TextureRect" parent="PlayerboardUI" unique_id=628611489]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot16" unique_id=754328744]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot16" unique_id=1152390013]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot16" unique_id=695895201]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot17" type="TextureRect" parent="PlayerboardUI" unique_id=14337200]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot17" unique_id=1908525374]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot17" unique_id=1938430010]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot17" unique_id=1187550807]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot18" type="TextureRect" parent="PlayerboardUI" unique_id=1450009773]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot18" unique_id=286299595]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot18" unique_id=166221410]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot18" unique_id=324198818]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot19" type="TextureRect" parent="PlayerboardUI" unique_id=863242693]
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot19" unique_id=739753928]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot19" unique_id=1396505845]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot19" unique_id=233557579]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot20" type="TextureRect" parent="PlayerboardUI" unique_id=2086008463]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot20" unique_id=1608997623]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot20" unique_id=1826090845]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot20" unique_id=1046262306]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot21" type="TextureRect" parent="PlayerboardUI" unique_id=1451444134]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot21" unique_id=2136156725]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot21" unique_id=606552769]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot21" unique_id=1120516969]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot22" type="TextureRect" parent="PlayerboardUI" unique_id=141949470]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot22" unique_id=1138719122]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot22" unique_id=367089612]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot22" unique_id=441881724]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot23" type="TextureRect" parent="PlayerboardUI" unique_id=1345458769]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot23" unique_id=563959407]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot23" unique_id=948060413]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot23" unique_id=1540856367]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot24" type="TextureRect" parent="PlayerboardUI" unique_id=1840834103]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot24" unique_id=1036547495]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot24" unique_id=703640093]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot24" unique_id=1249854708]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="Slot25" type="TextureRect" parent="PlayerboardUI" unique_id=1179195394]
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(36, 36)
layout_mode = 2
texture = ExtResource("6_2vy7d")
[node name="HighlightRect" type="TextureRect" parent="PlayerboardUI/Slot25" unique_id=797763971]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("7_2nq2l")
[node name="SelectRect" type="TextureRect" parent="PlayerboardUI/Slot25" unique_id=125513581]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("8_b18m4")
[node name="AdjacentRect" type="TextureRect" parent="PlayerboardUI/Slot25" unique_id=2054303245]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("9_6gcb6")
[node name="PlayeBoardPanelName" type="PanelContainer" parent="." unique_id=1458381676]
material = SubResource("ShaderMaterial_j8jky")
offset_left = 44.0
offset_top = 113.710526
offset_right = 216.29385
offset_bottom = 153.37068
rotation = -0.10297442
theme_override_styles/panel = SubResource("StyleBoxFlat_playerboard")
[node name="PlayerName" type="Label" parent="." unique_id=254337877]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 50.718987
offset_top = -244.58023
offset_right = 133.719
offset_bottom = -208.58023
grow_vertical = 2
rotation = -0.10297442
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 32
text = "Guest"
[node name="PlayerBoardLabel" type="Label" parent="." unique_id=341385584]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 170.71896
offset_top = -258.02036
offset_right = 210.71896
offset_bottom = -222.02036
grow_vertical = 2
rotation = -0.10297442
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 32
text = "X0"
[node name="StopTimer" type="PanelContainer" parent="." unique_id=991540081]
visible = false
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -58.0
offset_top = 80.0
offset_right = 58.0
offset_bottom = 113.00012
grow_horizontal = 2
[node name="HBox" type="HBoxContainer" parent="StopTimer" unique_id=1541315617]
layout_mode = 2
theme_override_constants/separation = 4
[node name="Segment0" type="Panel" parent="StopTimer/HBox" unique_id=307582302]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="Segment1" type="Panel" parent="StopTimer/HBox" unique_id=615805583]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="Segment2" type="Panel" parent="StopTimer/HBox" unique_id=1041800993]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="PowerUpBar" type="PanelContainer" parent="." unique_id=1775378146]
anchors_preset = 4
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 40.0
offset_top = -1.7106018
offset_right = 224.0
offset_bottom = 31.28952
grow_vertical = 2
rotation = -0.10297442
[node name="HBox" type="HBoxContainer" parent="PowerUpBar" unique_id=334600330]
layout_mode = 2
theme_override_constants/separation = 4
[node name="PowerLabel" type="Label" parent="PowerUpBar/HBox" unique_id=1945535407]
layout_mode = 2
theme_override_font_sizes/font_size = 18
text = "⚡"
[node name="Segment0" type="Panel" parent="PowerUpBar/HBox" unique_id=500774723]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="Segment1" type="Panel" parent="PowerUpBar/HBox" unique_id=1042222722]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="Segment2" type="Panel" parent="PowerUpBar/HBox" unique_id=272336972]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="Segment3" type="Panel" parent="PowerUpBar/HBox" unique_id=293120308]
custom_minimum_size = Vector2(36, 20)
layout_mode = 2
[node name="GoalsTimer" type="PanelContainer" parent="." unique_id=2106663301]
offset_left = 235.8717
offset_top = 338.0481
offset_right = 267.8717
offset_bottom = 371.04816
rotation = -0.10297442
[node name="TimerLabel" type="Label" parent="GoalsTimer" unique_id=466345203]
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 18
text = "00"
horizontal_alignment = 1
[node name="MessageInput" type="LineEdit" parent="." unique_id=286018566]
visible = false
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -208.0
offset_top = -72.0
offset_right = 212.0
offset_bottom = -41.0
grow_horizontal = 2
grow_vertical = 0
theme_override_styles/normal = ExtResource("5_dvx6y")
theme_override_styles/focus = SubResource("StyleBoxFlat_1cewu")
placeholder_text = "Chat"
alignment = 1
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=12971344]
environment = ExtResource("4_ky38j")
[node name="MessageBar" type="PanelContainer" parent="." unique_id=142729129]
visible = false
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 13.0
offset_top = -52.0
offset_right = 299.0
offset_bottom = -18.0
grow_vertical = 0
theme_override_styles/panel = ExtResource("5_dvx6y")
[node name="MarginContainer" type="MarginContainer" parent="MessageBar" unique_id=444870568]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 5
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 5
[node name="MessageContainer" type="VBoxContainer" parent="MessageBar/MarginContainer" unique_id=1424970772]
layout_mode = 2
theme_override_constants/separation = 4
[node name="PowerUpInventoryUI" type="Control" parent="." unique_id=1105620089]
layout_mode = 3
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -94.0
offset_top = -432.0
offset_right = -94.0
offset_bottom = -432.0
grow_horizontal = 0
grow_vertical = 0
script = ExtResource("powerup_ui_script")
[node name="Container" type="VBoxContainer" parent="PowerUpInventoryUI" unique_id=1100906843]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -31.999996
offset_right = 41.00098
offset_bottom = 350.0
grow_horizontal = 2
grow_vertical = 2
rotation = 0.10297442
theme_override_constants/separation = 10
[node name="SpeedBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=1549270030]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("26_2f3dj")
flat = true
icon_alignment = 1
expand_icon = true
[node name="WallBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=863365575]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("27_yq6so")
flat = true
icon_alignment = 1
expand_icon = true
[node name="FreezeAreaBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=1087493560]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("28_fv21b")
flat = true
icon_alignment = 1
expand_icon = true
[node name="GhostBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=2041811828]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("33_5q0nq")
flat = true
icon_alignment = 1
expand_icon = true
[node name="LeaderboardPanel" type="PanelContainer" parent="." unique_id=364209533]
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -273.64343
offset_top = 84.58379
offset_right = -26.733765
offset_bottom = 253.5838
grow_horizontal = 0
rotation = 0.10297442
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="LeaderboardPanel" unique_id=1736331167]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBox" type="VBoxContainer" parent="LeaderboardPanel/MarginContainer" unique_id=635878805]
layout_mode = 2
theme_override_constants/separation = 4
[node name="Title" type="Label" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=1810699363]
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "🏆 LEADERBOARD"
horizontal_alignment = 1
[node name="Separator" type="HSeparator" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=1615297005]
layout_mode = 2
[node name="Entry1" type="HBoxContainer" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=1372346601]
layout_mode = 2
[node name="RankLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry1" unique_id=828754165]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "1st"
[node name="NameLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry1" unique_id=777741978]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "Player 1"
clip_text = true
[node name="ScoreLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry1" unique_id=163441394]
layout_mode = 2
size_flags_horizontal = 3
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "0"
horizontal_alignment = 2
[node name="Entry2" type="HBoxContainer" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=1213770719]
layout_mode = 2
[node name="RankLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry2" unique_id=276085006]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "2nd"
[node name="NameLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry2" unique_id=980063105]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "Player 2"
clip_text = true
[node name="ScoreLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry2" unique_id=630589738]
layout_mode = 2
size_flags_horizontal = 3
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "0"
horizontal_alignment = 2
[node name="Entry3" type="HBoxContainer" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=988674004]
layout_mode = 2
[node name="RankLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry3" unique_id=940102589]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "3rd"
[node name="NameLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry3" unique_id=872999463]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "Player 3"
clip_text = true
[node name="ScoreLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry3" unique_id=508325054]
layout_mode = 2
size_flags_horizontal = 3
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "0"
horizontal_alignment = 2
[node name="Entry4" type="HBoxContainer" parent="LeaderboardPanel/MarginContainer/VBox" unique_id=394023021]
layout_mode = 2
[node name="RankLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry4" unique_id=539805932]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "4th"
[node name="NameLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry4" unique_id=379355680]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "Player 4"
clip_text = true
[node name="ScoreLabel" type="Label" parent="LeaderboardPanel/MarginContainer/VBox/Entry4" unique_id=560418594]
layout_mode = 2
size_flags_horizontal = 3
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 22
text = "0"
horizontal_alignment = 2
[node name="GlobalMatchTimer" type="PanelContainer" parent="." unique_id=1714357974]
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -75.0
offset_top = 8.0
offset_right = 73.0
offset_bottom = 72.0
grow_horizontal = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_kmb1v")
[node name="VBox" type="VBoxContainer" parent="GlobalMatchTimer" unique_id=24429117]
layout_mode = 2
alignment = 1
[node name="TimerLabel" type="Label" parent="GlobalMatchTimer/VBox" unique_id=689385799]
layout_mode = 2
theme_override_fonts/font = ExtResource("13_j8jky")
theme_override_font_sizes/font_size = 28
text = "3:00"
horizontal_alignment = 1
[node name="TouchControls" type="CanvasLayer" parent="." unique_id=1390485948]
script = ExtResource("touch_manager")
[node name="TouchControls" type="Control" parent="TouchControls" unique_id=1539594058]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = 318.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="VirtualJoystick" type="Control" parent="TouchControls/TouchControls" unique_id=1983608919]
visible = false
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 120.0
offset_top = -280.0
offset_right = 280.0
offset_bottom = -120.0
grow_vertical = 0
script = ExtResource("virtual_joystick")
[node name="ActionsBtn" type="VBoxContainer" parent="TouchControls/TouchControls" unique_id=278736451]
layout_mode = 0
offset_left = 48.000004
offset_top = 82.00001
offset_right = 114.71878
offset_bottom = 350.68915
rotation = -0.10297442
theme_override_constants/separation = 15
[node name="PutBtn" type="Button" parent="TouchControls/TouchControls/ActionsBtn" unique_id=1027790362]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("26_5q0nq")
flat = true
icon_alignment = 1
expand_icon = true
[node name="AttackModeBtn" type="Button" parent="TouchControls/TouchControls/ActionsBtn" unique_id=1380511463]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("27_dgi5k")
flat = true
icon_alignment = 1
expand_icon = true
[node name="SpawnBoostBtn" type="Button" parent="TouchControls/TouchControls/ActionsBtn" unique_id=1566173505]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
icon = ExtResource("28_j8jky")
flat = true
icon_alignment = 1
expand_icon = true
[node name="TektonGrabBtn" type="Button" parent="TouchControls/TouchControls/ActionsBtn" unique_id=2097928368]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
icon = ExtResource("36_pibwh")
flat = true
icon_alignment = 1
expand_icon = true
[node name="GrabBtn" type="Button" parent="TouchControls/TouchControls/ActionsBtn" unique_id=914810452]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 0
icon = ExtResource("25_qkpxi")
flat = true
icon_alignment = 1
expand_icon = true
[node name="SettingsBtn" type="Button" parent="TouchControls/TouchControls" unique_id=1964422444]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -78.0
offset_top = -302.0
offset_right = -30.0
offset_bottom = -254.0
grow_horizontal = 0
text = "⚙"
[node name="PauseMenu" type="CanvasLayer" parent="." unique_id=181131829]
process_mode = 3
layer = 10
visible = false
[node name="Background" type="ColorRect" parent="PauseMenu" unique_id=412985431]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.7)
[node name="Panel" type="PanelContainer" parent="PauseMenu" unique_id=407391814]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -150.0
offset_top = -150.0
offset_right = 150.0
offset_bottom = 150.0
grow_horizontal = 2
grow_vertical = 2
[node name="NetworkPanel" type="Panel" parent="PauseMenu/Panel" unique_id=935918250]
layout_mode = 2
theme_override_styles/panel = ExtResource("5_dvx6y")
[node name="NetworkInfo" type="HBoxContainer" parent="PauseMenu/Panel/NetworkPanel" unique_id=1194782604]
visible = false
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -135.0
offset_right = 135.0
offset_bottom = 23.0
grow_horizontal = 2
theme_override_constants/separation = 50
alignment = 1
[node name="NetworkSideDisplay" type="Label" parent="PauseMenu/Panel/NetworkPanel/NetworkInfo" unique_id=1748547015]
layout_mode = 2
text = "Network Side"
horizontal_alignment = 1
vertical_alignment = 1
[node name="UniquePeerID" type="Label" parent="PauseMenu/Panel/NetworkPanel/NetworkInfo" unique_id=1306253581]
layout_mode = 2
text = "Unique Peer ID"
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBox" type="VBoxContainer" parent="PauseMenu/Panel" unique_id=837757440]
layout_mode = 2
theme_override_constants/separation = 15
alignment = 1
[node name="Title" type="Label" parent="PauseMenu/Panel/VBox" unique_id=1740539610]
layout_mode = 2
theme_override_font_sizes/font_size = 24
text = "Menu"
horizontal_alignment = 1
[node name="Spacer" type="Control" parent="PauseMenu/Panel/VBox" unique_id=57341975]
custom_minimum_size = Vector2(0, 20)
layout_mode = 2
[node name="ResumeBtn" type="Button" parent="PauseMenu/Panel/VBox" unique_id=79086881]
custom_minimum_size = Vector2(200, 45)
layout_mode = 2
text = "Resume"
[node name="HowToPlayBtn" type="Button" parent="PauseMenu/Panel/VBox" unique_id=987654321]
custom_minimum_size = Vector2(200, 45)
layout_mode = 2
text = "How to Play"
[node name="SettingsBtn" type="Button" parent="PauseMenu/Panel/VBox" unique_id=215865401]
custom_minimum_size = Vector2(200, 45)
layout_mode = 2
text = "Settings"
[node name="QuitBtn" type="Button" parent="PauseMenu/Panel/VBox" unique_id=1771850243]
custom_minimum_size = Vector2(200, 45)
layout_mode = 2
text = "Quit Match"
[node name="HowToPlayPanel" type="CanvasLayer" parent="." unique_id=123456789]
process_mode = 3
layer = 11
visible = false
[node name="Background" type="ColorRect" parent="HowToPlayPanel" unique_id=123456790]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.8)
[node name="Panel" type="PanelContainer" parent="HowToPlayPanel" unique_id=123456791]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -300.0
offset_top = -250.0
offset_right = 300.0
offset_bottom = 250.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBox" type="VBoxContainer" parent="HowToPlayPanel/Panel" unique_id=123456792]
layout_mode = 2
theme_override_constants/separation = 12
alignment = 1
[node name="Title" type="Label" parent="HowToPlayPanel/Panel/VBox" unique_id=123456793]
layout_mode = 2
theme_override_font_sizes/font_size = 22
text = "How to Play"
horizontal_alignment = 1
[node name="TabContainer" type="TabContainer" parent="HowToPlayPanel/Panel/VBox" unique_id=123456794]
layout_mode = 2
size_flags_vertical = 3
current_tab = 0
[node name="Free Mode" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456795]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 0
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Free Mode" unique_id=123456796]
layout_mode = 2
bbcode_enabled = true
text = "[b]Free Mode[/b]
- Move around the grid and attack Tektons to spawn tiles.
- Grab tiles and use the [b]ARRANGE[/b] action to slot them into your player board.
- Match a 3x3 pattern shown in your [b]GOALS[/b] to score points and earn powerups.
- The player with the highest score when the global match timer ends wins!"
[node name="Stop n Go" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456797]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 1
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Stop n Go" unique_id=123456798]
layout_mode = 2
bbcode_enabled = true
text = "[b]Stop n Go[/b]
- The classic red light, green light experience.
- Move forward when the phase is [color=green][b]GO[/b][/color] (Green).
- Stop completely when the phase is [color=red][b]STOP[/b][/color] (Red). Moving during a red phase will reset you to the start!
- Your objective is to reach the mission tiles at the far end of the arena and safely carry them back to your starting zone.
- The first player to complete 8 missions and reach the finish floor wins."
[node name="Tekton Doors" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456799]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 2
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Tekton Doors" unique_id=123456800]
layout_mode = 2
bbcode_enabled = true
text = "[b]Tekton Doors[/b]
- Navigate a sprawling arena connected by color-coded portal doors.
- Grab tiles and match goal patterns to earn mission completions.
- Use doors to quickly teleport across rooms, but watch out for closures and traps.
- The first player to complete 8 missions and reach the finish room wins."
[node name="Controls" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456805]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 3
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Controls" unique_id=123456806]
layout_mode = 2
bbcode_enabled = true
text = "[b]Basic Controls[/b]
• [b]Movement:[/b] W/A/S/D, Arrow Keys, or Virtual Joystick.
• [b]Interact:[/b] Click or tap on game elements.
• [b]GRAB TILE:[/b] Spacebar (in some modes) or Click to pick up a tile.
• [b]GRAB TEKTON (G):[/b] Grab a nearby Tekton to carry it.
• [b]SPAWN TILES (E):[/b] While carrying a Tekton, spawn 5 common tiles around you.
• [b]ARRANGE:[/b] Insert a carried tile into your 3x3 Player Board."
[node name="The Grid" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456807]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 4
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/The Grid" unique_id=123456808]
layout_mode = 2
bbcode_enabled = true
text = "[b]The Grid & Tiles[/b]
• The arena is built on a grid. You interact with objects positioned on these grid coordinates.
• [b]Tiles:[/b] Core items shaped like Hearts, Diamonds, Stars, and Coins.
• [b]Player Board:[/b] A 3x3 grid assigned to you.
• [b]Goals:[/b] To score points or progress, you must pick up Tiles and ARRANGE them on your Player Board to match the 3x3 pattern shown in your Goals Window. Matching grants points or mission progression!"
[node name="Tektons" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456809]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 5
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Tektons" unique_id=123456810]
layout_mode = 2
bbcode_enabled = true
text = "[b]Tektons[/b]
• [b]Dynamic Tektons:[/b] Roaming metallic entities. Grab them to gain special benefits!
• [b]Grab & Hold (G):[/b] While holding a Tekton, you are [color=green][b]IMMUNE[/b][/color] to being knocked or staggered by others.
• [b]Tile Generation (E):[/b] Use your boost to force a carried Tekton to spawn 5 [b]Common Tiles[/b] instantly. The Tekton is released after spawning.
• [b]Static Tektons:[/b] Stationary sentry turrets that occupy a 3x3 space. They periodically throw tiles and obstacles around themselves. Stay alert!"
[node name="Skills" type="MarginContainer" parent="HowToPlayPanel/Panel/VBox/TabContainer" unique_id=123456811]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
metadata/_tab_index = 6
[node name="RichTextLabel" type="RichTextLabel" parent="HowToPlayPanel/Panel/VBox/TabContainer/Skills" unique_id=123456812]
layout_mode = 2
bbcode_enabled = true
text = "[b]Skills & Power-ups[/b]
Earn powerups by matching Goal tiles or finding them in the arena.
• [color=yellow][b]Speed Boost (Tile 11):[/b][/color] Gain +50% movement speed for 5 seconds.
• [color=gray][b]Wall Build (Tile 13):[/b][/color] Block paths with a temporary wall for 9 seconds.
• [color=aqua][b]Freeze Area (Tile 12):[/b][/color] Create a slow zone that traps opponents for 15 seconds.
• [color=purple][b]Ghost Mode (Tile 14):[/b][/color] Become invisible and phase past blocks for 6 seconds.
*Note: In Stop n Go, power-ups spawn specifically during the STOP transitions!*"
[node name="Spacer" type="Control" parent="HowToPlayPanel/Panel/VBox" unique_id=123456801]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
[node name="BackBtn" type="Button" parent="HowToPlayPanel/Panel/VBox" unique_id=123456802]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
text = "Back"
[node name="SettingsPanel" type="CanvasLayer" parent="." unique_id=268064562]
process_mode = 3
layer = 11
visible = false
[node name="Background" type="ColorRect" parent="SettingsPanel" unique_id=1148993432]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.8)
[node name="Panel" type="PanelContainer" parent="SettingsPanel" unique_id=1418717329]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -200.0
offset_top = -200.0
offset_right = 200.0
offset_bottom = 200.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBox" type="VBoxContainer" parent="SettingsPanel/Panel" unique_id=449477630]
layout_mode = 2
theme_override_constants/separation = 12
alignment = 1
[node name="Title" type="Label" parent="SettingsPanel/Panel/VBox" unique_id=1939206128]
layout_mode = 2
theme_override_font_sizes/font_size = 22
text = "Settings"
horizontal_alignment = 1
[node name="Spacer" type="Control" parent="SettingsPanel/Panel/VBox" unique_id=426750898]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
[node name="TouchHeader" type="Label" parent="SettingsPanel/Panel/VBox" unique_id=1095783125]
layout_mode = 2
theme_override_font_sizes/font_size = 16
text = "Touch Controls"
[node name="ButtonSizeRow" type="HBoxContainer" parent="SettingsPanel/Panel/VBox" unique_id=1573503465]
layout_mode = 2
[node name="Label" type="Label" parent="SettingsPanel/Panel/VBox/ButtonSizeRow" unique_id=1996113172]
layout_mode = 2
size_flags_horizontal = 3
text = "Button Size"
[node name="ButtonSizeSlider" type="HSlider" parent="SettingsPanel/Panel/VBox/ButtonSizeRow" unique_id=1536868944]
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
min_value = 50.0
max_value = 120.0
value = 70.0
[node name="OpacityRow" type="HBoxContainer" parent="SettingsPanel/Panel/VBox" unique_id=494509398]
layout_mode = 2
[node name="Label" type="Label" parent="SettingsPanel/Panel/VBox/OpacityRow" unique_id=252128874]
layout_mode = 2
size_flags_horizontal = 3
text = "Button Opacity"
[node name="OpacitySlider" type="HSlider" parent="SettingsPanel/Panel/VBox/OpacityRow" unique_id=1673848529]
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
max_value = 1.0
step = 0.1
value = 0.7
[node name="JoystickToggle" type="CheckButton" parent="SettingsPanel/Panel/VBox" unique_id=674311321]
layout_mode = 2
button_pressed = true
text = "Enable Virtual Joystick"
[node name="Spacer2" type="Control" parent="SettingsPanel/Panel/VBox" unique_id=166051520]
custom_minimum_size = Vector2(0, 15)
layout_mode = 2
[node name="BackBtn" type="Button" parent="SettingsPanel/Panel/VBox" unique_id=1290117622]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
text = "Back"
[node name="ArenaBG" type="Sprite3D" parent="." unique_id=2070634860]
transform = Transform3D(4, 0, 0, 0, 1.8291987, 3.557251, 0, -3.557251, 1.8291987, 6.109789, -30, -4)
texture = ExtResource("37_fuf3a")
region_rect = Rect2(0, 0, 1080, 0)
[connection signal="text_submitted" from="MessageInput" to="." method="_on_message_input_text_submitted"]
[connection signal="pressed" from="PauseMenu/Panel/VBox/ResumeBtn" to="." method="_on_resume_pressed"]
[connection signal="pressed" from="PauseMenu/Panel/VBox/HowToPlayBtn" to="." method="_on_how_to_play_pressed"]
[connection signal="pressed" from="PauseMenu/Panel/VBox/SettingsBtn" to="." method="_on_settings_pressed"]
[connection signal="pressed" from="PauseMenu/Panel/VBox/QuitBtn" to="." method="_on_quit_match_pressed"]
[connection signal="pressed" from="HowToPlayPanel/Panel/VBox/BackBtn" to="." method="_on_how_to_play_back_pressed"]
[connection signal="value_changed" from="SettingsPanel/Panel/VBox/ButtonSizeRow/ButtonSizeSlider" to="." method="_on_button_size_changed"]
[connection signal="value_changed" from="SettingsPanel/Panel/VBox/OpacityRow/OpacitySlider" to="." method="_on_opacity_changed"]
[connection signal="toggled" from="SettingsPanel/Panel/VBox/JoystickToggle" to="." method="_on_joystick_toggled"]
[connection signal="pressed" from="SettingsPanel/Panel/VBox/BackBtn" to="." method="_on_settings_back_pressed"]
+8 -8
View File
@@ -145,10 +145,10 @@ offset_bottom = 161.0
[node name="PowerUpItem" type="Control" parent="HighlightZones" unique_id=474081571]
layout_mode = 3
anchors_preset = 0
offset_left = 130.0
offset_top = 501.0
offset_right = 220.0
offset_bottom = 591.0
offset_left = 1170.0
offset_top = 578.0
offset_right = 1260.0
offset_bottom = 668.0
[node name="Leaderboard" type="Control" parent="HighlightZones" unique_id=1503191193]
layout_mode = 3
@@ -165,10 +165,10 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -315.0
offset_top = -210.0
offset_right = -15.0
offset_bottom = -130.0
offset_left = -823.0
offset_top = -114.0
offset_right = -523.0
offset_bottom = -34.0
grow_horizontal = 0
grow_vertical = 0
mouse_filter = 2
+203
View File
@@ -506,5 +506,208 @@ custom_minimum_size = Vector2(143, 38)
layout_mode = 2
text = "N/A"
[node name="Controller" type="ScrollContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer" unique_id=300000001]
visible = false
layout_mode = 2
metadata/_tab_index = 3
[node name="VBox" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller" unique_id=300000002]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 15
[node name="CtrlInfoSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox" unique_id=300000003]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlInfoSection" unique_id=300000004]
layout_mode = 2
text = "CONTROLLER BINDINGS (Press any button to rebind)"
label_settings = SubResource("LabelSettings_section")
[node name="CtrlGrid" type="GridContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox" unique_id=300000005]
layout_mode = 2
theme_override_constants/h_separation = 20
theme_override_constants/v_separation = 10
columns = 2
[node name="ColH1" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000006]
layout_mode = 2
text = "Action"
label_settings = SubResource("LabelSettings_section")
[node name="ColH2" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000007]
layout_mode = 2
text = "Button"
label_settings = SubResource("LabelSettings_section")
[node name="CtrlGrabLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000010]
layout_mode = 2
size_flags_horizontal = 3
text = "Grab Item"
label_settings = SubResource("LabelSettings_heading")
[node name="CtrlGrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000011]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 38)
layout_mode = 2
text = "A / Cross"
[node name="CtrlPowerupLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000020]
layout_mode = 2
size_flags_horizontal = 3
text = "Use PowerUp"
label_settings = SubResource("LabelSettings_heading")
[node name="CtrlPowerupBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000021]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 38)
layout_mode = 2
text = "Y / Triangle"
[node name="CtrlTektonGrabLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000030]
layout_mode = 2
size_flags_horizontal = 3
text = "Grab Tekton"
label_settings = SubResource("LabelSettings_heading")
[node name="CtrlTektonGrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000031]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 38)
layout_mode = 2
text = "RB / R1"
[node name="CtrlAttackLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000040]
layout_mode = 2
size_flags_horizontal = 3
text = "Attack / Knock"
label_settings = SubResource("LabelSettings_heading")
[node name="CtrlAttackBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlGrid" unique_id=300000041]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 38)
layout_mode = 2
text = "X / Square"
[node name="CtrlResetContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox" unique_id=300000050]
layout_mode = 2
[node name="CtrlResetBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controller/VBox/CtrlResetContainer" unique_id=300000051]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 38)
layout_mode = 2
text = "Reset to Defaults"
[node name="TouchInput" type="ScrollContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer" unique_id=200000001]
visible = false
layout_mode = 2
metadata/_tab_index = 4
[node name="VBox" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput" unique_id=200000002]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 20
[node name="JoystickSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000003]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickSection" unique_id=200000004]
layout_mode = 2
text = "VIRTUAL JOYSTICK"
label_settings = SubResource("LabelSettings_section")
[node name="JoystickSizeContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000005]
layout_mode = 2
theme_override_constants/separation = 8
[node name="JoystickSizeHeader" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickSizeContainer" unique_id=200000006]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickSizeContainer/JoystickSizeHeader" unique_id=200000007]
layout_mode = 2
size_flags_horizontal = 3
text = "Joystick Size"
label_settings = SubResource("LabelSettings_heading")
[node name="JoystickSizeValue" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickSizeContainer/JoystickSizeHeader" unique_id=200000008]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
text = "60"
label_settings = SubResource("LabelSettings_heading")
horizontal_alignment = 2
[node name="JoystickSizeSlider" type="HSlider" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickSizeContainer" unique_id=200000009]
unique_name_in_owner = true
layout_mode = 2
min_value = 40.0
max_value = 140.0
step = 5.0
value = 60.0
[node name="JoystickToggleContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000010]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickToggleContainer" unique_id=200000011]
layout_mode = 2
size_flags_horizontal = 3
text = "Show Joystick"
label_settings = SubResource("LabelSettings_heading")
[node name="JoystickEnabledToggle" type="CheckButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/JoystickToggleContainer" unique_id=200000012]
unique_name_in_owner = true
layout_mode = 2
button_pressed = true
[node name="ButtonsSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000013]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/ButtonsSection" unique_id=200000014]
layout_mode = 2
text = "TOUCH BUTTONS"
label_settings = SubResource("LabelSettings_section")
[node name="ButtonOpacityContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000015]
layout_mode = 2
theme_override_constants/separation = 8
[node name="ButtonOpacityHeader" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/ButtonOpacityContainer" unique_id=200000016]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/ButtonOpacityContainer/ButtonOpacityHeader" unique_id=200000017]
layout_mode = 2
size_flags_horizontal = 3
text = "Button Opacity"
label_settings = SubResource("LabelSettings_heading")
[node name="ButtonOpacityValue" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/ButtonOpacityContainer/ButtonOpacityHeader" unique_id=200000018]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
text = "70%"
label_settings = SubResource("LabelSettings_heading")
horizontal_alignment = 2
[node name="ButtonOpacitySlider" type="HSlider" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/ButtonOpacityContainer" unique_id=200000019]
unique_name_in_owner = true
layout_mode = 2
min_value = 0.1
max_value = 1.0
step = 0.05
value = 0.7
[node name="TouchButtonsToggleContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox" unique_id=200000020]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/TouchButtonsToggleContainer" unique_id=200000021]
layout_mode = 2
size_flags_horizontal = 3
text = "Show Touch Buttons"
label_settings = SubResource("LabelSettings_heading")
[node name="TouchButtonsEnabledToggle" type="CheckButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/TouchInput/VBox/TouchButtonsToggleContainer" unique_id=200000022]
unique_name_in_owner = true
layout_mode = 2
button_pressed = true
+1
View File
@@ -917,6 +917,7 @@ func reset() -> void:
available_rooms.clear()
is_host = false
_all_ready = false
is_tutorial_mode = false
match_duration = 180 # Reset to default 3 minutes
game_mode = "Freemode"
_update_available_areas(game_mode)
+22 -10
View File
@@ -7,6 +7,10 @@ var movement_manager: Node
var race_manager: Node
@onready var SettingsManager = get_node_or_null("/root/SettingsManager")
# Analog stick repeat throttle (prevents firing a new move every frame while held)
var _analog_move_timer: float = 0.0
const ANALOG_MOVE_RATE: float = 0.18 # seconds between grid steps when holding stick
func initialize(p_player: Node3D, p_movement_manager: Node, p_race_manager: Node):
player = p_player
movement_manager = p_movement_manager
@@ -21,16 +25,21 @@ func _process(delta):
return
var move_vec = Vector2i.ZERO
# 1. Controller / Joystick Movement
if SettingsManager and SettingsManager.settings.controls.get("use_controller", false):
var joystick_vec = Input.get_vector("move_west", "move_east", "move_north", "move_south")
if joystick_vec.length() > 0.3: # Deadzone
# 1. Left Analog Stick — always active (controller plugged in, any mode)
var joystick_vec = Input.get_vector("move_west", "move_east", "move_north", "move_south", 0.25)
if joystick_vec.length() > 0.25:
_analog_move_timer -= delta
if _analog_move_timer <= 0.0:
if abs(joystick_vec.x) > abs(joystick_vec.y):
move_vec.x = 1 if joystick_vec.x > 0 else -1
else:
move_vec.y = 1 if joystick_vec.y > 0 else -1
_analog_move_timer = ANALOG_MOVE_RATE
else:
_analog_move_timer = 0.0 # Reset so next touch fires immediately
# 2. Keyboard Movement (Fallback)
# 2. Keyboard / D-pad Movement (fires via action pressed, handled by event)
if move_vec == Vector2i.ZERO:
if Input.is_action_pressed("move_north"): move_vec.y -= 1
if Input.is_action_pressed("move_south"): move_vec.y += 1
@@ -75,8 +84,11 @@ func handle_unhandled_input(event):
if not player.is_multiplayer_authority() or player.is_frozen or player.is_stop_frozen or (TurnManager.turn_based_mode and (not player.is_my_turn or movement_manager.is_moving)):
return
# --- Keyboard Shortcuts (Event-based) ---
if event is InputEventKey and event.pressed and not event.echo:
# --- Action Shortcuts (Keyboard OR Controller Button) ---
var is_action_event = (event is InputEventKey and event.pressed and not event.echo) \
or (event is InputEventJoypadButton and event.pressed)
if is_action_event:
# Safety check for SettingsManager
if not SettingsManager:
return
@@ -87,21 +99,21 @@ func handle_unhandled_input(event):
get_viewport().set_input_as_handled()
return
# 3. Action Buttons (Remappable via InputMap)
# 2. Action Buttons (Remappable via InputMap)
if event.is_action_pressed("action_knock_tekton"):
if player.powerup_manager:
player.powerup_manager.use_special_effect()
if player.is_attack_mode and player.has_method("enter_attack_mode"):
player.enter_attack_mode()
get_viewport().set_input_as_handled()
elif event.is_action_pressed("action_grab_tekton"):
if not player.is_carrying_tekton:
if player.powerup_manager and player.powerup_manager.has_method("can_use_special"):
player.grab_tekton()
get_viewport().set_input_as_handled()
# Handle spawn point selection if not yet selected
if not player.spawn_point_selected and player.highlighted_spawn_points.size() > 0:
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
+85 -1
View File
@@ -53,7 +53,13 @@ var settings = {
# Power Bar Controls / Special
"attack_mode": KEY_Q,
"attack_mode_alt": KEY_U
"attack_mode_alt": KEY_U,
# Controller Button Bindings (JOY_BUTTON_* indices)
"ctrl_grab": JOY_BUTTON_A,
"ctrl_tekton_grab": JOY_BUTTON_RIGHT_SHOULDER,
"ctrl_use_powerup": JOY_BUTTON_Y,
"ctrl_attack_mode": JOY_BUTTON_X
}
}
@@ -207,6 +213,21 @@ func apply_control_settings():
event.keycode = secondary_key
InputMap.action_add_event(action_name, event)
# Add Joypad defaults for actions - use saved ctrl_* bindings
var joy_button_mapped = -1
match action_name:
"action_grab": joy_button_mapped = settings.controls.get("ctrl_grab", JOY_BUTTON_A)
"use_powerup": joy_button_mapped = settings.controls.get("ctrl_use_powerup", JOY_BUTTON_Y)
"action_grab_tekton": joy_button_mapped = settings.controls.get("ctrl_tekton_grab", JOY_BUTTON_RIGHT_SHOULDER)
"action_knock_tekton": joy_button_mapped = settings.controls.get("ctrl_attack_mode", JOY_BUTTON_X)
if action_name == "action_put": joy_button_mapped = JOY_BUTTON_B
if joy_button_mapped != -1:
var joy_btn_event = InputEventJoypadButton.new()
joy_btn_event.button_index = joy_button_mapped
InputMap.action_add_event(action_name, joy_btn_event)
# Add Joypad defaults for movement
if action_name.begins_with("move_"):
var joy_axis = -1
@@ -230,6 +251,69 @@ func set_control(action_name: String, keycode: int):
emit_signal("control_remapped", action_name, keycode)
save_settings()
# --- Controller Binding ---
# Godot 4 JoyButton name map (var not const — enum keys can't be used in const dicts)
var CTRL_BUTTON_NAMES: Dictionary = {
JOY_BUTTON_A: "A / Cross",
JOY_BUTTON_B: "B / Circle",
JOY_BUTTON_X: "X / Square",
JOY_BUTTON_Y: "Y / Triangle",
JOY_BUTTON_LEFT_SHOULDER: "LB / L1",
JOY_BUTTON_RIGHT_SHOULDER: "RB / R1",
JOY_BUTTON_LEFT_STICK: "L3",
JOY_BUTTON_RIGHT_STICK: "R3",
JOY_BUTTON_BACK: "Select / Share",
JOY_BUTTON_START: "Start / Options",
JOY_BUTTON_DPAD_UP: "D-Up",
JOY_BUTTON_DPAD_DOWN: "D-Down",
JOY_BUTTON_DPAD_LEFT: "D-Left",
JOY_BUTTON_DPAD_RIGHT: "D-Right",
}
func get_joy_button_name(button_index: int) -> String:
return CTRL_BUTTON_NAMES.get(button_index, "Btn %d" % button_index)
func get_controller_binding_text(ctrl_key: String) -> String:
"""Return the button name for a ctrl_* settings key."""
var idx = settings.controls.get(ctrl_key, -1)
if idx == -1:
return "Unbound"
return get_joy_button_name(idx)
func get_action_display(action_key: String) -> String:
"""Return keyboard text or controller button name based on use_controller setting."""
if settings.controls.get("use_controller", false):
# Map action key to its ctrl_* key
var ctrl_key_map = {
"grab": "ctrl_grab",
"use_powerup": "ctrl_use_powerup",
"tekton_grab": "ctrl_tekton_grab",
"attack_mode": "ctrl_attack_mode",
}
if ctrl_key_map.has(action_key):
return get_controller_binding_text(ctrl_key_map[action_key])
# Movement axes on left stick
if action_key.begins_with("move_"):
return "L-Stick"
return get_control_text(action_key)
return get_control_text(action_key)
func set_controller_binding(ctrl_key: String, button_index: int):
"""Save a controller button binding and re-apply input maps."""
if settings.controls.has(ctrl_key):
settings.controls[ctrl_key] = button_index
apply_control_settings()
emit_signal("control_remapped", ctrl_key, button_index)
save_settings()
func is_controller_button_used(button_index: int) -> String:
"""Check if a controller button is already assigned."""
for key in settings.controls.keys():
if key.begins_with("ctrl_") and settings.controls[key] == button_index:
return key
return ""
func get_control_keycode(action_name: String) -> int:
return settings.controls.get(action_name, -1)
+35 -42
View File
@@ -23,6 +23,7 @@ var tekton_grab_button: Button
const CONFIG_PATH = "user://touch_controls_settings.cfg"
var button_size: float = 70.0
var button_opacity: float = 0.7
var joystick_size: float = 60.0
var joystick_enabled: bool = true
var touch_buttons_enabled: bool = true # Master toggle for action buttons
var joystick_position: Vector2 = Vector2(120, -120) # Relative to bottom-left
@@ -45,20 +46,30 @@ func initialize(p_main: Node):
_load_settings()
# Connect to remapping signals
if SettingsManager and not SettingsManager.control_remapped.is_connected(_on_control_remapped):
SettingsManager.control_remapped.connect(_on_control_remapped)
if SettingsManager:
if not SettingsManager.control_remapped.is_connected(_on_control_remapped):
SettingsManager.control_remapped.connect(_on_control_remapped)
# Also refresh when settings_applied fires (e.g. use_controller toggle)
if not SettingsManager.settings_applied.is_connected(_on_settings_applied_refresh):
SettingsManager.settings_applied.connect(_on_settings_applied_refresh)
func _on_control_remapped(_action: String, _key: int):
print("[TouchControls] Control remapped: %s. Refreshing labels." % _action)
# Refresh primary assigned buttons
_refresh_all_shortcut_labels()
func _on_settings_applied_refresh():
"""Called when SettingsManager.settings_applied fires (e.g. use_controller toggled)."""
_refresh_all_shortcut_labels()
func _refresh_all_shortcut_labels():
"""Re-run _ensure_shortcut_label on all known buttons to reflect current binding mode."""
if grab_button: _ensure_shortcut_label(grab_button, "Grab")
if put_button: _ensure_shortcut_label(put_button, "Put")
if attack_mode_button: _ensure_shortcut_label(attack_mode_button, "AttackMode")
if spawn_boost_button: _ensure_shortcut_label(spawn_boost_button, "SpawnBoost")
if tekton_grab_button: _ensure_shortcut_label(tekton_grab_button, "TektonGrab")
# Also check all direct children of containers just in case
# Also walk containers for any dynamically added buttons
if power_bar_container:
for child in power_bar_container.get_children():
if child is Button:
@@ -106,35 +117,13 @@ func _create_touch_ui():
# Check if container already exists (added in scene)
var container = self
# Helper to find or create control
var find_or_create_joystick = func():
var joy = container.get_node_or_null("VirtualJoystick")
if joy:
print("[TouchControls] Found existing VirtualJoystick")
return joy
var joystick_script = load("res://scripts/ui/virtual_joystick.gd")
joy = Control.new()
joy.set_script(joystick_script)
joy.name = "VirtualJoystick"
joy.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
# Use standard size from joystick script defaults (radius 60 -> size 160)
var joy_size = Vector2(160, 160)
joy.custom_minimum_size = joy_size
joy.size = joy_size
joy.offset_left = 120
joy.offset_top = -280
joy.offset_right = 280
joy.offset_bottom = -120
container.add_child(joy)
return joy
virtual_joystick = find_or_create_joystick.call()
if not virtual_joystick.direction_changed.is_connected(_on_joystick_direction):
virtual_joystick.direction_changed.connect(_on_joystick_direction)
virtual_joystick = container.get_node_or_null("VirtualJoystick")
if virtual_joystick:
print("[TouchControls] Found local VirtualJoystick node")
if not virtual_joystick.direction_changed.is_connected(_on_joystick_direction):
virtual_joystick.direction_changed.connect(_on_joystick_direction)
else:
push_error("[TouchControls] VirtualJoystick node missing!")
# --- Actions Containers ---
power_bar_container = container.get_node_or_null("PowerBarBtn")
@@ -298,10 +287,10 @@ func _ensure_shortcut_label(btn: Button, button_name: String):
if not SettingsManager: return
match button_name:
"Grab": existing_lbl.text = SettingsManager.get_control_text("grab")
"Put": existing_lbl.text = SettingsManager.get_control_text("put")
"AttackMode": existing_lbl.text = SettingsManager.get_control_text("attack_mode")
"TektonGrab": existing_lbl.text = SettingsManager.get_control_text("tekton_grab")
"Grab": existing_lbl.text = SettingsManager.get_action_display("grab")
"Put": existing_lbl.text = SettingsManager.get_action_display("put")
"AttackMode": existing_lbl.text = SettingsManager.get_action_display("attack_mode")
"TektonGrab": existing_lbl.text = SettingsManager.get_action_display("tekton_grab")
print("[TouchControls] Updated %s shortcut label to: %s" % [button_name, existing_lbl.text])
@@ -330,10 +319,10 @@ func _ensure_shortcut_label(btn: Button, button_name: String):
shortcut_lbl.add_theme_constant_override("outline_size", 4)
match button_name:
"Grab": shortcut_lbl.text = SettingsManager.get_control_text("grab") if SettingsManager else "Space"
"Put": shortcut_lbl.text = SettingsManager.get_control_text("put") if SettingsManager else "R"
"AttackMode": shortcut_lbl.text = SettingsManager.get_control_text("attack_mode") if SettingsManager else "Q"
"TektonGrab": shortcut_lbl.text = SettingsManager.get_control_text("tekton_grab") if SettingsManager else "G"
"Grab": shortcut_lbl.text = SettingsManager.get_action_display("grab") if SettingsManager else "Space"
"Put": shortcut_lbl.text = SettingsManager.get_action_display("put") if SettingsManager else "R"
"AttackMode": shortcut_lbl.text = SettingsManager.get_action_display("attack_mode") if SettingsManager else "Q"
"TektonGrab": shortcut_lbl.text = SettingsManager.get_action_display("tekton_grab") if SettingsManager else "G"
btn.add_child(shortcut_lbl)
@@ -434,6 +423,7 @@ func _load_settings():
button_opacity = config.get_value("touch_controls", "button_opacity", 0.7)
button_scale = config.get_value("touch_controls", "button_scale", 1.0)
joystick_enabled = config.get_value("touch_controls", "joystick_enabled", true)
joystick_size = config.get_value("touch_controls", "joystick_size", 60.0)
touch_buttons_enabled = config.get_value("touch_controls", "touch_buttons_enabled", true)
# Load button positions
@@ -463,6 +453,7 @@ func _save_settings():
config.set_value("touch_controls", "button_opacity", button_opacity)
config.set_value("touch_controls", "button_scale", button_scale)
config.set_value("touch_controls", "joystick_enabled", joystick_enabled)
config.set_value("touch_controls", "joystick_size", joystick_size)
config.set_value("touch_controls", "touch_buttons_enabled", touch_buttons_enabled)
config.set_value("touch_controls", "grab_position", button_positions.grab)
config.set_value("touch_controls", "put_position", button_positions.put)
@@ -480,6 +471,8 @@ func _apply_settings():
# Apply joystick visibility
if virtual_joystick:
virtual_joystick.visible = joystick_enabled and _is_touch_device()
if virtual_joystick.has_method("set_radius"):
virtual_joystick.set_radius(joystick_size)
# Apply touch buttons visibility - FORCED ON per request to "just show them"
# Apply touch buttons visibility
+1 -1
View File
@@ -30,7 +30,7 @@ var _previous_playerboard_state: Array = []
func initialize(player_node):
# Get PowerUp Inventory UI from scene
powerup_inventory_ui = player_node.get_node_or_null("PowerUpInventoryUI")
powerup_inventory_ui = player_node.get_node_or_null("TouchLayer/TouchControls/PowerUpInventoryUI")
# Get node references from main scene
playerboard_ui = player_node.get_node_or_null("PlayerBoardUI/PlayerboardUI")
+13 -2
View File
@@ -202,6 +202,7 @@ func _process(delta):
var mesh_cache: Array[MeshInstance3D] = []
var original_scales: Array[Vector3] = []
var prompt_container: Node3D
var _prompt_key_label: Label = null # cached ref for live refresh
@onready var SettingsManager = get_node_or_null("/root/SettingsManager")
func _update_prompt_label():
@@ -245,13 +246,23 @@ func _ready():
prompt_container.visible = false
var key_label = prompt_container.get_node_or_null("KeyLabel")
if key_label:
_prompt_key_label = key_label
var shortcut_text = "G"
if SettingsManager and SettingsManager.has_method("get_control_text"):
shortcut_text = SettingsManager.get_control_text("tekton_grab")
if SettingsManager and SettingsManager.has_method("get_action_display"):
shortcut_text = SettingsManager.get_action_display("tekton_grab")
key_label.text = "[ " + str(shortcut_text) + " ]"
# Listen for controller mode change to refresh live
if SettingsManager and not SettingsManager.settings_applied.is_connected(_on_settings_refresh):
SettingsManager.settings_applied.connect(_on_settings_refresh)
else:
push_warning("[Tekton] 'InteractionPrompt' node missing. UI will not appear.")
func _on_settings_refresh():
"""Called when settings_applied fires - refresh the interaction prompt key label."""
if _prompt_key_label and SettingsManager:
var shortcut_text = SettingsManager.get_action_display("tekton_grab")
_prompt_key_label.text = "[ " + shortcut_text + " ]"
func _cache_meshes(node: Node):
if node is MeshInstance3D:
mesh_cache.append(node)
+15 -8
View File
@@ -24,15 +24,18 @@ signal effect_selected(effect: int)
func _ready():
print("[PowerUpUI] _ready called")
# Connect to SettingsManager to update labels
if SettingsManager and not SettingsManager.control_remapped.is_connected(_on_control_remapped):
SettingsManager.control_remapped.connect(_on_control_remapped)
# Connect to SettingsManager to update labels on rebind OR controller toggle
if SettingsManager:
if not SettingsManager.control_remapped.is_connected(_on_control_remapped):
SettingsManager.control_remapped.connect(_on_control_remapped)
if not SettingsManager.settings_applied.is_connected(_on_control_remapped_refresh):
SettingsManager.settings_applied.connect(_on_control_remapped_refresh)
# New Single Button UI
power_up_button = get_node_or_null("PowerUpBtn")
# New Single Button UI (moved to InteractionBtn)
power_up_button = get_node_or_null("../InteractionBtn/PowerUpBtn")
if not power_up_button:
# Fallback to Container/PowerUpBtn just in case
power_up_button = get_node_or_null("Container/PowerUpBtn")
# Fallback just in case
power_up_button = get_node_or_null("PowerUpBtn")
if not power_up_button:
print("[PowerUpUI] ERROR: PowerUpBtn not found")
@@ -51,6 +54,10 @@ func _on_control_remapped(_action: String, _key: int):
# Refresh all labels
_update_shortcuts_for_mode(LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO))
func _on_control_remapped_refresh():
"""Called when settings_applied fires (e.g. use_controller toggled)."""
_update_shortcuts_for_mode(LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO))
func _setup_powerup_btn(btn: Button):
# Start DISABLED
btn.disabled = true
@@ -105,7 +112,7 @@ func _update_btn_shortcut(btn: Button):
return
# Show universal powerup shortcut
sc_lbl.text = " %s " % SettingsManager.get_control_text("use_powerup")
sc_lbl.text = " %s " % SettingsManager.get_action_display("use_powerup")
func _on_btn_pressed(effect_id: int = -1):
var target_effect = effect_id if effect_id != -1 else current_effect
+170 -14
View File
@@ -26,6 +26,25 @@ var listening_action: String = "" # Set when waiting for a keypress
# Keys removed from the game - skip them even if stale user config has them
const DEPRECATED_ACTIONS: Array = ["put", "put_alt"]
# Touch Input Controls
@onready var joystick_size_slider = %JoystickSizeSlider
@onready var joystick_size_value = %JoystickSizeValue
@onready var joystick_enabled_toggle = %JoystickEnabledToggle
@onready var button_opacity_slider = %ButtonOpacitySlider
@onready var button_opacity_value = %ButtonOpacityValue
@onready var touch_buttons_enabled_toggle = %TouchButtonsEnabledToggle
const TOUCH_CONFIG_PATH = "user://touch_controls_settings.cfg"
# Controller Rebinding
@onready var ctrl_grab_btn = %CtrlGrabBtn
@onready var ctrl_powerup_btn = %CtrlPowerupBtn
@onready var ctrl_tekton_grab_btn = %CtrlTektonGrabBtn
@onready var ctrl_attack_btn = %CtrlAttackBtn
@onready var ctrl_reset_btn = %CtrlResetBtn
var listening_ctrl_key: String = "" # ctrl_* key being rebound
func _ready():
# Theme inheritance is broken by CanvasLayer root, no need for theme = null
_load_ui_values()
@@ -87,6 +106,33 @@ func _load_ui_values():
# Controls
use_controller_btn.button_pressed = s.controls.get("use_controller", false)
_update_all_key_labels()
# Touch Input
_load_touch_ui_values()
# Controller Bindings
_update_all_ctrl_labels()
func _load_touch_ui_values():
"""Load touch control settings from config file."""
var config = ConfigFile.new()
var joystick_size: float = 60.0
var joystick_on: bool = true
var btn_opacity: float = 0.7
var touch_btns_on: bool = true
if config.load(TOUCH_CONFIG_PATH) == OK:
joystick_size = config.get_value("touch_controls", "joystick_size", 60.0)
joystick_on = config.get_value("touch_controls", "joystick_enabled", true)
btn_opacity = config.get_value("touch_controls", "button_opacity", 0.7)
touch_btns_on = config.get_value("touch_controls", "touch_buttons_enabled", true)
joystick_size_slider.value = joystick_size
joystick_size_value.text = str(int(joystick_size))
joystick_enabled_toggle.button_pressed = joystick_on
button_opacity_slider.value = btn_opacity
button_opacity_value.text = str(int(btn_opacity * 100)) + "%"
touch_buttons_enabled_toggle.button_pressed = touch_btns_on
func _connect_signals():
# Video
@@ -105,8 +151,21 @@ func _connect_signals():
# Controls
use_controller_btn.toggled.connect(_on_control_setting_changed.bind("use_controller"))
# Touch Input
joystick_size_slider.value_changed.connect(_on_joystick_size_changed)
joystick_enabled_toggle.toggled.connect(_on_touch_toggle_changed.bind("joystick_enabled"))
button_opacity_slider.value_changed.connect(_on_button_opacity_changed)
touch_buttons_enabled_toggle.toggled.connect(_on_touch_toggle_changed.bind("touch_buttons_enabled"))
# Controller Rebinding
ctrl_grab_btn.pressed.connect(_on_ctrl_remap_pressed.bind("ctrl_grab"))
ctrl_powerup_btn.pressed.connect(_on_ctrl_remap_pressed.bind("ctrl_use_powerup"))
ctrl_tekton_grab_btn.pressed.connect(_on_ctrl_remap_pressed.bind("ctrl_tekton_grab"))
ctrl_attack_btn.pressed.connect(_on_ctrl_remap_pressed.bind("ctrl_attack_mode"))
ctrl_reset_btn.pressed.connect(_on_ctrl_reset_pressed)
# Close
close_button.pressed.connect(func(): visible = false)
close_button.pressed.connect(func(): listening_ctrl_key = ""; visible = false)
# Connect remapping buttons
for action_name in SettingsManager.settings.controls.keys():
@@ -153,6 +212,54 @@ func _on_audio_setting_changed(value: float, key: String):
func _on_control_setting_changed(value: bool, key: String):
SettingsManager.settings.controls[key] = value
SettingsManager.save_settings()
# Emit settings_applied so all UI (touch buttons, prompts) refresh their shortcut labels
if key == "use_controller":
SettingsManager.apply_control_settings()
SettingsManager.emit_signal("settings_applied")
func _on_joystick_size_changed(value: float):
joystick_size_value.text = str(int(value))
_save_touch_value("joystick_size", value)
# Live update the joystick if it's in the scene
var tc = _get_touch_controls()
if tc:
tc.joystick_size = value
if tc.virtual_joystick and tc.virtual_joystick.has_method("set_radius"):
tc.virtual_joystick.set_radius(value)
func _on_button_opacity_changed(value: float):
button_opacity_value.text = str(int(value * 100)) + "%"
_save_touch_value("button_opacity", value)
var tc = _get_touch_controls()
if tc:
tc.button_opacity = value
if tc.has_method("_apply_settings"):
tc._apply_settings()
func _on_touch_toggle_changed(state: bool, key: String):
_save_touch_value(key, state)
var tc = _get_touch_controls()
if tc:
if key == "joystick_enabled":
tc.joystick_enabled = state
elif key == "touch_buttons_enabled":
tc.touch_buttons_enabled = state
if tc.has_method("_apply_settings"):
tc._apply_settings()
func _save_touch_value(key: String, value) -> void:
"""Save a single touch config key without overwriting other keys."""
var config = ConfigFile.new()
config.load(TOUCH_CONFIG_PATH) # Load existing (ignore error if not found)
config.set_value("touch_controls", key, value)
config.save(TOUCH_CONFIG_PATH)
func _get_touch_controls() -> Node:
"""Try to find the TouchControls node in the Main scene."""
var main = get_tree().get_root().get_node_or_null("Main")
if main:
return main.get_node_or_null("TouchLayer/TouchControls")
return null
func _on_remap_button_pressed(action_name: String):
listening_action = action_name
@@ -162,40 +269,51 @@ func _on_remap_button_pressed(action_name: String):
btn.modulate = Color(0.5, 1.0, 0.5) # Signal "Listening"
func _input(event):
# Keyboard remapping
if listening_action != "" and event is InputEventKey and event.pressed:
# Capture the key
var keycode = event.keycode
# PREVENT DUPLICATES (User Request)
var existing_action = SettingsManager.is_key_used(keycode)
if existing_action != "" and existing_action != listening_action:
# Visual Feedback for Error
var error_btn = get_node_or_null("%" + listening_action.to_pascal_case() + "Btn")
if error_btn:
error_btn.text = "ALREADY USED!"
error_btn.modulate = Color(1.0, 0.3, 0.3) # Red error
# Play sound if available
error_btn.modulate = Color(1.0, 0.3, 0.3)
var sfx = get_node_or_null("/root/SfxManager")
if sfx and sfx.has_method("play_rpc"):
sfx.rpc("play_rpc", "error") # Assumes an error sound exists
# Reset listening but keep text for briefly before reverting
sfx.rpc("play_rpc", "error")
listening_action = ""
await get_tree().create_timer(1.2).timeout
_update_all_key_labels()
get_viewport().set_input_as_handled()
return
# Proceed with remapping if not a duplicate
SettingsManager.set_control(listening_action, keycode)
# Feedback and Reset
_update_key_label(listening_action)
listening_action = ""
get_viewport().set_input_as_handled()
# Controller button remapping
if listening_ctrl_key != "" and event is InputEventJoypadButton and event.pressed:
var btn_idx = event.button_index
# Consume event to prevent triggers
# Duplicate check
var existing = SettingsManager.is_controller_button_used(btn_idx)
var ctrl_btn = _get_ctrl_btn(listening_ctrl_key)
if existing != "" and existing != listening_ctrl_key:
if ctrl_btn:
ctrl_btn.text = "ALREADY USED!"
ctrl_btn.modulate = Color(1.0, 0.3, 0.3)
listening_ctrl_key = ""
await get_tree().create_timer(1.2).timeout
_update_all_ctrl_labels()
get_viewport().set_input_as_handled()
return
SettingsManager.set_controller_binding(listening_ctrl_key, btn_idx)
listening_ctrl_key = ""
_update_all_ctrl_labels()
get_viewport().set_input_as_handled()
func _update_all_key_labels():
@@ -210,6 +328,44 @@ func _update_key_label(action_name: String):
btn.text = SettingsManager.get_control_text(action_name)
btn.modulate = Color.WHITE
func _update_all_ctrl_labels():
"""Update all controller button labels from saved settings."""
if not SettingsManager: return
ctrl_grab_btn.text = SettingsManager.get_controller_binding_text("ctrl_grab")
ctrl_grab_btn.modulate = Color.WHITE
ctrl_powerup_btn.text = SettingsManager.get_controller_binding_text("ctrl_use_powerup")
ctrl_powerup_btn.modulate = Color.WHITE
ctrl_tekton_grab_btn.text = SettingsManager.get_controller_binding_text("ctrl_tekton_grab")
ctrl_tekton_grab_btn.modulate = Color.WHITE
ctrl_attack_btn.text = SettingsManager.get_controller_binding_text("ctrl_attack_mode")
ctrl_attack_btn.modulate = Color.WHITE
func _on_ctrl_remap_pressed(ctrl_key: String):
listening_ctrl_key = ctrl_key
var btn = _get_ctrl_btn(ctrl_key)
if btn:
btn.text = "Press a button..."
btn.modulate = Color(0.5, 1.0, 0.5)
func _get_ctrl_btn(ctrl_key: String) -> Button:
match ctrl_key:
"ctrl_grab": return ctrl_grab_btn
"ctrl_use_powerup": return ctrl_powerup_btn
"ctrl_tekton_grab": return ctrl_tekton_grab_btn
"ctrl_attack_mode": return ctrl_attack_btn
return null
func _on_ctrl_reset_pressed():
"""Reset controller bindings to defaults."""
if not SettingsManager: return
SettingsManager.settings.controls["ctrl_grab"] = JOY_BUTTON_A
SettingsManager.settings.controls["ctrl_use_powerup"] = JOY_BUTTON_Y
SettingsManager.settings.controls["ctrl_tekton_grab"] = JOY_BUTTON_RIGHT_SHOULDER
SettingsManager.settings.controls["ctrl_attack_mode"] = JOY_BUTTON_X
SettingsManager.apply_control_settings()
SettingsManager.save_settings()
_update_all_ctrl_labels()
func open():
_load_ui_values()
visible = true
+16 -2
View File
@@ -27,14 +27,28 @@ var _repeat_timer: float = 0.0
var _initial_repeat: bool = true
func _ready():
# Set minimum size for touch target
custom_minimum_size = Vector2(joystick_radius * 2 + 40, joystick_radius * 2 + 40)
_update_minimum_size()
center_position = size / 2
# Enable touch input
mouse_filter = Control.MOUSE_FILTER_STOP
set_process(true)
func set_radius(new_radius: float):
joystick_radius = new_radius
# Proportional knob
knob_radius = new_radius * (25.0 / 60.0)
_update_minimum_size()
# Optional: recalculate center if already initialized
if is_inside_tree():
center_position = size / 2
queue_redraw()
func _update_minimum_size():
custom_minimum_size = Vector2(joystick_radius * 2 + 40, joystick_radius * 2 + 40)
size = custom_minimum_size
func _draw():
# Draw base circle
var base_circle_color = pressed_color if is_pressed else base_color