Skip to content

Glass Floor Transparency Fix #288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@
#define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del"
///from base of turf/multiz_turf_new: (turf/source, direction)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new"
///from base of turf/initilize_turf_transparency: (turf/source, direction)
#define COMSIG_TURF_INITIALIZE_TRANSPARENCY "initilize_turf_transparency"
//! from base of turf/proc/afterShuttleMove: (turf/new_turf)
#define COMSIG_TURF_AFTER_SHUTTLE_MOVE "turf_after_shuttle_move"

Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define WARPWHISTLE_TRAIT "warpwhistle"
///Turf trait for when a turf is transparent
#define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent"
///Turf trait for when a transparent turf should display the bottom.
#define TURF_Z_SHOW_BOTTOM_TRAIT "turf_z_show_bottom"
/// Trait applied to slimes by low temperature
#define SLIME_COLD "slime-cold"
/// Trait applied to bots by being tipped over
Expand Down
88 changes: 58 additions & 30 deletions code/datums/elements/turf_transparency.dm
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
/datum/element/turf_z_transparency
var/show_bottom_level = FALSE
var/turf/our_turf
element_flags = ELEMENT_DETACH //Important so it is properly cleared out on turf qdel.

///This proc sets up the signals to handle updating viscontents when turfs above/below update. Handle plane and layer here too so that they don't cover other obs/turfs in Dream Maker
/datum/element/turf_z_transparency/Attach(datum/target, show_bottom_level = TRUE)
/datum/element/turf_z_transparency/Attach(turf/our_turf, show_bottom_level = TRUE)
. = ..()
if(!isturf(target))
if(!isturf(our_turf))
return ELEMENT_INCOMPATIBLE

our_turf = target

src.show_bottom_level = show_bottom_level

our_turf.plane = OPENSPACE_PLANE
our_turf.layer = OPENSPACE_LAYER

RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, PROC_REF(on_multiz_turf_del), TRUE)
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, PROC_REF(on_multiz_turf_new), TRUE)
RegisterSignal(our_turf, COMSIG_TURF_MULTIZ_DEL, PROC_REF(on_multiz_turf_del), TRUE)
RegisterSignal(our_turf, COMSIG_TURF_MULTIZ_NEW, PROC_REF(on_multiz_turf_new), TRUE)
RegisterSignal(our_turf, COMSIG_TURF_INITIALIZE_TRANSPARENCY, PROC_REF(initilize_turf_transparency), TRUE)

ADD_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)


update_multiz(our_turf, TRUE, TRUE)
if(show_bottom_level) //Sets up the trait to check when initializing the turf elsewhere.
ADD_TRAIT(our_turf, TURF_Z_SHOW_BOTTOM_TRAIT, TURF_TRAIT)

/datum/element/turf_z_transparency/Detach(datum/source, force)
. = ..()
var/turf/our_turf = source
our_turf.vis_contents.len = 0
our_turf.vis_contents.len = 0 //vis_contents are handled by Destroy() when a turf is qdel'd, but you could also call Detach from elsewhere.
UnregisterSignal(our_turf, COMSIG_TURF_MULTIZ_DEL)
UnregisterSignal(our_turf, COMSIG_TURF_MULTIZ_NEW)
UnregisterSignal(our_turf, COMSIG_TURF_INITIALIZE_TRANSPARENCY)
REMOVE_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)
REMOVE_TRAIT(our_turf, TURF_Z_SHOW_BOTTOM_TRAIT, TURF_TRAIT)

///Updates the viscontents or underlays below this tile.
/datum/element/turf_z_transparency/proc/update_multiz(turf/our_turf, prune_on_fail = FALSE, init = FALSE)
Expand All @@ -39,15 +36,16 @@
if(!show_bottom_level(our_turf) && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
our_turf.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
return FALSE
if(init)
our_turf.vis_contents += below_turf
if(isclosedturf(our_turf)) //Show girders below closed turfs
var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01)
girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += girder_underlay
var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02)
plating_underlay = RESET_ALPHA | RESET_COLOR
our_turf.underlays += plating_underlay
else
if(init)
our_turf.vis_contents += below_turf
if(isclosedturf(our_turf)) //Show girders below closed turfs
var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01)
girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += girder_underlay
var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02)
plating_underlay = RESET_ALPHA | RESET_COLOR
our_turf.underlays += plating_underlay
return TRUE

/datum/element/turf_z_transparency/proc/on_multiz_turf_del(turf/our_turf, turf/T, dir)
Expand All @@ -62,17 +60,47 @@
return
update_multiz(our_turf)

/**
* Initializes, or actually gives appearance to, transparent tiles.
*
* Called via COMSIG_TURF_INITIALIZE_TRANSPARENCY from:
* ChangeTurf() - generic case for glass floors, initialized when plating turns into glass floor.
* on_applied_turf() - material application, special case. You can make transparent tiled floor, so it's initialized here as the proc calls are different.
* onShuttleMove() is a case for both glass and material floors, as it's called only when the shuttle moves.
*
* We do these calls as late as possible to get a full baseturfs list to later pass to show_bottom_level().
* This should have no effect on multi-z performance, but I have not tested it.
*
* Arguments:
* * our_turf - turf being passed to initialize transparency. Only tested on open turfs.
*/
/datum/element/turf_z_transparency/proc/initilize_turf_transparency(turf/our_turf)
SIGNAL_HANDLER
update_multiz(our_turf, TRUE, TRUE)

///Called when there is no real turf below this turf
/datum/element/turf_z_transparency/proc/show_bottom_level(turf/our_turf)
if(!show_bottom_level)
if(!HAS_TRAIT(our_turf, TURF_Z_SHOW_BOTTOM_TRAIT))
return FALSE
var/turf/path = our_turf.virtual_level_trait(ZTRAIT_BASETURF) || /turf/open/space
if(!ispath(path))
path = text2path(path)

var/turf/path
if(our_turf.baseturfs && length(our_turf.baseturfs) > 1)
path = our_turf.baseturfs[2] //Why 2? It's usually a better indicator of what we landed on.
if(ispath(path, /turf/closed)) //Do not want to show walls, looks strange.
path = our_turf.baseturfs[1] //The first element is going to be a floor of some kind.

if(!path) //Fallback to the regular, bland, method of determining a level baseturf.
//linters fix, change to this in the future:
//path = our_turf.get_z_base_turf()
path = our_turf.virtual_level_trait(ZTRAIT_BASETURF) || /turf/open/space
if(!ispath(path))
warning("Z-level [our_turf.z] has invalid baseturf '[our_turf.virtual_level_trait(ZTRAIT_BASETURF)]'")
path = /turf/open/space
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = PLANE_SPACE)
path = text2path(path)
if(!ispath(path))
warning("Z-level [our_turf.z] has invalid baseturf '[our_turf.virtual_level_trait(ZTRAIT_BASETURF)]'")
path = /turf/open/space

//PLANE_SPACE to show the parallax if it's a space tile.
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = (ispath(path, /turf/open/space) ? PLANE_SPACE : null))
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += underlay_appearance
return TRUE
4 changes: 2 additions & 2 deletions code/datums/materials/_material.dm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ Simple datum which is instanced once per type and is used for every object of sa
O.heavyfootstep = turf_sound_override
if(alpha < 255)
T.AddElement(/datum/element/turf_z_transparency, TRUE)
SEND_SIGNAL(T, COMSIG_TURF_INITIALIZE_TRANSPARENCY)
return

///This proc is called when the material is removed from an object.
Expand Down Expand Up @@ -161,8 +162,7 @@ Simple datum which is instanced once per type and is used for every object of sa
o.throwforce = initial(o.throwforce)

/datum/material/proc/on_removed_turf(turf/T, amount, material_flags)
if(alpha != 255)
RemoveElement(/datum/element/turf_z_transparency, FALSE)
return

/** Returns the composition of this material.
*
Expand Down
27 changes: 20 additions & 7 deletions code/game/turfs/change_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if(turf_type)
ChangeTurf(turf_type, baseturf_type, flags)

//This proc is actually evil. Needs a rewrite.
/turf/proc/copyTurf(turf/T, copy_air, flags)
if(T.type != type)
var/obj/O
if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay
O = new()
O.underlays.Add(T)
T.ChangeTurf(type, null, flags)
if(underlays.len)
T.underlays = O.underlays
if(T.icon_state != icon_state)
T.icon_state = icon_state
if(T.icon != icon)
Expand All @@ -36,14 +31,28 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
T.setDir(dir)
if(T.smoothing_flags != smoothing_flags)
T.smoothing_flags = smoothing_flags
if(T.alpha != alpha)
T.alpha = alpha
//PENTEST ADDITION - GLASS TRANSPARENCY FIX - START
if(custom_materials)
//If it's not a glass floor, it's a material floor with transparency (glass floors are initialized in ChangeTurf()).
if(HAS_TRAIT(src, TURF_Z_TRANSPARENT_TRAIT))
T.AddElement(/datum/element/turf_z_transparency, TRUE)
T.custom_materials = custom_materials
//PENTEST ADDITION - GLASS TRANSPARENCY FIX - END
return T

/turf/open/copyTurf(turf/T, copy_air = FALSE)
/turf/open/copyTurf(turf/open/T, copy_air = FALSE)
. = ..()
if(isopenturf(T))
if(copy_air)
var/turf/open/openTurf = T
openTurf.air.copy_from(air)
if(custom_materials) //For custom material floor overrides on footsteps.
T.footstep = footstep
T.barefootstep = barefootstep
T.clawfootstep = clawfootstep
T.heavyfootstep = heavyfootstep

//wrapper for ChangeTurf()s that you want to prevent/affect without overriding ChangeTurf() itself
/turf/proc/TerraformTurf(path, new_baseturf, flags)
Expand Down Expand Up @@ -129,6 +138,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(

W.virtual_z = old_virtual_z

//We need baseturfs and virtual_z to be set before sending this signal.
if(!(flags & CHANGETURF_DEFER_CHANGE)) //Travel transparency initialization is handled in onShuttleMove().
SEND_SIGNAL(W, COMSIG_TURF_INITIALIZE_TRANSPARENCY)

lighting_corner_NE = old_lighting_corner_NE
lighting_corner_SE = old_lighting_corner_SE
lighting_corner_SW = old_lighting_corner_SW
Expand Down
10 changes: 3 additions & 7 deletions code/game/turfs/open/glass.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/turf/open/floor/glass
name = "Glass floor"
name = "glass floor"
desc = "While it at first appears to be a dangerous glass floor over space, closer inspection reveals it to simply be a screen behind a layer of glass."
icon = 'icons/turf/floors/glass.dmi'
icon_state = "glass-0"
Expand All @@ -16,15 +16,11 @@

/turf/open/floor/glass/Initialize(mapload, inherited_virtual_z)
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
..()
return INITIALIZE_HINT_LATELOAD

/turf/open/floor/glass/LateInitialize()
. = ..()
AddElement(/datum/element/turf_z_transparency, TRUE)
. = ..()

/turf/open/floor/glass/reinforced
name = "Reinforced glass floor"
name = "reinforced glass floor"
desc = "While it at first appears to be a dangerous glass floor over space, closer inspection reveals it to simply be a screen behind a reinforced protective layer of glass."
icon = 'icons/turf/floors/reinf_glass.dmi'
icon_state = "reinf_glass-0"
Expand Down
2 changes: 2 additions & 0 deletions code/modules/shuttle/on_move.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ All ShuttleMove procs go here
for(var/i in 0 to new_loc.get_missing_shuttles(newT)) //Start at 0 because get_missing_shuttles() will report 1 less missing shuttle because of the CopyOnTop()
newT.baseturfs.Insert(inject_index, /turf/baseturf_skipover/shuttle)

SEND_SIGNAL(newT, COMSIG_TURF_INITIALIZE_TRANSPARENCY) //After baseturfs ares established, we send this signal. Deferred to here on travel, otherwise usually performed in ChangeTurf().

return TRUE

// Called on the new turf after everything has been moved
Expand Down
Loading