Files
Bubberstation/code/__DEFINES/shuttles.dm
Y0SH1M4S73R 013de1fb80 Custom Shuttle QOL tweaks (and a fix to a mild shuttle engine exploit) (#89774)
## About The Pull Request

This PR adds some tweaks to make custom shuttles a bit easier to use,
and more useful.

- The station blueprints can be used to allow/forbid custom shuttle
docking in station/custom areas. Custom areas allow shuttle docking by
default, while station areas (apart from the asteroid) forbid it.
- A station area that allows shuttle docking can have a shuttle
built/expanded in it, as long as the area's APC isn't contained within
the frame used to construct/expand the shuttle.
- A shuttle frame does not need to contain the entirety of a custom
area, unless that frame contains the area's APC. If the frame doesn't
contain the entirety of the custom area, that section of the frame
becomes part of the default area, instead of a separate area.
- Custom shuttles will go off into the sunset at the end of the round,
as long as they have a welded engine.
- I think I saw a bug that caused engines to contribute twice the
intended power to the attached shuttle, possibly creating an exploit in
the case where the engine was broken while welded. I fixed that.
- Custom shuttle docking computers can cross over to any z-level
adjacent to the shuttle's z-level (or vertically-connected z-levels,
because docking computers can traverse stacked z-levels freely). This is
based on the new `zlink_range` var on all shuttle docking consoles,
which can be var-edited to provide the same functionality.
- Shuttle engines constructed from circuits now link to shuttles without
needing to be unanchored and reanchored.

## Why It's Good For The Game

The tweaks to shuttle construction and docking serve to address several
gripes I heard about players not being able to build/dock custom
shuttles in station areas. The means to do this have been locked behind
possession of the station blueprints.

I don't see what problem there would be with allowing custom shuttles to
leave the station at the end of the round, but I could lock it behind a
particular action (antag-exclusive or otherwise).

Custom shuttles don't quite have as much utility if you have to manually
travel to z-levels to drop off gigabeacons. Jumping to adjacent z-levels
one at a time is a bit more useful for space exploration.

## Changelog
🆑
add: The station blueprints can be used to toggle whether custom
shuttles can be built/expanded/docked within station areas.
qol: Custom areas do not have to be completely contained within shuttle
frames, as long as the APC isn't attached to the frame.
add: Custom shuttles with functioning engines will fly off into the
sunset when the emergency shuttle leaves.
add: Custom shuttle navigation computers can view space levels adjacent
to the one the shuttle is currently docked at.
fix: Constructed shuttle engines no longer contribute twice as much
engine power to shuttles, nor can they be used to add unlimited shuttle
power.
fix: Constructed shuttle engines now connect to shuttles when build,
rather than needing to be unachored and then reanchored.
/🆑
2025-03-13 12:25:09 +11:00

152 lines
5.3 KiB
Plaintext

//shuttle mode defines
#define SHUTTLE_IDLE "idle"
#define SHUTTLE_IGNITING "igniting"
#define SHUTTLE_RECALL "recalled"
#define SHUTTLE_CALL "called"
#define SHUTTLE_DOCKED "docked"
#define SHUTTLE_STRANDED "stranded"
#define SHUTTLE_DISABLED "disabled"
#define SHUTTLE_ESCAPE "escape"
#define SHUTTLE_ENDGAME "endgame: game over"
#define SHUTTLE_RECHARGING "recharging"
#define SHUTTLE_PREARRIVAL "landing"
#define EMERGENCY_IDLE_OR_RECALLED (SSshuttle.emergency && ((SSshuttle.emergency.mode == SHUTTLE_IDLE) || (SSshuttle.emergency.mode == SHUTTLE_RECALL)))
#define EMERGENCY_ESCAPED_OR_ENDGAMED (SSshuttle.emergency && ((SSshuttle.emergency.mode == SHUTTLE_ESCAPE) || (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)))
#define EMERGENCY_AT_LEAST_DOCKED (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_IDLE && SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_CALL)
#define EMERGENCY_PAST_POINT_OF_NO_RETURN ((SSshuttle.emergency && SSshuttle.emergency.mode == SHUTTLE_CALL && !SSshuttle.canRecall()) || EMERGENCY_AT_LEAST_DOCKED)
// Shuttle return values
#define SHUTTLE_CAN_DOCK "can_dock"
#define SHUTTLE_NOT_A_DOCKING_PORT "not a docking port"
#define SHUTTLE_DWIDTH_TOO_LARGE "docking width too large"
#define SHUTTLE_WIDTH_TOO_LARGE "width too large"
#define SHUTTLE_DHEIGHT_TOO_LARGE "docking height too large"
#define SHUTTLE_HEIGHT_TOO_LARGE "height too large"
#define SHUTTLE_ALREADY_DOCKED "we are already docked"
#define SHUTTLE_SOMEONE_ELSE_DOCKED "someone else docked"
//Launching Shuttles to CentCom
#define NOLAUNCH -1
#define UNLAUNCHED 0
/// This shuttle launched to head to end game (or has arrived there), it will not update further
#define ENDGAME_LAUNCHED 1
#define EARLY_LAUNCHED 2
/// "Endgame transit" denotes shuttles which "fly into the sunset" when the round ends, such as the whiteship.
/// These shuttles leave when the main emergency shuttle does but don't dock anywhere (to save space), so this counts as "escaped".
#define ENDGAME_TRANSIT 3
//positive value = cannot purchase
#define SHUTTLEPURCHASE_PURCHASABLE 0 //station can buy a shuttle
#define SHUTTLEPURCHASE_PURCHASED 1 //station has already bought a shuttle, so cannot
#define SHUTTLEPURCHASE_FORCED 2 //station was given a new shuttle through events or other shenanigans
// Ripples, effects that signal a shuttle's arrival
#define SHUTTLE_RIPPLE_TIME 100
#define TRANSIT_REQUEST 1
#define TRANSIT_READY 2
#define SHUTTLE_TRANSIT_BORDER 16
#define PARALLAX_LOOP_TIME 25
#define HYPERSPACE_END_TIME 5
#define HYPERSPACE_WARMUP 1
#define HYPERSPACE_LAUNCH 2
#define HYPERSPACE_END 3
#define CALL_SHUTTLE_REASON_LENGTH 12
//Engine related
#define ENGINE_COEFF_MIN 0.5
#define ENGINE_COEFF_MAX 2
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
#define ENGINE_START_TIME 100
// Alert level related
#define ALERT_COEFF_AUTOEVAC_NORMAL 2.5
#define ALERT_COEFF_GREEN 2
#define ALERT_COEFF_BLUE 1
#define ALERT_COEFF_RED 0.5
#define ALERT_COEFF_AUTOEVAC_CRITICAL 0.4
#define ALERT_COEFF_DELTA 0.25
//Docking error flags
#define DOCKING_SUCCESS 0
#define DOCKING_BLOCKED (1<<0)
#define DOCKING_IMMOBILIZED (1<<1)
#define DOCKING_AREA_EMPTY (1<<2)
#define DOCKING_NULL_DESTINATION (1<<3)
#define DOCKING_NULL_SOURCE (1<<4)
//Docking turf movements
#define MOVE_TURF 1
#define MOVE_AREA 2
#define MOVE_CONTENTS 4
//Rotation params
#define ROTATE_DIR 1
#define ROTATE_SMOOTH 2
#define ROTATE_OFFSET 4
#define SHUTTLE_DOCKER_LANDING_CLEAR 1
#define SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT 2
#define SHUTTLE_DOCKER_BLOCKED 3
//Shuttle defaults
#define SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE /area/shuttle
#define SHUTTLE_DEFAULT_UNDERLYING_AREA /area/space
/// Shuttle unlocks
// Needs Alien Technology researched.
#define SHUTTLE_UNLOCK_ALIENTECH "abductor"
// Needs bubblegum to die.
#define SHUTTLE_UNLOCK_BUBBLEGUM "bubblegum"
// Needs one to set the holodeck to Medieval Sim.
#define SHUTTLE_UNLOCK_MEDISIM "holodeck"
// Needs a rune to be cleared by a null rod.
#define SHUTTLE_UNLOCK_NARNAR "narnar"
// Needs someone to be polymorphed - Pride Mirror, Magic Mirror, Race Swap, Polymorph Staff/Wand. Badmin Mirror doesn't count, neither does xenobio.
#define SHUTTLE_UNLOCK_WABBAJACK "wabbajack"
// Needs cargo budget to be almost empty to be purchasable.
#define SHUTTLE_UNLOCK_SCRAPHEAP "scrapheap"
//Shuttle Events
///Self destruct if this is returned in process
#define SHUTTLE_EVENT_CLEAR 2
///spawned stuff should float by the window and not hit the shuttle
#define SHUTTLE_EVENT_MISS_SHUTTLE 1 << 0
///spawned stuff should hit the shuttle
#define SHUTTLE_EVENT_HIT_SHUTTLE 1 << 1
// Hijack stages
#define HIJACK_NOT_BEGUN 0
#define HIJACK_STAGE_1 1
#define HIJACK_STAGE_2 2
#define HIJACK_STAGE_3 3
#define HIJACK_STAGE_4 4
#define HIJACK_COMPLETED 5
// Custom shuttle construction errors
#define ORIGIN_NOT_ON_SHUTTLE 1 << 0
// The following two errors occur in mutually exclusive contexts, so they can share the same bitflag
#define TOO_MANY_SHUTTLES 1 << 1
#define FRAME_NOT_ADJACENT_TO_LINKED_SHUTTLE 1 << 1
#define ABOVE_MAX_SHUTTLE_SIZE 1 << 2
#define CUSTOM_AREA_NOT_COMPLETELY_CONTAINED 1 << 3
#define INTERSECTS_NON_WHITELISTED_AREA 1 << 4
#define CONTAINS_APC_OF_NON_CUSTOM_AREA 1 << 5
// Custom shuttle engine defines
#define CUSTOM_ENGINE_COEFF_MIN 0.5
#define CUSTOM_ENGINE_COEFF_MAX 10
#define CUSTOM_ENGINE_POWER_MULTIPLIER 25
#define CUSTOM_ENGINE_POWER_TURF_COUNT_OFFSET 5