Odd-shaped houses (Gitea #7): roofs may run through other roofs (an L, a wing at an angle, roofs at different heights), but not inside an identical one, and nothing else goes through them; the guide explains growing a house
This commit is contained in:
@@ -162,6 +162,23 @@ func recompute() -> Array:
|
||||
|
||||
# --- placement --------------------------------------------------------------
|
||||
|
||||
## Roof pieces: these may pass through one another.
|
||||
const ROOF_KINDS := ["roof", "roof_ridge"]
|
||||
|
||||
## A roof piece of `kind` already sitting at `xf` (the same place, facing
|
||||
## the same way), so a second one isn't put inside the first.
|
||||
func _same_roof_at(kind: String, xf: Transform3D, exclude: Node) -> bool:
|
||||
for p in build_pieces():
|
||||
if p == exclude or p.kind != kind:
|
||||
continue
|
||||
var pxf: Transform3D = p.global_transform
|
||||
var facing: float = pxf.basis.z.normalized().dot(xf.basis.z.normalized())
|
||||
if kind == "roof_ridge":
|
||||
facing = absf(facing) # (it's the same both ways round)
|
||||
if pxf.origin.distance_to(xf.origin) < 0.15 and facing > 0.99:
|
||||
return true
|
||||
return false
|
||||
|
||||
## Why a building piece can't go at `xf` ("" = it can).
|
||||
func check(def: Dictionary, xf: Transform3D, exclude: Node = null) -> String:
|
||||
var kind: String = def.place.kind
|
||||
@@ -172,6 +189,9 @@ func check(def: Dictionary, xf: Transform3D, exclude: Node = null) -> String:
|
||||
if c.y < terrain.water_level + 0.1:
|
||||
return "Can't build in water"
|
||||
var space := world.get_world_3d().direct_space_state
|
||||
var roofy: bool = kind in ROOF_KINDS
|
||||
if roofy and _same_roof_at(kind, xf, exclude):
|
||||
return "There's already a roof there"
|
||||
for s in info.shapes:
|
||||
var made := BuildPiece.make_shape(s, OVERLAP_MARGIN)
|
||||
var q := PhysicsShapeQueryParameters3D.new()
|
||||
@@ -182,9 +202,13 @@ func check(def: Dictionary, xf: Transform3D, exclude: Node = null) -> String:
|
||||
if exclude != null:
|
||||
ex.append(exclude.get_rid())
|
||||
q.exclude = ex
|
||||
var hits := space.intersect_shape(q, 1)
|
||||
if not hits.is_empty():
|
||||
last_blocker = hits[0].collider
|
||||
var hits := space.intersect_shape(q, 8)
|
||||
for h in hits:
|
||||
# Roofs can run through other roofs (Gitea #7: an L, a wing at an
|
||||
# angle, roofs at odd heights), but nothing else.
|
||||
if roofy and h.collider != null and String(h.collider.get("kind")) in ROOF_KINDS:
|
||||
continue
|
||||
last_blocker = h.collider
|
||||
return "Something's in the way"
|
||||
var mat := BuildPiece.material_of(def)
|
||||
if support_for(kind, xf, exclude, mat) < MIN_SUPPORT:
|
||||
|
||||
Reference in New Issue
Block a user