Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
73ddd8c
Add the Rig Bay seam: stand, mech SKUs, stand pools and defines
Jackriip Nov 11, 2026
3f6faf4
Open the outfitter's mech showroom: three rig stands and work thresholds
Jackriip Nov 11, 2026
fa49953
Give Wick a work routine in the Rig Bay
Jackriip Nov 11, 2026
f2ae640
Sell mechs off the Rig Bay stands at Wick's
Jackriip Nov 11, 2026
ef0cb39
Rate whole exosuits and add exosuit and mech price bands
Jackriip Nov 11, 2026
854bd85
Test the Rig Bay stands, chains, hold and restock
Jackriip Nov 11, 2026
2d892e6
Don't count a crew's hits on its own new mech as aggression; add the …
Jackriip Nov 11, 2026
b080b80
Rebuild the Rig Bay as a mech showroom with a workshop and a central …
Jackriip Nov 11, 2026
f215fe0
Rig Bay stand: gantry, chains and blocking animations for release and…
Jackriip Nov 11, 2026
4611ec9
Fit Wick's routine to the new Rig Bay layout
Jackriip Nov 11, 2026
f9e2f47
Give the Rig Bay hold test keyless crew members
Jackriip Nov 11, 2026
53f4d51
Rig Bay stand: full build of the release and beam-in (lamps, flash, s…
Jackriip Nov 11, 2026
7674499
Merge branch 'feature/rig-bay-shop' into feature/rig-bay
Jackriip Nov 11, 2026
0fd2cbe
Merge branch 'feature/rig-bay-wick' into feature/rig-bay
Jackriip Nov 11, 2026
a227100
Merge branch 'feature/rig-bay-anim' into feature/rig-bay
Jackriip Nov 11, 2026
350a53b
Rig Bay integration: wait out stand animations in tests, keep chains …
Jackriip Nov 11, 2026
714d73f
Rig Bay: turn the stand lamps on the client in step with the animatio…
Jackriip Nov 11, 2026
4a64367
Rig Bay: Wick only works on a mech once it hangs on its stand
Jackriip Nov 11, 2026
3174e81
Rig Bay: add a showpiece stand that sells one super mech a round
Jackriip Nov 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -6733,6 +6733,7 @@
#include "voidcrew\_DEFINES\overmap_zones.dm"
#include "voidcrew\_DEFINES\planet_defines.dm"
#include "voidcrew\_DEFINES\player_outposts.dm"
#include "voidcrew\_DEFINES\rig_bay.dm"
#include "voidcrew\_DEFINES\ship_combat.dm"
#include "voidcrew\_DEFINES\ship_construction.dm"
#include "voidcrew\_DEFINES\ship_defines.dm"
Expand Down Expand Up @@ -7739,6 +7740,13 @@
#include "voidcrew\modules\trade\favor_uniques\outfitter.dm"
#include "voidcrew\modules\trade\favor_uniques\pike.dm"
#include "voidcrew\modules\trade\favor_uniques\vex.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_clamp.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_mecha.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_shop.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_skus.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_stand.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_stand_visuals.dm"
#include "voidcrew\modules\trade\rig_bay\rig_bay_wick.dm"
#include "voidcrew\modules\transporter\_transporter.dm"
#include "voidcrew\modules\transporter\transporter_console.dm"
#include "voidcrew\modules\transporter\transporter_designs.dm"
Expand Down
4 changes: 3 additions & 1 deletion tools/ci/check_gear_ratings.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ def find_problems(static, docs, policy, exceptions, exceptions_text=""):
voucher_value = dm.eval("VOUCHER_CREDIT_VALUE")
if not isinstance(voucher_value, (int, float)):
raise ValueError(f"VOUCHER_CREDIT_VALUE should be a plain number, not {voucher_value!r}")
paths = sorted({*dm.compiled_types("/obj/item"), *(path for path in static.routed_types() if path.startswith("/obj/item"))})
# Whole mechs are vehicles, not items, but the Rig Bay sells them like gear.
roots = ("/obj/item", "/obj/vehicle/sealed/mecha")
paths = sorted({*(path for root in roots for path in dm.compiled_types(root)), *(path for path in static.routed_types() if path.startswith(roots))})
ordinary = [row["path"] for row in policy.get("ordinary_ingredients") or []]
steps, covers = reachable(static, paths, checked, ordinary)
entries = {}
Expand Down
4 changes: 3 additions & 1 deletion tools/gear_catalog/categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
('/obj/item/ammo_casing', 'ammo', '/obj/item/ammo_casing'),
('/obj/item/mecha_ammo', 'mech', '/obj/item/mecha_ammo'),
('/obj/item/mecha_parts', 'mech', '/obj/item/mecha_parts'),
# Whole exosuits, sold off the Rig Bay stands. Not items, so the checker adds their paths itself.
('/obj/vehicle/sealed/mecha', 'exosuits', '/obj/vehicle/sealed/mecha'),
('/obj/item/clothing/glasses', 'eyewear', '/obj/item/clothing/glasses'),
('/obj/item/clothing/head', 'headwear', '/obj/item/clothing/head'),
('/obj/item/clothing/suit', 'suits', '/obj/item/clothing/suit'),
Expand Down Expand Up @@ -314,7 +316,7 @@
GEAR_CATEGORIES = frozenset({
'guns', 'gun_parts', 'eyewear', 'melee', 'shields', 'explosives', 'headwear', 'suits', 'uniforms', 'gloves', 'shoes', 'masks',
'neckwear', 'accessories', 'earwear', 'modsuits', 'implants', 'cyberware', 'organs', 'ammo', 'tools', 'toolboxes', 'medical',
'belts', 'backpacks', 'storage', 'mech', 'robotics', 'comms', 'ship_parts', 'relics',
'belts', 'backpacks', 'storage', 'mech', 'exosuits', 'robotics', 'comms', 'ship_parts', 'relics',
})
NOT_GEAR_CATEGORIES = frozenset({
'food', 'botany', 'paper', 'decor', 'toys', 'trash', 'boards', 'machine_parts', 'stacks', 'circuits', 'slimes', 'genetics', 'cards',
Expand Down
24 changes: 24 additions & 0 deletions tools/gear_catalog/exceptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -538,5 +538,29 @@
"rule": "above_on_route",
"route": "/datum/design/beamrifle",
"reason": "Deliberate: reputation 22 and six anomaly cores are a real gate, so the Event Horizon stays craftable."
},
{
"path": "/obj/vehicle/sealed/mecha/honker",
"rule": "price_out_of_band",
"route": "/datum/shop_sku/rig_bay_mech/showpiece/honker",
"reason": "Deliberate: owner's showpiece stand pricing. Every super mech sells at 25,000 to 31,000 credits plus 3 vouchers, one a round, whatever its tier."
},
{
"path": "/obj/vehicle/sealed/mecha/justice/loaded",
"rule": "above_on_route",
"route": "/datum/shop_sku/rig_bay_mech/showpiece/justice",
"reason": "Deliberate: owner's decision to sell the super mechs as they are on the showpiece stand, one a round for the server and one per crew, at advanced reputation."
},
{
"path": "/obj/vehicle/sealed/mecha/marauder/loaded",
"rule": "above_on_route",
"route": "/datum/shop_sku/rig_bay_mech/showpiece/marauder",
"reason": "Deliberate: owner's decision to sell the super mechs as they are on the showpiece stand, one a round for the server and one per crew, at advanced reputation."
},
{
"path": "/obj/vehicle/sealed/mecha/ripley/paddy/preset",
"rule": "price_out_of_band",
"route": "/datum/shop_sku/rig_bay_mech/showpiece/paddy",
"reason": "Deliberate: owner's showpiece stand pricing. Every super mech sells at 25,000 to 31,000 credits plus 3 vouchers, one a round, whatever its tier."
}
]
28 changes: 28 additions & 0 deletions tools/gear_catalog/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@
4000
]
},
"exosuits": {
"green": [
3000,
9000
],
"red": [
15000,
35000
],
"yellow": [
8000,
18000
]
},
"explosives": {
"green": [
100,
Expand Down Expand Up @@ -162,6 +176,20 @@
1200
]
},
"mech": {
"green": [
100,
3000
],
"red": [
500,
12000
],
"yellow": [
100,
7000
]
},
"melee": {
"green": [
200,
Expand Down
136 changes: 136 additions & 0 deletions tools/gear_catalog/ratings/exosuits.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
{
"category": "exosuits",
"groups": [
"combat exosuits",
"working and medical exosuits"
],
"items": {
"/obj/vehicle/sealed/mecha/clarke": {
"confidence": "high",
"group": "working and medical exosuits",
"hash": "",
"name": "Clarke",
"rank": 1,
"reason": "Tracked mining mech with an ore box manager and sleeper, sold with a drill and mining scanner. Rated as its chassis.",
"tier": "green"
},
"/obj/vehicle/sealed/mecha/durand": {
"confidence": "medium",
"group": "combat exosuits",
"hash": "",
"name": "Durand",
"rank": 3,
"reason": "Heavy combat mech with a frontal shield, sold bare. Rated as its chassis.",
"tier": "red"
},
"/obj/vehicle/sealed/mecha/gygax": {
"confidence": "medium",
"group": "combat exosuits",
"hash": "",
"name": "Gygax",
"rank": 5,
"reason": "The entry combat mech, sold bare: 250 health, 20 bullet and 30 laser armor, with an overclock for speed. Rated as its chassis.",
"tier": "yellow"
},
"/obj/vehicle/sealed/mecha/honker": {
"confidence": "medium",
"group": "combat exosuits",
"hash": "",
"name": "H.O.N.K",
"rank": 7,
"reason": "Clown mech, sold bare: 140 health and no armor, weaker than a Gygax. It takes any combat gun, but the Honker that makes it dangerous is not included.",
"tier": "yellow"
},
"/obj/vehicle/sealed/mecha/justice/loaded": {
"confidence": "high",
"group": "combat exosuits",
"hash": "",
"name": "Justice",
"rank": 1,
"reason": "Sold with its stock thrusters, radio, air tank and top parts. Reflects every shot while its shields are up, cloaks, charges and beheads anyone downed. Rated as its chassis; the stock syndicate lock is removed at sale.",
"tier": "above"
},
"/obj/vehicle/sealed/mecha/marauder/loaded": {
"confidence": "high",
"group": "combat exosuits",
"hash": "",
"name": "Marauder",
"rank": 1,
"reason": "Sold with its stock pulse rifle, missile rack, thrusters, smoke and top parts: 500 health, 60 bullet and laser armor and 70 melee. Well past the Durand in every number.",
"tier": "above"
},
"/obj/vehicle/sealed/mecha/odysseus": {
"confidence": "high",
"group": "working and medical exosuits",
"hash": "",
"name": "Odysseus",
"rank": 4,
"reason": "Medical mech, sold with a mounted sleeper. Rated as its chassis.",
"tier": "green"
},
"/obj/vehicle/sealed/mecha/phazon": {
"confidence": "medium",
"group": "combat exosuits",
"hash": "",
"name": "Phazon",
"rank": 2,
"reason": "Sold bare: 200 health, 30 armor all round, walks through walls and switches damage type. Rated as its chassis.",
"tier": "red"
},
"/obj/vehicle/sealed/mecha/ripley": {
"confidence": "high",
"group": "working and medical exosuits",
"hash": "",
"name": "APLU MK-I \"Ripley\"",
"rank": 3,
"reason": "The open-cabin cargo and mining mech, sold with a hydraulic clamp and a drill. Rated as its chassis.",
"tier": "green"
},
"/obj/vehicle/sealed/mecha/ripley/mk2": {
"confidence": "high",
"group": "working and medical exosuits",
"hash": "",
"name": "APLU MK-II \"Ripley\"",
"rank": 2,
"reason": "The enclosed Ripley, sold with a hydraulic clamp and a drill. Rated as the MK-II conversion kit on a Ripley.",
"tier": "green"
},
"/obj/vehicle/sealed/mecha/ripley/paddy/preset": {
"confidence": "medium",
"group": "combat exosuits",
"hash": "",
"name": "APLU \"Paddy\"",
"rank": 6,
"reason": "Security Ripley sold with its stock disabler, cuffing claw and four-person cell: 250 health, faster than a Gygax, open cage. Takes people out of a fight rather than killing them. The stock security lock is removed at sale.",
"tier": "yellow"
},
"/obj/vehicle/sealed/mecha/savannah_ivanov": {
"confidence": "high",
"group": "combat exosuits",
"hash": "",
"name": "Savannah-Ivanov",
"rank": 1,
"reason": "Sold bare: 450 health, 40 bullet armor, leaps and flattens walls and anyone downed where it lands, and calls a missile strike. Needs two pilots. Rated as its chassis.",
"tier": "red"
}
},
"method": "A whole mech rates as its chassis does in mech.json: how many vested men it takes to match its health and armor. Its tg default kit and the stand's working kit are tools, not weapons; arms are sold and rated separately.",
"unrated": {
"/obj/vehicle/sealed/mecha": "abstract",
"/obj/vehicle/sealed/mecha/gygax/dark": "no route",
"/obj/vehicle/sealed/mecha/honker/dark": "no route",
"/obj/vehicle/sealed/mecha/honker/dark/loaded": "no route",
"/obj/vehicle/sealed/mecha/justice": "no route",
"/obj/vehicle/sealed/mecha/marauder": "no route",
"/obj/vehicle/sealed/mecha/marauder/mauler": "no route",
"/obj/vehicle/sealed/mecha/marauder/mauler/loaded": "no route",
"/obj/vehicle/sealed/mecha/marauder/seraph": "no route",
"/obj/vehicle/sealed/mecha/reticence": "no route",
"/obj/vehicle/sealed/mecha/reticence/loaded": "no route",
"/obj/vehicle/sealed/mecha/ripley/cargo": "no route",
"/obj/vehicle/sealed/mecha/ripley/deathripley": "no route",
"/obj/vehicle/sealed/mecha/ripley/deathripley/real": "no route",
"/obj/vehicle/sealed/mecha/ripley/mining": "no route",
"/obj/vehicle/sealed/mecha/ripley/paddy": "no route"
}
}
32 changes: 32 additions & 0 deletions voidcrew/_DEFINES/rig_bay.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// The Rig Bay: exosuits sold off chained stands at Wick's outfitter (voidcrew/modules/trade/rig_bay/).

/// On a display mech while it hangs from its stand's chains (set and cleared by the clamp component).
#define TRAIT_RIG_BAY_CLAMPED "rig_bay_clamped"
/// Trait source for TRAIT_RIG_BAY_CLAMPED.
#define RIG_BAY_TRAIT "rig_bay"

/// Sent on a mech when a mob tries to climb in: (mob/entering). Hooked in rig_bay_mecha.dm.
#define COMSIG_MECHA_TRY_ENTER "mecha_try_enter"
/// Return from COMSIG_MECHA_TRY_ENTER to refuse the entry.
#define COMPONENT_MECHA_BLOCK_ENTER (1<<0)

/// Longest a sold mech stays locked to the buyer's crew while it is on outpost ground.
#define RIG_BAY_HOLD_TIME (20 MINUTES)
/// Pixels a chained mech hangs above its stand. Release lowers it back to 0.
#define RIG_BAY_HANG_LIFT 4
/// Shared per-crew purchase key for the showpiece stand's whole line (voidcrew_crew_record favor_unique_purchases).
#define RIG_BAY_SHOWPIECE_CAP "rig_bay_showpiece"
/// How often a due restock retries while something blocks the stand tile.
#define RIG_BAY_RETRY_DELAY (10 SECONDS)

// Stand states (/obj/structure/rig_bay_stand var/stand_state)
/// Nothing on the stand; waits for the next due convoy.
#define RIG_BAY_STAND_EMPTY "empty"
/// A mech is beaming in. Its SKU has stock 0 until the beam-in finishes.
#define RIG_BAY_STAND_ARRIVING "arriving"
/// A mech hangs on the stand for sale. Its SKU has stock 1.
#define RIG_BAY_STAND_CLAMPED "clamped"
/// A sold mech is being lowered. Its SKU has stock 0.
#define RIG_BAY_STAND_RELEASING "releasing"
/// A sold mech is down and free but hasn't left the stand tile yet. Restock skips the stand.
#define RIG_BAY_STAND_SOLD_ON_STAND "sold_on_stand"
Loading
Loading