P2 stone: stonecutter, cut stone, stone floors/walls/pillars/stairs/windows/doorway, hearth; wooden stairs, windows, posts, palisade and gate; stone support rules
This commit is contained in:
@@ -90,6 +90,22 @@ static func build(key: String) -> ArrayMesh:
|
||||
"charcoal_kiln": m = _kiln()
|
||||
"smelter": m = _smelter()
|
||||
"forge": m = _forge()
|
||||
"cut_stone": m = _cut_stone()
|
||||
"stonecutter": m = _stonecutter()
|
||||
"stone_floor": m = _stone_floor()
|
||||
"stone_wall": m = _stone_wall()
|
||||
"stone_pillar": m = _stone_pillar()
|
||||
"stone_stairs": m = _stairs(true)
|
||||
"stone_window": m = _stone_window()
|
||||
"stone_doorway": m = _stone_doorway(true)
|
||||
"stone_doorway_frame": m = _stone_doorway(false)
|
||||
"stone_hearth": m = _hearth()
|
||||
"wood_stairs": m = _stairs(false)
|
||||
"wood_window": m = _wood_window()
|
||||
"wood_pillar": m = _wood_pillar()
|
||||
"palisade": m = _palisade()
|
||||
"palisade_gate": m = _palisade_gate(true)
|
||||
"palisade_gate_frame": m = _palisade_gate(false)
|
||||
"berry_bush": m = _berry_bush(true)
|
||||
"berry_bush_bare": m = _berry_bush(false)
|
||||
_:
|
||||
@@ -697,3 +713,227 @@ static func _fish(col: Color, len: float, grilled: bool) -> ArrayMesh:
|
||||
for s in [-1.0, 1.0]:
|
||||
P._blob(st, Vector3(len * 0.75, len * 0.38, s * len * 0.11), Vector3.ONE * len * 0.06, n, 0.0, Color(0.05, 0.05, 0.05), r, 0)
|
||||
return P._commit(st)
|
||||
|
||||
# --- P2 stone building and wooden upgrades ---------------------------------------
|
||||
# Dimensions match the colliders in build_piece.gd (pillar, stairs, window,
|
||||
# palisade) or reuse the wall/floor/door ones.
|
||||
|
||||
const MORTAR := Color(0.36, 0.35, 0.33)
|
||||
const STONE_BLOCK := Color(0.62, 0.61, 0.58)
|
||||
|
||||
static func _block_col(r: RandomNumberGenerator) -> Color:
|
||||
var c := P._mul(STONE_BLOCK, r.randf_range(0.8, 1.08))
|
||||
return c.lerp(Color(0.6, 0.55, 0.47), r.randf() * 0.25) # some warmer stones
|
||||
|
||||
## Courses of staggered blocks filling x0..x1, y0..y1, `depth` thick, with a
|
||||
## mortar core behind them so the joints read dark.
|
||||
static func _blocks(st: SurfaceTool, r: RandomNumberGenerator, x0: float, x1: float, y0: float, y1: float,
|
||||
depth: float = 0.22, course: float = 0.33) -> void:
|
||||
if x1 - x0 < 0.02 or y1 - y0 < 0.02:
|
||||
return
|
||||
_box(st, Vector3((x0 + x1) * 0.5, (y0 + y1) * 0.5, 0), Vector3(x1 - x0, y1 - y0, depth - 0.04), MORTAR)
|
||||
var rows := maxi(roundi((y1 - y0) / course), 1)
|
||||
var h := (y1 - y0) / rows
|
||||
for i in range(rows):
|
||||
var y := y0 + h * (i + 0.5)
|
||||
var x := x0
|
||||
# Stagger: every other course starts with a half block (world-aligned
|
||||
# so neighbouring walls line up).
|
||||
var step := 0.5
|
||||
var next := x0 + (step * 0.5 if i % 2 == 1 else step)
|
||||
while x < x1 - 0.01:
|
||||
var e := minf(next, x1)
|
||||
_box(st, Vector3((x + e) * 0.5, y, 0), Vector3(e - x - 0.025, h - 0.025, depth), _block_col(r))
|
||||
x = e
|
||||
next = e + step * r.randf_range(0.8, 1.2)
|
||||
|
||||
static func _cut_stone() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(211)
|
||||
_box(st, Vector3(0, 0.08, 0), Vector3(0.3, 0.16, 0.2), _block_col(r))
|
||||
_box(st, Vector3(0.01, 0.161, 0), Vector3(0.26, 0.004, 0.16), P._mul(STONE_BLOCK, 1.1))
|
||||
return P._commit(st)
|
||||
|
||||
## A heavy bench with a block on it and a frame saw: the stonecutter.
|
||||
static func _stonecutter() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(213)
|
||||
_box(st, Vector3(0, 0.72, 0), Vector3(1.6, 0.12, 0.8), PLANK)
|
||||
for sx in [-0.7, 0.7]:
|
||||
for sz in [-0.32, 0.32]:
|
||||
_box(st, Vector3(sx, 0.33, sz), Vector3(0.14, 0.66, 0.14), PLANK_DARK)
|
||||
_box(st, Vector3(0, 0.2, 0), Vector3(1.4, 0.08, 0.64), PLANK_DARK)
|
||||
# Rough stone waiting on the shelf, a block being cut on top.
|
||||
for i in range(3):
|
||||
_box(st, Vector3(-0.45 + 0.42 * i, 0.32, 0.02), Vector3(0.3, 0.16, 0.24), _block_col(r), Basis(Vector3.UP, r.randf_range(-0.3, 0.3)))
|
||||
_box(st, Vector3(0.2, 0.92, 0), Vector3(0.6, 0.28, 0.4), _block_col(r))
|
||||
# Frame saw: two uprights, a cross bar and the iron blade in the cut.
|
||||
for sx in [-0.2, 0.62]:
|
||||
_box(st, Vector3(sx, 1.12, 0), Vector3(0.05, 0.5, 0.05), HANDLE)
|
||||
_box(st, Vector3(0.21, 1.36, 0), Vector3(0.9, 0.04, 0.04), HANDLE)
|
||||
_box(st, Vector3(0.21, 1.04, 0), Vector3(0.86, 0.06, 0.012), IRON_BRIGHT)
|
||||
# Chips and dust.
|
||||
for i in range(5):
|
||||
_box(st, Vector3(r.randf_range(-0.7, 0.7), 0.79, r.randf_range(-0.3, 0.3)), Vector3(0.05, 0.03, 0.04), STONE)
|
||||
return P._commit(st)
|
||||
|
||||
## 2 x 2 m flagstones, top at y = 0, on a 0.2 m bed.
|
||||
static func _stone_floor() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(217)
|
||||
_box(st, Vector3(0, -0.11, 0), Vector3(2.0, 0.18, 2.0), MORTAR)
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
var c := Vector3(-0.75 + 0.5 * i + r.randf_range(-0.02, 0.02), -0.03, -0.75 + 0.5 * j + r.randf_range(-0.02, 0.02))
|
||||
_box(st, c, Vector3(0.47, 0.06, 0.47) * Vector3(r.randf_range(0.95, 1.0), 1, r.randf_range(0.95, 1.0)), _block_col(r))
|
||||
return P._commit(st)
|
||||
|
||||
static func _stone_wall() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
_blocks(st, _rng(219), -1.0, 1.0, 0.0, 2.0)
|
||||
return P._commit(st)
|
||||
|
||||
## Square column with a base and a capital, 0.4 m.
|
||||
static func _stone_pillar() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(223)
|
||||
_box(st, Vector3(0, 1.0, 0), Vector3(0.32, 2.0, 0.32), MORTAR)
|
||||
for i in range(6):
|
||||
var y := 0.2 + (1.6 / 6.0) * (i + 0.5)
|
||||
_box(st, Vector3(0, y, 0), Vector3(0.36, 1.6 / 6.0 - 0.025, 0.36), _block_col(r), Basis(Vector3.UP, r.randf_range(-0.04, 0.04)))
|
||||
_box(st, Vector3(0, 0.1, 0), Vector3(0.44, 0.2, 0.44), _block_col(r))
|
||||
_box(st, Vector3(0, 1.9, 0), Vector3(0.44, 0.2, 0.44), _block_col(r))
|
||||
return P._commit(st)
|
||||
|
||||
static func _wood_pillar() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(227)
|
||||
_box(st, Vector3(0, 1.0, 0), Vector3(0.3, 2.0, 0.3), _board(r, BEAM))
|
||||
_box(st, Vector3(0, 1.94, 0), Vector3(0.4, 0.12, 0.4), BEAM)
|
||||
_box(st, Vector3(0, 0.06, 0), Vector3(0.38, 0.12, 0.38), BEAM)
|
||||
return P._commit(st)
|
||||
|
||||
## 8 steps climbing 2 m over 4 m toward -Z (the collider is the smooth ramp
|
||||
## through their noses). Stone is solid underneath; wood is treads on two
|
||||
## stringers.
|
||||
static func _stairs(stone: bool) -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(229 if stone else 231)
|
||||
var a := 0.4636476
|
||||
for i in range(8):
|
||||
var top := 0.25 * (i + 1) - 0.06
|
||||
var zc := -0.25 - 0.5 * i
|
||||
if stone:
|
||||
_box(st, Vector3(0, top * 0.5, zc), Vector3(2.0, top, 0.5), MORTAR)
|
||||
_box(st, Vector3(0, top - 0.05, zc + 0.01), Vector3(1.96, 0.1, 0.5), _block_col(r))
|
||||
else:
|
||||
_box(st, Vector3(0, top - 0.04, zc + 0.03), Vector3(1.7, 0.08, 0.46), _board(r))
|
||||
if not stone:
|
||||
var length := sqrt(20.0)
|
||||
for x in [-0.9, 0.9]:
|
||||
_box(st, Vector3(x, 0.92, -2.0), Vector3(0.12, 0.26, length), BEAM, Basis(Vector3.RIGHT, a))
|
||||
return P._commit(st)
|
||||
|
||||
## Wall with a 1 x 0.7 m opening 1 m up (x -0.5..0.5, y 1.0..1.7).
|
||||
static func _stone_window() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(233)
|
||||
_blocks(st, r, -1.0, 1.0, 0.0, 1.0)
|
||||
_blocks(st, r, -1.0, -0.5, 1.0, 1.7, 0.22, 0.35)
|
||||
_blocks(st, r, 0.5, 1.0, 1.0, 1.7, 0.22, 0.35)
|
||||
_blocks(st, r, -1.0, 1.0, 1.7, 2.0, 0.22, 0.3)
|
||||
_box(st, Vector3(0, 0.97, 0.03), Vector3(1.2, 0.07, 0.3), _block_col(r)) # sill
|
||||
_box(st, Vector3(0, 1.75, 0), Vector3(1.24, 0.12, 0.24), _block_col(r)) # lintel
|
||||
return P._commit(st)
|
||||
|
||||
static func _wood_window() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(237)
|
||||
_wall_body(st, r, -0.84, 0.84, 0.1, 1.0)
|
||||
_wall_body(st, r, -0.84, -0.5, 1.0, 1.7)
|
||||
_wall_body(st, r, 0.5, 0.84, 1.0, 1.7)
|
||||
_wall_body(st, r, -0.84, 0.84, 1.7, 1.9)
|
||||
for x in [-0.92, 0.92]:
|
||||
_box(st, Vector3(x, 1.0, 0), Vector3(0.16, 2.0, 0.2), BEAM)
|
||||
for y in [0.06, 1.94]:
|
||||
_box(st, Vector3(0, y, 0), Vector3(1.68, 0.12, 0.2), BEAM)
|
||||
# Frame, sill and a shutter swung open on each side (outside, +Z).
|
||||
_box(st, Vector3(0, 0.98, 0.02), Vector3(1.16, 0.06, 0.26), BEAM)
|
||||
_box(st, Vector3(0, 1.72, 0), Vector3(1.1, 0.06, 0.2), BEAM)
|
||||
for side in [-1.0, 1.0]:
|
||||
_box(st, Vector3(side * 0.52, 1.35, 0), Vector3(0.05, 0.72, 0.2), BEAM)
|
||||
_box(st, Vector3(side * 0.78, 1.35, 0.14), Vector3(0.48, 0.66, 0.04), _board(r, PLANK_DARK))
|
||||
_box(st, Vector3(0.0, 1.35, 0), Vector3(0.03, 0.7, 0.03), BEAM) # mullion
|
||||
return P._commit(st)
|
||||
|
||||
## Stone arch for a 1.1 x 1.9 m door (the wooden leaf is wood_door_panel).
|
||||
static func _stone_doorway(with_panel: bool) -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(239)
|
||||
_blocks(st, r, -1.0, -0.55, 0.0, 2.0)
|
||||
_blocks(st, r, 0.55, 1.0, 0.0, 2.0)
|
||||
_box(st, Vector3(0, 1.97, 0), Vector3(1.14, 0.06, 0.2), MORTAR)
|
||||
# Arch stones over the opening: a keystone and its neighbours.
|
||||
for i in range(5):
|
||||
var x := -0.44 + 0.22 * i
|
||||
var h := 0.16 + (0.08 if i == 2 else 0.0)
|
||||
_box(st, Vector3(x, 1.9 + h * 0.5 - 0.02, 0), Vector3(0.2, h, 0.24), _block_col(r))
|
||||
if with_panel:
|
||||
_door_panel_into(st, Vector3(-0.54, 0, 0))
|
||||
return P._commit(st)
|
||||
|
||||
## Hearth: the fire sits at the origin in a stone firebox (back toward -Z),
|
||||
## under a hood and chimney.
|
||||
static func _hearth() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(241)
|
||||
_box(st, Vector3(0, 0.06, 0), Vector3(1.6, 0.12, 1.2), _block_col(r))
|
||||
_box(st, Vector3(0, 0.125, 0.05), Vector3(0.9, 0.01, 0.7), ASH)
|
||||
# Back and cheeks.
|
||||
_box(st, Vector3(0, 0.75, -0.48), Vector3(1.6, 1.3, 0.24), MORTAR)
|
||||
for i in range(4):
|
||||
_box(st, Vector3(-0.4 + 0.8 * (i % 2) + r.randf_range(-0.05, 0.05), 0.3 + 0.33 * i, -0.36), Vector3(0.7, 0.3, 0.02), _block_col(r))
|
||||
for sx in [-0.68, 0.68]:
|
||||
for i in range(4):
|
||||
_box(st, Vector3(sx, 0.28 + 0.3 * i, -0.05), Vector3(0.26, 0.28, 0.7), _block_col(r))
|
||||
# Mantel, hood and chimney.
|
||||
_box(st, Vector3(0, 1.3, 0.05), Vector3(1.7, 0.12, 0.8), _block_col(r))
|
||||
_box(st, Vector3(0, 1.55, -0.12), Vector3(1.3, 0.38, 0.6), MORTAR)
|
||||
_blocks(st, r, -0.3, 0.3, 1.74, 2.0, 0.42, 0.26)
|
||||
# A few logs in the fire.
|
||||
for i in range(3):
|
||||
var a := 0.6 * i - 0.6
|
||||
var d := Vector3(cos(a), 0, sin(a)) * 0.3
|
||||
P._cylinder(st, Vector3(0, 0.18, 0.05) - d, Vector3(0, 0.18, 0.05) + d, 0.06, 0.06, 5, P.BARK, r, -1.0, PLANK)
|
||||
return P._commit(st)
|
||||
|
||||
## 2 m of sharpened logs, 3 m tall.
|
||||
static func _palisade() -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(243)
|
||||
for i in range(5):
|
||||
_stake(st, r, -0.8 + 0.4 * i, 0.0, 3.0)
|
||||
for y in [0.7, 2.1]:
|
||||
_box(st, Vector3(0, y, -0.2), Vector3(2.0, 0.14, 0.08), BEAM)
|
||||
return P._commit(st)
|
||||
|
||||
static func _stake(st: SurfaceTool, r: RandomNumberGenerator, x: float, y0: float, top: float) -> void:
|
||||
var h := top - r.randf_range(0.0, 0.18)
|
||||
var rad := r.randf_range(0.16, 0.19)
|
||||
P._cylinder(st, Vector3(x, y0, 0), Vector3(x, h - 0.35, 0), rad, rad * 0.95, 7, P.BARK, r)
|
||||
P._cylinder(st, Vector3(x, h - 0.35, 0), Vector3(x, h, 0), rad * 0.95, 0.02, 7, P.WOOD, r)
|
||||
|
||||
## Palisade gate: stakes either side of a 1.1 x 1.9 m opening, more above it.
|
||||
static func _palisade_gate(with_panel: bool) -> ArrayMesh:
|
||||
var st := P._begin()
|
||||
var r := _rng(247)
|
||||
for x in [-0.8, 0.8]:
|
||||
_stake(st, r, x, 0.0, 3.0)
|
||||
for x in [-0.36, 0.0, 0.36]:
|
||||
_stake(st, r, x, 1.95, 3.0)
|
||||
for x in [-0.62, 0.62]:
|
||||
_box(st, Vector3(x, 0.98, 0), Vector3(0.12, 1.96, 0.2), BEAM)
|
||||
_box(st, Vector3(0, 1.98, 0), Vector3(1.4, 0.12, 0.24), BEAM)
|
||||
if with_panel:
|
||||
_door_panel_into(st, Vector3(-0.54, 0, 0))
|
||||
return P._commit(st)
|
||||
|
||||
Reference in New Issue
Block a user