diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 6e63e537952..433bfc66de3 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -7,6 +7,7 @@ * angle2dir * angle2text * worldtime2text + * text2dir_extended & dir2text_short */ //Returns an integer given a hex input, supports negative values "-ff" @@ -405,3 +406,51 @@ for(var/t in test_times) /proc/isLeap(y) return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + +// A copy of text2dir, extended to accept one and two letter +// directions, and to clearly return 0 otherwise. +/proc/text2dir_extended(direction) + switch(uppertext(direction)) + if("NORTH", "N") + return 1 + if("SOUTH", "S") + return 2 + if("EAST", "E") + return 4 + if("WEST", "W") + return 8 + if("NORTHEAST", "NE") + return 5 + if("NORTHWEST", "NW") + return 9 + if("SOUTHEAST", "SE") + return 6 + if("SOUTHWEST", "SW") + return 10 + else + return 0 + + + +// A copy of dir2text, which returns the short one or two letter +// directions used in tube icon states. +/proc/dir2text_short(direction) + switch(direction) + if(1) + return "N" + if(2) + return "S" + if(4) + return "E" + if(8) + return "W" + if(5) + return "NE" + if(6) + return "SE" + if(9) + return "NW" + if(10) + return "SW" + else + return diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index a1aeefc9618..ee7ad2dd4d3 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -123,12 +123,15 @@ Nah */ -//Allow you to drag-drop disposal pipes into it -/obj/machinery/pipedispenser/disposal/MouseDrop_T(var/obj/structure/disposalconstruct/pipe as obj, mob/usr as mob) +//Allow you to drag-drop disposal pipes and transit tubes into it +/obj/machinery/pipedispenser/disposal/MouseDrop_T(var/obj/structure/pipe as obj, mob/usr as mob) if(!usr.canmove || usr.stat || usr.restrained()) return - if (!istype(pipe) || get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 ) + if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod)) + return + + if (get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 ) return if (pipe.anchored) @@ -196,3 +199,73 @@ Nah wait = 0 return +//transit tube dispenser +//inherit disposal for the dragging proc +/obj/machinery/pipedispenser/disposal/transit_tube + name = "transit tube dispenser" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "pipe_d" + density = 1 + anchored = 1.0 + +/obj/machinery/pipedispenser/disposal/transit_tube/attack_hand(user as mob) + if(..()) + return + + var/dat = {"Transit Tubes:
+Straight Tube
+Straight Tube with Crossing
+Curved Tube
+Diagonal Tube
+Junction
+Station Equipment:
+Through Tube Station
+Terminus Tube Station
+Tube Blocker
+Transit Tube Pod
+"} + + user << browse("[src][dat]", "window=pipedispenser") + return + + +/obj/machinery/pipedispenser/disposal/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + src.add_fingerprint(usr) + if(!wait) + if(href_list["tube"]) + var/tube_type = text2num(href_list["tube"]) + if(tube_type <= 4) + var/obj/structure/c_transit_tube/C = new/obj/structure/c_transit_tube(src.loc) + switch(tube_type) + if(0) + C.icon_state = "E-W" + if(1) + C.icon_state = "E-W-Pass" + if(2) + C.icon_state = "S-NE" + if(3) + C.icon_state = "NE-SW" + if(4) + C.icon_state = "W-NE-SE" + C.add_fingerprint(usr) + else + switch(tube_type) + if(5) + var/obj/structure/c_transit_tube/station/C = new/obj/structure/c_transit_tube/station(src.loc) + C.add_fingerprint(usr) + if(6) + var/obj/structure/c_transit_tube/station/reverse/C = new/obj/structure/c_transit_tube/station/reverse(src.loc) + C.add_fingerprint(usr) + if(7) + var/obj/structure/c_transit_tube/station/block/C = new/obj/structure/c_transit_tube/station/block(src.loc) + C.add_fingerprint(usr) + if(8) + var/obj/structure/c_transit_tube_pod/C = new/obj/structure/c_transit_tube_pod(src.loc) + C.add_fingerprint(usr) + wait = 1 + spawn(15) + wait = 0 + return diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 327b1aa5906..315c5f0cd4d 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -8,6 +8,7 @@ icon_state = "closed" exit_delay = 2 enter_delay = 3 + tube_construction = /obj/structure/c_transit_tube/station var/pod_moving = 0 var/automatic_launch_time = 100 var/cooldown_delay = 200 @@ -27,6 +28,7 @@ // 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) @@ -40,6 +42,20 @@ return +//pod insertion +/obj/structure/transit_tube/station/MouseDrop_T(obj/structure/c_transit_tube_pod/R as obj, mob/user as mob) + if(!usr.canmove || usr.stat || usr.restrained()) + return + if (!istype(R) || get_dist(user, src) > 1 || get_dist(src,R) > 1) + return + var/obj/structure/transit_tube_pod/T = new/obj/structure/transit_tube_pod(src) + R.transfer_fingerprints_to(T) + T.add_fingerprint(usr) + T.loc = src.loc + T.dir = turn(src.dir, -90) + user.visible_message("[user] inserts the [R].", "You insert the [R].") + qdel(R) + /obj/structure/transit_tube/station/attack_hand(mob/user as mob) if(!pod_moving) @@ -76,6 +92,17 @@ src.Bumped(GM) qdel(G) break + if(istype(W, /obj/item/weapon/crowbar)) + for(var/obj/structure/transit_tube_pod/pod in loc) + if(pod.contents) + user << "Empty the pod first." + return + user.visible_message("[user] removes the [pod].", "You remove the [pod].") + 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) + ..(W, user) /obj/structure/transit_tube/station/proc/open_animation() if(icon_state == "closed") diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index 707dbb015df..152820d77dc 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -1,4 +1,3 @@ - // Basic transit tubes. Straight pieces, curved sections, // and basic splits/joins (no routing logic). // Mappers: you can use "Generate Instances from Icon-states" @@ -9,6 +8,7 @@ density = 1 layer = 3.1 anchored = 1.0 + var/tube_construction = /obj/structure/c_transit_tube var/list/tube_dirs = null var/exit_delay = 2 var/enter_delay = 1 @@ -48,6 +48,37 @@ obj/structure/transit_tube/ex_act(severity) if(tube_dirs == null) init_dirs() +/obj/structure/transit_tube/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/weapon/wrench)) + if(copytext(icon_state, 1, 3) != "D-") //decorative diagonals cannot be unwrenched directly + for(var/obj/structure/transit_tube_pod/pod in loc) + user << "Remove the pod first." + return + user.visible_message("[user] starts to deattach the [src]!", "You start deattaching the [name]...") + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 35)) + user << "You deattach the [name]!" + 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) + +//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) @@ -57,7 +88,6 @@ obj/structure/transit_tube/ex_act(severity) /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. @@ -258,53 +288,3 @@ obj/structure/transit_tube/ex_act(severity) direction_table[text] = directions return directions - - - -// A copy of text2dir, extended to accept one and two letter -// directions, and to clearly return 0 otherwise. -/obj/structure/transit_tube/proc/text2dir_extended(direction) - switch(uppertext(direction)) - if("NORTH", "N") - return 1 - if("SOUTH", "S") - return 2 - if("EAST", "E") - return 4 - if("WEST", "W") - return 8 - if("NORTHEAST", "NE") - return 5 - if("NORTHWEST", "NW") - return 9 - if("SOUTHEAST", "SE") - return 6 - if("SOUTHWEST", "SW") - return 10 - else - return 0 - - - -// A copy of dir2text, which returns the short one or two letter -// directions used in tube icon states. -/obj/structure/transit_tube/proc/dir2text_short(direction) - switch(direction) - if(1) - return "N" - if(2) - return "S" - if(4) - return "E" - if(8) - return "W" - if(5) - return "NE" - if(6) - return "SE" - if(9) - return "NW" - if(10) - return "SW" - else - return diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm new file mode 100644 index 00000000000..5806f16e349 --- /dev/null +++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm @@ -0,0 +1,132 @@ +// transit tube construction + +// normal transit tubes +/obj/structure/c_transit_tube + name = "unattached transit tube" + icon = 'icons/obj/pipes/transit_tube.dmi' + icon_state = "E-W" //icon_state decides which tube will be built + density = 0 + layer = 3.1 //same as the built tube + anchored = 0.0 + +//wrapper for turn that changes the transit tube formatted icon_state instead of the dir +/obj/structure/c_transit_tube/proc/tube_turn(var/angle) + var/list/badtubes = list("W-E", "W-E-Pass", "S-N", "S-N-Pass", "SW-NE", "SE-NW") + var/list/split_text = text2list(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 = list2text(split_text, "-") + if(badtubes.Find(newdir)) + split_text.Swap(1,2) + newdir = list2text(split_text, "-") + icon_state = newdir + +/obj/structure/c_transit_tube/proc/tube_flip() + var/list/split_text = text2list(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) + //for curves, swap the diagonal direction that is not in the same axis as the cardinal direction + else + 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 = list2text(split_text, "-") + +// disposals-style flip and rotate verbs +/obj/structure/c_transit_tube/verb/rotate() + set name = "Rotate Tube" + set category = "Object" + set src in view(1) + + if(usr.canUseTopic()) + return + + tube_turn(-90) + +/obj/structure/c_transit_tube/verb/flip() + set name = "Flip" + set category = "Object" + set src in view(1) + + if(usr.canUseTopic()) + 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(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/weapon/wrench)) + user << "You start attaching the [name]..." + src.add_fingerprint(user) + if(do_after(user, 40)) + if(!src) return + user << "You attach the [name]!" + var/obj/structure/transit_tube/R = src.buildtube() + src.transfer_fingerprints_to(R) + qdel(src) + return + +// transit tube station +/obj/structure/c_transit_tube/station + name = "unattached through station" + icon = 'icons/obj/pipes/transit_tube_station.dmi' + icon_state = "closed" + +/obj/structure/c_transit_tube/station/tube_turn(var/angle) + src.dir = 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.dir = src.dir + R.init_dirs() + return R + +// reverser station, used for the terminus +/obj/structure/c_transit_tube/station/reverse + name = "unattached terminus station" + +/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.dir = 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/pipes/transit_tube.dmi' + icon_state = "Block" + +/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.dir = 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/pipes/transit_tube_pod.dmi' + icon_state = "pod" + anchored = 0.0 + density = 0 diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 1eb1910a7fc..a787db9a347 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -25,6 +25,23 @@ ..() +/obj/structure/transit_tube_pod/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/weapon/crowbar)) + if(!moving) + for(var/obj/structure/transit_tube/station/T in loc) + return + if(src.contents) + user.visible_message("[user] empties the [src].", "You empty the [src].") + for(var/atom/movable/M in src.contents) + M.loc = src.loc + return + else + user << "You free the [src]." + 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) + /obj/structure/transit_tube_pod/proc/follow_tube(var/reverse_launch) if(moving) return diff --git a/tgstation.dme b/tgstation.dme index 3918643a73c..1aa51b82d88 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -672,6 +672,7 @@ #include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm" #include "code\game\objects\structures\stool_bed_chair_nest\stools.dm" #include "code\game\objects\structures\transit_tubes\station.dm" +#include "code\game\objects\structures\transit_tubes\transit_tube_construction.dm" #include "code\game\objects\structures\transit_tubes\transit_tube.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_pod.dm" #include "code\game\pooling\atom_pool.dm"