[MIRROR] Dunking handle_atom_del() in the trash bin. [MDB IGNORE] (#23183)

* Dunking handle_atom_del() in the trash bin.

* Update _box_magazine.dm

* Modular paths

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-08-18 18:17:04 +02:00
committed by GitHub
parent da34f6839a
commit d21e06104f
70 changed files with 356 additions and 468 deletions

View File

@@ -67,8 +67,6 @@
#define COMSIG_ATOM_ABSTRACT_EXITED "atom_abstract_exited"
///from base of atom/Bumped(): (/atom/movable)
#define COMSIG_ATOM_BUMPED "atom_bumped"
///from base of atom/handle_atom_del(): (atom/deleted)
#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del"
///from base of atom/has_gravity(): (turf/location, list/forced_gravities)
#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity"
///from internal loop in atom/movable/proc/CanReach(): (list/next)

View File

@@ -1070,14 +1070,6 @@
/atom/proc/get_dumping_location()
return null
/**
* This proc is called when an atom in our contents has it's [Destroy][/atom/proc/Destroy] called
*
* Default behaviour is to simply send [COMSIG_ATOM_CONTENTS_DEL]
*/
/atom/proc/handle_atom_del(atom/deleting_atom)
SEND_SIGNAL(src, COMSIG_ATOM_CONTENTS_DEL, deleting_atom)
/**
* the vision impairment to give to the mob whose perspective is set to that atom
*

View File

@@ -201,7 +201,6 @@
if(((can_atmos_pass == ATMOS_PASS_DENSITY && density) || can_atmos_pass == ATMOS_PASS_NO) && isturf(loc))
can_atmos_pass = ATMOS_PASS_YES
air_update_turf(TRUE, FALSE)
loc.handle_atom_del(src)
if(opacity)
RemoveElement(/datum/element/light_blocking)

View File

@@ -93,11 +93,12 @@
if(stored_id_card)
SSexplosions.low_mov_atom += stored_id_card
/obj/machinery/pdapainter/handle_atom_del(atom/A)
if(A == stored_pda)
/obj/machinery/pdapainter/Exited(atom/movable/gone, direction)
. = ..()
if(gone == stored_pda)
stored_pda = null
update_appearance(UPDATE_ICON)
if(A == stored_id_card)
if(gone == stored_id_card)
stored_id_card = null
update_appearance(UPDATE_ICON)

View File

@@ -198,14 +198,7 @@
end_processing()
dump_inventory_contents()
if (!isnull(component_parts))
// Don't delete the stock part singletons
for (var/atom/atom_part in component_parts)
qdel(atom_part)
component_parts.Cut()
component_parts = null
QDEL_NULL(circuit)
clear_components()
unset_static_power()
return ..()
@@ -818,6 +811,7 @@
new datum_part.physical_object_type(loc)
else
var/obj/item/obj_part = part
component_parts -= part
obj_part.forceMove(loc)
if(istype(obj_part, /obj/item/circuitboard/machine))
var/obj/item/circuitboard/machine/board = obj_part
@@ -879,21 +873,33 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += occupant
/obj/machinery/handle_atom_del(atom/deleting_atom)
if(deleting_atom == occupant)
/obj/machinery/Exited(atom/movable/gone, direction)
. = ..()
if(gone == occupant)
set_occupant(null)
update_appearance()
updateUsrDialog()
return ..()
// The circuit should also be in component parts, so don't early return.
if(deleting_atom == circuit)
if(gone == circuit)
circuit = null
if((deleting_atom in component_parts) && !QDELETED(src))
component_parts.Remove(deleting_atom)
if((gone in component_parts) && !QDELETED(src))
component_parts -= gone
// It would be unusual for a component_part to be qdel'd ordinarily.
deconstruct(FALSE)
return ..()
/**
* This should be called before mass qdeling components to make space for replacements.
* If not done, things will go awry as Exited() destroys the machine when it detects
* even a single component exiting the atom.
*/
/obj/machinery/proc/clear_components()
if(!component_parts)
return
var/list/old_components = component_parts
circuit = null
component_parts = null
for(var/atom/atom_part in old_components)
qdel(atom_part)
/obj/machinery/proc/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/screwdriver)
if((flags_1 & NODECONSTRUCT_1) || screwdriver.tool_behaviour != TOOL_SCREWDRIVER)
@@ -1117,14 +1123,6 @@
power -= power * 0.0005
return ..()
/obj/machinery/Exited(atom/movable/gone, direction)
. = ..()
if(gone == occupant)
set_occupant(null)
if(gone == circuit)
LAZYREMOVE(component_parts, gone)
circuit = null
/obj/machinery/proc/adjust_item_drop_location(atom/movable/dropped_atom) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
var/md5 = md5(dropped_atom.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
for (var/i in 1 to 32)

View File

@@ -72,8 +72,9 @@
icon_state = "[xray_module ? "xray" : null][initial(icon_state)]"
return ..()
/obj/structure/camera_assembly/handle_atom_del(atom/A)
if(A == xray_module)
/obj/structure/camera_assembly/Exited(atom/movable/gone, direction)
. = ..()
if(gone == xray_module)
xray_module = null
update_appearance()
if(malf_xray_firmware_present)
@@ -82,7 +83,7 @@
var/obj/machinery/camera/contained_camera = loc
contained_camera.removeXRay(malf_xray_firmware_present) //make sure we don't remove MALF upgrades.
else if(A == emp_module)
else if(gone == emp_module)
emp_module = null
if(malf_emp_firmware_present)
malf_emp_firmware_active = malf_emp_firmware_present //re-enable firmware based upgrades after the part is removed.
@@ -90,14 +91,12 @@
var/obj/machinery/camera/contained_camera = loc
contained_camera.removeEmpProof(malf_emp_firmware_present) //make sure we don't remove MALF upgrades
else if(A == proxy_module)
else if(gone == proxy_module)
emp_module = null
if(istype(loc, /obj/machinery/camera))
var/obj/machinery/camera/contained_camera = loc
contained_camera.removeMotion()
return ..()
/obj/structure/camera_assembly/Destroy()
QDEL_NULL(xray_module)

View File

@@ -202,19 +202,7 @@
if(istype(new_machine, /obj/machinery/computer))
var/obj/machinery/computer/new_computer = new_machine
// Machines will init with a set of default components.
// Triggering handle_atom_del will make the machine realise it has lost a component_parts and then deconstruct.
// Move to nullspace so we don't trigger handle_atom_del, then qdel.
// Finally, replace new machine's parts with this frame's parts.
if(new_computer.circuit)
// Move to nullspace and delete.
new_computer.circuit.moveToNullspace()
QDEL_NULL(new_computer.circuit)
for(var/old_part in new_computer.component_parts)
var/atom/movable/movable_part = old_part
// Move to nullspace and delete.
movable_part.moveToNullspace()
qdel(movable_part)
new_machine.clear_components()
// Set anchor state and move the frame's parts over to the new machine.
// Then refresh parts and call on_construction().

View File

@@ -269,15 +269,7 @@
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
if(istype(new_machine))
// Machines will init with a set of default components. Move to nullspace so we don't trigger handle_atom_del, then qdel.
// Finally, replace with this frame's parts.
if(new_machine.circuit)
// Move to nullspace and delete.
new_machine.circuit.moveToNullspace()
QDEL_NULL(new_machine.circuit)
for(var/obj/old_part in new_machine.component_parts)
old_part.moveToNullspace()
qdel(old_part)
new_machine.clear_components()
// Set anchor state
new_machine.set_anchored(anchored)

View File

@@ -27,16 +27,17 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
/obj/machinery/defibrillator_mount/Destroy()
if(defib)
QDEL_NULL(defib)
. = ..()
/obj/machinery/defibrillator_mount/handle_atom_del(atom/A)
if(A == defib)
defib = null
end_processing()
QDEL_NULL(defib)
return ..()
/obj/machinery/defibrillator_mount/Exited(atom/movable/gone, direction)
. = ..()
if(gone == defib)
// Make sure processing ends before the defib is nulled
end_processing()
defib = null
update_appearance()
/obj/machinery/defibrillator_mount/examine(mob/user)
. = ..()
if(defib)
@@ -171,10 +172,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
user.visible_message(span_notice("[user] unhooks [defib] from [src]."), \
span_notice("You slide out [defib] from [src] and unhook the charging cables."))
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
// Make sure processing ends before the defib is nulled
end_processing()
defib = null
update_appearance()
/obj/machinery/defibrillator_mount/charging
name = "PENLITE defibrillator mount"

View File

@@ -310,11 +310,12 @@
diag_hud.remove_atom_from_hud(src)
return ..()
/obj/machinery/door/airlock/handle_atom_del(atom/A)
if(A == note)
/obj/machinery/door/airlock/Exited(atom/movable/gone, direction)
. = ..()
if(gone == note)
note = null
update_appearance()
if(A == seal)
if(gone == seal)
seal = null
update_appearance()

View File

@@ -11,10 +11,10 @@
///Icon of the current screen status
var/screen_icon = "gulag_on"
/obj/machinery/gulag_item_reclaimer/handle_atom_del(atom/deleting_atom)
/obj/machinery/gulag_item_reclaimer/Exited(atom/movable/gone, direction)
. = ..()
for(var/person in stored_items)
stored_items[person] -= deleting_atom
return ..()
stored_items[person] -= gone
/obj/machinery/gulag_item_reclaimer/update_overlays()
. = ..()

View File

@@ -74,11 +74,6 @@
if(!QDELING(src))
qdel(src) //we're now a poster, huzzah!
/obj/item/poster/handle_atom_del(atom/deleting_atom)
if(deleting_atom == poster_structure)
poster_structure.moveToNullspace() //get it the fuck out of us since atom/destroy qdels contents and it'll cause a qdel loop
return ..()
/obj/item/poster/Destroy(force)
QDEL_NULL(poster_structure)
return ..()

View File

@@ -34,9 +34,9 @@
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
stack_trace("apply_defauly_parts called on machine that already had component_parts: [machine]")
// Move to nullspace so you don't trigger handle_atom_del logic and remove existing parts.
// Remove references of components so it doesn't trigger Exited logic and remove existing parts.
for(var/obj/item/part as anything in machine.component_parts)
part.moveToNullspace(loc)
machine.component_parts -= part
qdel(part)
// List of components always contains the circuit board used to build it.
@@ -47,9 +47,7 @@
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
stack_trace("apply_default_parts called from a circuit board that does not belong to machine: [machine]")
// Move to nullspace so you don't trigger handle_atom_del logic, remove old circuit, add new circuit.
machine.circuit.moveToNullspace()
qdel(machine.circuit)
QDEL_NULL(machine.circuit)
machine.circuit = src
return

View File

@@ -33,16 +33,14 @@
/obj/item/transfer_valve/IsAssemblyHolder()
return TRUE
/obj/item/transfer_valve/handle_atom_del(atom/deleted_atom)
/obj/item/transfer_valve/Exited(atom/movable/gone, direction)
. = ..()
if(deleted_atom == tank_one)
if(gone == tank_one)
tank_one = null
update_appearance()
return
if(deleted_atom == tank_two)
else if(gone == tank_two)
tank_two = null
update_appearance()
return
/obj/item/transfer_valve/attackby(obj/item/item, mob/user, params)
if(istype(item, /obj/item/tank))
@@ -152,7 +150,7 @@
T.Translate(-13, 0)
J.transform = T
underlays = list(J)
if(wired)
cable_overlay = mutable_appearance(icon, icon_state = "valve_cables", layer = layer + 0.05, appearance_flags = KEEP_TOGETHER)
add_overlay(cable_overlay)
@@ -160,12 +158,12 @@
else if(cable_overlay)
cut_overlay(cable_overlay, TRUE)
cable_overlay = null
worn_icon_state = "[initial(worn_icon_state)][tank_two ? "l" : ""][tank_one ? "r" : ""]"
if(ishuman(loc)) //worn
var/mob/living/carbon/human/human = loc
human.update_worn_back()
if(!attached_device)
return
@@ -303,14 +301,12 @@
split_gases()
valve_open = FALSE
tank_one.forceMove(drop_location())
tank_one = null
. = TRUE
if("tanktwo")
if(tank_two)
split_gases()
valve_open = FALSE
tank_two.forceMove(drop_location())
tank_two = null
. = TRUE
if("toggle")
toggle_valve()

View File

@@ -25,12 +25,12 @@
if(case)
. += span_warning("There seems to be something inside it, but you can't quite tell what from here...")
/obj/item/implantpad/handle_atom_del(atom/A)
if(A == case)
case = null
update_appearance()
updateSelfDialog()
/obj/item/implantpad/Exited(atom/movable/gone, direction)
. = ..()
if(gone == case)
case = null
update_appearance()
updateSelfDialog()
/obj/item/implantpad/AltClick(mob/user)
..()
@@ -44,7 +44,6 @@
add_fingerprint(user)
case.add_fingerprint(user)
case = null
updateSelfDialog()
update_appearance()

View File

@@ -37,16 +37,10 @@
cell = new cell(src)
// Clean up the cell on destroy
/obj/item/clothing/suit/space/Destroy()
if(isatom(cell))
QDEL_NULL(cell)
return ..()
// Clean up the cell on destroy
/obj/item/inspector/handle_atom_del(atom/A)
if(A == cell)
/obj/item/inspector/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
return ..()
// support for items that interact with the cell
/obj/item/inspector/get_cell()

View File

@@ -416,16 +416,15 @@
..()
if (held_sausage)
user.put_in_hands(held_sausage)
held_sausage = null
update_appearance()
/obj/item/melee/roastingstick/update_overlays()
. = ..()
if(held_sausage)
. += mutable_appearance(icon, "roastingstick_sausage")
/obj/item/melee/roastingstick/handle_atom_del(atom/target)
if (target == held_sausage)
/obj/item/melee/roastingstick/Exited(atom/movable/gone, direction)
. = ..()
if (gone == held_sausage)
held_sausage = null
update_appearance()

View File

@@ -32,17 +32,11 @@
return ..()
/obj/item/pet_carrier/Exited(atom/movable/gone, direction)
. = ..()
if(isliving(gone) && (gone in occupants))
var/mob/living/L = gone
var/mob/living/living_gone = gone
occupants -= gone
occupant_weight -= L.mob_size
/obj/item/pet_carrier/handle_atom_del(atom/A)
if(A in occupants && isliving(A))
var/mob/living/L = A
occupants -= L
occupant_weight -= L.mob_size
..()
occupant_weight -= living_gone.mob_size
/obj/item/pet_carrier/examine(mob/user)
. = ..()

View File

@@ -108,10 +108,10 @@
return ..()
/obj/item/toy/plush/handle_atom_del(atom/A)
if(A == grenade)
/obj/item/toy/plush/Exited(atom/movable/gone, direction)
. = ..()
if(gone == grenade)
grenade = null
..()
/obj/item/toy/plush/attack_self(mob/user)
. = ..()
@@ -148,7 +148,6 @@
else
to_chat(user, span_notice("You remove the grenade from [src]."))
user.put_in_hands(grenade)
grenade = null
return
if(isgrenade(I))
if(stuffed)

View File

@@ -250,15 +250,15 @@
var/turf/newtarget = locate(new_x, new_y, starting.z)
return newtarget
/obj/item/pneumatic_cannon/handle_atom_del(atom/A)
/obj/item/pneumatic_cannon/Exited(atom/movable/gone, direction)
. = ..()
if (loadedItems.Remove(A))
var/obj/item/I = A
if(istype(I))
loadedWeightClass -= I.w_class
if(loadedItems.Remove(gone))
var/obj/item/item = gone
if(istype(item))
loadedWeightClass -= item.w_class
else
loadedWeightClass--
else if (A == tank)
else if (gone == tank)
tank = null
update_appearance()

View File

@@ -46,16 +46,16 @@
if(AI_READY_CORE)
. += span_notice("The monitor's connection can be <b>cut</b>[core_mmi?.brainmob?.mind && !suicide_check() ? " the neural interface can be <b>screwed</b> in." : "."]")
/obj/structure/ai_core/handle_atom_del(atom/A)
if(A == circuit)
/obj/structure/ai_core/Exited(atom/movable/gone, direction)
. = ..()
if(gone == circuit)
circuit = null
if((state != GLASS_CORE) && (state != AI_READY_CORE))
state = EMPTY_CORE
update_appearance()
if(A == core_mmi)
if(gone == core_mmi)
core_mmi = null
return ..()
update_appearance()
/obj/structure/ai_core/Destroy()
QDEL_NULL(circuit)
@@ -200,9 +200,7 @@
P.play_tool_sound(src)
balloon_alert(user, "circuit board removed")
state = EMPTY_CORE
update_appearance()
circuit.forceMove(loc)
circuit = null
return
if(SCREWED_CORE)
if(P.tool_behaviour == TOOL_SCREWDRIVER && circuit)
@@ -298,8 +296,6 @@
P.play_tool_sound(src)
balloon_alert(user, "removed [AI_CORE_BRAIN(core_mmi)]")
core_mmi.forceMove(loc)
core_mmi = null
update_appearance()
return
if(GLASS_CORE)

View File

@@ -47,13 +47,13 @@
if(vname in list(NAMEOF(src, open), NAMEOF(src, showpiece), NAMEOF(src, custom_glass_overlay)))
update_appearance()
/obj/structure/displaycase/handle_atom_del(atom/A)
if(A == electronics)
/obj/structure/displaycase/Exited(atom/movable/gone, direction)
. = ..()
if(gone == electronics)
electronics = null
if(A == showpiece)
if(gone == showpiece)
showpiece = null
update_appearance()
return ..()
/obj/structure/displaycase/Destroy()
QDEL_NULL(electronics)
@@ -73,8 +73,6 @@
if(QDELETED(showpiece))
return
showpiece.forceMove(drop_location())
showpiece = null
update_appearance()
/obj/structure/displaycase/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)

View File

@@ -46,8 +46,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
/obj/structure/extinguisher_cabinet/Destroy()
if(stored_extinguisher)
qdel(stored_extinguisher)
stored_extinguisher = null
QDEL_NULL(stored_extinguisher)
return ..()
/obj/structure/extinguisher_cabinet/contents_explosion(severity, target)
@@ -62,8 +61,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += stored_extinguisher
/obj/structure/extinguisher_cabinet/handle_atom_del(atom/A)
if(A == stored_extinguisher)
/obj/structure/extinguisher_cabinet/Exited(atom/movable/gone, direction)
if(gone == stored_extinguisher)
stored_extinguisher = null
update_appearance(UPDATE_ICON)
@@ -104,11 +103,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
if(stored_extinguisher)
user.put_in_hands(stored_extinguisher)
user.balloon_alert(user, "extinguisher removed")
stored_extinguisher = null
if(!opened)
opened = 1
playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3)
update_appearance(UPDATE_ICON)
else
toggle_cabinet(user)

View File

@@ -92,7 +92,6 @@
return
if(!user.put_in_hands(weapon))
weapon.forceMove(get_turf(src))
update_appearance()
/**
* check_menu: Checks if we are allowed to interact with a radial menu
@@ -109,7 +108,8 @@
return FALSE
return TRUE
/obj/structure/guncase/handle_atom_del(atom/A)
/obj/structure/guncase/Exited(atom/movable/gone, direction)
. = ..()
update_appearance()
/obj/structure/guncase/contents_explosion(severity, target)

View File

@@ -53,24 +53,26 @@
MA.pixel_x = pixel_x
. += victim
/obj/structure/headpike/handle_atom_del(atom/A)
if(A == victim)
/obj/structure/headpike/Exited(atom/movable/gone, direction)
. = ..()
if(gone != victim && gone != spear)
return
if(gone == victim)
victim = null
if(A == spear)
if(gone == spear)
spear = null
if(!QDELETED(src))
deconstruct(TRUE)
return ..()
/obj/structure/headpike/deconstruct(disassembled)
if(victim) //Make sure the head always comes off
victim.forceMove(drop_location())
victim = null
var/obj/item/bodypart/head/our_head = victim
var/obj/item/spear/our_spear = spear
victim = null
spear = null
our_head?.forceMove(drop_location()) //Make sure the head always comes off
if(!disassembled)
return ..()
if(spear)
spear.forceMove(drop_location())
spear = null
our_spear?.forceMove(drop_location())
return ..()
/obj/structure/headpike/attack_hand(mob/user, list/modifiers)

View File

@@ -44,8 +44,9 @@
/obj/structure/statue/petrified/contents_explosion(severity, target)
return
/obj/structure/statue/petrified/handle_atom_del(atom/A)
if(A == petrified_mob)
/obj/structure/statue/petrified/Exited(atom/movable/gone, direction)
. = ..()
if(gone == petrified_mob)
petrified_mob = null
/obj/structure/statue/petrified/Destroy()
@@ -65,12 +66,11 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
petrified_mob.forceMove(loc)
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
REMOVE_TRAIT(petrified_mob, TRAIT_NOBLOOD, MAGIC_TRAIT)
petrified_mob.take_overall_damage((petrified_mob.health - atom_integrity + 100)) //any new damage the statue incurred is transfered to the mob
petrified_mob.faction -= FACTION_MIMIC
petrified_mob = null
petrified_mob.forceMove(loc)
return ..()
/obj/structure/statue/petrified/deconstruct(disassembled = TRUE)

View File

@@ -68,7 +68,6 @@
new /obj/item/stack/rods(Tsec, 2)
if(tank)
tank.forceMove(Tsec)
after_detach_tank()
qdel(src)
/obj/structure/tank_holder/attack_paw(mob/user, list/modifiers)
@@ -83,12 +82,11 @@
add_fingerprint(user)
tank.add_fingerprint(user)
user.put_in_hands(tank)
after_detach_tank()
/obj/structure/tank_holder/handle_atom_del(atom/A)
if(A == tank)
/obj/structure/tank_holder/Exited(atom/movable/gone, direction)
. = ..()
if(gone == tank)
after_detach_tank()
return ..()
/obj/structure/tank_holder/contents_explosion(severity, target)
if(!tank)

View File

@@ -208,9 +208,9 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += beaker
/obj/machinery/atmospherics/components/unary/cryo_cell/handle_atom_del(atom/A)
..()
if(A == beaker)
/obj/machinery/atmospherics/components/unary/cryo_cell/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
/obj/machinery/atmospherics/components/unary/cryo_cell/on_deconstruction()

View File

@@ -92,11 +92,6 @@
. = ..()
AddElement(/datum/element/update_icon_updates_onmob, ITEM_SLOT_HANDCUFFED)
/obj/item/clothing/shoes/sneakers/orange/handle_atom_del(atom/deleting_atom)
if(deleting_atom == attached_cuffs)
moveToNullspace(attached_cuffs)
return ..()
/obj/item/clothing/shoes/sneakers/orange/Destroy()
QDEL_NULL(attached_cuffs)
return ..()

View File

@@ -134,11 +134,11 @@
return ..()
// Clean up the cell on destroy
/obj/item/clothing/suit/space/handle_atom_del(atom/A)
if(A == cell)
/obj/item/clothing/suit/space/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
thermal_on = FALSE
return ..()
// support for items that interact with the cell
/obj/item/clothing/suit/space/get_cell()

View File

@@ -19,7 +19,8 @@
if(evidencebagEquip(I, user))
return 1
/obj/item/evidencebag/handle_atom_del(atom/A)
/obj/item/evidencebag/Exited(atom/movable/gone, direction)
. = ..()
cut_overlays()
w_class = initial(w_class)
icon_state = initial(icon_state)

View File

@@ -418,8 +418,9 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
playsound(src,'sound/effects/podwoosh.ogg',50, FALSE)
do_smoke(1, holder = src, location = get_turf(src))
/obj/machinery/exodrone_launcher/handle_atom_del(atom/A)
if(A == fuel_canister)
/obj/machinery/exodrone_launcher/Exited(atom/movable/gone, direction)
. = ..()
if(gone == fuel_canister)
fuel_canister = null
update_icon()

View File

@@ -56,11 +56,13 @@
return ..()
/obj/machinery/coffeemaker/Exited(atom/movable/gone, direction)
. = ..()
if(gone == coffeepot)
coffeepot = null
update_appearance(UPDATE_OVERLAYS)
if(gone == cartridge)
cartridge = null
return ..()
update_appearance(UPDATE_OVERLAYS)
/obj/machinery/coffeemaker/RefreshParts()
. = ..()
@@ -139,14 +141,6 @@
/obj/machinery/coffeemaker/attack_ai_secondary(mob/user, list/modifiers)
return attack_hand_secondary(user, modifiers)
/obj/machinery/coffeemaker/handle_atom_del(atom/A)
. = ..()
if(A == coffeepot)
coffeepot = null
if(A == cartridge)
cartridge = null
update_appearance(UPDATE_OVERLAYS)
/obj/machinery/coffeemaker/update_overlays()
. = ..()
. += overlay_checks()
@@ -527,13 +521,6 @@
QDEL_NULL(coffee)
return ..()
/obj/machinery/coffeemaker/impressa/Exited(atom/movable/gone, direction)
if(gone == coffeepot)
coffeepot = null
if(gone == coffee)
coffee = null
return ..()
/obj/machinery/coffeemaker/impressa/examine(mob/user)
. = ..()
if(coffee)
@@ -571,13 +558,11 @@
. += "grinder_full"
return .
/obj/machinery/coffeemaker/impressa/handle_atom_del(atom/A)
/obj/machinery/coffeemaker/impressa/Exited(atom/movable/gone, direction)
. = ..()
if(A == coffeepot)
coffeepot = null
if(A == coffee)
coffee.Cut()
update_appearance(UPDATE_OVERLAYS)
if(gone in coffee)
coffee -= gone
update_appearance(UPDATE_OVERLAYS)
/obj/machinery/coffeemaker/impressa/try_brew()
if(coffee_amount <= 0)

View File

@@ -155,11 +155,6 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
if(gone == frying)
reset_frying()
/obj/machinery/deepfryer/handle_atom_del(atom/deleting_atom)
. = ..()
if(deleting_atom == frying)
reset_frying()
/obj/machinery/deepfryer/proc/reset_frying()
if(!QDELETED(frying))
frying.AddElement(/datum/element/fried_item, cook_time)

View File

@@ -96,15 +96,10 @@
grilled_item.AddComponent(/datum/component/sizzle)
/obj/machinery/grill/Exited(atom/movable/gone, direction)
. = ..()
if(gone == grilled_item)
finish_grill()
grilled_item = null
return ..()
/obj/machinery/grill/handle_atom_del(atom/A)
if(A == grilled_item)
grilled_item = null
return ..()
/obj/machinery/grill/wrench_act(mob/living/user, obj/item/I)
. = ..()
@@ -131,7 +126,7 @@
return ..()
/obj/machinery/grill/proc/finish_grill()
if(grilled_item)
if(!QDELETED(grilled_item))
if(grill_time >= 20)
grilled_item.AddElement(/datum/element/grilled_item, grill_time)
UnregisterSignal(grilled_item, COMSIG_ITEM_GRILLED)

View File

@@ -349,7 +349,8 @@
.["name"] = name
.["isdryer"] = FALSE
/obj/machinery/smartfridge/handle_atom_del(atom/A) // Update the UIs in case something inside gets deleted
/obj/machinery/smartfridge/Exited(atom/movable/gone, direction) // Update the UIs in case something inside is removed
. = ..()
SStgui.update_uis(src)
/obj/machinery/smartfridge/ui_act(action, params)

View File

@@ -117,14 +117,12 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += beaker
/obj/machinery/biogenerator/handle_atom_del(atom/deleting_atom)
/obj/machinery/biogenerator/Exited(atom/movable/gone, direction)
. = ..()
if(deleting_atom == beaker)
if(gone == beaker)
beaker = null
update_appearance()
/obj/machinery/biogenerator/RefreshParts()
. = ..()

View File

@@ -42,16 +42,16 @@
UnregisterSignal(src, list(COMSIG_BASICMOB_LOOK_ALIVE, COMSIG_BASICMOB_LOOK_DEAD))
return ..()
/mob/living/basic/pet/dog/corgi/handle_atom_del(atom/deleting_atom)
if(deleting_atom == inventory_head)
/mob/living/basic/pet/dog/corgi/Exited(atom/movable/gone, direction)
. = ..()
if(gone == inventory_head)
inventory_head = null
update_corgi_fluff()
update_appearance(UPDATE_OVERLAYS)
if(deleting_atom == inventory_back)
if(gone == inventory_back)
inventory_back = null
update_corgi_fluff()
update_appearance(UPDATE_OVERLAYS)
return ..()
/mob/living/basic/pet/dog/corgi/gib()
if(inventory_head)

View File

@@ -69,10 +69,9 @@
. = ..()
add_memory_in_range(src, 7, /datum/memory/pet_died, deuteragonist = src) //Protagonist is the person memorizing it
/mob/living/basic/pet/handle_atom_del(atom/deleting_atom)
/mob/living/basic/pet/Exited(atom/movable/gone, direction)
. = ..()
if(deleting_atom != collar)
if(gone != collar)
return
collar = null

View File

@@ -128,10 +128,12 @@
return ..()
/mob/living/simple_animal/bot/cleanbot/Exited(atom/movable/gone, direction)
. = ..()
if(gone == build_bucket)
build_bucket = null
return ..()
if(gone == weapon)
weapon = null
update_appearance(UPDATE_ICON)
/mob/living/simple_animal/bot/cleanbot/Destroy()
QDEL_NULL(build_bucket)
@@ -248,12 +250,6 @@
if(is_type_in_typecache(scan_target, target_types))
return scan_target
/mob/living/simple_animal/bot/cleanbot/handle_atom_del(atom/deleting_atom)
if(deleting_atom == weapon)
weapon = null
update_appearance(UPDATE_ICON)
return ..()
/mob/living/simple_animal/bot/cleanbot/handle_automated_action()
. = ..()
if(!.)

View File

@@ -86,14 +86,14 @@
AddElement(/datum/element/ridable, /datum/component/riding/creature/mulebot)
diag_hud_set_mulebotcell()
/mob/living/simple_animal/bot/mulebot/handle_atom_del(atom/A)
if(A == load)
/mob/living/simple_animal/bot/mulebot/Exited(atom/movable/gone, direction)
. = ..()
if(gone == load)
unload(0)
if(A == cell)
if(gone == cell)
turn_off()
cell = null
diag_hud_set_mulebotcell()
return ..()
/mob/living/simple_animal/bot/mulebot/examine(mob/user)
. = ..()

View File

@@ -158,11 +158,11 @@
playsound(src, 'sound/machines/defib_zap.ogg', 50)
visible_message(span_warning("[src] shakes and speeds up!"))
/mob/living/simple_animal/bot/secbot/handle_atom_del(atom/deleting_atom)
if(deleting_atom == weapon)
/mob/living/simple_animal/bot/secbot/Exited(atom/movable/gone, direction)
. = ..()
if(gone == weapon)
weapon = null
update_appearance()
return ..()
// Variables sent to TGUI
/mob/living/simple_animal/bot/secbot/ui_data(mob/user)

View File

@@ -75,10 +75,10 @@
. = ..()
add_memory_in_range(src, 7, /datum/memory/pet_died, deuteragonist = src) //Protagonist is the person memorizing it
/mob/living/simple_animal/pet/handle_atom_del(atom/deleting_atom)
/mob/living/simple_animal/pet/Exited(atom/movable/gone, direction)
. = ..()
if(deleting_atom != collar)
if(gone != collar)
return
collar = null

View File

@@ -281,18 +281,18 @@
QDEL_NULL(boots)
return ..()
/obj/item/mod/construction/shell/handle_atom_del(atom/deleted_atom)
if(deleted_atom == core)
/obj/item/mod/construction/shell/Exited(atom/movable/gone, direction)
. = ..()
if(gone == core)
core = null
if(deleted_atom == helmet)
if(gone == helmet)
helmet = null
if(deleted_atom == chestplate)
if(gone == chestplate)
chestplate = null
if(deleted_atom == gauntlets)
if(gone == gauntlets)
gauntlets = null
if(deleted_atom == boots)
if(gone == boots)
boots = null
return ..()
#undef START_STEP
#undef CORE_STEP

View File

@@ -57,12 +57,13 @@
if(pai && !pai.holoform)
pai.emp_act(severity)
/obj/item/pai_card/handle_atom_del(atom/thing)
if(thing == pai) //double check /mob/living/silicon/pai/Destroy() if you change these.
pai = null
emotion_icon = initial(emotion_icon)
update_appearance()
return ..()
/obj/item/pai_card/proc/on_pai_del(atom/source)
SIGNAL_HANDLER
if(QDELETED(src))
return
pai = null
emotion_icon = initial(emotion_icon)
update_appearance()
/obj/item/pai_card/Initialize(mapload)
. = ..()
@@ -269,6 +270,7 @@
if(pai)
return FALSE
pai = downloaded
RegisterSignal(pai, COMSIG_QDELETING, PROC_REF(on_pai_del))
emotion_icon = "null"
update_appearance()
playsound(src, 'sound/effects/pai_boot.ogg', 50, TRUE, -1)

View File

@@ -35,6 +35,7 @@
/mob/living/silicon/pai/proc/extend_cable()
QDEL_NULL(hacking_cable) //clear any old cables
hacking_cable = new
RegisterSignal(hacking_cable, COMSIG_QDELETING, PROC_REF(on_hacking_cable_del))
var/mob/living/carbon/hacker = get_holder()
if(iscarbon(hacker) && hacker.put_in_hands(hacking_cable)) //important to double check since get_holder can return non-null values that aren't carbons.
hacker.visible_message(span_notice("A port on [src] opens to reveal a cable, which [hacker] quickly grabs."), span_notice("A port on [src] opens to reveal a cable, which you quickly grab."), span_hear("You hear the soft click of a plastic component and manage to catch the falling cable."))
@@ -89,7 +90,6 @@
*/
/mob/living/silicon/pai/proc/retract_cable()
balloon_alert(src, "cable retracted")
untrack_pai()
QDEL_NULL(hacking_cable)
return TRUE
@@ -112,17 +112,11 @@
// Now begin hacking
if(!do_after(src, 15 SECONDS, hacking_cable.machine, timed_action_flags = NONE, progress = TRUE))
balloon_alert(src, "failed! retracting...")
untrack_pai()
untrack_thing(hacking_cable)
QDEL_NULL(hacking_cable)
if(!QDELETED(card))
card.update_appearance()
return FALSE
var/obj/machinery/door/door = hacking_cable.machine
balloon_alert(src, "success")
door.open()
untrack_pai()
untrack_thing(hacking_cable)
QDEL_NULL(hacking_cable)
return TRUE

View File

@@ -184,30 +184,32 @@
else
. += "Systems nonfunctional."
/mob/living/silicon/pai/handle_atom_del(atom/deleting_atom)
if(deleting_atom == hacking_cable)
untrack_pai()
untrack_thing(hacking_cable)
hacking_cable = null
SStgui.update_user_uis(src)
if(!QDELETED(card))
card.update_appearance()
if(deleting_atom == atmos_analyzer)
/mob/living/silicon/pai/Exited(atom/movable/gone, direction)
if(gone == atmos_analyzer)
atmos_analyzer = null
if(deleting_atom == camera)
else if(gone == camera)
camera = null
if(deleting_atom == host_scan)
else if(gone == host_scan)
host_scan = null
if(deleting_atom == internal_gps)
else if(gone == internal_gps)
internal_gps = null
if(deleting_atom == instrument)
else if(gone == instrument)
instrument = null
if(deleting_atom == newscaster)
else if(gone == newscaster)
newscaster = null
if(deleting_atom == signaler)
else if(gone == signaler)
signaler = null
return ..()
/mob/living/silicon/pai/proc/on_hacking_cable_del(atom/source)
SIGNAL_HANDLER
untrack_pai()
untrack_thing(hacking_cable)
hacking_cable = null
SStgui.update_user_uis(src)
if(!QDELETED(card))
card.update_appearance()
/mob/living/silicon/pai/Initialize(mapload)
. = ..()
START_PROCESSING(SSfastprocess, src)

View File

@@ -96,22 +96,19 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks())
/obj/machinery/photocopier/proc/setup_components()
AddComponent(/datum/component/payment, PHOTOCOPIER_FEE, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL)
/obj/machinery/photocopier/handle_atom_del(atom/deleting_atom)
if(deleting_atom == object_copy)
/obj/machinery/photocopier/Exited(atom/movable/gone, direction)
. = ..()
if(gone == object_copy)
object_copy = null
if(deleting_atom == ass)
ass = null
if(deleting_atom == toner_cartridge)
if(gone == toner_cartridge)
toner_cartridge = null
if(deleting_atom in paper_stack)
paper_stack -= deleting_atom
return ..()
if(gone in paper_stack)
paper_stack -= gone
/obj/machinery/photocopier/Destroy()
// object_copy can be a traitor objective, don't qdel
if(object_copy)
object_copy.forceMove(drop_location())
object_copy = null
QDEL_NULL(toner_cartridge)
QDEL_LIST(paper_stack)
@@ -623,10 +620,6 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks())
visible_message(span_warning("[object_copy] is shoved out of the way by [ass]!"))
object_copy = null
/obj/machinery/photocopier/Exited(atom/movable/gone, direction)
check_ass() // There was potentially a person sitting on the copier, check if they're still there.
return ..()
/**
* Checks the living mob `ass` exists and its location is the same as the photocopier.
*

View File

@@ -260,14 +260,14 @@
area.apc = null
area = null
/obj/machinery/power/apc/handle_atom_del(atom/deleting_atom)
if(deleting_atom == cell)
/obj/machinery/power/apc/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
charging = APC_NOT_CHARGING
update_appearance()
if(!QDELING(src))
SStgui.update_uis(src)
return ..()
/obj/machinery/power/apc/examine(mob/user)
. = ..()

View File

@@ -50,6 +50,15 @@
QDEL_LIST(stored_ammo)
return ..()
/obj/item/ammo_box/Exited(atom/movable/gone, direction)
. = ..()
if(gone in stored_ammo)
remove_from_stored_ammo(gone)
/obj/item/ammo_box/proc/remove_from_stored_ammo(atom/movable/gone)
stored_ammo -= gone
update_appearance()
/obj/item/ammo_box/add_weapon_description()
AddElement(/datum/element/weapon_description, attached_proc = PROC_REF(add_notes_box))
@@ -84,19 +93,19 @@
return
for(var/i in max(1, stored_ammo.len) to max_ammo)
stored_ammo += new round_check() //SKYRAT EDTI CHANGE - SEC_HUAL - Moving to nullspace seems to help with lag.
stored_ammo += new round_check(src)
update_appearance()
///gets a round from the magazine, if keep is TRUE the round will stay in the gun
///gets a round from the magazine, if keep is TRUE the round will be moved to the bottom of the list.
/obj/item/ammo_box/proc/get_round(keep = FALSE)
if (!stored_ammo.len)
var/ammo_len = length(stored_ammo)
if (!ammo_len)
return null
else
var/b = stored_ammo[stored_ammo.len]
stored_ammo -= b
if (keep)
stored_ammo.Insert(1,b)
return b
var/casing = stored_ammo[ammo_len]
if (keep)
stored_ammo -= casing
stored_ammo.Insert(1,casing)
return casing
///puts a round into the magazine
/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0)
@@ -106,7 +115,7 @@
if (stored_ammo.len < max_ammo)
stored_ammo += R
R.moveToNullspace() //SKYRAT EDTI CHANGE - SEC_HUAL - Moving to nullspace seems to help with lag.
R.forceMove(src)
return TRUE
//for accessibles magazines (e.g internal ones) when full, start replacing spent ammo
@@ -117,7 +126,7 @@
AC.forceMove(get_turf(src.loc))
stored_ammo += R
R.moveToNullspace() //SKYRAT EDTI CHANGE - SEC_HUAL - Moving to nullspace seems to help with lag.
R.forceMove(src)
return TRUE
return FALSE
@@ -173,7 +182,6 @@
desc = "[initial(desc)] There [(shells_left == 1) ? "is" : "are"] [shells_left] shell\s left!"
/obj/item/ammo_box/update_icon_state()
. = ..()
var/shells_left = LAZYLEN(stored_ammo)
switch(multiple_sprites)
if(AMMO_BOX_PER_BULLET)
@@ -181,19 +189,20 @@
if(AMMO_BOX_FULL_EMPTY)
icon_state = "[multiple_sprite_use_base ? base_icon_state : initial(icon_state)]-[shells_left ? "full" : "empty"]"
/obj/item/ammo_box/update_overlays()
. = ..()
if(ammo_band_color && ammo_band_icon)
. += update_ammo_band()
update_ammo_band()
return ..()
/obj/item/ammo_box/proc/update_ammo_band()
overlays.Cut()
var/band_icon = ammo_band_icon
if(!(length(stored_ammo)) && ammo_band_icon_empty)
band_icon = ammo_band_icon_empty
var/image/ammo_band_image = image(icon, src, band_icon)
ammo_band_image.color = ammo_band_color
ammo_band_image.appearance_flags = RESET_COLOR|KEEP_APART
return ammo_band_image
overlays += ammo_band_image
///Count of number of bullets in the magazine
/obj/item/ammo_box/magazine/proc/ammo_count(countempties = TRUE)
@@ -204,11 +213,8 @@
return boolets
///list of every bullet in the magazine
/obj/item/ammo_box/magazine/proc/ammo_list(drop_list = FALSE)
var/list/L = stored_ammo.Copy()
if(drop_list)
stored_ammo.Cut()
return L
/obj/item/ammo_box/magazine/proc/ammo_list()
return stored_ammo.Copy()
///drops the entire contents of the magazine on the floor
/obj/item/ammo_box/magazine/proc/empty_magazine()
@@ -216,14 +222,3 @@
for(var/obj/item/ammo in stored_ammo)
ammo.forceMove(turf_mag)
stored_ammo -= ammo
/obj/item/ammo_box/magazine/handle_atom_del(atom/A)
stored_ammo -= A
update_appearance()
//SKRYAT EDIT ADDITION BEGIN - SEC_HAUL
/obj/item/ammo_box/Destroy()
. = ..()
for(var/i in stored_ammo)
qdel(i)
//SKYRAT EDIT END

View File

@@ -4,14 +4,18 @@
caliber = CALIBER_357
max_ammo = 7
/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0)
///Here, we have to maintain the list size, to emulate a cylinder with several chambers, empty or otherwise.
/obj/item/ammo_box/magazine/internal/cylinder/remove_from_stored_ammo(atom/movable/gone)
for(var/index in 1 to length(stored_ammo))
var/obj/item/ammo_casing/bullet = stored_ammo[index]
if(gone == bullet)
stored_ammo[index] = null
update_appearance()
return
/obj/item/ammo_box/magazine/internal/cylinder/get_round()
rotate()
var/b = stored_ammo[1]
if(!keep)
stored_ammo[1] = null
return b
return stored_ammo[1]
/obj/item/ammo_box/magazine/internal/cylinder/proc/rotate()
var/b = stored_ammo[1]
@@ -22,15 +26,10 @@
for(var/i in 1 to rand(0, max_ammo*2))
rotate()
/obj/item/ammo_box/magazine/internal/cylinder/ammo_list(drop_list = FALSE)
var/list/L = list()
for(var/i=1 to stored_ammo.len)
var/obj/item/ammo_casing/bullet = stored_ammo[i]
if(bullet)
L.Add(bullet)
if(drop_list)//We have to maintain the list size, to emulate a cylinder
stored_ammo[i] = null
return L
/obj/item/ammo_box/magazine/internal/cylinder/ammo_list()
var/list/no_nulls_ammo = stored_ammo.Copy()
list_clear_nulls(no_nulls_ammo)
return no_nulls_ammo
/obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0)
if(!R || !(caliber ? (caliber == R.caliber) : (ammo_type == R.type)))

View File

@@ -111,22 +111,19 @@
/obj/item/gun/proc/add_seclight_point()
return
/obj/item/gun/handle_atom_del(atom/A)
if(A == pin)
/obj/item/gun/Exited(atom/movable/gone, direction)
. = ..()
if(gone == pin)
pin = null
if(A == chambered)
if(gone == chambered)
chambered = null
update_appearance()
if(A == suppressed)
if(gone == suppressed)
clear_suppressor()
return ..()
/obj/item/gun/Exited(atom/movable/gone, direction)
if(gone == bayonet)
bayonet = null
if(!QDELING(src))
update_appearance()
return ..()
///Clears var and updates icon. In the case of ballistic weapons, also updates the gun's weight.
/obj/item/gun/proc/clear_suppressor()

View File

@@ -259,27 +259,34 @@
stack_trace("Trying to move a qdeleted casing of type [casing.type]!")
chambered = null
else if(casing_ejector || !from_firing)
chambered = null
casing.forceMove(drop_location()) //Eject casing onto ground.
if(!QDELETED(casing))
casing.bounce_away(TRUE)
SEND_SIGNAL(casing, COMSIG_CASING_EJECTED)
else if(empty_chamber)
UnregisterSignal(chambered, COMSIG_MOVABLE_MOVED)
chambered = null
if (chamber_next_round && (magazine?.max_ammo > 1))
chamber_round()
///Used to chamber a new round and eject the old one
/obj/item/gun/ballistic/proc/chamber_round(keep_bullet = FALSE, spin_cylinder, replace_new_round)
/obj/item/gun/ballistic/proc/chamber_round(spin_cylinder, replace_new_round)
if (chambered || !magazine)
return
if (magazine.ammo_count())
chambered = magazine.get_round(keep_bullet || bolt_type == BOLT_TYPE_NO_BOLT)
chambered = magazine.get_round((bolt_type == BOLT_TYPE_OPEN && !bolt_locked) || bolt_type == BOLT_TYPE_NO_BOLT)
if (bolt_type != BOLT_TYPE_OPEN)
chambered.forceMove(src)
else
RegisterSignal(chambered, COMSIG_MOVABLE_MOVED, PROC_REF(clear_chambered))
if(replace_new_round)
magazine.give_round(new chambered.type)
/obj/item/gun/ballistic/proc/clear_chambered(datum/source)
SIGNAL_HANDLER
UnregisterSignal(chambered, COMSIG_MOVABLE_MOVED)
chambered = null
///updates a bunch of racking related stuff and also handles the sound effects and the like
/obj/item/gun/ballistic/proc/rack(mob/user = null)
if (bolt_type == BOLT_TYPE_NO_BOLT) //If there's no bolt, nothing to rack
@@ -323,7 +330,7 @@
else
playsound(src, load_empty_sound, load_sound_volume, load_sound_vary)
if (bolt_type == BOLT_TYPE_OPEN && !bolt_locked)
chamber_round(TRUE)
chamber_round()
update_appearance()
return TRUE
else
@@ -510,7 +517,7 @@
if(bolt_type == BOLT_TYPE_NO_BOLT)
chambered = null
var/num_unloaded = 0
for(var/obj/item/ammo_casing/CB in get_ammo_list(FALSE, TRUE))
for(var/obj/item/ammo_casing/CB as anything in get_ammo_list(FALSE))
CB.forceMove(drop_location())
CB.bounce_away(FALSE, NONE)
num_unloaded++
@@ -561,14 +568,12 @@
return bullets
///gets a list of every bullet in the gun
/obj/item/gun/ballistic/proc/get_ammo_list(countchambered = TRUE, drop_all = FALSE)
/obj/item/gun/ballistic/proc/get_ammo_list(countchambered = TRUE)
var/list/rounds = list()
if(chambered && countchambered)
rounds.Add(chambered)
if(drop_all)
chambered = null
if(magazine)
rounds.Add(magazine.ammo_list(drop_all))
rounds.Add(magazine.ammo_list())
return rounds
#define BRAINS_BLOWN_THROW_RANGE 3

View File

@@ -33,38 +33,33 @@
if(isnull(chambered))
return ..()
chambered.forceMove(drop_location())
magazine.get_round(keep = FALSE)
var/obj/item/ammo_casing/arrow/our_arrow = chambered
user.put_in_hands(our_arrow)
drawn = FALSE
chambered = null
user.put_in_hands(chambered)
chambered = magazine.get_round()
update_appearance()
/obj/item/gun/ballistic/bow/proc/drop_arrow()
drawn = FALSE
if(chambered)
chambered.forceMove(drop_location())
magazine.get_round(keep = FALSE)
chambered = null
chambered.forceMove(drop_location())
chambered = magazine.get_round()
update_appearance()
/obj/item/gun/ballistic/bow/chamber_round(keep_bullet = FALSE, spin_cylinder, replace_new_round)
/obj/item/gun/ballistic/bow/chamber_round(spin_cylinder, replace_new_round)
if(chambered || !magazine)
return
if(magazine.ammo_count())
chambered = magazine.get_round(TRUE)
chambered.forceMove(src)
chambered = magazine.get_round()
RegisterSignal(chambered, COMSIG_MOVABLE_MOVED, PROC_REF(clear_chambered))
update_appearance()
/obj/item/gun/ballistic/bow/clear_chambered(datum/source)
. = ..()
drawn = FALSE
/obj/item/gun/ballistic/bow/attack_self(mob/user)
if(!chambered)
balloon_alert(user, "no arrow nocked!")
else
balloon_alert(user, "[drawn ? "string released" : "string drawn"]")
drawn = !drawn
playsound(src, 'sound/weapons/gun/bow/bow_draw.ogg', 25, TRUE)
return
balloon_alert(user, "[drawn ? "string released" : "string drawn"]")
drawn = !drawn
playsound(src, 'sound/weapons/gun/bow/bow_draw.ogg', 25, TRUE)
update_appearance()
/obj/item/gun/ballistic/bow/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
@@ -74,11 +69,8 @@
if(!drawn)
to_chat(user, span_warning("Without drawing the bow, the arrow uselessly falls to the ground."))
drop_arrow()
update_appearance()
return
drawn = FALSE
. = ..() //fires, removing the arrow
update_appearance()
return ..() //fires, removing the arrow
/obj/item/gun/ballistic/bow/equipped(mob/user, slot, initial)
. = ..()
@@ -94,10 +86,11 @@
addtimer(CALLBACK(src, PROC_REF(drop_arrow_if_not_held)), 0.1 SECONDS)
/obj/item/gun/ballistic/bow/proc/drop_arrow_if_not_held()
if(!ismob(loc))
if(drawn)
playsound(src, 'sound/weapons/gun/bow/bow_fire.ogg', 25, TRUE)
drop_arrow()
if(ismob(loc) || !chambered)
return
if(drawn)
playsound(src, 'sound/weapons/gun/bow/bow_fire.ogg', 25, TRUE)
drop_arrow()
/obj/item/gun/ballistic/bow/shoot_with_empty_chamber(mob/living/user)
return //no clicking sounds please

View File

@@ -21,13 +21,17 @@
last_fire = world.time
/obj/item/gun/ballistic/revolver/chamber_round(keep_bullet, spin_cylinder = TRUE, replace_new_round)
/obj/item/gun/ballistic/revolver/chamber_round(spin_cylinder = TRUE, replace_new_round)
if(!magazine) //if it mag was qdel'd somehow.
CRASH("revolver tried to chamber a round without a magazine!")
if(chambered)
UnregisterSignal(chambered, COMSIG_MOVABLE_MOVED)
if(spin_cylinder)
chambered = magazine.get_round(TRUE)
else
chambered = magazine.stored_ammo[1]
if(chambered)
RegisterSignal(chambered, COMSIG_MOVABLE_MOVED, PROC_REF(clear_chambered))
/obj/item/gun/ballistic/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj)
..()

View File

@@ -139,11 +139,11 @@
return ..()
/obj/item/gun/energy/handle_atom_del(atom/A)
if(A == cell)
/obj/item/gun/energy/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
update_appearance()
return ..()
/obj/item/gun/energy/process(seconds_per_tick)
if(selfcharge && cell && cell.percent() < 100)

View File

@@ -62,11 +62,11 @@
cached_target = null
return ..()
/obj/item/gun/blastcannon/handle_atom_del(atom/A)
if(A == bomb)
/obj/item/gun/blastcannon/Exited(atom/movable/gone, direction)
. = ..()
if(gone == bomb)
bomb = null
update_appearance()
return ..()
/obj/item/gun/blastcannon/assume_air(datum/gas_mixture/giver)
qdel(giver)

View File

@@ -38,10 +38,10 @@
max_syringes = reset_fantasy_variable("max_syringes", max_syringes)
return ..()
/obj/item/gun/syringe/handle_atom_del(atom/A)
/obj/item/gun/syringe/Exited(atom/movable/gone, direction)
. = ..()
if(A in syringes)
syringes.Remove(A)
if(gone in syringes)
syringes -= gone
/obj/item/gun/syringe/recharge_newshot()
if(!syringes.len)

View File

@@ -220,9 +220,9 @@
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += beaker
/obj/machinery/chem_dispenser/handle_atom_del(atom/A)
..()
if(A == beaker)
/obj/machinery/chem_dispenser/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
cut_overlays()

View File

@@ -49,9 +49,9 @@
QDEL_NULL(beaker)
return ..()
/obj/machinery/chem_heater/handle_atom_del(atom/A)
/obj/machinery/chem_heater/Exited(atom/movable/gone, direction)
. = ..()
if(A == beaker)
if(gone == beaker)
beaker = null
update_appearance()

View File

@@ -115,9 +115,9 @@ GLOBAL_LIST_INIT(chem_master_containers, list(
replace_beaker()
return ..()
/obj/machinery/chem_master/handle_atom_del(atom/deleted_atom)
..()
if(deleted_atom == beaker)
/obj/machinery/chem_master/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
update_appearance(UPDATE_ICON)

View File

@@ -43,9 +43,9 @@
QDEL_NULL(soundloop)
return ..()
/obj/structure/chem_separator/handle_atom_del(atom/deleted_atom)
..()
if(deleted_atom == beaker)
/obj/structure/chem_separator/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
update_appearance(UPDATE_ICON)

View File

@@ -73,11 +73,11 @@
/obj/machinery/computer/pandemic/attack_ai_secondary(mob/user, list/modifiers)
return attack_hand_secondary(user, modifiers)
/obj/machinery/computer/pandemic/handle_atom_del(atom/A)
if(A == beaker)
/obj/machinery/computer/pandemic/Exited(atom/movable/gone, direction)
. = ..()
if(gone == beaker)
beaker = null
update_appearance()
return ..()
/obj/machinery/computer/pandemic/attackby(obj/item/held_item, mob/user, params)
//Advanced science! Percision instruments (eg droppers and syringes) are precise enough to modify the loaded sample!

View File

@@ -112,13 +112,13 @@
/obj/machinery/reagentgrinder/attack_ai_secondary(mob/user, list/modifiers)
return attack_hand_secondary(user, modifiers)
/obj/machinery/reagentgrinder/handle_atom_del(atom/A)
/obj/machinery/reagentgrinder/Exited(atom/movable/gone, direction)
. = ..()
if(A == beaker)
if(gone == beaker)
beaker = null
update_appearance()
if(holdingitems[A])
holdingitems -= A
if(holdingitems[gone])
holdingitems -= gone
/obj/machinery/reagentgrinder/proc/drop_all_items()
for(var/i in holdingitems)

View File

@@ -88,8 +88,9 @@
trunk = null
return ..()
/obj/machinery/disposal/handle_atom_del(atom/A)
if(A == stored && !QDELETED(src))
/obj/machinery/disposal/Exited(atom/movable/gone, direction)
. = ..()
if(gone == stored && !QDELETED(src))
stored = null
deconstruct(FALSE)
@@ -279,11 +280,13 @@
var/turf/T = loc
if(!(flags_1 & NODECONSTRUCT_1))
if(stored)
stored.forceMove(T)
src.transfer_fingerprints_to(stored)
stored.set_anchored(FALSE)
stored.set_density(TRUE)
stored.update_appearance()
var/obj/structure/disposalconstruct/construct = stored
stored = null
construct.forceMove(T)
transfer_fingerprints_to(construct)
construct.set_anchored(FALSE)
construct.set_density(TRUE)
construct.update_appearance()
for(var/atom/movable/AM in src) //out, out, darned crowbar!
AM.forceMove(T)
..()

View File

@@ -76,10 +76,13 @@
expel(holdplease, get_turf(src), 0)
stored = null // It gets dumped out in expel()
/obj/structure/disposalpipe/handle_atom_del(atom/A)
if(A == stored && !QDELETED(src))
spawn_pipe = FALSE
stored = null
/obj/structure/disposalpipe/Exited(atom/movable/gone, direction)
. = ..()
if(gone != stored || QDELETED(src))
return
spawn_pipe = FALSE
stored = null
if(QDELETED(gone))
deconstruct(FALSE) //pipe has broken.
// returns the direction of the next pipe object, given the entrance dir
@@ -171,12 +174,13 @@
if(!(flags_1 & NODECONSTRUCT_1))
if(disassembled)
if(spawn_pipe)
if(isnull(stored)) // Don't have something? Make one now
stored = new /obj/structure/disposalconstruct(src, null, SOUTH, FALSE, src)
stored.forceMove(loc)
transfer_fingerprints_to(stored)
stored.setDir(dir)
var/obj/structure/disposalconstruct/construct = stored
if(!construct) // Don't have something? Make one now
construct = new /obj/structure/disposalconstruct(src, null, SOUTH, FALSE, src)
stored = null
construct.forceMove(loc)
transfer_fingerprints_to(construct)
construct.setDir(dir)
spawn_pipe = FALSE
else
var/turf/T = get_turf(src)

View File

@@ -69,12 +69,12 @@
connected_recycler = null
return ..()
/obj/machinery/computer/camera_advanced/xenobio/handle_atom_del(atom/A)
if(A == current_potion)
/obj/machinery/computer/camera_advanced/xenobio/Exited(atom/movable/gone, direction)
. = ..()
if(gone == current_potion)
current_potion = null
if(A in stored_slimes)
stored_slimes -= A
return ..()
if(gone in stored_slimes)
stored_slimes -= gone
/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
eyeobj = new /mob/camera/ai_eye/remote/xenobio(get_turf(src))

View File

@@ -93,7 +93,7 @@
var/datum/worn_feature_offset/worn_face_offset
/obj/item/bodypart/head/Destroy()
QDEL_NULL(brainmob) //order is sensitive, see warning in handle_atom_del() below
QDEL_NULL(brainmob) //order is sensitive, see warning in Exited() below
QDEL_NULL(brain)
QDEL_NULL(eyes)
QDEL_NULL(ears)
@@ -106,21 +106,21 @@
QDEL_NULL(worn_face_offset)
return ..()
/obj/item/bodypart/head/handle_atom_del(atom/head_atom)
if(head_atom == brain)
/obj/item/bodypart/head/Exited(atom/movable/gone, direction)
if(gone == brain)
brain = null
update_icon_dropped()
if(!QDELETED(brainmob)) //this shouldn't happen without badminnery.
message_admins("Brainmob: ([ADMIN_LOOKUPFLW(brainmob)]) was left stranded in [src] at [ADMIN_VERBOSEJMP(src)] without a brain!")
brainmob.log_message(", brainmob, was left stranded in [src] without a brain", LOG_GAME)
if(head_atom == brainmob)
if(gone == brainmob)
brainmob = null
if(head_atom == eyes)
if(gone == eyes)
eyes = null
update_icon_dropped()
if(head_atom == ears)
if(gone == ears)
ears = null
if(head_atom == tongue)
if(gone == tongue)
tongue = null
return ..()

View File

@@ -195,8 +195,9 @@
if(cell_cover_open)
return current_cell
/obj/item/gravity_harness/handle_atom_del(atom/harness_cell)
if(harness_cell == current_cell)
/obj/item/gravity_harness/Exited(atom/movable/gone, direction)
. = ..()
if(gone == current_cell)
change_mode(MODE_GRAVOFF)
current_cell = null

View File

@@ -132,14 +132,14 @@
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/gun/microfusion/handle_atom_del(atom/to_handle)
if(to_handle == cell)
/obj/item/gun/microfusion/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
update_appearance()
if(to_handle == phase_emitter)
else if(gone == phase_emitter)
phase_emitter = null
update_appearance()
return ..()
/obj/item/gun/microfusion/can_shoot()
return !QDELETED(cell) ? (cell.charge >= microfusion_lens.e_cost) : FALSE