ShitboxInfinity/levels/woolies_carpark/carpark.gd
type-two eb7c189c9f Gameplay systems + procedural Blender car fleet
Modes: Cruise / Crash Mode (60s damage dollars) / Race (3 laps, rubber-banded
rivals). Burnout loop: boost earned by drift, near miss, smash; takedowns refill
and grow the meter to 4x; hard crashes shed det_* panels and trigger Impact Time
slow-mo. Traffic follows the level RacePath frozen-kinematic and goes dynamic
when whacked. tools/build_cars.py builds six Aussie shitbox GLBs (profile
extrusion + detachable doors/mirrors/bumpers/bonnet/boot). Smoke test covers
all three modes headless.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:29:42 +10:00

55 lines
2.0 KiB
GDScript

extends Node3D
## ponytail: placeholder carpark built in code -- real levels arrive as level.glb from Blender
## and this whole folder becomes just the GLB + nothing else.
func _ready() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = 8
_box(Vector3(0, -0.5, 0), Vector3(240, 1, 160), Color(0.35, 0.35, 0.37)) # tarmac
for side in [-1, 1]: # kerb walls
_box(Vector3(0, 0.4, side * 79.0), Vector3(240, 0.8, 2), Color(0.6, 0.6, 0.6))
_box(Vector3(side * 119.0, 0.4, 0), Vector3(2, 0.8, 160), Color(0.6, 0.6, 0.6))
for row in 4: # rows of parked shitboxes, shuntable
for bay in 10:
if rng.randf() < 0.35:
continue
var pos := Vector3(-27.0 + bay * 6.0, 0.8, -30.0 + row * 18.0)
_box(pos, Vector3(1.9, 1.4, 4.4), Color.from_hsv(rng.randf(), 0.5, rng.randf_range(0.4, 0.9)), true)
for i in 6: # light poles
_box(Vector3(-30.0 + i * 12.0, 3.0, 8.0), Vector3(0.4, 6.0, 0.4), Color(0.3, 0.3, 0.3))
_race_path()
func _race_path() -> void:
# perimeter loop road around the parking rows -- race line + traffic route
var path := Path3D.new()
path.name = "RacePath"
var c := Curve3D.new()
var pts := [Vector3(45, 0, 55), Vector3(45, 0, -55), Vector3(-45, 0, -55), Vector3(-45, 0, 55)]
for i in pts.size() + 1:
var p: Vector3 = pts[i % pts.size()]
var to_prev: Vector3 = (pts[(i - 1 + pts.size()) % pts.size()] - p).normalized() * 12.0
var to_next: Vector3 = (pts[(i + 1) % pts.size()] - p).normalized() * 12.0
c.add_point(p, to_prev, to_next)
path.curve = c
add_child(path)
func _box(pos: Vector3, size: Vector3, color: Color, dynamic := false) -> void:
var body: PhysicsBody3D = RigidBody3D.new() if dynamic else StaticBody3D.new()
if dynamic:
body.mass = 300.0
var shape := CollisionShape3D.new()
var bs := BoxShape3D.new()
bs.size = size
shape.shape = bs
var mi := MeshInstance3D.new()
var bm := BoxMesh.new()
bm.size = size
var mat := StandardMaterial3D.new()
mat.albedo_color = color
bm.material = mat
mi.mesh = bm
body.add_child(shape)
body.add_child(mi)
body.position = pos
add_child(body)