75 lines
3.1 KiB
GDScript
75 lines
3.1 KiB
GDScript
extends Node3D
|
|
## The tutorial's hut outline (docs/TUTORIAL_DESIGN.md §2, step 17): a pale,
|
|
## see-through 4 x 4 m hut on a good spot near your fire, the same 20 pieces
|
|
## the game's own snapping makes (floors, walls and a door, roofs, gables).
|
|
## Each piece of the outline fades out once a real piece of that kind stands
|
|
## in its place. It's a suggestion: you can build anywhere.
|
|
|
|
## [item, offset from the first floor, yaw] (from build_system.gd
|
|
## debug_build_hut at yaw 0: the pieces snap to a fixed grid).
|
|
const LAYOUT := [
|
|
["wood_floor", Vector3(0, 0, 0), 0.0], ["wood_floor", Vector3(2, 0, 0), 0.0],
|
|
["wood_floor", Vector3(0, 0, 2), 0.0], ["wood_floor", Vector3(2, 0, 2), 0.0],
|
|
["wood_wall", Vector3(0, 0, -1), 0.0], ["wood_wall", Vector3(0, 0, 3), 0.0],
|
|
["wood_wall", Vector3(2, 0, -1), 0.0], ["wood_door", Vector3(2, 0, 3), 0.0],
|
|
["wood_wall", Vector3(3, 0, 0), PI * 0.5], ["wood_wall", Vector3(-1, 0, 0), PI * 0.5],
|
|
["wood_wall", Vector3(3, 0, 2), PI * 0.5], ["wood_wall", Vector3(-1, 0, 2), PI * 0.5],
|
|
["wood_roof", Vector3(0, 2, 3), 0.0], ["wood_roof", Vector3(0, 2, -1), PI],
|
|
["wood_roof", Vector3(2, 2, 3), 0.0], ["wood_roof", Vector3(2, 2, -1), PI],
|
|
["wood_gable", Vector3(-1, 2, 2), PI * 0.5], ["wood_gable", Vector3(-1, 2, 0), -PI * 0.5],
|
|
["wood_gable", Vector3(3, 2, 2), PI * 0.5], ["wood_gable", Vector3(3, 2, 0), -PI * 0.5],
|
|
]
|
|
const MATCH := 0.35 ## a real piece this close to a slot fills it
|
|
|
|
var world: Node3D
|
|
var origin := Transform3D() ## the first floor's place
|
|
var slots: Array = [] ## [item, Transform3D, MeshInstance3D]
|
|
var _check := 0.0
|
|
|
|
## Lays the outline out with its first floor at `xf` (from build_system's
|
|
## free placement, so it sits level on the ground).
|
|
func setup(w: Node3D, xf: Transform3D) -> void:
|
|
world = w
|
|
origin = xf
|
|
var m := StandardMaterial3D.new()
|
|
m.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
|
m.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
|
m.albedo_color = Color(0.6, 0.88, 1.0, 0.22)
|
|
m.cull_mode = BaseMaterial3D.CULL_DISABLED
|
|
m.no_depth_test = false
|
|
for e in LAYOUT:
|
|
var t := Transform3D(xf.basis * Basis(Vector3.UP, float(e[2])), xf * (e[1] as Vector3))
|
|
var mi := MeshInstance3D.new()
|
|
mi.mesh = ItemDB.mesh_for(String(e[0]))
|
|
mi.material_override = m
|
|
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
|
add_child(mi)
|
|
mi.global_transform = t
|
|
slots.append([String(e[0]), t, mi])
|
|
|
|
## The middle of the hut (the guide's marker points here).
|
|
func center() -> Vector3:
|
|
return origin * Vector3(1, 0, 1)
|
|
|
|
func _process(delta: float) -> void:
|
|
_check -= delta
|
|
if _check <= 0.0:
|
|
_check = 0.5
|
|
refresh()
|
|
|
|
## Hides each slot a real piece of its kind now fills. Returns how many are
|
|
## left to build.
|
|
func refresh() -> int:
|
|
var left := 0
|
|
var built: Array = world.build.build_pieces() if world != null else []
|
|
for s in slots:
|
|
var filled := false
|
|
for p in built:
|
|
if p.item_id == s[0] and (p as Node3D).global_position.distance_to((s[1] as Transform3D).origin) < MATCH:
|
|
filled = true
|
|
break
|
|
(s[2] as MeshInstance3D).visible = not filled
|
|
if not filled:
|
|
left += 1
|
|
return left
|