Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[READY] DRAMATIC SHUTTLES!! You can now fly around the shuttle #71906

Merged
merged 17 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new"
///from base of turf/proc/onShuttleMove(): (turf/new_turf)
#define COMSIG_TURF_ON_SHUTTLE_MOVE "turf_on_shuttle_move"
///from base of /datum/turf_reservation/proc/Release: (datum/turf_reservation/reservation)
#define COMSIG_TURF_RESERVATION_RELEASED "turf_reservation_released"
///from /turf/open/temperature_expose(datum/gas_mixture/air, exposed_temperature)
#define COMSIG_TURF_EXPOSE "turf_expose"
///from /turf/proc/immediate_calculate_adjacent_turfs()
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
#define MOVEMENT_LOOP_IGNORE_PRIORITY (1<<1)
///Should we override the loop's glide?
#define MOVEMENT_LOOP_IGNORE_GLIDE (1<<2)
///Should we not update our movables dir on move?
#define MOVEMENT_LOOP_NO_DIR_UPDATE (1<<3)

//Index defines for movement bucket data packets
#define MOVEMENT_BUCKET_TIME 1
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#define TRANSIT_REQUEST 1
#define TRANSIT_READY 2

#define SHUTTLE_TRANSIT_BORDER 8
#define SHUTTLE_TRANSIT_BORDER 16

#define PARALLAX_LOOP_TIME 25
#define HYPERSPACE_END_TIME 5
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
#define FIRE_PRIORITY_FLUIDS 20
#define FIRE_PRIORITY_AIR 20
#define FIRE_PRIORITY_NPC 20
#define FIRE_PRIORITY_HYPERSPACE_DRIFT 20
#define FIRE_PRIORITY_NPC_MOVEMENT 21
#define FIRE_PRIORITY_NPC_ACTIONS 22
#define FIRE_PRIORITY_PATHFINDING 23
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Increases chance of getting special traumas, makes them harder to cure
#define TRAIT_SPECIAL_TRAUMA_BOOST "special_trauma_boost"
#define TRAIT_SPACEWALK "spacewalk"
/// Sanity trait to keep track of when we're in hyperspace and add the appropriate element if we werent
#define TRAIT_HYPERSPACED "hyperspaced"
///Gives the movable free hyperspace movement without being pulled during shuttle transit
#define TRAIT_FREE_HYPERSPACE_MOVEMENT "free_hyperspace_movement"
/// Gets double arcade prizes
#define TRAIT_GAMERGOD "gamer-god"
#define TRAIT_GIANT "giant"
Expand Down
6 changes: 6 additions & 0 deletions code/controllers/subsystem/movement/hyperspace_drift.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
///This subsystem handles the hyperspace shuttle pull movement loops
MOVEMENT_SUBSYSTEM_DEF(hyperspace_drift)
name = "Hyperspace Drift"
priority = FIRE_PRIORITY_HYPERSPACE_DRIFT
flags = SS_NO_INIT|SS_TICKER
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
4 changes: 2 additions & 2 deletions code/controllers/subsystem/movement/movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ SUBSYSTEM_DEF(movement)
smash_bucket(bucket_time = loop.timer) // We can't pass an index in for context because we don't know our position

/datum/controller/subsystem/movement/proc/add_loop(datum/move_loop/add)
add.start_loop()
add.loop_started()
if(QDELETED(add))
return
queue_loop(add)

/datum/controller/subsystem/movement/proc/remove_loop(datum/move_loop/remove)
dequeue_loop(remove)
remove.stop_loop()
remove.loop_stopped()

31 changes: 27 additions & 4 deletions code/controllers/subsystem/movement/movement_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
var/timer = 0
///Is this loop running or not
var/running = FALSE
///Track if we're currently paused
var/paused = FALSE

/datum/move_loop/New(datum/movement_packet/owner, datum/controller/subsystem/movement/controller, atom/moving, priority, flags, datum/extra_info)
src.owner = owner
Expand All @@ -51,7 +53,8 @@
return TRUE
return FALSE

/datum/move_loop/proc/start_loop()
///Called when a loop is starting by a movement subsystem
/datum/move_loop/proc/loop_started()
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_MOVELOOP_START)
running = TRUE
Expand All @@ -62,7 +65,8 @@
return
timer = world.time + delay

/datum/move_loop/proc/stop_loop()
///Called when a loop is stopped, doesn't stop the loop itself
/datum/move_loop/proc/loop_stopped()
SHOULD_CALL_PARENT(TRUE)
running = FALSE
SEND_SIGNAL(src, COMSIG_MOVELOOP_STOP)
Expand Down Expand Up @@ -126,6 +130,25 @@
/datum/move_loop/proc/move()
return FALSE


///Pause our loop untill restarted with resume_loop()
/datum/move_loop/proc/pause_loop()
if(!controller || !running || paused) //we dead
return

//Dequeue us from our current bucket
controller.dequeue_loop(src)
paused = TRUE

///Resume our loop after being paused by pause_loop()
/datum/move_loop/proc/resume_loop()
if(!controller || !running || !paused)
return

controller.queue_loop(src)
timer = world.time
paused = FALSE

///Removes the atom from some movement subsystem. Defaults to SSmovement
/datum/controller/subsystem/move_manager/proc/stop_looping(atom/movable/moving, datum/controller/subsystem/movement/subsystem = SSmovement)
var/datum/movement_packet/our_info = moving.move_packet
Expand Down Expand Up @@ -168,7 +191,7 @@

/datum/move_loop/move/move()
var/atom/old_loc = moving.loc
moving.Move(get_step(moving, direction), direction)
moving.Move(get_step(moving, direction), direction, FALSE, !(flags & MOVEMENT_LOOP_NO_DIR_UPDATE))
// We cannot rely on the return value of Move(), we care about teleports and it doesn't
// Moving also can be null on occasion, if the move deleted it and therefor us
return old_loc != moving?.loc
Expand Down Expand Up @@ -376,7 +399,7 @@
return TRUE
return FALSE

/datum/move_loop/has_target/jps/start_loop()
/datum/move_loop/has_target/jps/loop_started()
. = ..()
INVOKE_ASYNC(src, PROC_REF(recalculate_path))

Expand Down
118 changes: 118 additions & 0 deletions code/datums/components/shuttle_cling.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

//Below defines are for the is_holding_on proc to see how well they're holding on and respond accordingly
///Instead of a high move force we just get launched away dramatically because we're that hopeless
#define SUPER_NOT_HOLDING_ON 0
///We're not holdin on and will get thrown off
#define NOT_HOLDING_ON 1
///We're holding on, but will be pulled slowly
#define CLINGING 2
///We're holding on really well and aren't suffering from any pull
#define ALL_GOOD 3

///Gets added to all movables that enter hyperspace and are supposed to suffer from "hyperspace drift"
///This lets people fly around shuttles during transit using jetpacks, or cling to the side if they got a spacesuit
///Dumping into deepspace is handled by the hyperspace turf, not the component.
///Not giving something this component while on hyperspace is safe, it just means free movement like carps
/datum/component/shuttle_cling
///The direction we push stuff towards
var/direction
///Path to the hyperspace tile, so we know if we're in hyperspace
var/hyperspace_type = /turf/open/space/transit

///Our moveloop, handles the transit pull
var/datum/move_loop/move/hyperloop

///If we can "hold on", how often do we move?
var/clinging_move_delay = 1 SECONDS
///If we can't hold onto anything, how fast do we get pulled away?
var/not_clinging_move_delay = 0.2 SECONDS

/datum/component/shuttle_cling/Initialize(direction)
. = ..()

if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE

src.direction = direction

ADD_TRAIT(parent, TRAIT_HYPERSPACED, src)

RegisterSignals(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_MOVABLE_UNBUCKLE, COMSIG_ATOM_NO_LONGER_PULLED), PROC_REF(check_state))

hyperloop = SSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_START_FAST | MOVEMENT_LOOP_NO_DIR_UPDATE)

check_state(parent) //otherwise we'll get moved 1 tile before we can correct ourselves, which isnt super bad but just looks jank

///Check if we're in hyperspace and our state in hyperspace
/datum/component/shuttle_cling/proc/check_state()
SIGNAL_HANDLER

if(!is_on_hyperspace(parent))
qdel(src)
return

var/should_loop = FALSE

switch(is_holding_on(parent))
if(SUPER_NOT_HOLDING_ON)
launch_very_hard(parent)
should_loop = TRUE
if(NOT_HOLDING_ON)
hyperloop.set_delay(not_clinging_move_delay)
should_loop = TRUE
if(CLINGING)
hyperloop.set_delay(clinging_move_delay)
should_loop = TRUE
if(ALL_GOOD)
should_loop = FALSE

if(should_loop && hyperloop.paused)
hyperloop.resume_loop()
else if(!should_loop && !hyperloop.paused)
hyperloop.pause_loop()

///Check if we're "holding on" to the shuttle
/datum/component/shuttle_cling/proc/is_holding_on(atom/movable/movee)
if(movee.pulledby || !isturf(movee.loc))
return ALL_GOOD
if(!isliving(movee))
return SUPER_NOT_HOLDING_ON

var/mob/living/living = movee

//Check if we can interact with stuff (checks for alive, arms, stun, etc)
if(!living.canUseTopic(living, be_close = TRUE, no_dexterity = FALSE, no_tk = TRUE, need_hands = TRUE))
return NOT_HOLDING_ON

if(living.buckled)
return ALL_GOOD

for(var/atom/handlebar in range(living, 1))
if(isclosedturf(handlebar))
return CLINGING
if(isobj(handlebar))
var/obj/object = handlebar
if(object.anchored && object.density)
return CLINGING
return NOT_HOLDING_ON

///Are we on a hyperspace tile? There's some special bullshit with lattices so we just wrap this check
/datum/component/shuttle_cling/proc/is_on_hyperspace(atom/movable/clinger)
if(istype(clinger.loc, hyperspace_type) && !(locate(/obj/structure/lattice) in clinger.loc))
return TRUE
return FALSE

///Launch the atom very hard, away from hyperspace
/datum/component/shuttle_cling/proc/launch_very_hard(atom/movable/byebye)
byebye.safe_throw_at(get_edge_target_turf(byebye, direction), 200, 1, spin = TRUE, force = MOVE_FORCE_EXTREMELY_STRONG)

/datum/component/shuttle_cling/Destroy(force, silent)
REMOVE_TRAIT(parent, TRAIT_HYPERSPACED, src)
QDEL_NULL(hyperloop)

return ..()

#undef SUPER_NOT_HOLDING_ON
#undef NOT_HOLDING_ON
#undef CLINGING
#undef ALL_GOOD
10 changes: 5 additions & 5 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -506,15 +506,15 @@
// Here's where we rewrite how byond handles movement except slightly different
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direction, glide_size_override = 0)
/atom/movable/Move(atom/newloc, direction, glide_size_override = 0, update_dir = TRUE)
. = FALSE
if(!newloc || newloc == loc)
return

if(!direction)
direction = get_dir(src, newloc)

if(set_dir_on_move && dir != direction)
if(set_dir_on_move && dir != direction && update_dir)
Time-Green marked this conversation as resolved.
Show resolved Hide resolved
setDir(direction)

var/is_multi_tile_object = bound_width > 32 || bound_height > 32
Expand Down Expand Up @@ -579,7 +579,7 @@

////////////////////////////////////////

/atom/movable/Move(atom/newloc, direct, glide_size_override = 0)
/atom/movable/Move(atom/newloc, direct, glide_size_override = 0, update_dir = TRUE)
var/atom/movable/pullee = pulling
var/turf/current_turf = loc
if(!moving_from_pull)
Expand Down Expand Up @@ -640,7 +640,7 @@
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!. && set_dir_on_move)
if(!. && set_dir_on_move && update_dir)
setDir(first_step_dir)
else if(!inertia_moving)
newtonian_move(direct)
Expand Down Expand Up @@ -681,7 +681,7 @@

last_move = direct

if(set_dir_on_move && dir != direct)
if(set_dir_on_move && dir != direct && update_dir)
setDir(direct)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s)
. = FALSE
Expand Down