diff --git a/Stations/sink.gd b/Stations/sink.gd index a541287..ac45744 100644 --- a/Stations/sink.gd +++ b/Stations/sink.gd @@ -1,94 +1,71 @@ -extends StaticBody3D +class_name Sink +extends WorkStation const plate_wash_time: float = 3.0 @export_range(0.0, 10.0, 0.1) var wash_speed: float = 1.0 -@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone -@onready var progress_bar: ProgressBar3D = $ProgressBar3D - -## Washing state. Both are replicated (see sink.tscn's Sync node) and refresh the -## display when they change. Only the world owner runs this station's _process -## and snap zone, so without this a client never updates its bar — it stayed -## frozen on screen long after the plate came out clean. -@export var time_washed: float = 0.0: set = _set_time_washed -@export var is_washing: bool = false: set = _set_is_washing -@export var plate: PlateController = null +var plate: PlateController = null -func _set_time_washed(value: float) -> void: - if is_equal_approx(time_washed, value): +func _ready() -> void: + super.ready() + SweetLogger.debug("Sink {0} _ready", [name]) + + +func _start_washing(work: float) -> void: + if not enabled: return - time_washed = value - _refresh_progress_bar() + result_id = "clean" + max_work = work + SweetLogger.info("Start washing - max_work: {0}", [max_work]) - -func _set_is_washing(value: bool) -> void: - if is_washing == value: - return - is_washing = value - _refresh_progress_bar() - _set_effects_playing(is_washing) - - -# Water, bubbles and the animation follow the washing state on every peer, not -# just the one running the logic. -func _set_effects_playing(playing: bool) -> void: +func _set_effects_playing(is_playing: bool) -> void: + SweetLogger.debug("Set Sink effects: {0}", [is_playing]) var player := get_node_or_null("AnimationPlayer") as AnimationPlayer if player: - player.play("working" if playing else "RESET") + player.play("working" if is_playing else "RESET") for effect in ["water", "bubbles", "GPUParticles3D"]: var node := get_node_or_null(effect) as Node3D if node: - node.visible = playing - -func _ready() -> void: - if not progress_bar or progress_bar is not ProgressBar3D: - SweetLogger.warning("{0} missing progress_bar reference", [name]) - - snap_zone.has_picked_up.connect(_on_object_picked_up) - snap_zone.has_dropped.connect(_on_object_dropped) - progress_bar.override_fill_color(Color.DODGER_BLUE) - _refresh_progress_bar() - - -func _refresh_progress_bar() -> void: - if not progress_bar: - return - progress_bar.set_progress(clampf(float(time_washed) / plate_wash_time, 0.0, 1.0)) - progress_bar.set_bar_visible(is_washing) - - -func _on_object_picked_up(_item) -> void: - SweetLogger.debug("Object picked up: {0}", [_item]) - plate = _item.get_node_or_null("PlateController") as PlateController - if plate: - # The setter starts the effects and shows the bar, here and on clients. - is_washing = plate.is_dirty - - -func _on_object_dropped(_item) -> void: - SweetLogger.debug("Object drop") - _reset_sink() - - -func _reset_sink(): - time_washed = 0 - is_washing = false - plate = null - -func complete_washing(): - if not plate: - return - plate.is_dirty = false - _reset_sink() - SweetLogger.debug("Washing complete") + node.visible = is_playing func _process(delta: float) -> void: - if is_washing: - time_washed += wash_speed * delta - _refresh_progress_bar() - SweetLogger.debug("Washing plate: {0}", [time_washed]) + super.process(delta) + if not enabled: + return + if result_id: + add_work(wash_speed * delta) + + +# Called from Station base class +func refresh_display() -> void: + super.refresh_display() + progress_bar.override_fill_color(Color.DODGER_BLUE) + + +# Called from Station base class +func on_object_picked_up(item: Node3D) -> void: + plate = item.get_node_or_null("PlateController") as PlateController + if not plate or not plate.is_dirty: + return + _set_effects_playing(true) + _start_washing(plate_wash_time) + + +# Called from Station base class +func on_object_dropped(_item: Node3D) -> void: + SweetLogger.debug("->[]") + _set_effects_playing(false) + plate = null + reset() + + +# Called from Station base class +func on_work_complete(): + SweetLogger.debug("->[]") + _set_effects_playing(false) + plate.is_dirty = false + reset() + - if time_washed >= plate_wash_time: - complete_washing() diff --git a/Stations/sink.tscn b/Stations/sink.tscn index 55065d1..e1bdde5 100644 --- a/Stations/sink.tscn +++ b/Stations/sink.tscn @@ -1,26 +1,7 @@ [gd_scene format=4 uid="uid://dvrk268s7gkxh"] +[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"] [ext_resource type="Script" uid="uid://byh5j25mwt3oc" path="res://stations/sink.gd" id="1_7hh4b"] -[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_uluvy"] -[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="2_3ocod"] -[ext_resource type="PackedScene" uid="uid://bxbocxdaayvwx" path="res://UI/progress_bar.tscn" id="4_1pinr"] - -[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_np_sink"] -properties/0/path = NodePath(".:position") -properties/0/spawn = false -properties/0/replication_mode = 1 -properties/1/path = NodePath(".:rotation") -properties/1/spawn = false -properties/1/replication_mode = 1 -properties/2/path = NodePath(".:time_washed") -properties/2/spawn = false -properties/2/replication_mode = 1 -properties/3/path = NodePath(".:is_washing") -properties/3/spawn = false -properties/3/replication_mode = 1 -properties/4/path = NodePath(".:visible") -properties/4/spawn = false -properties/4/replication_mode = 1 [sub_resource type="BoxShape3D" id="BoxShape3D_l02yb"] size = Vector3(0.6, 1.0024658, 0.6) @@ -191,37 +172,35 @@ material = SubResource("StandardMaterial3D_ai6d4") radius = 0.02 height = 0.04 -[node name="Sink" type="Node3D" unique_id=1559059799] +[node name="Sink" unique_id=707500902 instance=ExtResource("1_station")] -[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_uluvy")] +[node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")] station = NodePath("../Sink") -[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1601242574] -root_path = NodePath("../Sink") -replication_config = SubResource("SceneReplicationConfig_np_sink") +[node name="ProgressBar3D" parent="." index="4" unique_id=654673176] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3229032, -0.035980098) -[node name="Sink" type="StaticBody3D" parent="." unique_id=2055277359 groups=["station"]] +[node name="SnapZone" parent="." index="5" unique_id=1315859105] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9525887, 0) +collision_layer = 65536 +collision_mask = 65540 +stash_sound = SubResource("AudioStreamWAV_1pinr") +snap_mode = 1 + +[node name="CollisionShape3D" parent="SnapZone" index="0"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02560103, 0) +shape = SubResource("BoxShape3D_ai6d4") + +[node name="Sink" type="StaticBody3D" parent="." index="6" unique_id=2055277359 node_paths=PackedStringArray("snap_zone", "synchronizer", "progress_bar") groups=["station"]] script = ExtResource("1_7hh4b") +snap_zone = NodePath("../SnapZone") +synchronizer = NodePath("../MultiplayerSynchronizer") +progress_bar = NodePath("../ProgressBar3D") [node name="CollisionShape3D" type="CollisionShape3D" parent="Sink" unique_id=964735164] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.507675, 0) shape = SubResource("BoxShape3D_l02yb") -[node name="XRToolsSnapZone" type="Area3D" parent="Sink" unique_id=1762550988 groups=["station_zone"]] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9525887, 0) -collision_layer = 65536 -collision_mask = 65540 -script = ExtResource("2_3ocod") -stash_sound = SubResource("AudioStreamWAV_1pinr") -snap_mode = 1 -metadata/_custom_type_script = "uid://cquqe4f1m1sw6" - -[node name="CollisionShape3D2" type="CollisionShape3D" parent="Sink/XRToolsSnapZone" unique_id=860566355] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02560103, 0) -shape = SubResource("BoxShape3D_ai6d4") - -[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Sink/XRToolsSnapZone" unique_id=1926328538] - [node name="CSGCombiner3D" type="CSGCombiner3D" parent="Sink" unique_id=311064646] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.50644207, 0) @@ -254,9 +233,6 @@ transform = Transform3D(1, 0, 0, 0, 0.9367828, -0.34991136, 0, 0.34991136, 0.936 operation = 2 size = Vector3(1, 1.2053223, 0.352417) -[node name="ProgressBar3D" parent="Sink" unique_id=654673176 instance=ExtResource("4_1pinr")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3229032, -0.035980098) - [node name="bubbles" type="CSGCombiner3D" parent="Sink" unique_id=1624244242] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.50644207, 0) visible = false diff --git a/abstract/work_station.gd b/abstract/work_station.gd index 55b31f5..cb45a70 100644 --- a/abstract/work_station.gd +++ b/abstract/work_station.gd @@ -75,15 +75,15 @@ func add_work(work: float) -> void: if work <= 0: SweetLogger.warning("Work to add must be positive, work: {0}", [work]) return - if not NetworkManager.owns_world: - server_add_work(work) + if not NetworkManager.owns_world(): + server_add_work.rpc_id(1, work) return if not result_id or result_id.is_empty(): SweetLogger.warning("Work can not be added when result_id is empty") return current_work += work if current_work >= max_work: - _everyone_on_work_complete() + _everyone_on_work_complete.rpc() @rpc("any_peer", "call_remote", "reliable") diff --git a/content/station_layouts/small_line.tscn b/content/station_layouts/small_line.tscn index 6dd4a70..2a04b91 100644 --- a/content/station_layouts/small_line.tscn +++ b/content/station_layouts/small_line.tscn @@ -7,6 +7,7 @@ [ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://stations/raw_burger_dispenser.tscn" id="5_0342k"] [ext_resource type="PackedScene" uid="uid://ck5tuftqmyiue" path="res://stations/plate_dispenser.tscn" id="6_b5gb1"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="7_0342k"] +[ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://stations/dirt_station.tscn" id="8_b5gb1"] [node name="SmallLine" type="Node3D" unique_id=1844128818] @@ -29,3 +30,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.8000001, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4, 0, 1.2) [node name="Hob" parent="." unique_id=707500902 instance=ExtResource("1_1wuvq")] + +[node name="DirtStation" parent="." unique_id=784427347 instance=ExtResource("8_b5gb1")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8000001, 0, 0)