Files
Bubberstation/code/controllers/subsystem/overlays.dm
Waterpig bb70889f6e TG Upstream Part 1
3591 individual conflicts

Update build.js

Update install_node.sh

Update byond.js

oh my fucking god

hat

slow

huh

holy shit

we all fall down

2 more I missed

2900 individual conflicts

2700 Individual conflicts

replaces yarn file with tg version, bumping us down to 2200-ish

Down to 2000 individual conflicts

140 down

mmm

aaaaaaaaaaaaaaaaaaa

not yt

575

soon

900 individual conflicts

600 individual conflicts, 121 file conflicts

im not okay

160 across 19 files

29 in 4 files

0 conflicts, compiletime fix time

some minor incap stuff

missed ticks

weird dupe definition stuff

missed ticks 2

incap fixes

undefs and pie fix

Radio update and some extra minor stuff

returns a single override

no more dupe definitions, 175 compiletime errors

Unticked file fix

sound and emote stuff

honk and more radio stuff
2024-10-19 08:04:33 -07:00

234 lines
7.6 KiB
Plaintext

SUBSYSTEM_DEF(overlays)
name = "Overlay"
flags = SS_NO_FIRE|SS_NO_INIT
var/list/stats
/datum/controller/subsystem/overlays/PreInit()
stats = list()
/datum/controller/subsystem/overlays/Shutdown()
text2file(render_stats(stats), "[GLOB.log_directory]/overlay.log")
/datum/controller/subsystem/overlays/Recover()
stats = SSoverlays.stats
/// Converts an overlay list into text for debug printing
/// Of note: overlays aren't actually mutable appearances, they're just appearances
/// Don't have access to that type tho, so this is the best you're gonna get
/proc/overlays2text(list/overlays)
var/list/unique_overlays = list()
// As anything because we're basically doing type coercion, rather then actually filtering for mutable appearances
for(var/mutable_appearance/overlay as anything in overlays)
var/key = "[overlay.icon]-[overlay.icon_state]-[overlay.dir]"
unique_overlays[key] += 1
var/list/output_text = list()
for(var/key in unique_overlays)
output_text += "([key]) = [unique_overlays[key]]"
return output_text.Join("\n")
/proc/iconstate2appearance(icon, iconstate)
var/static/image/stringbro = new()
stringbro.icon = icon
stringbro.icon_state = iconstate
return stringbro.appearance
/proc/icon2appearance(icon)
var/static/image/iconbro = new()
iconbro.icon = icon
return iconbro.appearance
/atom/proc/build_appearance_list(list/build_overlays)
if (!islist(build_overlays))
build_overlays = list(build_overlays)
for (var/overlay in build_overlays)
if(!overlay)
build_overlays -= overlay
continue
if (istext(overlay))
// This is too expensive to run normally but running it during CI is a good test
if (PERFORM_ALL_TESTS(focus_only/invalid_overlays))
var/list/icon_states_available = icon_states(icon)
if(!(overlay in icon_states_available))
var/icon_file = "[icon]" || "Unknown Generated Icon"
stack_trace("Invalid overlay: Icon object '[icon_file]' [REF(icon)] used in '[src]' [type] is missing icon state [overlay].")
continue
var/index = build_overlays.Find(overlay)
build_overlays[index] = iconstate2appearance(icon, overlay)
else if(isicon(overlay))
var/index = build_overlays.Find(overlay)
build_overlays[index] = icon2appearance(overlay)
return build_overlays
/atom/proc/cut_overlays()
STAT_START_STOPWATCH
overlays = null
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
/atom/proc/cut_overlay(list/remove_overlays)
if(!overlays)
return
STAT_START_STOPWATCH
overlays -= build_appearance_list(remove_overlays)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
/atom/proc/add_overlay(list/add_overlays)
if(!overlays)
return
STAT_START_STOPWATCH
overlays += build_appearance_list(add_overlays)
VALIDATE_OVERLAY_LIMIT(src)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom
if(!other)
if(cut_old)
cut_overlays()
return
STAT_START_STOPWATCH
var/list/cached_other = other.overlays.Copy()
if(cut_old)
if(cached_other)
overlays = cached_other
else
overlays = null
VALIDATE_OVERLAY_LIMIT(src)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
else if(cached_other)
overlays += cached_other
VALIDATE_OVERLAY_LIMIT(src)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
//TODO: Better solution for these?
/image/proc/add_overlay(x)
overlays |= x
/image/proc/cut_overlay(x)
overlays -= x
/image/proc/cut_overlays(x)
overlays.Cut()
/image/proc/copy_overlays(atom/other, cut_old)
if(!other)
if(cut_old)
cut_overlays()
return
var/list/cached_other = other.overlays.Copy()
if(cached_other)
if(cut_old || !overlays.len)
overlays = cached_other
else
overlays |= cached_other
else if(cut_old)
cut_overlays()
// Debug procs
/atom
/// List of overlay "keys" (info about the appearance) -> mutable versions of static appearances
/// Drawn from the overlays list
var/list/realized_overlays
/// List of underlay "keys" (info about the appearance) -> mutable versions of static appearances
/// Drawn from the underlays list
var/list/realized_underlays
/image
/// List of overlay "keys" (info about the appearance) -> mutable versions of static appearances
/// Drawn from the overlays list
var/list/realized_overlays
/// List of underlay "keys" (info about the appearance) -> mutable versions of static appearances
/// Drawn from the underlays list
var/list/realized_underlays
/// Takes the atoms's existing overlays and underlays, and makes them mutable so they can be properly vv'd in the realized_overlays/underlays list
/atom/proc/realize_overlays()
realized_overlays = realize_appearance_queue(overlays)
realized_underlays = realize_appearance_queue(underlays)
/// Takes the image's existing overlays, and makes them mutable so they can be properly vv'd in the realized_overlays list
/image/proc/realize_overlays()
realized_overlays = realize_appearance_queue(overlays)
realized_underlays = realize_appearance_queue(underlays)
/// Takes a list of appearnces, makes them mutable so they can be properly vv'd and inspected
/proc/realize_appearance_queue(list/appearances)
var/list/real_appearances = list()
var/list/queue = appearances.Copy()
var/queue_index = 0
while(queue_index < length(queue))
queue_index++
// If it's not a command, we assert that it's an appearance
var/mutable_appearance/appearance = queue[queue_index]
if(!appearance) // Who fucking adds nulls to their sublists god you people are the worst
continue
var/mutable_appearance/new_appearance = new /mutable_appearance()
new_appearance.appearance = appearance
var/key = "[appearance.icon]-[appearance.icon_state]-[appearance.plane]-[appearance.layer]-[appearance.dir]-[appearance.color]"
var/tmp_key = key
var/appearance_indx = 1
while(real_appearances[tmp_key])
tmp_key = "[key]-[appearance_indx]"
appearance_indx++
real_appearances[tmp_key] = new_appearance
var/add_index = queue_index
// Now check its children
for(var/mutable_appearance/child_appearance as anything in appearance.overlays)
add_index++
queue.Insert(add_index, child_appearance)
for(var/mutable_appearance/child_appearance as anything in appearance.underlays)
add_index++
queue.Insert(add_index, child_appearance)
return real_appearances
/// Takes two appearances as args, prints out, logs, and returns a text representation of their differences
/// Including suboverlays
/proc/diff_appearances(mutable_appearance/first, mutable_appearance/second, iter = 0)
var/list/diffs = list()
var/list/firstdeet = first.vars
var/list/seconddeet = second.vars
var/diff_found = FALSE
for(var/name in first.vars)
var/firstv = firstdeet[name]
var/secondv = seconddeet[name]
if(firstv ~= secondv)
continue
if((islist(firstv) || islist(secondv)) && length(firstv) == 0 && length(secondv) == 0)
continue
if(name == "vars") // Go away
continue
if(name == "_listen_lookup") // This is just gonna happen with marked datums, don't care
continue
if(name == "overlays")
first.realize_overlays()
second.realize_overlays()
var/overlays_differ = FALSE
for(var/i in 1 to length(first.realized_overlays))
if(diff_appearances(first.realized_overlays[i], second.realized_overlays[i], iter + 1))
overlays_differ = TRUE
if(!overlays_differ)
continue
diff_found = TRUE
diffs += "Diffs detected at [name]: First ([firstv]), Second ([secondv])"
var/text = "Depth of: [iter]\n\t[diffs.Join("\n\t")]"
message_admins(text)
log_world(text)
return diff_found