[MIRROR] Fixes a bunch of harddels that are sourced from player action (#6252)

* Fixes a bunch of harddels that are sourced from player action

* Mirror!

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Funce <funce.973@gmail.com>
This commit is contained in:
SkyratBot
2021-06-11 03:13:33 +01:00
committed by GitHub
co-authored by LemonInTheDark Funce
parent cc5595fddf
commit 6f3b151bb8
165 changed files with 1076 additions and 546 deletions
+1 -1
View File
@@ -74,7 +74,7 @@
#define COOLDOWN_DECLARE(cd_index) var/##cd_index = 0
#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + cd_time)
#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))
//Returns true if the cooldown has run its course, false otherwise
#define COOLDOWN_FINISHED(cd_source, cd_index) (cd_source.cd_index < world.time)
+2
View File
@@ -445,3 +445,5 @@
#define THROW_MODE_TOGGLE 1
#define THROW_MODE_HOLD 2
//Saves a proc call, life is suffering. If who has no targets_from var, we assume it's just who
#define GET_TARGETS_FROM(who) (who.targets_from ? who.get_targets_from() : who)
+3
View File
@@ -88,6 +88,9 @@
///Call qdel on the atom after intialization
#define INITIALIZE_HINT_QDEL 2
///Call qdel with a force of TRUE after initialization
#define INITIALIZE_HINT_QDEL_FORCE 3
///type and all subtypes should always immediately call Initialize in New()
#define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\
..();\
+3
View File
@@ -632,6 +632,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Traits applied to a silicon mob by their model.
#define MODEL_TRAIT "model_trait"
/// Trait granted by [mob/living/silicon/ai]
/// Applied when the ai anchors itself
#define AI_ANCHOR_TRAIT "ai_anchor"
/// Trait from [/datum/antagonist/nukeop/clownop]
#define CLOWNOP_TRAIT "clownop"
+5
View File
@@ -57,6 +57,11 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
SEND_TEXT(world.log, text)
#endif
#ifdef REFERENCE_TRACKING_LOG
#define log_reftracker(msg) log_world("## REF SEARCH [msg]")
#else
#define log_reftracker(msg)
#endif
/* Items with ADMINPRIVATE prefixed are stripped from public logs. */
/proc/log_admin(text)
+3
View File
@@ -15,6 +15,9 @@
//#define REFERENCE_TRACKING
#ifdef REFERENCE_TRACKING
///Should we be logging our findings or not
#define REFERENCE_TRACKING_LOG
///Used for doing dry runs of the reference finder, to test for feature completeness
//#define REFERENCE_TRACKING_DEBUG
+13 -2
View File
@@ -8,6 +8,17 @@ GLOBAL_LIST_EMPTY(radial_menus)
plane = ABOVE_HUD_PLANE
var/datum/radial_menu/parent
/atom/movable/screen/radial/proc/set_parent(new_value)
if(parent)
UnregisterSignal(parent, COMSIG_PARENT_QDELETING)
parent = new_value
if(parent)
RegisterSignal(parent, COMSIG_PARENT_QDELETING, .proc/handle_parent_del)
/atom/movable/screen/radial/proc/handle_parent_del()
SIGNAL_HANDLER
set_parent(null)
/atom/movable/screen/radial/slice
icon_state = "radial_slice"
var/choice
@@ -133,7 +144,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
var/atom/movable/screen/radial/slice/new_element = new /atom/movable/screen/radial/slice
new_element.icon = icon_path //SKYRAT EDIT ADDITION - GUNPOINT
new_element.tooltips = use_tooltips
new_element.parent = src
new_element.set_parent(src)
elements += new_element
var/page = 1
@@ -227,7 +238,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
/datum/radial_menu/New()
close_button = new
close_button.parent = src
close_button.set_parent(src)
/datum/radial_menu/proc/Reset()
choices.Cut()
+1 -1
View File
@@ -26,7 +26,7 @@
/datum/radial_menu/persistent/New()
close_button = new /atom/movable/screen/radial/persistent/center
close_button.parent = src
close_button.set_parent(src)
/datum/radial_menu/persistent/element_chosen(choice_id,mob/user)
+3
View File
@@ -101,6 +101,9 @@ SUBSYSTEM_DEF(atoms)
if(INITIALIZE_HINT_QDEL)
qdel(A)
qdeleted = TRUE
if(INITIALIZE_HINT_QDEL_FORCE)
qdel(A, force = TRUE)
qdeleted = TRUE
else
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
+16 -4
View File
@@ -170,27 +170,34 @@ SUBSYSTEM_DEF(garbage)
// Something's still referring to the qdel'd object.
fail_counts[level]++
#ifdef REFERENCE_TRACKING
var/ref_searching = FALSE
#endif
switch (level)
if (GC_QUEUE_CHECK)
#ifdef REFERENCE_TRACKING
if(reference_find_on_fail[refID])
D.find_references()
INVOKE_ASYNC(D, /datum/proc/find_references)
ref_searching = TRUE
#ifdef GC_FAILURE_HARD_LOOKUP
else
D.find_references()
INVOKE_ASYNC(D, /datum/proc/find_references)
ref_searching = TRUE
#endif
reference_find_on_fail -= refID
#endif
var/type = D.type
var/datum/qdel_item/I = items[type]
#ifdef TESTING
log_world("## TESTING: GC: -- \ref[D] | [type] was unable to be GC'd --")
#ifdef TESTING
for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage
var/client/admin = c
if(!check_rights_for(admin, R_ADMIN))
continue
to_chat(admin, "## TESTING: GC: -- [ADMIN_VV(D)] | [type] was unable to be GC'd --")
testing("GC: -- \ref[src] | [type] was unable to be GC'd --")
#endif
I.failures++
if (GC_QUEUE_HARDDELETE)
@@ -201,6 +208,11 @@ SUBSYSTEM_DEF(garbage)
Queue(D, level+1)
#ifdef REFERENCE_TRACKING
if(ref_searching)
return
#endif
if (MC_TICK_CHECK)
return
if (count)
+1 -1
View File
@@ -353,7 +353,7 @@ SUBSYSTEM_DEF(persistence)
if(!istype(ending_human) || !ending_human.mind?.original_character_slot_index || !ending_human.client || !ending_human.client.prefs || !ending_human.client.prefs.persistent_scars)
continue
var/mob/living/carbon/human/original_human = ending_human.mind.original_character
var/mob/living/carbon/human/original_human = ending_human.mind.original_character.resolve()
if(!original_human)
continue
@@ -5,12 +5,10 @@ SUBSYSTEM_DEF(vis_overlays)
init_order = INIT_ORDER_VIS
var/list/vis_overlay_cache
var/list/unique_vis_overlays
var/list/currentrun
/datum/controller/subsystem/vis_overlays/Initialize()
vis_overlay_cache = list()
unique_vis_overlays = list()
return ..()
/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
@@ -45,7 +43,6 @@ SUBSYSTEM_DEF(vis_overlays)
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
overlay.cache_expiration = -1
var/cache_id = "\ref[overlay]@{[world.time]}"
unique_vis_overlays += overlay
vis_overlay_cache[cache_id] = overlay
. = overlay
thing.vis_contents += overlay
+4 -3
View File
@@ -26,7 +26,7 @@
if(!success) //Don't try again on this item if we failed
var/obj/item/target = controller.blackboard[BB_FETCH_TARGET]
if(target)
controller.blackboard[BB_FETCH_IGNORE_LIST][target] = TRUE
controller.blackboard[BB_FETCH_IGNORE_LIST][WEAKREF(target)] = TRUE
controller.blackboard[BB_FETCH_TARGET] = null
controller.blackboard[BB_FETCH_DELIVER_TO] = null
@@ -171,12 +171,13 @@
if(!istype(living_pawn) || !(isturf(living_pawn.loc) || HAS_TRAIT(living_pawn, TRAIT_AI_BAGATTACK)))
return
var/atom/movable/harass_target = controller.blackboard[BB_DOG_HARASS_TARGET]
var/datum/weakref/harass_ref = controller.blackboard[BB_DOG_HARASS_TARGET]
var/atom/movable/harass_target = harass_ref.resolve()
if(!harass_target || !can_see(living_pawn, harass_target, length=AI_DOG_VISION_RANGE))
finish_action(controller, FALSE)
return
if(controller.blackboard[BB_DOG_FRIENDS][harass_target])
if(controller.blackboard[BB_DOG_FRIENDS][harass_ref])
living_pawn.visible_message("<span class='danger'>[living_pawn] looks sideways at [harass_target] for a moment, then shakes [living_pawn.p_their()] head and ceases aggression.</span>")
finish_action(controller, FALSE)
return
+10 -9
View File
@@ -131,7 +131,7 @@
var/obj/item/thrown_thing = carbon_thrower.get_active_held_item()
if(!isitem(thrown_thing))
return
if(blackboard[BB_FETCH_IGNORE_LIST][thrown_thing])
if(blackboard[BB_FETCH_IGNORE_LIST][WEAKREF(thrown_thing)])
return
RegisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED, .proc/listen_throw_land)
@@ -160,7 +160,7 @@
befriend(user)
// if the dog has something in their mouth that they're not bringing to someone for whatever reason, have them drop it when pet by a friend
var/list/friends = blackboard[BB_DOG_FRIENDS]
if(blackboard[BB_SIMPLE_CARRY_ITEM] && !current_movement_target && friends[user])
if(blackboard[BB_SIMPLE_CARRY_ITEM] && !current_movement_target && friends[WEAKREF(user)])
var/obj/item/carried_item = blackboard[BB_SIMPLE_CARRY_ITEM]
pawn.visible_message("<span='danger'>[pawn] drops [carried_item] at [user]'s feet!</span>")
// maybe have a dedicated proc for dropping things
@@ -170,18 +170,19 @@
/// Someone is being nice to us, let's make them a friend!
/datum/ai_controller/dog/proc/befriend(mob/living/new_friend)
var/list/friends = blackboard[BB_DOG_FRIENDS]
if(friends[new_friend])
var/datum/weakref/friend_ref = WEAKREF(new_friend)
if(friends[friend_ref])
return
if(in_range(pawn, new_friend))
new_friend.visible_message("<b>[pawn]</b> licks at [new_friend] in a friendly manner!", "<span class='notice'>[pawn] licks at you in a friendly manner!</span>")
friends[new_friend] = TRUE
friends[friend_ref] = TRUE
RegisterSignal(new_friend, COMSIG_MOB_POINTED, .proc/check_point)
RegisterSignal(new_friend, COMSIG_MOB_SAY, .proc/check_verbal_command)
/// Someone is being mean to us, take them off our friends (add actual enemies behavior later)
/datum/ai_controller/dog/proc/unfriend(mob/living/ex_friend)
var/list/friends = blackboard[BB_DOG_FRIENDS]
friends[ex_friend] = null
friends -= WEAKREF(ex_friend)
UnregisterSignal(ex_friend, list(COMSIG_MOB_POINTED, COMSIG_MOB_SAY))
/// Someone is looking at us, if we're currently carrying something then show what it is, and include a message if they're our friend
@@ -191,7 +192,7 @@
var/obj/item/carried_item = blackboard[BB_SIMPLE_CARRY_ITEM]
if(carried_item)
examine_text += "<span class='notice'>[pawn.p_they(TRUE)] [pawn.p_are()] carrying [carried_item.get_examine_string(user)] in [pawn.p_their()] mouth.</span>"
if(blackboard[BB_DOG_FRIENDS][user])
if(blackboard[BB_DOG_FRIENDS][WEAKREF(user)])
var/mob/living/living_pawn = pawn
if(!IS_DEAD_OR_INCAP(living_pawn))
examine_text += "<span class='notice'>[pawn.p_they(TRUE)] seem[pawn.p_s()] happy to see you!</span>"
@@ -216,7 +217,7 @@
if(!COOLDOWN_FINISHED(src, command_cooldown))
return
if(!istype(clicker) || !blackboard[BB_DOG_FRIENDS][clicker])
if(!istype(clicker) || !blackboard[BB_DOG_FRIENDS][WEAKREF(clicker)])
return
. = COMPONENT_CANCEL_CLICK_ALT
INVOKE_ASYNC(src, .proc/command_radial, clicker)
@@ -246,7 +247,7 @@
/datum/ai_controller/dog/proc/check_verbal_command(mob/speaker, speech_args)
SIGNAL_HANDLER
if(!blackboard[BB_DOG_FRIENDS][speaker])
if(!blackboard[BB_DOG_FRIENDS][WEAKREF(speaker)])
return
if(!COOLDOWN_FINISHED(src, command_cooldown))
@@ -327,7 +328,7 @@
if(DOG_COMMAND_ATTACK)
pawn.visible_message("<span class='notice'>[pawn] follows [pointing_friend]'s gesture towards [pointed_movable] and growls intensely!</span>")
current_movement_target = pointed_movable
blackboard[BB_DOG_HARASS_TARGET] = pointed_movable
blackboard[BB_DOG_HARASS_TARGET] = WEAKREF(pointed_movable)
if(living_pawn.buckled)
current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/resist)//in case they are in bed or something
current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/harass)
+3 -2
View File
@@ -305,8 +305,9 @@ have ways of interacting with a specific mob and control it.
if(istype(AM, /obj/item))
var/mob/living/living_pawn = pawn
var/obj/item/I = AM
if(I.throwforce < living_pawn.health && ishuman(I.thrownby))
var/mob/living/carbon/human/H = I.thrownby
var/mob/thrown_by = I.thrownby?.resolve()
if(I.throwforce < living_pawn.health && ishuman(thrown_by))
var/mob/living/carbon/human/H = thrown_by
retaliate(H)
/datum/ai_controller/monkey/proc/on_entered(datum/source, atom/movable/AM)
+1 -1
View File
@@ -68,7 +68,7 @@
/datum/beam/Destroy()
QDEL_LIST(elements)
qdel(visuals)
QDEL_NULL(visuals)
UnregisterSignal(origin, COMSIG_MOVABLE_MOVED)
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
target = null
+13 -4
View File
@@ -4,7 +4,7 @@
var/window_id // window_id is used as the window name for browse and onclose
var/width = 0
var/height = 0
var/atom/ref = null
var/datum/weakref/ref = null
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
var/stylesheets[0]
var/scripts[0]
@@ -16,8 +16,8 @@
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null)
user = nuser
RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/user_deleted)
window_id = nwindow_id
if (ntitle)
title = format_text(ntitle)
@@ -26,7 +26,11 @@
if (nheight)
height = nheight
if (nref)
ref = nref
ref = WEAKREF(nref)
/datum/browser/proc/user_deleted(datum/source)
SIGNAL_HANDLER
user = null
/datum/browser/proc/add_head_content(nhead_content)
head_content = nhead_content
@@ -114,7 +118,12 @@
set waitfor = 0 //winexists sleeps, so we don't need to.
for (var/i in 1 to 10)
if (user?.client && winexists(user, window_id))
onclose(user, window_id, ref)
var/atom/send_ref
if(ref)
send_ref = ref.resolve()
if(!send_ref)
ref = null
onclose(user, window_id, send_ref)
break
/datum/browser/proc/close()
+1 -2
View File
@@ -132,8 +132,7 @@
for(var/i in affixes)
var/datum/fantasy_affix/affix = i
affix.remove(src)
for(var/i in appliedComponents)
qdel(i)
QDEL_LIST(appliedComponents)
master.force = max(0, master.force - quality)
master.throwforce = max(0, master.throwforce - quality)
+1 -1
View File
@@ -308,7 +308,7 @@
var/w_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS]
var/bw_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS]
var/wound_type = (initial(P.damage_type) == BRUTE) ? WOUND_BLUNT : WOUND_BURN // sharpness is handled in the wound rolling
wound_info_by_part[hit_part] = null
wound_info_by_part -= hit_part
hit_part.painless_wound_roll(wound_type, damage_dealt, w_bonus, bw_bonus, initial(P.sharpness))
if(num_hits > 1)
+1 -1
View File
@@ -97,7 +97,7 @@
if(AM.movement_type & (FLYING|FLOATING) || !AM.has_gravity())
return
var/atom/current_parent = parent
if(isturf(current_parent.loc))
if(isturf(current_parent?.loc))
play_squeak()
/datum/component/squeak/proc/use_squeak()
+12 -4
View File
@@ -398,20 +398,27 @@
M.client.screen |= boxes
M.client.screen |= closer
M.client.screen |= real_location.contents
M.active_storage = src
M.set_active_storage(src)
LAZYOR(is_using, M)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/mob_deleted)
return TRUE
/datum/component/storage/proc/mob_deleted(datum/source)
SIGNAL_HANDLER
hide_from(source)
/datum/component/storage/proc/hide_from(mob/M)
if(M.active_storage == src)
M.set_active_storage(null)
LAZYREMOVE(is_using, M)
UnregisterSignal(M, COMSIG_PARENT_QDELETING)
if(!M.client)
return TRUE
var/atom/real_location = real_location()
M.client.screen -= boxes
M.client.screen -= closer
M.client.screen -= real_location.contents
if(M.active_storage == src)
M.active_storage = null
LAZYREMOVE(is_using, M)
return TRUE
/datum/component/storage/proc/close(mob/M)
@@ -490,6 +497,7 @@
cansee |= M
else
LAZYREMOVE(is_using, M)
UnregisterSignal(M, COMSIG_PARENT_QDELETING)
return cansee
//Tries to dump content
+1 -4
View File
@@ -77,6 +77,7 @@
/obj/item/udder/Destroy()
. = ..()
STOP_PROCESSING(SSobj, src)
udder_mob = null
/obj/item/udder/process(delta_time)
if(udder_mob.stat != DEAD)
@@ -132,10 +133,6 @@
START_PROCESSING(SSobj, src)
RegisterSignal(udder_mob, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, .proc/on_mob_attacking)
/obj/item/udder/gutlunch/Destroy()
. = ..()
UnregisterSignal(udder_mob, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)
/obj/item/udder/gutlunch/process(delta_time)
var/mob/living/simple_animal/hostile/asteroid/gutlunch/gutlunch = udder_mob
if(reagents.total_volume != reagents.maximum_volume)
+8 -6
View File
@@ -6,7 +6,6 @@
var/current_charges = 1
var/max_charges = 1
var/charge_rate = 250
var/mob/living/carbon/human/holder
var/obj/item/dashing_item
var/dash_sound = 'sound/magic/blink.ogg'
var/recharge_sound = 'sound/magic/charge.ogg'
@@ -17,7 +16,10 @@
/datum/action/innate/dash/Grant(mob/user, obj/dasher)
. = ..()
dashing_item = dasher
holder = user
/datum/action/innate/dash/Destroy()
dashing_item = null
return ..()
/datum/action/innate/dash/IsAvailable()
if(current_charges > 0)
@@ -26,7 +28,7 @@
return FALSE
/datum/action/innate/dash/Activate()
dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item
dashing_item.attack_self(owner) //Used to toggle dash behavior in the dashing item
/datum/action/innate/dash/proc/Teleport(mob/user, atom/target)
if(!IsAvailable())
@@ -39,12 +41,12 @@
var/obj/spot2 = new phasein(get_turf(user), user.dir)
spot1.Beam(spot2,beam_effect,time=2 SECONDS)
current_charges--
holder.update_action_buttons_icon()
owner.update_action_buttons_icon()
addtimer(CALLBACK(src, .proc/charge), charge_rate)
/datum/action/innate/dash/proc/charge()
current_charges = clamp(current_charges + 1, 0, max_charges)
holder.update_action_buttons_icon()
owner.update_action_buttons_icon()
if(recharge_sound)
playsound(dashing_item, recharge_sound, 50, TRUE)
to_chat(holder, "<span class='notice'>[src] now has [current_charges]/[max_charges] charges.</span>")
to_chat(owner, "<span class='notice'>[src] now has [current_charges]/[max_charges] charges.</span>")
+5 -4
View File
@@ -15,7 +15,7 @@
///new name given to the item on announce
var/new_name
///optional fantasy component, used in building the name if provided
var/datum/component/fantasy/fantasy_component
var/datum/weakref/fantasy_component
/datum/element/curse_announcement/Attach(datum/target, announcement_message, filter_color, new_name, datum/component/fantasy/fantasy_component)
. = ..()
@@ -25,7 +25,7 @@
src.announcement_message = announcement_message
src.filter_color = filter_color
src.new_name = new_name
src.fantasy_component = fantasy_component
src.fantasy_component = WEAKREF(fantasy_component)
if(cursed_item.slot_equipment_priority) //if it can equip somewhere, only go active when it is actually done
RegisterSignal(cursed_item, COMSIG_ITEM_EQUIPPED, .proc/on_equipped)
else
@@ -47,8 +47,9 @@
/datum/element/curse_announcement/proc/announce(obj/item/cursed_item, mob/cursed)
//this is from rpgloot, remove the quality suffix to format the name correctly
var/quality_suffix_text
if(fantasy_component)
quality_suffix_text = " [fantasy_component.quality]"
var/datum/component/fantasy/perchance_to_dream = fantasy_component.resolve()
if(perchance_to_dream)
quality_suffix_text = " [perchance_to_dream.quality]"
cursed_item.name = replacetext(cursed_item.name, quality_suffix_text,"")
//modifications to the item so it looks cursed
+2 -1
View File
@@ -30,7 +30,8 @@
UnregisterSignal(source, COMSIG_MOUSEDROP_ONTO)
if (!isnull(strip_menus))
QDEL_NULL(strip_menus[source])
qdel(strip_menus[source])
strip_menus -= source
/datum/element/strippable/proc/mouse_drop_onto(datum/source, atom/over, mob/user)
SIGNAL_HANDLER
+1
View File
@@ -99,6 +99,7 @@ GLOBAL_LIST_INIT(huds, list(
/datum/atom_hud/proc/unregister_mob(datum/source, force)
SIGNAL_HANDLER
remove_hud_from(source, TRUE)
remove_from_hud(source)
/datum/atom_hud/proc/hide_single_atomhud_from(hud_user,hidden_atom)
if(hudusers[hud_user])
+24 -7
View File
@@ -69,8 +69,8 @@
var/list/skills_rewarded
///Assoc list of skills. Use SKILL_LVL to access level, and SKILL_EXP to access skill's exp.
var/list/known_skills = list()
///What character we joined in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not
var/mob/original_character
///Weakref to thecharacter we joined in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not
var/datum/weakref/original_character
/// The index for what character slot, if any, we were loaded from, so we can track persistent scars on a per-character basis. Each character slot gets PERSISTENT_SCAR_SLOTS scar slots
var/original_character_slot_index
/// The index for our current scar slot, so we don't have to constantly check the savefile (unlike the slots themselves, this index is independent of selected char slot, and increments whenever a valid char is joined with)
@@ -98,16 +98,29 @@
SSticker.minds -= src
QDEL_LIST(antag_datums)
QDEL_NULL(language_holder)
current = null
set_current(null)
return ..()
/datum/mind/proc/set_current(mob/new_current)
if(new_current && QDELETED(new_current))
CRASH("Tried to set a mind's current var to a qdeleted mob, what the fuck")
if(current)
UnregisterSignal(src, COMSIG_PARENT_QDELETING)
current = new_current
if(current)
RegisterSignal(src, COMSIG_PARENT_QDELETING, .proc/clear_current)
/datum/mind/proc/clear_current(datum/source)
SIGNAL_HANDLER
set_current(null)
/datum/mind/proc/get_language_holder()
if(!language_holder)
language_holder = new (src)
return language_holder
/datum/mind/proc/transfer_to(mob/new_character, force_key_move = 0)
original_character = null
set_original_character(null)
if(current) // remove ourself from our old body's mind variable
current.mind = null
UnregisterSignal(current, COMSIG_LIVING_DEATH)
@@ -120,7 +133,7 @@
key = new_character.key
if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null
new_character.mind.set_current(null)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
var/mob/living/old_current = current
@@ -131,7 +144,7 @@
remove_verb(current, /mob/proc/view_ambitions)
add_verb(new_character, /mob/proc/view_ambitions)
//SKYRAT CHANGE ADDITION END
current = new_character //associate ourself with our new body
set_current(new_character) //associate ourself with our new body
new_character.mind = src //and associate our new body with ourself
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
var/datum/antagonist/A = a
@@ -150,6 +163,10 @@
new_character.client.init_verbs() // re-initialize character specific verbs
current.update_atom_languages()
//I cannot trust you fucks to do this properly
/datum/mind/proc/set_original_character(new_original_character)
original_character = WEAKREF(new_original_character)
/datum/mind/proc/init_known_skills()
for (var/type in GLOB.skill_types)
known_skills[type] = list(SKILL_LEVEL_NONE, 0)
@@ -831,7 +848,7 @@
SSticker.minds += mind
if(!mind.name)
mind.name = real_name
mind.current = src
mind.set_current(src)
/mob/living/carbon/mind_initialize()
..()
@@ -160,8 +160,9 @@
if(istype(thrown_movable, /obj/item))
var/mob/living/honorbound = source
var/obj/item/thrown_item = thrown_movable
if(thrown_item.throwforce < honorbound.health && ishuman(thrown_item.thrownby))
guilty(thrown_item.thrownby)
var/mob/thrown_by = thrown_item.thrownby?.resolve()
if(thrown_item.throwforce < honorbound.health && ishuman(thrown_by))
guilty(thrown_by)
//spell checking
/datum/mutation/human/honorbound/proc/spell_check(mob/user, obj/effect/proc_holder/spell/spell_cast)
+19 -8
View File
@@ -125,8 +125,7 @@
qdel(src)
return
victim = L.owner
RegisterSignal(victim, COMSIG_PARENT_QDELETING, .proc/null_victim)
set_victim(L.owner)
set_limb(L)
LAZYADD(victim.all_wounds, src)
LAZYADD(limb.wounds, src)
@@ -162,7 +161,15 @@
/datum/wound/proc/null_victim()
SIGNAL_HANDLER
victim = null
set_victim(null)
/datum/wound/proc/set_victim(new_victim)
if(victim)
UnregisterSignal(victim, COMSIG_PARENT_QDELETING)
remove_wound_from_victim()
victim = new_victim
if(victim)
RegisterSignal(victim, COMSIG_PARENT_QDELETING, .proc/null_victim)
/datum/wound/proc/source_died()
SIGNAL_HANDLER
@@ -176,15 +183,19 @@
already_scarred = TRUE
var/datum/scar/new_scar = new
new_scar.generate(limb, src)
if(victim)
LAZYREMOVE(victim.all_wounds, src)
if(!victim.all_wounds)
victim.clear_alert("wound")
SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb)
remove_wound_from_victim()
if(limb && !ignore_limb)
LAZYREMOVE(limb.wounds, src)
limb.update_wounds(replaced)
/datum/wound/proc/remove_wound_from_victim()
if(!victim)
return
LAZYREMOVE(victim.all_wounds, src)
if(!victim.all_wounds)
victim.clear_alert("wound")
SEND_SIGNAL(victim, COMSIG_CARBON_LOSE_WOUND, src, limb)
/**
* replace_wound() is used when you want to replace the current wound with a new wound, presumably of the same category, just of a different severity (either up or down counts)
*
+1 -1
View File
@@ -17,7 +17,7 @@
qdel(src)
return
victim = dismembered_part.owner
set_victim(dismembered_part.owner)
if(dismembered_part.body_zone == BODY_ZONE_CHEST)
occur_text = "is split open, causing [victim.p_their()] internals organs to spill out!"
+2 -1
View File
@@ -597,7 +597,8 @@
. = ..()
if(AM.area_sensitive_contents)
for(var/atom/movable/location as anything in get_nested_locs(src) + src)
LAZYADD(location.area_sensitive_contents, AM.area_sensitive_contents)
//We can't make the assumption that objects won't become area sensitive in the process of entering us
LAZYOR(location.area_sensitive_contents, AM.area_sensitive_contents)
/// See traits.dm. Use this in place of ADD_TRAIT.
/atom/movable/proc/become_area_sensitive(trait_source = TRAIT_GENERIC)
+5
View File
@@ -19,6 +19,11 @@ GLOBAL_LIST_EMPTY(objectives)
if(text)
explanation_text = text
//Apparently objectives can be qdel'd. Learn a new thing every day
/datum/objective/Destroy()
GLOB.objectives -= src
return ..()
/datum/objective/proc/get_owners() // Combine owner and team into a single list.
. = (team?.members) ? team.members.Copy() : list()
if(owner)
+4 -4
View File
@@ -49,9 +49,9 @@
track.namecounts[name] = 1
if(ishuman(L))
track.humans[name] = L
track.humans[name] = WEAKREF(L)
else
track.others[name] = L
track.others[name] = WEAKREF(L)
var/list/targets = sortList(track.humans) + sortList(track.others)
@@ -67,9 +67,9 @@
if(!track.initialized)
trackable_mobs()
var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name])
var/datum/weakref/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name])
ai_actual_track(target)
ai_actual_track(target.resolve())
/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target)
if(!istype(target))
+10 -9
View File
@@ -8,7 +8,6 @@
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/operating
var/mob/living/carbon/human/patient
var/obj/structure/table/optable/table
var/list/advanced_surgeries = list()
var/datum/techweb/linked_techweb
@@ -75,16 +74,18 @@
surgery["desc"] = initial(S.desc)
surgeries += list(surgery)
data["surgeries"] = surgeries
data["patient"] = null
if(table)
data["table"] = table
if(!table.check_eligible_patient())
return data
data["patient"] = list()
patient = table.patient
else
//If there's no patient just hop to it yeah?
if(!table)
data["patient"] = null
return data
data["table"] = table
if(!table.check_eligible_patient())
return data
data["patient"] = list()
var/mob/living/carbon/human/patient = table.patient
switch(patient.stat)
if(CONSCIOUS)
data["patient"]["stat"] = "Conscious"
+17 -8
View File
@@ -232,10 +232,7 @@
can_use_scanner = TRUE
else
can_use_scanner = FALSE
if(connected_scanner)
if(connected_scanner.linked_console == src)
connected_scanner.linked_console = null
connected_scanner = null
set_connected_scanner(null)
is_viable_occupant = FALSE
// Check for a viable occupant in the scanner.
@@ -1682,8 +1679,7 @@
test_scanner = locate(/obj/machinery/dna_scannernew, get_step(src, direction))
if(!isnull(test_scanner))
if(test_scanner.is_operational)
connected_scanner = test_scanner
connected_scanner.linked_console = src
set_connected_scanner(test_scanner)
return
else
broken_scanner = test_scanner
@@ -1691,8 +1687,7 @@
// Ultimately, if we have a broken scanner, we'll attempt to connect to it as
// a fallback case, but the code above will prefer a working scanner
if(!isnull(broken_scanner))
connected_scanner = broken_scanner
connected_scanner.linked_console = src
set_connected_scanner(broken_scanner)
/**
* Called by connected DNA Scanners when their doors close.
@@ -2156,6 +2151,20 @@
diskette.forceMove(drop_location())
diskette = null
/obj/machinery/computer/scan_consolenew/proc/set_connected_scanner(new_scanner)
if(connected_scanner)
UnregisterSignal(connected_scanner, COMSIG_PARENT_QDELETING)
if(connected_scanner.linked_console == src)
connected_scanner.set_linked_console(null)
connected_scanner = new_scanner
if(connected_scanner)
RegisterSignal(connected_scanner, COMSIG_PARENT_QDELETING, .proc/react_to_scanner_del)
connected_scanner.set_linked_console(src)
/obj/machinery/computer/scan_consolenew/proc/react_to_scanner_del(datum/source)
SIGNAL_HANDLER
set_connected_scanner(null)
#undef ENZYME_COPY_BASE_COOLDOWN
#undef INJECTOR_TIMEOUT
#undef NUMBER_OF_BUFFERS
+12
View File
@@ -147,6 +147,18 @@
return
close_machine(target)
//This is only called by the scanner. if you ever want to use this outside of that context you'll need to refactor things a bit
/obj/machinery/dna_scannernew/proc/set_linked_console(new_console)
if(linked_console)
UnregisterSignal(linked_console, COMSIG_PARENT_QDELETING)
linked_console = new_console
if(linked_console)
RegisterSignal(linked_console, COMSIG_PARENT_QDELETING, .proc/react_to_console_del)
/obj/machinery/dna_scannernew/proc/react_to_console_del(datum/source)
SIGNAL_HANDLER
set_linked_console(null)
//Just for transferring between genetics machines.
/obj/item/disk/data
+30 -24
View File
@@ -43,7 +43,8 @@
update_indicator()
/obj/machinery/launchpad/Destroy()
qdel(hud_list[DIAG_LAUNCHPAD_HUD])
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.remove_from_hud(src)
return ..()
/obj/machinery/launchpad/examine(mob/user)
@@ -255,9 +256,9 @@
/obj/machinery/launchpad/briefcase/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/launchpad_remote))
var/obj/item/launchpad_remote/L = I
if(L.pad == src) //do not attempt to link when already linked
if(L.pad == WEAKREF(src)) //do not attempt to link when already linked
return ..()
L.pad = src
L.pad = WEAKREF(src)
to_chat(user, "<span class='notice'>You link [src] to [L].</span>")
else
return ..()
@@ -294,9 +295,9 @@
/obj/item/storage/briefcase/launchpad/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/launchpad_remote))
var/obj/item/launchpad_remote/L = I
if(L.pad == src.pad) //do not attempt to link when already linked
if(L.pad == WEAKREF(src.pad)) //do not attempt to link when already linked
return ..()
L.pad = src.pad
L.pad = WEAKREF(src.pad)
to_chat(user, "<span class='notice'>You link [pad] to [L].</span>")
else
return ..()
@@ -308,11 +309,12 @@
icon_state = "folder"
w_class = WEIGHT_CLASS_SMALL
var/sending = TRUE
var/obj/machinery/launchpad/briefcase/pad
//A weakref to our linked pad
var/datum/weakref/pad
/obj/item/launchpad_remote/Initialize(mapload, pad) //remote spawns linked to the briefcase pad
. = ..()
src.pad = pad
src.pad = WEAKREF(pad)
/obj/item/launchpad_remote/attack_self(mob/user)
. = ..()
@@ -332,16 +334,17 @@
/obj/item/launchpad_remote/ui_data(mob/user)
var/list/data = list()
data["has_pad"] = pad ? TRUE : FALSE
if(pad)
data["pad_closed"] = pad.closed
if(!pad || pad.closed)
var/obj/machinery/launchpad/briefcase/our_pad = pad.resolve()
data["has_pad"] = our_pad ? TRUE : FALSE
if(our_pad)
data["pad_closed"] = our_pad.closed
if(!our_pad || our_pad.closed)
return data
data["pad_name"] = pad.display_name
data["range"] = pad.range
data["x"] = pad.x_offset
data["y"] = pad.y_offset
data["pad_name"] = our_pad.display_name
data["range"] = our_pad.range
data["x"] = our_pad.x_offset
data["y"] = our_pad.y_offset
return data
/obj/item/launchpad_remote/proc/teleport(mob/user, obj/machinery/launchpad/pad)
@@ -357,19 +360,22 @@
. = ..()
if(.)
return
var/obj/machinery/launchpad/briefcase/our_pad = pad.resolve()
if(!our_pad)
pad = null
return TRUE
switch(action)
if("set_pos")
var/new_x = text2num(params["x"])
var/new_y = text2num(params["y"])
pad.set_offset(new_x, new_y)
our_pad.set_offset(new_x, new_y)
. = TRUE
if("move_pos")
var/plus_x = text2num(params["x"])
var/plus_y = text2num(params["y"])
pad.set_offset(
x = pad.x_offset + plus_x,
y = pad.y_offset + plus_y
our_pad.set_offset(
x = our_pad.x_offset + plus_x,
y = our_pad.y_offset + plus_y
)
. = TRUE
if("rename")
@@ -377,16 +383,16 @@
var/new_name = params["name"]
if(!new_name)
return
pad.display_name = new_name
our_pad.display_name = new_name
if("remove")
. = TRUE
if(usr && tgui_alert(usr, "Are you sure?", "Unlink Launchpad", list("I'm Sure", "Abort")) != "Abort")
pad = null
our_pad = null
if("launch")
sending = TRUE
teleport(usr, pad)
teleport(usr, our_pad)
. = TRUE
if("pull")
sending = FALSE
teleport(usr, pad)
teleport(usr, our_pad)
. = TRUE
+1 -1
View File
@@ -62,7 +62,7 @@
/obj/effect/anomaly/Destroy()
STOP_PROCESSING(SSobj, src)
qdel(countdown)
QDEL_NULL(countdown)
if(aSignal)
QDEL_NULL(aSignal)
return ..()
+1 -1
View File
@@ -16,7 +16,7 @@
COOLDOWN_DECLARE(respawn_cooldown)
/obj/effect/powerup/Initialize()
..()
. = ..()
if(lifetime)
QDEL_IN(src, lifetime)
var/static/list/loc_connections = list(
+3 -4
View File
@@ -142,8 +142,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
///list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item
var/list/species_exception = null
///Who threw the item
var/mob/thrownby = null
///A weakref to the mob who threw the item
var/datum/weakref/thrownby = null //I cannot verbally describe how much I hate this var
///Items can by default thrown up to 10 tiles by TK users
tk_throw_range = 10
@@ -698,11 +698,10 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE, quickstart = TRUE)
if(HAS_TRAIT(src, TRAIT_NODROP))
return
thrownby = thrower
thrownby = WEAKREF(thrower)
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
. = ..(target, range, speed, thrower, spin, diagonals_first, callback, force, gentle, quickstart = quickstart)
/obj/item/proc/after_throw(datum/callback/callback)
if (callback) //call the original callback
. = callback.Invoke()
+4 -3
View File
@@ -133,14 +133,15 @@
w_class = 5
force = 15
ignores_timeout = TRUE //non roundstart!
var/timesup = FALSE
//A cooldown, once it's over you can't declare a new name anymore
COOLDOWN_DECLARE(cutoff)
/obj/item/station_charter/revolution/Initialize()
. = ..()
addtimer(VARSET_CALLBACK(src, timesup, TRUE), 5 MINUTES)
COOLDOWN_START(src, cutoff, 5 MINUTES)
/obj/item/station_charter/revolution/attack_self(mob/living/user)
if(timesup && !used)
if(COOLDOWN_FINISHED(src, cutoff) && !used)
to_chat(user, "<span class='warning'>You have lost the victorious fervor to declare a new name.</span>")
return
. = ..()
+7 -1
View File
@@ -134,6 +134,10 @@
if(istype(C))
gun = C.gun
/obj/projectile/energy/chrono_beam/Destroy()
gun = null
return ..()
/obj/projectile/energy/chrono_beam/on_hit(atom/target)
if(target && gun && isliving(target))
var/obj/structure/chrono_field/F = new(target.loc, target, gun)
@@ -152,7 +156,9 @@
gun = loc
. = ..()
/obj/item/ammo_casing/energy/chrono_beam/Destroy()
gun = null
return ..()
@@ -16,6 +16,10 @@
var/valve_open = FALSE
var/toggle = TRUE
/obj/item/transfer_valve/Destroy()
attached_device = null
return ..()
/obj/item/transfer_valve/IsAssemblyHolder()
return TRUE
+4 -2
View File
@@ -184,8 +184,10 @@
diceroll(user)
/obj/item/dice/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
diceroll(thrownby)
. = ..()
var/mob/thrown_by = thrownby?.resolve()
if(thrown_by)
diceroll(thrown_by)
return ..()
/obj/item/dice/proc/diceroll(mob/user)
result = roll(sides)
@@ -2,8 +2,12 @@
name = "tracking implant"
desc = "Track with this."
activated = FALSE
var/lifespan_postmortem = 6000 //for how many deciseconds after user death will the implant work?
var/allow_teleport = TRUE //will people implanted with this act as teleporter beacons?
///for how many deciseconds after user death will the implant work?
var/lifespan_postmortem = 6000
///will people implanted with this act as teleporter beacons?
var/allow_teleport = TRUE
///The id of the timer that's qdeleting us
var/timerid
/obj/item/implant/tracking/c38
name = "TRAC implant"
@@ -13,7 +17,11 @@
/obj/item/implant/tracking/c38/Initialize()
. = ..()
QDEL_IN(src, lifespan)
timerid = QDEL_IN(src, lifespan)
/obj/item/implant/tracking/c38/Destroy()
deltimer(timerid)
return ..()
/obj/item/implant/tracking/New()
..()
+1 -1
View File
@@ -193,7 +193,7 @@
/// Subtype that's always junkmail
/obj/item/mail/junkmail/Initialize()
..()
. = ..()
junk_mail()
/// Crate for mail from CentCom.
+4
View File
@@ -231,6 +231,10 @@
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/item/melee/transforming/energy/blade/Destroy()
QDEL_NULL(spark_system)
return ..()
/obj/item/melee/transforming/energy/blade/transform_weapon(mob/living/user, supress_message_text)
return
+1 -1
View File
@@ -334,7 +334,7 @@
if(!iscarbon(user))
target.LAssailant = null
else
target.LAssailant = user
target.LAssailant = WEAKREF(user)
cooldown_check = world.time + cooldown
return
+3 -2
View File
@@ -348,8 +348,9 @@
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
if(isliving(hit_atom) && !iscyborg(hit_atom) && !caught && prob(throw_stun_chance))//if they are a living creature and they didn't catch it
baton_effect(hit_atom)
if(thrownby && !caught)
addtimer(CALLBACK(src, /atom/movable.proc/throw_at, thrownby, throw_range+2, throw_speed, null, TRUE), 1)
var/mob/thrown_by = thrownby?.resolve()
if(thrown_by && !caught)
addtimer(CALLBACK(src, /atom/movable.proc/throw_at, thrown_by, throw_range+2, throw_speed, null, TRUE), 1)
else
return ..()
+2 -1
View File
@@ -89,7 +89,8 @@
say(slogan)
COOLDOWN_START(src, next_slogan_tick, COOLDOWN_SLOGAN)
/obj/machinery/pinpointer_dispenser/Destroy()
//Do this when someone breaks you/blows you up. The bombs are funny
/obj/machinery/pinpointer_dispenser/deconstruct()
for(var/i in 1 to rand(3, 9)) //Doesn't synthesise them in real time and instead stockpiles completed ones (though this is not how the cooldown works)
new /obj/item/pinpointer/wayfinding (loc)
say("Ouch.")
@@ -399,8 +399,6 @@
var/sale_price = 20
///The Account which will receive payment for purchases. Set by the first ID to swipe the tray.
var/datum/bank_account/payments_acc = null
///We're using the same trick as paper does in order to cache the image, and only load the UI when messed with.
var/list/viewing_ui = list()
/obj/structure/displaycase/forsale/update_icon_state()
icon_state = "[initial(icon_state)][broken ? "_broken" : (open ? "_open" : (!showpiece ? "_empty" : null))]"
@@ -416,7 +414,6 @@
if(!ui)
ui = new(user, src, "Vendatray", name)
ui.set_autoupdate(FALSE)
viewing_ui[user] = ui
ui.open()
/obj/structure/displaycase/forsale/ui_data(mob/user)
@@ -77,7 +77,7 @@
yolk.equipOutfit(/datum/outfit/ashwalker)//this is an authentic mess we're making
yolk.update_body()
yolk.gib()
qdel(egg)
QDEL_NULL(egg)
return ..()
@@ -101,6 +101,11 @@
var/datum/team/ashwalkers/team
var/obj/structure/ash_walker_eggshell/eggshell
/obj/effect/mob_spawn/human/ash_walker/Destroy()
eggshell = null
return ..()
/obj/effect/mob_spawn/human/ash_walker/allow_spawn(mob/user)
if(!(user.key in team.players_spawned))//one per person unless you get a bonus spawn
return TRUE
@@ -125,7 +130,7 @@
H.remove_language(/datum/language/common)
team.players_spawned += (new_spawn.key)
eggshell.egg = null
qdel(eggshell)
QDEL_NULL(eggshell)
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload, datum/team/ashwalkers/ashteam)
. = ..()
+13 -2
View File
@@ -597,10 +597,21 @@
var/mob/living/carbon/M = locate(/mob/living/carbon) in loc
if(M)
if(M.resting)
patient = M
set_patient(M)
else
patient = null
set_patient(null)
/obj/structure/table/optable/proc/set_patient(new_patient)
if(patient)
UnregisterSignal(patient, COMSIG_PARENT_QDELETING)
patient = new_patient
if(patient)
RegisterSignal(patient, COMSIG_PARENT_QDELETING, .proc/patient_deleted)
/obj/structure/table/optable/proc/patient_deleted(datum/source)
SIGNAL_HANDLER
set_patient(null)
/obj/structure/table/optable/proc/check_eligible_patient()
get_patient()
if(!patient)
+9 -1
View File
@@ -114,6 +114,12 @@
time_between_triggers = 10
flare_message = "<span class='warning'>[src] snaps shut!</span>"
/obj/structure/trap/stun/hunter/Destroy()
if(!QDELETED(stored_item))
qdel(stored_item)
stored_item = null
return ..()
/obj/structure/trap/stun/hunter/on_entered(datum/source, atom/movable/AM)
if(isliving(AM))
var/mob/living/L = AM
@@ -167,7 +173,9 @@
forceMove(stored_trap)//moves item into trap
/obj/item/bountytrap/Destroy()
qdel(stored_trap)
if(!QDELETED(stored_trap))
qdel(stored_trap)
stored_trap = null
QDEL_NULL(radio)
QDEL_NULL(spark_system)
. = ..()
@@ -1,18 +1,10 @@
#ifdef REFERENCE_TRACKING
/datum/verb/find_refs()
set category = "Debug"
set name = "Find References"
set src in world
find_references(FALSE)
/datum/proc/find_references(skip_alert)
running_find_references = type
if(usr?.client)
if(usr.client.running_find_references)
testing("CANCELLED search for references to a [usr.client.running_find_references].")
log_reftracker("CANCELLED search for references to a [usr.client.running_find_references].")
usr.client.running_find_references = null
running_find_references = null
//restart the garbage collector
@@ -30,21 +22,29 @@
if(usr?.client)
usr.client.running_find_references = type
testing("Beginning search for references to a [type].")
log_reftracker("Beginning search for references to a [type].")
var/starting_time = world.time
//Time to search the whole game for our ref
DoSearchVar(GLOB, "GLOB") //globals
log_reftracker("Finished searching globals")
for(var/datum/thing in world) //atoms (don't beleive its lies)
DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time)
log_reftracker("Finished searching atoms")
for(var/datum/thing) //datums
DoSearchVar(thing, "Datums -> [thing.type]", search_time = starting_time)
log_reftracker("Finished searching datums")
//Warning, attempting to search clients like this will cause crashes if done on live. Watch yourself
for(var/client/thing) //clients
DoSearchVar(thing, "Clients -> [thing.type]", search_time = starting_time)
log_reftracker("Finished searching clients")
log_reftracker("Completed search for references to a [type].")
testing("Completed search for references to a [type].")
if(usr?.client)
usr.client.running_find_references = null
running_find_references = null
@@ -53,25 +53,6 @@
SSgarbage.can_fire = TRUE
SSgarbage.next_fire = world.time + world.tick_lag
/datum/verb/qdel_then_find_references()
set category = "Debug"
set name = "qdel() then Find References"
set src in world
qdel(src, TRUE) //force a qdel
if(!running_find_references)
find_references(TRUE)
/datum/verb/qdel_then_if_fail_find_references()
set category = "Debug"
set name = "qdel() then Find References if GC failure"
set src in world
qdel_and_find_ref_if_fail(src, TRUE)
/datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64, search_time = world.time)
#ifdef REFERENCE_TRACKING_DEBUG
if(!found_refs)
@@ -82,9 +63,14 @@
return
if(!recursive_limit)
testing("Recursion limit reached. [container_name]")
log_reftracker("Recursion limit reached. [container_name]")
return
//Check each time you go down a layer. This makes it a bit slow, but it won't effect the rest of the game at all
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
if(istype(potential_container, /datum))
var/datum/datum_container = potential_container
if(datum_container.last_find_references == search_time)
@@ -94,6 +80,9 @@
var/list/vars_list = datum_container.vars
for(var/varname in vars_list)
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
if (varname == "vars" || varname == "vis_locs") //Fun fact, vis_locs don't count for references
continue
var/variable = vars_list[varname]
@@ -102,41 +91,44 @@
#ifdef REFERENCE_TRACKING_DEBUG
found_refs[varname] = TRUE
#endif
testing("Found [type] \ref[src] in [datum_container.type]'s \ref[datum_container] [varname] var. [container_name]")
log_reftracker("Found [type] \ref[src] in [datum_container.type]'s \ref[datum_container] [varname] var. [container_name]")
continue
else if(islist(variable))
if(islist(variable))
DoSearchVar(variable, "[container_name] \ref[datum_container] -> [varname] (list)", recursive_limit - 1, search_time)
else if(islist(potential_container))
var/normal = IS_NORMAL_LIST(potential_container)
for(var/element_in_list in potential_container)
var/list/potential_cache = potential_container
for(var/element_in_list in potential_cache)
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
//Check normal entrys
if(element_in_list == src)
#ifdef REFERENCE_TRACKING_DEBUG
found_refs[potential_container] = TRUE
found_refs[potential_cache] = TRUE
#endif
testing("Found [type] \ref[src] in list [container_name].")
log_reftracker("Found [type] \ref[src] in list [container_name].")
continue
var/assoc_val = null
if(!isnum(element_in_list) && normal)
assoc_val = potential_cache[element_in_list]
//Check assoc entrys
else if(!isnum(element_in_list) && normal && potential_container[element_in_list] == src)
if(assoc_val == src)
#ifdef REFERENCE_TRACKING_DEBUG
found_refs[potential_container] = TRUE
found_refs[potential_cache] = TRUE
#endif
testing("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]")
log_reftracker("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]")
continue
//We need to run both of these checks, since our object could be hiding in either of them
else
//Check normal sublists
if(islist(element_in_list))
DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", recursive_limit - 1, search_time)
//Check assoc sublists
if(!isnum(element_in_list) && normal && islist(potential_container[element_in_list]))
DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [potential_container[element_in_list]] (list)", recursive_limit - 1, search_time)
#ifndef FIND_REF_NO_CHECK_TICK
CHECK_TICK
#endif
//Check normal sublists
if(islist(element_in_list))
DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", recursive_limit - 1, search_time)
//Check assoc sublists
if(islist(assoc_val))
DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [assoc_val] (list)", recursive_limit - 1, search_time)
/proc/qdel_and_find_ref_if_fail(datum/thing_to_del, force = FALSE)
thing_to_del.qdel_and_find_ref_if_fail(force)
@@ -22,5 +22,5 @@
owner.vomit(20)
var/mob/living/simple_animal/slime/Slime = new(get_turf(owner), "grey")
Slime.Friends = list(owner)
Slime.Leader = owner
Slime.set_friends(list(owner))
Slime.set_leader(owner)
@@ -70,6 +70,10 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
stack_trace("blobstrain created without overmind")
overmind = new_overmind
/datum/blobstrain/Destroy()
overmind = null
return ..()
/datum/blobstrain/proc/on_gain()
overmind.color = complementary_color
@@ -181,6 +181,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
SSticker.force_ending = 1
/mob/camera/blob/Destroy()
QDEL_NULL(blobstrain)
for(var/BL in GLOB.blobs)
var/obj/structure/blob/B = BL
if(B && B.overmind == src)
@@ -168,8 +168,9 @@
if(iscarbon(hit_atom) && !caught)//if they are a carbon and they didn't catch it
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(src, hit_atom)
if(thrownby && !caught)
addtimer(CALLBACK(src, /atom/movable.proc/throw_at, thrownby, throw_range+2, throw_speed, null, TRUE), 1)
var/mob/thrown_by = thrownby?.resolve()
if(thrown_by && !caught)
addtimer(CALLBACK(src, /atom/movable.proc/throw_at, thrown_by, throw_range+2, throw_speed, null, TRUE), 1)
else
return ..()
+5 -1
View File
@@ -149,6 +149,10 @@
AddComponent(/datum/component/butchering, 50, 80)
AddComponent(/datum/component/two_handed, require_twohands=TRUE)
/obj/item/cult_bastard/Destroy()
QDEL_NULL(jaunt)
QDEL_NULL(linked_action)
return ..()
/obj/item/cult_bastard/examine(mob/user)
. = ..()
@@ -234,7 +238,7 @@
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
/datum/action/innate/dash/cult/IsAvailable()
if(IS_CULTIST(holder) && current_charges)
if(IS_CULTIST(owner) && current_charges)
return TRUE
else
return FALSE
@@ -12,6 +12,7 @@
/datum/disease/advance/sentient_disease/Destroy()
. = ..()
overmind = null
GLOB.sentient_disease_instances -= src
/datum/disease/advance/sentient_disease/remove_disease()
@@ -76,10 +76,12 @@ the new instance inside the host to be updated to the template's stats.
/mob/camera/disease/Destroy()
. = ..()
QDEL_NULL(adaptation_menu_action)
disease_template = null
for(var/V in GLOB.sentient_disease_instances)
var/datum/disease/advance/sentient_disease/S = V
if(S.overmind == src)
S.overmind = null
browser = null
/mob/camera/disease/Login()
. = ..()
@@ -99,7 +99,7 @@
UnregisterSignal(victim, COMSIG_MOB_STATCHANGE)
/mob/living/simple_animal/hostile/imp/slaughter/Initialize(mapload, obj/effect/dummy/phased_mob/bloodpool)//Bloodpool is the blood pool we spawn in
..()
. = ..()
ADD_TRAIT(src, TRAIT_BLOODCRAWL_EAT, "innate")
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
+4
View File
@@ -32,6 +32,10 @@
var/datum/wires/connected = null
var/next_activate = 0 //When we're next allowed to activate - for spam control
/obj/item/assembly/Destroy()
holder = null
return ..()
/obj/item/assembly/get_part_rating()
return 1
+9 -6
View File
@@ -342,19 +342,22 @@
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocols fix the flashbulb if it ever burns out."
var/flashcd = 20
var/overheat = 0
var/obj/item/organ/cyberimp/arm/flash/I = null
//Wearef to our arm
var/datum/weakref/arm
/obj/item/assembly/flash/armimplant/burn_out()
if(I?.owner)
to_chat(I.owner, "<span class='warning'>Your photon projector implant overheats and deactivates!</span>")
I.Retract()
var/obj/item/organ/cyberimp/arm/flash/real_arm = arm.resolve()
if(real_arm?.owner)
to_chat(real_arm.owner, "<span class='warning'>Your photon projector implant overheats and deactivates!</span>")
real_arm.Retract()
overheat = TRUE
addtimer(CALLBACK(src, .proc/cooldown), flashcd * 2)
/obj/item/assembly/flash/armimplant/try_use_flash(mob/user = null)
if(overheat)
if(I?.owner)
to_chat(I.owner, "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>")
var/obj/item/organ/cyberimp/arm/flash/real_arm = arm.resolve()
if(real_arm?.owner)
to_chat(real_arm.owner, "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>")
return FALSE
overheat = TRUE
addtimer(CALLBACK(src, .proc/cooldown), flashcd)
@@ -25,11 +25,10 @@
SSair.start_processing_machine(src)
/obj/machinery/portable_atmospherics/Destroy()
SSair.stop_processing_machine(src)
disconnect()
QDEL_NULL(air_contents)
SSair.stop_processing_machine(src)
return ..()
/obj/machinery/portable_atmospherics/ex_act(severity, target)
+6
View File
@@ -181,6 +181,12 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
vis_contents += portal_visuals
return ..()
/obj/machinery/gateway/Destroy()
destination.target_gateway = null
GLOB.gateway_destinations -= destination
destination = null
return ..()
/obj/machinery/gateway/proc/generate_destination()
destination = new destination_type
destination.name = destination_name
@@ -44,7 +44,7 @@
var/active = 1
/obj/structure/firepit/Initialize()
..()
. = ..()
toggleFirepit()
/obj/structure/firepit/interact(mob/living/user)
@@ -40,6 +40,7 @@
. = ..()
if(!reset)
reset = new reset_path(get_turf(src))
reset.flag = src
RegisterSignal(src, COMSIG_PARENT_PREQDELETED, .proc/reset_flag) //just in case CTF has some map hazards (read: chasms).
/obj/item/ctf/ComponentInitialize()
@@ -55,7 +56,10 @@
/obj/item/ctf/proc/reset_flag(capture = FALSE)
SIGNAL_HANDLER
forceMove(get_turf(src.reset))
var/turf/our_turf = get_turf(src.reset)
if(!our_turf)
return TRUE
forceMove(our_turf)
for(var/mob/M in GLOB.player_list)
var/area/mob_area = get_area(M)
if(istype(mob_area, game_area))
@@ -143,6 +147,13 @@
icon_state = "banner"
desc = "This is where a banner with Nanotrasen's logo on it would go."
layer = LOW_ITEM_LAYER
var/obj/item/ctf/flag
/obj/effect/ctf/flag_reset/Destroy()
if(flag)
flag.reset = null
flag = null
return ..()
/obj/effect/ctf/flag_reset/red
name = "red flag landmark"
@@ -806,6 +817,13 @@
continue
CTF.dead_barricades += src
/obj/effect/ctf/dead_barricade/Destroy()
for(var/obj/machinery/capture_the_flag/CTF in GLOB.machines)
if(CTF.game_id != game_id)
continue
CTF.dead_barricades -= src
return ..()
/obj/effect/ctf/dead_barricade/proc/respawn()
if(!QDELETED(src))
new /obj/structure/barricade/security/ctf(get_turf(src))
+4 -2
View File
@@ -466,16 +466,18 @@
return
glow_effect.layer = LOW_ITEM_LAYER
glow_effect.fadeAway(delays[POD_OPENING])
remove_glow()
//Trust the signals
/obj/structure/closet/supplypod/proc/remove_glow()
SIGNAL_HANDLER
UnregisterSignal(glow_effect, COMSIG_PARENT_QDELETING)
vis_contents -= glow_effect
glow_effect = null
/obj/structure/closet/supplypod/Destroy()
deleteRubble()
endGlow()
//Trust the signals even harder
qdel(glow_effect)
open_pod(src, broken = TRUE) //Lets dump our contents by opening up
return ..()
+2 -2
View File
@@ -3,9 +3,9 @@
/mob/proc/set_suicide(suicide_state)
suiciding = suicide_state
if(suicide_state)
GLOB.suicided_mob_list += src
add_to_mob_suicide_list()
else
GLOB.suicided_mob_list -= src
remove_from_mob_suicide_list()
/mob/living/carbon/set_suicide(suicide_state) //you thought that box trick was pretty clever, didn't you? well now hardmode is on, boyo.
. = ..()
+1 -1
View File
@@ -181,7 +181,7 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.get_item_by_slot(ITEM_SLOT_HEAD) == src)
if(H.get_item_by_slot(ITEM_SLOT_HEAD) == src && !QDELETED(src)) //This can be called as a part of destroy
user.remove_language(/datum/language/piratespeak/, TRUE, TRUE, LANGUAGE_HAT)
to_chat(user, "<span class='boldnotice'>You can no longer speak like a pirate.</span>")
+1 -1
View File
@@ -52,7 +52,7 @@
/obj/item/clothing/mask/gas/welding/up
/obj/item/clothing/mask/gas/welding/up/Initialize()
..()
. = ..()
visor_toggling()
// ********************************************************************
@@ -66,6 +66,7 @@
/obj/item/clothing/suit/space/chronos/Destroy()
dropped()
QDEL_NULL(teleport_now)
return ..()
/obj/item/clothing/suit/space/chronos/emp_act(severity)
@@ -331,6 +332,10 @@
check_flags = AB_CHECK_CONSCIOUS //|AB_CHECK_INSIDE
var/obj/item/clothing/suit/space/chronos/chronosuit = null
/datum/action/innate/chrono_teleport/Destroy()
chronosuit = null
return ..()
/datum/action/innate/chrono_teleport/IsAvailable()
return (chronosuit && chronosuit.activated && chronosuit.camera && !chronosuit.teleporting)
+4 -5
View File
@@ -33,6 +33,9 @@
/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
. = ..()
if(!QDELETED(suit))
qdel(suit)
suit = null
QDEL_NULL(soundloop)
STOP_PROCESSING(SSobj, src)
@@ -115,7 +118,6 @@
var/list/hardsuit_tail_colors //SKYRAT EDIT ADDITION - CUSTOMIZATION
/obj/item/clothing/suit/space/hardsuit/Initialize()
if(jetpack && ispath(jetpack))
jetpack = new jetpack(src)
@@ -890,10 +892,7 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
slowdown = 0
shield_icon = "shield-red"
/obj/item/clothing/suit/space/hardsuit/shielded/syndi/Initialize()
jetpack = new /obj/item/tank/jetpack/suit(src)
. = ..()
jetpack = /obj/item/tank/jetpack/suit
/obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
name = "blood-red hardsuit helmet"
+3 -2
View File
@@ -146,10 +146,11 @@
. = ..()
/obj/item/clothing/suit/space/hardsuit/Destroy()
if(helmet)
if(!QDELETED(helmet))
helmet.suit = null
qdel(helmet)
qdel(jetpack)
helmet = null
QDEL_NULL(jetpack)
return ..()
/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
+16 -1
View File
@@ -15,6 +15,10 @@
/// What equipment slot the accessory attaches to.
var/attachment_slot = CHEST
/obj/item/clothing/accessory/Destroy()
set_detached_pockets(null)
return ..()
/obj/item/clothing/accessory/proc/can_attach_accessory(obj/item/clothing/U, mob/user)
if(!attachment_slot || (U && U.body_parts_covered & attachment_slot))
return TRUE
@@ -27,7 +31,7 @@
if(SEND_SIGNAL(U, COMSIG_CONTAINS_STORAGE))
return FALSE
U.TakeComponent(storage)
detached_pockets = storage
set_detached_pockets(storage)
U.attached_accessory = src
forceMove(U)
layer = FLOAT_LAYER
@@ -70,6 +74,17 @@
U.attached_accessory = null
U.accessory_overlay = null
/obj/item/clothing/accessory/proc/set_detached_pockets(new_pocket)
if(detached_pockets)
UnregisterSignal(detached_pockets, COMSIG_PARENT_QDELETING)
detached_pockets = new_pocket
if(detached_pockets)
RegisterSignal(detached_pockets, COMSIG_PARENT_QDELETING, .proc/handle_pockets_del)
/obj/item/clothing/accessory/proc/handle_pockets_del(datum/source)
SIGNAL_HANDLER
set_detached_pockets(null)
/obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user)
return
+2 -1
View File
@@ -83,7 +83,8 @@
if(!(resistance_flags & ON_FIRE) && !force)
return QDEL_HINT_LETMELIVE
SSticker.round_end_events -= roundend_callback
LAZYREMOVE(SSticker.round_end_events, roundend_callback)
roundend_callback = null //This ought to free the callback datum, and prevent us from harddeling
for(var/i in GLOB.player_list)
var/mob/M = i
var/message = "<span class='warning'>A dark temptation has passed from this world"
@@ -15,7 +15,7 @@
Destructive scans can only be performed with the experimental destructive scanner."
/// The typepaths and number of atoms that must be scanned
var/list/required_atoms = list()
/// The list of atoms with sub-lists of atom references for scanned atoms contributing to the experiment
/// The list of atoms with sub-lists of atom references for scanned atoms contributing to the experiment (Or a count of atoms destoryed for destructive expiriments)
var/list/scanned = list()
/**
@@ -79,7 +79,7 @@
/datum/experiment/scanning/perform_experiment_actions(datum/component/experiment_handler/experiment_handler, atom/target)
var/contributing_index_value = get_contributing_index(target)
if (contributing_index_value)
scanned[contributing_index_value] += traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? 1 : target
scanned[contributing_index_value] += traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? 1 : WEAKREF(target)
if(traits & EXPERIMENT_TRAIT_DESTRUCTIVE && !isliving(target))//only qdel things when destructive scanning and they're not living (living things get gibbed)
qdel(target)
do_after_experiment(target, contributing_index_value)
@@ -107,7 +107,7 @@
var/list/seen = scanned[req_atom]
if (destructive && (req_atom in scanned) && scanned[req_atom] < required_atoms[req_atom])
selected = req_atom
else if (!destructive && seen.len < required_atoms[req_atom] && !(target in seen))
else if (!destructive && seen.len < required_atoms[req_atom] && !(WEAKREF(target) in seen))
selected = req_atom
// Run any additonal checks if necessary
@@ -34,7 +34,7 @@
var/selected
if (destructive && (req_atom in scanned))
selected = req_atom
else if (!destructive && !(target in scanned[req_atom]))
else if (!destructive && !(WEAKREF(target) in scanned[req_atom]))
selected = req_atom
// Run any additonal checks if necessary
+1 -1
View File
@@ -36,7 +36,7 @@
INVOKE_ASYNC(src, .proc/timestop)
/obj/effect/timestop/Destroy()
qdel(chronofield)
QDEL_NULL(chronofield)
playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, frequency = -1) //reverse!
return ..()
+1 -1
View File
@@ -1212,7 +1212,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
var/mob/living/carbon/human/human_mob = target
LAZYNULL(human_mob.hal_screwydoll)
human_mob.update_health_hud()
..()
return ..()
/datum/hallucination/items/New(mob/living/carbon/C, forced = TRUE)
@@ -14,7 +14,7 @@
var/obj/machinery/smartfridge/food/cart_smartfridge
var/obj/structure/table/reinforced/cart_table
var/obj/effect/food_cart_stand/cart_tent
var/static/list/packed_things
var/list/packed_things
/obj/machinery/food_cart/Initialize()
. = ..()
@@ -26,6 +26,7 @@
RegisterSignal(cart_griddle, COMSIG_PARENT_QDELETING, .proc/lost_part)
RegisterSignal(cart_smartfridge, COMSIG_PARENT_QDELETING, .proc/lost_part)
RegisterSignal(cart_table, COMSIG_PARENT_QDELETING, .proc/lost_part)
RegisterSignal(cart_tent, COMSIG_PARENT_QDELETING, .proc/lost_part)
/obj/machinery/food_cart/Destroy()
if(cart_griddle)
@@ -34,7 +35,9 @@
QDEL_NULL(cart_smartfridge)
if(cart_table)
QDEL_NULL(cart_table)
QDEL_NULL(cart_tent)
if(cart_tent)
QDEL_NULL(cart_tent)
packed_things.Cut()
return ..()
/obj/machinery/food_cart/examine(mob/user)
@@ -113,7 +116,7 @@
UnregisterSignal(cart_griddle, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
UnregisterSignal(cart_smartfridge, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
UnregisterSignal(cart_table, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
UnregisterSignal(cart_tent, COMSIG_MOVABLE_MOVED)
UnregisterSignal(cart_tent, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
obj_break()
/obj/machinery/food_cart/obj_break(damage_flag)
@@ -126,6 +126,8 @@
/obj/machinery/restaurant_portal/Destroy()
. = ..()
turned_on_portal = null
linked_venue.restaurant_portal = null
linked_venue = null
/obj/machinery/restaurant_portal/update_overlays()
. = ..()
@@ -182,6 +184,7 @@
if(linked_venue.open)
linked_venue.close()
linked_venue.restaurant_portal.linked_venue = null
linked_venue.restaurant_portal = null
linked_venue = chosen_venue
linked_venue.restaurant_portal = src
+35 -25
View File
@@ -28,31 +28,36 @@
/obj/effect/holodeck_effect/cards
icon = 'icons/obj/toy.dmi'
icon_state = "deck_nanotrasen_full"
var/obj/item/toy/cards/deck/D
var/obj/item/toy/cards/deck/deck
/obj/effect/holodeck_effect/cards/activate(obj/machinery/computer/holodeck/HC)
D = new(loc)
deck = new(loc)
safety(!(HC.obj_flags & EMAGGED))
D.holo = HC
return D
deck.holo = HC
RegisterSignal(deck, COMSIG_PARENT_QDELETING, .proc/handle_card_delete)
return deck
/obj/effect/holodeck_effect/cards/proc/handle_card_delete(datum/source)
SIGNAL_HANDLER
deck = null
/obj/effect/holodeck_effect/cards/safety(active)
if(!D)
if(!deck)
return
if(active)
D.card_hitsound = null
D.card_force = 0
D.card_throwforce = 0
D.card_throw_speed = 3
D.card_throw_range = 7
D.card_attack_verb_continuous = string_list(list("attacks"))
deck.card_hitsound = null
deck.card_force = 0
deck.card_throwforce = 0
deck.card_throw_speed = 3
deck.card_throw_range = 7
deck.card_attack_verb_continuous = string_list(list("attacks"))
else
D.card_hitsound = 'sound/weapons/bladeslice.ogg'
D.card_force = 5
D.card_throwforce = 10
D.card_throw_speed = 3
D.card_throw_range = 7
D.card_attack_verb_continuous = string_list(list("attacks", "slices", "dices", "slashes", "cuts"))
deck.card_hitsound = 'sound/weapons/bladeslice.ogg'
deck.card_force = 5
deck.card_throwforce = 10
deck.card_throw_speed = 3
deck.card_throw_range = 7
deck.card_attack_verb_continuous = string_list(list("attacks", "slices", "dices", "slashes", "cuts"))
/obj/effect/holodeck_effect/sparks/activate(obj/machinery/computer/holodeck/HC)
@@ -76,24 +81,29 @@
/obj/effect/holodeck_effect/mobspawner
var/mobtype = /mob/living/simple_animal/hostile/carp/holocarp
var/mob/mob = null
var/mob/our_mob = null
/obj/effect/holodeck_effect/mobspawner/activate(obj/machinery/computer/holodeck/HC)
if(islist(mobtype))
mobtype = pick(mobtype)
mob = new mobtype(loc)
mob.flags_1 |= HOLOGRAM_1
our_mob = new mobtype(loc)
our_mob.flags_1 |= HOLOGRAM_1
// these vars are not really standardized but all would theoretically create stuff on death
for(var/v in list("butcher_results","corpse","weapon1","weapon2","blood_volume") & mob.vars)
mob.vars[v] = null
return mob
for(var/v in list("butcher_results","corpse","weapon1","weapon2","blood_volume") & our_mob.vars)
our_mob.vars[v] = null
RegisterSignal(our_mob, COMSIG_PARENT_QDELETING, .proc/handle_mob_delete)
return our_mob
/obj/effect/holodeck_effect/mobspawner/deactivate(obj/machinery/computer/holodeck/HC)
if(mob)
HC.derez(mob)
if(our_mob)
HC.derez(our_mob)
qdel(src)
/obj/effect/holodeck_effect/mobspawner/proc/handle_mob_delete(datum/source)
SIGNAL_HANDLER
our_mob = null
/obj/effect/holodeck_effect/mobspawner/pet
/obj/effect/holodeck_effect/mobspawner/pet/Initialize()
-2
View File
@@ -14,8 +14,6 @@
var/datum/plant_gene/stored_trait
///Determines the appearance of the graft. Rudimentary right now so it just picks randomly.
var/graft_appearance
///Seed that the graft was taken from, used for applying parent stats. Can be unexpectedly nulled by the parent plant getting deleted.
var/obj/item/seeds/parent_seed = null
/// The name of the plant this was taken from.
var/parent_name = ""
///The lifespan stat of the parent seed when the graft was taken.
-1
View File
@@ -611,7 +611,6 @@
*/
/obj/item/seeds/proc/create_graft()
var/obj/item/graft/snip = new(loc, graft_gene)
snip.parent_seed = src
snip.parent_name = plantname
snip.name += "([plantname])"
+4 -2
View File
@@ -53,8 +53,10 @@ Key procs
var/atom/owner
/// Initializes, and copies in the languages from the current atom if available.
///datum/language_holder/New(_owner) //ORIGINAL
/datum/language_holder/New(_owner, datum/preferences/pref_load) //SKYRAT EDIT CHANGE - CUSTOMIZATION
///datum/language_holder/New(atom/_owner) //ORIGINAL
/datum/language_holder/New(atom/_owner, datum/preferences/pref_load) //SKYRAT EDIT CHANGE - CUSTOMIZATION
if(_owner && QDELETED(_owner))
CRASH("Langauge holder added to a qdeleting thing, what the fuck \ref[_owner]")
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
if(pref_load)
//If we're loading a holder from prefs, override the languages
+2 -1
View File
@@ -61,7 +61,8 @@
source_atom = null
source_turf = null
pixel_turf = null
. = ..()
return ..()
// Yes this doesn't align correctly on anything other than 4 width tabs.
// If you want it to go switch everybody to elastic tab stops.
+12 -4
View File
@@ -17,9 +17,12 @@ GLOBAL_LIST(labor_sheet_values)
/obj/machinery/mineral/labor_claim_console/Initialize()
. = ..()
Radio = new/obj/item/radio(src)
Radio = new /obj/item/radio(src)
Radio.listening = FALSE
locate_stacking_machine()
//If we can't find a stacking machine end it all ok?
if(!stacking_machine)
return INITIALIZE_HINT_QDEL
if(!GLOB.labor_sheet_values)
var/sheet_list = list()
@@ -30,6 +33,13 @@ GLOBAL_LIST(labor_sheet_values)
sheet_list += list(list("ore" = initial(sheet.name), "value" = initial(sheet.point_value)))
GLOB.labor_sheet_values = sortList(sheet_list, /proc/cmp_sheet_list)
/obj/machinery/mineral/labor_claim_console/Destroy()
QDEL_NULL(Radio)
if(stacking_machine)
stacking_machine.console = null
stacking_machine = null
return ..()
/proc/cmp_sheet_list(list/a, list/b)
return a["value"] - b["value"]
@@ -115,9 +125,7 @@ GLOBAL_LIST(labor_sheet_values)
/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine()
stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
if(stacking_machine)
stacking_machine.CONSOLE = src
else
qdel(src)
stacking_machine.console = src
/obj/machinery/mineral/labor_claim_console/emag_act(mob/user)
if(!(obj_flags & EMAGGED))
@@ -345,6 +345,12 @@
var/obj/item/warp_cube/linked
var/teleporting = FALSE
/obj/item/warp_cube/Destroy()
if(!QDELETED(linked))
qdel(linked)
linked = null
return ..()
/obj/item/warp_cube/attack_self(mob/user)
var/turf/current_location = get_turf(user)
var/area/current_area = current_location.loc
@@ -1136,11 +1142,11 @@
club.update_appearance()
current_charges = clamp(current_charges + 1, 0, max_charges)
holder.update_action_buttons_icon()
owner.update_action_buttons_icon()
if(recharge_sound)
playsound(dashing_item, recharge_sound, 50, TRUE)
to_chat(holder, "<span class='notice'>[src] now has [current_charges]/[max_charges] charges.</span>")
to_chat(owner, "<span class='notice'>[src] now has [current_charges]/[max_charges] charges.</span>")
/obj/item/hierophant_club
name = "hierophant club"
@@ -1176,6 +1182,10 @@
. = ..()
blink = new(src)
/obj/item/hierophant_club/Destroy()
. = ..()
QDEL_NULL(blink)
/obj/item/hierophant_club/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
+13 -5
View File
@@ -16,7 +16,13 @@
. = ..()
machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
if (machine)
machine.CONSOLE = src
machine.console = src
/obj/machinery/mineral/stacking_unit_console/Destroy()
if(machine)
machine.console = null
machine = null
return ..()
/obj/machinery/mineral/stacking_unit_console/multitool_act(mob/living/user, obj/item/I)
if(!multitool_check_buffer(user, I))
@@ -78,7 +84,7 @@
circuit = /obj/item/circuitboard/machine/stacking_machine
input_dir = EAST
output_dir = WEST
var/obj/machinery/mineral/stacking_unit_console/CONSOLE
var/obj/machinery/mineral/stacking_unit_console/console
var/stk_types = list()
var/stk_amt = list()
var/stack_list[0] //Key: Type. Value: Instance of type.
@@ -92,7 +98,9 @@
materials = AddComponent(/datum/component/remote_materials, "stacking", mapload, FALSE, mapload && force_connect)
/obj/machinery/mineral/stacking_machine/Destroy()
CONSOLE = null
if(console)
console.machine = null
console = null
materials = null
return ..()
@@ -105,8 +113,8 @@
/obj/machinery/mineral/stacking_machine/multitool_act(mob/living/user, obj/item/multitool/M)
if(istype(M))
if(istype(M.buffer, /obj/machinery/mineral/stacking_unit_console))
CONSOLE = M.buffer
CONSOLE.machine = src
console = M.buffer
console.machine = src
to_chat(user, "<span class='notice'>You link [src] to the console in [M]'s buffer.</span>")
return TRUE
+2 -1
View File
@@ -7,8 +7,9 @@
if(!mind)
mind = new /datum/mind(key)
mind.active = TRUE
mind.current = src
mind.set_current(src)
my_client = client //SKYRAT EDIT ADDITION
. = ..()
if(!. || !client)
return FALSE
@@ -465,7 +465,7 @@
mind.active = FALSE //we wish to transfer the key manually
mind.original_character_slot_index = client.prefs.default_slot
mind.transfer_to(H) //won't transfer key since the mind is not active
mind.original_character = H
mind.set_original_character(H)
H.name = real_name
client.init_verbs()
-1
View File
@@ -223,7 +223,6 @@
if(blood_id == /datum/reagent/blood) //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
blood_data["viruses"] = list()
for(var/thing in diseases)
+2 -1
View File
@@ -31,9 +31,10 @@
if(stat!=DEAD) //If not dead.
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
if(mind) //You aren't allowed to return to brains that don't exist
mind.current = null
mind.set_current(null)
ghostize() //Ghostize checks for key so nothing else is necessary.
container = null
QDEL_NULL(stored_dna)
return ..()
+1 -1
View File
@@ -226,7 +226,7 @@
destroy_all_skillchips()
if(owner?.mind) //You aren't allowed to return to brains that don't exist
owner.mind.current = null
owner.mind.set_current(null)
return ..()
/obj/item/organ/brain/on_life(delta_time, times_fired)
@@ -44,6 +44,7 @@
/mob/living/carbon/human/Destroy()
QDEL_NULL(physiology)
QDEL_LIST(bioware)
GLOB.human_list -= src
return ..()
@@ -155,7 +155,7 @@
if(istype(AM, /obj/item))
I = AM
throwpower = I.throwforce
if(I.thrownby == src) //No throwing stuff at yourself to trigger hit reactions
if(I.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions
return ..()
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
hitpush = FALSE
@@ -500,7 +500,7 @@
var/obj/item/I
if(istype(AM, /obj/item))
I = AM
if(I.thrownby == H) //No throwing stuff at yourself to trigger the teleport
if(I.thrownby == WEAKREF(H)) //No throwing stuff at yourself to trigger the teleport
return 0
else
reactive_teleport(H)
@@ -653,7 +653,7 @@
var/obj/item/I
if(istype(AM, /obj/item))
I = AM
if(I.thrownby == H) //No throwing stuff at yourself to make bananas
if(I.thrownby == WEAKREF(H)) //No throwing stuff at yourself to make bananas
return 0
else
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))

Some files were not shown because too many files have changed in this diff Show More