Fleet expansion: ute, wagon, muscle coupe, microcar (34 cars)

Four new archetypes, all one spec dict each:
- HARDON WB UTE: builder grows ute=True support -- cab glass ends behind the
  seats, open tray with visible floor, bulkhead and a det_ tailgate. The most
  load-bearing vehicle shape in Australian culture.
- HARDON WAGGO HJ: the roof refuses to end; vinyl cap, tan over brown.
- FALCODORE 351 GT-OH-NO: black bonnet, ducktail, and per the reversed-stats
  rule the worst grip in the game (4.6) under the most bark (1710 kg).
- BUBBLA 600: a jellybean with delusions. 640 kg, grip 8.2, second-quickest
  car in the game behind the Excel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
m3ultra 2026-07-30 13:44:40 +10:00
parent 63c32928ee
commit d886188475
13 changed files with 267 additions and 1 deletions

BIN
cars/bubbla_600/car.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bga334jjf0qr"
path="res://.godot/imported/car.glb-fba78adb4b9130fb21f17c25cced4ff6.scn"
[deps]
source_file="res://cars/bubbla_600/car.glb"
dest_files=["res://.godot/imported/car.glb-fba78adb4b9130fb21f17c25cced4ff6.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1

View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
[resource]
script = ExtResource("1")
display_name = "BUBBLA 600"
model_path = "res://cars/bubbla_600/car.glb"
engine_power = 21.5
mass = 640.0
grip = 8.2
length = 3.02
width = 1.36

BIN
cars/falcodore_gtho/car.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://g4q84xm33g7g"
path="res://.godot/imported/car.glb-01b9fd83b05bbda1fdc40c5562994619.scn"
[deps]
source_file="res://cars/falcodore_gtho/car.glb"
dest_files=["res://.godot/imported/car.glb-01b9fd83b05bbda1fdc40c5562994619.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1

View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
[resource]
script = ExtResource("1")
display_name = "FALCODORE 351 GT-OH-NO"
model_path = "res://cars/falcodore_gtho/car.glb"
engine_power = 11.0
mass = 1710.0
grip = 4.6
length = 4.78
width = 1.90

BIN
cars/hardon_waggo/car.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bam2iy6k10043"
path="res://.godot/imported/car.glb-09cd7e118105e6df57c604e92df5480c.scn"
[deps]
source_file="res://cars/hardon_waggo/car.glb"
dest_files=["res://.godot/imported/car.glb-09cd7e118105e6df57c604e92df5480c.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1

View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
[resource]
script = ExtResource("1")
display_name = "HARDON WAGGO HJ"
model_path = "res://cars/hardon_waggo/car.glb"
engine_power = 12.5
mass = 1620.0
grip = 5.0
length = 4.88
width = 1.88

BIN
cars/hardon_wb_ute/car.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c6jbk3njlj4ud"
path="res://.godot/imported/car.glb-8a5e4c32a4b915df0a53b42dc911d644.scn"
[deps]
source_file="res://cars/hardon_wb_ute/car.glb"
dest_files=["res://.godot/imported/car.glb-8a5e4c32a4b915df0a53b42dc911d644.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1

View File

@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="CarStats" load_steps=2 format=3]
[ext_resource type="Script" path="res://src/car_stats.gd" id="1"]
[resource]
script = ExtResource("1")
display_name = "HARDON WB UTE"
model_path = "res://cars/hardon_wb_ute/car.glb"
engine_power = 13.5
mass = 1520.0
grip = 5.2
length = 4.92
width = 1.85

View File

@ -95,6 +95,31 @@ CARS = {
ohang_f=0.79, ohang_r=0.72, wheel=0.26,
paint=(0.92, 0.92, 0.89, 1), chrome_bumpers=False, hatch=True,
louvres=True, indicators=True, side_strip=True, wide_grille=True),
# The ute: cab ends behind the seats, everything aft is open tray. The
# single most load-bearing vehicle shape in Australian culture.
"hardon_wb_ute": dict(L=4.92, W=1.85, nose=0.66, belt=0.84, tail=0.80,
bonnet=1.50, boot=2.30, roof=1.38, roof_rear=0.18,
ohang_f=0.90, ohang_r=1.00, wheel=0.31,
paint=(0.93, 0.93, 0.90, 1), chrome_bumpers=True, hatch=False,
doors=2, ute=True, side_strip=True),
# wagon: the roof just refuses to end
"hardon_waggo": dict(L=4.88, W=1.88, nose=0.68, belt=0.85, tail=1.02,
bonnet=1.50, boot=0.50, roof=1.40, roof_rear=0.42,
ohang_f=0.90, ohang_r=1.00, wheel=0.31,
paint=(0.58, 0.44, 0.28, 1), chrome_bumpers=True, hatch=True,
roof_cap=(0.30, 0.22, 0.14, 1)),
# muscle coupe: all bark, worst grip in the game (reversed-stats rule)
"falcodore_gtho": dict(L=4.78, W=1.90, nose=0.62, belt=0.86, tail=0.82,
bonnet=1.55, boot=1.10, roof=1.30, roof_rear=0.70,
ohang_f=0.88, ohang_r=0.95, wheel=0.31,
paint=(0.55, 0.05, 0.07, 1), chrome_bumpers=False, hatch=False,
doors=2, bonnet_color=(0.05, 0.05, 0.05, 1), spoiler=True),
# microcar: a jellybean with delusions
"bubbla_600": dict(L=3.02, W=1.36, nose=0.52, belt=0.72, tail=0.86,
bonnet=0.62, boot=0.24, roof=1.30, roof_rear=0.55,
ohang_f=0.52, ohang_r=0.50, wheel=0.22,
paint=(0.55, 0.75, 0.88, 1), chrome_bumpers=True, hatch=True,
indicators=True),
# mokes use the open-tub builder: style="moke"
"mini_merk": dict(style="moke", L=3.05, W=1.42, nose=0.60, tub=0.66, canopy=1.38,
bonnet=0.85, ohang_f=0.55, ohang_r=0.55, wheel=0.26,
@ -327,13 +352,22 @@ def build(car_id, s):
parts.append(box("det_tailgate", (0, r - 0.03, (s["belt"] + s["roof"]) / 2 - 0.04),
(W * 0.72, 0.05, s["roof"] - s["belt"] - 0.22), paint_dk))
if s.get("ute"): # open tray behind the cab: visible floor + rip-off tailgate
tray_f = boot_y + 0.08 # tray starts where the cab glass ends
parts.append(box("tray_floor", (0, (tray_f + r + 0.15) / 2, s["belt"] - 0.28),
(W * 0.82, tray_f - r - 0.25, 0.05), paint_dk))
parts.append(box("tray_bulkhead", (0, tray_f, (s["belt"] - 0.28 + s["belt"]) / 2 + 0.06),
(W * 0.82, 0.05, 0.34), paint_dk))
parts.append(box("det_tailgate", (0, r + 0.10, s["belt"] - 0.12),
(W * 0.76, 0.05, 0.30), paint_dk))
# bonnet plate follows the bonnet slope; optional two-tone accent colour
bonnet_mat = material("bonnet", s["bonnet_color"], rough=0.35) if "bonnet_color" in s else paint_dk
by1, bz1, by2, bz2 = f - 0.35, nose2, ws_base + 0.03, s["belt"]
ang = math.atan2(bz2 - bz1, by2 - by1)
parts.append(box("det_bonnet", ((0, (by1 + by2) / 2, (bz1 + bz2) / 2 + 0.02)),
(W * 0.7, math.hypot(by2 - by1, bz2 - bz1) - 0.1, 0.04), bonnet_mat, rot_x=-ang))
if not s["hatch"] and not s.get("van"):
if not s["hatch"] and not s.get("van") and not s.get("ute"):
ty1, tz1, ty2, tz2 = boot_y - 0.03, s["belt"], r + 0.1, s["tail"]
ang = math.atan2(tz2 - tz1, ty2 - ty1)
parts.append(box("det_boot", ((0, (ty1 + ty2) / 2, (tz1 + tz2) / 2 + 0.02)),