feat: modeled market stalls, mega wall ads, traffic lights, awnings
Final detail pass — no gameplay object remains a plain box: - Markets: box stalls replaced with modeled kit stalls (4 styles seeded), hidden box colliders keep the wood acoustics; hand carts at the market mouths; standing lanterns between stalls - Shrines: hanging lanterns on the stone pillars, wooden fences flanking the torii approach - Towers: giant mid-height wall ads on the street faces (the anime-city mega-ad look), on top of crown boards and corner columns - Storefront awnings (kit detail piece) on ~40% of buildings - Traffic signals at every central-avenue crossing, diagonal from the streetlights - Fantasy Town Kit (CC0) installed at assets/props/town Verified via street capture (wall-scale glyph ads, pharmacy signs, banner ads, stalls, carts); movement 11/11, smoke 0, acoustics PASSED. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
648872a16d
commit
c8a85586bd
@@ -177,6 +177,10 @@ func _kit_fill_side(front_x: float, dir: int, z0: float, z1: float, seed_id: Str
|
||||
var h: float = KIT_BUILDINGS[key].y * KIT_SCALE
|
||||
_kit_building(key, Vector3(front_x, 0, zc), yaw, "K%s_%d" % [seed_id, idx])
|
||||
var face_yaw := -90.0 if dir > 0 else 90.0 # ad quads face the street
|
||||
# Storefront awning on some buildings (kit detail piece)
|
||||
if _rng.randi() % 5 < 2:
|
||||
_kit_prop_path(KIT_DIR + "detail-awning-wide.glb",
|
||||
Vector3(front_x, 3.1, zc), face_yaw, minf(w * 0.9, 11.0))
|
||||
# Street-level posters plastered on the facade (graphic density)
|
||||
var posters := 1 + _rng.randi() % 3
|
||||
for p in posters:
|
||||
@@ -467,6 +471,10 @@ func _tower_block(c: Vector3, bx: int, bz: int) -> void:
|
||||
_box_static(c + Vector3(0, h + 2.4, 0), Vector3(0.6, 4.0, tw - 4.0), METAL, n + "_Crown", "metal")
|
||||
_ad_quad(c + Vector3(0.42, h + 2.4, 0), Vector2(tw - 4.6, 3.3), 90.0, _board_tex())
|
||||
_ad_quad(c + Vector3(-0.42, h + 2.4, 0), Vector2(tw - 4.6, 3.3), -90.0, _board_tex())
|
||||
# Giant mid-height wall ad on the tower's street faces (ZZZ-style)
|
||||
var wall_off := dims.z * s * 0.5 + 0.15
|
||||
_ad_quad(c + Vector3(0, FLOOR_H + dims.y * s * 0.45, -wall_off).rotated(Vector3.UP, deg_to_rad(yaw)),
|
||||
Vector2(tw * 0.55, tw * 0.8), yaw + 180.0, _poster_tex())
|
||||
_spawn_points.append(c + Vector3(0, FLOOR_H + 1.5, (BLOCK - 4.0) * 0.4))
|
||||
|
||||
|
||||
@@ -492,14 +500,18 @@ func _shrine_block(c: Vector3, bx: int, bz: int) -> void:
|
||||
# Hall with slide roof
|
||||
_box_static(c + Vector3(0, 2.0, -10.0), Vector3(12.0, 4.0, 8.0), WOOD.darkened(0.2), n + "_Hall", "wood")
|
||||
_ramp_static(c + Vector3(0, 4.9, -8.2), Vector3(13.0, 0.3, 5.6), Vector3(-24, 0, 0), VERMILION.darkened(0.35), n + "_Roof", "wood")
|
||||
# Stone lanterns + real modeled trees (trunk collider under each)
|
||||
# Stone + hanging lanterns, wooden gate fence, real modeled trees
|
||||
for i in 2:
|
||||
var lx := -8.0 + 16.0 * float(i)
|
||||
_box_static(c + Vector3(lx, 1.0, 8.0), Vector3(1.0, 2.0, 1.0), Color(0.55, 0.55, 0.52), n + "_Lant%d" % i, "brick")
|
||||
_kit_prop_path("res://assets/props/town/lantern.glb", c + Vector3(lx, 2.0, 8.0), 0.0, 2.6)
|
||||
_box_static(c + Vector3(lx, 1.6, -2.0), Vector3(0.8, 3.2, 0.8), TRUNK, n + "_Trunk%d" % i, "wood")
|
||||
_kit_prop_path("res://assets/props/nature/" + ["tree_detailed.glb", "tree_default.glb"][i % 2],
|
||||
c + Vector3(lx, 0, -2.0), _rng.randf_range(0.0, 360.0), 7.0)
|
||||
_kit_prop_path("res://assets/props/nature/tree_oak.glb", c + Vector3(0, 0, 2.0), _rng.randf_range(0.0, 360.0), 6.0)
|
||||
# Fence gate flanking the torii approach
|
||||
_kit_prop_path("res://assets/props/town/fence.glb", c + Vector3(-8.0, 0.15, tz - 0.2), 0.0, 3.0)
|
||||
_kit_prop_path("res://assets/props/town/fence.glb", c + Vector3(8.0, 0.15, tz - 0.2), 0.0, 3.0)
|
||||
_spawn_points.append(c + Vector3(0, 1.5, 12))
|
||||
|
||||
|
||||
@@ -513,17 +525,26 @@ func _market_block(c: Vector3, bx: int, bz: int) -> void:
|
||||
for pi in 3:
|
||||
var pp := c + Vector3(_rng.randf_range(-9.0, 9.0), 0.1, _rng.randf_range(-12.0, 12.0))
|
||||
_kit_prop(["detail-parasol-a", "detail-parasol-b"][pi % 2], pp, _rng.randf_range(0.0, 360.0), 6.0)
|
||||
# Stall rows down the middle
|
||||
# Modeled stall rows down the middle (kit stalls + carts, box colliders)
|
||||
var stall_keys := ["stall", "stall-green", "stall-red", "stall-bench"]
|
||||
for r in 2:
|
||||
var x := c.x + (-5.0 if r == 0 else 5.0)
|
||||
for s in 4:
|
||||
var z := c.z - 15.0 + float(s) * 10.0
|
||||
_box_static(Vector3(x, 1.0, z), Vector3(3.2, 2.0, 2.2), WOOD, "%s_S%d_%d" % [n, r, s], "wood")
|
||||
_box_static(Vector3(x, 2.35, z), Vector3(4.0, 0.16, 3.0),
|
||||
SIGN_COLORS[(r + s) % SIGN_COLORS.size()].darkened(0.5), "%s_C%d_%d" % [n, r, s], "wood")
|
||||
var body := _box_static(Vector3(x, 1.3, z), Vector3(3.4, 2.6, 3.0), WOOD, "%s_S%d_%d" % [n, r, s], "wood")
|
||||
for mi in body.find_children("*", "MeshInstance3D", false, false):
|
||||
mi.visible = false # collider only; the kit stall is the visual
|
||||
_kit_prop_path("res://assets/props/town/%s.glb" % stall_keys[(r * 4 + s + bx) % stall_keys.size()],
|
||||
Vector3(x, 0.02, z), 90.0 if r == 0 else -90.0, 3.2)
|
||||
if s % 2 == 0:
|
||||
_kit_prop_path("res://assets/props/town/lantern.glb",
|
||||
Vector3(x + 2.2, 0.02, z + 1.8), 0.0, 3.0)
|
||||
# Lantern string over each row
|
||||
for l in 6:
|
||||
_deco_box(Vector3(x, 3.6, c.z - 17.5 + float(l) * 7.0), Vector3(0.32, 0.45, 0.32), Color(1.0, 0.62, 0.25), true)
|
||||
# Hand carts at the market mouths
|
||||
_kit_prop_path("res://assets/props/town/cart.glb", c + Vector3(0, 0.02, 19.0), _rng.randf_range(-30, 30), 3.0)
|
||||
_kit_prop_path("res://assets/props/town/cart-high.glb", c + Vector3(2.0, 0.02, -19.0), _rng.randf_range(150, 210), 3.0)
|
||||
# Vending pair at the north entry
|
||||
for v in 2:
|
||||
_box_static(c + Vector3(-1.5 + 3.0 * float(v), 1.0, -BLOCK * 0.5 + 3.0), Vector3(1.1, 2.0, 0.9),
|
||||
@@ -700,6 +721,9 @@ func _build_avenues() -> void:
|
||||
_box_static(Vector3(x, 3.4, z), Vector3(0.26, 6.8, 0.26), METAL, "LampP_%d_%d" % [int(z), int(side)], "metal")
|
||||
_kit_prop_path("res://assets/props/roads/light-curved.glb",
|
||||
Vector3(x, 0, z), 90.0 if side > 0 else -90.0, lamp_scale)
|
||||
# Traffic signal on the opposite diagonal corner of each crossing
|
||||
_kit_prop_path("res://assets/props/roads/light-square-cross.glb",
|
||||
Vector3(x, 0, z - side * (ROAD_W * 0.5 + 0.8)), 90.0 if side > 0 else -90.0, lamp_scale * 0.8)
|
||||
for x in lines:
|
||||
if absf(x) < 1.0:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user