mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 06:29:23 +01:00
[MIRROR] Fix runtime with RPD unwrenching. (#1606)
* Fix runtime with RPD unwrenching. (#54773) [01:44:12] Runtime in RPD.dm, line 392: Cannot read 1.type /obj/machinery/atmospherics/wrench_act can return a boolean instead of an object under the following scenarios: You cannot unwrench the machine. You can unwrench the machine, but use_tool later returns FALSE instead of TRUE. use_tool can fail when you stack wrench_acts ontop of eachother. The first wrench_act will work as expected and return the deconstructed version of the pipe, all other stacked wrench_acts will have use_tool fail and will instead just return TRUE. This PR prevents stacking of wrench_act-based do_afters and guards against unexpected runtimes by CRASHing when wrench_act returns something unexpected. * Fix runtime with RPD unwrenching. Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk>
This commit is contained in:
@@ -378,35 +378,39 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit))
|
||||
return ..()
|
||||
|
||||
var/atom/attack_target = A
|
||||
|
||||
//So that changing the menu settings doesn't affect the pipes already being built.
|
||||
var/queued_p_type = recipe.id
|
||||
var/queued_p_dir = p_dir
|
||||
var/queued_p_flipped = p_flipped
|
||||
|
||||
//Unwrench pipe before we build one over/paint it.
|
||||
if((mode & DESTROY_MODE) && (upgrade_flags & RPD_UPGRADE_UNWRENCH) && istype(A, /obj/machinery/atmospherics))
|
||||
A = A.wrench_act(user, src)
|
||||
//Unwrench pipe before we build one over/paint it, but only if we're not already running a do_after on it already to prevent a potential runtime.
|
||||
if((mode & DESTROY_MODE) && (upgrade_flags & RPD_UPGRADE_UNWRENCH) && istype(attack_target, /obj/machinery/atmospherics) && !(attack_target in user.do_afters))
|
||||
attack_target = attack_target.wrench_act(user, src)
|
||||
if(!isatom(attack_target))
|
||||
CRASH("When attempting to call [A.type].wrench_act(), received the following non-atom return value: [attack_target]")
|
||||
|
||||
//make sure what we're clicking is valid for the current category
|
||||
var/static/list/make_pipe_whitelist
|
||||
if(!make_pipe_whitelist)
|
||||
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille))
|
||||
if(istype(A, /obj/machinery/atmospherics) && (mode & BUILD_MODE && !(mode & PAINT_MODE))) //Reduces pixelhunt when coloring is off.
|
||||
A = get_turf(A)
|
||||
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
|
||||
if(istype(attack_target, /obj/machinery/atmospherics) && (mode & BUILD_MODE && !(mode & PAINT_MODE))) //Reduces pixelhunt when coloring is off.
|
||||
attack_target = get_turf(attack_target)
|
||||
var/can_make_pipe = (isturf(attack_target) || is_type_in_typecache(attack_target, make_pipe_whitelist))
|
||||
|
||||
. = TRUE
|
||||
|
||||
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
|
||||
if((mode & DESTROY_MODE) && istype(attack_target, /obj/item/pipe) || istype(attack_target, /obj/structure/disposalconstruct) || istype(attack_target, /obj/structure/c_transit_tube) || istype(attack_target, /obj/structure/c_transit_tube_pod) || istype(attack_target, /obj/item/pipe_meter))
|
||||
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
if(do_after(user, destroy_speed, target = A))
|
||||
if(do_after(user, destroy_speed, target = attack_target))
|
||||
activate()
|
||||
qdel(A)
|
||||
qdel(attack_target)
|
||||
return
|
||||
|
||||
if((mode & PAINT_MODE))
|
||||
var/obj/machinery/atmospherics/M = A
|
||||
var/obj/machinery/atmospherics/M = attack_target
|
||||
if(istype(M) && M.paintable)
|
||||
to_chat(user, "<span class='notice'>You start painting \the [M] [paint_color]...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
@@ -414,7 +418,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
M.paint(GLOB.pipe_paint_colors[paint_color]) //paint the pipe
|
||||
user.visible_message("<span class='notice'>[user] paints \the [M] [paint_color].</span>","<span class='notice'>You paint \the [M] [paint_color].</span>")
|
||||
return
|
||||
var/obj/item/pipe/I = A
|
||||
var/obj/item/pipe/I = attack_target
|
||||
if(istype(I) && I.paintable)
|
||||
to_chat(user, "<span class='notice'>You start painting \the [I] [paint_color]...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
@@ -431,9 +435,9 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
if (recipe.type == /datum/pipe_info/meter)
|
||||
to_chat(user, "<span class='notice'>You start building a meter...</span>")
|
||||
if(do_after(user, atmos_build_speed, target = A))
|
||||
if(do_after(user, atmos_build_speed, target = attack_target))
|
||||
activate()
|
||||
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
|
||||
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(attack_target))
|
||||
PM.setAttachLayer(piping_layer)
|
||||
if(mode & WRENCH_MODE)
|
||||
PM.wrench_act(user, src)
|
||||
@@ -442,14 +446,14 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
to_chat(user, "<span class='notice'>You can't build this object on the layer...</span>")
|
||||
return ..()
|
||||
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
|
||||
if(do_after(user, atmos_build_speed, target = A))
|
||||
if(do_after(user, atmos_build_speed, target = attack_target))
|
||||
if(recipe.all_layers == FALSE && (piping_layer == 1 || piping_layer == 5))//double check to stop cheaters (and to not waste time waiting for something that can't be placed)
|
||||
to_chat(user, "<span class='notice'>You can't build this object on the layer...</span>")
|
||||
return ..()
|
||||
activate()
|
||||
var/obj/machinery/atmospherics/path = queued_p_type
|
||||
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
|
||||
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), queued_p_type, queued_p_dir)
|
||||
var/obj/item/pipe/P = new pipe_item_type(get_turf(attack_target), queued_p_type, queued_p_dir)
|
||||
|
||||
if(queued_p_flipped && istype(P, /obj/item/pipe/trinary/flippable))
|
||||
var/obj/item/pipe/trinary/flippable/F = P
|
||||
@@ -466,14 +470,14 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if(DISPOSALS_CATEGORY) //Making disposals pipes
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(isclosedturf(A))
|
||||
attack_target = get_turf(attack_target)
|
||||
if(isclosedturf(attack_target))
|
||||
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a disposals pipe...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
if(do_after(user, disposal_build_speed, target = A))
|
||||
var/obj/structure/disposalconstruct/C = new (A, queued_p_type, queued_p_dir, queued_p_flipped)
|
||||
if(do_after(user, disposal_build_speed, target = attack_target))
|
||||
var/obj/structure/disposalconstruct/C = new (attack_target, queued_p_type, queued_p_dir, queued_p_flipped)
|
||||
|
||||
if(!C.can_place())
|
||||
to_chat(user, "<span class='warning'>There's not enough room to build that here!</span>")
|
||||
@@ -491,22 +495,22 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
if(TRANSIT_CATEGORY) //Making transit tubes
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(isclosedturf(A))
|
||||
attack_target = get_turf(attack_target)
|
||||
if(isclosedturf(attack_target))
|
||||
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a transit tube...</span>")
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
if(do_after(user, transit_build_speed, target = A))
|
||||
if(do_after(user, transit_build_speed, target = attack_target))
|
||||
activate()
|
||||
if(queued_p_type == /obj/structure/c_transit_tube_pod)
|
||||
var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(A)
|
||||
var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(attack_target)
|
||||
pod.add_fingerprint(usr)
|
||||
if(mode & WRENCH_MODE)
|
||||
pod.wrench_act(user, src)
|
||||
|
||||
else
|
||||
var/obj/structure/c_transit_tube/tube = new queued_p_type(A)
|
||||
var/obj/structure/c_transit_tube/tube = new queued_p_type(attack_target)
|
||||
tube.setDir(queued_p_dir)
|
||||
|
||||
if(queued_p_flipped)
|
||||
|
||||
Reference in New Issue
Block a user