Let shopkeepers roam safely around their shops

This commit is contained in:
Alexander Sellite 2026-09-01 17:30:27 -04:00
parent 134ece4a10
commit 76b4f19e4d
9 changed files with 990 additions and 25 deletions

View file

@ -100,6 +100,7 @@ func _validate_world_switching() -> void:
assert(world.get_fishing_shop() != null)
assert(world.get_player_storage() != null)
assert(not world.get_fishable_water_regions().is_empty())
_validate_starter_shopkeeper_roaming(world)
var starter_safe_points := world.get_safe_respawn_points()
assert(not starter_safe_points.is_empty())
var authored_safe_point: SafeRespawnPoint = starter_safe_points.back()
@ -117,6 +118,44 @@ func _validate_world_switching() -> void:
await process_frame
func _validate_starter_shopkeeper_roaming(world: TestWorld) -> void:
var starter_region := world.get_node(
"Regions/StarterIslandRegion"
) as StarterIslandRegion
assert(starter_region != null)
for interaction: FishingShopInteraction in [
starter_region.get_fishing_shop(),
starter_region.get_decor_shop(),
starter_region.get_rv_upgrade_shop(),
]:
assert(interaction != null)
# Presentation patrols are inactive on a dedicated/headless world until a
# local player is bound, so they cannot spend physics-query budget there.
assert(
not interaction.is_processing()
and not interaction.is_physics_processing()
)
var visual := interaction.get_node("../Shopkeeper") as Node3D
var visual_transform := visual.transform
var fixed_area_transform := interaction.global_transform
var route_found := false
for _attempt_cycle: int in 4:
interaction.call("_choose_roaming_destination")
if interaction.is_roaming_walking():
route_found = true
break
assert(route_found)
assert(not (interaction.get("_roaming_route") as Array).is_empty())
for _movement_slice: int in 24:
interaction.call("_advance_roaming_walk", 0.05)
if visual.position.distance_to(visual_transform.origin) > 0.01:
break
assert(visual.position.distance_to(visual_transform.origin) > 0.01)
assert(interaction.global_transform.is_equal_approx(fixed_area_transform))
visual.transform = visual_transform
interaction.call("_schedule_idle")
func _validate_world_boundary_clearance(world: TestWorld) -> void:
var active_region := world.get("_active_region") as WorldRegion
assert(active_region != null)