diff --git a/code/game/atoms.dm b/code/game/atoms.dm index ea3b9df4f54..3c541a308ff 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -305,6 +305,10 @@ /atom/proc/rpd_act() return +/atom/proc/rpd_blocksusage() + // Atoms that return TRUE prevent RPDs placing any kind of pipes on their turf. + return FALSE + /atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 270b2a99411..e84d0778ef3 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -140,6 +140,7 @@ //update the name and icon of the pipe item depending on the type /obj/item/pipe/rpd_act(mob/user, obj/item/rpd/our_rpd) + . = TRUE if(our_rpd.mode == RPD_ROTATE_MODE) rotate() else if(our_rpd.mode == RPD_FLIP_MODE) @@ -147,7 +148,7 @@ else if(our_rpd.mode == RPD_DELETE_MODE) our_rpd.delete_single_pipe(user, src) else - ..() + return ..() /obj/item/pipe/proc/update(var/obj/machinery/atmospherics/make_from) name = "[get_pipe_name(pipe_type, PIPETYPE_ATMOS)] fitting" diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 6d79a65dcbd..f1e27be33fa 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -541,6 +541,8 @@ /obj/machinery/shieldwall/attack_hand(mob/user as mob) return +/obj/machinery/shieldwall/rpd_blocksusage() + return TRUE /obj/machinery/shieldwall/process() if(needs_power) diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index ffcb2e06785..c139155b57c 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -192,11 +192,27 @@ var/list/pipemenu = list( return if(world.time < lastused + spawndelay) return + + var/turf/T = get_turf(target) - for(var/obj/machinery/shieldwall/S in T) - to_chat(user, "[S] blocks access!") - return - target.rpd_act(user, src) //Handle RPD effects in separate procs + if(target != T) + // We only check the rpd_act of the target if it isn't the turf, because otherwise + // (A) blocked turfs can be acted on, and (B) unblocked turfs get acted on twice. + if(target.rpd_act(user, src) == TRUE) + // If the object we are clicking on has a valid RPD interaction for just that specific object, do that and nothing else. + // Example: clicking on a pipe with a RPD in rotate mode should rotate that pipe and ignore everything else on the tile. + return + + // If we get this far, we have to check every object in the tile, to make sure that none of them block RPD usage on this tile. + // This is done by calling rpd_blocksusage on every /obj in the tile. If any block usage, fail at this point. + + for(var/obj/O in T) + if(O.rpd_blocksusage() == TRUE) + to_chat(user, "[O] blocks the [src]!") + return + + // If we get here, then we're effectively acting on the turf, probably placing a pipe. + T.rpd_act(user, src) #undef RPD_COOLDOWN_TIME #undef RPD_WALLBUILD_TIME diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index a7e57ce5a52..6c7094fbe9f 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -71,10 +71,6 @@ SSnanoui.close_uis(src) return ..() -/obj/rpd_act(mob/user, obj/item/rpd/our_rpd) - var/turf/T = get_turf(src) //This preserves RPD behaviour on specific turfs - T.rpd_act(user, our_rpd) - /obj/proc/process() set waitfor = 0 processing_objects.Remove(src) diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index c7e276cae17..3bb3c237d07 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -258,6 +258,7 @@ return /obj/structure/disposalconstruct/rpd_act(mob/user, obj/item/rpd/our_rpd) + . = TRUE if(our_rpd.mode == RPD_ROTATE_MODE) rotate() else if(our_rpd.mode == RPD_FLIP_MODE) @@ -265,4 +266,4 @@ else if(our_rpd.mode == RPD_DELETE_MODE) our_rpd.delete_single_pipe(user, src) else - ..() + return ..()