Tutorial: Old Tam's hut outline beside the fire, pieces snap into it

This commit is contained in:
Paul Bailey
2026-11-05 15:01:59 +00:00
parent f93ebe1bea
commit dbcc6f6e59
6 changed files with 157 additions and 8 deletions

View File

@@ -120,6 +120,7 @@ func start(w: Node3D, from_saved: Dictionary = {}) -> void:
_enter()
func stop() -> void:
_clear_outline()
active = false
world = null
@@ -145,7 +146,16 @@ func _enter() -> void:
_check() # (done early? it ticks straight away)
const DemoWolf = preload("res://scripts/creatures/tutorial_wolf.gd")
const HutOutline = preload("res://scripts/ui/hut_outline.gd")
var demo_wolf: Node3D = null
var outline: Node3D = null ## the hut outline, while the hut step is on
func _clear_outline() -> void:
if outline != null and is_instance_valid(outline):
outline.queue_free()
outline = null
if world != null and is_instance_valid(world):
world.build.outline = null
## A step's set-up: the clock, some animals, the demo wolf.
func _setup(su: Dictionary) -> void:
@@ -168,6 +178,28 @@ func _setup(su: Dictionary) -> void:
if world.terrain.inside_boundary(at.x, at.z, 4.0) and world.terrain.sample_height(at.x, at.z) > world.terrain.water_level + 0.3:
world.creatures.spawn(String(sp.kind), at)
break
if String(su.get("outline", "")) == "hut":
_clear_outline()
# A good spot a few metres from your fire (or from you).
# Search out from the fire in small rings, starting far enough out
# that the hut (3 m half-width) leaves the fire 2 m clear of its walls.
var near: Vector3 = world.player.global_position
var step := 4.0
var min_dist := 0.0
for pc in world.all_pieces():
if pc.item_id == "campfire" and pc.global_position.distance_to(near) < 30.0:
near = pc.global_position
step = 1.5
min_dist = 5.0
var site: Vector3 = world.build.debug_find_site(near, 3.0, step, min_dist)
var yaw: float = world.player.rotation.y
var b := Basis(Vector3.UP, yaw)
var first: Transform3D = world.build._free_xf("floor", site + b * Vector3(-1, 0, -1), yaw, true)
outline = HutOutline.new()
outline.name = "HutOutline"
world.add_child(outline)
outline.setup(world, first)
world.build.outline = outline
if su.get("demo_wolf", false):
if demo_wolf != null and is_instance_valid(demo_wolf):
demo_wolf.queue_free()
@@ -200,6 +232,7 @@ func _check() -> void:
_advance()
func _advance() -> void:
_clear_outline() # (it was only for the step that's ending)
var s := current()
done.append(String(s.id))
step_done.emit(index, s)
@@ -349,6 +382,11 @@ func find_marker() -> Vector3:
for pc in world.all_pieces():
if pc.item_id == what.substr(6):
cands.append(pc)
elif what == "outline":
# Wherever the outline still has pieces to build: its middle.
if outline != null and is_instance_valid(outline):
return outline.center()
return Vector3.INF
elif what == "lake":
# The lake's shore, on your side of it.
var c: Vector2 = world.terrain.lake_center