Refactor /turf/var/intact (#62331)

Turfs have a variable, intact, which conflates three meanings:

    Determining whether there's something that can be pried out, such as directly with a crowbar or indirectly with a tile stack and a crowbar off-hand.
    Determining whether underfloor pieces are visible.
    Determining whether underfloor pieces can be interacted with - by players with tools, through interaction with effects like chemical acid, or foam.

When plating is hit with a stack of tiles, /turf/open/floor/attackby checks whether the turf is intact, and if so, ends the attack chain regardless of whether or not the attempt to hotswap a turf (with a crowbar) is successful or not. However, turfs which want the underfloor to be visible - such as catwalks and glass - set the intact variable to FALSE, and so can be repeatedly placed over one another, as if they were the first tile to be placed over the plating.

This refactors /turf/var/intact into two distinct variables:

    /turf/var/overfloor_placed, for whether or not there is something over plating.
    /turf/var/underfloor_visible, for whether or not the various underfloor pieces should be invisible, visible, or both visible and interactable.

All references to /turf/var/intact have been replaced with an equivalent overfloor_placed or underfloor_visible reference, depending on which check is appropriate. underfloor_accessibility can take one of UNDERFLOOR_HIDDEN, UNDERFLOOR_VISIBLE, or UNDERFLOOR_INTERACTABLE. This prevents cases such as acid foam or tools phasing through glass floors to affect the underfloor pieces underneath, and covers all kinds of unusual, not-wiring-visiblity usage such as Holodeck completeness, Revenant interaction, or station integrity checking.
This commit is contained in:
esainane
2021-10-28 19:14:40 -03:00
committed by GitHub
parent 2343a73dba
commit d521116acf
29 changed files with 58 additions and 46 deletions
+4
View File
@@ -22,3 +22,7 @@
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3]))
#define UNDERFLOOR_HIDDEN 0
#define UNDERFLOOR_VISIBLE 1
#define UNDERFLOOR_INTERACTABLE 2
+1 -1
View File
@@ -41,7 +41,7 @@ SUBSYSTEM_DEF(minor_mapping)
var/turf/T = pick_n_take(turfs)
var/obj/item/storage/backpack/satchel/flat/F = new(T)
SEND_SIGNAL(F, COMSIG_OBJ_HIDE, T.intact)
SEND_SIGNAL(F, COMSIG_OBJ_HIDE, T.underfloor_accessibility < UNDERFLOOR_VISIBLE)
amount--
/proc/find_exposed_wires()
+2 -2
View File
@@ -294,10 +294,10 @@
net.add_plumber(src, dir)
net.add_plumber(P, opposite_dir)
/datum/component/plumbing/proc/hide(atom/movable/AM, intact)
/datum/component/plumbing/proc/hide(atom/movable/AM, should_hide)
SIGNAL_HANDLER
tile_covered = intact
tile_covered = should_hide
AM.update_appearance()
/datum/component/plumbing/proc/change_ducting_layer(obj/caller, obj/O, new_layer = DUCT_LAYER_DEFAULT)
+2 -6
View File
@@ -38,15 +38,11 @@
floor += 2
if(iswallturf(T))
var/turf/closed/wall/TW = T
if(TW.intact)
wall += 2
else
wall += 1
wall += 1
if(istype(T, /turf/closed/wall/r_wall))
var/turf/closed/wall/r_wall/TRW = T
if(TRW.intact)
if(TRW.d_state == INTACT)
r_wall += 2
else
r_wall += 1
+2 -2
View File
@@ -98,7 +98,7 @@
/obj/machinery/navbeacon/attackby(obj/item/I, mob/user, params)
var/turf/T = loc
if(T.intact)
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
return // prevent intraction when T-scanner revealed
if(I.tool_behaviour == TOOL_SCREWDRIVER)
@@ -131,7 +131,7 @@
. = ..()
var/ai = isAI(user)
var/turf/T = loc
if(T.intact)
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
return // prevent intraction when T-scanner revealed
if(!open && !ai) // can't alter controls if not open, unless you're an AI
+1 -1
View File
@@ -142,7 +142,7 @@
if(!O.anchored)
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
continue
var/mob/living/target = locate() in view(4,src)
if(target && !target.stat)
@@ -144,7 +144,7 @@
continue
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
continue
if(lifetime % reagent_divisor)
reagents.expose(O, VAPOR, fraction)
@@ -241,7 +241,7 @@
for(var/atom/movable/AM in T)
if(AM.type == src.type)
continue
if(T.intact && HAS_TRAIT(AM, TRAIT_T_RAY_VISIBLE))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(AM, TRAIT_T_RAY_VISIBLE))
continue
reagents.expose(AM, TOUCH, fraction)
+1 -1
View File
@@ -78,7 +78,7 @@
if(I.tool_behaviour == TOOL_WRENCH)
if(mode == DISCONNECTED)
var/turf/T = loc
if(isturf(T) && !T.intact)
if(isturf(T) && T.underfloor_accessibility >= UNDERFLOOR_INTERACTABLE)
attached = locate() in T
if(!attached)
to_chat(user, span_warning("\The [src] must be placed over an exposed, powered cable node!"))
+2 -2
View File
@@ -45,7 +45,7 @@
return
if(isturf(loc))
var/turf/T = loc
if(T.intact && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
return
take_damage(400, BRUTE, MELEE, 0, get_dir(src, B))
@@ -127,7 +127,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
/obj/fire_act(exposed_temperature, exposed_volume)
if(isturf(loc))
var/turf/T = loc
if(T.intact && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
return
if(exposed_temperature && !(resistance_flags & FIRE_PROOF))
take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0)
+4 -3
View File
@@ -18,9 +18,10 @@
thermal_conductivity = 0.04
heat_capacity = 10000
intact = TRUE
tiled_dirt = TRUE
overfloor_placed = TRUE
var/broken = FALSE
var/burnt = FALSE
var/floor_tile = null //tile that this floor drops
@@ -166,7 +167,7 @@
. = ..()
if(.)
return .
if(intact && istype(object, /obj/item/stack/tile))
if(overfloor_placed && istype(object, /obj/item/stack/tile))
try_replace_tile(object, user, params)
return TRUE
if(user.combat_mode && istype(object, /obj/item/stack/sheet))
@@ -175,7 +176,7 @@
return FALSE
/turf/open/floor/crowbar_act(mob/living/user, obj/item/I)
if(intact && pry_tile(I, user))
if(overfloor_placed && pry_tile(I, user))
return TRUE
/turf/open/floor/proc/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
@@ -13,6 +13,7 @@
baseturfs = /turf/open/floor/plating
floor_tile = /obj/item/stack/tile/catwalk_tile
footstep = FOOTSTEP_CATWALK
overfloor_placed = TRUE
var/covered = TRUE
/turf/open/floor/plating/catwalk_floor/Initialize(mapload)
+2 -1
View File
@@ -11,7 +11,8 @@
name = "plating"
icon_state = "plating"
base_icon_state = "plating"
intact = FALSE
overfloor_placed = FALSE
underfloor_accessibility = UNDERFLOOR_INTERACTABLE
baseturfs = /turf/baseturf_bottom
footstep = FOOTSTEP_PLATING
barefootstep = FOOTSTEP_HARD_BAREFOOT
+2 -1
View File
@@ -5,7 +5,8 @@
icon_state = "glass-0"
base_icon_state = "glass"
baseturfs = /turf/open/openspace
intact = FALSE //this means wires go on top
overfloor_placed = FALSE // We can't tear this up, with tools, explosives, or other means.
underfloor_accessibility = UNDERFLOOR_VISIBLE
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = list(SMOOTH_GROUP_TURF_OPEN, SMOOTH_GROUP_FLOOR_TRANSPARENT_GLASS)
canSmoothWith = list(SMOOTH_GROUP_FLOOR_TRANSPARENT_GLASS)
+2 -1
View File
@@ -18,7 +18,8 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
baseturfs = /turf/open/openspace
can_atmos_pass_vertical = ATMOS_PASS_YES
baseturfs = /turf/open/openspace
intact = FALSE //this means wires go on top
overfloor_placed = FALSE
underfloor_accessibility = UNDERFLOOR_INTERACTABLE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/can_cover_up = TRUE
var/can_build_on = TRUE
+2 -1
View File
@@ -2,7 +2,8 @@
icon = 'icons/turf/space.dmi'
icon_state = "0"
name = "\proper space"
intact = 0
overfloor_placed = FALSE
underfloor_accessibility = UNDERFLOOR_INTERACTABLE
temperature = TCMB
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
+9 -5
View File
@@ -8,7 +8,11 @@ GLOBAL_LIST_EMPTY(station_turfs)
/// Turf bitflags, see code/__DEFINES/flags.dm
var/turf_flags = NONE
var/intact = 1
/// If there's a tile over a basic floor that can be ripped out
var/overfloor_placed = FALSE
/// How accessible underfloor pieces such as wires, pipes, etc are on this turf. Can be HIDDEN, VISIBLE, or INTERACTABLE.
var/underfloor_accessibility = UNDERFLOOR_HIDDEN
// baseturfs can be either a list or a single turf type.
// In class definition like here it should always be a single type.
@@ -413,7 +417,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
/turf/proc/levelupdate()
for(var/obj/O in src)
if(O.flags_1 & INITIALIZED_1)
SEND_SIGNAL(O, COMSIG_OBJ_HIDE, intact)
SEND_SIGNAL(O, COMSIG_OBJ_HIDE, underfloor_accessibility < UNDERFLOOR_VISIBLE)
// override for space turfs, since they should never hide anything
/turf/open/space/levelupdate()
@@ -464,7 +468,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
////////////////////////////////////////////////////
/turf/singularity_act()
if(intact)
if(underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
for(var/obj/O in contents) //this is for deleting things like wires contained in the turf
if(HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
O.singularity_act()
@@ -475,7 +479,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
return TRUE
/turf/proc/can_lay_cable()
return can_have_cabling() & !intact
return can_have_cabling() && underfloor_accessibility >= UNDERFLOOR_INTERACTABLE
/turf/proc/visibilityChanged()
GLOB.cameranet.updateVisibility(src)
@@ -550,7 +554,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
AddComponent(/datum/component/acid, acidpwr, acid_volume)
for(var/obj/O in src)
if(intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
if(underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
continue
O.acid_act(acidpwr, acid_volume)
@@ -257,7 +257,7 @@
if(!isplatingturf(T) && !istype(T, /turf/open/floor/engine/cult) && isfloorturf(T) && prob(15))
var/turf/open/floor/floor = T
if(floor.intact && floor.floor_tile)
if(floor.overfloor_placed && floor.floor_tile)
new floor.floor_tile(floor)
floor.broken = 0
floor.burnt = 0
+7 -5
View File
@@ -25,6 +25,9 @@ and clear when youre done! if you dont i will use :newspaper2: on you
#define HOLODECK_CD 2 SECONDS
#define HOLODECK_DMG_CD 5 SECONDS
/// typecache for turfs that should be considered ok during floorchecks.
/// A linked turf being anything not in this typecache will cause the holodeck to perform an emergency shutdown.
GLOBAL_LIST_INIT(typecache_holodeck_linked_floorcheck_ok, typecacheof(list(/turf/open/floor/holofloor, /turf/closed)))
/obj/machinery/computer/holodeck
name = "holodeck control console"
@@ -365,13 +368,12 @@ and clear when youre done! if you dont i will use :newspaper2: on you
active = FALSE
load_program(offline_program, TRUE)
///returns TRUE if the entire floor of the holodeck is intact, returns FALSE if any are broken
///returns TRUE if all floors of the holodeck are present, returns FALSE if any are broken or removed
/obj/machinery/computer/holodeck/proc/floorcheck()
for(var/turf/holo_floor in linked)
if(isspaceturf(holo_floor))
return FALSE
if(!holo_floor.intact)
return FALSE
if (is_type_in_typecache(holo_floor, GLOB.typecache_holodeck_linked_floorcheck_ok))
continue
return FALSE
return TRUE
///changes all weapons in the holodeck to do stamina damage if set
+1 -1
View File
@@ -148,7 +148,7 @@
/turf/open/floor/holofloor/carpet/update_icon(updates=ALL)
. = ..()
if((updates & UPDATE_SMOOTHING) && intact && smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
if((updates & UPDATE_SMOOTHING) && overfloor_placed && smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
QUEUE_SMOOTH(src)
/turf/open/floor/holofloor/wood
@@ -91,7 +91,7 @@
/mob/living/simple_animal/mouse/handle_automated_action()
if(prob(chew_probability))
var/turf/open/floor/F = get_turf(src)
if(istype(F) && !F.intact)
if(istype(F) && F.underfloor_accessibility >= UNDERFLOOR_INTERACTABLE)
var/obj/structure/cable/C = locate() in F
if(C && prob(15))
var/powered = C.avail()
@@ -292,7 +292,7 @@
. = ..()
if(prob(40))
var/turf/open/floor/F = get_turf(src)
if(istype(F) && !F.intact)
if(istype(F) && F.underfloor_accessibility >= UNDERFLOOR_INTERACTABLE)
var/obj/structure/cable/C = locate() in F
if(C && prob(15))
if(C.avail())
+1 -1
View File
@@ -636,7 +636,7 @@
var/turf/host_turf = get_turf(src)
if(!host_turf)
CRASH("attackby on APC when it's not on a turf")
if (host_turf.intact)
if (host_turf.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
to_chat(user, span_warning("You must remove the floor plating in front of the APC first!"))
return
else if (terminal)
+2 -2
View File
@@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
/obj/structure/cable/proc/handlecable(obj/item/W, mob/user, params)
var/turf/T = get_turf(src)
if(T.intact)
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
return
if(W.tool_behaviour == TOOL_WIRECUTTER)
if (shock(user, 50))
@@ -567,7 +567,7 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
if(!isturf(user.loc))
return
if(!isturf(T) || T.intact || !T.can_have_cabling())
if(!isturf(T) || T.underfloor_accessibility || !T.can_have_cabling())
to_chat(user, span_warning("You can only lay cables on catwalks and plating!"))
return
+1 -1
View File
@@ -210,7 +210,7 @@
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
var/turf/T = user.loc
if(T.intact || !isfloorturf(T))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE || !isfloorturf(T))
return
if(get_dist(src, user) > 1)
return
+1 -1
View File
@@ -116,7 +116,7 @@
return
var/turf/T = get_turf(user)
if (T.intact) //is the floor plating removed ?
if (T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE) //can we get to the underfloor?
to_chat(user, span_warning("You must first remove the floor plating!"))
return
+1 -1
View File
@@ -42,7 +42,7 @@
/obj/machinery/power/terminal/proc/dismantle(mob/living/user, obj/item/I)
if(isturf(loc))
var/turf/T = loc
if(T.intact)
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE)
to_chat(user, span_warning("You must first expose the power terminal!"))
return
@@ -116,7 +116,7 @@
var/ispipe = is_pipe() // Indicates if we should change the level of this pipe
var/turf/T = get_turf(src)
if(T.intact && isfloorturf(T))
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && isfloorturf(T))
var/obj/item/crowbar/held_crowbar = user.is_holding_item_of_type(/obj/item/crowbar)
if(!held_crowbar || !T.crowbar_act(user, held_crowbar))
to_chat(user, span_warning("You can only attach the [pipename] if the floor plating is removed!"))
+1 -1
View File
@@ -93,7 +93,7 @@
var/eject_range = 5
var/turf/open/floor/floorturf
if(isfloorturf(T) && T.intact) //intact floor, pop the tile
if(isfloorturf(T) && T.overfloor_placed) // pop the tile if present
floorturf = T
if(floorturf.floor_tile)
new floorturf.floor_tile(T)