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:
AffectedArc07
2020-10-29 14:07:58 +00:00
committed by GitHub
4 changed files with 146 additions and 98 deletions
@@ -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)