mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 16:44:33 +01:00
Merge pull request #13549 from farie82/tubes-tweak
Refactors and reworks transit tube pods. Maint drones can now also use them
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
#define CLOSE_DURATION 6
|
||||
#define OPEN_DURATION 6
|
||||
#define LAUNCH_COOLDOWN 50
|
||||
|
||||
|
||||
// A place where tube pods stop, and people can get in or out.
|
||||
// Mappers: use "Generate Instances from Directions" for this
|
||||
@@ -8,13 +12,11 @@
|
||||
icon_state = "closed"
|
||||
exit_delay = 1
|
||||
enter_delay = 2
|
||||
var/pod_moving = 0
|
||||
var/cooldown_delay = 50
|
||||
var/pod_moving = FALSE
|
||||
var/launch_cooldown = 0
|
||||
var/reverse_launch = 0
|
||||
var/reverse_launch = FALSE
|
||||
var/hatch_state = TRANSIT_TUBE_CLOSED
|
||||
|
||||
var/const/OPEN_DURATION = 6
|
||||
var/const/CLOSE_DURATION = 6
|
||||
var/list/disallowed_mobs = list(/mob/living/silicon/ai)
|
||||
|
||||
/obj/structure/transit_tube/station/New()
|
||||
@@ -27,116 +29,134 @@
|
||||
|
||||
// Stations which will send the tube in the opposite direction after their stop.
|
||||
/obj/structure/transit_tube/station/reverse
|
||||
reverse_launch = 1
|
||||
reverse_launch = TRUE
|
||||
|
||||
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
|
||||
if(!pod_moving && icon_state == "open" && istype(AM, /mob/living) && !is_type_in_list(AM, disallowed_mobs))
|
||||
/obj/structure/transit_tube/station/Bumped(mob/living/L)
|
||||
if(!pod_moving && hatch_state == TRANSIT_TUBE_OPEN && isliving(L) && !is_type_in_list(L, disallowed_mobs))
|
||||
var/failed = FALSE
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(pod.contents.len)
|
||||
to_chat(AM, "<span class=The pod is already occupied.</span>")
|
||||
return
|
||||
failed = TRUE
|
||||
else if(!pod.moving && (pod.dir in directions()))
|
||||
AM.forceMove(pod)
|
||||
pod.move_into(L)
|
||||
return
|
||||
if(failed)
|
||||
to_chat(L, "<span class='warning'>The pod is already occupied.</span>")
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
|
||||
if(!pod_moving)
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && (pod.dir in directions()))
|
||||
if(icon_state == "closed")
|
||||
open_animation()
|
||||
|
||||
else if(icon_state == "open")
|
||||
if(pod.contents.len && user.loc != pod)
|
||||
user.visible_message("<span class='warning'>[user] starts emptying [pod]'s contents onto the floor!</span>")
|
||||
if(do_after(user, 40, target = src)) //So it doesn't default to close_animation() on fail
|
||||
if(pod.loc == loc)
|
||||
for(var/atom/movable/AM in pod)
|
||||
AM.loc = get_turf(user)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M.Weaken(5)
|
||||
|
||||
else
|
||||
close_animation()
|
||||
break
|
||||
/obj/structure/transit_tube/station/attack_hand(mob/user)
|
||||
if(pod_moving)
|
||||
return
|
||||
var/obj/structure/transit_tube_pod/pod = locate() in loc
|
||||
if(!pod)
|
||||
return
|
||||
// Can't get in moving pods. Or pods that have openings on the other side
|
||||
if(pod.moving || !(pod.dir in directions()))
|
||||
return
|
||||
if(hatch_state != TRANSIT_TUBE_OPEN)
|
||||
return
|
||||
// Can't empty it when inside or when there is nothing inside
|
||||
if(!length(pod.contents) || user.loc == pod)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] starts emptying [pod]'s contents onto the floor!</span>", \
|
||||
"<span class='notice'>You start emptying [pod]'s contents onto the floor.</span>", "<span class='warning'>You hear a loud noise! As if somebody is throwing stuff on the floor!</span>")
|
||||
if(!do_after(user, 20, target = pod))
|
||||
return
|
||||
for(var/atom/movable/AM in pod)
|
||||
pod.eject(AM)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M.Weaken(5)
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/grab) && icon_state == "open")
|
||||
if(istype(W, /obj/item/grab) && hatch_state == TRANSIT_TUBE_OPEN)
|
||||
var/obj/item/grab/G = W
|
||||
if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE)
|
||||
var/mob/GM = G.affecting
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
pod.visible_message("<span class='warning'>[user] starts putting [GM] into the [pod]!</span>")
|
||||
if(do_after(user, 60, target = GM) && GM && G && G.affecting == GM)
|
||||
if(do_after(user, 30, target = GM) && GM && G && G.affecting == GM)
|
||||
GM.Weaken(5)
|
||||
src.Bumped(GM)
|
||||
Bumped(GM)
|
||||
qdel(G)
|
||||
break
|
||||
|
||||
/obj/structure/transit_tube/station/proc/open_animation()
|
||||
if(icon_state == "closed")
|
||||
/obj/structure/transit_tube/station/proc/open_hatch()
|
||||
if(hatch_state == TRANSIT_TUBE_CLOSED)
|
||||
icon_state = "opening"
|
||||
spawn(OPEN_DURATION)
|
||||
if(icon_state == "opening")
|
||||
icon_state = "open"
|
||||
hatch_state = TRANSIT_TUBE_OPENING
|
||||
addtimer(CALLBACK(src, .proc/open_hatch_callback), OPEN_DURATION)
|
||||
|
||||
/obj/structure/transit_tube/station/proc/open_hatch_callback()
|
||||
if(hatch_state == TRANSIT_TUBE_OPENING)
|
||||
icon_state = "open"
|
||||
hatch_state = TRANSIT_TUBE_OPEN
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/close_animation()
|
||||
if(icon_state == "open")
|
||||
/obj/structure/transit_tube/station/proc/close_hatch()
|
||||
if(hatch_state == TRANSIT_TUBE_OPEN)
|
||||
icon_state = "closing"
|
||||
spawn(CLOSE_DURATION)
|
||||
if(icon_state == "closing")
|
||||
icon_state = "closed"
|
||||
|
||||
hatch_state = TRANSIT_TUBE_CLOSING
|
||||
addtimer(CALLBACK(src, .proc/close_hatch_calllback), CLOSE_DURATION)
|
||||
|
||||
/obj/structure/transit_tube/station/proc/close_hatch_calllback()
|
||||
if(hatch_state == TRANSIT_TUBE_CLOSING)
|
||||
icon_state = "closed"
|
||||
hatch_state = TRANSIT_TUBE_CLOSED
|
||||
|
||||
/obj/structure/transit_tube/station/proc/launch_pod()
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && (pod.dir in directions()))
|
||||
spawn(5)
|
||||
pod_moving = 1
|
||||
close_animation()
|
||||
sleep(CLOSE_DURATION + 2)
|
||||
|
||||
//reverse directions for automated cycling
|
||||
var/turf/next_loc = get_step(loc, pod.dir)
|
||||
var/obj/structure/transit_tube/nexttube
|
||||
for(var/obj/structure/transit_tube/tube in next_loc)
|
||||
if(tube.has_entrance(pod.dir))
|
||||
nexttube = tube
|
||||
break
|
||||
if(!nexttube)
|
||||
pod.dir = turn(pod.dir, 180)
|
||||
|
||||
if(icon_state == "closed" && pod)
|
||||
pod.follow_tube()
|
||||
|
||||
pod_moving = 0
|
||||
|
||||
addtimer(CALLBACK(src, .proc/launch_pod_callback, pod), 5)
|
||||
return
|
||||
|
||||
/obj/structure/transit_tube/station/proc/launch_pod_callback(obj/structure/transit_tube_pod/pod)
|
||||
pod_moving = TRUE
|
||||
close_hatch()
|
||||
sleep(CLOSE_DURATION + 2)
|
||||
|
||||
//reverse directions for automated cycling
|
||||
var/turf/next_loc = get_step(loc, pod.dir)
|
||||
var/obj/structure/transit_tube/nexttube
|
||||
for(var/obj/structure/transit_tube/tube in next_loc)
|
||||
if(tube.has_entrance(pod.dir))
|
||||
nexttube = tube
|
||||
break
|
||||
if(!nexttube)
|
||||
pod.dir = turn(pod.dir, 180)
|
||||
|
||||
if(hatch_state == TRANSIT_TUBE_CLOSED && pod)
|
||||
pod.follow_tube()
|
||||
|
||||
pod_moving = FALSE
|
||||
|
||||
/obj/structure/transit_tube/station/process()
|
||||
if(!pod_moving)
|
||||
if(!pod_moving && launch_cooldown <= world.time)
|
||||
launch_pod()
|
||||
|
||||
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
|
||||
pod_moving = 1
|
||||
spawn(5)
|
||||
launch_cooldown = world.time + cooldown_delay
|
||||
open_animation()
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod_moving = 0
|
||||
pod.mix_air()
|
||||
pod_moving = TRUE
|
||||
addtimer(CALLBACK(src, .proc/pod_stopped_callback, pod), 5)
|
||||
|
||||
/obj/structure/transit_tube/station/proc/pod_stopped_callback(obj/structure/transit_tube_pod/pod)
|
||||
launch_cooldown = world.time + LAUNCH_COOLDOWN
|
||||
open_hatch(pod)
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod.eject_mindless(dir)
|
||||
pod_moving = FALSE
|
||||
pod.mix_air()
|
||||
|
||||
// Tube station directions are simply 90 to either side of
|
||||
// the exit.
|
||||
/obj/structure/transit_tube/station/init_dirs()
|
||||
tube_dirs = list(turn(dir, 90), turn(dir, -90))
|
||||
|
||||
#undef CLOSE_DURATION
|
||||
#undef OPEN_DURATION
|
||||
#undef LAUNCH_COOLDOWN
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
icon = 'icons/obj/pipes/transit_tube_pod.dmi'
|
||||
icon_state = "pod"
|
||||
animate_movement = FORWARD_STEPS
|
||||
anchored = 1.0
|
||||
density = 1
|
||||
var/moving = 0
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/moving = FALSE
|
||||
var/datum/gas_mixture/air_contents = new()
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/New(loc)
|
||||
..(loc)
|
||||
|
||||
@@ -26,14 +25,14 @@
|
||||
|
||||
/obj/structure/transit_tube_pod/Process_Spacemove()
|
||||
if(moving) //No drifting while moving in the tubes
|
||||
return 1
|
||||
return TRUE
|
||||
else return ..()
|
||||
|
||||
/obj/structure/transit_tube_pod/proc/follow_tube(var/reverse_launch)
|
||||
if(moving)
|
||||
return
|
||||
|
||||
moving = 1
|
||||
moving = TRUE
|
||||
|
||||
spawn()
|
||||
var/obj/structure/transit_tube/current_tube = null
|
||||
@@ -70,23 +69,23 @@
|
||||
break
|
||||
|
||||
if(current_tube == null)
|
||||
dir = next_dir
|
||||
setDir(next_dir)
|
||||
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
|
||||
break
|
||||
|
||||
last_delay = current_tube.enter_delay(src, next_dir)
|
||||
sleep(last_delay)
|
||||
dir = next_dir
|
||||
loc = next_loc // When moving from one tube to another, skip collision and such.
|
||||
setDir(next_dir)
|
||||
forceMove(next_loc) // When moving from one tube to another, skip collision and such.
|
||||
density = current_tube.density
|
||||
|
||||
if(current_tube && current_tube.should_stop_pod(src, next_dir))
|
||||
current_tube.pod_stopped(src, dir)
|
||||
break
|
||||
|
||||
density = 1
|
||||
density = TRUE
|
||||
|
||||
moving = 0
|
||||
moving = FALSE
|
||||
|
||||
|
||||
// Should I return a copy here? If the caller edits or qdel()s the returned
|
||||
@@ -141,10 +140,11 @@
|
||||
// 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) && mob.client)
|
||||
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))
|
||||
mob.forceMove(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.
|
||||
@@ -155,19 +155,41 @@
|
||||
if(dir in station.directions())
|
||||
if(!station.pod_moving)
|
||||
if(direction == station.dir)
|
||||
if(station.icon_state == "open")
|
||||
mob.forceMove(loc)
|
||||
if(station.hatch_state == TRANSIT_TUBE_OPEN)
|
||||
eject(mob, direction)
|
||||
|
||||
else
|
||||
station.open_animation()
|
||||
station.open_hatch()
|
||||
|
||||
else if(direction in station.directions())
|
||||
dir = direction
|
||||
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))
|
||||
dir = direction
|
||||
setDir(direction)
|
||||
return
|
||||
|
||||
/obj/structure/transit_tube_pod/proc/move_into(atom/movable/A)
|
||||
icon_state = "pod_occupied"
|
||||
A.forceMove(src)
|
||||
|
||||
/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)
|
||||
icon_state = "pod"
|
||||
A.forceMove(loc)
|
||||
A.Move(get_step(loc, direction), direction)
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
M.reset_perspective(null)
|
||||
|
||||
Reference in New Issue
Block a user