Fix bug where only net_pickable could disable XRToolPickables
This commit is contained in:
@@ -35,6 +35,9 @@ properties/1/replication_mode = 1
|
|||||||
properties/2/path = NodePath("NetPickable:net_held_by")
|
properties/2/path = NodePath("NetPickable:net_held_by")
|
||||||
properties/2/spawn = true
|
properties/2/spawn = true
|
||||||
properties/2/replication_mode = 1
|
properties/2/replication_mode = 1
|
||||||
|
properties/3/path = NodePath(".:enabled")
|
||||||
|
properties/3/spawn = false
|
||||||
|
properties/3/replication_mode = 1
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_s6exe"]
|
[sub_resource type="Gradient" id="Gradient_s6exe"]
|
||||||
interpolation_mode = 2
|
interpolation_mode = 2
|
||||||
|
|||||||
+22
-4
@@ -24,6 +24,12 @@ var _original_freeze_mode: RigidBody3D.FreezeMode
|
|||||||
# branch of apply_held_state() clears while someone else is holding the item.
|
# branch of apply_held_state() clears while someone else is holding the item.
|
||||||
var _original_enabled: bool
|
var _original_enabled: bool
|
||||||
|
|
||||||
|
# Intent set by external game logic (e.g. a station enabling/disabling a tool),
|
||||||
|
# independent of hold state. apply_held_state() is the sole writer of the
|
||||||
|
# pickable's actual `enabled` property, so this is how other systems express
|
||||||
|
# "should be enabled" without fighting that reconciliation every tick.
|
||||||
|
var _tool_enabled: bool = true
|
||||||
|
|
||||||
# Whether the "our own hand still holds this" guard has already been logged for
|
# Whether the "our own hand still holds this" guard has already been logged for
|
||||||
# the current grab. apply_held_state() runs every network tick, so without this
|
# the current grab. apply_held_state() runs every network tick, so without this
|
||||||
# the guard message repeats for as long as you hold the item.
|
# the guard message repeats for as long as you hold the item.
|
||||||
@@ -47,6 +53,17 @@ func _ready() -> void:
|
|||||||
apply_held_state.call_deferred()
|
apply_held_state.call_deferred()
|
||||||
|
|
||||||
|
|
||||||
|
## Called by external game logic (e.g. Counter._enable_tool/_disable_tool) to
|
||||||
|
## express whether this item should be usable right now, independent of hold
|
||||||
|
## state. Reapplies immediately so the change takes effect without waiting for
|
||||||
|
## the next net_held_by tick.
|
||||||
|
func set_tool_enabled(value: bool) -> void:
|
||||||
|
if _tool_enabled == value:
|
||||||
|
return
|
||||||
|
_tool_enabled = value
|
||||||
|
apply_held_state()
|
||||||
|
|
||||||
|
|
||||||
func _set_net_held_by(value: int) -> void:
|
func _set_net_held_by(value: int) -> void:
|
||||||
var old := net_held_by
|
var old := net_held_by
|
||||||
net_held_by = value
|
net_held_by = value
|
||||||
@@ -95,10 +112,11 @@ func apply_held_state() -> void:
|
|||||||
# e.g. a plate still got marked dirty) while pick_up() bailed out on
|
# e.g. a plate still got marked dirty) while pick_up() bailed out on
|
||||||
# the disabled item, leaving the zone holding an item with no grab
|
# the disabled item, leaving the zone holding an item with no grab
|
||||||
# driver that then fell out of the station.
|
# driver that then fell out of the station.
|
||||||
if _pickable.enabled != _original_enabled:
|
var want_enabled_authority := _original_enabled and _tool_enabled
|
||||||
|
if _pickable.enabled != want_enabled_authority:
|
||||||
if NetworkManager.is_online():
|
if NetworkManager.is_online():
|
||||||
SweetLogger.debug("{0}: reclaiming ownership, restoring enabled {1}->{2}", [_pickable.name, _pickable.enabled, _original_enabled])
|
SweetLogger.debug("{0}: reclaiming ownership, restoring enabled {1}->{2}", [_pickable.name, _pickable.enabled, want_enabled_authority])
|
||||||
_pickable.enabled = _original_enabled
|
_pickable.enabled = want_enabled_authority
|
||||||
return
|
return
|
||||||
# A net_held_by/position sync update can race ahead of the
|
# A net_held_by/position sync update can race ahead of the
|
||||||
# authority-handoff RPC that's about to confirm a grab we just made
|
# authority-handoff RPC that's about to confirm a grab we just made
|
||||||
@@ -125,7 +143,7 @@ func apply_held_state() -> void:
|
|||||||
# physics-property writes per item per tick. The comparison also means we
|
# physics-property writes per item per tick. The comparison also means we
|
||||||
# still re-apply if something else perturbs the state (e.g. let_go()
|
# still re-apply if something else perturbs the state (e.g. let_go()
|
||||||
# restoring the collision mask after a force-drop).
|
# restoring the collision mask after a force-drop).
|
||||||
var want_enabled := (net_held_by == 0)
|
var want_enabled := (net_held_by == 0) and _tool_enabled
|
||||||
if _pickable.freeze \
|
if _pickable.freeze \
|
||||||
and _pickable.freeze_mode == RigidBody3D.FREEZE_MODE_KINEMATIC \
|
and _pickable.freeze_mode == RigidBody3D.FREEZE_MODE_KINEMATIC \
|
||||||
and _pickable.collision_mask == 0 \
|
and _pickable.collision_mask == 0 \
|
||||||
|
|||||||
+16
-9
@@ -18,7 +18,7 @@ func _ready() -> void:
|
|||||||
SweetLogger.warning("{0} missing chop_audio reference", [name])
|
SweetLogger.warning("{0} missing chop_audio reference", [name])
|
||||||
if not knife:
|
if not knife:
|
||||||
SweetLogger.warning("{0} missing knife reference", [name])
|
SweetLogger.warning("{0} missing knife reference", [name])
|
||||||
_hide_all_tools()
|
_disable_all_tools()
|
||||||
|
|
||||||
|
|
||||||
func _start_chopping(id: String, work: float) -> void:
|
func _start_chopping(id: String, work: float) -> void:
|
||||||
@@ -33,12 +33,20 @@ func _process(delta: float) -> void:
|
|||||||
super.process(delta)
|
super.process(delta)
|
||||||
|
|
||||||
|
|
||||||
|
func _enable_tool(_item: XRToolsPickable):
|
||||||
func _hide_all_tools():
|
SweetLogger.debug("Enable tool {0} on {1}", [_item.name, name])
|
||||||
knife.visible = false
|
_item.visible = true
|
||||||
knife.enabled = false
|
_item.get_node("NetPickable").set_tool_enabled(true)
|
||||||
|
|
||||||
|
|
||||||
|
func _disable_tool(_item: XRToolsPickable):
|
||||||
|
SweetLogger.debug("Disable tool {0} on {1}", [_item.name, name])
|
||||||
|
_item.visible = false
|
||||||
|
_item.get_node("NetPickable").set_tool_enabled(false)
|
||||||
|
|
||||||
|
func _disable_all_tools():
|
||||||
|
SweetLogger.debug("Disable all tools on {0}", [name])
|
||||||
|
_disable_tool(knife)
|
||||||
|
|
||||||
|
|
||||||
func _on_gesture_area_body_entered(body: Node3D) -> void:
|
func _on_gesture_area_body_entered(body: Node3D) -> void:
|
||||||
@@ -84,20 +92,19 @@ func on_food_item_picked_up(food_item: FoodItem) -> void:
|
|||||||
SweetLogger.debug("Held a FoodItem that is not choppable, id: {0} 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
|
||||||
|
|
||||||
knife.visible = true
|
_enable_tool(knife)
|
||||||
knife.enabled = true
|
|
||||||
_start_chopping(result, RecipeManager.get_chopping_work(food_item.id))
|
_start_chopping(result, RecipeManager.get_chopping_work(food_item.id))
|
||||||
|
|
||||||
|
|
||||||
# Called from Station base class
|
# Called from Station base class
|
||||||
func on_object_dropped(_item: Node3D) -> void:
|
func on_object_dropped(_item: Node3D) -> void:
|
||||||
SweetLogger.debug("->[]")
|
SweetLogger.debug("->[]")
|
||||||
_hide_all_tools()
|
_disable_all_tools()
|
||||||
reset()
|
reset()
|
||||||
|
|
||||||
|
|
||||||
# Called from Station base class
|
# Called from Station base class
|
||||||
func on_work_complete():
|
func on_work_complete():
|
||||||
SweetLogger.debug("->[]")
|
SweetLogger.debug("->[]")
|
||||||
_hide_all_tools()
|
_disable_all_tools()
|
||||||
convert_item()
|
convert_item()
|
||||||
|
|||||||
Reference in New Issue
Block a user