From e6dceaf173cc390cb9418b024bed9c6d0f54e114 Mon Sep 17 00:00:00 2001 From: Yogi Wiguna Date: Mon, 2 Mar 2026 16:49:40 +0800 Subject: [PATCH] feat: Add a multiplayer-synchronized portal door with visual elements, player detection, and dynamic color. --- scenes/portal_door.tscn | 17 ++++++++++++++++- scripts/portal_door.gd | 42 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/scenes/portal_door.tscn b/scenes/portal_door.tscn index 6206158..df4882b 100644 --- a/scenes/portal_door.tscn +++ b/scenes/portal_door.tscn @@ -10,6 +10,16 @@ albedo_color = Color(0.1, 0.5, 0.8, 1) metallic = 0.8 roughness = 0.2 +[sub_resource type="PlaneMesh" id="PlaneMesh_ground"] +size = Vector2(1.0, 1.0) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ground"] +transparency = 1 +albedo_color = Color(1, 1, 1, 0.4) +emission_enabled = true +emission = Color(1, 1, 1, 1) +emission_energy_multiplier = 1.0 + [sub_resource type="PlaneMesh" id="PlaneMesh_vortex"] size = Vector2(1.4, 2.1) @@ -18,7 +28,7 @@ transparency = 1 albedo_color = Color(0.0, 0.6, 1.0, 0.4) emission_enabled = true emission = Color(0.0, 0.4, 1.0, 1) -emission_energy_multiplier = 2.0 +emission_energy_multiplier = 5.0 [sub_resource type="BoxShape3D" id="BoxShape3D_trigger"] size = Vector3(1.4, 2.1, 0.8) @@ -63,6 +73,11 @@ transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 1.1 mesh = SubResource("PlaneMesh_vortex") surface_material_override/0 = SubResource("StandardMaterial3D_vortex") +[node name="GroundIndicator" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0.4) +mesh = SubResource("PlaneMesh_ground") +surface_material_override/0 = SubResource("StandardMaterial3D_ground") + [node name="Area3D" type="Area3D" parent="."] collision_layer = 0 collision_mask = 2 diff --git a/scripts/portal_door.gd b/scripts/portal_door.gd index 7da8d5b..5e7ed05 100644 --- a/scripts/portal_door.gd +++ b/scripts/portal_door.gd @@ -28,6 +28,9 @@ func _ready(): # Visual feedback: indicate door is active _update_visuals() + + # Adjust GroundIndicator position based on spawn_offset metadata + _adjust_indicator_position() func _on_body_entered(body: Node3D): if not is_active: return @@ -76,6 +79,15 @@ func _update_visuals(): var mat = frame.get_surface_override_material(0) if mat: mat.albedo_color = portal_color.lerp(Color.BLACK, 0.4) + + var ground = get_node_or_null("GroundIndicator") + if ground: + var mat = ground.get_surface_override_material(0) + if mat: + mat.albedo_color = portal_color + mat.albedo_color.a = 0.4 + mat.emission = portal_color + mat.emission_energy_multiplier = 2.0 func _initialize_unique_materials(): var vortex = get_node_or_null("Vortex") @@ -96,9 +108,29 @@ func _initialize_unique_materials(): if mat: frame.set_surface_override_material(0, mat.duplicate()) + + var ground = get_node_or_null("GroundIndicator") + if ground: + var mat = ground.get_surface_override_material(0) + if not mat: + mat = ground.mesh.surface_get_material(0) + if mat: + ground.set_surface_override_material(0, mat.duplicate()) -func get_teleport_target_position() -> Vector2i: - # This function will be called by the manager to determine WHERE the player spawns - # usually just outside the target door's position. - # For now, let's just return a placeholder that the manager will override. - return Vector2i.ZERO +func _adjust_indicator_position(): + # This uses the spawn_offset metadata set by PortalModeManager + # to push the ground indicator "into" the room. + if not has_meta("spawn_offset"): return + + var ground = get_node_or_null("GroundIndicator") + if not ground: return + + var offset_2d = get_meta("spawn_offset") # Vector2i + var offset_3d = Vector3(offset_2d.x, 0, offset_2d.y) + + # Convert the global direction (into the room) to local coordinates + var local_dir = to_local(global_position + offset_3d).normalized() + + # Nudge the indicator in that direction + ground.position = local_dir * 0.5 # Reduced from 0.6 to close the gap + ground.position.y = 0.05 # Keep it just above the floor