diff --git a/code/__DEFINES/pipes.dm b/code/__DEFINES/pipes.dm index 8eadcae54e6..ec5fbd01cd9 100644 --- a/code/__DEFINES/pipes.dm +++ b/code/__DEFINES/pipes.dm @@ -1,5 +1,4 @@ -//Atmospherics pipes - +// MARK: Atmospherics pipes #define PIPE_SIMPLE_STRAIGHT 0 #define PIPE_SIMPLE_BENT 1 #define PIPE_HE_STRAIGHT 2 @@ -41,8 +40,7 @@ #define PIPE_GAS_SENSOR 98 #define PIPE_METER 99 -//Disposals pipes - +// MARK: Disposals pipes #define PIPE_DISPOSALS_STRAIGHT 100 #define PIPE_DISPOSALS_BENT 101 #define PIPE_DISPOSALS_JUNCTION_RIGHT 102 @@ -55,7 +53,7 @@ #define PIPE_DISPOSALS_SORT_RIGHT 109 #define PIPE_DISPOSALS_SORT_LEFT 110 -// Transit tubes +// MARK: Transit tubes #define PIPE_TRANSIT_POD 200 #define PIPE_TRANSIT_TUBE 201 #define PIPE_TRANSIT_TUBE_DIAGONAL 202 @@ -65,8 +63,7 @@ #define PIPE_TRANSIT_TUBE_TERMINUS_DISPENSER 206 #define PIPE_TRANSIT_TUBE_DISPENSER_STATION 207 -//RPD stuff - +// MARK: RPD stuff #define RPD_ATMOS_MODE 1 #define RPD_DISPOSALS_MODE 2 #define RPD_ROTATE_MODE 3 @@ -84,8 +81,9 @@ #define PIPETYPE_DISPOSAL 2 #define PIPETYPE_TRANSIT 3 -// Connection types +#define RPD_TOOL_SUCCESS (1<<1) +// MARK: Connection types #define CONNECT_TYPE_NORMAL 1 #define CONNECT_TYPE_SUPPLY 2 #define CONNECT_TYPE_SCRUBBER 3 diff --git a/code/game/machinery/pipe/pipe_construction.dm b/code/game/machinery/pipe/pipe_construction.dm index 51304148e0e..2a8771237cc 100644 --- a/code/game/machinery/pipe/pipe_construction.dm +++ b/code/game/machinery/pipe/pipe_construction.dm @@ -341,7 +341,6 @@ /obj/item/pipe/wrench_act(mob/user, obj/item/I) . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return @@ -528,6 +527,7 @@ "You fasten [src].", "You hear a ratchet.") qdel(src) // remove the pipe item + . |= RPD_TOOL_SUCCESS /obj/item/pipe_meter name = "meter" diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index 89043519bfe..bc55bdcf4c6 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -39,6 +39,7 @@ var/ranged = FALSE var/primary_sound = 'sound/machines/click.ogg' var/alt_sound = null + var/auto_wrench_toggle = TRUE //Lists of things var/list/mainmenu = list( @@ -114,8 +115,7 @@ else if(!iconrotation) //If user selected a rotation P.dir = user.dir to_chat(user, "[src] rapidly dispenses [P]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(P, user.get_inactive_hand()))) - P.wrench_act(user, user.get_inactive_hand()) + automatic_wrench_down(user, P) activate_rpd(TRUE) /obj/item/rpd/proc/create_disposals_pipe(mob/user, turf/T) //Make a disposals pipe / construct @@ -127,8 +127,7 @@ if(!iconrotation && whatdpipe != PIPE_DISPOSALS_JUNCTION_RIGHT) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though P.flip() to_chat(user, "[src] rapidly dispenses [P]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(P, user.get_inactive_hand()))) - P.attackby(user.get_inactive_hand(), user) + automatic_wrench_down(user, P) activate_rpd(TRUE) /obj/item/rpd/proc/create_transit_tube(mob/user, turf/dest) @@ -144,8 +143,7 @@ S.dir = iconrotation ? iconrotation : user.dir to_chat(user, "[src] rapidly dispenses [S]!") - if(istype(user.get_inactive_hand(), /obj/item/wrench) && (user.can_reach(S, user.get_inactive_hand()))) - S.wrench_act(user, user.get_inactive_hand()) + automatic_wrench_down(user, S) activate_rpd(TRUE) /obj/item/rpd/proc/rotate_all_pipes(mob/user, turf/T) //Rotate all pipes on a turf @@ -195,6 +193,22 @@ QDEL_NULL(P) activate_rpd() +/** + * Automatically wrenches down an atmos device/pipe if the auto_wrench_toggle is TRUE. + * Arguments: + * * user - the user of the RPD. + * * target - the pipe/device/tube being placed by the RPD. + */ +/obj/item/rpd/proc/automatic_wrench_down(mob/living/user, obj/item/target) + if(!auto_wrench_toggle) + return + if(mode == RPD_TRANSIT_MODE) + if(target.screwdriver_act(user, src) & RPD_TOOL_SUCCESS) + playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) + return + if(target.wrench_act(user, src) & RPD_TOOL_SUCCESS) + playsound(src, 'sound/items/impactwrench.ogg', 50, TRUE) + return // TGUI stuff /obj/item/rpd/attack_self(mob/user) @@ -228,6 +242,7 @@ data["whatdpipe"] = whatdpipe data["whatpipe"] = whatpipe data["whatttube"] = whatttube + data["auto_wrench_toggle"] = auto_wrench_toggle return data /obj/item/rpd/ui_act(action, list/params) @@ -249,6 +264,8 @@ pipe_category = isnum(params[action]) ? params[action] : text2num(params[action]) if("mode") mode = isnum(params[action]) ? params[action] : text2num(params[action]) + if("auto_wrench_toggle") + auto_wrench_toggle = !auto_wrench_toggle //RPD radial menu /obj/item/rpd/proc/check_menu(mob/living/user) @@ -325,14 +342,17 @@ // If we get here, then we're effectively acting on the turf, probably placing a pipe. if(ranged) //woosh beam if bluespaced at a distance - if(get_dist(src, T) <= (user.client.maxview() + 2))\ - user.Beam(T, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 5) - else + if(get_dist(src, T) >= (user.client.maxview() + 2)) message_admins("\[EXPLOIT] [key_name_admin(user)] attempted to place pipes with a BRPD via a camera console. (Attempted range exploit)") playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE) to_chat(user, "ERROR: \The [T] is out of [src]'s range!") return + if(!(user in viewers(12, T))) // Checks if the user can see the target turf + to_chat(user, "[src] needs full visibility to determine the dispensing location.") + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE) + return + user.Beam(T, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 0.5 SECONDS) T.rpd_act(user, src) /obj/item/rpd/attack_obj(obj/O, mob/living/user) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm index 9836fb7343f..0878ca196be 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm @@ -9,6 +9,7 @@ var/installed_type = null var/installed_type_flipped = null var/flipped = FALSE + var/is_station = FALSE /obj/structure/transit_tube_construction/proc/rotate() setDir(turn(dir, -90)) @@ -43,20 +44,25 @@ . = TRUE var/turf/T = get_turf(src) if(!isfloorturf(T) && !isspaceturf(T)) - to_chat(user, "You cannot install [src] here.") + to_chat(user, "You cannot install [src] here.") return for(var/obj/turf_contents in T) // It's okay for tube parts to be installed over existing pods. if(!istype(turf_contents, /obj/structure/transit_tube_pod) && turf_contents.density) - to_chat(user, "There is not enough space to install [src] here.") + to_chat(user, "There is not enough space to install [src] here.") return + if(is_station && !user.can_reach(src)) + to_chat(user, "[src] must be installed manually.") + return var/install_type = flipped ? installed_type_flipped : installed_type var/atom/installed = new install_type(T) installed.dir = dir user.visible_message("[user] installs [src].") + I.play_tool_sound(src, I.tool_volume) qdel(src) + . |= RPD_TOOL_SUCCESS /obj/structure/transit_tube_construction/wrench_act(mob/living/user, obj/item/I) . = TRUE @@ -93,7 +99,7 @@ qdel(src) - to_chat(user, "[src] can only be installed in a transit tube!") + to_chat(user, "[src] can only be installed in a transit tube!") /obj/structure/transit_tube_construction/straight installed_type = /obj/structure/transit_tube @@ -121,14 +127,17 @@ installed_type = /obj/structure/transit_tube/station base_icon_state = "transit_station" icon_state = "transit_station" + is_station = TRUE /obj/structure/transit_tube_construction/terminus/dispenser installed_type = /obj/structure/transit_tube/station/dispenser/reverse installed_type_flipped = /obj/structure/transit_tube/station/dispenser/reverse/flipped base_icon_state = "transit_dispenser_terminus" icon_state = "transit_dispenser_terminus" + is_station = TRUE /obj/structure/transit_tube_construction/station/dispenser installed_type = /obj/structure/transit_tube/station/dispenser base_icon_state = "transit_dispenser_station" icon_state = "transit_dispenser_station" + is_station = TRUE diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 4efce256902..0ddbc578c37 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -138,27 +138,31 @@ // weldingtool: convert to real pipe /obj/structure/disposalconstruct/wrench_act(mob/living/user, obj/item/I) + . = TRUE var/ispipe = is_pipe() var/nicetype = get_nice_name() - if(anchored) - anchored = FALSE - if(ispipe) - level = 2 - density = FALSE - else - density = TRUE - to_chat(user, "You detach the [nicetype] from the underfloor.") + var/turf/T = get_turf(src) + + if(T.intact) + to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") + return + + if(ispipe) + anchored = !anchored + level = anchored ? 1 : 2 + to_chat(user, anchored ? "You attach the [nicetype] to the underfloor." : "You detach the [nicetype] from the underfloor.") else - anchored = TRUE - if(ispipe) - level = 1 // We don't want disposal bins to disappear under the floors - density = FALSE - else - density = TRUE // We don't want disposal bins or outlets to go density 0 - to_chat(user, "You attach the [nicetype] to the underfloor.") + var/obj/structure/disposalpipe/trunk/CT = locate() in T //For disposal bins, chutes, outlets. + if(!CT) + to_chat(user, "The [nicetype] requires a trunk underneath it in order to be anchored.") + return + anchored = !anchored + density = anchored + to_chat(user, anchored ? "You attach the [nicetype] to the trunk." : "You detach the [nicetype] from the trunk.") + I.play_tool_sound(src, I.tool_volume) update() - return TRUE + . |= RPD_TOOL_SUCCESS /obj/structure/disposalconstruct/proc/is_pipe() switch(ptype) @@ -186,18 +190,17 @@ /obj/structure/disposalconstruct/attackby(obj/item/I, mob/user, params) var/nicetype = get_nice_name() var/ispipe = is_pipe() // Indicates if we should change the level of this pipe + var/turf/T = get_turf(src) add_fingerprint(user) - - var/turf/T = src.loc if(T.intact) - to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") + to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") return if(ptype in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE)) // Disposal or outlet var/obj/structure/disposalpipe/trunk/CP = locate() in T if(!CP) // There's no trunk - to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") + to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") return else for(var/obj/structure/disposalpipe/CP in T) @@ -207,15 +210,15 @@ if(istype(CP, /obj/structure/disposalpipe/broken)) pdir = CP.dir if(pdir & dpdir) - to_chat(user, "There is already a [nicetype] at that location.") + to_chat(user, "There is already a [nicetype] at that location.") return if(istype(I, /obj/item/weldingtool)) if(anchored) if(I.tool_use_check(user, 0)) - to_chat(user, "Welding the [nicetype] in place.") + to_chat(user, "You begin welding the [nicetype] in place.") if(I.use_tool(src, user, 20, volume = I.tool_volume)) - to_chat(user, "The [nicetype] has been welded in place!") + to_chat(user, "You have welded the [nicetype] in place!") update() // TODO: Make this neat if(ispipe) // Pipe @@ -252,10 +255,10 @@ qdel(src) return else - to_chat(user, "You need more welding fuel to complete this task.") + to_chat(user, "You need more welding fuel to complete this task.") return else - to_chat(user, "You need to attach it to the plating first!") + to_chat(user, "You need to attach it to the plating first!") return /obj/structure/disposalconstruct/rpd_act(mob/user, obj/item/rpd/our_rpd) diff --git a/tgui/packages/tgui/interfaces/RPD.js b/tgui/packages/tgui/interfaces/RPD.js index 468a0aa5675..a1a3574771b 100644 --- a/tgui/packages/tgui/interfaces/RPD.js +++ b/tgui/packages/tgui/interfaces/RPD.js @@ -101,20 +101,11 @@ const AtmosPipeContent = (props, context) => {
+ {pipelist .filter((p) => p.pipe_type === 1 && p.pipe_id === whatpipe && p.orientations !== 1) .map((p) => ( - -