Files
ArcaneMusicandGitHub b14f1aaa4b Adds Jet Boots, a very expensive new toy for cargo. (#96299)
## About The Pull Request
This PR adds Jet Boots, a new pair of footwear that can be purchased
from cargo as an import item.
Jet boots share behavior with their parent, the rocket boots, featuring
the long range jet dash that already comes with rocket boots, though
this differs from the jump boot's dash due to being a shorter distance
as well as being far less safe as a result.

The main draw for this item is that it has a toggle action to enable
sustained jet flight. That sustained flight behaves the same as a flight
potions, offering the ability to fly over tables, as well as a passive
movement when applied. One issue with these boots, matching flight with
wings, is that you need to be in suitable atmosphere in order to be able
to propel yourself. An additional restriction is that due to your
propulsion being based on your shoes, being leg-cuffed (such as from
bolas or bear-traps) will prevent you from being able to fly.

One pair of Jet Boots requires **40,000 credits**.

### Minor things
In adding this, most of the code was applied from the existing logic
already used for mob flight and the flight organs. Considering this is
like, the 3rd thing that has consistent flight behavior(?) I'm tempted
to try and refactor it into a component, but in the interest of being
somewhat lazy I held off for this moment. I could be easily convinced to
do so, however.

These boots arrive via a gold crate. They sell for the same amount, but
the only way to let us do that was to tweak the gold crate code so that
they're not hardcoded to always arrive with gold bars and the champion's
belt. As such, there's an update map's script attached to this PR to
move existing gold crate subtypes to a "stocked" variant.

<img width="336" height="224" alt="image"
src="https://github.com/user-attachments/assets/1209e6d8-0ccb-411f-b5f6-56a808709911"
/>

## Why It's Good For The Game

The last few weeks I've kinda challenged myself with the following
question and began working backwards: "What should cargo be able to buy
for 40,000 credits?". I mulled over a few ideas, including being able to
drop in map templates onto the station, additional cargo shuttle
upgrades (In the vein of the atmos refill upgrade from my last PR), etc.
I decided on trying and making something that is inherently a selfish
purchase. Not quite to the level of buying a cargo shuttle that kills
the entire crew, but the kind that makes you think "Oh my god, cargo
just blew their entire budget on a pair of shoes".

That said, offering players flight is a rare, and expensive upgrade,
based on the fact that flight potions and the like are similarly a rare
upgrade. The alternative, training and breeding a raptor capable of
flight, is also already in cargo's domain, but typically reserved for
shaft mining use. The main give here is that in exchange for flight,
it's still bound to an item. Someone can still murder you for your
shoes, or stun you and take them off your body, especially with the
increased stun multiplier while in propelled flight.

## Changelog

🆑
add: Cargo may now purchase jet boots, boots that enable sustained
flight, for 40,000 credits via the imports section.
/🆑
2026-06-30 21:51:15 +02:00

115 lines
3.0 KiB
Plaintext

/////////////////////////////////////////////
//////// Attach a trail to any object, that spawns when it moves (like for the jetpack)
/// just pass in the object to attach it to in set_up
/// Then do start() to start it and stop() to stop it, obviously
/// and don't call start() in a loop that will be repeated otherwise it'll get spammed!
/////////////////////////////////////////////
/datum/effect_system/trail_follow
/// Previous position of the atom we're tracking
var/turf/oldposition
/// Are we currently spawning particles?
var/active = FALSE
/// Can the particles be spawned ontop of eachother?
var/allow_overlap = FALSE
/// Should we automatically start processing ourselves?
var/auto_process = TRUE
/// Delay before we delete the particles
var/qdel_in_time = 1 SECONDS
/// Typepath we should spawn
var/effect_type = null
/// Should we flick an icon state and blank out the particles afterwards?
var/fade = TRUE
/// icon_state to flick on our particles
var/fadetype = "ion_fade"
/// Are we restricted to zero-g only?
var/nograv_required = FALSE
/datum/effect_system/trail_follow/New(turf/location)
. = ..()
attach(location)
oldposition = location
/datum/effect_system/trail_follow/Destroy()
oldposition = null
stop()
return ..()
/datum/effect_system/trail_follow/proc/stop()
oldposition = null
STOP_PROCESSING(SSfastprocess, src)
active = FALSE
return TRUE
/datum/effect_system/trail_follow/start()
oldposition = get_turf(holder)
if(!check_conditions())
return FALSE
if(auto_process)
START_PROCESSING(SSfastprocess, src)
active = TRUE
return TRUE
/datum/effect_system/trail_follow/process()
generate_effect()
/datum/effect_system/trail_follow/proc/generate_effect()
if(!check_conditions())
return stop()
if(!oldposition || oldposition == get_turf(holder))
oldposition = get_turf(holder)
return
if(nograv_required && oldposition.has_gravity())
oldposition = get_turf(holder)
return
var/obj/effect/particle = new effect_type(oldposition)
set_dir(particle)
if(fade)
flick(fadetype, particle)
particle.icon_state = ""
if(qdel_in_time)
QDEL_IN(particle, qdel_in_time)
/datum/effect_system/trail_follow/proc/check_conditions()
if(!get_turf(holder))
return FALSE
return TRUE
/datum/effect_system/trail_follow/proc/set_dir(obj/effect/effect)
effect.setDir(holder.dir)
/datum/effect_system/trail_follow/steam
effect_type = /obj/effect/particle_effect/steam
/obj/effect/particle_effect/ion_trails
name = "ion trails"
icon_state = "ion_trails"
anchored = TRUE
/obj/effect/particle_effect/ion_trails/flight
icon_state = "ion_trails_flight"
/datum/effect_system/trail_follow/ion
effect_type = /obj/effect/particle_effect/ion_trails
nograv_required = TRUE
qdel_in_time = 2 SECONDS
/datum/effect_system/trail_follow/ion/grav_allowed
nograv_required = FALSE
/datum/effect_system/trail_follow/smoke
effect_type = /obj/effect/particle_effect/smoke_trail
fadetype = "smoke_trail"
qdel_in_time = 2.3 SECONDS
/obj/effect/particle_effect/smoke_trail
name = "smoke trails"
icon_state = "smoke_trail"
anchored = TRUE