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..2a1edbfa870 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/transit_tube_pod)) + return + + if (get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 ) return if (pipe.anchored) @@ -196,3 +199,79 @@ 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
+Clockwise Curved Tube
+Counterclockwise Curved Tube
+Diagonal Tube
+Clockwise Junction
+Counterclockwise 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 <= 6) + 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 = "S-NW" + if(4) + C.icon_state = "NE-SW" + if(5) + C.icon_state = "W-NE-SE" + if(6) + C.icon_state = "S-NE-NW" + C.add_fingerprint(usr) + else + switch(tube_type) + if(7) + var/obj/structure/c_transit_tube/station/C = new/obj/structure/c_transit_tube/station(src.loc) + C.add_fingerprint(usr) + if(8) + var/obj/structure/c_transit_tube/station/reverse/C = new/obj/structure/c_transit_tube/station/reverse(src.loc) + C.add_fingerprint(usr) + if(9) + var/obj/structure/c_transit_tube/station/block/C = new/obj/structure/c_transit_tube/station/block(src.loc) + C.add_fingerprint(usr) + if(10) + 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..ce38f66f96a 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -40,6 +40,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 +90,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..162aea555a2 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" @@ -48,6 +47,30 @@ 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)) + 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, 80)) + user << "You deattach the [name]!" + if(copytext(icon_state, 1, 3) != "D-") + if(istype(src, /obj/structure/transit_tube/station/reverse)) + var/obj/structure/R = new/obj/structure/c_transit_tube/station/reverse(src.loc) + src.transfer_fingerprints_to(R) + R.add_fingerprint(user) + else if(istype(src, /obj/structure/transit_tube/station)) + var/obj/structure/R = new/obj/structure/c_transit_tube/station(src.loc) + src.transfer_fingerprints_to(R) + R.add_fingerprint(user) + else + var/obj/structure/R = new/obj/structure/c_transit_tube(src.loc) + R.icon_state = src.icon_state + src.transfer_fingerprints_to(R) + R.add_fingerprint(user) + qdel(src) // Called to check if a pod should stop upon entering this tube. /obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir) @@ -258,53 +281,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..72daccb3969 --- /dev/null +++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm @@ -0,0 +1,132 @@ +// transit tube construction +//TODO: dispenser, restrict flip/rotate, testing + +// 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 + +// 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.stat) + return + + tube_turn(-90) + +//not a real flip because it won't mirror junction pipe exits +//yes i am autistic +/obj/structure/c_transit_tube/verb/flip() + set name = "Rotate Tube Twice" + set category = "Object" + set src in view(1) + + if(usr.stat) + return + + tube_turn(180) + +/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/rotate() + set name = "Rotate Tube" + set category = "Object" + set src in view(1) + + if(usr.stat) + return + + src.dir = turn(src.dir, -90) + +/obj/structure/c_transit_tube/station/flip() + set name = "Rotate Tube Twice" + set category = "Object" + set src in view(1) + + if(usr.stat) + return + + src.dir = turn(src.dir, 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 + 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"