7 Commits

Author SHA1 Message Date
JonShard 20a437681a Disable stations when entering build mode 2026-08-14 14:26:20 +02:00
JonShard c18b09ab31 Refactor dispensers 2026-08-14 14:26:19 +02:00
JonShard 3153df7baa Refactor DirtStation 2026-08-14 14:26:19 +02:00
JonShard 8ecde66441 Refactor Counter 2026-08-14 14:26:19 +02:00
JonShard d7ccab2e3c Refactor Sink 2026-08-14 14:26:19 +02:00
JonShard f28c987a3a Cleanup logs, make prints more uniform. 2026-08-14 14:26:19 +02:00
JonShard 9e0c3ed174 Split Station into WorkStation abstract script 2026-08-14 14:25:57 +02:00
56 changed files with 886 additions and 1071 deletions
+9 -9
View File
@@ -19,9 +19,9 @@ var contained_items: Array[FoodItem] # Expose nice list of others to read
func _ready() -> void: func _ready() -> void:
area_3d.body_entered.connect(_on_body_entered) area_3d.body_entered.connect(_on_body_entered)
if not area_3d: if not area_3d:
push_error("Area3D node not found in container.gd") SweetLogger.warning("{0} missing area_3d reference", [name])
if not xr_pickable: if not xr_pickable:
push_error("XRPickable node not found in container.gd") SweetLogger.warning("{0} missing xr_pickable reference", [name])
# Absorbing items is a server decision (the container's holder is server- # Absorbing items is a server decision (the container's holder is server-
@@ -29,13 +29,13 @@ func _ready() -> void:
func _on_body_entered(body: Node3D) -> void: func _on_body_entered(body: Node3D) -> void:
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
return return
SweetLogger.debug("enabled: {0}", [enabled]) SweetLogger.debug("Enabled: {0}", [enabled])
if not enabled: if not enabled:
SweetLogger.debug("disabled in _on_body_entered body") SweetLogger.debug("Disabled in _on_body_entered body")
return return
if not body.is_in_group(target_group): if not body.is_in_group(target_group):
return return
SweetLogger.debug("body: {0}", [body]) SweetLogger.debug("Body: {0}", [body])
# If one of us is in a station # If one of us is in a station
@@ -46,14 +46,14 @@ func _on_body_entered(body: Node3D) -> void:
# If enough space, add item # If enough space, add item
var food_item = body.get_node("FoodItem") var food_item = body.get_node("FoodItem")
SweetLogger.debug("in station found {0} of type {1}: {2}", [target_group, FoodItem.Type.keys()[food_item.type], body.name], "container.gd", "_on_body_entered") SweetLogger.debug("In station found {0} of type {1}: {2}", [target_group, FoodItem.Type.keys()[food_item.type], body.name], "container.gd", "_on_body_entered")
var meal_count := contained_items.filter(func(f): return f.type == FoodItem.Type.MEAL).size() var meal_count := contained_items.filter(func(f): return f.type == FoodItem.Type.MEAL).size()
var side_count := contained_items.filter(func(f): return f.type == FoodItem.Type.SIDE).size() var side_count := contained_items.filter(func(f): return f.type == FoodItem.Type.SIDE).size()
if food_item.type == FoodItem.Type.MEAL and meal_count < meal_positions.size(): if food_item.type == FoodItem.Type.MEAL and meal_count < meal_positions.size():
SweetLogger.debug("adding meal") SweetLogger.debug("Adding meal")
_add_item(body) _add_item(body)
if food_item.type == FoodItem.Type.SIDE and side_count < side_positions.size(): if food_item.type == FoodItem.Type.SIDE and side_count < side_positions.size():
SweetLogger.debug("adding side") SweetLogger.debug("Adding side")
_add_item(body) _add_item(body)
@@ -93,7 +93,7 @@ func _add_item(item: Node3D) -> void:
NetworkManager.despawn_item(item) NetworkManager.despawn_item(item)
# In case the container is on a table that needs to register this addition, # In case the container is on a table that needs to register this addition,
# ask all table in scene to absorb any new items. # ask all table in scene to absorb any new items.
SweetLogger.debug("group call absorb_items()") SweetLogger.debug("Group call absorb_items()")
get_tree().call_group("table", "absorb_items") get_tree().call_group("table", "absorb_items")
+1 -1
View File
@@ -18,7 +18,7 @@ func get_food_items() -> Array[FoodItem]:
func _ready() -> void: func _ready() -> void:
if not dirty_node: if not dirty_node:
push_error("Plate is missing its dirty_node") SweetLogger.warning("{0} missing dirty_node reference", [name])
dirty_node.visible = is_dirty dirty_node.visible = is_dirty
-1
View File
@@ -68,7 +68,6 @@ func _exit_tree() -> void:
func _on_session_started(_is_server: bool) -> void: func _on_session_started(_is_server: bool) -> void:
NetworkManager.gate_existing_stations()
_populate_world_if_owner() _populate_world_if_owner()
+3 -2
View File
@@ -33,7 +33,7 @@ var _grab_race_logged := false
func _ready() -> void: func _ready() -> void:
_pickable = get_parent() as XRToolsPickable _pickable = get_parent() as XRToolsPickable
if not _pickable: if not _pickable:
push_error("NetPickable must be a child of an XRToolsPickable") SweetLogger.error("{0} must be a child of an XRToolsPickable", [name])
return return
_original_freeze_mode = _pickable.freeze_mode _original_freeze_mode = _pickable.freeze_mode
_original_enabled = _pickable.enabled _original_enabled = _pickable.enabled
@@ -116,7 +116,8 @@ func apply_held_state() -> void:
# Someone else owns it: stop simulating locally, just follow the sync. # Someone else owns it: stop simulating locally, just follow the sync.
if _pickable.is_picked_up(): if _pickable.is_picked_up():
if NetworkManager.is_online(): if NetworkManager.is_online():
SweetLogger.debug("{0}: was held by {1} on this peer, but authority now says peer {2} owns it — force-dropping", [_pickable.name, _holder_desc(), net_held_by]) # Jon's note: When we get this warning, it usually mean a client-side snapzone is not disabled, and is fighting the server over the item.
SweetLogger.warning("{0}: was held by {1} on this peer, but authority now says peer {2} owns it — force-dropping", [_pickable.name, _holder_desc(), net_held_by])
_pickable.drop() _pickable.drop()
# Bail out when we're already in the follow-the-sync state. Without this the # Bail out when we're already in the follow-the-sync state. Without this the
# writes below (and the line logged with them) repeated every tick for every # writes below (and the line logged with them) repeated every tick for every
+2 -72
View File
@@ -154,7 +154,7 @@ func _despawn_static_item(path: NodePath) -> void:
func _spawn_item_from_data(data: Variant) -> Node: func _spawn_item_from_data(data: Variant) -> Node:
var scene: PackedScene = load(data["scene"]) var scene: PackedScene = load(data["scene"])
if not scene: if not scene:
push_error("spawn_item: could not load scene %s" % str(data.get("scene"))) SweetLogger.error("Could not load scene {0}", [str(data.get("scene"))])
return null return null
var inst := scene.instantiate() var inst := scene.instantiate()
if inst is Node3D: if inst is Node3D:
@@ -163,62 +163,8 @@ func _spawn_item_from_data(data: Variant) -> Node:
inst.name = data["name"] inst.name = data["name"]
for key in data.get("props", {}): for key in data.get("props", {}):
inst.set(key, data["props"][key]) inst.set(key, data["props"][key])
if not owns_world():
_gate_station(inst)
# ...and again once the node is in the tree. Gating before _ready() is what
# keeps a station from ever ticking on a client, but a station's own
# _ready() runs afterwards and can undo it (table.gd re-arms its state
# machine with set_process(true)). The deferred pass runs after every
# _ready() in this frame and re-asserts the gate.
_gate_station.call_deferred(inst)
return inst return inst
# Stations run their own logic and auto-grab (XRToolsSnapZone with
# snap_mode=RANGE) identically on every peer by default, which would let each
# peer independently grab/simulate the same shared object. Disable both on
# every peer except the one that owns world logic; the server-authoritative
# item-authority RPCs are what let clients still grab a server-held item by
# hand. Runs before the node enters the tree, so its own _ready() sees the
# final (disabled) state.
#
# Group contract (see also _station_snap_zones): "station" marks the body that
# runs the station's script, "station_zone" marks its snap zones. Station scenes
# wrap that body in a Node3D (for StationMovement), and spawn_item hands us that
# wrapper, so accept either and recurse — a type check on the node we're handed
# silently gated nothing for stations whose root isn't the body itself.
func _gate_station(node: Node) -> void:
if not node.is_in_group("station"):
for child in node.find_children("*", "", true, false):
if child.is_in_group("station"):
_gate_station(child)
return
# Only report a gate that actually changed something: this runs a second time
# (deferred) for every spawned station, and on a re-gate that found nothing to
# do there is nothing worth logging.
var changed := node.is_processing()
for zone in node.find_children("*", "XRToolsSnapZone", true, false):
changed = changed or zone.enabled or zone.is_processing()
zone.enabled = false
zone.set_process(false)
node.set_process(false)
if changed:
log_line("gated station (non-owner peer): %s" % node.name)
## Gate every station already sitting in the scene tree, for peers that don't
## own world logic. Stations that arrive through spawn_item() are gated as they
## are built (see _spawn_item_from_data), but ones baked into a scene file never
## pass through there — leaving a client running its own snap zones, which then
## grab items straight out of the local hand and fight the server's
## authoritative placement. Idempotent, so it's safe on every session start.
func gate_existing_stations() -> void:
if owns_world():
return
for station in get_tree().get_nodes_in_group("station"):
_gate_station(station)
# --- Item grab-authority transfer ----------------------------------------- # --- Item grab-authority transfer -----------------------------------------
## Called by NetPickable when this peer grabs an item by hand. Godot rejects ## Called by NetPickable when this peer grabs an item by hand. Godot rejects
@@ -420,22 +366,6 @@ func owns_world() -> bool:
return not is_online() or is_server() return not is_online() or is_server()
# --- Station work-progress seam -------------------------------------------
## Reusable entry point for a client to contribute work to a station (e.g. a
## future chopping/gesture station). The client detects the gesture locally and
## calls this; the server validates and accumulates. Timer-driven stations like
## the Hob don't need it, but it is the drop-in seam for input-driven ones.
@rpc("any_peer", "reliable")
func submit_work(station_path: NodePath, amount: float) -> void:
if not is_server():
return
var station := get_node_or_null(station_path)
if station and station.has_method("add_work"):
log_line("submit_work: peer %d contributed %.2f to %s" % [multiplayer.get_remote_sender_id(), amount, station.name])
station.add_work(multiplayer.get_remote_sender_id(), amount)
## Called by the world scene once it's ready, passing its spawners. Must run ## Called by the world scene once it's ready, passing its spawners. Must run
## before world_ready()/host()/join() on every peer so the custom spawn ## before world_ready()/host()/join() on every peer so the custom spawn
## function is installed before any spawn packet can arrive. ## function is installed before any spawn packet can arrive.
@@ -544,7 +474,7 @@ func _on_player_absent(peer_id: int) -> void:
# --- Command-line driven test bootstrap ----------------------------------- # --- Command-line driven test bootstrap -----------------------------------
func _handle_cmdline() -> void: func _handle_cmdline() -> void:
SweetLogger.info("Networkmanager _handle_cmdline()") SweetLogger.debug("->[]")
var args := OS.get_cmdline_args() var args := OS.get_cmdline_args()
if args.has("--server"): if args.has("--server"):
log_line("cmdline: --server") log_line("cmdline: --server")
+16 -2
View File
@@ -7,9 +7,22 @@ func _ready() -> void:
func _on_game_state_changed(new_state: GameManager.GameState) -> void: func _on_game_state_changed(new_state: GameManager.GameState) -> void:
SweetLogger.info("game_state_changed to {0}", [GameManager.GameState.keys()[new_state]], "build_mode_controller.gd", "_on_game_state_changed") SweetLogger.info("Game state changed to {0}", [GameManager.GameState.keys()[new_state]], "build_mode_controller.gd", "_on_game_state_changed")
if new_state == GameManager.GameState.BUILDING: if new_state == GameManager.GameState.BUILDING:
despawn_unheld_pickables() despawn_unheld_pickables()
if not NetworkManager.owns_world():
return
if new_state == GameManager.GameState.BUILDING:
_set_stations_enabled(false)
elif new_state == GameManager.GameState.RUNNING:
_set_stations_enabled(true)
# Only Station-derived stations expose `enabled` (Table runs its own FSM).
func _set_stations_enabled(value: bool) -> void:
for station in get_tree().get_nodes_in_group("station"):
if station is Station:
station.enabled = value
# Despawn all food_items unless it's in a "persistent_inventory" snap_zone # Despawn all food_items unless it's in a "persistent_inventory" snap_zone
@@ -25,7 +38,8 @@ func despawn_unheld_pickables():
NetworkManager.despawn_item(pickable) NetworkManager.despawn_item(pickable)
continue continue
if not held_by.is_in_group("persistent_inventory"): if not held_by.is_in_group("persistent_inventory"):
SweetLogger.debug("despawn_unheld_pickables held_by: {0}, pickable: {1}", [held_by, pickable]) SweetLogger.debug("Despawn unheld pickable held_by: {0}, pickable: {1}", [held_by, pickable])
pickable.drop()
NetworkManager.despawn_item(pickable) NetworkManager.despawn_item(pickable)
+7 -7
View File
@@ -10,16 +10,16 @@ var _food_item: FoodItem
func _ready() -> void: func _ready() -> void:
SweetLogger.debug("_ready(): {0}", [_pickable.name]) SweetLogger.debug("{0} ready", [_pickable.name])
_food_item = get_parent().get_node_or_null("FoodItem") as FoodItem _food_item = get_parent().get_node_or_null("FoodItem") as FoodItem
if not _food_item: if not _food_item:
push_error("CombinableItem is missing FoodItem reference. must be a sibling of a FoodItem on ", get_parent().name, ".") SweetLogger.warning("{0} missing FoodItem reference, must be a sibling of a FoodItem", [get_parent().name])
if not _pickable: if not _pickable:
push_error("CombineZone must be a grand child of an XRToolsPickable.") SweetLogger.error("{0} must be a grandchild of an XRToolsPickable", [get_parent().name])
return return
if not _food_item: if not _food_item:
push_error("CombineZone requires a FoodItem sibling on ", _pickable.name, ".") SweetLogger.warning("{0} requires a FoodItem sibling", [_pickable.name])
return return
# Detect items whether held (layer 17 "Held Objects") or loose # Detect items whether held (layer 17 "Held Objects") or loose
@@ -52,12 +52,12 @@ func _on_body_entered(body: Node3D) -> void:
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
return return
if _combining or body == _pickable: if _combining or body == _pickable:
SweetLogger.debug("other is our own pickable") SweetLogger.debug("Other is our own pickable")
return return
var other := Helper.find_food_item(body) var other := Helper.find_food_item(body)
if not other: if not other:
SweetLogger.debug("other is not a foodItem") SweetLogger.debug("Other is not a FoodItem")
return return
var result: PackedScene = RecipeManager.get_combination_result(_food_item.id, other.id) var result: PackedScene = RecipeManager.get_combination_result(_food_item.id, other.id)
@@ -69,7 +69,7 @@ func _on_body_entered(body: Node3D) -> void:
# Instantiate the result of combination and free the two ingredient items # Instantiate the result of combination and free the two ingredient items
func _combine(other_body: Node3D, result: PackedScene) -> void: func _combine(other_body: Node3D, result: PackedScene) -> void:
SweetLogger.debug("combining {0} + {1} into {2}", [_food_item.id, Helper.find_food_item(other_body).id, result.resource_path]) SweetLogger.debug("Combining {0} + {1} into {2}", [_food_item.id, Helper.find_food_item(other_body).id, result.resource_path])
# Get Snapzone # Get Snapzone
var snap_zone := _pickable.get_picked_up_by() var snap_zone := _pickable.get_picked_up_by()
+1 -1
View File
@@ -6,4 +6,4 @@ extends Node
func _ready() -> void: func _ready() -> void:
if not turns_into: if not turns_into:
push_error("Cooking Error: 'turns_into' PackedScene is missing on ", name, ". Please assign a scene in the Inspector.") SweetLogger.warning("{0} missing turns_into reference", [name])
+3 -3
View File
@@ -15,10 +15,10 @@ var _time_left: float = time_to_despawn
func _ready() -> void: func _ready() -> void:
if not _pickable: if not _pickable:
push_error("DespawningItem must be a grand child of an XRToolsPickable.") SweetLogger.error("{0} must be a grandchild of an XRToolsPickable", [name])
return return
if not _rigid: if not _rigid:
push_error("DespawningItem must be a grand child of an RigidBody3D.") SweetLogger.error("{0} must be a grandchild of a RigidBody3D", [name])
return return
@@ -41,7 +41,7 @@ func _process(delta: float) -> void:
# Count down to zero and despawn # Count down to zero and despawn
_time_left -= delta _time_left -= delta
if _time_left <= 0: if _time_left <= 0:
SweetLogger.debug("despawning {0}", [get_parent()]) SweetLogger.debug("Despawning {0}", [get_parent()])
NetworkManager.despawn_item(get_parent()) NetworkManager.despawn_item(get_parent())
# Stop counting: despawn_item() only queues the free, so without this we # Stop counting: despawn_item() only queues the free, so without this we
# keep re-reporting the same item every frame until it actually goes. # keep re-reporting the same item every frame until it actually goes.
+3 -3
View File
@@ -7,12 +7,12 @@ extends Node3D
func _ready() -> void: func _ready() -> void:
if not kitchen_scene: if not kitchen_scene:
push_error("StationSpawner missing kitchen_scene") SweetLogger.warning("{0} missing kitchen_scene reference", [name])
SweetLogger.debug("initializing") SweetLogger.debug("->[]")
if NetworkManager.owns_world(): if NetworkManager.owns_world():
SweetLogger.debug("initializing on server") SweetLogger.debug("Initializing on server")
# Later we will do procedural generation here. # Later we will do procedural generation here.
# For now we just load a scene. # For now we just load a scene.
NetworkManager.call_deferred("spawn_item", kitchen_scene.resource_path, transform) NetworkManager.call_deferred("spawn_item", kitchen_scene.resource_path, transform)
+13 -13
View File
@@ -1,22 +1,22 @@
[gd_scene format=3 uid="uid://22shbqdvnwgo"] [gd_scene format=3 uid="uid://22shbqdvnwgo"]
[ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_nlnup"] [ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_nlnup"]
[ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://Prefabs/XROrigin.tscn" id="2_8pfaf"] [ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_8pfaf"]
[ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://Textures/dev_material_3d.tres" id="3_gatbn"] [ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_gatbn"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://Stations/Hob.tscn" id="4_3lufs"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="4_3lufs"]
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://Textures/sky/NightSkyHDRI009_16K.tres" id="5_kh26v"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_kh26v"]
[ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://Stations/BurgerBunsDispenser.tscn" id="7_tejmp"] [ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="7_tejmp"]
[ext_resource type="PackedScene" uid="uid://dpot5qie20vf6" path="res://Items/burger.tscn" id="9_rwx83"] [ext_resource type="PackedScene" uid="uid://dpot5qie20vf6" path="res://items/burger.tscn" id="9_rwx83"]
[ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://Stations/sink.tscn" id="12_ah4xa"] [ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="12_ah4xa"]
[ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://Stations/dirt_station.tscn" id="13_46xi2"] [ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://stations/dirt_station.tscn" id="13_46xi2"]
[ext_resource type="PackedScene" uid="uid://ck5tuftqmyiue" path="res://Stations/plate_dispenser.tscn" id="14_h88sx"] [ext_resource type="PackedScene" uid="uid://ck5tuftqmyiue" path="res://stations/plate_dispenser.tscn" id="14_h88sx"]
[ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://Stations/raw_burger_dispenser.tscn" id="15_m3h4l"] [ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://stations/raw_burger_dispenser.tscn" id="15_m3h4l"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://Stations/Counter.tscn" id="15_tpcje"] [ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="15_tpcje"]
[ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://Stations/table.tscn" id="16_g2k6a"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="16_g2k6a"]
[ext_resource type="Script" uid="uid://k8ywnvlhcic4" path="res://test/testworldLoad.gd" id="16_m3h4l"] [ext_resource type="Script" uid="uid://k8ywnvlhcic4" path="res://test/testworldLoad.gd" id="16_m3h4l"]
[ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="17_gatbn"] [ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="17_gatbn"]
[ext_resource type="PackedScene" uid="uid://xtcei2uvd5li" path="res://UI/game_over_panel.tscn" id="18_3lufs"] [ext_resource type="PackedScene" uid="uid://xtcei2uvd5li" path="res://UI/game_over_panel.tscn" id="18_3lufs"]
[ext_resource type="Script" uid="uid://cwijoksyou1ey" path="res://Prefabs/GameOvercontroler.gd" id="19_3lufs"] [ext_resource type="Script" uid="uid://cwijoksyou1ey" path="res://prefabs/GameOvercontroler.gd" id="19_3lufs"]
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"] [sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
size = Vector3(16, 0.1, 16) size = Vector3(16, 0.1, 16)
+1 -1
View File
@@ -11,7 +11,7 @@
[ext_resource type="PackedScene" uid="uid://dlw5geheupgpt" path="res://stations/hatch.tscn" id="12_dpf3b"] [ext_resource type="PackedScene" uid="uid://dlw5geheupgpt" path="res://stations/hatch.tscn" id="12_dpf3b"]
[ext_resource type="PackedScene" uid="uid://e4i6o5oriecx" path="res://items/PickupCube.tscn" id="13_1f3bw"] [ext_resource type="PackedScene" uid="uid://e4i6o5oriecx" path="res://items/PickupCube.tscn" id="13_1f3bw"]
[ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="13_yjosk"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="13_yjosk"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="14_2ndvi"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="14_2ndvi"]
[ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="14_di04w"] [ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="14_di04w"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="15_di04w"] [ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="15_di04w"]
[ext_resource type="PackedScene" uid="uid://xtcei2uvd5li" path="res://UI/game_over_panel.tscn" id="15_eoxxy"] [ext_resource type="PackedScene" uid="uid://xtcei2uvd5li" path="res://UI/game_over_panel.tscn" id="15_eoxxy"]
+4 -4
View File
@@ -30,14 +30,14 @@ func _reset_values() -> void:
func start_next_day() -> void: func start_next_day() -> void:
SweetLogger.info("starting next day") SweetLogger.info("Starting next day")
_reset_values() _reset_values()
GameManager.set_customers_per_day(GameManager.customers_per_day + GameManager.customers_count_increase_per_day) GameManager.set_customers_per_day(GameManager.customers_per_day + GameManager.customers_count_increase_per_day)
GameManager.set_day_number(GameManager.day_number + 1) GameManager.set_day_number(GameManager.day_number + 1)
func finish_current_day() -> void: func finish_current_day() -> void:
SweetLogger.info("finishing current day") SweetLogger.info("Finishing current day")
_reset_values() _reset_values()
@@ -50,9 +50,9 @@ func _process(delta: float) -> void:
#print("DayController: customers_at_this_time: ", customers_at_this_time) #print("DayController: customers_at_this_time: ", customers_at_this_time)
if customers_spawned < customers_at_this_time: if customers_spawned < customers_at_this_time:
customers_spawned += 1 customers_spawned += 1
SweetLogger.debug("spawning customer") SweetLogger.debug("Spawning customer")
Signals.request_customer_spawn.emit() Signals.request_customer_spawn.emit()
# If day complete # If day complete
if GameManager.customers_per_day == customers_served and customers_spawned == GameManager.customers_per_day: if GameManager.customers_per_day == customers_served and customers_spawned == GameManager.customers_per_day:
SweetLogger.info("day complete") SweetLogger.info("Day complete")
finish_current_day() finish_current_day()
-113
View File
@@ -3,18 +3,7 @@
[ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_jfr2g"] [ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_jfr2g"]
[ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_8wkh3"] [ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_8wkh3"]
[ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_m56cs"] [ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_m56cs"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="4_5kvh0"]
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_l1qm6"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_l1qm6"]
[ext_resource type="PackedScene" uid="uid://c0lknik4noobs" path="res://items/BurgerBuns.tscn" id="6_bktvt"]
[ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="7_1nkd0"]
[ext_resource type="PackedScene" uid="uid://bp3v1jl8pctro" path="res://Containers/plate.tscn" id="8_l1owj"]
[ext_resource type="PackedScene" uid="uid://dpot5qie20vf6" path="res://items/burger.tscn" id="9_220hi"]
[ext_resource type="PackedScene" uid="uid://b3m2ag8g5rj4r" path="res://items/hamburger.tscn" id="10_qacki"]
[ext_resource type="PackedScene" uid="uid://e4i6o5oriecx" path="res://items/PickupCube.tscn" id="11_npf8s"]
[ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="12_8apyq"]
[ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://stations/dirt_station.tscn" id="13_jnwcx"]
[ext_resource type="PackedScene" uid="uid://cfc4ho67u4r5e" path="res://items/cooked_burger.tscn" id="14_1lg2m"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="15_yy81s"]
[ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="16_vp"] [ext_resource type="PackedScene" uid="uid://clujaf3u776a3" path="res://addons/godot-xr-tools/objects/viewport_2d_in_3d.tscn" id="16_vp"]
[ext_resource type="PackedScene" path="res://UI/main_menu_panel.tscn" id="17_panel"] [ext_resource type="PackedScene" path="res://UI/main_menu_panel.tscn" id="17_panel"]
@@ -61,111 +50,9 @@ shape = SubResource("BoxShape3D_vlqg6")
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor/CollisionShape3D" unique_id=1939997056] [node name="MeshInstance3D" type="MeshInstance3D" parent="Floor/CollisionShape3D" unique_id=1939997056]
mesh = SubResource("BoxMesh_24d3s") mesh = SubResource("BoxMesh_24d3s")
[node name="Hob" parent="." unique_id=1687971542 instance=ExtResource("4_5kvh0")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.29336345, 0.015500337, -1.484)
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1177077250] [node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1177077250]
environment = SubResource("Environment_bvwq1") environment = SubResource("Environment_bvwq1")
[node name="BurgerBuns" parent="." unique_id=1088240294 instance=ExtResource("6_bktvt")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5530176, 1.0505146, -1.3074328)
[node name="BurgerBunsDispenser" parent="." unique_id=1720683779 instance=ExtResource("7_1nkd0")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.568947, -0.018512607, -1.317366)
[node name="Plate" parent="." unique_id=190487773 instance=ExtResource("8_l1owj")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5717233, 1.1548845, 1.5373346)
[node name="burger" parent="." unique_id=1417604760 instance=ExtResource("9_220hi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6888188, 1.0325116, -1.7110313)
[node name="burger2" parent="." unique_id=1584460510 instance=ExtResource("9_220hi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6931299, 1.1429771, -1.71225)
[node name="burger3" parent="." unique_id=1884095916 instance=ExtResource("9_220hi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.69027674, 1.1099085, -1.7210286)
[node name="burger4" parent="." unique_id=1844818864 instance=ExtResource("9_220hi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.69134104, 1.0672915, -1.7210286)
[node name="Hamburger" parent="." unique_id=761091445 instance=ExtResource("10_qacki")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.9352558, 1.2334514, 1.2447833)
[node name="PickableObject" parent="." unique_id=1675596942 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, 0, -2.6077032e-08, 1.4901161e-08, 1, 0.6225724, 1.0654817, -1.0473135)
[node name="PickableObject2" parent="." unique_id=713087634 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, -5.293956e-23, -2.6077032e-08, 1.4901161e-08, 1, 0.6359743, 1.0501236, -1.1673055)
[node name="PickableObject3" parent="." unique_id=879935619 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, 0, -2.6077032e-08, 1.4901161e-08, 1, 0.5142721, 1.0654817, -1.0473135)
[node name="PickableObject4" parent="." unique_id=198541902 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, -5.293956e-23, -2.6077032e-08, 1.4901161e-08, 1, 0.5276739, 1.0501236, -1.1673055)
[node name="Hamburger2" parent="." unique_id=1349934579 instance=ExtResource("10_qacki")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.9857153, 1.1424131, 0.9472374)
[node name="PickableObject5" parent="." unique_id=1021333509 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, 0, -2.6077032e-08, 1.4901161e-08, 1, 0.73287535, 1.0922265, -1.0473135)
[node name="PickableObject6" parent="." unique_id=1268843669 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, -5.293956e-23, -2.6077032e-08, 1.4901161e-08, 1, 0.7462772, 1.0768684, -1.1673055)
[node name="Sink" parent="." unique_id=2055277359 instance=ExtResource("12_8apyq")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.3147688, 0.015500337, -1.4940417)
[node name="DirtStation" parent="." unique_id=160842153 instance=ExtResource("13_jnwcx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.0864775, 0.5, -1.244947)
[node name="Plate2" parent="." unique_id=356790445 instance=ExtResource("8_l1owj")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5730225, 1.1085004, 0.59790254)
[node name="CookedBurger" parent="." unique_id=1127807542 instance=ExtResource("14_1lg2m")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.30782473, 1.1446649, -1.0928738)
[node name="CookedBurger2" parent="." unique_id=160088590 instance=ExtResource("14_1lg2m")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.30671906, 1.0522771, -1.0928738)
[node name="CookedBurger3" parent="." unique_id=992183367 instance=ExtResource("14_1lg2m")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.3344773, 1.0492828, -0.7096845)
[node name="CookedBurger4" parent="." unique_id=1837607086 instance=ExtResource("14_1lg2m")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.30671906, 1.098119, -1.0928738)
[node name="BurgerBuns2" parent="." unique_id=1210358958 instance=ExtResource("6_bktvt")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.3596323, 1.0205106, -0.22482127)
[node name="PickableObject7" parent="." unique_id=641653545 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, 0, -2.6077032e-08, 1.4901161e-08, 1, -1.3556751, 1.0887735, 0.28881657)
[node name="PickableObject8" parent="." unique_id=1733819363 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, -5.293956e-23, -2.6077032e-08, 1.4901161e-08, 1, -1.3422732, 1.0734154, 0.16882455)
[node name="PickableObject9" parent="." unique_id=12419746 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, 0, -2.6077032e-08, 1.4901161e-08, 1, -1.4639754, 1.0887735, 0.28881657)
[node name="PickableObject10" parent="." unique_id=313160217 instance=ExtResource("11_npf8s")]
transform = Transform3D(1, 0, -2.2351742e-08, -2.9802322e-08, 1.0000001, -5.293956e-23, -2.6077032e-08, 1.4901161e-08, 1, -1.4505737, 1.0734154, 0.16882455)
[node name="Counter" parent="." unique_id=1487893288 instance=ExtResource("15_yy81s")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.7124918, 0.015500337, -1.4886917)
[node name="Counter2" parent="." unique_id=368890752 instance=ExtResource("15_yy81s")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -1.7648025, 0.015500337, -0.4458799)
[node name="Counter3" parent="." unique_id=1498817646 instance=ExtResource("15_yy81s")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -1.7648025, 0.015500337, 0.55367994)
[node name="Counter4" parent="." unique_id=906748771 instance=ExtResource("15_yy81s")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -1.7648025, 0.015500337, 1.5539298)
[node name="Hamburger3" parent="." unique_id=369573848 instance=ExtResource("10_qacki")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.7201865, 1.142413, 0.14773655)
[node name="Plate3" parent="." unique_id=2004250522 instance=ExtResource("8_l1owj")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5818124, 1.1085004, -0.4634577)
[node name="WorldContent" type="Node3D" parent="." unique_id=1660879286] [node name="WorldContent" type="Node3D" parent="." unique_id=1660879286]
[node name="Players" type="Node3D" parent="." unique_id=494935131] [node name="Players" type="Node3D" parent="." unique_id=494935131]
+8 -8
View File
@@ -1,15 +1,15 @@
[gd_scene format=3 uid="uid://c30i6h32w8p47"] [gd_scene format=3 uid="uid://c30i6h32w8p47"]
[ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_kdan8"] [ext_resource type="Script" uid="uid://d1cefhe3yyyds" path="res://Net/multiplayer_world.gd" id="1_kdan8"]
[ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://Prefabs/XROrigin.tscn" id="2_g30gi"] [ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_g30gi"]
[ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://Textures/dev_material_3d.tres" id="3_75ecy"] [ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_75ecy"]
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://Textures/sky/NightSkyHDRI009_16K.tres" id="5_c3xgf"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_c3xgf"]
[ext_resource type="Script" uid="uid://fyd2rjramhbb" path="res://Prefabs/kitchen_instantiator.gd" id="6_pw2j5"] [ext_resource type="Script" uid="uid://fyd2rjramhbb" path="res://prefabs/kitchen_instantiator.gd" id="6_pw2j5"]
[ext_resource type="PackedScene" uid="uid://damrxtlt7uswf" path="res://content/station_layouts/small_line.tscn" id="7_0sjqq"] [ext_resource type="PackedScene" uid="uid://damrxtlt7uswf" path="res://content/station_layouts/small_line.tscn" id="7_0sjqq"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://Stations/Hob.tscn" id="8_0sjqq"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="8_0sjqq"]
[ext_resource type="PackedScene" uid="uid://dm70ynyuw1a5u" path="res://Prefabs/day_controller.tscn" id="9_5wx0o"] [ext_resource type="PackedScene" uid="uid://dm70ynyuw1a5u" path="res://prefabs/day_controller.tscn" id="9_5wx0o"]
[ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://Prefabs/build_mode_controller.tscn" id="10_464r1"] [ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://prefabs/build_mode_controller.tscn" id="10_464r1"]
[ext_resource type="PackedScene" uid="uid://dxe05wp60jg3l" path="res://Scenes/queue_controller.tscn" id="11_de1dy"] [ext_resource type="PackedScene" uid="uid://dxe05wp60jg3l" path="res://scenes/queue_controller.tscn" id="11_de1dy"]
[ext_resource type="Script" uid="uid://biu4qr3nr1eny" path="res://test/mp_test_driver.gd" id="99_mptst"] [ext_resource type="Script" uid="uid://biu4qr3nr1eny" path="res://test/mp_test_driver.gd" id="99_mptst"]
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"] [sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
+1 -1
View File
@@ -32,7 +32,7 @@ func spawn_customer() -> void:
func _rebuild_table_list() -> void: func _rebuild_table_list() -> void:
_tables.clear() _tables.clear()
_tables.append_array(get_tree().get_nodes_in_group("table")) _tables.append_array(get_tree().get_nodes_in_group("table"))
SweetLogger.debug("_rebuild_table_list complete: {0}", [_tables]) SweetLogger.debug("Rebuild table list complete: {0}", [_tables])
func _try_to_assign_customers() -> void: func _try_to_assign_customers() -> void:
+1 -1
View File
@@ -4,7 +4,7 @@
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="2_1jq86"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="2_1jq86"]
[ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="3_bryd6"] [ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="3_bryd6"]
[ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="4_kpgm6"] [ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="4_kpgm6"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="5_gfdi7"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="5_gfdi7"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="7_jnxsa"] [ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="7_jnxsa"]
[ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://prefabs/build_mode_controller.tscn" id="9_hooyg"] [ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://prefabs/build_mode_controller.tscn" id="9_hooyg"]
[ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="11_gaw43"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="11_gaw43"]
+10 -10
View File
@@ -114,14 +114,14 @@ func get_next(size, walls):
var offset = [-1,-1] var offset = [-1,-1]
walls.shuffle() walls.shuffle()
SweetLogger.debug("get_next size: {0}", [size]) SweetLogger.debug("Size: {0}", [size])
for wall in walls: for wall in walls:
SweetLogger.debug("get_next wall: {0}", [wall]) SweetLogger.debug("Wall: {0}", [wall])
if wall["der"][1] == 0: if wall["der"][1] == 0:
SweetLogger.debug("get_next horizontal wall") SweetLogger.debug("Horizontal wall")
if size[0]<wall["len"]-6: if size[0]<wall["len"]-6:
SweetLogger.debug("TileMapLayer get_next length 6 less can go anywhere") SweetLogger.debug("Length 6 less can go anywhere")
if wall["der"][0] == 1:offset[1] = wall["pos"][1] if wall["der"][0] == 1:offset[1] = wall["pos"][1]
else: offset[1] = wall["pos"][1]-size[1] else: offset[1] = wall["pos"][1]-size[1]
@@ -130,16 +130,16 @@ func get_next(size, walls):
if size[0]+offset[0]>wall["pos"][0]+wall["len"]-3:offset[0] = wall["len"]-(3+size[0]) if size[0]+offset[0]>wall["pos"][0]+wall["len"]-3:offset[0] = wall["len"]-(3+size[0])
elif size[0]<=wall["len"]-3: elif size[0]<=wall["len"]-3:
SweetLogger.debug("TileMapLayer get_next 3 less needs to be on a corner") SweetLogger.debug("3 less needs to be on a corner")
if wall["der"][0] == 1:offset[1] = wall["pos"][1] if wall["der"][0] == 1:offset[1] = wall["pos"][1]
else: offset[1] = wall["pos"][1]-size[1] else: offset[1] = wall["pos"][1]-size[1]
if randi_range(0, 1):offset[0]=wall["pos"][0]+wall["len"]-size[0] if randi_range(0, 1):offset[0]=wall["pos"][0]+wall["len"]-size[0]
else:offset[0] = wall["pos"][0] else:offset[0] = wall["pos"][0]
else: else:
SweetLogger.debug("get_next vertical wall") SweetLogger.debug("Vertical wall")
if size[1]<wall["len"]-6: if size[1]<wall["len"]-6:
SweetLogger.debug("TileMapLayer get_next length 6 less can go anywhere") SweetLogger.debug("Length 6 less can go anywhere")
if wall["der"][1] == 1:offset[0] = wall["pos"][0] if wall["der"][1] == 1:offset[0] = wall["pos"][0]
else: offset[0] = wall["pos"][0]-size[0] else: offset[0] = wall["pos"][0]-size[0]
@@ -148,10 +148,10 @@ func get_next(size, walls):
if size[1]+offset[1]>wall["len"]-3:offset[1] = wall["len"]-(3+size[1]) if size[1]+offset[1]>wall["len"]-3:offset[1] = wall["len"]-(3+size[1])
elif size[1]<=wall["len"]-3: elif size[1]<=wall["len"]-3:
SweetLogger.debug("TileMapLayer get_next 3 less needs to be on a corner") SweetLogger.debug("3 less needs to be on a corner")
if wall["der"][1] == 1:offset[0] = wall["pos"][0] if wall["der"][1] == 1:offset[0] = wall["pos"][0]
else: offset[0] = wall["pos"][0]-size[0] else: offset[0] = wall["pos"][0]-size[0]
SweetLogger.debug("get_next offset: {0}", [offset]) SweetLogger.debug("Offset: {0}", [offset])
if randi() % 2:offset[1]=wall["pos"][1]+wall["len"]-size[1] if randi() % 2:offset[1]=wall["pos"][1]+wall["len"]-size[1]
else:offset[1] = wall["pos"][1] else:offset[1] = wall["pos"][1]
@@ -165,7 +165,7 @@ func get_next(size, walls):
func draw_room(Size, offset=Vector2i(0, 0)): func draw_room(Size, offset=Vector2i(0, 0)):
var walls = [] var walls = []
offset = Vector2i(offset[0], offset[1]) offset = Vector2i(offset[0], offset[1])
SweetLogger.debug("draw_room size: {0} offset: {1}", [Size, offset]) SweetLogger.debug("Size: {0} offset: {1}", [Size, offset])
for i in range(Size[0]): for i in range(Size[0]):
tile_map.set_cell(Vector2i(i+offset[0],offset[1]), 0, Vector2i(1,1)) tile_map.set_cell(Vector2i(i+offset[0],offset[1]), 0, Vector2i(1,1))
+11 -27
View File
@@ -1,22 +1,10 @@
[gd_scene format=3 uid="uid://c6rift56ql3f8"] [gd_scene format=3 uid="uid://c6rift56ql3f8"]
[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_myl3s"] [ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_myl3s"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="1_p30r1"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_u2p81"]
[ext_resource type="PackedScene" uid="uid://c0lknik4noobs" path="res://items/BurgerBuns.tscn" id="2_1q74o"] [ext_resource type="PackedScene" uid="uid://c0lknik4noobs" path="res://items/BurgerBuns.tscn" id="2_1q74o"]
[ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_rf1b2"] [ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_rf1b2"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_u2p81"]
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(".:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"] [sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"]
radius = 0.3 radius = 0.3
@@ -27,30 +15,26 @@ radius = 0.3
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"]
albedo_color = Color(0.6784191, 0.54546416, 0.016760282, 1) albedo_color = Color(0.6784191, 0.54546416, 0.016760282, 1)
[node name="BurgerBunsDispenser" type="Node3D" unique_id=1410160280] [node name="BurgerBunsDispenser" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_u2p81")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../BurgerBunsDispenser") station = NodePath("../BurgerBunsDispenser")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=904562637] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
root_path = NodePath("../BurgerBunsDispenser")
replication_config = SubResource("SceneReplicationConfig_u2p81")
[node name="BurgerBunsDispenser" type="StaticBody3D" parent="." unique_id=1720683779 groups=["station"]]
script = ExtResource("1_myl3s")
item_scene = ExtResource("2_1q74o")
[node name="XRToolsSnapZone" type="Area3D" parent="BurgerBunsDispenser" unique_id=805334513 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0162505, -0.002165556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0162505, -0.002165556)
collision_layer = 65536 collision_layer = 65536
collision_mask = 65536 collision_mask = 65536
script = ExtResource("1_p30r1")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D" type="CollisionShape3D" parent="BurgerBunsDispenser/XRToolsSnapZone" unique_id=1104626493] [node name="CollisionShape3D" parent="SnapZone" index="0"]
shape = SubResource("SphereShape3D_xmbo2") shape = SubResource("SphereShape3D_xmbo2")
[node name="BurgerBunsDispenser" type="StaticBody3D" parent="." index="6" unique_id=1720683779 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("1_myl3s")
item_scene = ExtResource("2_1q74o")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="CollisionShape3D" type="CollisionShape3D" parent="BurgerBunsDispenser" unique_id=1470079357] [node name="CollisionShape3D" type="CollisionShape3D" parent="BurgerBunsDispenser" unique_id=1470079357]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("CylinderShape3D_24d3s") shape = SubResource("CylinderShape3D_24d3s")
+20 -49
View File
@@ -1,32 +1,10 @@
[gd_scene format=3 uid="uid://efaec6ymgabo"] [gd_scene format=3 uid="uid://efaec6ymgabo"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_3jbl6"] [ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="1_dlkho"]
[ext_resource type="Script" uid="uid://cql13y8da4auf" path="res://stations/counter.gd" id="1_oapbh"] [ext_resource type="Script" uid="uid://cql13y8da4auf" path="res://stations/counter.gd" id="1_oapbh"]
[ext_resource type="AudioStream" uid="uid://bqtk1adk8umbx" path="res://sounds/220197__gameaudio__click-basic.wav" id="2_0aadn"] [ext_resource type="AudioStream" uid="uid://bqtk1adk8umbx" path="res://sounds/220197__gameaudio__click-basic.wav" id="2_0aadn"]
[ext_resource type="AudioStream" uid="uid://daiv8ubwdbidf" path="res://sounds/220195__gameaudio__click-wooden-1.wav" id="2_lg82m"] [ext_resource type="AudioStream" uid="uid://daiv8ubwdbidf" path="res://sounds/220195__gameaudio__click-wooden-1.wav" id="2_lg82m"]
[ext_resource type="PackedScene" uid="uid://dgk88esxip5xi" path="res://items/knife.tscn" id="3_3gvdi"] [ext_resource type="PackedScene" uid="uid://dgk88esxip5xi" path="res://items/knife.tscn" id="3_3gvdi"]
[ext_resource type="PackedScene" uid="uid://bxbocxdaayvwx" path="res://UI/progress_bar.tscn" id="6_racgh"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_3jbl6"]
properties/0/path = NodePath("Counter:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("Counter:rotation")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("Counter:process_result")
properties/2/spawn = false
properties/2/replication_mode = 1
properties/3/path = NodePath("Counter:process_result_work")
properties/3/spawn = false
properties/3/replication_mode = 1
properties/4/path = NodePath("Counter:work_progress")
properties/4/spawn = false
properties/4/replication_mode = 1
properties/5/path = NodePath("Counter:visible")
properties/5/spawn = false
properties/5/replication_mode = 1
[sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"] [sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"]
size = Vector3(0.48521727, 0.040039063, 0.41994628) size = Vector3(0.48521727, 0.040039063, 0.41994628)
@@ -46,20 +24,33 @@ albedo_color = Color(0.66595805, 0.53976387, 0.4331022, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"]
albedo_color = Color(1.1759251, 0.741115, 0.5692133, 1) albedo_color = Color(1.1759251, 0.741115, 0.5692133, 1)
[node name="Counter" type="Node3D" unique_id=672880121] [node name="Counter" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_3jbl6")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../Counter") station = NodePath("../Counter")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1583772931] [node name="ProgressBar3D" parent="." index="4" unique_id=654673176]
replication_config = SubResource("SceneReplicationConfig_3jbl6") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2838624, -0.18)
[node name="Counter" type="StaticBody3D" parent="." unique_id=1487893288 node_paths=PackedStringArray("audio", "knife", "progress_bar") groups=["station"]] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0647464, 0)
collision_layer = 65536
collision_mask = 65540
stash_sound = ExtResource("2_0aadn")
snap_mode = 1
[node name="CollisionShape3D" parent="SnapZone" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.002, 0)
shape = SubResource("BoxShape3D_1ntq7")
[node name="Counter" type="StaticBody3D" parent="." index="6" unique_id=1487893288 node_paths=PackedStringArray("audio", "knife", "snap_zone", "synchronizer", "progress_bar") groups=["station"]]
script = ExtResource("1_oapbh") script = ExtResource("1_oapbh")
audio = NodePath("AudioStreamPlayer3D") audio = NodePath("AudioStreamPlayer3D")
chop_audio = ExtResource("2_lg82m") chop_audio = ExtResource("2_lg82m")
knife = NodePath("Knife") knife = NodePath("Knife")
progress_bar = NodePath("ProgressBar3D") snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
progress_bar = NodePath("../ProgressBar3D")
[node name="CollisionShape3DCuttingBoard" type="CollisionShape3D" parent="Counter" unique_id=706340473] [node name="CollisionShape3DCuttingBoard" type="CollisionShape3D" parent="Counter" unique_id=706340473]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00088502467, 1.0178218, 0.0009101778) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00088502467, 1.0178218, 0.0009101778)
@@ -85,24 +76,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2838624, 0)
freeze = true freeze = true
release_mode = 1 release_mode = 1
[node name="XRToolsSnapZone" type="Area3D" parent="Counter" unique_id=1647380272 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0647464, 0)
collision_layer = 65536
collision_mask = 65540
script = ExtResource("1_dlkho")
stash_sound = ExtResource("2_0aadn")
snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Counter/XRToolsSnapZone" unique_id=969340130]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.002, 0)
shape = SubResource("BoxShape3D_1ntq7")
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Counter/XRToolsSnapZone" unique_id=1786831079]
[node name="ProgressBar3D" parent="Counter" unique_id=654673176 instance=ExtResource("6_racgh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2838624, -0.18)
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="Counter" unique_id=451757283] [node name="CSGCombiner3D" type="CSGCombiner3D" parent="Counter" unique_id=451757283]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5038623, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5038623, 0)
@@ -155,5 +128,3 @@ operation = 2
size = Vector3(0.037109375, 0.092285156, 0.26757813) size = Vector3(0.037109375, 0.092285156, 0.26757813)
[connection signal="body_entered" from="Counter/GestureArea" to="Counter" method="_on_gesture_area_body_entered"] [connection signal="body_entered" from="Counter/GestureArea" to="Counter" method="_on_gesture_area_body_entered"]
[connection signal="has_dropped" from="Counter/XRToolsSnapZone" to="Counter" method="_on_snap_zone_dropped"]
[connection signal="has_picked_up" from="Counter/XRToolsSnapZone" to="Counter" method="_on_snap_zone_picked_up"]
+43 -79
View File
@@ -1,40 +1,14 @@
[gd_scene format=3 uid="uid://j7caslh27nor"] [gd_scene format=3 uid="uid://b052o1fgwq5bw"]
[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_2p1q6"]
[ext_resource type="Script" uid="uid://bsn8vhv5adxdo" path="res://stations/hob.gd" id="1_7jc4g"] [ext_resource type="Script" uid="uid://bsn8vhv5adxdo" path="res://stations/hob.gd" id="1_7jc4g"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_pydjp"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="2_er1dp"]
[ext_resource type="AudioStream" uid="uid://dmyuqe5058sv3" path="res://sounds/220197__gameaudio__click-basic.wav" id="3_6oyg1"]
[ext_resource type="PackedScene" uid="uid://bxbocxdaayvwx" path="res://UI/progress_bar.tscn" id="3_7uuqv"]
[ext_resource type="Material" uid="uid://d1djvskv4n4m3" path="res://textures/hob_off.tres" id="4_8qpxk"] [ext_resource type="Material" uid="uid://d1djvskv4n4m3" path="res://textures/hob_off.tres" id="4_8qpxk"]
[ext_resource type="Material" uid="uid://db7c7w4apwti7" path="res://textures/hob_on.tres" id="6_m7l4u"] [ext_resource type="Material" uid="uid://db7c7w4apwti7" path="res://textures/hob_on.tres" id="6_m7l4u"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_np_hob"] [sub_resource type="BoxShape3D" id="BoxShape3D_l0sax"]
properties/0/path = NodePath("Hob:time_cooked")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("Hob:cooking_result")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("Hob:cooking_result_time")
properties/2/spawn = false
properties/2/replication_mode = 1
properties/3/path = NodePath("Hob:position")
properties/3/spawn = false
properties/3/replication_mode = 1
properties/4/path = NodePath("Hob:rotation")
properties/4/spawn = false
properties/4/replication_mode = 1
properties/5/path = NodePath("Hob:visible")
properties/5/spawn = false
properties/5/replication_mode = 1
[sub_resource type="BoxShape3D" id="BoxShape3D_kdxnr"]
size = Vector3(0.6, 1, 0.6) size = Vector3(0.6, 1, 0.6)
[sub_resource type="BoxShape3D" id="BoxShape3D_7uuqv"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bmu77"]
size = Vector3(0.6, 0.12802735, 0.6)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gkb3v"]
[sub_resource type="Animation" id="Animation_7uuqv"] [sub_resource type="Animation" id="Animation_7uuqv"]
length = 0.001 length = 0.001
@@ -163,134 +137,124 @@ tracks/4/keys = {
"values": [1.0, 0.0, 1.0] "values": [1.0, 0.0, 1.0]
} }
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ac5f3"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_pydjp"]
_data = { _data = {
&"RESET": SubResource("Animation_7uuqv"), &"RESET": SubResource("Animation_7uuqv"),
&"hob": SubResource("Animation_6oyg1") &"hob": SubResource("Animation_6oyg1")
} }
[node name="Hob" type="Node3D" unique_id=172418174] [node name="Hob" unique_id=707500902 instance=ExtResource("1_2p1q6")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_pydjp")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../Hob") station = NodePath("../Hob")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=768992259] [node name="ProgressBar3D" parent="." index="4" unique_id=654673176]
replication_config = SubResource("SceneReplicationConfig_np_hob") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, -0.18)
[node name="Hob" type="StaticBody3D" parent="." unique_id=1332123047 groups=["station"]] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
script = ExtResource("1_7jc4g") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.048892, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Hob" unique_id=1283846023]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51483154, 0)
shape = SubResource("BoxShape3D_kdxnr")
[node name="XRToolsSnapZone" type="Area3D" parent="Hob" unique_id=538157739 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0418437, 0)
collision_layer = 65536
collision_mask = 65540
script = ExtResource("2_er1dp")
stash_sound = ExtResource("3_6oyg1")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Hob/XRToolsSnapZone" unique_id=370920392] [node name="Hob" type="StaticBody3D" parent="." index="6" unique_id=732560156 node_paths=PackedStringArray("animation_player", "notification_audio", "ambient_audio", "progress_bar", "snap_zone", "synchronizer") groups=["station"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.000975132, 0) script = ExtResource("1_7jc4g")
shape = SubResource("BoxShape3D_7uuqv") animation_player = NodePath("AnimationPlayer")
notification_audio = NodePath("../AudioStreamPlayer3DPulse")
ambient_audio = NodePath("../AudioStreamPlayer3DContinous")
progress_bar = NodePath("../ProgressBar3D")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Hob/XRToolsSnapZone" unique_id=1991627595] [node name="CollisionShape3D" type="CollisionShape3D" parent="Hob" index="0" unique_id=3886639]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.022546828, -0.5270121, 0.36528283) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51483154, 0)
stream = ExtResource("3_6oyg1") shape = SubResource("BoxShape3D_l0sax")
[node name="ProgressBar3D" parent="Hob" unique_id=654673176 instance=ExtResource("3_7uuqv")] [node name="CSGCombiner3D" type="CSGCombiner3D" parent="Hob" index="1" unique_id=1047451362]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2621956, -0.09216304)
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="Hob" unique_id=70901698]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51483154, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51483154, 0)
[node name="CSGBox3D" type="CSGBox3D" parent="Hob/CSGCombiner3D" unique_id=1111505172] [node name="CSGBox3D" type="CSGBox3D" parent="Hob/CSGCombiner3D" index="0" unique_id=797498087]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00071543455, 3.7252903e-09, -0.008516133) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00071543455, 3.7252903e-09, -0.008516133)
size = Vector3(0.6, 1, 0.5821045) size = Vector3(0.6, 1, 0.5821045)
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Hob/CSGCombiner3D/CSGBox3D" unique_id=1338463939] [node name="CSGCylinder3D" type="CSGCylinder3D" parent="Hob/CSGCombiner3D/CSGBox3D" index="0" unique_id=1788217430]
transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5103538, -7.827557e-05) transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5103538, -7.827557e-05)
operation = 2 operation = 2
radius = 0.25976563 radius = 0.25976563
height = 0.08898926 height = 0.08898926
sides = 32 sides = 32
[node name="CSGTorus3D3" type="CSGTorus3D" parent="Hob/CSGCombiner3D" unique_id=666891341] [node name="CSGTorus3D3" type="CSGTorus3D" parent="Hob/CSGCombiner3D" index="1" unique_id=1365654856]
transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05) transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05)
inner_radius = 0.09153879 inner_radius = 0.09153879
outer_radius = 0.120084204 outer_radius = 0.120084204
sides = 32 sides = 32
material = ExtResource("4_8qpxk") material = ExtResource("4_8qpxk")
[node name="CSGTorus3D2" type="CSGTorus3D" parent="Hob/CSGCombiner3D" unique_id=24541894] [node name="CSGTorus3D2" type="CSGTorus3D" parent="Hob/CSGCombiner3D" index="2" unique_id=2113291709]
transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05) transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05)
inner_radius = 0.15036294 inner_radius = 0.15036294
outer_radius = 0.17592031 outer_radius = 0.17592031
sides = 32 sides = 32
material = ExtResource("4_8qpxk") material = ExtResource("4_8qpxk")
[node name="CSGTorus3D" type="CSGTorus3D" parent="Hob/CSGCombiner3D" unique_id=1901978664] [node name="CSGTorus3D" type="CSGTorus3D" parent="Hob/CSGCombiner3D" index="3" unique_id=196825717]
transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05) transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.5003869, -7.827557e-05)
inner_radius = 0.20426142 inner_radius = 0.20426142
outer_radius = 0.2321898 outer_radius = 0.2321898
sides = 32 sides = 32
material = ExtResource("4_8qpxk") material = ExtResource("4_8qpxk")
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=1107239311] [node name="CSGCylinder3D" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="4" unique_id=893001662]
transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.4498226, -7.827557e-05) transform = Transform3D(0.8943019, 0, 0, 0, 0.8943019, 0, 0, 0, 0.8943019, 0, 0.4498226, -7.827557e-05)
radius = 0.071777344 radius = 0.071777344
height = 0.09637451 height = 0.09637451
sides = 32 sides = 32
[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=435540815] [node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="5" unique_id=1086831704]
transform = Transform3D(0.8943019, 0, 0, 0, -3.9091177e-08, 0.8943019, 0, -0.8943019, -3.9091177e-08, 0, 0.48668858, -0.0020651226) transform = Transform3D(0.8943019, 0, 0, 0, -3.9091177e-08, 0.8943019, 0, -0.8943019, -3.9091177e-08, 0, 0.48668858, -0.0020651226)
radius = 0.008 radius = 0.008
height = 0.44487303 height = 0.44487303
[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=878171801] [node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="6" unique_id=145519146]
transform = Transform3D(-3.9091177e-08, -0.8943019, -3.9091177e-08, 0, -3.9091177e-08, 0.8943019, -0.8943019, 3.9091177e-08, 1.7087296e-15, 0, 0.48668858, -0.0020651226) transform = Transform3D(-3.9091177e-08, -0.8943019, -3.9091177e-08, 0, -3.9091177e-08, 0.8943019, -0.8943019, 3.9091177e-08, 1.7087296e-15, 0, 0.48668858, -0.0020651226)
radius = 0.008 radius = 0.008
height = 0.44487303 height = 0.44487303
[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=1619646436] [node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="7" unique_id=905149123]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, -0.20412213, 0.42728558, 0.26171687) transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, -0.20412213, 0.42728558, 0.26171687)
radius = 0.044433594 radius = 0.044433594
height = 0.10932617 height = 0.10932617
material = SubResource("StandardMaterial3D_gkb3v") material = SubResource("StandardMaterial3D_bmu77")
[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=548846612] [node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="8" unique_id=2028954364]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0.12531614, 0.42728558, 0.26171687) transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0.12531614, 0.42728558, 0.26171687)
radius = 0.044433594 radius = 0.044433594
height = 0.10932617 height = 0.10932617
material = SubResource("StandardMaterial3D_gkb3v") material = SubResource("StandardMaterial3D_bmu77")
[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" unique_id=1208989647] [node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Hob/CSGCombiner3D" index="9" unique_id=1588021797]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0.22979808, 0.42728558, 0.26171687) transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0.22979808, 0.42728558, 0.26171687)
radius = 0.044433594 radius = 0.044433594
height = 0.10932617 height = 0.10932617
material = SubResource("StandardMaterial3D_gkb3v") material = SubResource("StandardMaterial3D_bmu77")
[node name="CSGBox3D2" type="CSGBox3D" parent="Hob/CSGCombiner3D" unique_id=465340362] [node name="CSGBox3D2" type="CSGBox3D" parent="Hob/CSGCombiner3D" index="10" unique_id=1620789236]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.039733887, -0.07685089, 0.29250562) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.039733887, -0.07685089, 0.29250562)
operation = 2 operation = 2
size = Vector3(1.0999756, 0.8462982, 0.072387695) size = Vector3(1.0999756, 0.8462982, 0.072387695)
[node name="CSGBox3D3" type="CSGBox3D" parent="Hob/CSGCombiner3D" unique_id=1813079759] [node name="CSGBox3D3" type="CSGBox3D" parent="Hob/CSGCombiner3D" index="11" unique_id=1140499039]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.003479004, -0.08253479, 0.2656765) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.003479004, -0.08253479, 0.2656765)
size = Vector3(0.55, 0.835, 0.072) size = Vector3(0.55, 0.835, 0.072)
[node name="CSGBox3D4" type="CSGBox3D" parent="Hob/CSGCombiner3D" unique_id=1978186019] [node name="CSGBox3D4" type="CSGBox3D" parent="Hob/CSGCombiner3D" index="12" unique_id=923397574]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.003479004, -0.45215607, 0.24655426) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.003479004, -0.45215607, 0.24655426)
size = Vector3(0.55, 0.096, 0.14) size = Vector3(0.55, 0.096, 0.14)
[node name="AnimationPlayer" type="AnimationPlayer" parent="Hob" unique_id=1525460719] [node name="AnimationPlayer" type="AnimationPlayer" parent="Hob" index="2" unique_id=1592340772]
root_node = NodePath("../..") root_node = NodePath("../..")
libraries/ = SubResource("AnimationLibrary_ac5f3") libraries/ = SubResource("AnimationLibrary_pydjp")
[node name="OmniLight3D" type="OmniLight3D" parent="Hob" unique_id=1618457623] [node name="OmniLight3D" type="OmniLight3D" parent="Hob" index="3" unique_id=2050713654]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0201802, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0201802, 0)
light_color = Color(1, 0.13725491, 0, 1) light_color = Color(1, 0.13725491, 0, 1)
light_energy = 0.0 light_energy = 0.0
+58 -111
View File
@@ -1,4 +1,5 @@
extends StaticBody3D class_name Counter
extends WorkStation
@export var chop_work_steps: float = 5.0 @export var chop_work_steps: float = 5.0
@export var chop_min_speed: float = 2.0 @export var chop_min_speed: float = 2.0
@@ -6,92 +7,46 @@ extends StaticBody3D
@export var audio: AudioStreamPlayer3D @export var audio: AudioStreamPlayer3D
@export var chop_audio: AudioStream @export var chop_audio: AudioStream
@export var knife: XRToolsPickable @export var knife: XRToolsPickable
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
@export var progress_bar: ProgressBar3D
# Chopping state. Follow the hob/sink pattern so the display refreshes when
# values change; only the world owner runs the station's process in practice.
@export var process_result: String = "": set = _set_result
@export var process_result_work: float = 0.0: set = _set_result_work
@export var work_progress: float = 0.0: set = _set_work_progress
func _ready() -> void: func _ready() -> void:
super.ready()
SweetLogger.debug("Counter {0} _ready", [name])
if not audio: if not audio:
push_error("Counter is missing reference to AudioStreamPlayer3D") SweetLogger.warning("{0} missing audio reference", [name])
if not chop_audio: if not chop_audio:
push_error("Counter is missing reference to chop_audio AudioStream") SweetLogger.warning("{0} missing chop_audio reference", [name])
if not progress_bar or progress_bar is not ProgressBar3D: if not knife:
push_error("Counter missing reference to progressbar, or wrong type:", progress_bar) SweetLogger.warning("{0} missing knife reference", [name])
if not knife or knife is not XRToolsPickable:
push_error("Counter missing reference to knife, or wrong type:", knife)
if not snap_zone or snap_zone is not XRToolsSnapZone:
push_error("Counter missing reference to snap_zone, or wrong type:", snap_zone)
snap_zone.has_picked_up.connect(_on_object_picked_up)
snap_zone.has_dropped.connect(_on_object_dropped)
progress_bar.override_fill_color(Color.GREEN)
_hide_all_tools()
_refresh_progress_bar()
func _set_work_progress(value: float) -> void:
work_progress = value
_refresh_progress_bar()
func _set_result(value: String) -> void:
process_result = value
_refresh_progress_bar()
# When a chopping recipe is set, show the knife for the player to use.
if not process_result.is_empty():
knife.visible = true
knife.enabled = true
SweetLogger.debug("chopping recipe set: {0}", [process_result])
else:
_hide_all_tools() _hide_all_tools()
func _set_result_work(value: float) -> void: func _start_chopping(id: String, work: float) -> void:
process_result_work = value if not enabled:
_refresh_progress_bar()
func _refresh_progress_bar() -> void:
if not progress_bar:
return return
var progress := 0.0 result_id = id
if process_result != "" and process_result_work > 0: max_work = work
progress = clampf(float(work_progress) / process_result_work, 0.0, 1.0) SweetLogger.info("Start chopping - result_id: {0}, max_work: {1}", [result_id, max_work])
progress_bar.set_progress(progress)
progress_bar.set_bar_visible(not process_result.is_empty()) func _process(delta: float) -> void:
progress_bar.override_fill_color(Color.GREEN) super.process(delta)
func _hide_all_tools():
knife.visible = false
knife.enabled = false
# Add work from gesture area (knife hits). This increments the chopping progress.
func add_work(work: float) -> void:
SweetLogger.debug("add_work: {0}", [work])
# Only the world owner should drive the authoritative state. Guarding is
# handled by higher-level NetworkManager logic elsewhere, mirror hob's
# convert_held_to_item which checks ownership before spawning.
work_progress += work
# Play chopping sound if available
if audio and chop_audio:
audio.stream = chop_audio
audio.play()
# If we've reached the required time, convert the held item
if process_result != "" and process_result_work > 0 and work_progress >= process_result_work:
SweetLogger.debug("chopping complete, converting item to: {0}", [process_result])
work_progress = 0
convert_held_to_item(process_result)
func _on_gesture_area_body_entered(body: Node3D) -> void: func _on_gesture_area_body_entered(body: Node3D) -> void:
SweetLogger.debug("gesture area entered: {0}", [body]) SweetLogger.debug("Gesture area entered: {0}", [body])
if body.is_in_group("chopping_tool"): if not body.is_in_group("chopping_tool"):
if process_result == "": return
SweetLogger.debug("knife entered but nothing to chop") if result_id == "":
SweetLogger.debug("Knife entered but nothing to chop")
return return
var speed := 0.0 var speed := 0.0
@@ -101,56 +56,48 @@ func _on_gesture_area_body_entered(body: Node3D) -> void:
speed = body.velocity.length() speed = body.velocity.length()
if speed < chop_min_speed: if speed < chop_min_speed:
SweetLogger.debug("knife too slow for chopping: {0}", [speed]) SweetLogger.debug("Knife too slow for chopping: {0}", [speed])
return return
if audio and chop_audio:
audio.stream = chop_audio
audio.play()
add_work(chop_work_steps) add_work(chop_work_steps)
func _on_object_picked_up(_item: Variant) -> void: # Called from Station base class
SweetLogger.debug("object picked up: {0}", [_item]) func refresh_display() -> void:
var food_item = Helper.find_food_item(_item) super.refresh_display()
if not food_item: progress_bar.override_fill_color(Color.GREEN)
SweetLogger.debug("held object is not a FoodItem")
return
# Called from Station base class
func on_food_item_picked_up(food_item: FoodItem) -> void:
SweetLogger.debug("Object picked up: {0}", [food_item])
if not food_item:
SweetLogger.debug("Held object is not a FoodItem")
return
var result = RecipeManager.get_chopping_result(food_item.id) var result = RecipeManager.get_chopping_result(food_item.id)
if not result: if not result:
SweetLogger.debug("held a FoodItem that is not choppable, id: {0} process_result: {1}", [food_item.id, result]) SweetLogger.debug("Held a FoodItem that is not choppable, id: {0} result: {1}", [food_item.id, result])
return return
process_result = result knife.visible = true
process_result_work = RecipeManager.get_chopping_work(food_item.id) knife.enabled = true
SweetLogger.debug("set process_result {0} work: {1}", [process_result, process_result_work]) _start_chopping(result, RecipeManager.get_chopping_work(food_item.id))
func _on_object_dropped(_item: Variant) -> void: # Called from Station base class
SweetLogger.debug("object drop") func on_object_dropped(_item: Node3D) -> void:
work_progress = 0 SweetLogger.debug("->[]")
process_result = ""
process_result_work = 0
_hide_all_tools() _hide_all_tools()
reset()
func convert_held_to_item(_item: String) -> void: # Called from Station base class
if not NetworkManager.owns_world(): func on_work_complete():
return SweetLogger.debug("->[]")
SweetLogger.debug("converting {0}", [_item]) _hide_all_tools()
convert_item()
var old_pickable = snap_zone.picked_up_object
if not old_pickable:
push_warning("Counter finished processing _item, but snap zone is missing its reference")
return
var original_transform = old_pickable.global_transform
var new_scene_instance = NetworkManager.spawn_item(RecipeManager.get_item_scene(_item).resource_path, original_transform)
SweetLogger.debug("freeing old_pickable {0}", [old_pickable])
snap_zone.drop_object()
NetworkManager.despawn_item(old_pickable)
snap_zone.pick_up_object(new_scene_instance)
func _hide_all_tools():
knife.visible = false
knife.enabled = false
+11 -26
View File
@@ -1,22 +1,10 @@
[gd_scene format=3 uid="uid://bbg7dwsbxxh1t"] [gd_scene format=3 uid="uid://bbg7dwsbxxh1t"]
[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_4m60m"] [ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_4m60m"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_qooyy"]
[ext_resource type="PackedScene" uid="uid://e4i6o5oriecx" path="res://items/PickupCube.tscn" id="2_nn8tr"] [ext_resource type="PackedScene" uid="uid://e4i6o5oriecx" path="res://items/PickupCube.tscn" id="2_nn8tr"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="3_ahn1e"]
[ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_nn8tr"] [ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_nn8tr"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_0wtc7"]
properties/0/path = NodePath("CubeSideDispenser:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("CubeSideDispenser:rotation")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("CubeSideDispenser:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"] [sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"]
radius = 0.3 radius = 0.3
@@ -31,30 +19,27 @@ albedo_color = Color(0.1764706, 1, 1, 1)
material = SubResource("StandardMaterial3D_24d3s") material = SubResource("StandardMaterial3D_24d3s")
size = Vector3(0.1, 0.1, 0.1) size = Vector3(0.1, 0.1, 0.1)
[node name="CubeSideDispenser" type="Node3D" unique_id=1285718741] [node name="CubeSideDispenser" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_qooyy")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../CubeSideDispenser") station = NodePath("../CubeSideDispenser")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=821487160] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
replication_config = SubResource("SceneReplicationConfig_0wtc7")
[node name="CubeSideDispenser" type="StaticBody3D" parent="." unique_id=200950572 groups=["station"]]
script = ExtResource("1_4m60m")
item_scene = ExtResource("2_nn8tr")
[node name="XRToolsSnapZone" type="Area3D" parent="CubeSideDispenser" unique_id=1018021004 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0440714, -0.002165556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0440714, -0.002165556)
collision_layer = 65536 collision_layer = 65536
collision_mask = 65536 collision_mask = 65536
script = ExtResource("3_ahn1e")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D" type="CollisionShape3D" parent="CubeSideDispenser/XRToolsSnapZone" unique_id=182042233] [node name="CollisionShape3D" parent="SnapZone" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.15291119, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.15291119, 0)
shape = SubResource("SphereShape3D_xmbo2") shape = SubResource("SphereShape3D_xmbo2")
[node name="CubeSideDispenser" type="StaticBody3D" parent="." index="6" unique_id=200950572 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("1_4m60m")
item_scene = ExtResource("2_nn8tr")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="CollisionShape3D" type="CollisionShape3D" parent="CubeSideDispenser" unique_id=1974757539] [node name="CollisionShape3D" type="CollisionShape3D" parent="CubeSideDispenser" unique_id=1974757539]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("CylinderShape3D_24d3s") shape = SubResource("CylinderShape3D_24d3s")
+8 -8
View File
@@ -1,19 +1,19 @@
extends StaticBody3D class_name DirtStation
extends Station
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
# Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
snap_zone.has_picked_up.connect(_makeDirty) super.ready()
SweetLogger.debug("DirtStation {0} _ready", [name])
func _makeDirty(item) -> void:
# Called from Station base class
func on_object_picked_up(item: Node3D) -> void:
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
return return
var plate: PlateController = item.get_node_or_null("PlateController") as PlateController var plate: PlateController = item.get_node_or_null("PlateController") as PlateController
if not plate: if not plate:
SweetLogger.debug("held object is not a Plate") SweetLogger.debug("Held object is not a Plate")
return return
if not plate.is_dirty: if not plate.is_dirty:
plate.is_dirty = true plate.is_dirty = true
+15 -30
View File
@@ -1,19 +1,7 @@
[gd_scene format=3 uid="uid://cnjwtnhwh0i8q"] [gd_scene format=3 uid="uid://cnjwtnhwh0i8q"]
[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://q7tpwmrbmu1m" path="res://stations/dirt_station.gd" id="1_hc1d4"] [ext_resource type="Script" uid="uid://q7tpwmrbmu1m" path="res://stations/dirt_station.gd" id="1_hc1d4"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_ucg2q"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="2_v0ytd"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_ku4h3"]
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(".:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"] [sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"]
size = Vector3(0.5, 1, 0.5) size = Vector3(0.5, 1, 0.5)
@@ -28,17 +16,25 @@ size = Vector3(0.5, 1, 0.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_mep2a"] [sub_resource type="BoxShape3D" id="BoxShape3D_mep2a"]
size = Vector3(0.81640625, 0.5635376, 0.79351807) size = Vector3(0.81640625, 0.5635376, 0.79351807)
[node name="DirtStation" type="Node3D" unique_id=784427347] [node name="DirtStation" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_ucg2q")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../DirtStation") station = NodePath("../DirtStation")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1485614825] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
root_path = NodePath("../DirtStation") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0313971, 0)
replication_config = SubResource("SceneReplicationConfig_ku4h3") collision_layer = 65536
collision_mask = 65540
snap_mode = 1
[node name="DirtStation" type="StaticBody3D" parent="." unique_id=160842153 groups=["station"]] [node name="CollisionShape3D" parent="SnapZone" index="0"]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0.008666992, -0.11009073, -0.009353638)
shape = SubResource("BoxShape3D_mep2a")
[node name="DirtStation" type="StaticBody3D" parent="." index="6" unique_id=160842153 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("1_hc1d4") script = ExtResource("1_hc1d4")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="CollisionShape3D" type="CollisionShape3D" parent="DirtStation" unique_id=1400366312] [node name="CollisionShape3D" type="CollisionShape3D" parent="DirtStation" unique_id=1400366312]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
@@ -52,14 +48,3 @@ mesh = SubResource("BoxMesh_ay2w6")
transform = Transform3D(0.9999992, 0, 0, 0, 0.99999946, 0, 0, 0, 0.9999992, 0.002797456, 0.6309581, -0.2812457) transform = Transform3D(0.9999992, 0, 0, 0, 0.99999946, 0, 0, 0, 0.9999992, 0.002797456, 0.6309581, -0.2812457)
text = "Dirt" text = "Dirt"
[node name="XRToolsSnapZone" type="Area3D" parent="DirtStation" unique_id=333161027 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0313971, 0)
collision_layer = 65536
collision_mask = 65540
script = ExtResource("2_v0ytd")
snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D2" type="CollisionShape3D" parent="DirtStation/XRToolsSnapZone" unique_id=1398712192]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0.008666992, -0.11009073, -0.009353638)
shape = SubResource("BoxShape3D_mep2a")
+52 -113
View File
@@ -1,127 +1,66 @@
extends StaticBody3D class_name Hob
extends WorkStation
@export var cook_speed = 1 @export var cook_speed = 1
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
@onready var progress_bar: ProgressBar3D = $ProgressBar3D
## Cooking state. All three are replicated (see Hob.tscn's Sync node) and each @export var animation_player: AnimationPlayer
## refreshes the display when it changes, which is what makes the hob look alive
## on a client: only the world owner runs the station's _process and its snap
## zone, so a client never reaches the code below by itself and would otherwise
## show a hob that never lights up.
@export var time_cooked: float = 0.0: set = _set_time_cooked
@export var cooking_result: String = "": set = _set_cooking_result
@export var cooking_result_time: float = 0.0: set = _set_cooking_result_time
func _set_time_cooked(value: float) -> void:
if is_equal_approx(time_cooked, value):
return
time_cooked = value
_refresh_display()
func _set_cooking_result(value: String) -> void:
if cooking_result == value:
return
cooking_result = value
_refresh_display()
# The flames follow whether we're cooking, on every peer.
_play_animation("hob" if not cooking_result.is_empty() else "RESET")
func _set_cooking_result_time(value: float) -> void:
if is_equal_approx(cooking_result_time, value):
return
cooking_result_time = value
_refresh_display()
func _ready() -> void: func _ready() -> void:
if not progress_bar or progress_bar is not ProgressBar3D: super.ready()
push_error("Hob missing reference to progressbar, or wrong type:", progress_bar) SweetLogger.debug("Hob {0} _ready", [name])
snap_zone.has_picked_up.connect(_on_object_picked_up) if not animation_player:
snap_zone.has_dropped.connect(_on_object_dropped) SweetLogger.warning("{0} missing animation_player reference", [name])
_refresh_display()
func _start_cooking(id: String, work: float) -> void:
func _play_animation(name: String) -> void: animation_player.play("hob")
# Replicated setters can fire before the node is in the tree (spawn payload), if not enabled:
# when the @onready children don't exist yet.
var player := get_node_or_null("AnimationPlayer") as AnimationPlayer
if player:
player.play(name)
func _refresh_display() -> void:
# Guarded for the same reason as _play_animation.
if not progress_bar:
return
var progress := 0.0
if cooking_result and cooking_result_time > 0:
progress = clampf(float(time_cooked) / cooking_result_time, 0.0, 1.0)
progress_bar.set_progress(progress)
progress_bar.set_bar_visible(not cooking_result.is_empty())
progress_bar.override_fill_color(Color.RED if cooking_result == "charcoal" else Color.GREEN)
func _on_object_picked_up(_item) -> void:
SweetLogger.debug("object picked up: {0}", [_item])
# Find the CookableItem in held object
var _food_item = _item.get_node_or_null("FoodItem") as FoodItem
if not _food_item:
SweetLogger.debug("held object is not a FoodItem")
return
var result = RecipeManager.get_cooking_result(_food_item.id)
if not result:
SweetLogger.debug("held a FoodItem that is not cookable, id: {0} result: {1}", [_food_item.id, result])
return return
cooking_result = result result_id = id
cooking_result_time = RecipeManager.get_cooking_time(_food_item.id) max_work = work
SweetLogger.debug("set cooking_result {0}", [cooking_result]) SweetLogger.info("Start cooking - result_id: {0}, max_work: {1}", [result_id, max_work])
# The setters above already refresh the display and start the flames. # The flames follow whether we're cooking, on every peer.
func _on_object_dropped(_item) -> void:
SweetLogger.debug("object drop")
time_cooked = 0
cooking_result = ""
cooking_result_time = 0
func convert_held_to_item(_item: String) -> void:
if not NetworkManager.owns_world():
return
SweetLogger.debug("converting {0}", [_item])
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
# Spawn the new item through the server so it replicates to every peer
# (including late joiners), in the old item's position.
var original_transform = old_pickable.global_transform
var new_scene_instance = NetworkManager.spawn_item(RecipeManager.get_item_scene(_item).resource_path, original_transform)
# Drop and free the old item and pick up the new one
SweetLogger.debug("freeing old_pickable {0}", [old_pickable])
snap_zone.drop_object()
NetworkManager.despawn_item(old_pickable)
snap_zone.pick_up_object(new_scene_instance)
# If cooking something, progress cooking, when done, convert item
func _process(delta: float) -> void: func _process(delta: float) -> void:
if cooking_result: super.process(delta)
#print("Hob cooking_result: ", cooking_result) if not enabled:
time_cooked += cook_speed * delta return
_refresh_display() if result_id:
if time_cooked >= cooking_result_time: add_work(cook_speed * delta)
time_cooked = 0
convert_held_to_item(cooking_result)
# Called from Station base class
func refresh_display() -> void:
super.refresh_display()
progress_bar.override_fill_color(Color.RED if result_id == "charcoal" else Color.GREEN)
# Called from Station base class
func on_food_item_picked_up(food_item: FoodItem) -> void:
SweetLogger.debug("Object picked up: {0}", [food_item])
if not food_item:
SweetLogger.debug("Held object is not a FoodItem")
return
var result = RecipeManager.get_cooking_result(food_item.id)
if not result:
SweetLogger.debug("Held a FoodItem that is not cookable, id: {0} result: {1}", [food_item.id, result])
return
_start_cooking(result, RecipeManager.get_cooking_time(food_item.id))
# Called from Station base class
func on_food_item_dropped(_food_item: FoodItem):
SweetLogger.debug("->[]")
animation_player.play("RESET")
reset()
# Called from Station base class
func on_work_complete():
SweetLogger.debug("->[]")
animation_player.play("RESET")
convert_item()
+15 -14
View File
@@ -1,26 +1,27 @@
extends StaticBody3D class_name ItemDispenser
extends Station
@export var item_scene: PackedScene @export var item_scene: PackedScene
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
func _ready() -> void: func _ready() -> void:
super.ready()
SweetLogger.debug("ItemDispenser {0} _ready", [name])
if not item_scene: if not item_scene:
push_error("Item dispenser is missing a reference to it's item to dispense") SweetLogger.warning("{0} missing item_scene reference", [name])
if not snap_zone:
push_error("Item dispenser is missing a reference to its snap zone child")
func _process(_delta: float) -> void: func _process(delta: float) -> void:
super.process(delta)
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
return return
#if snap_zone.picked_up_object: # Player picked up this station if not enabled:
#if visible: if snap_zone.picked_up_object:
#snap_zone.picked_up_object.enabled = true var item := snap_zone.picked_up_object
#else: snap_zone.drop_object()
#snap_zone.picked_up_object.enabled = false NetworkManager.despawn_item(item)
#return return
#
if not snap_zone.picked_up_object: if not snap_zone.picked_up_object:
SweetLogger.debug("missing item, spawning new item") SweetLogger.debug("Missing item, spawning new item")
var new_item = NetworkManager.spawn_item(item_scene.resource_path, snap_zone.global_transform) var new_item = NetworkManager.spawn_item(item_scene.resource_path, snap_zone.global_transform)
snap_zone.pick_up_object(new_item) snap_zone.pick_up_object(new_item)
+11 -26
View File
@@ -1,22 +1,10 @@
[gd_scene format=3 uid="uid://ck5tuftqmyiue"] [gd_scene format=3 uid="uid://ck5tuftqmyiue"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_jgjsq"] [ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_jm0ik"] [ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_jm0ik"]
[ext_resource type="PackedScene" uid="uid://bp3v1jl8pctro" path="res://Containers/plate.tscn" id="2_tfo2i"] [ext_resource type="PackedScene" uid="uid://bp3v1jl8pctro" path="res://Containers/plate.tscn" id="2_tfo2i"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="3_lr065"]
[ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_tfo2i"] [ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="4_tfo2i"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_jgjsq"]
properties/0/path = NodePath("PlateDispenser:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("PlateDispenser:rotation")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("PlateDispenser:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"] [sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"]
radius = 0.3 radius = 0.3
@@ -24,29 +12,26 @@ radius = 0.3
height = 1.0 height = 1.0
radius = 0.3 radius = 0.3
[node name="PlateDispenser" type="Node3D" unique_id=53391541] [node name="PlateDispenser" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_jgjsq")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../PlateDispenser") station = NodePath("../PlateDispenser")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=901684173] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
replication_config = SubResource("SceneReplicationConfig_jgjsq")
[node name="PlateDispenser" type="StaticBody3D" parent="." unique_id=710538846 groups=["station"]]
script = ExtResource("1_jm0ik")
item_scene = ExtResource("2_tfo2i")
[node name="XRToolsSnapZone" type="Area3D" parent="PlateDispenser" unique_id=238176038 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.1603245, -0.002165556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.1603245, -0.002165556)
collision_layer = 65536 collision_layer = 65536
collision_mask = 65536 collision_mask = 65536
script = ExtResource("3_lr065")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlateDispenser/XRToolsSnapZone" unique_id=1942470044] [node name="CollisionShape3D" parent="SnapZone" index="0"]
shape = SubResource("SphereShape3D_xmbo2") shape = SubResource("SphereShape3D_xmbo2")
[node name="PlateDispenser" type="StaticBody3D" parent="." index="6" unique_id=710538846 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("1_jm0ik")
item_scene = ExtResource("2_tfo2i")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlateDispenser" unique_id=831688237] [node name="CollisionShape3D" type="CollisionShape3D" parent="PlateDispenser" unique_id=831688237]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("CylinderShape3D_24d3s") shape = SubResource("CylinderShape3D_24d3s")
+11 -26
View File
@@ -1,22 +1,10 @@
[gd_scene format=3 uid="uid://sc6i0i1f0o48"] [gd_scene format=3 uid="uid://sc6i0i1f0o48"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_8orw3"] [ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="2_30d2d"] [ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="2_30d2d"]
[ext_resource type="PackedScene" uid="uid://drwuhqb3pjtiy" path="res://items/potato.tscn" id="3_mjqsn"] [ext_resource type="PackedScene" uid="uid://drwuhqb3pjtiy" path="res://items/potato.tscn" id="3_mjqsn"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="4_fx1kw"]
[ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="5_ur331"] [ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="5_ur331"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_8orw3"]
properties/0/path = NodePath("PotatoDispenser:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("PotatoDispenser:rotation")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("PotatoDispenser:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"] [sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"]
radius = 0.3 radius = 0.3
@@ -27,29 +15,26 @@ radius = 0.3
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_d4wpw"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_d4wpw"]
albedo_color = Color(0.48, 0.34336, 0.1872, 1) albedo_color = Color(0.48, 0.34336, 0.1872, 1)
[node name="PotatoDispenser" type="Node3D" unique_id=1410160280] [node name="PotatoDispenser" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("1_8orw3")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../PotatoDispenser") station = NodePath("../PotatoDispenser")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=41449367] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
replication_config = SubResource("SceneReplicationConfig_8orw3")
[node name="PotatoDispenser" type="StaticBody3D" parent="." unique_id=1720683779 groups=["station"]]
script = ExtResource("2_30d2d")
item_scene = ExtResource("3_mjqsn")
[node name="XRToolsSnapZone" type="Area3D" parent="PotatoDispenser" unique_id=805334513 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0162505, -0.002165556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0162505, -0.002165556)
collision_layer = 65536 collision_layer = 65536
collision_mask = 65536 collision_mask = 65536
script = ExtResource("4_fx1kw")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D" type="CollisionShape3D" parent="PotatoDispenser/XRToolsSnapZone" unique_id=1104626493] [node name="CollisionShape3D" parent="SnapZone" index="0"]
shape = SubResource("SphereShape3D_xmbo2") shape = SubResource("SphereShape3D_xmbo2")
[node name="PotatoDispenser" type="StaticBody3D" parent="." index="6" unique_id=1720683779 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("2_30d2d")
item_scene = ExtResource("3_mjqsn")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="CollisionShape3D" type="CollisionShape3D" parent="PotatoDispenser" unique_id=1470079357] [node name="CollisionShape3D" type="CollisionShape3D" parent="PotatoDispenser" unique_id=1470079357]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("CylinderShape3D_24d3s") shape = SubResource("CylinderShape3D_24d3s")
+11 -26
View File
@@ -1,22 +1,10 @@
[gd_scene format=3 uid="uid://cwnwo4i28upap"] [gd_scene format=3 uid="uid://cwnwo4i28upap"]
[ext_resource type="PackedScene" uid="uid://cbs8jiqe8rcmn" path="res://abstract/station.tscn" id="1_station"]
[ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_gkb3v"] [ext_resource type="Script" uid="uid://0y6wnjcsum6" path="res://stations/item_dispenser.gd" id="1_gkb3v"]
[ext_resource type="PackedScene" uid="uid://dpot5qie20vf6" path="res://items/burger.tscn" id="2_mep2a"] [ext_resource type="PackedScene" uid="uid://dpot5qie20vf6" path="res://items/burger.tscn" id="2_mep2a"]
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="3_3xuvi"]
[ext_resource type="Texture2D" uid="uid://cexxfyw03hr81" path="res://textures/1.png" id="4_1f5le"] [ext_resource type="Texture2D" uid="uid://cexxfyw03hr81" path="res://textures/1.png" id="4_1f5le"]
[ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="5_mep2a"] [ext_resource type="PackedScene" uid="uid://mpapt5mkbuao" path="res://prefabs/slide_off_dome.tscn" id="5_mep2a"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="6_8ou8n"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_8ou8n"]
properties/0/path = NodePath("RawBurgerDispenser:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("RawBurgerDispenser:rotation")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("RawBurgerDispenser:visible")
properties/2/spawn = false
properties/2/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"] [sub_resource type="SphereShape3D" id="SphereShape3D_xmbo2"]
radius = 0.3 radius = 0.3
@@ -28,29 +16,26 @@ radius = 0.3
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_di04w"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_di04w"]
albedo_texture = ExtResource("4_1f5le") albedo_texture = ExtResource("4_1f5le")
[node name="RawBurgerDispenser" type="Node3D" unique_id=383615587] [node name="RawBurgerDispenser" unique_id=707500902 instance=ExtResource("1_station")]
[node name="StationMovement" parent="." unique_id=946873975 node_paths=PackedStringArray("station") instance=ExtResource("6_8ou8n")] [node name="StationMovement" parent="." index="0" unique_id=946873975 node_paths=PackedStringArray("station")]
station = NodePath("../RawBurgerDispenser") station = NodePath("../RawBurgerDispenser")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1886082284] [node name="SnapZone" parent="." index="5" unique_id=1315859105]
replication_config = SubResource("SceneReplicationConfig_8ou8n")
[node name="RawBurgerDispenser" type="StaticBody3D" parent="." unique_id=235630131 groups=["station"]]
script = ExtResource("1_gkb3v")
item_scene = ExtResource("2_mep2a")
[node name="XRToolsSnapZone" type="Area3D" parent="RawBurgerDispenser" unique_id=1523586273 groups=["station_zone"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0645258, -0.002165556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00070536137, 1.0645258, -0.002165556)
collision_layer = 65536 collision_layer = 65536
collision_mask = 65536 collision_mask = 65536
script = ExtResource("3_3xuvi")
snap_mode = 1 snap_mode = 1
metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
[node name="CollisionShape3D" type="CollisionShape3D" parent="RawBurgerDispenser/XRToolsSnapZone" unique_id=2105824734] [node name="CollisionShape3D" parent="SnapZone" index="0"]
shape = SubResource("SphereShape3D_xmbo2") shape = SubResource("SphereShape3D_xmbo2")
[node name="RawBurgerDispenser" type="StaticBody3D" parent="." index="6" unique_id=235630131 node_paths=PackedStringArray("snap_zone", "synchronizer") groups=["station"]]
script = ExtResource("1_gkb3v")
item_scene = ExtResource("2_mep2a")
snap_zone = NodePath("../SnapZone")
synchronizer = NodePath("../MultiplayerSynchronizer")
[node name="SlideOffDome" parent="RawBurgerDispenser" unique_id=1427609426 instance=ExtResource("5_mep2a")] [node name="SlideOffDome" parent="RawBurgerDispenser" unique_id=1427609426 instance=ExtResource("5_mep2a")]
[node name="CollisionShape3D" type="CollisionShape3D" parent="RawBurgerDispenser" unique_id=378049928] [node name="CollisionShape3D" type="CollisionShape3D" parent="RawBurgerDispenser" unique_id=378049928]
+54 -77
View File
@@ -1,94 +1,71 @@
extends StaticBody3D class_name Sink
extends WorkStation
const plate_wash_time: float = 3.0 const plate_wash_time: float = 3.0
@export_range(0.0, 10.0, 0.1) var wash_speed: float = 1.0 @export_range(0.0, 10.0, 0.1) var wash_speed: float = 1.0
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone var plate: PlateController = null
@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
func _set_time_washed(value: float) -> void: func _ready() -> void:
if is_equal_approx(time_washed, value): super.ready()
SweetLogger.debug("Sink {0} _ready", [name])
func _start_washing(work: float) -> void:
if not enabled:
return return
time_washed = value result_id = "clean"
_refresh_progress_bar() max_work = work
SweetLogger.info("Start washing - max_work: {0}", [max_work])
func _set_effects_playing(is_playing: bool) -> void:
func _set_is_washing(value: bool) -> void: SweetLogger.debug("Set Sink effects: {0}", [is_playing])
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:
var player := get_node_or_null("AnimationPlayer") as AnimationPlayer var player := get_node_or_null("AnimationPlayer") as AnimationPlayer
if player: if player:
player.play("working" if playing else "RESET") player.play("working" if is_playing else "RESET")
for effect in ["water", "bubbles", "GPUParticles3D"]: for effect in ["water", "bubbles", "GPUParticles3D"]:
var node := get_node_or_null(effect) as Node3D var node := get_node_or_null(effect) as Node3D
if node: if node:
node.visible = playing node.visible = is_playing
func _ready() -> void:
if not progress_bar or progress_bar is not ProgressBar3D:
push_error("Sink missing reference to progressbar, or wrong type:", progress_bar)
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!")
func _process(delta: float) -> void: func _process(delta: float) -> void:
if is_washing: super.process(delta)
time_washed += wash_speed * delta if not enabled:
_refresh_progress_bar() return
SweetLogger.debug("washing plate: {0}", [time_washed]) 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()
+20 -44
View File
@@ -1,26 +1,7 @@
[gd_scene format=4 uid="uid://dvrk268s7gkxh"] [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="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"] [sub_resource type="BoxShape3D" id="BoxShape3D_l02yb"]
size = Vector3(0.6, 1.0024658, 0.6) size = Vector3(0.6, 1.0024658, 0.6)
@@ -191,37 +172,35 @@ material = SubResource("StandardMaterial3D_ai6d4")
radius = 0.02 radius = 0.02
height = 0.04 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") station = NodePath("../Sink")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1601242574] [node name="ProgressBar3D" parent="." index="4" unique_id=654673176]
root_path = NodePath("../Sink") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3229032, -0.035980098)
replication_config = SubResource("SceneReplicationConfig_np_sink")
[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") 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] [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) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.507675, 0)
shape = SubResource("BoxShape3D_l02yb") 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] [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) 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 operation = 2
size = Vector3(1, 1.2053223, 0.352417) 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] [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) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.50644207, 0)
visible = false visible = false
+19 -19
View File
@@ -21,7 +21,7 @@ const GHOST_COLOR_INVALID: Color = Color(1, 0, 0, 0.35)
func set_move_handle_enabled(enabled: bool) -> void: func set_move_handle_enabled(enabled: bool) -> void:
SweetLogger.debug("set_move_handle_enabled: {0}", [enabled]) SweetLogger.debug("Set move handle enabled: {0}", [enabled])
move_handle.visible = enabled move_handle.visible = enabled
move_handle.enabled = enabled move_handle.enabled = enabled
if enabled: if enabled:
@@ -32,18 +32,18 @@ func _on_game_state_changed(new_state: GameManager.GameState) -> void:
set_move_handle_enabled(new_state == GameManager.GameState.BUILDING) set_move_handle_enabled(new_state == GameManager.GameState.BUILDING)
func _on_station_bought(_instance: Node3D): func _on_station_bought(_instance: Node3D):
SweetLogger.info("_on_station_bought") SweetLogger.debug("->[]")
if GameManager.game_state == GameManager.GameState.BUILDING: if GameManager.game_state == GameManager.GameState.BUILDING:
set_move_handle_enabled(true) set_move_handle_enabled(true)
func _ready() -> void: func _ready() -> void:
SweetLogger.debug("enter") SweetLogger.debug("->[]")
if not station: if not station:
push_error("StationMovement is missing referece to station") SweetLogger.warning("{0} missing station reference", [name])
if not move_handle: if not move_handle:
push_error("StationMovement is missing reference to move_handle") SweetLogger.warning("{0} missing move_handle reference", [name])
if not move_ghost: if not move_ghost:
push_error("StationMovement is missing reference to move_ghost") SweetLogger.warning("{0} missing move_ghost reference", [name])
move_handle_rigid = move_handle as RigidBody3D move_handle_rigid = move_handle as RigidBody3D
original_collision_layer = station.collision_layer original_collision_layer = station.collision_layer
@@ -105,9 +105,9 @@ func _apply_visibility_state(ghost_visible: bool, station_visible: bool) -> void
func _handle_pickup(_by: Node) -> void: func _handle_pickup(_by: Node) -> void:
SweetLogger.info("handle pickup") SweetLogger.debug("->[]")
if move_handle.get_picked_up_by() and move_handle.get_picked_up_by() is XRToolsSnapZone: if move_handle.get_picked_up_by() and move_handle.get_picked_up_by() is XRToolsSnapZone:
SweetLogger.info("handle pickup by snap zone, dropping and resetting position") SweetLogger.info("Handle pickup by snap zone, dropping and resetting position")
move_handle.drop() move_handle.drop()
move_handle.global_position = station.global_position + Vector3(0, original_handle_y_pos, 0) move_handle.global_position = station.global_position + Vector3(0, original_handle_y_pos, 0)
move_handle.rotation = station.rotation move_handle.rotation = station.rotation
@@ -121,7 +121,7 @@ func _handle_pickup(_by: Node) -> void:
func _handle_drop(_by: Node) -> void: func _handle_drop(_by: Node) -> void:
SweetLogger.info("handle drop") SweetLogger.info("Handle drop")
is_moving = false is_moving = false
_apply_visibility_state(false, true) _apply_visibility_state(false, true)
station.collision_layer = original_collision_layer station.collision_layer = original_collision_layer
@@ -134,11 +134,11 @@ func _handle_drop(_by: Node) -> void:
if is_valid: if is_valid:
station.global_transform = move_ghost.global_transform station.global_transform = move_ghost.global_transform
move_handle.global_transform = move_ghost.global_transform.translated(Vector3(0, original_handle_y_pos, 0)) move_handle.global_transform = move_ghost.global_transform.translated(Vector3(0, original_handle_y_pos, 0))
SweetLogger.debug("handle drop (local apply), station authority: {0} move_handle authority: {1}", [station.get_multiplayer_authority(), move_handle.get_multiplayer_authority()]) SweetLogger.debug("Handle drop (local apply), station authority: {0} move_handle authority: {1}", [station.get_multiplayer_authority(), move_handle.get_multiplayer_authority()])
else: else:
station.global_transform = original_station_transform station.global_transform = original_station_transform
move_handle.global_transform = original_station_transform.translated(Vector3(0, original_handle_y_pos, 0)) move_handle.global_transform = original_station_transform.translated(Vector3(0, original_handle_y_pos, 0))
SweetLogger.debug("handle drop (local reject), restoring original position", []) SweetLogger.debug("Handle drop (local reject), restoring original position")
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
@@ -186,7 +186,7 @@ func _is_move_position_valid() -> bool:
@rpc("any_peer", "call_local", "reliable") @rpc("any_peer", "call_local", "reliable")
func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool): func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool):
SweetLogger.debug("enter") SweetLogger.debug("->[]")
if not multiplayer.is_server(): if not multiplayer.is_server():
return return
if not (client_thinks_valid): if not (client_thinks_valid):
@@ -198,7 +198,7 @@ func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool):
if not _was_last_pos_valid: # Edge case if not _was_last_pos_valid: # Edge case
server_update_visibility.rpc(false, true) server_update_visibility.rpc(false, true)
SweetLogger.warning("Can not not reset visibility to normal when the last pos was invalid") SweetLogger.warning("Can not not reset visibility to normal when the last pos was invalid")
SweetLogger.debug("transform rejected (invalid)") SweetLogger.debug("Transform rejected (invalid)")
_was_last_pos_valid = false _was_last_pos_valid = false
return return
@@ -208,38 +208,38 @@ func server_handle_drop(new_transform: Transform3D, client_thinks_valid: bool):
server_update_visibility.rpc(false, true) server_update_visibility.rpc(false, true)
_was_last_pos_valid = true _was_last_pos_valid = true
SweetLogger.debug("transform applied") SweetLogger.debug("Transform applied")
@rpc("any_peer", "call_local", "reliable") # Server updates clients @rpc("any_peer", "call_local", "reliable") # Server updates clients
func server_artificial_pickup(): func server_artificial_pickup():
SweetLogger.debug("enter") SweetLogger.debug("->[]")
_handle_pickup(self) # Arg is not used, but required of the signal. _handle_pickup(self) # Arg is not used, but required of the signal.
@rpc("any_peer", "call_local", "reliable") # Server updates clients @rpc("any_peer", "call_local", "reliable") # Server updates clients
func server_update_station_transform(new_transform: Transform3D) -> void: func server_update_station_transform(new_transform: Transform3D) -> void:
SweetLogger.debug("entered") SweetLogger.debug("->[]")
station.global_transform = new_transform station.global_transform = new_transform
original_station_transform = new_transform original_station_transform = new_transform
@rpc("any_peer", "call_local", "reliable") # Server updates clients @rpc("any_peer", "call_local", "reliable") # Server updates clients
func server_update_handle_transform(new_transform: Transform3D) -> void: func server_update_handle_transform(new_transform: Transform3D) -> void:
SweetLogger.debug("entered") SweetLogger.debug("->[]")
move_handle.global_transform = new_transform move_handle.global_transform = new_transform
@rpc("any_peer", "call_local", "reliable") @rpc("any_peer", "call_local", "reliable")
func server_update_visibility(ghost_visible: bool, station_visible: bool) -> void: func server_update_visibility(ghost_visible: bool, station_visible: bool) -> void:
SweetLogger.debug("entered") SweetLogger.debug("->[]")
move_ghost.visible = ghost_visible move_ghost.visible = ghost_visible
station.visible = station_visible station.visible = station_visible
@rpc("any_peer", "call_local", "unreliable") @rpc("any_peer", "call_local", "unreliable")
func server_update_move_ghost_transform(new_transform: Transform3D, new_color: Color = GHOST_COLOR_VALID) -> void: func server_update_move_ghost_transform(new_transform: Transform3D, new_color: Color = GHOST_COLOR_VALID) -> void:
SweetLogger.debug("entered") SweetLogger.debug("->[]")
move_ghost.global_transform = new_transform move_ghost.global_transform = new_transform
_set_ghost_color(new_color) _set_ghost_color(new_color)
+27 -27
View File
@@ -47,7 +47,7 @@ var _players_count: int = 0
func place_order() -> void: func place_order() -> void:
SweetLogger.debug("place_order()") SweetLogger.debug("->[]")
var new_orders: Array[String] = _unsatisfied_orders.duplicate() var new_orders: Array[String] = _unsatisfied_orders.duplicate()
# for _i in range(0, randi_range(1, 2)): # for _i in range(0, randi_range(1, 2)):
# new_orders.append(GameManager.get_random_meal()) # new_orders.append(GameManager.get_random_meal())
@@ -64,7 +64,7 @@ func server_place_order() -> void:
func absorb_items(): func absorb_items():
SweetLogger.debug("absorb_items()") SweetLogger.debug("->[]")
for snap_zone_node in snap_zones: for snap_zone_node in snap_zones:
var held_object = snap_zone_node.picked_up_object var held_object = snap_zone_node.picked_up_object
if not held_object: if not held_object:
@@ -74,7 +74,7 @@ func absorb_items():
func satisfyAllOrders() -> void: func satisfyAllOrders() -> void:
SweetLogger.debug("satisfyAllOrders()") SweetLogger.debug("->[]")
_unsatisfied_orders.clear() _unsatisfied_orders.clear()
_original_orders.clear() _original_orders.clear()
clearAllFood() clearAllFood()
@@ -82,7 +82,7 @@ func satisfyAllOrders() -> void:
func clearAllFood() -> void: func clearAllFood() -> void:
SweetLogger.debug("clearAllFood()") SweetLogger.debug("->[]")
for zone in snap_zones: for zone in snap_zones:
var held_object = zone.picked_up_object var held_object = zone.picked_up_object
if not held_object: if not held_object:
@@ -103,7 +103,7 @@ func clearAllFood() -> void:
# Group called from Queue when trying to assign customers to tables # Group called from Queue when trying to assign customers to tables
func try_consume_customer() -> bool: func try_consume_customer() -> bool:
if _state == TableState.EMPTY: if _state == TableState.EMPTY:
SweetLogger.debug("try_consume_customer, consumed a customer") SweetLogger.debug("Try consume customer, consumed a customer")
_state_end(TableState.EMPTY) _state_end(TableState.EMPTY)
return true return true
return false return false
@@ -111,18 +111,18 @@ func try_consume_customer() -> bool:
func _ready() -> void: func _ready() -> void:
if not label_3d: if not label_3d:
push_error("Table is missing reference to Label3D") SweetLogger.warning("{0} missing label_3d reference", [name])
if not label_3d_time: if not label_3d_time:
push_error("Table is missing reference to Label3DTime") SweetLogger.warning("{0} missing label_3d_time reference", [name])
if not progress_bar or progress_bar is not ProgressBar3D: if not progress_bar or progress_bar is not ProgressBar3D:
push_error("Table missing reference to progressbar, or wrong type:", progress_bar) SweetLogger.warning("{0} missing progress_bar reference", [name])
progress_bar.y_billboard = true progress_bar.y_billboard = true
progress_bar.exponential = true progress_bar.exponential = true
# Render whatever state already arrived from the server before we were in # Render whatever state already arrived from the server before we were in
# the tree (see the guard in _refresh_display). # the tree (see the guard in _refresh_display).
_refresh_display.call_deferred() _refresh_display.call_deferred()
if not audio_player: if not audio_player:
push_error("Table is missing reference to AudioStreamPlayer3D") SweetLogger.warning("{0} missing audio_player reference", [name])
# Get snap_zones for plates, store in array snap_zones # Get snap_zones for plates, store in array snap_zones
for child in get_children(): for child in get_children():
@@ -131,7 +131,7 @@ func _ready() -> void:
snap_zones.append(snap_zone_node) snap_zones.append(snap_zone_node)
if snap_zones.is_empty(): if snap_zones.is_empty():
push_error("Table is missing XRToolsSnapZone children") SweetLogger.warning("{0} missing XRToolsSnapZone children", [name])
return return
for snap_zone_node in snap_zones: for snap_zone_node in snap_zones:
@@ -148,14 +148,14 @@ func _ready() -> void:
func _on_object_picked_up(_item) -> void: func _on_object_picked_up(_item) -> void:
SweetLogger.debug("object picked up: {0}", [_item]) SweetLogger.debug("Object picked up: {0}", [_item])
if _state == TableState.EATING: if _state == TableState.EATING:
return return
_absorb_item_if_correct(_item) _absorb_item_if_correct(_item)
func _on_object_dropped(_item) -> void: func _on_object_dropped(_item) -> void:
SweetLogger.debug("object dropped, item: {0}", [_item]) SweetLogger.debug("Object dropped, item: {0}", [_item])
# If then player picks up a food_item (side) the table has already registerd, unregister # If then player picks up a food_item (side) the table has already registerd, unregister
var food_item: FoodItem = Helper.find_food_item(_item) var food_item: FoodItem = Helper.find_food_item(_item)
if food_item and food_item.type == FoodItem.Type.SIDE: if food_item and food_item.type == FoodItem.Type.SIDE:
@@ -172,12 +172,12 @@ func _on_object_dropped(_item) -> void:
# There is no on_stay signal, we have to track player with bool # There is no on_stay signal, we have to track player with bool
func _on_player_enter(_body): func _on_player_enter(_body):
_players_count += 1 _players_count += 1
SweetLogger.debug("_on_player_enter() players_count: {0}", [_players_count]) SweetLogger.debug("Player enter, players_count: {0}", [_players_count])
func _on_player_exit(_body): func _on_player_exit(_body):
_players_count -= 1 _players_count -= 1
SweetLogger.debug("_on_player_exit() players_count: {0}", [_players_count]) SweetLogger.debug("Player exit, players_count: {0}", [_players_count])
func _place_order_if_player(): func _place_order_if_player():
@@ -194,20 +194,20 @@ func _place_order_if_player():
func _get_plate_controller_from_item(_item: Node) -> PlateController: func _get_plate_controller_from_item(_item: Node) -> PlateController:
if not _item: if not _item:
SweetLogger.debug("_item is null") SweetLogger.debug("Item is null")
return null return null
for child in _item.get_children(): for child in _item.get_children():
if child is PlateController: if child is PlateController:
SweetLogger.debug("found child") SweetLogger.debug("Found child")
return child return child
SweetLogger.debug("no match") SweetLogger.debug("No match")
return null return null
func _absorb_item_if_correct(_item: Node) -> void: func _absorb_item_if_correct(_item: Node) -> void:
SweetLogger.debug("_absorb_item_if_correct, item: {0}", [_item]) SweetLogger.debug("Absorb item if correct, item: {0}", [_item])
if not _item: if not _item:
return return
if not (_state == TableState.WAITING_PRIMARY or _state == TableState.WAITING_FRIEND): if not (_state == TableState.WAITING_PRIMARY or _state == TableState.WAITING_FRIEND):
@@ -215,14 +215,14 @@ func _absorb_item_if_correct(_item: Node) -> void:
# Plate: Get plate controller in child of _item (hopefully a plate XRpickable) # Plate: Get plate controller in child of _item (hopefully a plate XRpickable)
var plate_controller = _get_plate_controller_from_item(_item) var plate_controller = _get_plate_controller_from_item(_item)
SweetLogger.debug("_absorb_item_if_correct plate_controller ref: {0}", [plate_controller]) SweetLogger.debug("Plate_controller ref: {0}", [plate_controller])
_item.print_tree_pretty() _item.print_tree_pretty()
if plate_controller: if plate_controller:
# Absorm items from the plate we want # Absorm items from the plate we want
for food_item: FoodItem in plate_controller.container.contained_items: # TOOD: handle registering the meal again when a side is added to the plate for food_item: FoodItem in plate_controller.container.contained_items: # TOOD: handle registering the meal again when a side is added to the plate
if food_item.id in _unsatisfied_orders and not food_item.is_absorbed: if food_item.id in _unsatisfied_orders and not food_item.is_absorbed:
SweetLogger.debug("_absorb_item_if_correct held a plate with FoodItem that is in unsatisfied orders, removing it") SweetLogger.debug("Held a plate with FoodItem that is in unsatisfied orders, removing it")
(plate_controller.get_parent() as XRToolsPickable).get_picked_up_by().enabled = false # Lock meal that is deliverd (plate_controller.get_parent() as XRToolsPickable).get_picked_up_by().enabled = false # Lock meal that is deliverd
_unsatisfied_orders.erase(food_item.id) _unsatisfied_orders.erase(food_item.id)
food_item.is_absorbed = true food_item.is_absorbed = true
@@ -232,17 +232,17 @@ func _absorb_item_if_correct(_item: Node) -> void:
# Side pickable item, no container # Side pickable item, no container
var food_item: FoodItem = Helper.find_food_item(_item) var food_item: FoodItem = Helper.find_food_item(_item)
if food_item and food_item.type == FoodItem.Type.SIDE: if food_item and food_item.type == FoodItem.Type.SIDE:
SweetLogger.debug("_absorb_item_if_correct held a side that is in unsatisfied orders, removing it") SweetLogger.debug("Held a side that is in unsatisfied orders, removing it")
# Do not lock snap zone here. Problem if table want many meals, but to many sides have filled up slots, so can't place plates. # Do not lock snap zone here. Problem if table want many meals, but to many sides have filled up slots, so can't place plates.
_unsatisfied_orders.erase(food_item.id) _unsatisfied_orders.erase(food_item.id)
_update_state_from_orders() _update_state_from_orders()
return return
SweetLogger.debug("absorb_item_if_correct() held object is not a Plate or Side") SweetLogger.debug("Held object is not a Plate or Side")
func _update_state_from_orders(): func _update_state_from_orders():
SweetLogger.debug("_update_state_from_orders: unsatisfied_orders: {0}", [_unsatisfied_orders]) SweetLogger.debug("Unsatisfied_orders: {0}", [_unsatisfied_orders])
if _unsatisfied_orders.size() > 0 and _state != TableState.EATING: if _unsatisfied_orders.size() > 0 and _state != TableState.EATING:
_set_state(TableState.WAITING_FRIEND) _set_state(TableState.WAITING_FRIEND)
@@ -265,7 +265,7 @@ func _collect_money_from_food():
elif food_item: elif food_item:
GameManager.set_money(GameManager.money + food_item.sell_value) GameManager.set_money(GameManager.money + food_item.sell_value)
SweetLogger.debug("_collect_money_from_food(), money: {0}", [GameManager.money]) SweetLogger.debug("Money: {0}", [GameManager.money])
func _set_snap_zones_enabled(value: bool) -> void: func _set_snap_zones_enabled(value: bool) -> void:
@@ -349,7 +349,7 @@ func _refresh_display() -> void:
# null. Bail out until _ready() has resolved them; _ready() calls back in # null. Bail out until _ready() has resolved them; _ready() calls back in
# once it has, so nothing that arrived early is lost. # once it has, so nothing that arrived early is lost.
if not progress_bar or not label_3d or not label_3d_time: if not progress_bar or not label_3d or not label_3d_time:
push_error("Table missing progress bar or label") SweetLogger.warning("{0} missing progress_bar or label reference", [name])
return return
match _state: match _state:
TableState.IDLE: TableState.IDLE:
@@ -385,10 +385,10 @@ func _refresh_display() -> void:
func _process(delta: float) -> void: func _process(delta: float) -> void:
_refresh_display() _refresh_display()
_place_order_if_player() _place_order_if_player()
SweetLogger.error("State {0} time: {1} duration: {2}", [TableState.keys()[_state], _state_time, _state_duration]) #SweetLogger.error("State {0} time: {1} duration: {2}", [TableState.keys()[_state], _state_time, _state_duration])
if not NetworkManager.owns_world(): if not NetworkManager.owns_world():
SweetLogger.error("Is not server, return") SweetLogger.debug("Not server, skipping state update")
return return
if GameManager.game_state == GameManager.GameState.GAME_OVER: if GameManager.game_state == GameManager.GameState.GAME_OVER:
+1 -1
View File
@@ -1,6 +1,6 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://cmia50cfqxxo4"] [gd_resource type="StandardMaterial3D" format=3 uid="uid://cmia50cfqxxo4"]
[ext_resource type="Texture2D" uid="uid://di387qcr5vmsp" path="res://Textures/devTex.svg" id="1_3jxsn"] [ext_resource type="Texture2D" uid="uid://di387qcr5vmsp" path="res://textures/devTex.svg" id="1_3jxsn"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0gbf8"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0gbf8"]
transparency = 1 transparency = 1
+1 -1
View File
@@ -1,6 +1,6 @@
[gd_resource type="Sky" format=3 uid="uid://c1abtpwhdm2d5"] [gd_resource type="Sky" format=3 uid="uid://c1abtpwhdm2d5"]
[ext_resource type="Texture2D" uid="uid://bsuhedl8ltapa" path="res://Textures/sky/NightSkyHDRI009_16K_HDR.exr" id="acg_mft3ic9d"] [ext_resource type="Texture2D" uid="uid://bsuhedl8ltapa" path="res://textures/sky/NightSkyHDRI009_16K_HDR.exr" id="acg_mft3ic9d"]
[sub_resource type="PanoramaSkyMaterial" id="acg_025sfqr4"] [sub_resource type="PanoramaSkyMaterial" id="acg_025sfqr4"]
panorama = ExtResource("acg_mft3ic9d") panorama = ExtResource("acg_mft3ic9d")
+1 -1
View File
@@ -10,7 +10,7 @@ class_name ProgressBar3D
func _ready() -> void: func _ready() -> void:
if not progress_bar: if not progress_bar:
push_error("Progressbar3D missing reference to ProgressBar") SweetLogger.warning("{0} missing progress_bar reference", [name])
if y_billboard: if y_billboard:
$Sprite3D.billboard = BaseMaterial3D.BillboardMode.BILLBOARD_FIXED_Y $Sprite3D.billboard = BaseMaterial3D.BillboardMode.BILLBOARD_FIXED_Y
+9 -9
View File
@@ -3,21 +3,21 @@
[ext_resource type="Script" uid="uid://xrfp03b32j1t" path="res://UI/shop_ui.gd" id="1_2k6ie"] [ext_resource type="Script" uid="uid://xrfp03b32j1t" path="res://UI/shop_ui.gd" id="1_2k6ie"]
[ext_resource type="PackedScene" uid="uid://u7rpukx5ebqo" path="res://UI/shop_station_panel.tscn" id="1_pogqh"] [ext_resource type="PackedScene" uid="uid://u7rpukx5ebqo" path="res://UI/shop_station_panel.tscn" id="1_pogqh"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="2_35otv"] [ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="2_35otv"]
[ext_resource type="Texture2D" uid="uid://c0nd4nh4vja73" path="res://textures/shop/counter.png" id="3_74fni"] [ext_resource type="Texture2D" uid="uid://dhja7i8tgb3ao" path="res://textures/shop/counter.png" id="3_74fni"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="4_l3qkl"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="4_l3qkl"]
[ext_resource type="Texture2D" uid="uid://ejby14dl1svr" path="res://textures/shop/hob.png" id="5_2k6ie"] [ext_resource type="Texture2D" uid="uid://br4ytiocwouqh" path="res://textures/shop/hob.png" id="5_2k6ie"]
[ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="6_rktus"] [ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="6_rktus"]
[ext_resource type="Texture2D" uid="uid://ecdu0qqhib4" path="res://textures/shop/sink.png" id="7_4titf"] [ext_resource type="Texture2D" uid="uid://gi6bksvs8ybx" path="res://textures/shop/sink.png" id="7_4titf"]
[ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="9_84wnh"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="9_84wnh"]
[ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://stations/raw_burger_dispenser.tscn" id="9_vl3v4"] [ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://stations/raw_burger_dispenser.tscn" id="9_vl3v4"]
[ext_resource type="Texture2D" uid="uid://dpaqhbpmk7exf" path="res://textures/shop/raw_burger.png" id="10_rkek4"] [ext_resource type="Texture2D" uid="uid://b57nybt7her3k" path="res://textures/shop/raw_burger.png" id="10_rkek4"]
[ext_resource type="Texture2D" uid="uid://cv3grgonwlakt" path="res://textures/shop/table.png" id="10_sb5p3"] [ext_resource type="Texture2D" uid="uid://dp4ccvp2xgpqy" path="res://textures/shop/table.png" id="10_sb5p3"]
[ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="11_4m5wg"] [ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="11_4m5wg"]
[ext_resource type="Texture2D" uid="uid://bmomecu0058xg" path="res://textures/shop/burger_buns.png" id="12_84wnh"] [ext_resource type="Texture2D" uid="uid://4p7i3p3ox3qi" path="res://textures/shop/burger_buns.png" id="12_84wnh"]
[ext_resource type="PackedScene" uid="uid://ck5tuftqmyiue" path="res://stations/plate_dispenser.tscn" id="13_4m5wg"] [ext_resource type="PackedScene" uid="uid://ck5tuftqmyiue" path="res://stations/plate_dispenser.tscn" id="13_4m5wg"]
[ext_resource type="Texture2D" uid="uid://cjrwhtsjjhtu7" path="res://textures/shop/plates.png" id="14_84wnh"] [ext_resource type="Texture2D" uid="uid://ouqlicmcjay3" path="res://textures/shop/plates.png" id="14_84wnh"]
[ext_resource type="PackedScene" uid="uid://sc6i0i1f0o48" path="res://stations/potato_dispenser.tscn" id="17_pdan6"] [ext_resource type="PackedScene" uid="uid://sc6i0i1f0o48" path="res://stations/potato_dispenser.tscn" id="17_pdan6"]
[ext_resource type="Texture2D" uid="uid://blekcmdjkxs0q" path="res://textures/shop/potatoes.png" id="18_6lkkh"] [ext_resource type="Texture2D" uid="uid://br4y6kq8w3usi" path="res://textures/shop/potatoes.png" id="18_6lkkh"]
[sub_resource type="LabelSettings" id="LabelSettings_vlqg6"] [sub_resource type="LabelSettings" id="LabelSettings_vlqg6"]
font_size = 35 font_size = 35
+2 -2
View File
@@ -21,12 +21,12 @@ func _process(_delta: float) -> void:
func _on_button_pressed() -> void: func _on_button_pressed() -> void:
SweetLogger.debug("buy {0}", [station_name]) SweetLogger.debug("Buy {0}", [station_name])
_buy_station() _buy_station()
func _buy_station() -> void: func _buy_station() -> void:
SweetLogger.debug("cost={0} current money={1}", [cost, GameManager.money]) SweetLogger.debug("Cost={0} current money={1}", [cost, GameManager.money])
GameManager.set_money(GameManager.money - cost) GameManager.set_money(GameManager.money - cost)
var transform = Helper.get_snapped_transform(XRHelpers.get_xr_origin(self).get_node_or_null("PlayerBody")) var transform = Helper.get_snapped_transform(XRHelpers.get_xr_origin(self).get_node_or_null("PlayerBody"))
var forward: Vector3 = -transform.basis.z.normalized() var forward: Vector3 = -transform.basis.z.normalized()
+8 -8
View File
@@ -22,7 +22,7 @@ func _ready() -> void:
Signals.station_bought.connect(_on_station_bought) Signals.station_bought.connect(_on_station_bought)
viewport = get_parent().get_parent() as XRToolsViewport2DIn3D viewport = get_parent().get_parent() as XRToolsViewport2DIn3D
if not viewport: if not viewport:
push_error("Shop UI could not find XRToolsViewport2DIn3D grand parent") SweetLogger.error("{0} could not find XRToolsViewport2DIn3D grandparent", [name])
enabled = false enabled = false
@@ -32,9 +32,9 @@ func _process(_delta: float) -> void:
func toggle_shop(): func toggle_shop():
if GameManager.game_state == GameManager.GameState.BUILDING: if GameManager.game_state == GameManager.GameState.BUILDING:
SweetLogger.debug("toggle shop") SweetLogger.debug("Toggle shop")
enabled = !enabled enabled = !enabled
SweetLogger.debug("_process: money={0} label text={1}", [GameManager.money, money_label.text]) SweetLogger.debug("Money={0} label text={1}", [GameManager.money, money_label.text])
@@ -54,11 +54,11 @@ func _set_poke_enabled_for_controller(controller_node: XRController3D, value: bo
var poke_node = Helper.find_first_child_of_type(controller_node, XRToolsPoke) var poke_node = Helper.find_first_child_of_type(controller_node, XRToolsPoke)
if poke_node: if poke_node:
SweetLogger.debug("_set_poke_enabled_for_controller: {0} poke enabled: {1}", [poke_node.name, value]) SweetLogger.debug("Poke enabled: {0} on {1}", [value, poke_node.name])
poke_node.enabled = value poke_node.enabled = value
poke_node.visible = value poke_node.visible = value
else: else:
SweetLogger.debug("_set_poke_enabled_for_controller: {0} poke not found", [controller_node.name]) SweetLogger.debug("Poke not found on {0}", [controller_node.name])
# For some reason, this is called every frame the button is down. So we need our own timer. # For some reason, this is called every frame the button is down. So we need our own timer.
func _on_controller_button_pressed(button_name: String) -> void: func _on_controller_button_pressed(button_name: String) -> void:
@@ -80,13 +80,13 @@ func _on_other_controller_button_pressed(button_name: String) -> void:
func _on_station_bought(_instance) -> void: func _on_station_bought(_instance) -> void:
enabled = false enabled = false
money_label.text = str(GameManager.money) + "$" money_label.text = str(GameManager.money) + "$"
SweetLogger.debug("_on_station_bought: new money: {0}", [GameManager.money]) SweetLogger.debug("New money: {0}", [GameManager.money])
func detect_hand_from_xr_ancestor() -> void: func detect_hand_from_xr_ancestor() -> void:
controller = XRHelpers.get_xr_controller(self) controller = XRHelpers.get_xr_controller(self)
if not controller: if not controller:
push_error("Shop UI could not find XRController3D ancestor") SweetLogger.error("{0} could not find XRController3D ancestor", [name])
return return
var left_controller := XRHelpers.get_left_controller(self) var left_controller := XRHelpers.get_left_controller(self)
@@ -96,4 +96,4 @@ func detect_hand_from_xr_ancestor() -> void:
other_controller = right_controller other_controller = right_controller
elif controller == right_controller: elif controller == right_controller:
other_controller = left_controller other_controller = left_controller
SweetLogger.debug("detected hand: {0}", [controller.get_tracker_hand()]) SweetLogger.debug("Detected hand: {0}", [controller.get_tracker_hand()])
+115
View File
@@ -0,0 +1,115 @@
class_name Station
extends Node3D
### Abstract 'class', should never be instantiated ###
# - Keep all logic all stations share.
# - Contain as much of the networking code syncing stations as possible.
## Sounds
@export var pickup_sound: AudioStream
@export var drop_sound: AudioStream
## Node references. These are all required snd should be set in the inspector
@export var snap_zone: XRToolsSnapZone
@export var synchronizer: MultiplayerSynchronizer
var sync_config: SceneReplicationConfig
var enabled: bool: # When disabled the station only updated display and sounds.
get: return snap_zone.enabled
set(p_enabled):
SweetLogger.info("Set enabled {0} on station {1} on client {2}", [p_enabled, name, multiplayer.get_unique_id()])
snap_zone.enabled = p_enabled
snap_zone.set_process(p_enabled)
# The child station has to call super.ready() for this to be called
func ready() -> void:
SweetLogger.debug("Station {0} ready", [name])
if not snap_zone:
SweetLogger.warning("{0} missing snap_zone reference", [name])
if not synchronizer:
SweetLogger.warning("{0} missing synchronizer reference", [name])
# Disable if we're not the server.
if not NetworkManager.owns_world():
enabled = false
snap_zone.has_picked_up.connect(_on_object_picked_up_handler)
snap_zone.has_dropped.connect(_on_object_dropped_handler)
# Configure Multiplayer Syncronizer
# This overwrites any changes made in the inspector.
synchronizer.root_path = get_path()
synchronizer.replication_config = SceneReplicationConfig.new()
sync_config = synchronizer.replication_config
# The child station has to call super.process(delta) for this to be called
func process(_delta: float) -> void:
refresh_display()
## Signal handles ##
func _on_object_picked_up_handler(item: Node3D) -> void:
if not NetworkManager.owns_world():
return
_clients_on_object_picked_up_handler.rpc(item.get_path())
_apply_object_picked_up(item)
func _on_object_dropped_handler(item: Node3D) -> void:
if not NetworkManager.owns_world():
return
_clients_on_object_dropped_handler.rpc(item.get_path())
_apply_object_dropped(item)
func _apply_object_picked_up(item: Node3D) -> void:
SweetLogger.debug("Pickup: {0}", [item.name])
on_object_picked_up(item)
var food_item = Helper.find_food_item(item)
if food_item:
on_food_item_picked_up(food_item)
func _apply_object_dropped(item: Node3D) -> void:
SweetLogger.debug("Drop: {0}", [item.name])
on_object_dropped(item)
var food_item = Helper.find_food_item(item)
if food_item:
on_food_item_dropped(food_item)
# Propagate events to clients
@rpc("authority", "call_remote", "reliable")
func _clients_on_object_picked_up_handler(item_path: NodePath):
var item := Helper.get_node_from_path(self, item_path) as Node3D
if not item:
return
_apply_object_picked_up(item)
@rpc("authority", "call_remote", "reliable")
func _clients_on_object_dropped_handler(item_path: NodePath):
var item := Helper.get_node_from_path(self, item_path) as Node3D
if not item:
return
_apply_object_dropped(item)
## Virutal methods
# The child station implements these if it cares about them.
func on_object_picked_up(_item: Node3D) -> void:
SweetLogger.debug("Not implemented in {0}", [name])
func on_object_dropped(_item: Node3D) -> void:
SweetLogger.debug("Not implemented in {0}", [name])
func on_food_item_picked_up(_food_item: FoodItem) -> void:
SweetLogger.debug("Not implemented in {0}", [name])
func on_food_item_dropped(_food_item: FoodItem) -> void:
SweetLogger.debug("Not implemented in {0}", [name])
func refresh_display() -> void:
pass
+1
View File
@@ -0,0 +1 @@
uid://1ii5ov17p2p6
+23
View File
@@ -0,0 +1,23 @@
[gd_scene format=3 uid="uid://cbs8jiqe8rcmn"]
[ext_resource type="PackedScene" uid="uid://cvucwxibtol5f" path="res://stations/StationMovement.tscn" id="1_yuo1j"]
[ext_resource type="PackedScene" uid="uid://bxbocxdaayvwx" path="res://UI/progress_bar.tscn" id="2_be8yi"]
[ext_resource type="PackedScene" uid="uid://ce7vysyvondf8" path="res://addons/godot-xr-tools/objects/snap_zone.tscn" id="3_be8yi"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_0o2ds"]
[node name="Station" type="Node3D" unique_id=707500902]
[node name="StationMovement" parent="." unique_id=946873975 instance=ExtResource("1_yuo1j")]
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1536666704]
replication_config = SubResource("SceneReplicationConfig_0o2ds")
[node name="AudioStreamPlayer3DPulse" type="AudioStreamPlayer3D" parent="." unique_id=1976975302]
[node name="AudioStreamPlayer3DContinous" type="AudioStreamPlayer3D" parent="." unique_id=925832848]
[node name="ProgressBar3D" parent="." unique_id=654673176 instance=ExtResource("2_be8yi")]
[node name="SnapZone" parent="." unique_id=1315859105 groups=["station_zone"] instance=ExtResource("3_be8yi")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
+128
View File
@@ -0,0 +1,128 @@
class_name WorkStation
extends Station
### Abstract 'class', should never be instantiated ###
# This script serves two main jobs:
# - Keep all logic all workstations (sink, hob...) share.
# - Contain as much of the networking code syncing stations as possible.
## Sounds
@export var process_sound: AudioStream
@export var complete_sound: AudioStream
## Node references. These are all required snd should be set in the inspector
@export var notification_audio: AudioStreamPlayer3D # Short sounds like pickup or complete
@export var ambient_audio: AudioStreamPlayer3D # Releating sounds like a cooking noise
@export var progress_bar: ProgressBar3D
## Synced by MultiplayerSyncronizer ##
var current_work: float # How far a FoodItem conversion is toward completion
var max_work: float # How much work has to be acheived to trigger conversion
var result_id: String # Station active if not empty. What FoodItem id the conversion turns the current FoodItem into.
# The child station has to call super.ready() for this to be called
func ready() -> void:
super.ready()
if not notification_audio:
SweetLogger.warning("{0} missing notification_audio reference", [name])
if not ambient_audio:
SweetLogger.warning("{0} missing ambient_audio reference", [name])
if not progress_bar:
SweetLogger.warning("{0} missing progress_bar reference", [name])
# Configure Multiplayer Syncronizer
# Base Station creates the config, here we append to it:
var properties: Array[NodePath] = [ ".:current_work", ".:max_work", ".:result_id"]
for property_path in properties:
sync_config.add_property(property_path)
sync_config.property_set_spawn(property_path, false)
sync_config.property_set_replication_mode(property_path, SceneReplicationConfig.REPLICATION_MODE_ON_CHANGE)
# The child station has to call super.process(delta) for this to be called
func process(delta: float) -> void:
super.process(delta)
#SweetLogger.debug("station process result_id: {0}, work: {1}, max_work: {2}", [result_id, current_work, max_work])
refresh_display()
# Propagate events to clients
@rpc("authority", "call_local", "reliable")
func _everyone_on_work_complete():
on_work_complete()
## Virutal methods ##
# The child station implements these if it cares about them.
func on_work_complete() -> void:
SweetLogger.debug("Not implemented in {0}", [name])
# The child station has to call super.refresh_display for this to be called
func refresh_display() -> void:
super.refresh_display()
var is_active: bool = not result_id.is_empty()
progress_bar.set_bar_visible(is_active)
progress_bar.set_progress((current_work / max_work) if is_active else 0.0)
## Public methods ##
# Will be called by clients to the server, and server to server
func add_work(work: float) -> void:
SweetLogger.debug("Add work: {0} current: {1} max_work: {2}", [snappedf(work, 0.01), snappedf(current_work, 0.01), snappedf(max_work, 0.01)])
if work <= 0:
SweetLogger.warning("Work to add must be positive, work: {0}", [work])
return
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.rpc()
@rpc("any_peer", "call_remote", "reliable")
func server_add_work(work: float) -> void:
add_work(work)
# Converts the currenly held item into result_id, by despawning it and instantiating a new item
func convert_item() -> Node3D:
if not NetworkManager.owns_world():
return
SweetLogger.info("Convert item, result_id: {0}", [result_id])
if not NetworkManager.owns_world:
SweetLogger.warning("Only the server should ever call this!")
return null
if not result_id or result_id.is_empty():
SweetLogger.warning("Station tried to convert item, but result_id is null or empty!")
return
var old_pickable = snap_zone.picked_up_object
if not old_pickable:
SweetLogger.warning("Station tried to convert item, but item is missing!")
return null
var target_id := result_id
var original_transform = old_pickable.global_transform
var new_scene_instance = NetworkManager.spawn_item(RecipeManager.get_item_scene(target_id).resource_path, original_transform)
reset()
# Drop and free the old item and pick up the new one
SweetLogger.debug("Freeing old_pickable {0}", [old_pickable])
snap_zone.drop_object()
NetworkManager.despawn_item(old_pickable)
snap_zone.pick_up_object(new_scene_instance)
SweetLogger.info("Convert item into id: {0}, node name: {1}", [target_id, new_scene_instance.name])
return new_scene_instance
func reset() -> void:
SweetLogger.debug("->[]")
current_work = 0
max_work = 0
result_id = ""
+1
View File
@@ -0,0 +1 @@
uid://b25s3bhslrlxc
Binary file not shown.
+1 -1
View File
@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://bu6jt26pq2y0k"] [gd_scene format=3 uid="uid://bu6jt26pq2y0k"]
[ext_resource type="PackedScene" uid="uid://q37nqadkibbp" path="res://environment/door.tscn" id="1_hgrxd"] [ext_resource type="PackedScene" uid="uid://q37nqadkibbp" path="res://environment/door.tscn" id="1_hgrxd"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="1_p8umn"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="1_p8umn"]
[ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="2_d63j6"] [ext_resource type="PackedScene" uid="uid://caf0xanmxbshy" path="res://stations/table.tscn" id="2_d63j6"]
[ext_resource type="PackedScene" uid="uid://dlw5geheupgpt" path="res://stations/hatch.tscn" id="3_d63j6"] [ext_resource type="PackedScene" uid="uid://dlw5geheupgpt" path="res://stations/hatch.tscn" id="3_d63j6"]
[ext_resource type="PackedScene" uid="uid://da6yrsnxvsrif" path="res://environment/wall.tscn" id="4_41vpv"] [ext_resource type="PackedScene" uid="uid://da6yrsnxvsrif" path="res://environment/wall.tscn" id="4_41vpv"]
+11 -3
View File
@@ -1,17 +1,17 @@
[gd_scene format=3 uid="uid://damrxtlt7uswf"] [gd_scene format=3 uid="uid://damrxtlt7uswf"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="1_1wuvq"] [ext_resource type="PackedScene" uid="uid://b052o1fgwq5bw" path="res://stations/Hob.tscn" id="1_1wuvq"]
[ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="2_3qwcq"] [ext_resource type="PackedScene" uid="uid://efaec6ymgabo" path="res://stations/Counter.tscn" id="2_3qwcq"]
[ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="3_3qwcq"] [ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="3_3qwcq"]
[ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="4_5eled"] [ext_resource type="PackedScene" uid="uid://c6rift56ql3f8" path="res://stations/BurgerBunsDispenser.tscn" id="4_5eled"]
[ext_resource type="PackedScene" uid="uid://cwnwo4i28upap" path="res://stations/raw_burger_dispenser.tscn" id="5_0342k"] [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://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://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"]
[ext_resource type="PackedScene" uid="uid://sc6i0i1f0o48" path="res://stations/potato_dispenser.tscn" id="9_ok0xr"]
[node name="SmallLine" type="Node3D" unique_id=1844128818] [node name="SmallLine" type="Node3D" unique_id=1844128818]
[node name="Hob" parent="." unique_id=1687971542 instance=ExtResource("1_1wuvq")]
[node name="Counter" parent="." unique_id=1487893288 instance=ExtResource("2_3qwcq")] [node name="Counter" parent="." unique_id=1487893288 instance=ExtResource("2_3qwcq")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.6, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.6, 0, 0)
@@ -29,3 +29,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.8000001, 0, 0)
[node name="Table" parent="." unique_id=987495548 instance=ExtResource("7_0342k")] [node name="Table" parent="." unique_id=987495548 instance=ExtResource("7_0342k")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4, 0, 1.2) 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)
[node name="PotatoDispenser" parent="." unique_id=522124817 instance=ExtResource("9_ok0xr")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.8000001, 0, 0.6)
+16
View File
@@ -1,4 +1,20 @@
### Station inheritence suggestion
Station
WorkStation (performs work on a food item to convert it)
Hob
Sink
Counter
StorageStation (one snap zone and list of positions, FILO item dispenser, like a gun magazine)
Shelf
PlateRak
Dishwasher
SharedInventoryStation (one snap zone, shares a list of connected stations with which items exist in each of them)
Table
Belt
Dispenser
### Multiplayer bugs
- despan flicker for clien broken - despan flicker for clien broken
- client keep autorityu of thrown object until lands - client keep autorityu of thrown object until lands
- in build mode, snap zones off, stations disabled - in build mode, snap zones off, stations disabled
+27 -27
View File
@@ -9,9 +9,9 @@ func set_money(value):
if multiplayer.is_server(): if multiplayer.is_server():
money = max(0,value) money = max(0,value)
client_sync_money.rpc(money) client_sync_money.rpc(money)
SweetLogger.info("set_money money set to {0}", [money]) SweetLogger.info("Set to {0}", [money])
else: else:
SweetLogger.info("set_money client/(peer_id={0}) attempted to set money directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_money.rpc_id(1, value) server_set_money.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") # CLIENT -> SERVER: Request a change @rpc("any_peer", "call_remote", "reliable") # CLIENT -> SERVER: Request a change
@@ -29,9 +29,9 @@ func set_day_number(value: int) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
day_number = value day_number = value
client_sync_day_number.rpc(day_number) client_sync_day_number.rpc(day_number)
SweetLogger.info("set_day_number day_number set to {0}", [day_number]) SweetLogger.info("Set to {0}", [day_number])
else: else:
SweetLogger.info("set_day_number client/(peer_id={0}) attempted to set day_number directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_day_number.rpc_id(1, value) server_set_day_number.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -51,9 +51,9 @@ func set_meals_in_play(value: Array[String]) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
meals_in_play = value meals_in_play = value
client_sync_meals_in_play.rpc(meals_in_play) client_sync_meals_in_play.rpc(meals_in_play)
SweetLogger.info("set_meals_in_play meals_in_play set to {0}", [meals_in_play]) SweetLogger.info("Set to {0}", [meals_in_play])
else: else:
SweetLogger.info("set_meals_in_play client/(peer_id={0}) attempted to set meals_in_play directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_meals_in_play.rpc_id(1, value) server_set_meals_in_play.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -73,9 +73,9 @@ func set_sides_in_play(value: Array[String]) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
sides_in_play = value sides_in_play = value
client_sync_sides_in_play.rpc(sides_in_play) client_sync_sides_in_play.rpc(sides_in_play)
SweetLogger.info("set_sides_in_play sides_in_play set to {0}", [sides_in_play]) SweetLogger.info("Set to {0}", [sides_in_play])
else: else:
SweetLogger.info("set_sides_in_play client/(peer_id={0}) attempted to set sides_in_play directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_sides_in_play.rpc_id(1, value) server_set_sides_in_play.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -96,9 +96,9 @@ func set_day_length_seconds(value: float) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
day_length_seconds = value day_length_seconds = value
client_sync_day_length_seconds.rpc(day_length_seconds) client_sync_day_length_seconds.rpc(day_length_seconds)
SweetLogger.info("set_day_length_seconds day_length_seconds set to {0}", [day_length_seconds]) SweetLogger.info("Set to {0}", [day_length_seconds])
else: else:
SweetLogger.info("set_day_length_seconds client/(peer_id={0}) attempted to set day_length_seconds directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_day_length_seconds.rpc_id(1, value) server_set_day_length_seconds.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -118,9 +118,9 @@ func set_customers_per_day(value: float) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
customers_per_day = value customers_per_day = value
client_sync_customers_per_day.rpc(customers_per_day) client_sync_customers_per_day.rpc(customers_per_day)
SweetLogger.info("set_customers_per_day customers_per_day set to {0}", [customers_per_day]) SweetLogger.info("Set to {0}", [customers_per_day])
else: else:
SweetLogger.info("set_customers_per_day client/(peer_id={0}) attempted to set customers_per_day directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_customers_per_day.rpc_id(1, value) server_set_customers_per_day.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -140,9 +140,9 @@ func set_customers_count_increase_per_day(value: float) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
customers_count_increase_per_day = value customers_count_increase_per_day = value
client_sync_customers_count_increase_per_day.rpc(customers_count_increase_per_day) client_sync_customers_count_increase_per_day.rpc(customers_count_increase_per_day)
SweetLogger.info("set_customers_count_increase_per_day customers_count_increase_per_day set to {0}", [customers_count_increase_per_day]) SweetLogger.info("Set to {0}", [customers_count_increase_per_day])
else: else:
SweetLogger.info("set_customers_count_increase_per_day client/(peer_id={0}) attempted to set customers_count_increase_per_day directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_customers_count_increase_per_day.rpc_id(1, value) server_set_customers_count_increase_per_day.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -162,9 +162,9 @@ func set_group_min_size(value: int) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
group_min_size = value group_min_size = value
client_sync_group_min_size.rpc(group_min_size) client_sync_group_min_size.rpc(group_min_size)
SweetLogger.info("set_group_min_size group_min_size set to {0}", [group_min_size]) SweetLogger.info("Set to {0}", [group_min_size])
else: else:
SweetLogger.info("set_group_min_size client/(peer_id={0}) attempted to set group_min_size directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_group_min_size.rpc_id(1, value) server_set_group_min_size.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -184,9 +184,9 @@ func set_group_max_size(value: int) -> void:
if multiplayer.is_server(): if multiplayer.is_server():
group_max_size = value group_max_size = value
client_sync_group_max_size.rpc(group_max_size) client_sync_group_max_size.rpc(group_max_size)
SweetLogger.info("set_group_max_size group_max_size set to {0}", [group_max_size]) SweetLogger.info("Set to {0}", [group_max_size])
else: else:
SweetLogger.info("set_group_max_size client/(peer_id={0}) attempted to set group_max_size directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_group_max_size.rpc_id(1, value) server_set_group_max_size.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -213,9 +213,9 @@ func set_game_state(value: GameState) -> void:
game_state = value game_state = value
client_sync_game_state.rpc(game_state) client_sync_game_state.rpc(game_state)
Signals.game_state_changed.emit(game_state) Signals.game_state_changed.emit(game_state)
SweetLogger.info("set_game_state game_state set to {0}", [game_state]) SweetLogger.info("Set to {0}", [game_state])
else: else:
SweetLogger.info("set_game_state client/(peer_id={0}) attempted to set game_state directly, sending request to server", [multiplayer.get_unique_id()]) SweetLogger.info("Client (peer {0}) attempted direct set, forwarding to server", [multiplayer.get_unique_id()])
server_set_game_state.rpc_id(1, value) server_set_game_state.rpc_id(1, value)
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
@@ -230,29 +230,29 @@ func client_sync_game_state(value: GameState) -> void:
func get_random_meal() -> String: func get_random_meal() -> String:
if meals_in_play.size() == 0: if meals_in_play.size() == 0:
push_error("GameManager: get_random_meal() called but meals_in_play is empty") SweetLogger.error("Get_random_meal() called but meals_in_play is empty")
return "" return ""
var rand_index = randi() % meals_in_play.size() var rand_index = randi() % meals_in_play.size()
SweetLogger.debug("get_random_meal() returning {0}", [meals_in_play[rand_index]]) SweetLogger.debug("Get_random_meal() returning {0}", [meals_in_play[rand_index]])
return meals_in_play[rand_index] return meals_in_play[rand_index]
func get_random_side() -> String: func get_random_side() -> String:
SweetLogger.debug("get_random_side()") SweetLogger.debug("->[]")
if sides_in_play.size() == 0: if sides_in_play.size() == 0:
push_error("GameManager: get_random_side() called but sides_in_play is empty") SweetLogger.error("Get_random_side() called but sides_in_play is empty")
return "" return ""
var rand_index = randi() % sides_in_play.size() var rand_index = randi() % sides_in_play.size()
SweetLogger.debug("get_random_side() list={0} returning {1}", [sides_in_play, sides_in_play[rand_index]], "GameManager.gd", "get_random_side") SweetLogger.debug("List={0} returning {1}", [sides_in_play, sides_in_play[rand_index]], "GameManager.gd", "get_random_side")
return sides_in_play[rand_index] return sides_in_play[rand_index]
func _restart(): func _restart():
SweetLogger.info("restart Game") SweetLogger.info("Restart game")
game_state = GameState.RUNNING game_state = GameState.RUNNING
func game_over(): func game_over():
SweetLogger.info("Game Over") SweetLogger.info("Game over")
game_state = GameState.GAME_OVER game_state = GameState.GAME_OVER
Signals.game_over.emit() Signals.game_over.emit()
+21 -21
View File
@@ -16,7 +16,7 @@ static func load_recipes() -> void:
var recipe_path := "res://recipes.yaml" var recipe_path := "res://recipes.yaml"
if not FileAccess.file_exists(recipe_path): if not FileAccess.file_exists(recipe_path):
push_error("RecipeManager: recipes.yaml was not found at %s" % recipe_path) SweetLogger.error("Recipes.yaml was not found at {0}", [recipe_path])
return return
var yaml_available := ClassDB.class_exists("YAML") var yaml_available := ClassDB.class_exists("YAML")
@@ -25,7 +25,7 @@ static func load_recipes() -> void:
if result != null and not result.has_error(): if result != null and not result.has_error():
var data = result.get_data() var data = result.get_data()
if typeof(data) != TYPE_DICTIONARY: if typeof(data) != TYPE_DICTIONARY:
push_warning("RecipeManager: YAML addon parsed recipes.yaml but returned an unsupported structure") SweetLogger.warning("YAML addon parsed recipes.yaml but returned an unsupported structure")
_recipes = data _recipes = data
_build_scene_paths() _build_scene_paths()
@@ -98,12 +98,12 @@ static func get_item_scene(item_id: StringName) -> PackedScene:
load_recipes() load_recipes()
var scene_path = _scene_paths.get(str(item_id), "") var scene_path = _scene_paths.get(str(item_id), "")
if typeof(scene_path) != TYPE_STRING or scene_path.is_empty(): if typeof(scene_path) != TYPE_STRING or scene_path.is_empty():
push_error("RecipeManager: no scene mapping found for item id '%s'" % item_id) SweetLogger.error("No scene mapping found for item id '{0}'", [item_id])
return null return null
var scene = ResourceLoader.load(scene_path) var scene = ResourceLoader.load(scene_path)
if not scene: if not scene:
push_error("RecipeManager: failed to load scene '%s' for item '%s'" % [scene_path, item_id]) SweetLogger.error("Failed to load scene '{0}' for item '{1}'", [scene_path, item_id])
return null return null
return scene as PackedScene return scene as PackedScene
@@ -111,14 +111,14 @@ static func get_item_scene(item_id: StringName) -> PackedScene:
static func print_all_recipes() -> void: static func print_all_recipes() -> void:
load_recipes() load_recipes()
if not _loaded: if not _loaded:
SweetLogger.warning("could not load recipes.yaml; no recipes printed.") SweetLogger.warning("Could not load recipes.yaml; no recipes printed")
return return
if _combining_map.is_empty(): if _combining_map.is_empty():
SweetLogger.warning("no combining recipes found") SweetLogger.warning("No combining recipes found")
return return
SweetLogger.info("#### RecipeManager: Loaded recipes ####") SweetLogger.info("#### Loaded recipes ####")
_print_combining_recipes() _print_combining_recipes()
SweetLogger.info("") SweetLogger.info("")
_print_cooking_recipes() _print_cooking_recipes()
@@ -135,7 +135,7 @@ static func _print_combining_recipes() -> void:
var key_str = str(pair_key) var key_str = str(pair_key)
var separator_index = key_str.find("|") var separator_index = key_str.find("|")
if separator_index == -1: if separator_index == -1:
SweetLogger.warning("invalid combining map key '{0}'", [key_str]) SweetLogger.warning("Invalid combining map key '{0}'", [key_str])
continue continue
var first = key_str.substr(0, separator_index) var first = key_str.substr(0, separator_index)
@@ -198,7 +198,7 @@ static func _build_combining_map() -> void:
for result_id in combining.keys(): for result_id in combining.keys():
var recipe_entries = _get_recipe_entries(combining[result_id]) var recipe_entries = _get_recipe_entries(combining[result_id])
if recipe_entries.is_empty(): if recipe_entries.is_empty():
push_error("RecipeManager: combining recipe '%s' must contain at least one valid recipe" % result_id) SweetLogger.error("Combining recipe '{0}' must contain at least one valid recipe", [result_id])
continue continue
for recipe in recipe_entries: for recipe in recipe_entries:
var first = StringName(recipe[0]) var first = StringName(recipe[0])
@@ -251,24 +251,24 @@ static func _build_cooking_map() -> void:
if typeof(cook_val) == TYPE_ARRAY: if typeof(cook_val) == TYPE_ARRAY:
for entry in cook_val: for entry in cook_val:
if typeof(entry) != TYPE_DICTIONARY: if typeof(entry) != TYPE_DICTIONARY:
push_error("RecipeManager: cooking recipe for '%s' contains a non-dictionary entry" % cooked_id) SweetLogger.error("Cooking recipe for '{0}' contains a non-dictionary entry", [cooked_id])
continue continue
entries.append(entry) entries.append(entry)
elif typeof(cook_val) == TYPE_DICTIONARY: elif typeof(cook_val) == TYPE_DICTIONARY:
entries.append(cook_val) entries.append(cook_val)
else: else:
push_error("RecipeManager: cooking recipe for '%s' must be a dictionary or array of dictionaries" % cooked_id) SweetLogger.error("Cooking recipe for '{0}' must be a dictionary or array of dictionaries", [cooked_id])
continue continue
var parsed_entries: Array = [] var parsed_entries: Array = []
for cook_def in entries: for cook_def in entries:
var ingredient = cook_def.get("ingredient", "") var ingredient = cook_def.get("ingredient", "")
if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty(): if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty():
push_error("RecipeManager: cooking recipe '%s' missing a valid 'ingredient' field" % cooked_id) SweetLogger.error("Cooking recipe '{0}' missing a valid 'ingredient' field", [cooked_id])
continue continue
var time_val = cook_def.get("time", null) var time_val = cook_def.get("time", null)
if typeof(time_val) != TYPE_INT and typeof(time_val) != TYPE_FLOAT: if typeof(time_val) != TYPE_INT and typeof(time_val) != TYPE_FLOAT:
push_error("RecipeManager: cooking recipe '%s' missing a valid 'time' field" % cooked_id) SweetLogger.error("Cooking recipe '{0}' missing a valid 'time' field", [cooked_id])
continue continue
parsed_entries.append({"ingredient": StringName(str(ingredient)), "time": float(time_val)}) parsed_entries.append({"ingredient": StringName(str(ingredient)), "time": float(time_val)})
@@ -289,15 +289,15 @@ static func _build_chopping_map() -> void:
for chopped_id in chopping.keys(): for chopped_id in chopping.keys():
var chop_def = chopping[chopped_id] var chop_def = chopping[chopped_id]
if typeof(chop_def) != TYPE_DICTIONARY: if typeof(chop_def) != TYPE_DICTIONARY:
push_error("RecipeManager: chopping recipe for '%s' must be a dictionary" % chopped_id) SweetLogger.error("Chopping recipe for '{0}' must be a dictionary", [chopped_id])
continue continue
var ingredient = chop_def.get("ingredient", "") var ingredient = chop_def.get("ingredient", "")
if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty(): if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty():
push_error("RecipeManager: chopping recipe '%s' missing a valid 'ingredient' field" % chopped_id) SweetLogger.error("Chopping recipe '{0}' missing a valid 'ingredient' field", [chopped_id])
continue continue
var work_val = chop_def.get("work", null) var work_val = chop_def.get("work", null)
if typeof(work_val) != TYPE_INT and typeof(work_val) != TYPE_FLOAT: if typeof(work_val) != TYPE_INT and typeof(work_val) != TYPE_FLOAT:
push_error("RecipeManager: chopping recipe '%s' missing a valid 'work' field" % chopped_id) SweetLogger.error("Chopping recipe '{0}' missing a valid 'work' field", [chopped_id])
continue continue
# store chopped item -> { ingredient: StringName, work: float } # store chopped item -> { ingredient: StringName, work: float }
_chopping_map[StringName(chopped_id)] = {"ingredient": StringName(str(ingredient)), "work": float(work_val)} _chopping_map[StringName(chopped_id)] = {"ingredient": StringName(str(ingredient)), "work": float(work_val)}
@@ -316,15 +316,15 @@ static func _build_rolling_map() -> void:
for rolled_id in rolling.keys(): for rolled_id in rolling.keys():
var roll_def = rolling[rolled_id] var roll_def = rolling[rolled_id]
if typeof(roll_def) != TYPE_DICTIONARY: if typeof(roll_def) != TYPE_DICTIONARY:
push_error("RecipeManager: rolling recipe for '%s' must be a dictionary" % rolled_id) SweetLogger.error("Rolling recipe for '{0}' must be a dictionary", [rolled_id])
continue continue
var ingredient = roll_def.get("ingredient", "") var ingredient = roll_def.get("ingredient", "")
if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty(): if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty():
push_error("RecipeManager: rolling recipe '%s' missing a valid 'ingredient' field" % rolled_id) SweetLogger.error("Rolling recipe '{0}' missing a valid 'ingredient' field", [rolled_id])
continue continue
var work_val = roll_def.get("work", null) var work_val = roll_def.get("work", null)
if typeof(work_val) != TYPE_INT and typeof(work_val) != TYPE_FLOAT: if typeof(work_val) != TYPE_INT and typeof(work_val) != TYPE_FLOAT:
push_error("RecipeManager: rolling recipe '%s' missing a valid 'work' field" % rolled_id) SweetLogger.error("Rolling recipe '{0}' missing a valid 'work' field", [rolled_id])
continue continue
# store rolled item -> { ingredient: StringName, work: float } # store rolled item -> { ingredient: StringName, work: float }
_rolling_map[StringName(rolled_id)] = {"ingredient": StringName(str(ingredient)), "work": float(work_val)} _rolling_map[StringName(rolled_id)] = {"ingredient": StringName(str(ingredient)), "work": float(work_val)}
@@ -343,13 +343,13 @@ static func _build_augmenting_map() -> void:
for target_id in augmenting.keys(): for target_id in augmenting.keys():
var augment_def = augmenting[target_id] var augment_def = augmenting[target_id]
if typeof(augment_def) != TYPE_DICTIONARY: if typeof(augment_def) != TYPE_DICTIONARY:
push_error("RecipeManager: augmenting recipe for '%s' must be a dictionary" % target_id) SweetLogger.error("Augmenting recipe for '{0}' must be a dictionary", [target_id])
continue continue
var map: Dictionary = {} var map: Dictionary = {}
for attr_key in augment_def.keys(): for attr_key in augment_def.keys():
var ingredient = augment_def[attr_key] var ingredient = augment_def[attr_key]
if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty(): if typeof(ingredient) != TYPE_STRING or str(ingredient).is_empty():
push_error("RecipeManager: augmenting recipe '%s' has invalid ingredient for '%s'" % [target_id, attr_key]) SweetLogger.error("Augmenting recipe '{0}' has invalid ingredient for '{1}'", [target_id, attr_key])
continue continue
# store ingredient -> attribute_key (e.g. sliced_tomato -> has_tomato) # store ingredient -> attribute_key (e.g. sliced_tomato -> has_tomato)
map[StringName(str(ingredient))] = StringName(str(attr_key)) map[StringName(str(ingredient))] = StringName(str(attr_key))
+10 -3
View File
@@ -25,15 +25,15 @@ static func find_first_child_of_type(node: Node, type: Variant) -> Node:
# Returns true if decendant is a decendant node of root, false otherwise. Returns false if either node is null. # Returns true if decendant is a decendant node of root, false otherwise. Returns false if either node is null.
static func is_node_decendant_of(decendant: Node, root: Node) -> bool: static func is_node_decendant_of(decendant: Node, root: Node) -> bool:
if not decendant or not root: if not decendant or not root:
SweetLogger.debug("is_node_decendant_of: decendant or root is null") SweetLogger.debug("Decendant or root is null")
return false return false
var current: Node = decendant var current: Node = decendant
while current: while current:
if current == root: if current == root:
SweetLogger.debug("is_node_decendant_of: decendant {0} is a descendant of root {1}", [decendant.name, root.name]) SweetLogger.debug("Decendant {0} is a descendant of root {1}", [decendant.name, root.name])
return true return true
current = current.get_parent() current = current.get_parent()
SweetLogger.debug("is_node_decendant_of: decendant {0} is NOT a descendant of root {1}", [decendant.name, root.name]) SweetLogger.debug("Decendant {0} is NOT a descendant of root {1}", [decendant.name, root.name])
return false return false
@@ -46,3 +46,10 @@ static func get_snapped_transform(node: Node3D) -> Transform3D:
var target_yaw: float = snappedf(node.global_rotation_degrees.y, 90) var target_yaw: float = snappedf(node.global_rotation_degrees.y, 90)
new_transform.basis = Basis(Vector3.UP, deg_to_rad(target_yaw)) new_transform.basis = Basis(Vector3.UP, deg_to_rad(target_yaw))
return new_transform return new_transform
static func get_node_from_path(from: Node, node_path: NodePath) -> Node3D:
var item := from.get_node_or_null(node_path) as Node3D
if not item:
SweetLogger.warning("Could not resolve node from node_path: {0}, are the trees in sync?", [node_path])
return null
return item
+1
View File
@@ -53,6 +53,7 @@ station="Hobs, Counters ..."
table="all nodes with table script" table="all nodes with table script"
chopping_tool="A pickable body that chops" chopping_tool="A pickable body that chops"
persistent_inventory="A station that keeps it's held items in build mode" persistent_inventory="A station that keeps it's held items in build mode"
station_zone="The snap_zone node on stations should have this"
[input] [input]
+1 -1
View File
@@ -4,7 +4,7 @@
[ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_j7vd1"] [ext_resource type="PackedScene" uid="uid://j5s5wus7tuhb" path="res://prefabs/XROrigin.tscn" id="2_j7vd1"]
[ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_ssbaf"] [ext_resource type="Material" uid="uid://cmia50cfqxxo4" path="res://textures/dev_material_3d.tres" id="3_ssbaf"]
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="4_081u3"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="4_081u3"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob.tscn" id="5_t1fa7"] [ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="5_t1fa7"]
[ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="6_6jhmh"] [ext_resource type="PackedScene" uid="uid://dvrk268s7gkxh" path="res://stations/sink.tscn" id="6_6jhmh"]
[ext_resource type="PackedScene" uid="uid://bp3v1jl8pctro" path="res://Containers/plate.tscn" id="7_bowes"] [ext_resource type="PackedScene" uid="uid://bp3v1jl8pctro" path="res://Containers/plate.tscn" id="7_bowes"]
[ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://stations/dirt_station.tscn" id="8_pvl84"] [ext_resource type="PackedScene" uid="uid://cnjwtnhwh0i8q" path="res://stations/dirt_station.tscn" id="8_pvl84"]
+8 -8
View File
@@ -42,17 +42,17 @@ func _run() -> void:
_clear_previous_results(logs_dir) _clear_previous_results(logs_dir)
print_rich("[b]Running the multiplayer test suite...[/b]") print_rich("[b]Running the multiplayer test suite...[/b]")
SweetLogger.info("the editor will be unresponsive until it finishes (~2 minutes)") SweetLogger.info("The editor will be unresponsive until it finishes (~2 minutes)")
var server_pid := _launch(exe, project_dir, ["--server"], SERVER_SCENE) var server_pid := _launch(exe, project_dir, ["--server"], SERVER_SCENE)
if server_pid <= 0: if server_pid <= 0:
push_error("Could not start the server instance") SweetLogger.error("Could not start the server instance")
return return
# Give the host time to come up and open its port before the client dials in. # Give the host time to come up and open its port before the client dials in.
OS.delay_msec(5000) OS.delay_msec(5000)
var client_pid := _launch(exe, project_dir, ["--join", "127.0.0.1"], CLIENT_SCENE) var client_pid := _launch(exe, project_dir, ["--join", "127.0.0.1"], CLIENT_SCENE)
if client_pid <= 0: if client_pid <= 0:
push_error("Could not start the client instance") SweetLogger.error("Could not start the client instance")
OS.kill(server_pid) OS.kill(server_pid)
return return
@@ -61,7 +61,7 @@ func _run() -> void:
OS.delay_msec(500) OS.delay_msec(500)
waited += 0.5 waited += 0.5
if OS.is_process_running(server_pid): if OS.is_process_running(server_pid):
SweetLogger.warning("timed out after {0}s, stopping the instances", [TIMEOUT_SEC]) SweetLogger.warning("Timed out after {0}s, stopping the instances", [TIMEOUT_SEC])
OS.kill(server_pid) OS.kill(server_pid)
if OS.is_process_running(client_pid): if OS.is_process_running(client_pid):
OS.kill(client_pid) OS.kill(client_pid)
@@ -105,7 +105,7 @@ func _clear_previous_results(logs_dir: String) -> void:
func _print_report(logs_dir: String) -> void: func _print_report(logs_dir: String) -> void:
var path := logs_dir.path_join("mptest_report.txt") var path := logs_dir.path_join("mptest_report.txt")
if not FileAccess.file_exists(path): if not FileAccess.file_exists(path):
push_error("No report at %s the run did not finish. Check logs/mptest_server.log" % path) SweetLogger.error("No report at {0}, the run did not finish, check logs/mptest_server.log", [path])
return return
var text := FileAccess.get_file_as_string(path) var text := FileAccess.get_file_as_string(path)
SweetLogger.info("") SweetLogger.info("")
@@ -119,7 +119,7 @@ func _print_report(logs_dir: String) -> void:
print_rich("[color=gray]%s[/color]" % line) print_rich("[color=gray]%s[/color]" % line)
else: else:
SweetLogger.info("{0}", [line]) SweetLogger.info("{0}", [line])
SweetLogger.info("report: {0}", [path]) SweetLogger.info("Report: {0}", [path])
func _build_gif(project_dir: String, logs_dir: String) -> void: func _build_gif(project_dir: String, logs_dir: String) -> void:
@@ -129,9 +129,9 @@ func _build_gif(project_dir: String, logs_dir: String) -> void:
"-ExecutionPolicy", "Bypass", "-File", script, "-ExecutionPolicy", "Bypass", "-File", script,
], out, true) ], out, true)
for line in out: for line in out:
print(line) SweetLogger.debug("{0}", [line])
var gif := logs_dir.path_join("mptest_run.gif") var gif := logs_dir.path_join("mptest_run.gif")
if code == 0 and FileAccess.file_exists(gif): if code == 0 and FileAccess.file_exists(gif):
print_rich("[b]gif:[/b] %s" % gif) print_rich("[b]gif:[/b] %s" % gif)
else: else:
push_warning("GIF was not produced (is ffmpeg on PATH?). See the output above.") SweetLogger.warning("GIF was not produced (is ffmpeg on PATH?), see the output above")
+2 -2
View File
@@ -3,8 +3,8 @@ extends Node
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
SweetLogger.debug("stations: {0}", [get_stations()]) SweetLogger.debug("Stations: {0}", [get_stations()])
SweetLogger.debug("items: {0}", [get_items()]) SweetLogger.debug("Items: {0}", [get_items()])