feat: update vfx
This commit is contained in:
@@ -140,6 +140,10 @@ var _bot_names: Dictionary = {}
|
||||
# Room list filter ("" = all, "Freemode", "Stop n Go", etc.)
|
||||
var _room_mode_filter: String = ""
|
||||
|
||||
# Re-entry guard for the async host flow (prevents double-click from starting
|
||||
# two overlapping create_match() calls).
|
||||
var _is_hosting: bool = false
|
||||
|
||||
# =============================================================================
|
||||
# Chat System
|
||||
# =============================================================================
|
||||
@@ -248,6 +252,13 @@ func _ready():
|
||||
# Connect UserProfileManager signals
|
||||
UserProfileManager.profile_loaded.connect(func(_p): _sync_room_profile_card())
|
||||
UserProfileManager.profile_updated.connect(func(): _sync_room_profile_card())
|
||||
|
||||
# Clear the host re-entry guard whenever the host flow concludes — success,
|
||||
# failure, or leaving the room.
|
||||
LobbyManager.room_joined.connect(func(_r): _is_hosting = false)
|
||||
LobbyManager.room_left.connect(func(): _is_hosting = false)
|
||||
NakamaManager.match_join_error.connect(func(_e): _is_hosting = false)
|
||||
NakamaManager.connection_failed.connect(func(_e): _is_hosting = false)
|
||||
|
||||
# Connect Mailbox UI
|
||||
if MailManager:
|
||||
|
||||
+138
@@ -1919,6 +1919,144 @@ func sync_grid_item(x: int, y: int, z: int, item: int):
|
||||
if enhanced_gridmap.has_method("update_grid_data"):
|
||||
enhanced_gridmap.update_grid_data()
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func play_freeze_floor_vfx(center_x: int, center_z: int, radius: int, duration: float) -> void:
|
||||
# Spawns a flat freeze-floor AnimatedSprite3D that covers the (2*radius+1)^2
|
||||
# frozen area, centered on the given grid cell and sitting just above the
|
||||
# floor surface. The template under vfxController/AnimatedSprite3D (hidden) is
|
||||
# laid flat and sized for ~1 tile; we duplicate it, then size it to the area
|
||||
# from its measured footprint. Runs on every peer.
|
||||
var vfx_root := get_node_or_null("vfxController")
|
||||
if not vfx_root:
|
||||
return
|
||||
var template := vfx_root.get_node_or_null("AnimatedSprite3D") as AnimatedSprite3D
|
||||
if not template:
|
||||
return
|
||||
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
if not enhanced_gridmap:
|
||||
return
|
||||
var cell: Vector3 = enhanced_gridmap.cell_size
|
||||
|
||||
var vfx := template.duplicate() as AnimatedSprite3D
|
||||
|
||||
# --- Scale to cover the whole area -------------------------------------
|
||||
# The template's world footprint = its local sprite size (texture * pixel_size,
|
||||
# from the AABB) times each basis axis length. Scale each flat axis (X = width,
|
||||
# Y = depth, since the sprite is rotated to lie flat) so it spans the area.
|
||||
# AREA_SIZE_FACTOR oversizes slightly so the visible art (which has transparent
|
||||
# padding inside the frame) actually fills the (2*radius+1)-tile region — tune
|
||||
# this if it reads a touch small or large.
|
||||
const AREA_SIZE_FACTOR := 1.25
|
||||
var aabb := template.get_aabb()
|
||||
var b := template.transform.basis
|
||||
var base_w: float = absf(aabb.size.x) * b.x.length()
|
||||
var base_d: float = absf(aabb.size.y) * b.y.length()
|
||||
var want_w: float = float(2 * radius + 1) * cell.x * AREA_SIZE_FACTOR
|
||||
var want_d: float = float(2 * radius + 1) * cell.z * AREA_SIZE_FACTOR
|
||||
if base_w > 0.0001:
|
||||
b.x = b.x * (want_w / base_w)
|
||||
if base_d > 0.0001:
|
||||
b.y = b.y * (want_d / base_d)
|
||||
|
||||
# --- World center of the freeze area -----------------------------------
|
||||
# X/Z use the same convention players use (grid_to_world): cell center =
|
||||
# index*size + half a cell. Y is taken from the template's own position in the
|
||||
# scene, so the height can be tuned in the editor (move vfxController/
|
||||
# AnimatedSprite3D up/down) without touching code. vfxController/Main sit at
|
||||
# the origin, so this local point is also the world point.
|
||||
var world_center := Vector3(
|
||||
center_x * cell.x + cell.x * 0.5,
|
||||
template.position.y,
|
||||
center_z * cell.z + cell.z * 0.5
|
||||
)
|
||||
|
||||
# Assign basis + origin together in one shot so nothing overwrites the position.
|
||||
vfx.transform = Transform3D(b, world_center)
|
||||
vfx.visible = true
|
||||
vfx_root.add_child(vfx)
|
||||
vfx.play()
|
||||
|
||||
print("[FreezeVFX] center cell=(%d,%d) -> world=%s, scale=(%.2f x %.2f)" % [center_x, center_z, world_center, want_w, want_d])
|
||||
|
||||
await get_tree().create_timer(duration).timeout
|
||||
|
||||
if is_instance_valid(vfx):
|
||||
vfx.queue_free()
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func play_block_floor_vfx(cells: PackedVector2Array, duration: float) -> void:
|
||||
# Spawns one box_block VFX per blocked cell (each covers 1x1), autoplaying its
|
||||
# wall animation. The template under vfxController/box_block (hidden) is sized
|
||||
# for one cell; we duplicate it per cell, keeping its Y/scale from the scene so
|
||||
# height can be tuned in the editor. Runs on every peer.
|
||||
var vfx_root := get_node_or_null("vfxController")
|
||||
if not vfx_root:
|
||||
return
|
||||
var template := vfx_root.get_node_or_null("box_block")
|
||||
if not template:
|
||||
return
|
||||
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
if not enhanced_gridmap:
|
||||
return
|
||||
var cell: Vector3 = enhanced_gridmap.cell_size
|
||||
|
||||
var spawned: Array = []
|
||||
for c in cells:
|
||||
# DUPLICATE_USE_INSTANTIATION so the instanced glb subtree (incl. its
|
||||
# AnimationPlayer) is recreated in the copy rather than dropped.
|
||||
var box := template.duplicate(DUPLICATE_USE_INSTANTIATION)
|
||||
# X/Z = cell center (same convention as players), Y/scale kept from template.
|
||||
var pos := Vector3(
|
||||
int(c.x) * cell.x + cell.x * 0.5,
|
||||
template.position.y,
|
||||
int(c.y) * cell.z + cell.z * 0.5
|
||||
)
|
||||
box.transform = Transform3D(template.transform.basis, pos)
|
||||
box.visible = true
|
||||
vfx_root.add_child(box)
|
||||
_autoplay_vfx_animation(box)
|
||||
spawned.append(box)
|
||||
|
||||
await get_tree().create_timer(duration).timeout
|
||||
|
||||
for box in spawned:
|
||||
if is_instance_valid(box):
|
||||
box.queue_free()
|
||||
|
||||
func _autoplay_vfx_animation(node: Node) -> void:
|
||||
# Find the AnimationPlayer Godot creates for an imported glb/scene and play its
|
||||
# first clip once (one-shot) when the VFX is spawned.
|
||||
var anim_player := node.get_node_or_null("AnimationPlayer") as AnimationPlayer
|
||||
if not anim_player:
|
||||
for child in node.get_children():
|
||||
if child is AnimationPlayer:
|
||||
anim_player = child
|
||||
break
|
||||
if not anim_player:
|
||||
return
|
||||
var list := anim_player.get_animation_list()
|
||||
if list.is_empty():
|
||||
return
|
||||
var anim_name: String = list[0]
|
||||
var anim := anim_player.get_animation(anim_name)
|
||||
if anim:
|
||||
anim.loop_mode = Animation.LOOP_NONE
|
||||
anim_player.play(anim_name)
|
||||
|
||||
func play_playerboard_scatter_vfx() -> void:
|
||||
# One-shot "scatter" animation over the local player's board UI. Triggered for
|
||||
# the player whose tiles were scattered (caught outside the safe zone in
|
||||
# Stop n Go). The clip is already non-looping in the SpriteFrames.
|
||||
var vfx := get_node_or_null("PlayerBoardUI/AnimatedSprite2D") as AnimatedSprite2D
|
||||
if not vfx:
|
||||
return
|
||||
vfx.visible = true
|
||||
vfx.play("scatter")
|
||||
await vfx.animation_finished
|
||||
vfx.visible = false
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_grid_items_batch(data: Array):
|
||||
# data is an array of dictionaries: [{x: int, y: int, z: int, item: int}, ...]
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
[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="Texture2D" uid="uid://byh7506oksbhb" path="res://assets/graphics/vfx/tile_vfx_freeze/freezebawah.png" id="2_2cjbq"]
|
||||
[ext_resource type="PackedScene" uid="uid://d3m0u8gl5odhw" path="res://assets/models/meshes/box_block.tscn" id="2_chjal"]
|
||||
[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="StyleBox" uid="uid://dlw1ogamn741n" path="res://assets/styles/box_flat.tres" id="5_dvx6y"]
|
||||
@@ -14,6 +16,7 @@
|
||||
[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://cmoyhmh4jpep0" path="res://assets/graphics/vfx/playerboard_scatter.png" id="14_5poiv"]
|
||||
[ext_resource type="Texture2D" uid="uid://bafocgx2apwjm" path="res://assets/graphics/gui/stop_timer/Segment0_empty.png" id="14_fv21b"]
|
||||
[ext_resource type="Texture2D" uid="uid://c4xpg3j7p7g33" path="res://assets/graphics/gui/global_match_timer/timer.png" id="14_tel4y"]
|
||||
[ext_resource type="Texture2D" uid="uid://73ayhl1lqdpt" path="res://assets/graphics/gui/gauge/PowerLabel.png" id="14_vxglm"]
|
||||
@@ -41,6 +44,316 @@
|
||||
[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="AtlasTexture" id="AtlasTexture_0loja"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(0, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ids8r"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(500, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_dnhof"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1000, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1v6qk"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1500, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_augu2"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2000, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_tm6hj"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2500, 0, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kf5aa"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(0, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_t5ykj"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(500, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_e755i"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1000, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ro3en"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1500, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_od4ux"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2000, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xhfw6"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2500, 500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1epgm"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(0, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_152kg"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(500, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_r4e17"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1000, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_y57op"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1500, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_mlv25"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2000, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_a82wo"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2500, 1000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_gdvew"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(0, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kjtvk"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(500, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xrs0c"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1000, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xljpf"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1500, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j4bwh"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2000, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ksmap"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2500, 1500, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ygd8o"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(0, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2s0kr"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(500, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xaipn"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1000, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ndrjj"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(1500, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ih3m7"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2000, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_11yus"]
|
||||
atlas = ExtResource("2_2cjbq")
|
||||
region = Rect2(2500, 2000, 500, 500)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_5poiv"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_0loja")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ids8r")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_dnhof")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_1v6qk")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_augu2")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_tm6hj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_kf5aa")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_t5ykj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_e755i")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ro3en")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_od4ux")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xhfw6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_1epgm")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_152kg")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_r4e17")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_y57op")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_mlv25")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_a82wo")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_gdvew")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_kjtvk")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xrs0c")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xljpf")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_j4bwh")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ksmap")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ygd8o")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_2s0kr")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xaipn")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ndrjj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ih3m7")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_11yus")
|
||||
}],
|
||||
"loop": false,
|
||||
"name": &"freeze_floor",
|
||||
"speed": 15.0
|
||||
}]
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2cjbq"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(0, 0, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_chjal"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(357, 0, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_cjqg0"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(714, 0, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vchkt"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(1071, 0, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_txyw0"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(0, 340, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vc5cj"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(357, 340, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_nvyfr"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(714, 340, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ty1g6"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(1071, 340, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j2jfr"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(0, 680, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bjg73"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(357, 680, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bu4jf"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(714, 680, 357, 340)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_o7ddy"]
|
||||
atlas = ExtResource("14_5poiv")
|
||||
region = Rect2(1071, 680, 357, 340)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_0loja"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_2cjbq")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_chjal")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_cjqg0")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_vchkt")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_txyw0")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_vc5cj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_nvyfr")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ty1g6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_j2jfr")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bjg73")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bu4jf")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_o7ddy")
|
||||
}],
|
||||
"loop": false,
|
||||
"name": &"scatter",
|
||||
"speed": 30.0
|
||||
}]
|
||||
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_c6pm6"]
|
||||
content_margin_bottom = 20.0
|
||||
texture = ExtResource("14_tel4y")
|
||||
@@ -104,6 +417,20 @@ texture = SubResource("CompressedTexture2D_chjal")
|
||||
[node name="Main" type="Node3D" unique_id=864552263]
|
||||
script = ExtResource("1_xcpe3")
|
||||
|
||||
[node name="vfxController" type="Node3D" parent="." unique_id=968868013]
|
||||
|
||||
[node name="box_block" parent="vfxController" unique_id=1480078977 instance=ExtResource("2_chjal")]
|
||||
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0.35, 0.5)
|
||||
visible = false
|
||||
|
||||
[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="vfxController" unique_id=1360317189]
|
||||
transform = Transform3D(0.2, 0, 0, 0, -8.742278e-09, 0.15, 0, -0.2, -6.5567085e-09, 0.5, 0.4, 0.5)
|
||||
visible = false
|
||||
sprite_frames = SubResource("SpriteFrames_5poiv")
|
||||
animation = &"freeze_floor"
|
||||
frame = 29
|
||||
frame_progress = 1.0
|
||||
|
||||
[node name="EnhancedGridMap" type="GridMap" parent="." unique_id=1838552857]
|
||||
mesh_library = ExtResource("1_110wo")
|
||||
cell_size = Vector3(1, 0.2, 1)
|
||||
@@ -1077,6 +1404,14 @@ theme_override_fonts/font = ExtResource("13_j8jky")
|
||||
theme_override_font_sizes/font_size = 32
|
||||
text = "X0"
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="PlayerBoardUI" unique_id=390404299]
|
||||
visible = false
|
||||
position = Vector2(117.56293, 165.96373)
|
||||
sprite_frames = SubResource("SpriteFrames_0loja")
|
||||
animation = &"scatter"
|
||||
frame = 11
|
||||
frame_progress = 1.0
|
||||
|
||||
[node name="GlobalMatchTimer" type="PanelContainer" parent="." unique_id=1714357974]
|
||||
custom_minimum_size = Vector2(372, 162)
|
||||
anchors_preset = 5
|
||||
|
||||
@@ -413,6 +413,18 @@ func play_scatter_knock():
|
||||
await vfx_scatter_knock.animation_finished
|
||||
vfx_scatter_knock.visible = false
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func play_playerboard_scatter():
|
||||
"""Show the one-shot scatter VFX over the playerboard UI, but only on the
|
||||
local human player's own client (the board UI belongs to them)."""
|
||||
var is_local = name == str(multiplayer.get_unique_id())
|
||||
var is_bot_check = is_bot or is_in_group("Bots")
|
||||
if not is_local or is_bot_check:
|
||||
return
|
||||
var main = get_tree().get_root().get_node_or_null("Main")
|
||||
if main and main.has_method("play_playerboard_scatter_vfx"):
|
||||
main.play_playerboard_scatter_vfx()
|
||||
|
||||
func _init_managers():
|
||||
movement_manager = load("res://scripts/managers/player_movement_manager.gd").new()
|
||||
movement_manager.name = "MovementManager"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://dyovwailce5tf" path="res://scripts/tekton.gd" id="1_tekton"]
|
||||
[ext_resource type="Script" uid="uid://c67yq846u8y68" path="res://scripts/tekton_controller.gd" id="2_controller"]
|
||||
[ext_resource type="PackedScene" uid="uid://statictektonmesh001" path="res://scenes/static_tekton_mesh.tscn" id="3_d2kpk"]
|
||||
[ext_resource type="PackedScene" uid="uid://df7h7y7y7y7y7" path="res://scenes/static_tekton_mesh.tscn" id="3_d2kpk"]
|
||||
[ext_resource type="Texture2D" uid="uid://biun2yvglxgij" path="res://assets/graphics/touch_control/grab_tekton.png" id="4_grab_icon"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_tekton"]
|
||||
@@ -17,6 +17,7 @@ script = ExtResource("2_controller")
|
||||
[node name="Visuals" type="Node3D" parent="." unique_id=1698719440]
|
||||
|
||||
[node name="tekton" parent="Visuals" unique_id=2052742928 instance=ExtResource("3_d2kpk")]
|
||||
transform = Transform3D(-0.2, 0, -1.7484556e-08, 0, 0.2, 0, 1.7484556e-08, 0, -0.2, 0, 0, 0)
|
||||
|
||||
[node name="HitArea" type="Area3D" parent="." unique_id=2139590311]
|
||||
collision_layer = 4
|
||||
|
||||
@@ -72,6 +72,13 @@ func on_create_room_pressed() -> void:
|
||||
lobby._sync_room_profile_card()
|
||||
|
||||
func host_room(game_mode: String) -> void:
|
||||
# Guard against double-clicks: the create flow is async, and a second press
|
||||
# before it finishes re-enters create_match() while the bridge is still
|
||||
# JOINING, which throws "Cannot create match when state is JOINING".
|
||||
if lobby._is_hosting:
|
||||
return
|
||||
lobby._is_hosting = true
|
||||
|
||||
if AuthManager.is_guest:
|
||||
if LobbyManager.local_player_name.is_empty() or LobbyManager.local_player_name == "Player":
|
||||
LobbyManager.local_player_name = NameGenerator.generate_guest_name()
|
||||
@@ -92,6 +99,7 @@ func host_room(game_mode: String) -> void:
|
||||
var ok = await LobbyManager.create_room_lan(room_label)
|
||||
if not ok:
|
||||
lobby.connection_status.text = "Failed to start LAN room. Check port 7777."
|
||||
lobby._is_hosting = false
|
||||
else:
|
||||
lobby.connection_status.text = "Creating Nakama room..."
|
||||
var room_label := "%sRoom %d" % [mode_prefix, randi_range(1000, 9999)]
|
||||
|
||||
Reference in New Issue
Block a user