diff --git a/godot/scripts/Tables.gd b/godot/scripts/Tables.gd index 919b681..1310921 100644 --- a/godot/scripts/Tables.gd +++ b/godot/scripts/Tables.gd @@ -10,12 +10,14 @@ class_name Tables ## table is authorable in minutes, tables can be diffed, and dev/probe_tables.gd can build ## every one of them headless and assert the playfield is sane. -const ORDER := ["neon", "grotto", "foundry"] +const ORDER := ["neon", "grotto", "foundry", "orbital", "thedig"] static func get_table(id: String) -> Dictionary: match id: "grotto": return grotto() "foundry": return foundry() + "orbital": return orbital() + "thedig": return thedig() return neon() static func next_id(id: String) -> String: @@ -217,3 +219,134 @@ static func foundry() -> Dictionary: }, "parts": parts, } + +# ================================================================ TABLE 4 +## ORBITAL — everything funnels to the centre. Two saucers flank a long central ramp, and +## the pops sit in a tight cluster at the top so a ball that gets up there RATTLES. +static func orbital() -> Dictionary: + var parts: Array = [] + parts.append({"kind": "flipper", "id": "flip_l", "at": Vector3(-0.060, 0.022, 0.420), + "side": -1, "length": 0.076, "limit_lo": -32.0, "limit_hi": 30.0, "torque": 7.5}) + parts.append({"kind": "flipper", "id": "flip_r", "at": Vector3(0.060, 0.022, 0.420), + "side": 1, "length": 0.076, "limit_lo": -30.0, "limit_hi": 32.0, "torque": 7.5}) + parts.append({"kind": "sling", "id": "sling_l", "at": Vector3(-0.124, 0.0, 0.340), + "dir": Vector3(1, 0, -0.6), "yaw": deg_to_rad(-34.0), "kick": 0.140, "points": 130}) + parts.append({"kind": "sling", "id": "sling_r", "at": Vector3(0.124, 0.0, 0.340), + "dir": Vector3(-1, 0, -0.6), "yaw": deg_to_rad(34.0), "kick": 0.140, "points": 130}) + parts.append({"kind": "post", "id": "op_l", "at": Vector3(-0.106, 0.0, 0.348)}) + parts.append({"kind": "post", "id": "op_r", "at": Vector3(0.106, 0.0, 0.348)}) + + # the long central ramp — the spine of the table + parts.append({"kind": "ramp", "id": "ramp_c", "at": Vector3(0.0, 0.0, 0.180), + "length": 0.34, "width": 0.054, "rise": 0.075, "points": 3500}) + # orbit lanes hugging the ramp, each with a spinner in it + parts.append({"kind": "spinner", "id": "orb_l", "at": Vector3(-0.148, 0.0, 0.120), + "yaw": deg_to_rad(14.0), "points": 130}) + parts.append({"kind": "spinner", "id": "orb_r", "at": Vector3(0.148, 0.0, 0.120), + "yaw": deg_to_rad(-14.0), "points": 130}) + parts.append({"kind": "wall", "id": "orb_gl", "at": Vector3(-0.196, 0.0, 0.120), + "size": Vector3(0.012, 0.05, 0.220), "yaw": deg_to_rad(5.0)}) + parts.append({"kind": "wall", "id": "orb_gr", "at": Vector3(0.196, 0.0, 0.120), + "size": Vector3(0.012, 0.05, 0.220), "yaw": deg_to_rad(-5.0)}) + + # twin saucers = the multiball locks, deliberately easy to SEE and hard to HIT + parts.append({"kind": "saucer", "id": "lock_l", "at": Vector3(-0.165, 0.0, -0.100), + "eject": Vector3(0.5, 0, 1), "hold": 1.0, "power": 0.21, "points": 3000}) + parts.append({"kind": "saucer", "id": "lock_r", "at": Vector3(0.165, 0.0, -0.100), + "eject": Vector3(-0.5, 0, 1), "hold": 1.0, "power": 0.21, "points": 3000}) + + # a tight four-pop cluster at the top: get up here and the ball goes mad + parts.append({"kind": "bumper", "id": "pop_n", "at": Vector3(0.0, 0.0, -0.400), "kick": 0.185, "points": 300}) + parts.append({"kind": "bumper", "id": "pop_s", "at": Vector3(0.0, 0.0, -0.280), "kick": 0.185, "points": 300}) + parts.append({"kind": "bumper", "id": "pop_w", "at": Vector3(-0.068, 0.0, -0.340), "kick": 0.185, "points": 300}) + parts.append({"kind": "bumper", "id": "pop_e", "at": Vector3(0.068, 0.0, -0.340), "kick": 0.185, "points": 300}) + + for i in 3: + parts.append({"kind": "drop", "id": "od_%d" % i, "bank": "airlock", + "at": Vector3(-0.058 + i * 0.058, 0.0, -0.185), "points": 550}) + var g := ["O", "R", "B"] + for i in g.size(): + parts.append({"kind": "rollover", "id": "olane_%d" % i, "glyph": g[i], + "at": Vector3(-0.090 + i * 0.090, 0.0, -0.470), "points": 175}) + + return { + "name": "ORBITAL", + "subtitle": "everything funnels to the centre.", + "width": 0.50, "length": 1.16, + "palette": { + "field": Color(0.04, 0.05, 0.12), "rail": Color(0.60, 0.66, 0.78), + "flipper": Color(0.30, 0.70, 1.00), "bumper": Color(0.95, 0.95, 0.55), + "sling": Color(0.60, 0.45, 0.95), "target": Color(0.90, 0.90, 0.95), + "drop": Color(0.40, 0.95, 0.85), "spinner": Color(0.85, 0.90, 1.00), + "lane": Color(0.55, 0.70, 1.00), "ramp": Color(0.75, 0.78, 0.88), + "wall": Color(0.10, 0.14, 0.26), "post": Color(0.88, 0.92, 1.00), + "saucer": Color(0.02, 0.03, 0.08), + }, + "parts": parts, + } + +# ================================================================ TABLE 5 +## THE DIG — the record shop table, and the one that belongs to this house. The bank is a +## row of crates you flip through, the ramp is the counter, and the spinner is a turntable. +## Same universe as the shop in Destroyulator; the theme is the only thing borrowed. +static func thedig() -> Dictionary: + var parts: Array = [] + parts.append({"kind": "flipper", "id": "flip_l", "at": Vector3(-0.063, 0.022, 0.405), + "side": -1, "length": 0.080, "limit_lo": -31.0, "limit_hi": 31.0, "torque": 7.2}) + parts.append({"kind": "flipper", "id": "flip_r", "at": Vector3(0.063, 0.022, 0.405), + "side": 1, "length": 0.080, "limit_lo": -31.0, "limit_hi": 31.0, "torque": 7.2}) + parts.append({"kind": "sling", "id": "sling_l", "at": Vector3(-0.128, 0.0, 0.325), + "dir": Vector3(1, 0, -0.55), "yaw": deg_to_rad(-33.0), "kick": 0.138, "points": 125}) + parts.append({"kind": "sling", "id": "sling_r", "at": Vector3(0.128, 0.0, 0.325), + "dir": Vector3(-1, 0, -0.55), "yaw": deg_to_rad(33.0), "kick": 0.138, "points": 125}) + parts.append({"kind": "post", "id": "dp_l", "at": Vector3(-0.110, 0.0, 0.335)}) + parts.append({"kind": "post", "id": "dp_r", "at": Vector3(0.110, 0.0, 0.335)}) + + # THE CRATES: a six-bank you flip through one sleeve at a time. Clearing it is + # "finding the record", which is the entire fantasy of a record shop. + for i in 6: + parts.append({"kind": "drop", "id": "crate_%d" % i, "bank": "crates", + "at": Vector3(-0.140 + i * 0.056, 0.0, 0.070), "points": 450}) + + # the turntable: a spinner you can whip, dead centre + parts.append({"kind": "spinner", "id": "deck", "at": Vector3(0.0, 0.0, -0.020), + "points": 160}) + # the counter — a ramp up to the register + parts.append({"kind": "ramp", "id": "counter", "at": Vector3(-0.130, 0.0, 0.200), + "yaw": deg_to_rad(15.0), "length": 0.28, "width": 0.050, "rise": 0.062, + "points": 2200}) + # listening booth: capture the ball, hold it a good long while + parts.append({"kind": "saucer", "id": "booth", "at": Vector3(0.160, 0.0, -0.150), + "eject": Vector3(-0.5, 0, 1), "hold": 1.4, "power": 0.22, "points": 4500}) + + # the wall of rare sleeves — a target array that pays + for i in 4: + parts.append({"kind": "target", "id": "rare_%d" % i, + "at": Vector3(-0.175 + i * 0.030, 0.0, -0.250), "yaw": deg_to_rad(18.0), + "width": 0.026, "points": 400}) + parts.append({"kind": "bumper", "id": "pop_a", "at": Vector3(0.080, 0.0, -0.330), + "kick": 0.170, "points": 275}) + parts.append({"kind": "bumper", "id": "pop_b", "at": Vector3(0.150, 0.0, -0.395), + "kick": 0.170, "points": 275}) + parts.append({"kind": "bumper", "id": "pop_c", "at": Vector3(0.010, 0.0, -0.400), + "kick": 0.170, "points": 275}) + var g := ["D", "I", "G"] + for i in g.size(): + parts.append({"kind": "rollover", "id": "dlane_%d" % i, "glyph": g[i], + "at": Vector3(-0.100 + i * 0.090, 0.0, -0.455), "points": 180}) + + return { + "name": "THE DIG", + "subtitle": "flip the crates. find the record.", + "width": 0.52, "length": 1.12, + "palette": { + "field": Color(0.14, 0.07, 0.13), "rail": Color(0.58, 0.55, 0.60), + "flipper": Color(1.00, 0.36, 0.62), "bumper": Color(0.98, 0.80, 0.30), + "sling": Color(0.50, 0.85, 0.70), "target": Color(0.85, 0.60, 0.95), + "drop": Color(0.35, 0.65, 0.95), "spinner": Color(0.20, 0.20, 0.24), + "lane": Color(1.00, 0.50, 0.70), "ramp": Color(0.55, 0.38, 0.24), + "wall": Color(0.24, 0.12, 0.22), "post": Color(0.92, 0.88, 0.95), + "saucer": Color(0.08, 0.04, 0.08), + }, + "parts": parts, + }