mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-05 06:05:58 +01:00
8788e48378
## About The Pull Request https://github.com/tgstation/tgstation/assets/7501474/a2d83ce8-eba1-42d9-a1f8-9d73f7c40b21 Adds shuttle events! Stuff can now start to happen outside the shuttle, either benign or spicy (but usually just fun to watch)! ## Why It's Good For The Game The shuttle escape sequence is an important part of the game, uniting about every player surviving player. Recently, #71906 has made the escape sequence more forgiving as well as more interesting by conditionally doubling the playing field. The area outside the shuttle is still mostly empty though, except for the few people being spaced, daredevils and the occasional epic space fight. This PR adds adds some space events to spice up the outside of the shuttle! This both gives people something too look at, making the escape sequence feel less static and more lively, as well as give people a reason to go outside and get the full experience of ~being decapitated by a meteor~ swimming with the fishes! <details> <summary>Shuttle Events</summary> **Friendly carp swarm** Spawns a group of carp that flies past the shuttle, completely friendly unless provoked. **Friendly meteors** Spawns a lot of strong meteors, but they all miss the shuttle. Completely safe as long as you don't go EVA **Maintenance debris** Picks random stuff from the maintenance spawn pool and throws it at the shuttle. Completely benign, unless you get hit in the head by a toolbox. Could get you some cool stuff though! **Dust storm** Spawns a bunch of dust meteors. Has a rare chance to hit the shuttle, doing minimal damage but can damage windows and might need inflight maintenance **Alien queen** One in every 250 escapes. Spawns a player controlled alien queen and a ripley mech. RIP AND TEAR!! Really not that dangerous when you realize the entire crew is on the shuttle and the queen is fat as fuck, but can still be fun to throw people around a bit before being torn to shreds. **ANGRY CARP** Once in every 500 escapes. Spawns 12 normal carp and 3 big carps, who may just decide to go through the shuttle or try and bust through the window if you look at them wrong. Somewhat dangerous, you could stay away from the windows and try to hide, or more likely shoot at them and weld the windows **Fake TTV** Lol **Italian Storm** Once in every 2000 rounds. Throws pasta, pizza and meatballs at the shuttle. Definitely not me going off the rails with a testing event **Player controlled carp trio** Once in every 100 escapes. Spawns three player controlled carp to harass the shuttle. May rarely be a magicarp, megacarp or chaos carp. I can't honestly see them do anything other than be annoying for 3 seconds and die There are some other admin only ones: a group of passive carps going directly through the shuttle and just being little shits, and a magic carp swarm </details> Events are selected seperately, there isn't a crazy weighting system, each just has a chance to run, and multiple could run at once. They also don't immediately trigger, so people can get settled a bit, and to make sure just waiting out the more dangerous ones is still a valid strategy. ## Changelog 🆑 add: Adds shuttle events! If shuttle escapes weren't exciting before (doubtful), they definitely are now! I'm joking it's mostly an atmosphere thing. admin: Adds an admin panel to interact with shuttle events, under the Events tab: Change Shuttle Events fix: Objects spawned in hyperspace will properly catch hyperspace drift /🆑 There's a few things I'd like to do later (another PR) (honestly anyone can do them because I suck at follow-ups), because this is too big as is: - Hijack triggered shuttle events - More events (got a lot of cool suggestions, but I'm putting most of them on hold) - Maybe stration announcements if some more dangerous ones get added - Structures appearing next to the escape shuttle??? --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
139 lines
6.8 KiB
Plaintext
139 lines
6.8 KiB
Plaintext
///An event that can run during shuttle flight, and will run for the duration of it (configurable)
|
|
/datum/shuttle_event
|
|
///How we're announced to ghosts and stuff
|
|
var/name = "The concept of a shuttle event"
|
|
///probability of this event to run from 0 to 100
|
|
var/event_probability = 0
|
|
///Track if we're allowed to run, gets turned to TRUE when the activation timer hits
|
|
VAR_PRIVATE/active = FALSE
|
|
///fraction of the escape timer at which we activate, 0 means we start running immediately
|
|
///(so if activation timer is 0.2 and shuttle takes 3 minutes to get going, it will activate in 36 seconds)
|
|
///We only care about the timer from the moment of launch, any speed changed afterwards are not worth dealing with
|
|
var/activation_fraction = 0
|
|
///when do we activate?
|
|
VAR_PRIVATE/activate_at
|
|
///Our reference to the docking port and thus the shuttle
|
|
var/obj/docking_port/mobile/port
|
|
|
|
/datum/shuttle_event/New(obj/docking_port/mobile/port)
|
|
. = ..()
|
|
|
|
src.port = port
|
|
|
|
/datum/shuttle_event/proc/start_up_event(evacuation_duration)
|
|
activate_at = world.time + evacuation_duration * activation_fraction
|
|
|
|
///We got activated
|
|
/datum/shuttle_event/proc/activate()
|
|
return
|
|
|
|
///Process with the SShutle subsystem. Return SHUTTLE_EVENT_CLEAR to self-destruct
|
|
/datum/shuttle_event/proc/event_process()
|
|
. = TRUE
|
|
|
|
if(!active)
|
|
if(world.time < activate_at)
|
|
return FALSE
|
|
active = TRUE
|
|
. = activate()
|
|
|
|
///Spawns objects, mobs, whatever with all the necessary code to make it hit and/or miss the shuttle
|
|
/datum/shuttle_event/simple_spawner
|
|
///behaviour of spawning objects, if we spawn
|
|
var/spawning_flags = SHUTTLE_EVENT_MISS_SHUTTLE | SHUTTLE_EVENT_HIT_SHUTTLE
|
|
///List of valid spawning turfs, generated from generate_spawning_turfs(), that will HIT the shuttle
|
|
var/list/turf/spawning_turfs_hit
|
|
///List of valid spawning turfs, generated from generate_spawning_turfs(), that will MISS the shuttle
|
|
var/list/turf/spawning_turfs_miss
|
|
///Chance, from 0 to 100, for something to spawn
|
|
var/spawn_probability_per_process = 0
|
|
///Increment if you want more stuff to spawn at once
|
|
var/spawns_per_spawn = 1
|
|
///weighted list with spawnable movables
|
|
var/list/spawning_list = list()
|
|
///If set to TRUE, every time an object is spawned their weight is decreased untill they are removed
|
|
var/remove_from_list_when_spawned = FALSE
|
|
///If set to true, we'll delete ourselves if we cant spawn anything anymore. Useful in conjunction with remove_from_list_when_spawned
|
|
var/self_destruct_when_empty = FALSE
|
|
|
|
/datum/shuttle_event/simple_spawner/start_up_event(evacuation_duration)
|
|
..()
|
|
|
|
generate_spawning_turfs(port.return_coords(), spawning_flags, port.preferred_direction)
|
|
|
|
///Bounding coords are list(x0, y0, x1, y1) where x0 and y0 are top-left
|
|
/datum/shuttle_event/simple_spawner/proc/generate_spawning_turfs(list/bounding_coords, spawning_behaviour, direction)
|
|
spawning_turfs_hit = list() //turfs that will drift its contents to miss the shuttle
|
|
spawning_turfs_miss = list() //turfs that will drift its contents to hit the shuttle
|
|
var/list/step_dir //vector, either -1, 0 or 1. once we get a corner (lets say top right), in which direction do we 'walk' to get the full side? (this case to the right, so (1, 0)
|
|
var/list/target_corner //Top left or bottom right corner
|
|
var/list/spawn_offset //bounding_coords is ONLY the shuttle, not the space around it, so offset spawn_tiles or stuff spawns on the walls of the shuttle
|
|
|
|
switch(direction)
|
|
if(NORTH) //we're travelling north (so people get pushed south)
|
|
step_dir = list(1, 0)
|
|
target_corner = list(bounding_coords[1], bounding_coords[2])
|
|
spawn_offset = list(0, SHUTTLE_TRANSIT_BORDER)
|
|
if(SOUTH)
|
|
step_dir = list(-1, 0)
|
|
target_corner = list(bounding_coords[3], bounding_coords[4])
|
|
spawn_offset = list(0, -SHUTTLE_TRANSIT_BORDER)
|
|
if(EAST)
|
|
step_dir = list(0, 1)
|
|
target_corner = list(bounding_coords[3], bounding_coords[4])
|
|
spawn_offset = list(SHUTTLE_TRANSIT_BORDER, 0)
|
|
if(WEST)
|
|
step_dir = list(0, -1)
|
|
target_corner = list(bounding_coords[1], bounding_coords[2])
|
|
spawn_offset = list(-SHUTTLE_TRANSIT_BORDER, 0)
|
|
|
|
if(spawning_behaviour & SHUTTLE_EVENT_HIT_SHUTTLE)
|
|
///so we get either the horizontal width or vertical width, which would both equal the amount of spawn tiles
|
|
var/tile_amount = abs((direction == NORTH || SOUTH) ? bounding_coords[1] - bounding_coords[3] : bounding_coords[2] - bounding_coords[4])
|
|
for(var/i in 0 to tile_amount)
|
|
var/list/target_coords = list(target_corner[1] + step_dir[1] * i + spawn_offset[1], target_corner[2] + step_dir[2] * i + spawn_offset[2])
|
|
spawning_turfs_hit.Add(locate(target_coords[1], target_coords[2], port.z))
|
|
if(spawning_behaviour & SHUTTLE_EVENT_MISS_SHUTTLE)
|
|
for(var/i in 1 to SHUTTLE_TRANSIT_BORDER)
|
|
//Get the corner tile, and move away from the shuttle and towards the cordon
|
|
spawning_turfs_miss.Add(locate(target_corner[1] - step_dir[1] * i + spawn_offset[1], target_corner[2] - step_dir[2] * i + spawn_offset[2], port.z))
|
|
var/corner_delta = list(bounding_coords[3] - bounding_coords[1], bounding_coords[2] - bounding_coords[4])
|
|
//Get the corner tile, but jump over the shuttle and then continue unto the cordon
|
|
spawning_turfs_miss.Add(locate(target_corner[1] + corner_delta[1] * step_dir[1] + step_dir[1] * i + spawn_offset[1], target_corner[2] + corner_delta[2] * step_dir[2] + step_dir[2] * i + spawn_offset[2], port.z))
|
|
|
|
|
|
/datum/shuttle_event/simple_spawner/event_process()
|
|
. = ..()
|
|
|
|
if(!.)
|
|
return FALSE
|
|
|
|
if(!LAZYLEN(spawning_list) && self_destruct_when_empty)
|
|
return SHUTTLE_EVENT_CLEAR
|
|
|
|
if(prob(spawn_probability_per_process))
|
|
for(var/i in 1 to spawns_per_spawn)
|
|
spawn_movable(get_type_to_spawn())
|
|
|
|
///Pick a random turf from the valid turfs we got. Overwrite if you need some custom picking
|
|
/datum/shuttle_event/simple_spawner/proc/get_spawn_turf()
|
|
RETURN_TYPE(/turf)
|
|
return pick(spawning_turfs_hit + spawning_turfs_miss)
|
|
|
|
///Spawn stuff! if you're not using this, don't use the simple_spawner subtype
|
|
/datum/shuttle_event/simple_spawner/proc/spawn_movable(spawn_type)
|
|
post_spawn(new spawn_type (get_spawn_turf()))
|
|
|
|
///Not technically a getter if remove_from_list_when_spawned=TRUE. Otherwise, this returns the type we're going to spawn and throw at the shuttle
|
|
/datum/shuttle_event/simple_spawner/proc/get_type_to_spawn()
|
|
. = pick_weight(spawning_list)
|
|
if(remove_from_list_when_spawned) //if we have this enabled, we decrease the pickweight by 1 till it runs out
|
|
spawning_list[.] -= 1
|
|
if(spawning_list[.] < 1)
|
|
spawning_list.Remove(.)
|
|
|
|
///Do any post-spawn edits you need to do
|
|
/datum/shuttle_event/simple_spawner/proc/post_spawn(atom/movable/spawnee)
|
|
ADD_TRAIT(spawnee, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT, REF(src)) //Lets us spawn and move further away from the shuttle without being teleported into space
|
|
ADD_TRAIT(spawnee, TRAIT_DEL_ON_SPACE_DUMP, REF(src)) //if we hit the cordon, we get deleted. If the shuttle can make you, it can qdel you
|