Files
Yogstation/code/controllers/subsystem/demo.dm
Chubbygummibear 0fda5cfc6a Icon smoothing, and Rendering overhaul, and Camera fix, and mapmerge.py fix, and Multi-z, and THE PLANE CUBE (#21221)
* why no work

angy

* weird errors

shit sucks

* fixved it

I can spell good

* fix?

POSSIBLY

* nope

wasnt this

* no more immutable

thhanks koffee

* ok

ok

* removes all the pref stuff

""removes""

* remove this

idiot

* this goes bye

 bye

* these go too

genius

* bye

bye

* better night vision

* tries to fix camera

maybe

* ok fuck it we ball

we ball

* ok lets go back

go back go back go back

* WORK

DAMNIT

* ha

fuc kyou

* this

maybe

* this doesnt work :(

* maybe fix

maybe

* fucks everything

why do i do this

* test update

test

* Revert "tries to fix camera"

This reverts commit 2d14fbae66.

* reverts everything I just did

peko pain

* bye

bitch

* oh yeah add this

I guess

* Fucks up the camera net + chunk

why

* test maybe revert

* Revert "test maybe revert"

This reverts commit 98c5ef1b93.

* Revert "Fucks up the camera net + chunk"

This reverts commit 0e421ebf5f.

* this isnt going well

uh oh

* Attempts to rework out security camera

and probably more

* Revert "this isnt going well"

This reverts commit 1d8ceac867.

* Revert "Revert "this isnt going well""

This reverts commit e26fb61415.

* ok

ok

* Revert "ok"

This reverts commit 7e7a7f8372.

* Revert "Merge remote-tracking branch 'upstream/master' into NahI'dPortit"

This reverts commit 01094731c1, reversing
changes made to c0cf69ebf1.

* this doesn't need to be redefined

I guess

* no we need this

totally

* a familiar pain

* 515 is L

* yeah

yeah

* ok god

fine

* bye bye basemap :(

doesnt work on runtime station

* Fixes AI statis not working

god im good

* remove this

oh god

* Revert "Revert "Merge remote-tracking branch 'upstream/master' into NahI'dPortit""

This reverts commit b3fb3ba0db.

* proves to god I exist

and im pissed

* yog exclusive feature (tm)

plane master

* bring this back from previous push

* updates vendor emissives

as well as firealarms

* Updates barsign

and fucks everything up

* Fixes barsigns breaks all lights and updates barsigns to be machines and not structures

We will address this in a later patch

* not sure who changed that

oh well

* yeah

this got moved

* this needs updating

yeah

* turns off the carbon monoxide alarm

duh

* FIXES IT YES

thank you biome

* turns this off too

yeah

* Can't compile yet but ports a ton of shit

* L

* the game opens ig

* extra shit

* fixes

* signals and smooth queue

* look ma im going horribly out of scope

* fixes chasms

* this fixed nothing

* ???

* more barsigns

for later

* forgive me cowboy. also fuck diagonals

* oops

we need this apparently

* fuck it we ball

* Update _lists.dm

* Update icon_smoothing.dm

* it now works kinda

* Update atom_initializing_EXPENSIVE.dm

* lighting don't work

* we have light

* sort turfs better

* big fucking reorganize

* like everything except templates

* boy i sure hope nothing bad happens to these bar templates

* we're back

* no runtimes baby

* no errors

* shuttles are almost fixed i think

* Revert "shuttles are almost fixed i think"

This reverts commit 046058827c.

* Revert "Merge remote-tracking branch 'upstream/master' into icon_smoothing"

This reverts commit 863e1b776d, reversing
changes made to 884623e600.

* Revert "no errors"

This reverts commit 884623e600.

* too far back i think

* midround smoothing runtimes fixed i think

* comment cleanup

* should fix the component runtimes

* Revert "Revert "Merge remote-tracking branch 'upstream/master' into icon_smoothing""

This reverts commit a8ff8d63aa.

* NO RUNTIMES AND ICEMETA WORKS LET'S GOOOOOO

* please stay fixed icemeta

* organizing render dms

* woops this too in the reorganizing

* cryo fixed

* nah, i'd win

* parallax isn't my problem

* pls don't break icemeta

* runtime station gets a cam console

* well it compiles

* maybe fix the map

* woops

* man i hate maps

* was that it?

* PLEASE

* missing focus tests

* maybe that was it

* maybe

* let's take the batteries out of the carbon monoxide detector

* fuck osha

* i hate vending machines

* that's not a computer

* slot machine fix

* PLEASE

* that wasn't supposed to be there

* fuck it i can't fix everything at once

* BLUESPACE LOCKER?

* literally why

* hhh

* does this fix chasms?

* that should fix bad index

* please?

* turf_flags for reservations

* haha oops

* yolo (kill me)

* fix wood walls and other walls

* fix stairs

* that might have fixed shittles

* baseturfs are good now i think

* should fix plasma windows

* decals fixed

* please fix changelog

* shuttle lighting still fucky

* lighting is stinky slow and doesn't finish updating by the time the server starts guh

* lighting seemingly works

* slipping works

* shuttle sounds, slips, and windoors fixed

* why am i here

* fuck the changelog

* of course someone touched smoothing as i'm almost done

* we good?

* updating ai_eye and rename

* z updates and more ai cam updates

* ice fixed

* weather and ice fix

* clockies can see and other clean up catches

* windows fixed

* cowbot forgive me i'm trying to update flashlights to tg because there's no light on lower multi-z z's like ice meta bottom floor

* movable lighting works on multi-z

* gps fix

* item stacking from drag works

* falsewall fix

* job panel fixed

* AI HANDLED

* woops that comment should be gone

* i hate ai i hate ai

* brass glass visible again

* vents on top of tiles now

* sigdrobe sprite back

* centcomm portals work

* portals and see openspace mapping icons fixed

* icemeta my behated

* kill

* is that it

* lighting cutoff is old hat

* angery overlay

* not super necessary

* also extra but whatever

* ticker but thicker

* job fix i hope

* this isn't needed anymore

* latejoin fix?

* laserpointer, pipecrawl, and some consoles fixed

* i hate fixing bugs as they're made

* we're not ready for that

* redef cleanup

* gps arrows, gun flashlights, shuttle console placement, multi-z pulling fixed

* goofy ah gun code

* this was a good idea and necessary

* should fix caltrop component

* does this please the linter

* linter please accept this async function

* THERE

* take the batteries out

* make it stop

* cowbot stopped me from letting ghosts dab

* recycler loc fix

* fix border firedoors not blocking movement

* should fix screen fade out and fade in on round start and end

* darker command tile trim and fixed bronze wall sprites

* fuck you linter

* railings actually stop you from leaving

* probably fixes gibtonite overlay when struck

* armaments dispenser and clockwork catwalk

* turbine fix probably

* pointing at inhand items should be fixed

* fix overwatch app

* should hopefully fix cable rotation on shuttle move

* flashlights have better directionality logic

* hopefully fixes shuttle atmos on move

* grilles fixed

* hopefully this fixes shuttle buttons, airolocks, and other machinery not working after moving

* ice meta mining area finally not freezing

* fix lightbulb icons not updating

* lava mask and lighting dots

* we actually have this

* fuck glowshrooms GC

* fix light fixture interactions and icon updates

* hopefully catches all the updates

* lava lighting good to go

* seclite was missing inhands

* smoothing in replays

* light updates accurate in replays

* biome's multi-z requests

---------

Co-authored-by: cowbot92 <75333826+cowbot92@users.noreply.github.com>
Co-authored-by: Molti <gamingjoelouis@gmail.com>
Co-authored-by: Ringalong <53777086+JohnFulpWillard@users.noreply.github.com>
2024-02-18 13:16:55 -06:00

479 lines
15 KiB
Plaintext

SUBSYSTEM_DEF(demo)
name = "Demo"
wait = 1
flags = SS_TICKER | SS_BACKGROUND
///Adding Lobby to the runlevel because we want it to start writing before the game starts since there's a of atoms queued to be written during init
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
init_order = INIT_ORDER_DEMO
loading_points = 12.6 SECONDS // Yogs -- loading times
var/list/pre_init_lines = list() // stuff like chat before the init
var/list/icon_cache = list()
var/list/icon_state_caches = list()
var/list/name_cache = list()
var/list/marked_dirty = list()
var/list/marked_new = list()
var/list/marked_turfs = list()
var/list/del_list = list()
var/last_written_time = null
var/last_chat_message = null
// stats stuff
var/last_queued = 0
var/last_completed = 0
/datum/controller/subsystem/demo/proc/write_time()
if(!can_fire)
return
var/new_time = world.time
if(last_written_time != new_time)
if(initialized)
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "time [new_time]\n")
else
pre_init_lines += "time [new_time]"
last_written_time = new_time
/datum/controller/subsystem/demo/proc/write_event_line(line)
if(!can_fire)
return
write_time()
if(initialized)
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "[line]\n")
else
pre_init_lines += line
/datum/controller/subsystem/demo/proc/write_chat(target, text)
if(!can_fire)
return
var/target_text = ""
if(target == GLOB.clients)
target_text = "world"
else if(islist(target))
var/list/target_keys = list()
for(var/T in target)
var/client/C = CLIENT_FROM_VAR(T)
if(C)
target_keys += C.ckey
if(!target_keys.len)
return
target_text = jointext(target_keys, ",")
else
var/client/C = CLIENT_FROM_VAR(target)
if(C)
target_text = C.ckey
else
return
var/json_encoded = json_encode(text)
write_event_line("chat [target_text] [last_chat_message == json_encoded ? "=" : json_encoded]")
last_chat_message = json_encoded
/datum/controller/subsystem/demo/Initialize()
if(!CONFIG_GET(flag/demos_enabled))
flags |= SS_NO_FIRE
can_fire = FALSE
marked_dirty.Cut()
marked_new.Cut()
marked_turfs.Cut()
return SS_INIT_SUCCESS
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "demo version 1\n") // increment this if you change the format
if(GLOB.revdata)
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "commit [GLOB.revdata.commit || GLOB.revdata.originmastercommit]\n")
// write a "snapshot" of the world at this point.
// start with turfs
log_world("Writing turfs...")
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "init [world.maxx] [world.maxy] [world.maxz]\n")
marked_turfs.Cut()
for(var/z in 1 to world.maxz)
var/row_list = list()
var/last_appearance
var/rle_count = 1
for(var/y in 1 to world.maxy)
for(var/x in 1 to world.maxx)
var/turf/T = locate(x,y,z)
T.demo_last_appearance = T.appearance
var/this_appearance
// space turfs are difficult to RLE otherwise, because they all
// have different appearances despite being the same thing.
if(T.type == /turf/open/space || T.type == /turf/open/space/basic)
this_appearance = "s" // save the bytes
else if(istype(T, /turf/open/space/transit))
this_appearance = "t[T.dir]"
else
this_appearance = T.appearance
if(this_appearance == last_appearance)
rle_count++
else
if(rle_count > 1)
row_list += rle_count
rle_count = 1
if(istext(this_appearance))
row_list += this_appearance
else
// do a diff with the previous turf to save those bytes
row_list += encode_appearance(this_appearance, istext(last_appearance) ? null : last_appearance)
last_appearance = this_appearance
if(rle_count > 1)
row_list += rle_count
WRITE_LOG_NO_FORMAT(GLOB.demo_log, jointext(row_list, ",") + "\n")
CHECK_TICK
// then do objects
log_world("Writing objects")
marked_new.Cut()
marked_dirty.Cut()
for(var/z in 1 to world.maxz)
var/spacing = 0
var/row_list = list()
for(var/y in 1 to world.maxy)
for(var/x in 1 to world.maxx)
var/turf/T = locate(x,y,z)
var/list/turf_list = list()
for(var/C in T.contents)
var/atom/movable/as_movable = C
if(as_movable.loc != T)
continue
if(isobj(C) || ismob(C))
turf_list += encode_init_obj(C)
if(turf_list.len)
if(spacing)
row_list += spacing
spacing = 0
row_list += turf_list
spacing++
CHECK_TICK // This is a bit risky because something might change but meh, its not a big deal.
WRITE_LOG_NO_FORMAT(GLOB.demo_log, jointext(row_list, ",") + "\n")
// track objects that exist in nullspace
var/nullspace_list = list()
for(var/M in world)
if(!isobj(M) && !ismob(M))
continue
var/atom/movable/AM = M
if(AM.loc != null)
continue
nullspace_list += encode_init_obj(AM)
CHECK_TICK
WRITE_LOG_NO_FORMAT(GLOB.demo_log, jointext(nullspace_list, ",") + "\n")
for(var/line in pre_init_lines)
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "[line]\n")
return SS_INIT_SUCCESS
/datum/controller/subsystem/demo/fire()
if(!src.marked_new.len && !src.marked_dirty.len && !src.marked_turfs.len && !src.del_list.len)
return // nothing to do
last_queued = src.marked_new.len + src.marked_dirty.len + src.marked_turfs.len
last_completed = 0
write_time()
if(src.del_list.len)
var/s = "del [jointext(src.del_list, ",")]\n" // if I don't do it like this I get "incorrect number of macro arguments" because byond is stupid and sucks
WRITE_LOG_NO_FORMAT(GLOB.demo_log, s)
src.del_list.Cut()
var/canceled = FALSE
var/list/marked_dirty = src.marked_dirty
var/list/dirty_updates = list()
while(marked_dirty.len)
last_completed++
var/atom/movable/M = marked_dirty[marked_dirty.len]
marked_dirty.len--
if(M.gc_destroyed || !M)
continue
if(M.loc == M.demo_last_loc && M.appearance == M.demo_last_appearance)
continue
var/loc_string = "="
if(M.loc != M.demo_last_loc)
loc_string = "null"
if(isturf(M.loc))
loc_string = "[M.x],[M.y],[M.z]"
else if(ismovable(M.loc))
loc_string = "\ref[M.loc]"
M.demo_last_loc = M.loc
var/appearance_string = "="
if(ismob(M))
appearance_string = encode_appearance(M.appearance, target = M)
M.demo_last_appearance = M.appearance
else if(M.appearance != M.demo_last_appearance)
appearance_string = encode_appearance(M.appearance, M.demo_last_appearance, TRUE, M)
M.demo_last_appearance = M.appearance
dirty_updates += "\ref[M] [loc_string] [appearance_string]"
if(MC_TICK_CHECK)
canceled = TRUE
break
if(dirty_updates.len)
var/s = "update [jointext(dirty_updates, ",")]\n"
WRITE_LOG_NO_FORMAT(GLOB.demo_log, s)
if(canceled)
return
var/list/marked_new = src.marked_new
var/list/new_updates = list()
while(marked_new.len)
last_completed++
var/atom/movable/M = marked_new[marked_new.len]
marked_new.len--
if(M.gc_destroyed || !M)
continue
var/loc_string = "null"
if(isturf(M.loc))
loc_string = "[M.x],[M.y],[M.z]"
else if(ismovable(M.loc))
loc_string = "\ref[M.loc]"
M.demo_last_appearance = M.appearance
new_updates += "\ref[M] [loc_string] [encode_appearance(M.appearance, target = M)]"
if(MC_TICK_CHECK)
canceled = TRUE
break
if(new_updates.len)
var/s = "new [jointext(new_updates, ",")]\n"
WRITE_LOG_NO_FORMAT(GLOB.demo_log, s)
if(canceled)
return
var/list/marked_turfs = src.marked_turfs
var/list/turf_updates = list()
while(marked_turfs.len)
last_completed++
var/turf/T = marked_turfs[marked_turfs.len]
marked_turfs.len--
if(T && T.appearance != T.demo_last_appearance)
turf_updates += "([T.x],[T.y],[T.z])=[encode_appearance(T.appearance, T.demo_last_appearance)]"
T.demo_last_appearance = T.appearance
if(MC_TICK_CHECK)
canceled = TRUE
break
if(turf_updates.len)
var/s = "turf [jointext(turf_updates, ",")]\n"
WRITE_LOG_NO_FORMAT(GLOB.demo_log, s)
if(canceled)
return
/datum/controller/subsystem/demo/proc/encode_init_obj(atom/movable/M)
M.demo_last_loc = M.loc
M.demo_last_appearance = M.appearance
var/encoded_appearance = encode_appearance(M.appearance, target = M)
var/list/encoded_contents = list()
for(var/C in M.contents)
if(isobj(C) || ismob(C))
encoded_contents += encode_init_obj(C)
return "\ref[M]=[encoded_appearance][(encoded_contents.len ? "([jointext(encoded_contents, ",")])" : "")]"
// please make sure the order you call this function in is the same as the order you write
/datum/controller/subsystem/demo/proc/encode_appearance(image/appearance, image/diff_appearance, diff_remove_overlays = FALSE, atom/movable/target)
if(appearance == null)
return "n"
if(appearance == diff_appearance)
return "="
var/icon_txt = "[appearance.icon]"
var/cached_icon = icon_cache[icon_txt] || icon_txt
var/list/icon_state_cache
if(!isnum(cached_icon))
icon_cache[icon_txt] = icon_cache.len + 1
icon_state_cache = (icon_state_caches[++icon_state_caches.len] = list())
else
icon_state_cache = icon_state_caches[cached_icon]
var/list/cached_icon_state = icon_state_cache[appearance.icon_state] || appearance.icon_state
if(!isnum(cached_icon_state))
icon_state_cache[appearance.icon_state] = icon_state_cache.len + 1
var/cached_name = name_cache[appearance.name] || appearance.name
if(!isnum(cached_name))
name_cache[appearance.name] = name_cache.len + 1
var/color_string = appearance.color || "w"
if(islist(color_string))
var/list/old_list = appearance.color
var/list/inted = list()
inted.len = old_list.len
for(var/i in 1 to old_list.len)
inted[i] += round(old_list[i] * 255)
color_string = jointext(inted, ",")
var/overlays_string = "\[]"
var/list/appearance_overlays = appearance.overlays
if(appearance_overlays.len)
var/list/overlays_list = list()
for(var/i in 1 to appearance_overlays.len)
var/image/overlay = appearance_overlays[i]
overlays_list += encode_appearance(overlay, appearance, TRUE, target = target)
overlays_string = "\[[jointext(overlays_list, ",")]]"
var/underlays_string = "\[]"
var/list/appearance_underlays = appearance.underlays
if(appearance_underlays.len)
var/list/underlays_list = list()
for(var/i in 1 to appearance_underlays.len)
var/image/underlay = appearance_underlays[i]
underlays_list += encode_appearance(underlay, appearance, TRUE, target = target)
underlays_string = "\[[jointext(underlays_list, ",")]]"
var/appearance_transform_string = "i"
if(appearance.transform)
var/matrix/M = appearance.transform
appearance_transform_string = "[M.a],[M.b],[M.c],[M.d],[M.e],[M.f]"
if(appearance_transform_string == "1,0,0,0,1,0")
appearance_transform_string = "i"
var/tmp_dir = appearance.dir
if(target)
tmp_dir = target.dir
var/list/appearance_list = list(
json_encode(cached_icon),
json_encode(cached_icon_state),
json_encode(cached_name),
appearance.appearance_flags,
appearance.layer,
appearance.plane == -32767 ? "" : PLANE_TO_TRUE(appearance.plane),
tmp_dir == 2 ? "" : tmp_dir,
appearance.color ? color_string : "",
appearance.alpha == 255 ? "" : appearance.alpha,
appearance.pixel_x == 0 ? "" : appearance.pixel_x,
appearance.pixel_y == 0 ? "" : appearance.pixel_y,
appearance.blend_mode <= 1 ? "" : appearance.blend_mode,
appearance_transform_string != "i" ? appearance_transform_string : "",
appearance:invisibility == 0 ? "" : appearance:invisibility, // colon because dreamchecker is dumb
appearance.pixel_w == 0 ? "" : appearance.pixel_w,
appearance.pixel_z == 0 ? "" : appearance.pixel_z,
appearance.overlays.len ? overlays_string : "",
appearance.underlays.len ? underlays_string : ""
)
while(appearance_list[appearance_list.len] == "" && appearance_list.len > 0)
appearance_list.len--
var/undiffed_string = "{[jointext(appearance_list, ";")]}"
if(diff_appearance)
var/overlays_identical = TRUE
if(diff_remove_overlays)
overlays_identical = (appearance.overlays.len == 0)
else if(appearance.overlays.len != diff_appearance.overlays.len)
overlays_identical = FALSE
else
for(var/i in 1 to appearance.overlays.len)
if(appearance.overlays[i] != diff_appearance.overlays[i])
overlays_identical = FALSE
break
var/underlays_identical = TRUE
if(diff_remove_overlays)
underlays_identical = (appearance.underlays.len == 0)
else if(appearance.underlays.len != diff_appearance.underlays.len)
underlays_identical = FALSE
else
for(var/i in 1 to appearance.underlays.len)
if(appearance.underlays[i] != diff_appearance.underlays[i])
underlays_identical = FALSE
break
var/diff_transform_string = "i"
if(diff_appearance.transform)
var/matrix/M = diff_appearance.transform
diff_transform_string = "[M.a],[M.b],[M.c],[M.d],[M.e],[M.f]"
if(diff_transform_string == "1,0,0,0,1,0")
diff_transform_string = "i"
var/list/diffed_appearance_list = list(
json_encode(cached_icon),
json_encode(cached_icon_state),
json_encode(cached_name),
appearance.appearance_flags == diff_appearance.appearance_flags ? "" : appearance.appearance_flags,
appearance.layer == diff_appearance.layer ? "" : appearance.layer,
PLANE_TO_TRUE(appearance.plane) == PLANE_TO_TRUE(diff_appearance.plane) ? "" : PLANE_TO_TRUE(appearance.plane),
appearance.dir == diff_appearance.dir ? "" : appearance.dir,
appearance.color == diff_appearance.color ? "" : color_string,
appearance.alpha == diff_appearance.alpha ? "" : appearance.alpha,
appearance.pixel_x == diff_appearance.pixel_x ? "" : appearance.pixel_x,
appearance.pixel_y == diff_appearance.pixel_y ? "" : appearance.pixel_y,
appearance.blend_mode == diff_appearance.blend_mode ? "" : appearance.blend_mode,
appearance_transform_string == diff_transform_string ? "" : appearance_transform_string,
appearance:invisibility == diff_appearance:invisibility ? "" : appearance:invisibility, // colon because dreamchecker is too dumb
appearance.pixel_w == diff_appearance.pixel_w ? "" : appearance.pixel_w,
appearance.pixel_z == diff_appearance.pixel_z ? "" : appearance.pixel_z,
overlays_identical ? "" : overlays_string,
underlays_identical ? "" :underlays_string
)
while(diffed_appearance_list[diffed_appearance_list.len] == "" && diffed_appearance_list.len > 0)
diffed_appearance_list.len--
var/diffed_string = "~{[jointext(diffed_appearance_list, ";")]}"
if(length(diffed_string) < length(undiffed_string))
return diffed_string
return undiffed_string
/datum/controller/subsystem/demo/stat_entry(msg)
msg += "Remaining: {"
msg += "Trf:[marked_turfs.len]|"
msg += "New:[marked_new.len]|"
msg += "Upd:[marked_dirty.len]|"
msg += "Del:[del_list.len]"
msg += "}"
return ..(msg)
/datum/controller/subsystem/demo/get_metrics()
. = ..()
.["remaining_turfs"] = marked_turfs.len
.["remaining_new"] = marked_new.len
.["remaining_updated"] = marked_dirty.len
.["remaining_deleted"] = del_list.len
/datum/controller/subsystem/demo/proc/mark_turf(turf/T)
if(!can_fire)
return
if(!isturf(T))
return
marked_turfs[T] = TRUE
/datum/controller/subsystem/demo/proc/mark_new(atom/movable/M)
if(!can_fire)
return
if(!ismovable(M))
return
if(M.gc_destroyed || QDELETED(M))
return
marked_new[M] = TRUE
if(marked_dirty[M])
marked_dirty -= M
// I can't wait for when TG ports this and they make this a #define macro.
/datum/controller/subsystem/demo/proc/mark_dirty(atom/movable/M)
if(!can_fire)
return
if(!ismovable(M))
return
if(M.gc_destroyed || QDELETED(M))
return
if(isturf(M))
mark_turf(M)
return
if(marked_new[M])
return
marked_dirty[M] = TRUE
/datum/controller/subsystem/demo/proc/mark_destroyed(atom/movable/M)
if(!can_fire)
return
if(!ismovable(M))
return
if(marked_new[M])
marked_new -= M
if(marked_dirty[M])
marked_dirty -= M
if(initialized)
del_list["\ref[M]"] = 1