Workaround BYOND bug by switching floor decals from turf overlays to a magic overlay object.

* New atom to hold a turf's decal overlays instead of the turf itself.
* Change floor_decal initialization to use it instead, and change other decal/overlay interaction procs to use it instead.
* Add floor decal initialization to master controller to do them in one fel swoop instead of nickel and diming.
* Stop area init from updating open space turfs; let the open space controller do it.
This commit is contained in:
Leshana
2017-05-18 19:11:51 -04:00
parent 48eb4a0a49
commit a8c9bb786a
6 changed files with 126 additions and 51 deletions

View File

@@ -57,16 +57,31 @@ datum/controller/game_controller/proc/setup_objects()
//Set up spawn points.
populate_spawn_points()
admin_notice("<span class='danger'>Initializing Floor Decals</span>", R_DEBUG)
var/list/turfs_with_decals = list()
for(var/obj/effect/floor_decal/D in world)
var/T = D.add_to_turf_decals()
if(T) turfs_with_decals |= T
CHECK_SLEEP_MASTER
for(var/item in turfs_with_decals)
var/turf/T = item
if(T.decals) T.apply_decals()
CHECK_SLEEP_MASTER
floor_decals_initialized = TRUE
sleep(1)
admin_notice("<span class='danger'>Initializing objects</span>", R_DEBUG)
for(var/obj/object in world)
if(isnull(object.gcDestroyed))
object.initialize()
CHECK_SLEEP_MASTER
sleep(1)
admin_notice("<span class='danger'>Initializing areas</span>", R_DEBUG)
for(var/area/area in all_areas)
area.initialize()
CHECK_SLEEP_MASTER
sleep(1)
admin_notice("<span class='danger'>Initializing pipe networks</span>", R_DEBUG)
for(var/obj/machinery/atmospherics/machine in machines)

View File

@@ -14,56 +14,16 @@ var/list/floor_decals = list()
if(newcolour) color = newcolour
..(newloc)
// VOREStation Edit - Hack to workaround byond crash bug
/obj/effect/floor_decal/initialize()
if(supplied_dir) set_dir(supplied_dir)
if(!floor_decals_initialized || !loc || deleted(src))
return
add_to_turf_decals()
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
var/cache_key = "[alpha]-[color]-[dir]-[icon_state]-[layer]"
var/image/I = floor_decals[cache_key]
if(!I)
I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir)
I.layer = T.layer
I.color = src.color
I.alpha = src.alpha
floor_decals[cache_key] = I
if(!T.decals) T.decals = list()
T.decals += I
var/pre_overlay_count = T.overlays.len
T.overlays += I
var/post_overlay_count = T.overlays.len
if(pre_overlay_count + 1 != post_overlay_count)
world.log << "Corrupted turf repair during decal init at: [x],[y],[z]"
var/list/tempdecals = T.decals
var/old_affecting_lights = T.affecting_lights
var/old_lighting_overlay = T.lighting_overlay
var/old_corners = T.corners
if(T.connections) T.connections.erase_all()
for(var/obj/machinery/atmospherics/pipe/P in T.contents)
P.initialize()
var/turf/newturf = new T.type(T)
if(air_master)
air_master.mark_for_update(newturf) //handle the addition of the new turf.
if(lighting_overlays_initialised)
newturf.lighting_overlay = old_lighting_overlay
newturf.affecting_lights = old_affecting_lights
newturf.corners = old_corners
newturf.recalc_atom_opacity()
if(tempdecals)
newturf.decals = tempdecals
for(var/image/old in tempdecals)
var/pre_ovr = newturf.overlays.len
newturf.overlays += old
if(newturf.overlays.len != pre_ovr +1)
return
var/prenew = newturf.overlays.len
newturf.overlays += I
if(newturf.overlays.len != prenew +1)
return
qdel(src)
T.apply_decals()
qdel(src)
return
// VOREStation Edit End
/obj/effect/floor_decal/reset
name = "reset marker"

View File

@@ -0,0 +1,90 @@
//
// Initialize floor decals! Woo! This is crazy.
//
var/global/floor_decals_initialized = FALSE
// The Turf Decal Holder
// Since it is unsafe to add overlays to turfs, we hold them here for now.
// Since I want this object to basically not exist, I am modeling it in part after lighting_overlay
/atom/movable/turf_overlay_holder
name = "turf overlay holder"
density = 0
simulated = 0
anchored = 1
layer = TURF_LAYER
icon = null
icon_state = null
mouse_opacity = 0
auto_init = 0
/atom/movable/turf_overlay_holder/New(var/atom/newloc)
..()
verbs.Cut()
var/turf/T = loc
T.overlay_holder = src
/atom/movable/turf_overlay_holder/Destroy()
if(loc)
var/turf/T = loc
if(T.overlay_holder == src)
T.overlay_holder = null
. = ..()
// Variety of overrides so the overlays don't get affected by weird things.
/atom/movable/turf_overlay_holder/ex_act()
return
/atom/movable/turf_overlay_holder/singularity_act()
return
/atom/movable/turf_overlay_holder/singularity_pull()
return
/atom/movable/turf_overlay_holder/forceMove()
return 0 //should never move
/atom/movable/turf_overlay_holder/Move()
return 0
/atom/movable/turf_overlay_holder/throw_at()
return 0
/obj/effect/floor_decal/proc/add_to_turf_decals()
if(src.supplied_dir) src.set_dir(src.supplied_dir)
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
var/cache_key = "[src.alpha]-[src.color]-[src.dir]-[src.icon_state]-[T.layer]"
var/image/I = floor_decals[cache_key]
if(!I)
I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir)
I.layer = T.layer
I.color = src.color
I.alpha = src.alpha
floor_decals[cache_key] = I
if(!T.decals) T.decals = list()
//world.log << "About to add img:\ref[I] onto decals at turf:\ref[T] ([T.x],[T.y],[T.z]) which has appearance:\ref[T.appearance] and decals.len=[T.decals.len]"
T.decals += I
return T
// qdel(D)
src.loc = null
src.tag = null
// Changes to turf to let us do this
/turf
var/atom/movable/turf_overlay_holder/overlay_holder = null
// After a turf change, destroy the old overlay holder since we will have lost access to it.
/turf/post_change()
var/atom/movable/turf_overlay_holder/TOH = locate(/atom/movable/turf_overlay_holder, src)
if(TOH)
qdel(TOH)
..()
/turf/proc/apply_decals()
if(decals)
if(!overlay_holder)
overlay_holder = new(src)
overlay_holder.overlays = src.decals
else if(overlay_holder)
overlay_holder.overlays.Cut()

View File

@@ -60,8 +60,11 @@ var/list/flooring_cache = list()
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)
if(decals && decals.len)
overlays |= decals
// VOREStation Edit - Hack workaround to byond crash bug
//if(decals && decals.len)
//overlays |= decals
apply_decals()
// VOREStation Edit End
if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo
icon = 'icons/turf/flooring/plating.dmi'

View File

@@ -54,7 +54,7 @@
levelupdate()
for(var/atom/movable/A in src)
A.fall()
update_icon()
OS_controller.add_turf(src, 1)
// override to make sure nothing is hidden
/turf/simulated/open/levelupdate()
@@ -85,7 +85,13 @@
bottom_turf.plane = src.plane
bottom_turf.color = below.color
underlays += bottom_turf
overlays += below.overlays
// VOREStation Edit - Hack workaround to byond crash bug - Include the magic overlay holder object.
//overlays += below.overlays
if(below.overlay_holder)
overlays += (below.overlays + below.overlay_holder.overlays)
else
overlays += below.overlays
// VOREStation Edit End
// get objects (not mobs, they are handled by /obj/zshadow)
var/image/o_img = list()

View File

@@ -1070,6 +1070,7 @@
#include "code\game\turfs\flooring\flooring_premade.dm"
#include "code\game\turfs\flooring\flooring_vr.dm"
#include "code\game\turfs\flooring\shuttle_vr.dm"
#include "code\game\turfs\flooring\turf_overlay_holder.dm"
#include "code\game\turfs\initialization\init.dm"
#include "code\game\turfs\initialization\maintenance.dm"
#include "code\game\turfs\simulated\floor.dm"