diff --git a/aurorastation.dme b/aurorastation.dme index 827f91ce301..e54eb4f1ff7 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -270,6 +270,10 @@ #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" +#include "code\datums\observation\_debug.dm" +#include "code\datums\observation\destroyed.dm" +#include "code\datums\observation\moved.dm" +#include "code\datums\observation\observation.dm" #include "code\datums\radio\frequency.dm" #include "code\datums\radio\signal.dm" #include "code\datums\repositories\cameras.dm" @@ -370,9 +374,6 @@ #include "code\game\area\areas.dm" #include "code\game\area\asteroid_areas.dm" #include "code\game\area\Space Station 13 areas.dm" -#include "code\game\datum_events\death.dm" -#include "code\game\datum_events\destroyed.dm" -#include "code\game\datum_events\moved.dm" #include "code\game\dna\dna2.dm" #include "code\game\dna\dna2_domutcheck.dm" #include "code\game\dna\dna2_helpers.dm" diff --git a/code/__defines/lists.dm b/code/__defines/lists.dm index ce0a6acc921..1b24a50bc19 100644 --- a/code/__defines/lists.dm +++ b/code/__defines/lists.dm @@ -6,7 +6,7 @@ #define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null) #define LAZYLEN(L) length(L) #define LAZYCLEARLIST(L) if(L) L.Cut() -#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; +#define LAZYSET(L, K, V) if (!L) { L = list(); } L[K] = V; #define LAZYPICK(L,DEFAULT) (LAZYLEN(L) ? pick(L) : DEFAULT) // Shims for some list procs in lists.dm. diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 9bee0296984..96bc915a862 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -235,22 +235,19 @@ var/datum/controller/subsystem/garbage_collector/SSgarbage // This should be overridden to remove all references pointing to the object being destroyed. // Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. /datum/proc/Destroy(force=FALSE) - if (destroy_listeners) - RaiseOnDestroy() - - SSnanoui.close_uis(src) - weakref = null + destroyed_event.raise_event(src) + SSnanoui.close_uis(src) tag = null - var/list/timers = active_timers active_timers = null if (timers) - for(var/thing in timers) + for (var/thing in timers) var/datum/timedevent/timer = thing if (timer.spent) continue qdel(timer) + return QDEL_HINT_QUEUE /datum/var/gcDestroyed //Time when this object was destroyed. diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm index ef34d8dcfca..458d20b6d84 100644 --- a/code/controllers/subsystems/job.dm +++ b/code/controllers/subsystems/job.dm @@ -505,6 +505,10 @@ H.centcomm_despawn_timer = addtimer(CALLBACK(H, /mob/living/.proc/centcomm_timeout), 10 MINUTES, TIMER_STOPPABLE) var/datum/job/job = GetJob(rank) + + if(spawning_at != "Arrivals Shuttle" || job.latejoin_at_spawnpoints) + return EquipRank(H, rank, 1) + var/list/spawn_in_storage = list() H <<"You have ten minutes to reach the station before you will be forced there." @@ -771,8 +775,14 @@ else permitted = TRUE - if(G.whitelisted && !is_alien_whitelisted(H, all_species[G.whitelisted])) - permitted = FALSE + if (G.whitelisted) + var/found = FALSE + for (var/species in G.whitelisted) + if (is_alien_whitelisted(H, global.all_species[species])) + found = TRUE + break + if (!found) + permitted = FALSE if(!permitted) H << "Your current job or whitelist status does not permit you to spawn with [thing]!" diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index f8e5ac7fd9d..e8d7af303ad 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -11,7 +11,8 @@ /var/list/controller_debug_list = list( "Configuration", "Cameras", - "Gas Data" + "Gas Data", + "Observation" ) /client/proc/debug_controller(controller in controller_debug_list) @@ -30,4 +31,7 @@ if("Gas Data") debug_variables(gas_data) feedback_add_details("admin_verb","DGasdata") + if("Observation") + debug_variables(all_observable_events) + feedback_add_details("admin_verb", "DObservation") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") diff --git a/code/datums/observation/_debug.dm b/code/datums/observation/_debug.dm new file mode 100644 index 00000000000..2f882929cff --- /dev/null +++ b/code/datums/observation/_debug.dm @@ -0,0 +1,11 @@ +/**************** +* Debug Support * +****************/ +var/datum/all_observable_events/all_observable_events = new() + +/datum/all_observable_events + var/list/events + +/datum/all_observable_events/New() + events = list() + ..() diff --git a/code/datums/observation/destroyed.dm b/code/datums/observation/destroyed.dm new file mode 100644 index 00000000000..5b5af06050d --- /dev/null +++ b/code/datums/observation/destroyed.dm @@ -0,0 +1,4 @@ +var/datum/observ/destroyed/destroyed_event = new() + +/datum/observ/destroyed + name = "Destroyed" diff --git a/code/datums/observation/moved.dm b/code/datums/observation/moved.dm new file mode 100644 index 00000000000..627e7c93bac --- /dev/null +++ b/code/datums/observation/moved.dm @@ -0,0 +1,41 @@ +var/datum/observ/moved/moved_event = new() + +/datum/observ/moved + name = "Moved" + expected_type = /atom/movable + +/datum/observ/moved/register(var/eventSource, var/datum/procOwner, var/proc_call) + . = ..() + var/atom/movable/child = eventSource + if(.) + var/atom/movable/parent = child.loc + while(istype(parent) && !moved_event.is_listening(parent, child)) + moved_event.register(parent, child, /atom/movable/proc/recursive_move) + child = parent + parent = child.loc + +/******************** +* Movement Handling * +********************/ + +/atom/movable/proc/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc) + var/turf/T = get_turf(new_loc) + if(T && T != loc) + forceMove(T) + +/atom/movable/proc/recursive_move(var/atom/movable/am, var/old_loc, var/new_loc) + moved_event.raise_event(list(src, old_loc, new_loc)) + +/atom/Entered(var/atom/movable/am, atom/old_loc) + ..() + moved_event.raise_event(am, old_loc, am.loc) + +/atom/movable/Entered(var/atom/movable/am, atom/old_loc) + ..() + if(moved_event.has_listeners(am) && !moved_event.is_listening(src, am)) + moved_event.register(src, am, /atom/movable/proc/recursive_move) + +/atom/movable/Exited(var/atom/movable/am, atom/old_loc) + ..() + if(moved_event.is_listening(src, am, /atom/movable/proc/recursive_move)) + moved_event.unregister(src, am) diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm new file mode 100644 index 00000000000..f540c89f807 --- /dev/null +++ b/code/datums/observation/observation.dm @@ -0,0 +1,60 @@ +/datum/observ + var/name = "Unnamed Event" + var/expected_type = /datum + var/list/listeners_assoc + +/datum/observ/New() + all_observable_events.events += src + listeners_assoc = list() + ..() + +/datum/observ/proc/is_listening(var/eventSource, var/datum/procOwner, var/proc_call) + var/listeners = listeners_assoc[eventSource] + if(!listeners) + return FALSE + + var/stored_proc_call = listeners[procOwner] + return stored_proc_call && (!proc_call || stored_proc_call == proc_call) + +/datum/observ/proc/has_listeners(var/eventSource) + var/list/listeners = listeners_assoc[eventSource] + return LAZYLEN(listeners) + +/datum/observ/proc/register(var/eventSource, var/datum/procOwner, var/proc_call) + if(!(eventSource && procOwner && procOwner)) + return FALSE + if(istype(eventSource, /datum/observ)) + return FALSE + + if(!istype(eventSource, expected_type)) + CRASH("Unexpected type. Expected [expected_type], was [eventSource]") + + LAZYINITLIST(listeners_assoc[eventSource]) + listeners_assoc[eventSource][procOwner] = proc_call + destroyed_event.register(procOwner, src, /datum/observ/proc/unregister) + return TRUE + +/datum/observ/proc/unregister(var/eventSource, var/datum/procOwner) + if(!(eventSource && procOwner)) + return FALSE + if(istype(eventSource, /datum/observ)) + return FALSE + + var/list/listeners = listeners_assoc[eventSource] + if(!listeners) + return FALSE + + listeners -= procOwner + if (!listeners.len) + listeners_assoc -= eventSource + destroyed_event.unregister(procOwner, src) + return TRUE + +/datum/observ/proc/raise_event(...) + if(!args.len) + return + var/listeners = listeners_assoc[args[1]] + if(!listeners) + return + for(var/listener in listeners) + call(listener, listeners[listener])(arglist(args)) diff --git a/code/datums/trading/vox.dm b/code/datums/trading/vox.dm index d5bd35817fc..6711ddd564c 100644 --- a/code/datums/trading/vox.dm +++ b/code/datums/trading/vox.dm @@ -49,7 +49,8 @@ possible_trading_items = list( /obj/item/weapon/gun/projectile/dartgun/vox = TRADER_SUBTYPES_ONLY, /obj/item/mecha_parts/mecha_equipment/tool = TRADER_SUBTYPES_ONLY, - /obj/item/mecha_parts/mecha_equipment/weapon/ballistic = TRADER_SUBTYPES_ONLY, + /obj/item/mecha_parts/mecha_equipment/weapon = TRADER_SUBTYPES_ONLY, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic = TRADER_BLACKLIST, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = TRADER_BLACKLIST, /obj/item/trash = TRADER_SUBTYPES_ONLY, /obj/item/clothing/accessory = TRADER_ALL, diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4781284f719..950e89a731d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -282,8 +282,8 @@ . = ..() if (.) // Events. - if (move_listeners) - RaiseOnMove(src, old_loc, loc) + if (moved_event.listeners_assoc[src]) + moved_event.raise_event(src, old_loc, loc) // Parallax. if (contained_mobs) diff --git a/code/game/datum_events/death.dm b/code/game/datum_events/death.dm deleted file mode 100644 index cddd99d9aa2..00000000000 --- a/code/game/datum_events/death.dm +++ /dev/null @@ -1,37 +0,0 @@ -/mob/living - var/list/death_listeners - -/mob/living/proc/OnDeath(thingtocall, proctocall, ...) - .(CALLBACK(thingtocall, proctocall, ...)) - -/mob/living/OnDeath(datum/callback/callback) - LAZYSET(death_listeners, callback.object, callback) - if (callback.object && callback.object != GLOBAL_PROC) - callback.object.OnDestroy(CALLBACK(src, .proc/UnregisterOnDeath, callback.object)) - -/mob/living/proc/UnregisterOnDeath(object) - if (!death_listeners) - return FALSE - - death_listeners[object] = null - death_listeners -= object - - UNSETEMPTY(death_listeners) - . = TRUE - -/mob/living/proc/RaiseOnDeath(gibbed) - if (!death_listeners) - return FALSE - - for (var/thing in death_listeners) - var/datum/callback/cb = death_listeners[thing] - cb.InvokeAsync(gibbed) - -/mob/living/Destroy() - death_listeners = null - return ..() - -/mob/living/death(gibbed, deathmessage = "seizes up and falls limp...") - . = ..() - if (.) - RaiseOnDeath(gibbed) diff --git a/code/game/datum_events/destroyed.dm b/code/game/datum_events/destroyed.dm deleted file mode 100644 index bac84a9526b..00000000000 --- a/code/game/datum_events/destroyed.dm +++ /dev/null @@ -1,31 +0,0 @@ -/datum - var/list/destroy_listeners - -/** - * @param second_link should only ever be passed as TRUE from this proc. It's a - * recursion guard. The reverse registration is necessary to clean up hard refs. - */ -/datum/proc/OnDestroy(datum/callback/callback, second_link = FALSE) - LAZYSET(destroy_listeners, callback.object, callback) - if (!second_link && callback.object && callback.object != GLOBAL_PROC) - callback.object.OnDestroy(CALLBACK(src, .proc/UnregisterOnDestroy, callback.object), TRUE) - -/datum/proc/UnregisterOnDestroy(object) - if (!destroy_listeners) - return FALSE - - destroy_listeners[object] = null - destroy_listeners -= object - - UNSETEMPTY(destroy_listeners) - . = TRUE - -/datum/proc/RaiseOnDestroy() - if (!destroy_listeners) - return FALSE - - . = 0 - for (var/thing in destroy_listeners) - var/datum/callback/cb = destroy_listeners[thing] - cb.InvokeAsync() - .++ diff --git a/code/game/datum_events/moved.dm b/code/game/datum_events/moved.dm deleted file mode 100644 index 49b6bbd28ce..00000000000 --- a/code/game/datum_events/moved.dm +++ /dev/null @@ -1,60 +0,0 @@ -/atom/movable - var/list/move_listeners - -/atom/movable/proc/OnMove(datum/callback/callback) - if (!move_listeners || !move_listeners[callback.object]) - LAZYSET(move_listeners, callback.object, callback) - if (callback.object && callback.object != GLOBAL_PROC) - callback.object.OnDestroy(CALLBACK(src, .proc/UnregisterOnMove, callback.object)) - - var/atom/movable/parent = loc - var/atom/movable/child = src - while (istype(parent) && (!parent.move_listeners || !(parent.move_listeners[child]))) - parent.OnMove(CALLBACK(child, .proc/recursive_move)) - child = parent - parent = child.loc - -/atom/movable/proc/UnregisterOnMove(object) - if (!move_listeners) - return FALSE - - move_listeners[object] = null - move_listeners -= object - - UNSETEMPTY(move_listeners) - . = TRUE - -/atom/movable/proc/RaiseOnMove(atom/movable/source, atom/old_loc, atom/new_loc) - if (!move_listeners) - return FALSE - - . = 0 - for (var/thing in move_listeners) - var/datum/callback/cb = move_listeners[thing] - cb.InvokeAsync(source, old_loc, new_loc) - .++ - -/atom/Entered(atom/movable/AM, atom/old_loc) - . = ..() - if (AM.move_listeners) - AM.RaiseOnMove(AM, old_loc, loc) - -/atom/movable/Entered(atom/movable/AM, atom/old_loc) - . = ..() - if (AM.move_listeners && !(move_listeners && move_listeners[AM])) - OnMove(CALLBACK(AM, .proc/recursive_move)) - -/atom/movable/proc/recursive_move(atom/movable/AM, old_loc, new_loc) - if (move_listeners) - RaiseOnMove(AM, old_loc, new_loc) - -/atom/movable/proc/move_to_destination(atom/movable/AM, old_loc, new_loc) - var/turf/T = get_turf(new_loc) - if (T && T != loc) - forceMove(T) - -/atom/movable/forceMove(atom/dest) - var/oldloc = loc - . = ..() - if (. && move_listeners) - RaiseOnMove(src, oldloc, loc) diff --git a/code/game/gamemodes/mixed/infiltration.dm b/code/game/gamemodes/mixed/infiltration.dm index 81a05215be0..00c62add1c0 100644 --- a/code/game/gamemodes/mixed/infiltration.dm +++ b/code/game/gamemodes/mixed/infiltration.dm @@ -9,3 +9,4 @@ require_all_templates = 1 votable = 1 antag_tags = list(MODE_MALFUNCTION, MODE_NINJA) + disabled_jobs = list("AI") \ No newline at end of file diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm index 66bae9b8f6f..fcda6531cdc 100644 --- a/code/game/jobs/access_datum.dm +++ b/code/game/jobs/access_datum.dm @@ -454,7 +454,7 @@ /datum/access/merchant id = access_merchant desc = "Merchant Access" - access_type = ACCESS_TYPE_NONE + access_type = ACCESS_TYPE_CENTCOM /*************** * Antag access * diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 8cbba3861f0..ca2da97c6f6 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -114,11 +114,10 @@ var/const/HOLOPAD_MODE = RANGE_BASED activate_holocall(caller_id) /obj/machinery/hologram/holopad/proc/end_call(mob/user) + caller_id.unset_machine() caller_id.reset_view() //Send the caller back to his body - clear_holo(caller_id) // destroy the hologram - caller_id = null //Reset caller_id - sourcepad.targetpad = null - sourcepad = null //Reset source + clear_holo(null, caller_id) // destroy the hologram + caller_id = null /obj/machinery/hologram/holopad/proc/activate_holocall(mob/living/carbon/caller_id) if(caller_id) @@ -217,7 +216,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(caller_id) var/tempicon = 0 for(var/datum/data/record/t in data_core.locked) - if(t.fields["name"]==caller_id.name) + if(t.fields["name"] == caller_id.name) tempicon = t.fields["image"] hologram.name = "[caller_id.name] (Hologram)" hologram.loc = get_step(src,1) @@ -245,14 +244,21 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ A.holo = src return 1 -/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/silicon/ai/user) - if(user.holo == src) +/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/silicon/ai/user, mob/living/carbon/caller_id) + if(user) + qdel(masters[user])//Get rid of user's hologram user.holo = null - qdel(masters[user])//Get rid of user's hologram - masters -= user //Discard AI from the list of those who use holopad + masters -= user //Discard AI from the list of those who use holopad + if(caller_id) + qdel(masters[caller_id])//Get rid of user's hologram + masters -= caller_id //Discard the caller from the list of those who use holopad if (!masters.len)//If no users left set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted) icon_state = "holopad0" + if(sourcepad) + sourcepad.targetpad = null + sourcepad = null + caller_id = null return 1 /obj/machinery/hologram/holopad/machinery_process() @@ -267,13 +273,13 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ continue use_power(power_per_hologram) - if(last_request + 200 < world.time&&incoming_connection==1) + if(last_request + 200 < world.time && incoming_connection==1) incoming_connection = 0 end_call() if(sourcepad) sourcepad.audible_message("The holopad connection timed out") sourcepad = 0 - if (caller_id&&sourcepad) + if (caller_id && sourcepad) if(caller_id.loc!=sourcepad.loc) sourcepad.visible_message("Severing connection to distant holopad.") visible_message("The connection has been terminated by [caller_id].") diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index e3122ae13bc..74a37559af5 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -64,7 +64,7 @@ /obj/machinery/icecream_vat/Initialize() . = ..() create_reagents(100) - while(product_types.len < 6) + while(product_types.len < 8) product_types.Add(5) reagents.add_reagent("milk", 5) reagents.add_reagent("flour", 5) @@ -82,7 +82,7 @@ dat += "Vanilla icecream: Select Make x5 [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice)
" dat += "Strawberry icecream: Select Make x5 [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)
" dat += "Chocolate icecream: Select Make x5 [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)
" - dat += "Blue icecream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
" + dat += "Blue icecream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
" dat += "Cherry icecream: Select Make x5 [product_types[ICECREAM_CHERRY]] dollops left. (Ingredients: milk, ice, cherry jelly)
" dat += "Banana icecream: Select Make x5 [product_types[ICECREAM_BANANA]] dollops left. (Ingredients: milk, ice, banana)
" dat += "
CONES
" diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 08de1b9b798..3d9b1a4d754 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -82,7 +82,7 @@ charging = null update_icon() -/obj/machinery/recharger/process() +/obj/machinery/recharger/machinery_process() if(stat & (NOPOWER|BROKEN) || !anchored) update_use_power(0) icon_state = icon_state_idle diff --git a/code/game/machinery/ringer.dm b/code/game/machinery/ringer.dm index 2d7a59d116a..8a73d5a4169 100644 --- a/code/game/machinery/ringer.dm +++ b/code/game/machinery/ringer.dm @@ -54,7 +54,8 @@ return user << "You link \the [C] to \the [src], it will now ring upon someone using \the [src]." rings_pdas += C - C.OnDestroy(CALLBACK(src, .proc/remove_pda, C)) + // WONT FIX: This requires callbacks fuck my dick. + destroyed_event.register(C, src, .proc/remove_pda) update_icon() else @@ -100,7 +101,7 @@ addtimer(CALLBACK(src, .proc/unping), 45 SECONDS) -/obj/machinery/ringer/proc/unping(var/obj/item/device/pda/pda) +/obj/machinery/ringer/proc/unping() pinged = FALSE update_icon() @@ -143,4 +144,4 @@ var/listener/L = thing var/obj/machinery/ringer/C = L.target if (istype(C)) - C.ring_pda() \ No newline at end of file + C.ring_pda() diff --git a/code/game/machinery/station_holomap.dm b/code/game/machinery/station_holomap.dm index 943bcf770ed..a9d85993714 100644 --- a/code/game/machinery/station_holomap.dm +++ b/code/game/machinery/station_holomap.dm @@ -93,8 +93,8 @@ user.client.images |= holomap_datum.station_map watching_mob = user - watching_mob.OnMove(CALLBACK(src, .proc/checkPosition)) - watching_mob.OnDestroy(CALLBACK(src, .proc/stopWatching)) + moved_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) + destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching) update_use_power(2) if(bogus) @@ -120,8 +120,8 @@ animate(holomap_datum.station_map, alpha = 0, time = 5, easing = LINEAR_EASING) var/mob/M = watching_mob addtimer(CALLBACK(src, .proc/clear_image, M, holomap_datum.station_map), 5, TIMER_CLIENT_TIME)//we give it time to fade out - watching_mob.UnregisterOnMove(src) - watching_mob.UnregisterOnDestroy(src) + moved_event.unregister(watching_mob, src) + destroyed_event.unregister(watching_mob, src) watching_mob = null update_use_power(1) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index a4b2533dcf6..0db8f693dec 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -17,7 +17,7 @@ /obj/item/device/multitool/hacktool/Destroy() for(var/T in known_targets) var/atom/target = T - target.UnregisterOnDestroy(src) + destroyed_event.unregister(target, src) known_targets.Cut() qdel(hack_state) hack_state = null @@ -68,7 +68,7 @@ return 0 known_targets.Insert(1, target) // Insert the newly hacked target first, - target.OnDestroy(CALLBACK(src, .proc/on_target_destroy)) + destroyed_event.register(target, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy) return 1 /obj/item/device/multitool/hacktool/proc/sanity_check() @@ -77,7 +77,7 @@ if(known_targets.len > max_known_targets) for(var/i = (max_known_targets + 1) to known_targets.len) var/atom/A = known_targets[i] - A.UnregisterOnDestroy(src) + destroyed_event.unregister(A, src) known_targets.Cut(max_known_targets + 1) /obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index b3de54f204c..5220fabc014 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -50,13 +50,13 @@ unregister_buffer(buffer_object) buffer_object = buffer if(buffer_object) - buffer_object.OnDestroy(CALLBACK(src, .proc/unregister_buffer)) + destroyed_event.register(buffer_object, src, /obj/item/device/multitool/proc/unregister_buffer) /obj/item/device/multitool/proc/unregister_buffer(var/atom/buffer_to_unregister) // Only remove the buffered object, don't reset the name // This means one cannot know if the buffer has been destroyed until one attempts to use it. if(buffer_to_unregister == buffer_object && buffer_object) - buffer_object.UnregisterOnDestroy(src) + destroyed_event.unregister(buffer_object, src) buffer_object = null /obj/item/device/multitool/resolve_attackby(atom/A, mob/user) diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 443c482a510..df8778c8d17 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -65,13 +65,13 @@ unset_registered_user() registered_user = user user.set_id_info(src) - user.OnDestroy(CALLBACK(src, .proc/unset_registered_user)) + destroyed_event.register(user, src, /obj/item/weapon/card/id/syndicate/proc/unset_registered_user) return TRUE /obj/item/weapon/card/id/syndicate/proc/unset_registered_user(var/mob/user) if(!registered_user || (user && user != registered_user)) return - registered_user.UnregisterOnDestroy(src) + destroyed_event.unregister(registered_user, src) registered_user = null /obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index aeb1221f140..d732edb5585 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -444,7 +444,7 @@ /obj/item/weapon/storage/backpack/messenger/tox name = "research messenger bag" desc = "A backpack worn over one shoulder. Useful for holding science materials." - icon_state = "courierbagnt" + icon_state = "courierbagtox" /obj/item/weapon/storage/backpack/messenger/gen name = "geneticist messenger bag" diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 40d9a948e14..e6fab23344f 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -151,8 +151,8 @@ if(!newname || newname == "") var/datum/language/L = all_languages[user.species.default_language] newname = L.get_random_name() - user.real_name = newname - user.name = user.real_name + user.fully_replace_character_name(user.real_name,newname) user.h_style = "Short Vox Quills" user.f_style = "Shaved" + user.update_hair(0) ..() \ No newline at end of file diff --git a/code/modules/ambient_occlusion/ao_turf.dm b/code/modules/ambient_occlusion/ao_turf.dm index f2d857e5e78..c11cd15cbfe 100644 --- a/code/modules/ambient_occlusion/ao_turf.dm +++ b/code/modules/ambient_occlusion/ao_turf.dm @@ -1,7 +1,7 @@ #ifdef AO_USE_LIGHTING_OPACITY -#define AO_TURF_CHECK(T) (!T.has_opaque_atom) +#define AO_TURF_CHECK(T) (!T.has_opaque_atom || !T.permit_ao) #else -#define AO_TURF_CHECK(T) (!T.density || !T.opacity) +#define AO_TURF_CHECK(T) (!T.density || !T.opacity || !T.permit_ao) #endif /turf diff --git a/code/modules/client/preference_setup/global/02_settings.dm b/code/modules/client/preference_setup/global/02_settings.dm index 1f7568e1c8d..71ad90270f1 100644 --- a/code/modules/client/preference_setup/global/02_settings.dm +++ b/code/modules/client/preference_setup/global/02_settings.dm @@ -31,7 +31,9 @@ "toggles", "asfx_togs", "lastmotd" = "motd_hash", - "lastmemo" = "memo_hash" + "lastmemo" = "memo_hash", + "parallax_toggles" = "parallax_togs", + "parallax_speed" ), "args" = list("ckey") ) diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 6c8467ba6f9..d3a5900f1f1 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -64,7 +64,7 @@ var/list/gear_datums = list() continue if(G.whitelisted && preference_mob) for(var/species in G.whitelisted) - if(is_alien_whitelisted(preference_mob, species)) + if(is_alien_whitelisted(preference_mob, global.all_species[species])) . += gear_name break else diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index d605db74fc2..61ab553f077 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -206,7 +206,7 @@ All custom items with worn sprites must follow the contained sprite system: http contained_sprite = TRUE gender = NEUTER body_parts_covered = null - + fingerprint_chance = 50 /obj/structure/bed/chair/wheelchair/fluff/nomak_scooter //Mobility Scooter - Dubaku Nomak - demonofthefall name = "mobility scooter" @@ -491,7 +491,7 @@ All custom items with worn sprites must follow the contained sprite system: http species_restricted = null gender = NEUTER body_parts_covered = null - + fingerprint_chance = 100 /obj/item/clothing/under/dress/fluff/sayyidah_dress //Traditional Jumper Dress - Sayyidah Al-Kateb - alberyk name = "traditional jumper dress" @@ -1403,15 +1403,15 @@ All custom items with worn sprites must follow the contained sprite system: http if (use_check(usr)) return - var/style = input("You change the shirt to;","Change the shirt style") as null|anything in list("Eiffel Tower Diner","Pyramids of Giza Café","Phoenixport","New Parthenon") + var/style = input("You change the shirt to;","Change the shirt style") as null|anything in list("Eiffel Tower Diner","Pyramids of Giza CafĂ©","Phoenixport","New Parthenon") switch(style) if("Eiffel Tower Diner") item_state = "harley_uniform" desc = "A white t-shirt with the writing \"Eiffel Tower Diner\" on it in a small font, below a recreation of the famous monument in question, the Eiffel Tower." - if("Pyramids of Giza Café") + if("Pyramids of Giza CafĂ©") item_state = "harley_uniform_1" - desc = "A white t-shirt with \"GIZA CAFÉ\" written in large, retro font, with a small background. It looks slightly well-worn." + desc = "A white t-shirt with \"GIZA CAFÉ\" written in large, retro font, with a small background. It looks slightly well-worn." if("Phoenixport") item_state = "harley_uniform_2" @@ -1424,3 +1424,25 @@ All custom items with worn sprites must follow the contained sprite system: http usr.update_inv_w_uniform() usr.visible_message("[user] fumbles with \the [src], changing the shirt..", "You change \the [src]'s style to be '[style]'.") + + +/obj/item/clothing/gloves/watch/fluff/rex_watch //Engraved Wristwatch - Rex Winters - tailson + name = "engraved wristwatch" + desc = " A fine gold watch. On the inside is an engraving that reads \"Happy birthday dad, thinking of you always\"." + icon = 'icons/obj/custom_items/rex_watch.dmi' + icon_state = "rex_watch" + + +/obj/item/device/camera/fluff/hadley_camera //Hadley's Camera - Hadley Dawson - fekkor + name = "customized camera" + desc = "A early 2450's Sunny camera with an adjustable lens, this one has a sticker with the name \"Hadley\" on the back." + icon = 'icons/obj/custom_items/hadley_camera.dmi' + icon_state = "hadley_camera" + icon_on = "hadley_camera" + icon_off = "hadley_camera_off" + + +/obj/item/clothing/accessory/medal/silver/fluff/kalren_medal //Silver Star of Merit - Kalren Halstere - brutishcrab51 + name = "silver star of merit" + desc = "The Biesel Silver Star of Merit, rewarded for bravery and professionalism in the line of duty." + icon_state = "silver_sword" diff --git a/code/modules/ghosttrap/trap.dm b/code/modules/ghosttrap/trap.dm index 2ae8d2124d0..a419dc82a31 100644 --- a/code/modules/ghosttrap/trap.dm +++ b/code/modules/ghosttrap/trap.dm @@ -50,7 +50,7 @@ var/list/ghost_traps /datum/ghosttrap/proc/request_player(var/mob/target, var/request_string, var/request_timeout) if(request_timeout) request_timeouts[target] = world.time + request_timeout - target.OnDestroy(CALLBACK(src, .proc/target_destroyed)) + destroyed_event.register(target, src, /datum/ghosttrap/proc/target_destroyed) else request_timeouts -= target diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 082c2826402..19b43d1cfd9 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -91,7 +91,8 @@ for(var/i = 1 to outputs.len) set_pin_data(IC_OUTPUT, i, i == output_index ? output : null) - + + push_data() activate_pin(2) /obj/item/integrated_circuit/transfer/demultiplexer/medium diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 0f68103d896..3f1a7474ed2 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -166,6 +166,7 @@ else set_pin_data(IC_OUTPUT, 1, null) + push_data() activate_pin(2) /obj/item/integrated_circuit/input/adjacent_locator @@ -185,6 +186,7 @@ var/atom/A = get_pin_data_as_type(IC_INPUT, 1, /atom) if(!A) set_pin_data(IC_OUTPUT, 1, null) + push_data() return var/desired_type = A.type @@ -197,6 +199,7 @@ if(valid_things.len) set_pin_data(IC_OUTPUT, 1, pick(valid_things)) + push_data() /obj/item/integrated_circuit/input/signaler name = "integrated signaler" diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 648bcc20f76..43e0b72d54c 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -170,14 +170,14 @@ // These procs do not relocate the grenade, that's the callers responsibility /obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/weapon/grenade/G) attached_grenade = G - attached_grenade.OnDestroy(CALLBACK(src, .proc/detach_grenade)) + destroyed_event.register(attached_grenade, src, .proc/detach_grenade) size += G.w_class desc += " \An [attached_grenade] is attached to it!" /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() if(!attached_grenade) return - attached_grenade.UnregisterOnDestroy(src) + destroyed_event.unregister(attached_grenade, src) attached_grenade = null size = initial(size) desc = initial(desc) diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 114e456a6b5..fa0a4fa16a1 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -41,7 +41,7 @@ for(var/i = 1 to inputs.len) var/data = get_pin_data(IC_INPUT, i) set_pin_data(IC_OUTPUT, i, data) - + push_data() activate_pin(2) /obj/item/integrated_circuit/memory/storage/medium @@ -85,6 +85,7 @@ /obj/item/integrated_circuit/memory/constant/do_work() set_pin_data(IC_OUTPUT, 1, data) + push_data() activate_pin(2) /obj/item/integrated_circuit/memory/constant/attack_self(mob/user) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index a578dd42429..25f202ad40e 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -272,6 +272,7 @@ if(camera) set_camera_status(0) set_pin_data(IC_INPUT, 2, FALSE) + push_data() /obj/item/integrated_circuit/output/led name = "light-emitting diode" @@ -292,6 +293,7 @@ /obj/item/integrated_circuit/output/led/power_fail() set_pin_data(IC_INPUT, 1, FALSE) + push_data() /obj/item/integrated_circuit/output/led/any_examine(mob/user) var/text_output = list() diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 26972380429..340a584819f 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -20,11 +20,14 @@ set_pin_data(IC_OUTPUT, 1, null) if(!isweakref(I.data)) + push_data() return var/atom/A = I.data.resolve() if(!A) + push_data() return if(!(A in view(get_turf(src)))) + push_data() return // Can't see the target. var/desired_dir = get_dir(get_turf(src), A) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index e776b67afd1..7cca06dcfc7 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -357,8 +357,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp stop_following() following = target - following.OnMove(CALLBACK(src, /atom/movable/.proc/move_to_destination)) - following.OnDestroy(CALLBACK(src, .proc/stop_following)) + moved_event.register(following, src, /atom/movable/proc/move_to_destination) + destroyed_event.register(following, src, /mob/dead/observer/proc/stop_following) src << "Now following \the [following]" move_to_destination(following, following.loc, following.loc) @@ -366,8 +366,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/proc/stop_following() if(following) src << "No longer following \the [following]" - following.UnregisterOnMove(src) - following.UnregisterOnDestroy(src) + moved_event.unregister(following, src) + destroyed_event.unregister(following, src) following = null /mob/dead/observer/move_to_destination(var/atom/movable/am, var/old_loc, var/new_loc) diff --git a/code/modules/mob/freelook/mask/update_triggers.dm b/code/modules/mob/freelook/mask/update_triggers.dm index 2da12ccf5c4..2b3ab6e9d75 100644 --- a/code/modules/mob/freelook/mask/update_triggers.dm +++ b/code/modules/mob/freelook/mask/update_triggers.dm @@ -36,7 +36,7 @@ /mob/living/death(gibbed, deathmessage="seizes up and falls limp...") . = ..() - if (.) + if(.) // If true, the mob went from living to dead (assuming everyone has been overriding as they should...) cultnet.updateVisibility(src) diff --git a/code/modules/mob/living/simple_animal/hostile/sarlacc.dm b/code/modules/mob/living/simple_animal/hostile/sarlacc.dm index e519e3a47da..9405e276ad1 100644 --- a/code/modules/mob/living/simple_animal/hostile/sarlacc.dm +++ b/code/modules/mob/living/simple_animal/hostile/sarlacc.dm @@ -205,12 +205,8 @@ asleep = 1 icon_state = "sarlacc_asleep" sarlacc.deployed = 0 - var/make_loot = loot_count visible_message("With a contented heave, \the [src] slides into the earth and begins regurgitating several treasures before shutting tight.") - while(make_loot) - for(var/turf/simulated/floor/F in orange(1,src)) - new /obj/random/loot(F) - make_loot-- + new/obj/random/loot(get_turf(src)) /mob/living/simple_animal/hostile/greatworm/FindTarget() if(eating) diff --git a/code/modules/projectiles/targeting/targeting_mob.dm b/code/modules/projectiles/targeting/targeting_mob.dm index ad82b9f48ad..decb5e4fa9a 100644 --- a/code/modules/projectiles/targeting/targeting_mob.dm +++ b/code/modules/projectiles/targeting/targeting_mob.dm @@ -23,7 +23,7 @@ /mob/living/death(gibbed,deathmessage="seizes up and falls limp...") . = ..() - if (.) + if(.) stop_aiming(no_message=1) /mob/living/update_canmove() diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm index dfce63bacfc..cc23bcec696 100644 --- a/code/modules/projectiles/targeting/targeting_overlay.dm +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -173,9 +173,9 @@ obj/aiming_overlay/proc/update_aiming_deferred() locked = 0 update_icon() lock_time = world.time + 35 - owner.OnMove(CALLBACK(src, .proc/update_aiming)) - aiming_at.OnMove(CALLBACK(src, .proc/target_moved)) - aiming_at.OnDestroy(CALLBACK(src, .proc/cancel_aiming)) + moved_event.register(owner, src, /obj/aiming_overlay/proc/update_aiming) + moved_event.register(aiming_at, src, /obj/aiming_overlay/proc/target_moved) + destroyed_event.register(aiming_at, src, /obj/aiming_overlay/proc/cancel_aiming) /obj/aiming_overlay/proc/aim_cooldown(var/seconds) aimcooldown = world.time + seconds SECONDS @@ -213,10 +213,10 @@ obj/aiming_overlay/proc/update_aiming_deferred() if(!no_message) owner.visible_message("\The [owner] lowers \the [aiming_with].") - owner.UnregisterOnMove(src) + moved_event.unregister(owner, src) if(aiming_at) - aiming_at.UnregisterOnMove(src) - aiming_at.UnregisterOnDestroy(src) + moved_event.unregister(aiming_at, src) + destroyed_event.unregister(aiming_at, src) aiming_at.aimed -= src aiming_at = null diff --git a/code/unit_tests/observation_tests.dm b/code/unit_tests/observation_tests.dm index c952f5efb57..7dc522aa8f4 100644 --- a/code/unit_tests/observation_tests.dm +++ b/code/unit_tests/observation_tests.dm @@ -1,5 +1,5 @@ /proc/is_listening_to_movement(var/atom/movable/listening_to, var/listener) - return !!(listening_to.move_listeners && listening_to.move_listeners[listener]) + return moved_event.is_listening(listening_to, listener) datum/unit_test/observation name = "OBSERVATION template" @@ -19,8 +19,8 @@ datum/unit_test/observation/moved_observer_shall_register_on_follow/start_test() else fail("The observer is not following the mob.") - qdel(H) - qdel(O) + QDEL_IN(H, 10 SECONDS) + QDEL_IN(O, 10 SECONDS) return 1 datum/unit_test/observation/moved_observer_shall_unregister_on_nofollow @@ -38,8 +38,8 @@ datum/unit_test/observation/moved_observer_shall_unregister_on_nofollow/start_te else fail("The observer is still following the mob.") - qdel(H) - qdel(O) + QDEL_IN(H, 10 SECONDS) + QDEL_IN(O, 10 SECONDS) return 1 datum/unit_test/observation/moved_shall_not_register_on_enter_without_listeners @@ -56,8 +56,8 @@ datum/unit_test/observation/moved_shall_not_register_on_enter_without_listeners/ else fail("The mob has registered to the closet's moved event.") - qdel(C) - qdel(H) + QDEL_IN(C, 10 SECONDS) + QDEL_IN(H, 10 SECONDS) return 1 datum/unit_test/observation/moved_shall_registers_recursively_on_new_listener @@ -78,9 +78,9 @@ datum/unit_test/observation/moved_shall_registers_recursively_on_new_listener/st else fail("Recursive moved registration failed. Human listening to closet: [listening_to_closet] - Observer listening to human: [listening_to_human]") - qdel(C) - qdel(H) - qdel(O) + QDEL_IN(C, 10 SECONDS) + QDEL_IN(H, 10 SECONDS) + QDEL_IN(O, 10 SECONDS) return 1 datum/unit_test/observation/moved_shall_registers_recursively_with_existing_listener @@ -101,8 +101,8 @@ datum/unit_test/observation/moved_shall_registers_recursively_with_existing_list else fail("Recursive moved registration failed. Human listening to closet: [listening_to_closet] - Observer listening to human: [listening_to_human]") - qdel(C) - qdel(H) - qdel(O) + QDEL_IN(C, 10 SECONDS) + QDEL_IN(H, 10 SECONDS) + QDEL_IN(O, 10 SECONDS) return 1 diff --git a/code/world.dm b/code/world.dm index c4df35bce2c..fa9d0adbce6 100644 --- a/code/world.dm +++ b/code/world.dm @@ -107,12 +107,25 @@ var/list/world_api_rate_limit = list() /world/Topic(T, addr, master, key) var/list/response[] = list() - var/list/queryparams[] = json_decode(T) + var/list/queryparams[] + + try + queryparams = json_decode(T) + catch() + queryparams = list() + + log_debug("API: Request Received - from:[addr], master:[master], key:[key]") + diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key], auth:[queryparams["auth"] ? queryparams["auth"] : "null"] [log_end]" + + if (!queryparams.len) + log_debug("API - Bad Request - Invalid/no JSON data sent.") + response["statuscode"] = 400 + response["response"] = "Bad Request - Invalid/no JSON data sent." + return json_encode(response) + queryparams["addr"] = addr //Add the IP to the queryparams that are passed to the api functions var/query = queryparams["query"] var/auth = queryparams["auth"] - log_debug("API: Request Received - from:[addr], master:[master], key:[key]") - diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key], auth:[auth] [log_end]" /*if (!SSticker) //If the game is not started most API Requests would not work because of the throtteling response["statuscode"] = 500 diff --git a/html/changelog.html b/html/changelog.html index 8bf8ea2fe0c..ef07640fe14 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,19 @@ -->
+

20 October 2017

+

Lohikar updated:

+ +

MoondancerPony updated:

+ +

15 October 2017

AgentWhatever updated: