feat: Introduce an EnhancedGridMap with advanced grid generation, randomization, and data serialization features, along with a default MeshLibrary and a new main scene script.
This commit is contained in:
@@ -182,6 +182,38 @@ func clear_grid(floor_index: int = -1):
|
||||
clear_floor(floor_index)
|
||||
update_grid_data()
|
||||
|
||||
# =============================================================================
|
||||
# Data Serialization Helpers (For Networking)
|
||||
# =============================================================================
|
||||
|
||||
func get_floor_data(floor_index: int) -> PackedInt32Array:
|
||||
# Returns a flat PackedInt32Array [x, z, item_id, ...] for the specified floor.
|
||||
var data = PackedInt32Array()
|
||||
# Use get_used_cells() as the source of truth from the GridMap itself
|
||||
for cell in get_used_cells():
|
||||
if cell.y == floor_index:
|
||||
data.append(cell.x)
|
||||
data.append(cell.z)
|
||||
data.append(get_cell_item(cell))
|
||||
return data
|
||||
|
||||
func set_floor_data(floor_index: int, data: PackedInt32Array):
|
||||
# Sets the floor items from a flat PackedInt32Array. Clears existing items on that floor first.
|
||||
clear_floor(floor_index)
|
||||
# Iterate by triplets [x, z, item]
|
||||
var count = data.size()
|
||||
if count % 3 != 0:
|
||||
print("[EnhancedGridMap] Error: Malformed grid data array (size %d not divisible by 3)" % count)
|
||||
return
|
||||
|
||||
for i in range(0, count, 3):
|
||||
var x = data[i]
|
||||
var z = data[i+1]
|
||||
var item = data[i+2]
|
||||
set_cell_item(Vector3i(x, floor_index, z), item)
|
||||
|
||||
update_grid_data()
|
||||
|
||||
func fill_grid(item_index: int, floor_index: int = -1):
|
||||
if not mesh_library:
|
||||
print("No MeshLibrary assigned to GridMap")
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
[ext_resource type="ArrayMesh" uid="uid://brevl3ab0tdqe" path="res://assets/models/tiles/tile_wall.tres" id="4_8v5xv"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://b5ta7tcw0iscd" path="res://assets/models/tiles/tile_coin.tres" id="4_76xkl"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://d4himvyb81in8" path="res://assets/models/meshes/non-walkable.res" id="4_sx8rm"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://dr80txgr61irt" path="res://assets/models/tiles/tile_diamond.tres" id="5_j2mx0"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://dr80txgr61irt" path="res://assets/models/tiles/tile_area_freeze.tres" id="5_sx8rm"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://dr80txgr61irt" path="res://assets/models/tiles/tile_diamond.tres" id="5_sx8rm"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://bqvqj3fhf5x51" path="res://assets/models/tiles/tile_ghost.tres" id="6_r32il"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://cv4bedhida00g" path="res://assets/models/tiles/tile_star.tres" id="7_p5epg"]
|
||||
|
||||
@@ -151,7 +150,7 @@ item/7/shapes = []
|
||||
item/7/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
item/7/navigation_layers = 1
|
||||
item/8/name = "tile_diamond"
|
||||
item/8/mesh = ExtResource("5_j2mx0")
|
||||
item/8/mesh = ExtResource("5_sx8rm")
|
||||
item/8/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
item/8/mesh_cast_shadow = 1
|
||||
item/8/shapes = []
|
||||
|
||||
@@ -463,6 +463,10 @@ func _setup_client_game():
|
||||
# Wait shorter time for host to be ready, then request full sync to correct positions/state
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
rpc_id(1, "request_full_player_sync", my_id)
|
||||
|
||||
# Only request grid if we remain connected
|
||||
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
|
||||
rpc_id(1, "request_full_grid_sync")
|
||||
|
||||
func _auto_start_from_lobby():
|
||||
"""Called when main.tscn is loaded from lobby - game is already connected."""
|
||||
@@ -1032,6 +1036,32 @@ func randomize_game_grid():
|
||||
# For now, let's assume server authority + sync on connect handles it, or add sync loop if critical.
|
||||
pass
|
||||
|
||||
@rpc("any_peer")
|
||||
func request_full_grid_sync():
|
||||
if multiplayer.is_server():
|
||||
var sender_id = multiplayer.get_remote_sender_id()
|
||||
print("[Main] Grid sync requested by %d" % sender_id)
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
if enhanced_gridmap:
|
||||
var grid_data = enhanced_gridmap.get_floor_data(1) # Sync Floor 1 (Items)
|
||||
print("[Main] Server: Prepared grid data. Size: %d. Sending to %d..." % [grid_data.size(), sender_id])
|
||||
|
||||
# Force send (Server is usually always connected)
|
||||
rpc_id(sender_id, "sync_full_grid_data", grid_data)
|
||||
print("[Main] Server: Sent rpc_id to %d" % sender_id)
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func sync_full_grid_data(data: PackedInt32Array):
|
||||
print("[Main] sync_full_grid_data received. Items: %d" % (data.size() / 3))
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
if not enhanced_gridmap:
|
||||
print("[Main] Error: EnhancedGridMap not found!")
|
||||
return
|
||||
|
||||
# Apply the synced data to Floor 1
|
||||
enhanced_gridmap.set_floor_data(1, data)
|
||||
print("[Main] Grid sync complete.")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Goals Cycle & Leaderboard UI
|
||||
|
||||
Reference in New Issue
Block a user