mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-10 01:22:41 +00:00
291 lines
8.7 KiB
Plaintext
291 lines
8.7 KiB
Plaintext
#define MOVE_ANIMATION_STAGE_ONE 1
|
|
#define MOVE_ANIMATION_STAGE_TWO 2
|
|
|
|
/obj/structure/transit_tube_pod
|
|
icon = 'icons/obj/pipes/transit_tube_pod.dmi'
|
|
icon_state = "pod"
|
|
animate_movement = FORWARD_STEPS
|
|
anchored = TRUE
|
|
density = TRUE
|
|
var/moving = FALSE
|
|
var/datum/gas_mixture/air_contents = new()
|
|
/// The tube we're currently traveling through
|
|
var/obj/structure/transit_tube/current_tube = null
|
|
/// The direction of our next transit from pipe to pipe. Stored between process calls here.
|
|
var/next_dir
|
|
/// The location of our next target tube. Stored same as above
|
|
var/next_loc
|
|
/// How long to wait when entering a new tube
|
|
var/enter_delay = 0
|
|
/// How long to wait when exiting a new tube
|
|
var/exit_delay
|
|
/// The next time we'll be moving
|
|
COOLDOWN_DECLARE(move_cooldown)
|
|
/// The move animation mode for the next processing tick
|
|
var/current_move_anim_mode = MOVE_ANIMATION_STAGE_ONE
|
|
/// Icon state in use while we're occupied
|
|
var/occupied_icon_state = "pod_occupied"
|
|
|
|
/obj/structure/transit_tube_pod/Initialize(mapload)
|
|
. = ..()
|
|
|
|
air_contents.set_oxygen(MOLES_O2STANDARD * 2)
|
|
air_contents.set_nitrogen(MOLES_N2STANDARD)
|
|
air_contents.set_temperature(T20C)
|
|
|
|
for(var/obj/structure/transit_tube/tube in loc)
|
|
dir = pick(tube.directions())
|
|
break
|
|
follow_tube()
|
|
|
|
/obj/structure/transit_tube_pod/update_icon_state()
|
|
. = ..()
|
|
icon_state = length(contents) ? occupied_icon_state : initial(icon_state)
|
|
|
|
/obj/structure/transit_tube_pod/proc/stop_following()
|
|
STOP_PROCESSING(SStransit_tube, src)
|
|
|
|
/obj/structure/transit_tube_pod/Destroy()
|
|
empty_pod()
|
|
stop_following()
|
|
return ..()
|
|
|
|
/obj/structure/transit_tube_pod/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
|
|
if(moving) //No drifting while moving in the tubes
|
|
return TRUE
|
|
else return ..()
|
|
|
|
/obj/structure/transit_tube_pod/proc/empty_pod(atom/location)
|
|
if(!location)
|
|
location = get_turf(src)
|
|
for(var/atom/movable/M in contents)
|
|
M.forceMove(location)
|
|
update_appearance()
|
|
|
|
/obj/structure/transit_tube_pod/crowbar_act(mob/living/user, obj/item/I)
|
|
. = ..()
|
|
if(moving)
|
|
return
|
|
|
|
if(length(contents))
|
|
I.play_tool_sound(src)
|
|
user.visible_message("<span class='notice'>[user] pries [src] open.</span>")
|
|
empty_pod()
|
|
|
|
/obj/structure/transit_tube_pod/screwdriver_act(mob/living/user, obj/item/I)
|
|
. = TRUE
|
|
var/obj/structure/transit_tube_construction/pod/P = new(get_turf(src))
|
|
P.dir = dir
|
|
to_chat(user, "<span class='notice'>You uninstall [src].</span>")
|
|
qdel(src)
|
|
|
|
/obj/structure/transit_tube_pod/wrench_act(mob/living/user, obj/item/I)
|
|
. = TRUE
|
|
to_chat(user, "<span class='notice'>You must uninstall [src] before disassembling it!</span>")
|
|
|
|
/obj/structure/transit_tube_pod/process()
|
|
..()
|
|
|
|
if(!COOLDOWN_FINISHED(src, move_cooldown))
|
|
return
|
|
|
|
var/move_result = move_animation(current_move_anim_mode)
|
|
if(isnull(move_result))
|
|
if(isnull(current_tube) || (!(dir in current_tube.directions()) && !(REVERSE_DIR(dir) in current_tube.directions())))
|
|
outside_tube()
|
|
return PROCESS_KILL
|
|
|
|
current_move_anim_mode = move_result
|
|
|
|
/obj/structure/transit_tube_pod/proc/outside_tube()
|
|
var/list/savedcontents = contents.Copy()
|
|
var/saveddir = dir
|
|
var/turf/destination = get_edge_target_turf(src, saveddir)
|
|
visible_message("<span class='warning'>[src] ejects its insides out!</span>")
|
|
for(var/i in savedcontents)
|
|
var/atom/movable/AM = i
|
|
AM.throw_at(destination, rand(1, 3), 5)
|
|
|
|
|
|
/obj/structure/transit_tube_pod/proc/move_animation(stage = MOVE_ANIMATION_STAGE_ONE)
|
|
if(stage == MOVE_ANIMATION_STAGE_ONE)
|
|
next_dir = current_tube.get_exit(dir)
|
|
|
|
if(!next_dir)
|
|
moving = FALSE
|
|
density = TRUE
|
|
return
|
|
exit_delay = current_tube.exit_delay
|
|
next_loc = get_step(src, next_dir)
|
|
current_tube = null
|
|
for(var/obj/structure/transit_tube/tube in next_loc)
|
|
if(tube.has_entrance(next_dir))
|
|
current_tube = tube
|
|
break
|
|
|
|
if(isnull(current_tube))
|
|
setDir(next_dir)
|
|
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
|
|
moving = FALSE
|
|
density = TRUE
|
|
return
|
|
|
|
enter_delay = current_tube.enter_delay(src, next_dir)
|
|
if(enter_delay > 0)
|
|
COOLDOWN_START(src, move_cooldown, enter_delay)
|
|
return MOVE_ANIMATION_STAGE_TWO
|
|
|
|
stage = MOVE_ANIMATION_STAGE_TWO
|
|
|
|
if(stage == MOVE_ANIMATION_STAGE_TWO)
|
|
setDir(next_dir)
|
|
forceMove(next_loc) // When moving from one tube to another, skip collision and such.
|
|
density = current_tube.density
|
|
|
|
if(current_tube?.should_stop_pod(src, next_dir))
|
|
current_tube.pod_stopped(src, dir)
|
|
else
|
|
COOLDOWN_START(src, move_cooldown, exit_delay)
|
|
return MOVE_ANIMATION_STAGE_ONE
|
|
|
|
density = TRUE
|
|
moving = FALSE
|
|
|
|
return MOVE_ANIMATION_STAGE_ONE
|
|
|
|
|
|
/obj/structure/transit_tube_pod/proc/follow_tube(reverse_launch)
|
|
if(moving)
|
|
return
|
|
|
|
moving = TRUE
|
|
|
|
for(var/obj/structure/transit_tube/tube in loc)
|
|
if(tube.has_exit(dir))
|
|
current_tube = tube
|
|
break
|
|
|
|
if(!isnull(current_tube))
|
|
START_PROCESSING(SStransit_tube, src)
|
|
// move_animation(MOVE_ANIMATION_STAGE_ONE)
|
|
else
|
|
moving = FALSE
|
|
|
|
/obj/structure/transit_tube_pod/return_obj_air()
|
|
RETURN_TYPE(/datum/gas_mixture)
|
|
return air_contents
|
|
|
|
// Called when a pod arrives at, and before a pod departs from a station,
|
|
// giving it a chance to mix its internal air supply with the turf it is
|
|
// currently on.
|
|
/obj/structure/transit_tube_pod/proc/mix_air()
|
|
var/datum/milla_safe/transit_pod_mix/milla = new()
|
|
milla.invoke_async(src)
|
|
|
|
/datum/milla_safe/transit_pod_mix
|
|
|
|
/datum/milla_safe/transit_pod_mix/on_run(obj/structure/transit_tube_pod/pod)
|
|
var/datum/gas_mixture/environment = null
|
|
if(isobj(pod.loc))
|
|
var/obj/O = pod.loc
|
|
environment = O.return_obj_air()
|
|
if(isnull(environment))
|
|
var/turf/T = get_turf(pod)
|
|
environment = get_turf_air(T)
|
|
|
|
var/env_pressure = environment.return_pressure()
|
|
var/int_pressure = pod.air_contents.return_pressure()
|
|
var/total_pressure = env_pressure + int_pressure
|
|
|
|
if(total_pressure == 0)
|
|
return
|
|
|
|
// Math here: Completely made up, not based on realistic equasions.
|
|
// Goal is to balance towards equal pressure, but ensure some gas
|
|
// transfer in both directions regardless.
|
|
// Feel free to rip this out and replace it with something better,
|
|
// I don't really know muhch about how gas transfer rates work in
|
|
// SS13.
|
|
var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure)
|
|
var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure)
|
|
|
|
var/datum/gas_mixture/from_env = environment.remove(environment.total_moles() * transfer_in)
|
|
var/datum/gas_mixture/from_int = pod.air_contents.remove(pod.air_contents.total_moles() * transfer_out)
|
|
|
|
environment.merge(from_int)
|
|
pod.air_contents.merge(from_env)
|
|
|
|
|
|
|
|
// When the player moves, check if the pos is currently stopped at a station.
|
|
// if it is, check the direction. If the direction matches the direction of
|
|
// the station, try to exit. If the direction matches one of the station's
|
|
// tube directions, launch the pod in that direction.
|
|
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
|
|
if(istype(mob) && mob.client)
|
|
// If the pod is not in a tube at all, you can get out at any time.
|
|
if(!(locate(/obj/structure/transit_tube) in loc))
|
|
eject(mob, direction)
|
|
return
|
|
|
|
//if(moving && istype(loc, /turf/space))
|
|
// Todo: If you get out of a moving pod in space, you should move as well.
|
|
// Same direction as pod? Direcion you moved? Halfway between?
|
|
|
|
if(!moving)
|
|
for(var/obj/structure/transit_tube/station/station in loc)
|
|
if((dir in station.directions()) || (turn(dir, 180) in station.directions()))
|
|
if(!station.pod_moving)
|
|
if(direction == turn(station.boarding_dir, 180))
|
|
if(station.hatch_state == TRANSIT_TUBE_OPEN)
|
|
eject(mob, direction)
|
|
|
|
else
|
|
station.open_hatch()
|
|
|
|
else if(direction in station.directions())
|
|
setDir(direction)
|
|
station.launch_pod()
|
|
return
|
|
|
|
for(var/obj/structure/transit_tube/tube in loc)
|
|
if(dir in tube.directions())
|
|
if(tube.has_exit(direction))
|
|
setDir(direction)
|
|
return
|
|
|
|
/obj/structure/transit_tube_pod/proc/move_into(atom/movable/A)
|
|
A.forceMove(src)
|
|
update_appearance()
|
|
|
|
/obj/structure/transit_tube_pod/proc/eject_mindless(direction)
|
|
for(var/atom/movable/A in contents)
|
|
if(ismob(A))
|
|
var/mob/M = A
|
|
if(M.mind) // Only eject mindless mobs
|
|
continue
|
|
eject(A, direction)
|
|
A.Move(get_step(loc, direction), direction)
|
|
|
|
|
|
/obj/structure/transit_tube_pod/proc/eject(atom/movable/A, direction)
|
|
A.forceMove(loc)
|
|
update_appearance()
|
|
A.Move(get_step(loc, direction), direction)
|
|
if(ismob(A))
|
|
var/mob/M = A
|
|
M.reset_perspective(null)
|
|
|
|
|
|
/obj/structure/transit_tube_pod/dispensed
|
|
name = "temporary transit tube pod"
|
|
desc = "Gets you from here to there, and no further."
|
|
|
|
|
|
/obj/structure/transit_tube_pod/dispensed/outside_tube()
|
|
if(!QDELETED(src))
|
|
qdel(src)
|
|
|
|
#undef MOVE_ANIMATION_STAGE_TWO
|
|
#undef MOVE_ANIMATION_STAGE_ONE
|