Refit the tourist backpack and photo prop
Full build / Import + headless tests (push) Successful in 38s
Full build / Full desktop build + optional release (push) Skipped

Hide the tourist photo-pose bag outside camera poses, flatten the backpack straps onto the chest, rebuild the gear GLB/AO and publish the before/after NPC sheet.
This commit is contained in:
zwitschi committed 2026-11-02 18:39:03 +01:00
1 parent e7ee177c31
commit 7c1a4bfd69
14 files changed
+108 -45

No files matched your search

+17 -1
View File
@@ -114,6 +114,7 @@ var _focus_circle: MeshInstance3D = null
var _name_tag: Label3D = null
## Theater props and limbs for the idle poses (ADR-0010 rig).
var _photo_prop: MeshInstance3D = null
var _photo_flash: MeshInstance3D = null
var _sign_prop: MeshInstance3D = null
var _legs: Array[Node3D] = []
var _arms: Array[Node3D] = []
@@ -891,8 +892,11 @@ func _add_props(npc_type: int) -> void:
match npc_type:
Rules.NpcType.INFLUENCER:
_photo_prop = _add_box_prop(_rig, Vector3(0.16, 0.1, 0.09), Vector3(0.3, chest_y, 0.22), Color(0.1, 0.1, 0.1))
_photo_prop.name = "PhotoProp"
_photo_prop.visible = false
_photo_prop_base_y = _photo_prop.position.y
_add_box_prop(_rig, Vector3(0.05, 0.05, 0.06), Vector3(0.34, chest_y + 0.06, 0.30), Color(0.4, 0.7, 1.0))
_photo_flash = _add_box_prop(_rig, Vector3(0.05, 0.05, 0.06), Vector3(0.34, chest_y + 0.06, 0.30), Color(0.4, 0.7, 1.0))
_photo_flash.visible = false
Rules.NpcType.DELIVERY:
_add_box_prop(_rig, Vector3(0.34, 0.26, 0.28), Vector3(0.0, 1.02, 0.3), Color(0.55, 0.4, 0.25))
Rules.NpcType.PERFORMER:
@@ -917,6 +921,8 @@ func _add_props(npc_type: int) -> void:
_sign_prop_base_y = _sign_prop.position.y
Rules.NpcType.TOURIST:
_photo_prop = _add_box_prop(_rig, Vector3(0.3, 0.36, 0.14), Vector3(-0.34, 1.15, -0.18), Color(0.25, 0.3, 0.45))
_photo_prop.name = "PhotoProp"
_photo_prop.visible = false
_photo_prop_base_y = _photo_prop.position.y
Rules.NpcType.CONFUSED_VISITOR:
_add_box_prop(_rig, Vector3(0.3, 0.05, 0.34), Vector3(0, 0.92, 0.06), Color(0.9, 0.88, 0.8))
@@ -1042,6 +1048,12 @@ static func prop_lift_for_pose(pose: String, phase: float) -> float:
return 0.0
return maxf(0.0, sin(phase * 1.7)) * 0.16
## The tourist's camera bag and the influencer's chest camera are only part of
## the silhouette while the character is actually taking photos. Keeping them
## hidden at other times prevents the tourist from reading as two backpacks.
static func photo_prop_visible_for_pose(pose: String) -> bool:
return pose == "photo" or pose == "film"
## Opposite arm/leg swing for the walk cycle. `side` is 0 or 1; pure so the gait
## can be checked without a scene tree.
static func limb_swing(phase: float, side: int, amplitude: float) -> float:
@@ -1060,6 +1072,10 @@ func _animate(delta: float) -> void:
var pose := theater_pose()
var escalation: int = npc.highest_escalation_received if npc != null else 0
var crouch := crouch_for_pose(pose)
if _photo_prop:
_photo_prop.visible = photo_prop_visible_for_pose(pose)
if _photo_flash:
_photo_flash.visible = photo_prop_visible_for_pose(pose)
if speed > 0.3:
_idle_t = 0.0
_bob_phase += delta * (6.0 + speed * 1.7)
+8
View File
@@ -47,6 +47,14 @@ func test_hand_items_are_known_and_deterministic() -> bool:
Rules.NpcType.TOURIST, seed_value * 31)
return TestUtils.check(ok, "hand items stay in the catalogue and are deterministic")
func test_photo_prop_only_shows_for_camera_poses() -> bool:
return TestUtils.check(
not NpcAvatar.photo_prop_visible_for_pose("idle")
and not NpcAvatar.photo_prop_visible_for_pose("perform")
and NpcAvatar.photo_prop_visible_for_pose("photo")
and NpcAvatar.photo_prop_visible_for_pose("film"),
"camera bag prop is hidden outside photo/film poses")
func test_idle_styles_are_known() -> bool:
var allowed := ["phone", "crossed", "look", "clipboard", "breathe"]
var ok := true