From 6a591b9e3ad8b81ab64d3a445c37f10ea2b6c520 Mon Sep 17 00:00:00 2001 From: JonShard Date: Tue, 11 Aug 2026 13:24:51 +0200 Subject: [PATCH] Add bought station is ghost when spawns --- Scenes/test_small.tscn | 2 +- Stations/StationMovement.tscn | 5 +++-- Stations/station_movement.gd | 35 ++++++++++++++++------------- UI/shop_station_button.gd | 32 +++++++++++++++++++------- addons/sweet-logger/sweet_logger.gd | 6 ++--- 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/Scenes/test_small.tscn b/Scenes/test_small.tscn index 75d7e5c..bc3cbbe 100644 --- a/Scenes/test_small.tscn +++ b/Scenes/test_small.tscn @@ -62,7 +62,7 @@ transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 1.80 spawn_path = NodePath("../WorldContent") [node name="PlayersSpawner" type="MultiplayerSpawner" parent="." unique_id=1840881658] -_spawnable_scenes = PackedStringArray("res://Player/net_player.tscn") +_spawnable_scenes = PackedStringArray("uid://c58ns7csdahjy") spawn_path = NodePath("../Players") [node name="GameOverPanel" parent="." unique_id=522901881 instance=ExtResource("12_n58f2")] diff --git a/Stations/StationMovement.tscn b/Stations/StationMovement.tscn index aeec35f..8d31180 100644 --- a/Stations/StationMovement.tscn +++ b/Stations/StationMovement.tscn @@ -62,14 +62,15 @@ move_ghost = NodePath("MoveGhost") [node name="MoveHandle" type="RigidBody3D" parent="." unique_id=954108203 groups=["platalbe_item"]] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) -collision_layer = 4 +collision_layer = 262144 collision_mask = 196615 axis_lock_linear_y = true axis_lock_angular_x = true axis_lock_angular_z = true -mass = 0.004 +mass = 0.001 gravity_scale = 0.5 linear_damp = 100.0 +angular_damp = 100.0 script = ExtResource("2_tbkb3") picked_up_layer = 64 release_mode = 1 diff --git a/Stations/station_movement.gd b/Stations/station_movement.gd index a954182..61ba138 100644 --- a/Stations/station_movement.gd +++ b/Stations/station_movement.gd @@ -15,7 +15,7 @@ var ghost_materials: Array[StandardMaterial3D] = [] # Ghost update throttling (clients send unreliable RPCs to server at this rate) var ghost_send_interval: float = 0.1 # seconds (10 Hz) var _ghost_send_accum: float = 0.0 - +var _was_last_pos_valid: bool = false const GHOST_COLOR_VALID: Color = Color(0, 1, 0, 0.35) const GHOST_COLOR_INVALID: Color = Color(1, 0, 0, 0.35) @@ -37,6 +37,7 @@ func _on_station_bought(_instance: Node3D): set_move_handle_enabled(true) func _ready() -> void: + SweetLogger.debug("enter") if not station: push_error("StationMovement is missing referece to station") if not move_handle: @@ -52,11 +53,11 @@ func _ready() -> void: move_handle.dropped.connect(_handle_drop) Signals.station_bought.connect(_on_station_bought) - move_ghost.monitoring = true - move_ghost.visible = false _cache_ghost_materials() _set_ghost_color(GHOST_COLOR_VALID) set_move_handle_enabled(GameManager.game_state == GameManager.GameState.BUILDING) + move_ghost.monitoring = true + move_ghost.visible = false Signals.game_state_changed.connect(_on_game_state_changed) @@ -144,10 +145,6 @@ func _process(_delta: float) -> void: if not is_moving: return - # Update the ghost locally for instant feedback and send throttled unreliable RPCs to the server - move_ghost.visible = true - station.visible = false - move_ghost.global_transform = Helper.get_snapped_transform(move_handle) move_ghost.global_transform.origin.y = original_station_transform.origin.y @@ -189,6 +186,7 @@ func _is_move_position_valid() -> bool: @rpc("any_peer", "call_remote", "reliable") func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool): + SweetLogger.debug("enter") if not multiplayer.is_server(): return if not (client_thinks_valid): @@ -197,45 +195,50 @@ func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool): server_update_station_transform.rpc(original_trans) server_update_move_ghost_transform.rpc(original_trans) server_update_handle_transform.rpc(original_trans.translated(Vector3(0, original_handle_y_pos, 0))) - server_update_visibility.rpc(false, true) - SweetLogger.debug("server_handle_drop: transform rejected (invalid)") + if not _was_last_pos_valid: # Edge case + server_update_visibility.rpc(false, true) + SweetLogger.warning("Can not not reset visibility to normal when the last pos was invalid") + SweetLogger.debug("transform rejected (invalid)") + _was_last_pos_valid = false return server_update_station_transform.rpc(new_transform) server_update_move_ghost_transform.rpc(new_transform) server_update_handle_transform.rpc(new_transform.translated(Vector3(0, original_handle_y_pos, 0))) server_update_visibility.rpc(false, true) - - SweetLogger.debug("server_handle_drop: transform applied") + _was_last_pos_valid = true + + SweetLogger.debug("transform applied") @rpc("any_peer", "call_local", "reliable") # Server updates clients func server_artificial_pickup(): + SweetLogger.debug("enter") _handle_pickup(self) # Arg is not used, but required of the signal. @rpc("any_peer", "call_local", "reliable") # Server updates clients func server_update_station_transform(new_transform: Transform3D) -> void: - SweetLogger.debug("server_update_station_transform") + SweetLogger.debug("entered") station.global_transform = new_transform original_station_transform = new_transform @rpc("any_peer", "call_local", "reliable") # Server updates clients func server_update_handle_transform(new_transform: Transform3D) -> void: - SweetLogger.debug("server_update_handle_transform") + SweetLogger.debug("entered") move_handle.global_transform = new_transform @rpc("any_peer", "call_local", "reliable") func server_update_visibility(ghost_visible: bool, station_visible: bool) -> void: - SweetLogger.debug("server_update_visibility") + SweetLogger.debug("entered") move_ghost.visible = ghost_visible station.visible = station_visible @rpc("any_peer", "call_local", "unreliable") -func server_update_move_ghost_transform(new_transform: Transform3D, new_color: Color = Color.YELLOW) -> void: - SweetLogger.debug("server_update_move_ghost_transform") +func server_update_move_ghost_transform(new_transform: Transform3D, new_color: Color = GHOST_COLOR_VALID) -> void: + SweetLogger.debug("entered") move_ghost.global_transform = new_transform _set_ghost_color(new_color) diff --git a/UI/shop_station_button.gd b/UI/shop_station_button.gd index eab38d4..d563288 100644 --- a/UI/shop_station_button.gd +++ b/UI/shop_station_button.gd @@ -16,28 +16,44 @@ func _ready() -> void: button.icon = icon_texture +func _process(_delta: float) -> void: + button.disabled = GameManager.money < cost + + func _on_button_pressed() -> void: - SweetLogger.debug("buy {0}", [station_name], "shop_station_button.gd", "_on_button_pressed") + SweetLogger.debug("buy {0}", [station_name]) _buy_station() func _buy_station() -> void: - SweetLogger.debug("_buy_station: cost={0} current money={1}", [cost, GameManager.money], "shop_station_button.gd", "_buy_station") + SweetLogger.debug("cost={0} current money={1}", [cost, GameManager.money]) GameManager.set_money(GameManager.money - cost) var transform = Helper.get_snapped_transform(XRHelpers.get_xr_origin(self).get_node_or_null("PlayerBody")) var forward: Vector3 = -transform.basis.z.normalized() transform.origin += (forward * 0.6) - var instance = NetworkManager.spawn_item(station_scene.resource_path, transform) + var instance if NetworkManager.is_online() and not NetworkManager.is_server(): _ask_server_to_spawn.rpc_id(1, station_scene.resource_path, transform) - + else: + instance = NetworkManager.spawn_item(station_scene.resource_path, transform) + update_instance_move(instance) Signals.station_bought.emit(instance) - + + @rpc("any_peer", "call_remote", "reliable") func _ask_server_to_spawn(station_scene_path, transform): - NetworkManager.spawn_item(station_scene_path, transform) + if not multiplayer.is_server(): + return + var instance = NetworkManager.spawn_item(station_scene_path, transform) + update_instance_move(instance) + + +func update_instance_move(instance: Node3D) -> void: + var move = Helper.find_first_child_of_type(instance, StationMovement) as StationMovement + if not move: + SweetLogger.error("Could not find StationMovement under station {0}", [instance.name]) + move.server_artificial_pickup() # Make the new station appear as ghost, the player has to place it. + -func _process(_delta: float) -> void: - button.disabled = GameManager.money < cost diff --git a/addons/sweet-logger/sweet_logger.gd b/addons/sweet-logger/sweet_logger.gd index 8db9ec4..11af65d 100644 --- a/addons/sweet-logger/sweet_logger.gd +++ b/addons/sweet-logger/sweet_logger.gd @@ -95,14 +95,14 @@ const TIMESTAMP_BG_COLOR = "#1e3a5f" #===================================================================================# ## Column widths for alignment (in characters) const PEER_ID_COLUMN_WIDTH = 6 -const LOG_TYPE_COLUMN_WIDTH = 6 +const LOG_TYPE_COLUMN_WIDTH = 7 ## Default mm:ss:ms; with SHOW_TIMESTAMP_HOURS, hh:mm:ss:ms const TIMESTAMP_COLUMN_WIDTH_MMSSMS = 9 const TIMESTAMP_COLUMN_WIDTH_HHMMSSMS = 12 -const SCRIPT_FUNCTION_COLUMN_WIDTH = 45 +const SCRIPT_FUNCTION_COLUMN_WIDTH = 50 const TRUNCATE_PEER_NAME = 6 -const TRUNCATE_SCRIPT_NAME = 18 +const TRUNCATE_SCRIPT_NAME = 20 const TRUNCATE_FUNCTION_NAME = 30 #===================================================================================#