63 lines
2.0 KiB
GDScript
63 lines
2.0 KiB
GDScript
extends StaticBody3D
|
|
|
|
## Cooking station. The cook timer and item conversion run only on the machine
|
|
## that owns world logic (server or offline host); `progress` is replicated to
|
|
## clients for UI via a MultiplayerSynchronizer. This is the reference
|
|
## implementation of the reusable "station work-progress" pattern: a server-owned
|
|
## progress value advanced by an input source (here, a timer), which converts the
|
|
## held item once it reaches the threshold and spawns the result over the network.
|
|
|
|
@export var cook_speed := 1.0
|
|
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
|
|
|
|
var item = null
|
|
var progress: float = 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
if snap_zone.initial_object:
|
|
item = snap_zone.initial_object
|
|
|
|
|
|
func convert_item(cookable: CookableItem) -> void:
|
|
var old_pickable = snap_zone.picked_up_object
|
|
if not old_pickable:
|
|
push_warning("Hob finished cooking item, but snap zone is missing its reference")
|
|
return
|
|
|
|
var original_transform: Transform3D = old_pickable.global_transform
|
|
|
|
# Spawn the result over the network (server) or locally (offline).
|
|
var result := NetworkManager.spawn_item(cookable.turns_into.resource_path, original_transform)
|
|
|
|
# Remove the cooked item (despawn replicates for spawner-managed items).
|
|
snap_zone.drop_object()
|
|
old_pickable.queue_free()
|
|
|
|
# Snap the result into the now-empty zone.
|
|
if result:
|
|
snap_zone.pick_up_object(result)
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
# Only the world owner runs cooking logic; clients receive `progress` + the
|
|
# converted item via replication.
|
|
if not NetworkManager.owns_world():
|
|
return
|
|
|
|
# Find the CookableItem in the held object.
|
|
var cookable = null
|
|
if snap_zone.picked_up_object:
|
|
var matches = snap_zone.picked_up_object.get_children().filter(func(c): return c is CookableItem)
|
|
if matches.size() > 0:
|
|
cookable = matches[0]
|
|
|
|
# Advance progress and convert once cooked.
|
|
if cookable:
|
|
progress += cook_speed * delta
|
|
if progress >= cookable.cooking_time:
|
|
progress = 0.0
|
|
convert_item(cookable)
|
|
else:
|
|
progress = 0.0
|