diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 02e3fe6f3d..cf669b905a 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -5,9 +5,21 @@ // global signals // These are signals which can be listened to by any component on any parent // start global signals with "!", this used to be necessary but now it's just a formatting choice -#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) -#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) -#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) +/// from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) +#define COMSIG_GLOB_NEW_Z "!new_z" +/// called after a successful var edit somewhere in the world: (list/args) +#define COMSIG_GLOB_VAR_EDIT "!var_edit" +/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) +#define COMSIG_GLOB_EXPLOSION "!explosion" +/// mob was created somewhere : (mob) +#define COMSIG_GLOB_MOB_CREATED "!mob_created" +/// mob died somewhere : (mob , gibbed) +#define COMSIG_GLOB_MOB_DEATH "!mob_death" +/// global living say plug - use sparingly: (mob/speaker , message) +#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" +/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic) +#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic" + #define COMPONENT_GLOB_BLOCK_CINEMATIC 1 // signals from globally accessible objects /// from SSsun when the sun changes position : (azimuth) diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm index 28803f0979..3782d8be94 100644 --- a/code/controllers/admin.dm +++ b/code/controllers/admin.dm @@ -3,7 +3,9 @@ name = "Initializing..." var/target -/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical +INITIALIZE_IMMEDIATE(/obj/effect/statclick) //it's new, but rebranded. + +/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical . = ..() name = text src.target = target diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 148822cdd1..22f047a297 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -1,4 +1,4 @@ - /** +/** * Failsafe * * Pretty much pokes the MC to make sure it's still alive. @@ -31,7 +31,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) Initialize() /datum/controller/failsafe/Initialize() - set waitfor = 0 + set waitfor = FALSE Failsafe.Loop() if(!QDELETED(src)) qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us @@ -97,4 +97,4 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) /datum/controller/failsafe/stat_entry(msg) msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])" - return msg + return msg \ No newline at end of file diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index 6b5fb294ea..21f022acfd 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -20,8 +20,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) Initialize() -/datum/controller/global_vars/Destroy() - //fuck off kevinz +/datum/controller/global_vars/Destroy(force) + // This is done to prevent an exploit where admins can get around protected vars + SHOULD_CALL_PARENT(FALSE) return QDEL_HINT_IWILLGC /datum/controller/global_vars/stat_entry(msg) diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index bb8ce951f5..e49da32557 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -97,9 +97,9 @@ return //This is used so the mc knows when the subsystem sleeps. do not override. -/datum/controller/subsystem/proc/ignite(resumed = 0) +/datum/controller/subsystem/proc/ignite(resumed = FALSE) SHOULD_NOT_OVERRIDE(TRUE) - set waitfor = 0 + set waitfor = FALSE . = SS_SLEEPING fire(resumed) . = state diff --git a/code/datums/browser.dm b/code/datums/browser.dm index dbe60817bd..2057cbb21a 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -451,7 +451,7 @@ // otherwise, just reset the client mob's machine var. // /client/verb/windowclose(atomref as text) - set hidden = 1 // hide this verb from the user's panel + set hidden = TRUE // hide this verb from the user's panel set name = ".windowclose" // no autocomplete on cmd line if(atomref!="null") // if passed a real atomref diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm index df2c15e9c8..7b3081cb33 100644 --- a/code/datums/cinematic.dm +++ b/code/datums/cinematic.dm @@ -1,5 +1,3 @@ -GLOBAL_LIST_EMPTY(cinematics) - // Use to play cinematics. // Watcher can be world,mob, or a list of mobs // Blocks until sequence is done. @@ -18,6 +16,7 @@ GLOBAL_LIST_EMPTY(cinematics) playing.is_global = TRUE watcher = GLOB.mob_list playing.play(watcher) + qdel(playing) /obj/screen/cinematic icon = 'icons/effects/station_explosion.dmi' @@ -25,12 +24,13 @@ GLOBAL_LIST_EMPTY(cinematics) plane = SPLASHSCREEN_PLANE layer = SPLASHSCREEN_LAYER mouse_opacity = MOUSE_OPACITY_TRANSPARENT - screen_loc = "1,1" + screen_loc = "BOTTOM,LEFT+50%" + appearance_flags = APPEARANCE_UI | TILE_BOUND /datum/cinematic var/id = CINEMATIC_DEFAULT var/list/watching = list() //List of clients watching this - var/list/locked = list() //Who had mob_transforming set during the cinematic + var/list/locked = list() //Who had mob_transforming set during the cinematic var/is_global = FALSE //Global cinematics will override mob-specific ones var/obj/screen/cinematic/screen var/datum/callback/special_callback //For special effects synced with animation (explosions after the countdown etc) @@ -38,28 +38,35 @@ GLOBAL_LIST_EMPTY(cinematics) var/stop_ooc = TRUE //Turns off ooc when played globally. /datum/cinematic/New() - GLOB.cinematics += src screen = new(src) /datum/cinematic/Destroy() - GLOB.cinematics -= src + for(var/CC in watching) + if(!CC) + continue + var/client/C = CC + //C.mob.clear_fullscreen("cinematic") + C.screen -= screen + watching = null QDEL_NULL(screen) - for(var/mob/M in locked) - M.mob_transforming = FALSE + QDEL_NULL(special_callback) + for(var/MM in locked) + if(!MM) + continue + var/mob/M = MM + M.mob_transforming = FALSE + locked = null return ..() /datum/cinematic/proc/play(watchers) - //Check if you can actually play it (stop mob cinematics for global ones) and create screen objects - for(var/A in GLOB.cinematics) - var/datum/cinematic/C = A - if(C == src) - continue - if(C.is_global || !is_global) - return //Can't play two global or local cinematics at the same time + //Check if cinematic can actually play (stop mob cinematics for global ones) + if(SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PLAY_CINEMATIC, src) & COMPONENT_GLOB_BLOCK_CINEMATIC) + return - //Close all open windows if global - if(is_global) - SStgui.close_all_uis() + //We are now playing this cinematic + + //Handle what happens when a different cinematic tries to play over us + RegisterSignal(SSdcs, COMSIG_GLOB_PLAY_CINEMATIC, .proc/replacement_cinematic) //Pause OOC var/ooc_toggled = FALSE @@ -67,24 +74,17 @@ GLOBAL_LIST_EMPTY(cinematics) ooc_toggled = TRUE toggle_ooc(FALSE) - - for(var/mob/M in GLOB.mob_list) - if(M in watchers) - M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ? - locked += M - //Close watcher ui's - SStgui.close_user_uis(M) - if(M.client) - watching += M.client - M.client.screen += screen - else - if(is_global) - M.mob_transforming = TRUE - locked += M + //Place /obj/screen/cinematic into everyone's screens, prevent them from moving + for(var/MM in watchers) + var/mob/M = MM + show_to(M, M.client) + RegisterSignal(M, COMSIG_MOB_CLIENT_LOGIN, .proc/show_to) + //Close watcher ui's + SStgui.close_user_uis(M) //Actually play it content() - + //Cleanup sleep(cleanup_time) @@ -92,7 +92,17 @@ GLOBAL_LIST_EMPTY(cinematics) if(ooc_toggled) toggle_ooc(TRUE) - qdel(src) +/datum/cinematic/proc/show_to(mob/M, client/C) + //SIGNAL_HANDLER //must not wait. + + if(!M.mob_transforming) + locked += M + M.mob_transforming = TRUE //Should this be done for non-global cinematics or even at all ? + if(!C) + return + watching += C + //M.overlay_fullscreen("cinematic",/obj/screen/fullscreen/cinematic_backdrop) + C.screen += screen //Sound helper /datum/cinematic/proc/cinematic_sound(s) @@ -111,6 +121,13 @@ GLOBAL_LIST_EMPTY(cinematics) /datum/cinematic/proc/content() sleep(50) +/datum/cinematic/proc/replacement_cinematic(datum/source, datum/cinematic/other) + //SIGNAL_HANDLER + + if(!is_global && other.is_global) //Allow it to play if we're local and it's global + return NONE + return COMPONENT_GLOB_BLOCK_CINEMATIC + /datum/cinematic/nuke_win id = CINEMATIC_NUKE_WIN diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 7756cfd906..d11532a883 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -15,22 +15,32 @@ * If this is non zero then the object has been garbage collected and is awaiting either * a hard del by the GC subsystme, or to be autocollected (if it has no references) */ - var/gc_destroyed //Time when this object was destroyed. + var/gc_destroyed /// Active timers with this datum as the target var/list/active_timers /// Status traits attached to this datum var/list/status_traits - /// Components attached to this datum - /// Lazy associated list in the structure of `type:component/list of components` + + /** + * Components attached to this datum + * + * Lazy associated list in the structure of `type:component/list of components` + */ var/list/datum_components - /// Any datum registered to receive signals from this datum is in this list - /// Lazy associated list in the structure of `signal:registree/list of registrees` - var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register + /** + * Any datum registered to receive signals from this datum is in this list + * + * Lazy associated list in the structure of `signal:registree/list of registrees` + */ + var/list/comp_lookup /// Lazy associated list in the structure of `signals:proctype` that are run when the datum receives that signal var/list/list/datum/callback/signal_procs - /// Is this datum capable of sending signals? - /// Set to true when a signal has been registered + /** + * Is this datum capable of sending signals? + * + * Set to true when a signal has been registered + */ var/signal_enabled = FALSE /// Datum level flags @@ -39,7 +49,12 @@ /// A weak reference to another datum var/datum/weakref/weak_reference - ///Lazy associative list of currently active cooldowns. + /* + * Lazy associative list of currently active cooldowns. + * + * cooldowns [ COOLDOWN_INDEX ] = add_timer() + * add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index + */ var/list/cooldowns #ifdef TESTING @@ -51,23 +66,34 @@ var/list/cached_vars #endif +/** + * Called when a href for this datum is clicked + * + * Sends a [COMSIG_TOPIC] signal + */ +/datum/Topic(href, href_list[]) + ..() + SEND_SIGNAL(src, COMSIG_TOPIC, usr, href_list) + + /** * Default implementation of clean-up code. * * This should be overridden to remove all references pointing to the object being destroyed, if * you do override it, make sure to call the parent and return it's return value by default * - * Return an appropriate QDEL_HINT to modify handling of your deletion; - * in most cases this is QDEL_HINT_QUEUE. + * Return an appropriate [QDEL_HINT][QDEL_HINT_QUEUE] to modify handling of your deletion; + * in most cases this is [QDEL_HINT_QUEUE]. * * The base case is responsible for doing the following * * Erasing timers pointing to this datum * * Erasing compenents on this datum * * Notifying datums listening to signals from this datum that we are going away * - * Returns QDEL_HINT_QUEUE + * Returns [QDEL_HINT_QUEUE] */ /datum/proc/Destroy(force=FALSE, ...) + SHOULD_CALL_PARENT(TRUE) tag = null datum_flags &= ~DF_USE_TAG //In case something tries to REF us weak_reference = null //ensure prompt GCing of weakref. @@ -112,7 +138,7 @@ UnregisterSignal(target, signal_procs[target]) //END: ECS SHIT - SSsounds.free_datum_channels(src) + SSsounds.free_datum_channels(src) //?? (not on tg) return QDEL_HINT_QUEUE @@ -143,15 +169,15 @@ to_chat(target, txt_changed_vars()) #endif -//Return a LIST for serialize_datum to encode! Not the actual json! +///Return a LIST for serialize_datum to encode! Not the actual json! /datum/proc/serialize_list(list/options) CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!") -//Accepts a LIST from deserialize_datum. Should return src or another datum. +///Accepts a LIST from deserialize_datum. Should return src or another datum. /datum/proc/deserialize_list(json, list/options) CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!") -//Serializes into JSON. Does not encode type. +///Serializes into JSON. Does not encode type. /datum/proc/serialize_json(list/options) . = serialize_list(options) if(!islist(.)) @@ -159,13 +185,14 @@ else . = json_encode(.) -//Deserializes from JSON. Does not parse type. +///Deserializes from JSON. Does not parse type. /datum/proc/deserialize_json(list/input, list/options) var/list/jsonlist = json_decode(input) . = deserialize_list(jsonlist) if(!istype(., /datum)) . = null +///Convert a datum into a json blob /proc/json_serialize_datum(datum/D, list/options) if(!istype(D)) return @@ -174,6 +201,7 @@ jsonlist["DATUM_TYPE"] = D.type return json_encode(jsonlist) +/// Convert a list of json to datum /proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE) if(!islist(jsonlist)) if(!istext(jsonlist)) diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index 482e15c57d..b4e483ae2b 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -214,6 +214,7 @@ /datum/point/vector/processed/Destroy() STOP_PROCESSING(SSprojectiles, src) + return ..() /datum/point/vector/processed/proc/start() last_process = world.time diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm index fbe9036ea7..31e0c3501b 100644 --- a/code/datums/weakrefs.dm +++ b/code/datums/weakrefs.dm @@ -16,8 +16,12 @@ /datum/weakref/New(datum/thing) reference = REF(thing) -/datum/weakref/Destroy() - return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore. +/datum/weakref/Destroy(force) + if(!force) + return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore. + var/datum/target = resolve() + target?.weak_reference = null + return ..() /datum/weakref/proc/resolve() var/datum/D = locate(reference) diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm b/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm index 5c4b1f2b9f..26c8bd5949 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm @@ -180,10 +180,12 @@ button.screen_loc = DEFAULT_BLOODSPELLS button.moved = DEFAULT_BLOODSPELLS button.ordered = FALSE + /datum/action/bloodsucker/passive/Destroy() if(owner) Remove(owner) target = null + return ..() /////////////////////////////////// TARGETTED POWERS /////////////////////////////////// diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm index 536c07cd62..e8fb82a5d1 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm @@ -456,6 +456,7 @@ /obj/structure/bloodsucker/candelabrum/Destroy() STOP_PROCESSING(SSobj, src) + return ..() //return a hint /obj/structure/bloodsucker/candelabrum/update_icon_state() icon_state = "candelabrum[lit ? "_lit" : ""]" diff --git a/code/modules/mapping/minimaps.dm b/code/modules/mapping/minimaps.dm index e0eb174cb3..51fde1f8db 100644 --- a/code/modules/mapping/minimaps.dm +++ b/code/modules/mapping/minimaps.dm @@ -134,12 +134,13 @@ return num; } window.onload = function() { - var datas = \[[jointext(datas, ",")]] - if(!window.HTMLCanvasElement){ - //something has gone horribly wrong! + if(!window.HTMLCanvasElement) { + var label = document.getElementById("label-1"); + label.textContent = "