Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
@@ -2,21 +2,17 @@
// A place where tube pods stop, and people can get in or out.
// Mappers: use "Generate Instances from Directions" for this
// one.
/obj/structure/transit_tube/station
name = "station tube station"
icon_state = "closed_station0"
icon = 'icons/obj/atmospherics/pipes/transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 1
enter_delay = 2
tube_construction = /obj/structure/c_transit_tube/station
var/open_status = STATION_TUBE_CLOSED
var/pod_moving = 0
var/cooldown_delay = 50
var/launch_cooldown = 0
var/reverse_launch = 0
var/base_icon = "station0"
var/boarding_dir //from which direction you can board the tube
var/const/OPEN_DURATION = 6
var/const/CLOSE_DURATION = 6
@@ -29,15 +25,19 @@
STOP_PROCESSING(SSobj, src)
return ..()
// Stations which will send the tube in the opposite direction after their stop.
/obj/structure/transit_tube/station/reverse
tube_construction = /obj/structure/c_transit_tube/station/reverse
reverse_launch = 1
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
return 1
/obj/structure/transit_tube/station/Bumped(atom/movable/AM)
if(!pod_moving && open_status == STATION_TUBE_OPEN && ismob(AM) && AM.dir == boarding_dir)
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving)
AM.forceMove(pod)
pod.update_icon()
if(!pod.moving && pod.dir in directions())
AM.loc = pod
return
@@ -49,18 +49,19 @@
return
for(var/obj/structure/transit_tube_pod/pod in loc)
return //no fun allowed
var/obj/structure/transit_tube_pod/TP = new(loc)
R.transfer_fingerprints_to(TP)
TP.add_fingerprint(user)
TP.setDir(turn(src.dir, -90))
user.visible_message("[user] inserts [R].", "<span class='notice'>You insert [R].</span>")
var/obj/structure/transit_tube_pod/T = new/obj/structure/transit_tube_pod(src)
R.transfer_fingerprints_to(T)
T.add_fingerprint(user)
T.loc = src.loc
T.setDir(turn(src.dir, -90))
user.visible_message("[user] inserts the [R].", "<span class='notice'>You insert the [R].</span>")
qdel(R)
/obj/structure/transit_tube/station/attack_hand(mob/user)
if(!pod_moving)
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
if(open_status == STATION_TUBE_OPEN)
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
if(icon_state == "open")
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.buckled || GM.has_buckled_mobs())
@@ -69,23 +70,26 @@
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, 15, target = src))
if(open_status == STATION_TUBE_OPEN && GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.has_buckled_mobs())
if(GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.has_buckled_mobs())
GM.Weaken(5)
src.Bumped(GM)
break
else
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && (pod.dir in tube_dirs))
if(open_status == STATION_TUBE_CLOSED)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(open_status == STATION_TUBE_OPEN)
else if(icon_state == "open")
if(pod.contents.len && user.loc != pod)
user.visible_message("[user] starts emptying [pod]'s contents onto the floor.", "<span class='notice'>You start emptying [pod]'s contents onto the floor...</span>")
if(do_after(user, 10, target = src)) //So it doesn't default to close_animation() on fail
if(pod && pod.loc == loc)
if(pod.loc == loc)
for(var/atom/movable/AM in pod)
AM.forceMove(get_turf(user))
AM.loc = get_turf(user)
if(ismob(AM))
var/mob/M = AM
M.Weaken(5)
else
close_animation()
@@ -94,41 +98,46 @@
/obj/structure/transit_tube/station/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/crowbar))
for(var/obj/structure/transit_tube_pod/P in loc)
P.deconstruct(FALSE, user)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(pod.contents)
user << "<span class='warning'>Empty the pod first!</span>"
return
user.visible_message("[user] removes the [pod].", "<span class='notice'>You remove the [pod].</span>")
var/obj/structure/c_transit_tube_pod/R = new/obj/structure/c_transit_tube_pod(src.loc)
pod.transfer_fingerprints_to(R)
R.add_fingerprint(user)
qdel(pod)
else
return ..()
/obj/structure/transit_tube/station/proc/open_animation()
if(open_status == STATION_TUBE_CLOSED)
icon_state = "opening_[base_icon]"
open_status = STATION_TUBE_OPENING
if(icon_state == "closed")
icon_state = "opening"
spawn(OPEN_DURATION)
if(open_status == STATION_TUBE_OPENING)
icon_state = "open_[base_icon]"
open_status = STATION_TUBE_OPEN
if(icon_state == "opening")
icon_state = "open"
/obj/structure/transit_tube/station/proc/close_animation()
if(open_status == STATION_TUBE_OPEN)
icon_state = "closing_[base_icon]"
open_status = STATION_TUBE_CLOSING
if(icon_state == "open")
icon_state = "closing"
spawn(CLOSE_DURATION)
if(open_status == STATION_TUBE_CLOSING)
icon_state = "closed_[base_icon]"
open_status = STATION_TUBE_CLOSED
if(icon_state == "closing")
icon_state = "closed"
/obj/structure/transit_tube/station/proc/launch_pod()
if(launch_cooldown >= world.time)
return
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving)
if(!pod.moving && turn(pod.dir, (reverse_launch ? 180 : 0)) in directions())
pod_moving = 1
close_animation()
sleep(CLOSE_DURATION + 2)
if(open_status == STATION_TUBE_CLOSED && pod && pod.loc == loc)
pod.follow_tube()
if(icon_state == "closed" && pod)
pod.follow_tube(reverse_launch)
pod_moving = 0
return 1
return 0
@@ -140,63 +149,13 @@
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = 1
spawn(5)
if(reverse_launch)
pod.setDir(tube_dirs[1]) //turning the pod around for next launch.
launch_cooldown = world.time + cooldown_delay
open_animation()
sleep(OPEN_DURATION + 2)
pod_moving = 0
if(!qdeleted(pod))
pod.air_contents.share(loc.return_air()) //mix the pod's gas mixture with the tile it's on
/obj/structure/transit_tube/station/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(EAST, WEST)
if(SOUTH)
tube_dirs = list(EAST, WEST)
if(EAST)
tube_dirs = list(NORTH, SOUTH)
if(WEST)
tube_dirs = list(NORTH, SOUTH)
boarding_dir = turn(dir, 180)
/obj/structure/transit_tube/station/flipped
icon_state = "closed_station1"
base_icon = "station1"
tube_construction = /obj/structure/c_transit_tube/station/flipped
/obj/structure/transit_tube/station/flipped/init_tube_dirs()
..()
boarding_dir = dir
// Stations which will send the tube in the opposite direction after their stop.
/obj/structure/transit_tube/station/reverse
tube_construction = /obj/structure/c_transit_tube/station/reverse
reverse_launch = 1
icon_state = "closed_terminus0"
base_icon = "terminus0"
/obj/structure/transit_tube/station/reverse/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(EAST)
if(SOUTH)
tube_dirs = list(WEST)
if(EAST)
tube_dirs = list(SOUTH)
if(WEST)
tube_dirs = list(NORTH)
boarding_dir = turn(dir, 180)
/obj/structure/transit_tube/station/reverse/flipped
icon_state = "closed_terminus1"
base_icon = "terminus1"
tube_construction = /obj/structure/c_transit_tube/station/reverse/flipped
/obj/structure/transit_tube/station/reverse/flipped/init_tube_dirs()
..()
boarding_dir = dir
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))
@@ -1,52 +1,58 @@
// Basic transit tubes. Straight pieces, curved sections,
// and basic splits/joins (no routing logic).
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
name = "transit tube"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "straight"
icon_state = "E-W"
density = 1
layer = LOW_ITEM_LAYER
layer = ABOVE_OBJ_LAYER
anchored = 1
climbable = 1
var/tube_construction = /obj/structure/c_transit_tube
var/list/tube_dirs //list of directions this tube section can connect to.
var/list/tube_dirs = null
var/exit_delay = 1
var/enter_delay = 0
// alldirs in global.dm is the same list of directions, but since
// the specific order matters to get a usable icon_state, it is
// copied here so that, in the unlikely case that alldirs is changed,
// this continues to work.
var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
/obj/structure/transit_tube/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
return 1
return !density
/obj/structure/transit_tube/New(loc, newdirection)
// When destroyed by explosions, properly handle contents.
obj/structure/transit_tube/ex_act(severity, target)
if(3 - severity >= 0)
var/oldloc = loc
..(severity + 1)
for(var/atom/movable/AM in contents)
AM.loc = oldloc
/obj/structure/transit_tube/New(loc)
..(loc)
if(newdirection)
setDir(newdirection)
init_tube_dirs()
generate_tube_overlays()
/obj/structure/transit_tube/Destroy()
for(var/obj/structure/transit_tube_pod/P in loc)
P.deconstruct(FALSE)
return ..()
/obj/structure/transit_tube/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
if(tube_dirs == null)
init_dirs()
/obj/structure/transit_tube/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
if(tube_construction)
if(copytext(icon_state, 1, 3) != "D-") //decorative diagonals cannot be unwrenched directly
for(var/obj/structure/transit_tube_pod/pod in src.loc)
user << "<span class='warning'>Remove the pod first!</span>"
return
user.visible_message("[user] starts to deattach \the [src].", "<span class='notice'>You start to deattach the [name]...</span>")
playsound(src.loc, W.usesound, 50, 1)
if(do_after(user, 35*W.toolspeed, target = src))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
if(do_after(user, 35/W.toolspeed, target = src))
user << "<span class='notice'>You deattach the [name].</span>"
var/obj/structure/c_transit_tube/R = new tube_construction(loc)
R.setDir(dir)
transfer_fingerprints_to(R)
var/obj/structure/R = new tube_construction(src.loc)
R.icon_state = src.icon_state
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
src.destroy_diagonals()
qdel(src)
else if(istype(W, /obj/item/weapon/crowbar))
for(var/obj/structure/transit_tube_pod/pod in src.loc)
@@ -54,6 +60,21 @@
else
return ..()
//destroys disconnected decorative diagonals
/obj/structure/transit_tube/proc/destroy_diagonals()
for(var/obj/structure/transit_tube/D in orange(1, src))
if(copytext(D.icon_state, 1, 3) == "D-") //is diagonal
var/my_dir = text2dir_extended(copytext(D.icon_state, 3, 5))
var/is_connecting = 0
for(var/obj/structure/transit_tube/N in orange(1,D))
if( (( get_dir(D,N) == turn(my_dir, -45) && D.has_exit(turn(my_dir, 90)) ) || \
( get_dir(D,N) == turn(my_dir, 45) && D.has_exit(turn(my_dir, -90))) ) && \
D != src )
is_connecting = 1
break
if(!is_connecting)
qdel(D)
// Called to check if a pod should stop upon entering this tube.
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
return 0
@@ -62,11 +83,18 @@
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
return
// Returns a /list of directions this tube section can connect to.
// Tubes that have some sort of logic or changing direction might
// override it with additional logic.
/obj/structure/transit_tube/proc/directions()
return tube_dirs
/obj/structure/transit_tube/proc/has_entrance(from_dir)
from_dir = turn(from_dir, 180)
for(var/direction in tube_dirs)
for(var/direction in directions())
if(direction == from_dir)
return 1
@@ -75,7 +103,7 @@
/obj/structure/transit_tube/proc/has_exit(in_dir)
for(var/direction in tube_dirs)
for(var/direction in directions())
if(direction == in_dir)
return 1
@@ -90,7 +118,7 @@
var/in_dir_cw = turn(in_dir, -45)
var/in_dir_ccw = turn(in_dir, 45)
for(var/direction in tube_dirs)
for(var/direction in directions())
if(direction == in_dir)
return direction
@@ -115,154 +143,143 @@
return enter_delay
/obj/structure/transit_tube/proc/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTH, SOUTH)
if(SOUTH)
tube_dirs = list(NORTH, SOUTH)
if(EAST)
tube_dirs = list(EAST, WEST)
if(WEST)
tube_dirs = list(EAST, WEST)
// Parse the icon_state into a list of directions.
// This means that mappers can use Dream Maker's built in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
/obj/structure/transit_tube/proc/init_dirs()
if(icon_state == "auto")
// Additional delay, for map loading.
spawn(1)
init_dirs_automatic()
/obj/structure/transit_tube/proc/generate_tube_overlays()
for(var/direction in tube_dirs)
if(direction in diagonals)
if(direction & NORTH)
create_tube_overlay(direction ^ 3, NORTH)
if(direction & EAST)
create_tube_overlay(direction ^ 12, EAST)
else
create_tube_overlay(direction ^ 12, WEST)
else
create_tube_overlay(direction)
/obj/structure/transit_tube/proc/create_tube_overlay(direction, shift_dir)
var/image/I
if(shift_dir)
I = image(loc = src, icon_state = "decorative_diag", dir = direction)
switch(shift_dir)
if(NORTH)
I.pixel_y = 32
if(SOUTH)
I.pixel_y = -32
if(EAST)
I.pixel_x = 32
if(WEST)
I.pixel_x = -32
else
I = image(loc = src, icon_state = "decorative", dir = direction)
add_overlay(I)
tube_dirs = parse_dirs(icon_state)
if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass"))
density = 0
//Some of these are mostly for mapping use
/obj/structure/transit_tube/horizontal
dir = WEST
// Initialize dirs by searching for tubes that do/might connect
// on nearby turfs. Create corner pieces if nessecary.
// Pick two directions, preferring tubes that already connect
// to loc, or other auto tubes if there aren't enough connections.
/obj/structure/transit_tube/proc/init_dirs_automatic()
var/list/connected = list()
var/list/connected_auto = list()
for(var/direction in tube_dir_list)
var/location = get_step(loc, direction)
for(var/obj/structure/transit_tube/tube in location)
if(tube.directions() == null && tube.icon_state == "auto")
connected_auto += direction
break
else if(turn(direction, 180) in tube.directions())
connected += direction
break
connected += connected_auto
tube_dirs = select_automatic_dirs(connected)
if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2]))
tube_dirs.Swap(1, 2)
generate_automatic_corners(tube_dirs)
select_automatic_icon_state(tube_dirs)
/obj/structure/transit_tube/diagonal
icon_state = "diagonal"
tube_construction = /obj/structure/c_transit_tube/diagonal
/obj/structure/transit_tube/diagonal/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTHEAST, SOUTHWEST)
if(SOUTH)
tube_dirs = list(NORTHEAST, SOUTHWEST)
if(EAST)
tube_dirs = list(NORTHWEST, SOUTHEAST)
if(WEST)
tube_dirs = list(NORTHWEST, SOUTHEAST)
// Given a list of directions, look a pair that forms a 180 or
// 135 degree angle, and return a list containing the pair.
// If none exist, return list(connected[1], turn(connected[1], 180)
/obj/structure/transit_tube/proc/select_automatic_dirs(connected)
if(length(connected) < 1)
return list()
//mostly for mapping use
/obj/structure/transit_tube/diagonal/topleft
dir = WEST
for(var/i = 1, i <= length(connected), i++)
for(var/j = i + 1, j <= length(connected), j++)
var/d1 = connected[i]
var/d2 = connected[j]
/obj/structure/transit_tube/diagonal/crossing
density = 0
icon_state = "diagonal_crossing"
tube_construction = /obj/structure/c_transit_tube/diagonal/crossing
if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225))
return list(d1, d2)
//mostly for mapping use
/obj/structure/transit_tube/diagonal/crossing/topleft
dir = WEST
return list(connected[1], turn(connected[1], 180))
/obj/structure/transit_tube/curved
icon_state = "curved0"
tube_construction = /obj/structure/c_transit_tube/curved
/obj/structure/transit_tube/curved/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTH, SOUTHWEST)
if(SOUTH)
tube_dirs = list(SOUTH, NORTHEAST)
if(EAST)
tube_dirs = list(EAST, NORTHWEST)
if(WEST)
tube_dirs = list(SOUTHEAST, WEST)
/obj/structure/transit_tube/curved/flipped
icon_state = "curved1"
tube_construction = /obj/structure/c_transit_tube/curved/flipped
/obj/structure/transit_tube/curved/flipped/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTH, SOUTHEAST)
if(SOUTH)
tube_dirs = list(SOUTH, NORTHWEST)
if(EAST)
tube_dirs = list(EAST, SOUTHWEST)
if(WEST)
tube_dirs = list(NORTHEAST, WEST)
/obj/structure/transit_tube/proc/select_automatic_icon_state(directions)
if(length(directions) == 2)
icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]"
/obj/structure/transit_tube/junction
icon_state = "junction0"
tube_construction = /obj/structure/c_transit_tube/junction
/obj/structure/transit_tube/junction/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTH, SOUTHEAST, SOUTHWEST)//ending with the prefered direction
if(SOUTH)
tube_dirs = list(SOUTH, NORTHWEST, NORTHEAST)
if(EAST)
tube_dirs = list(EAST, SOUTHWEST, NORTHWEST)
if(WEST)
tube_dirs = list(WEST, NORTHEAST, SOUTHEAST)
// Look for diagonal directions, generate the decorative corners in each.
/obj/structure/transit_tube/proc/generate_automatic_corners(directions)
for(var/direction in directions)
if(direction == 5 || direction == 6 || direction == 9 || direction == 10)
if(direction & NORTH)
create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3)
/obj/structure/transit_tube/junction/flipped
icon_state = "junction1"
tube_construction = /obj/structure/c_transit_tube/junction/flipped
else
create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3)
/obj/structure/transit_tube/junction/flipped/init_tube_dirs()
switch(dir)
if(NORTH)
tube_dirs = list(NORTH, SOUTHWEST, SOUTHEAST)//ending with the prefered direction
if(SOUTH)
tube_dirs = list(SOUTH, NORTHEAST, NORTHWEST)
if(EAST)
tube_dirs = list(EAST, NORTHWEST, SOUTHWEST)
if(WEST)
tube_dirs = list(WEST, SOUTHEAST, NORTHEAST)
if(direction & EAST)
create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12)
else
create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12)
/obj/structure/transit_tube/crossing
icon_state = "crossing"
tube_construction = /obj/structure/c_transit_tube/crossing
density = 0
//mostly for mapping use
/obj/structure/transit_tube/crossing/horizontal
dir = WEST
// Generate a corner, if one doesn't exist for the direction on the turf.
/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction)
var/state = "D-[dir2text_short(direction)]"
for(var/obj/structure/transit_tube/tube in location)
if(tube.icon_state == state)
return
var/obj/structure/transit_tube/tube = new(location)
tube.icon_state = state
tube.init_dirs()
// Uses a list() to cache return values. Since they should
// never be edited directly, all tubes with a certain
// icon_state can just reference the same list. In theory,
// reduces memory usage, and improves CPU cache usage.
// In reality, I don't know if that is quite how BYOND works,
// but it is probably safer to assume the existence of, and
// rely on, a sufficiently smart compiler/optimizer.
/obj/structure/transit_tube/proc/parse_dirs(text)
var/global/list/direction_table = list()
if(text in direction_table)
return direction_table[text]
var/list/split_text = splittext(text, "-")
// If the first token is D, the icon_state represents
// a purely decorative tube, and doesn't actually
// connect to anything.
if(split_text[1] == "D")
direction_table[text] = list()
return null
var/list/directions = list()
for(var/text_part in split_text)
var/direction = text2dir_extended(text_part)
if(direction > 0)
directions += direction
direction_table[text] = directions
return directions
@@ -4,44 +4,58 @@
/obj/structure/c_transit_tube
name = "unattached transit tube"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "straight"
icon_state = "E-W" //icon_state decides which tube will be built
density = 0
layer = LOW_ITEM_LAYER //same as the built tube
layer = ABOVE_OBJ_LAYER //same as the built tube
anchored = 0
var/flipped = 0
var/build_type = /obj/structure/transit_tube
var/flipped_build_type
var/base_icon
/obj/structure/c_transit_tube/examine(mob/user)
..()
user << "<span class='notice'>Alt-click to rotate it clockwise.</span>"
/obj/structure/c_transit_tube/proc/tube_rotate()
setDir(turn(dir, -90))
//wrapper for turn that changes the transit tube formatted icon_state instead of the dir
/obj/structure/c_transit_tube/proc/tube_turn(angle)
var/list/badtubes = list("W-E", "W-E-Pass", "S-N", "S-N-Pass", "SW-NE", "SE-NW")
var/list/split_text = splittext(icon_state, "-")
for(var/i=1; i<=split_text.len; i++)
var/curdir = text2dir_extended(split_text[i]) //0 if not a valid direction (e.g. Pass, Block)
if(curdir)
split_text[i] = dir2text_short(turn(curdir, angle))
var/newdir = jointext(split_text, "-")
if(badtubes.Find(newdir))
split_text.Swap(1,2)
newdir = jointext(split_text, "-")
icon_state = newdir
/obj/structure/c_transit_tube/proc/tube_flip()
if(flipped_build_type)
flipped = !flipped
var/cur_flip = initial(flipped) ? !flipped : flipped
if(cur_flip)
build_type = flipped_build_type
else
build_type = initial(build_type)
icon_state = "[base_icon][flipped]"
var/list/split_text = splittext(icon_state, "-")
//skip straight pipes
if(length(split_text[2]) < 2)
return
//for junctions, just swap the diagonals with each other
if(split_text.len == 3 && split_text[3] != "Pass")
split_text.Swap(2,3)
else if(length(split_text[1]) == 2 && length(split_text[2]) == 2) //diagonals
split_text[1] = copytext(split_text[1],1,2) + copytext(split_text[2],2,3)
split_text[2] = copytext(split_text[2],1,2) + ((copytext(split_text[2],2,3) == "E") ? "W" : "E")
//for curves, swap the diagonal direction that is not in the same axis as the cardinal direction
else
setDir(turn(dir, 180))
if(split_text[1] == "N" || split_text[1] == "S")
split_text[2] = copytext(split_text[2],1,2) + ((copytext(split_text[2],2,3) == "E") ? "W" : "E")
else
split_text[2] = ((copytext(split_text[2],1,2) == "N") ? "S" : "N") + copytext(split_text[2],2,3)
icon_state = jointext(split_text, "-")
// disposals-style flip and rotate verbs
/obj/structure/c_transit_tube/verb/rotate()
set name = "Rotate Tube"
set name = "Rotate Tube CW"
set category = "Object"
set src in view(1)
if(usr.incapacitated())
return
tube_rotate()
tube_turn(-90)
/obj/structure/c_transit_tube/AltClick(mob/user)
..()
@@ -50,7 +64,18 @@
return
if(!in_range(src, user))
return
tube_rotate()
else
rotate()
/obj/structure/c_transit_tube/verb/rotate_ccw()
set name = "Rotate Tube CCW"
set category = "Object"
set src in view(1)
if(usr.incapacitated())
return
tube_turn(90)
/obj/structure/c_transit_tube/verb/flip()
set name = "Flip"
@@ -59,20 +84,25 @@
if(usr.incapacitated())
return
tube_flip()
/obj/structure/c_transit_tube/proc/buildtube()
var/obj/structure/transit_tube/R = new/obj/structure/transit_tube(src.loc)
R.icon_state = src.icon_state
R.init_dirs()
R.generate_automatic_corners(R.tube_dirs)
return R
/obj/structure/c_transit_tube/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench))
user << "<span class='notice'>You start attaching the [name]...</span>"
add_fingerprint(user)
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 40*I.toolspeed, target = src))
if(qdeleted(src))
return
src.add_fingerprint(user)
if(do_after(user, 40/I.toolspeed, target = src))
if(!src) return
user << "<span class='notice'>You attach the [name].</span>"
var/obj/structure/transit_tube/R = new build_type(loc, dir)
transfer_fingerprints_to(R)
var/obj/structure/transit_tube/R = src.buildtube()
src.transfer_fingerprints_to(R)
qdel(src)
else
return ..()
@@ -80,79 +110,51 @@
// transit tube station
/obj/structure/c_transit_tube/station
name = "unattached through station"
icon_state = "closed_station0"
build_type = /obj/structure/transit_tube/station
flipped_build_type = /obj/structure/transit_tube/station/flipped
base_icon = "closed_station"
icon = 'icons/obj/atmospherics/pipes/transit_tube_station.dmi'
icon_state = "closed"
/obj/structure/c_transit_tube/station/flipped
icon_state = "closed_station1"
flipped = 1
build_type = /obj/structure/transit_tube/station/flipped
flipped_build_type = /obj/structure/transit_tube/station
/obj/structure/c_transit_tube/station/tube_turn(var/angle)
src.setDir(turn(src.dir, angle))
/obj/structure/c_transit_tube/station/tube_flip()
src.tube_turn(180)
/obj/structure/c_transit_tube/station/buildtube()
var/obj/structure/transit_tube/station/R = new/obj/structure/transit_tube/station(src.loc)
R.setDir(src.dir)
R.init_dirs()
return R
// reverser station, used for the terminus
/obj/structure/c_transit_tube/station/reverse
name = "unattached terminus station"
icon_state = "closed_terminus0"
build_type = /obj/structure/transit_tube/station/reverse
flipped_build_type = /obj/structure/transit_tube/station/reverse/flipped
base_icon = "closed_terminus"
/obj/structure/c_transit_tube/station/reverse/flipped
icon_state = "closed_terminus1"
flipped = 1
build_type = /obj/structure/transit_tube/station/reverse/flipped
flipped_build_type = /obj/structure/transit_tube/station/reverse
/obj/structure/c_transit_tube/station/reverse/buildtube()
var/obj/structure/transit_tube/station/reverse/R = new/obj/structure/transit_tube/station/reverse(src.loc)
R.setDir(src.dir)
R.init_dirs()
return R
// block, used after the terminus of a transit tube station, decorative only
// code-wise they're normal tubes but they're ~speshul~ because they care about the dir instead of the icon_state
// in that sense they're the same as stations and can reuse their flip and rotate verbs
/obj/structure/c_transit_tube/station/block
name = "unattached tube blocker"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "Block"
/obj/structure/c_transit_tube/crossing
icon_state = "crossing"
build_type = /obj/structure/transit_tube/crossing
/obj/structure/c_transit_tube/diagonal
icon_state = "diagonal"
build_type = /obj/structure/transit_tube/diagonal
/obj/structure/c_transit_tube/diagonal/crossing
icon_state = "diagonal_crossing"
build_type = /obj/structure/transit_tube/diagonal/crossing
/obj/structure/c_transit_tube/curved
icon_state = "curved0"
build_type = /obj/structure/transit_tube/curved
flipped_build_type = /obj/structure/transit_tube/curved/flipped
base_icon = "curved"
/obj/structure/c_transit_tube/curved/flipped
icon_state = "curved1"
build_type = /obj/structure/transit_tube/curved/flipped
flipped_build_type = /obj/structure/transit_tube/curved
flipped = 1
/obj/structure/c_transit_tube/junction
icon_state = "junction0"
build_type = /obj/structure/transit_tube/junction
flipped_build_type = /obj/structure/transit_tube/junction/flipped
base_icon = "junction"
/obj/structure/c_transit_tube/junction/flipped
icon_state = "junction1"
flipped = 1
build_type = /obj/structure/transit_tube/junction/flipped
flipped_build_type = /obj/structure/transit_tube/junction
/obj/structure/c_transit_tube/station/block/buildtube()
var/obj/structure/transit_tube/R = new/obj/structure/transit_tube(src.loc)
R.icon_state = src.icon_state
R.setDir(src.dir)
R.init_dirs()
return R
//transit tube pod
//see station.dm for the logic
/obj/structure/c_transit_tube_pod
name = "unattached transit tube pod"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon = 'icons/obj/atmospherics/pipes/transit_tube_pod.dmi'
icon_state = "pod"
anchored = 0
density = 0
@@ -1,104 +1,85 @@
/obj/structure/transit_tube_pod
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon = 'icons/obj/atmospherics/pipes/transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
anchored = 1
density = 1
layer = BELOW_OBJ_LAYER
var/moving = 0
var/datum/gas_mixture/air_contents = new()
/obj/structure/transit_tube_pod/New(loc)
..()
..(loc)
air_contents.assert_gases("o2", "n2")
air_contents.gases["o2"][MOLES] = MOLES_O2STANDARD * 2
air_contents.gases["n2"][MOLES] = MOLES_N2STANDARD
air_contents.temperature = T20C
// Give auto tubes time to align before trying to start moving
spawn(5)
follow_tube()
/obj/structure/transit_tube_pod/Destroy()
empty_pod()
return ..()
for(var/atom/movable/AM in contents)
AM.loc = loc
/obj/structure/transit_tube_pod/update_icon()
if(contents.len)
icon_state = "pod_occupied"
else
icon_state = "pod"
return ..()
/obj/structure/transit_tube_pod/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/crowbar))
if(!moving)
playsound(src.loc, I.usesound, 50, 1)
if(contents.len)
for(var/obj/structure/transit_tube/station/T in loc)
return
if(src.contents.len)
user.visible_message("[user] empties \the [src].", "<span class='notice'>You empty \the [src].</span>")
empty_pod()
src.empty()
return
else
deconstruct(TRUE, user)
user << "<span class='notice'>You free \the [src].</span>"
var/obj/structure/c_transit_tube_pod/R = new/obj/structure/c_transit_tube_pod(src.loc)
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
qdel(src)
else
return ..()
/obj/structure/transit_tube_pod/deconstruct(disassembled = TRUE, mob/user)
if(!(flags & NODECONSTRUCT))
var/atom/location = get_turf(src)
if(user)
location = user.loc
add_fingerprint(user)
user.visible_message("[user] removes [src].", "<span class='notice'>You remove [src].</span>")
var/obj/structure/c_transit_tube_pod/R = new/obj/structure/c_transit_tube_pod(location)
transfer_fingerprints_to(R)
R.setDir(dir)
empty_pod(location)
qdel(src)
/obj/structure/transit_tube_pod/ex_act(severity, target)
..()
if(!qdeleted(src))
empty_pod()
/obj/structure/transit_tube_pod/contents_explosion(severity, target)
for(var/atom/movable/AM in contents)
AM.ex_act(severity, target)
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
/obj/structure/transit_tube_pod/container_resist()
var/mob/living/user = usr
if(!moving)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user << "<span class='notice'>You start trying to escape from the pod...</span>"
if(do_after(user, 600, target = src))
user << "<span class='notice'>You manage to open the pod.</span>"
empty_pod()
src.empty()
/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_icon()
/obj/structure/transit_tube_pod/proc/empty()
for(var/atom/movable/M in src.contents)
M.loc = src.loc
/obj/structure/transit_tube_pod/Process_Spacemove()
if(moving) //No drifting while moving in the tubes
return 1
else return ..()
/obj/structure/transit_tube_pod/proc/follow_tube()
/obj/structure/transit_tube_pod/proc/follow_tube(reverse_launch)
set waitfor = 0
if(moving)
return
moving = 1
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
var/last_delay = 0
var/exit_delay
if(reverse_launch)
setDir(turn(dir, 180) )// Back it up
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
@@ -141,38 +122,90 @@
density = 1
moving = 0
var/obj/structure/transit_tube/TT = locate(/obj/structure/transit_tube) in loc
if(!TT || (!(dir in TT.tube_dirs) && !(turn(dir,180) in TT.tube_dirs))) //landed on a turf without transit tube or not in our direction
deconstruct(FALSE) //we automatically deconstruct the pod
// Should I return a copy here? If the caller edits or del()s the returned
// datum, there might be problems if I don't...
/obj/structure/transit_tube_pod/return_air()
return air_contents
var/datum/gas_mixture/GM = new()
GM.copy_from(air_contents)
return GM
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
// 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/gas_mixture/environment = loc.return_air()
var/env_pressure = environment.return_pressure()
var/int_pressure = 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 = loc.remove_air(environment.total_moles() * transfer_in)
var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles() * transfer_out)
loc.assume_air(from_int)
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(istype(mob, /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.loc = loc
mob.client.Move(get_step(loc, direction), direction)
mob.reset_perspective(null)
//if(moving && istype(loc, /turf/open/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(!station.pod_moving)
if(direction == turn(station.boarding_dir,180))
if(station.open_status == STATION_TUBE_OPEN)
mob.forceMove(loc)
update_icon()
else
station.open_animation()
if(dir in station.directions())
if(!station.pod_moving)
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
mob.reset_perspective(null)
else if(direction in station.tube_dirs)
setDir(direction)
station.launch_pod()
return
else
station.open_animation()
for(var/obj/structure/transit_tube/TT in loc)
if(dir in TT.tube_dirs)
if(TT.has_exit(direction))
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
return