Impliments Ghom review, reverts blood list back to component

This commit is contained in:
Poojawa
2019-08-15 12:32:44 -05:00
parent 2073921f4b
commit 0290a46ddc
54 changed files with 662 additions and 613 deletions
+19 -125
View File
@@ -37,9 +37,6 @@
var/rad_insulation = RAD_NO_INSULATION
var/icon/blood_splatter_icon
var/list/fingerprints
var/list/fingerprintshidden
var/list/blood_DNA
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
@@ -248,22 +245,24 @@
return TRUE
return FALSE
/atom/proc/examine(mob/user)
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src]."
if(src.blood_DNA && !istype(src, /obj/effect/decal))
if(gender == PLURAL)
f_name = "some "
else
f_name = "a "
f_name += "<span class='danger'>blood-stained</span> [name]!"
/atom/proc/get_examine_name(mob/user)
. = "\a [src]"
var/list/override = list(gender == PLURAL ? "some" : "a", " ", "[name]")
if(article)
. = "[article] [src]"
override[EXAMINE_POSITION_ARTICLE] = article
if(SEND_SIGNAL(src, COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED)
. = override.Join("")
to_chat(user, "[icon2html(src, user)] That's [f_name]")
///Generate the full examine string of this atom (including icon for goonchat)
/atom/proc/get_examine_string(mob/user, thats = FALSE)
. = "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
/atom/proc/examine(mob/user)
to_chat(user, "[get_examine_string(user, TRUE)].")
if(desc)
to_chat(user, desc)
// *****RM
//to_chat(user, "[name]: Dn:[density] dir:[dir] cont:[contents] icon:[icon] is:[icon_state] loc:[loc]")
if(reagents)
if(reagents.reagents_holder_flags & TRANSPARENT)
@@ -285,6 +284,8 @@
else
to_chat(user, "<span class='danger'>It's empty.</span>")
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user)
/atom/proc/relaymove(mob/user)
if(buckle_message_cooldown <= world.time)
buckle_message_cooldown = world.time + 50
@@ -349,24 +350,12 @@
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
return FALSE
if(!blood_DNA) //if our list of DNA doesn't exist yet, initialise it.
blood_DNA = list()
var/old_length = blood_DNA.len
blood_DNA |= new_blood_dna
if(blood_DNA.len == old_length)
var/old_length = blood_DNA_length()
add_blood(new_blood_dna)
if(blood_DNA_length() == old_length)
return FALSE
return TRUE
//to add blood dna info to the object's blood_DNA list
/atom/proc/transfer_blood_dna(list/blood_dna)
if(!blood_DNA)
blood_DNA = list()
var/old_length = blood_DNA.len
blood_DNA |= blood_dna
if(blood_DNA.len > old_length)
return TRUE//some new blood DNA was added
//to add blood from a mob onto something, and transfer their dna info
/atom/proc/add_mob_blood(mob/living/M)
var/list/blood_dna = M.get_blood_dna_list()
@@ -374,101 +363,6 @@
return FALSE
return add_blood(blood_dna)
//to add blood onto something, with blood dna info to include.
/atom/proc/add_blood(list/blood_dna)
return FALSE
/obj/add_blood(list/blood_dna)
return transfer_blood_dna(blood_dna)
/obj/item/add_blood(list/blood_dna)
if(!..())
return FALSE
add_blood_overlay()
return TRUE //we applied blood to the item
/obj/item/proc/add_blood_overlay()
if(!blood_DNA.len)
return
if(initial(icon) && initial(icon_state))
blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
blood_overlay = image(blood_splatter_icon)
blood_overlay.color = blood_DNA_to_color()
add_overlay(blood_overlay)
/obj/item/clothing/gloves/add_blood(mob/living/carbon/M)
. = ..()
transfer_blood = rand(2, 4)
return TRUE
/obj/item/clothing/shoes/add_blood(mob/living/carbon/M)
. = ..()
// transfer_blood = rand(2, 4)
return TRUE
/turf/add_blood(list/blood_dna)
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
if(!B)
B = new /obj/effect/decal/cleanable/blood/splatter(src)
B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
return TRUE //we bloodied the floor
/mob/living/carbon/human/add_blood(list/blood_dna)
if(wear_suit)
wear_suit.add_blood(blood_dna)
update_inv_wear_suit()
else if(w_uniform)
w_uniform.add_blood(blood_dna)
update_inv_w_uniform()
if(gloves)
var/obj/item/clothing/gloves/G = gloves
G.add_blood(blood_dna)
else
transfer_blood_dna(blood_dna)
bloody_hands = rand(2, 4)
update_inv_gloves() //handles bloody hands overlays and updating
if(shoes)
var/obj/item/clothing/shoes/S = shoes
S.add_blood(blood_dna)
// else
// transfer_blood_dna(blood_dna)
// bloody_feet = rand(2, 4)
update_inv_shoes() // get them feet messy for prints!
return TRUE
/atom/proc/clean_blood()
if(islist(blood_DNA))
blood_DNA = null
return TRUE
/atom/proc/blood_DNA_to_color()
var/list/colors = list()//first we make a list of all bloodtypes present
for(var/bloop in blood_DNA)
if(colors[blood_DNA[bloop]])
colors[blood_DNA[bloop]]++
else
colors[blood_DNA[bloop]] = 1
var/final_rgb = "#940000"
if(colors.len)
var/sum = 0 //this is all shitcode, but it works; trust me
final_rgb = bloodtype_to_color(colors[1])
sum = colors[colors[1]]
if(colors.len > 1)
var/i = 2
while(i <= colors.len)
var/tmp = colors[colors[i]]
final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum))
sum += tmp
i++
return final_rgb
/atom/proc/wash_cream()
return TRUE
+2 -3
View File
@@ -247,8 +247,7 @@
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
I.clean_blood()
I.fingerprints = list()
SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
var/datum/component/radioactive/contamination = I.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
@@ -419,4 +418,4 @@
if(I)
I.forceMove(loc)
. = TRUE
update_icon()
update_icon()
+7 -10
View File
@@ -11,6 +11,10 @@
var/obj/item/color_source
var/max_wash_capacity = 5
/obj/machinery/washing_machine/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click it to start a wash cycle.</span>")
@@ -55,8 +59,7 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
/obj/machinery/washing_machine/clean_blood()
..()
/obj/machinery/washing_machine/proc/clean_blood()
if(!busy)
bloody_mess = FALSE
update_icon()
@@ -64,7 +67,7 @@
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
AM.clean_blood()
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
AM.machine_wash(src)
busy = FALSE
@@ -92,12 +95,6 @@
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/obj/item/reagents_containers/rag/towel/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/dog/corgi/machine_wash(obj/machinery/washing_machine/WM)
gib()
@@ -274,4 +271,4 @@
..()
density = TRUE //because machinery/open_machine() sets it to 0
color_source = null
has_corgi = 0
has_corgi = 0
@@ -1,8 +1,7 @@
/obj/effect/decal/cleanable
gender = PLURAL
layer = ABOVE_NORMAL_TURF_LAYER
var/list/random_icon_states = list()
var/list/random_icon_states = null
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
@@ -26,9 +25,9 @@
if(LAZYLEN(diseases_to_add))
AddComponent(/datum/component/infective, diseases_to_add)
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C)
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
qdel(C)
return TRUE
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
@@ -70,9 +69,10 @@
//Add "bloodiness" of this blood's type, to the human's shoes
//This is on /cleanable because fuck this ancient mess
/obj/effect/decal/cleanable/Crossed(atom/movable/O)
..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
if(H.shoes && blood_state && bloodiness && (!HAS_TRAIT(H,TRAIT_LIGHT_STEP) || !H.mind.assigned_role == "Detective"))
if(H.shoes && blood_state && bloodiness && !HAS_TRAIT(H, TRAIT_LIGHT_STEP))
var/obj/item/clothing/shoes/S = H.shoes
var/add_blood = 0
if(bloodiness >= BLOOD_GAIN_PER_STEP)
@@ -81,8 +81,7 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
if(blood_DNA && blood_DNA.len)
S.add_blood(blood_DNA)
S.add_blood(return_blood_DNA())
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
@@ -3,17 +3,17 @@
name = "xeno blood"
desc = "It's green and acidic. It looks like... <i>blood?</i>"
color = BLOOD_COLOR_XENO
blood_DNA = list("UNKNOWN DNA" = "X*")
/obj/effect/decal/cleanable/blood/splatter/xeno
color = BLOOD_COLOR_XENO
/obj/effect/decal/cleanable/blood/gibs/xeno
color = BLOOD_COLOR_XENO
gibs_reagent_id = "liquidxenogibs"
gibs_bloodtype = "X*"
/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidxenogibs", 5)
update_icon()
/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
@@ -35,7 +35,7 @@
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA)
splat.add_blood(return_blood_DNA())
if(!step_to(src, get_step(src, direction), 0))
break
@@ -6,11 +6,17 @@
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = "liquidgibs"
var/gibs_bloodtype = "A+"
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
. = ..()
if(random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
if(gibs_reagent_id)
reagents.add_reagent(gibs_reagent_id, 5)
if(gibs_bloodtype)
add_blood(list("Non-human DNA" = gibs_bloodtype))
update_icon()
@@ -51,7 +57,7 @@
if(infective)
diseases = infective.diseases
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA)
splat.add_blood(return_blood_DNA())
if(!step_to(src, get_step(src, direction), 0))
break
@@ -81,9 +87,8 @@
/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
setDir(pick(1,2,4,8))
setDir(pick(GLOB.cardinals))
icon_state += "-old"
add_blood(list("Non-human DNA" = "A+"))
update_icon()
/obj/effect/decal/cleanable/blood/drip
@@ -101,9 +106,6 @@
/obj/effect/decal/cleanable/blood/gibs/human/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidgibs", 5)
if(!blood_DNA.len)
add_blood(list("Non-human DNA" = "A+"))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/human/up
@@ -128,12 +130,11 @@
//Lizards
/obj/effect/decal/cleanable/blood/gibs/human/lizard
body_colors = "117720"
gibs_reagent_id = "liquidgibs"
gibs_bloodtype = "L"
/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidgibs", 5)
if(!blood_DNA.len)
add_blood(list("Non-human DNA" = "L"))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/human/lizard/up
@@ -157,12 +158,11 @@
// Slime Gibs
/obj/effect/decal/cleanable/blood/gibs/slime
desc = "They look gooey and gruesome."
gibs_reagent_id = "liquidslimegibs"
gibs_bloodtype = "GEL"
/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidslimegibs", 5)
if(!blood_DNA.len)
add_blood(list("Non-human DNA" = "GEL"))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/slime/update_icon()
@@ -197,21 +197,22 @@
/obj/effect/decal/cleanable/blood/gibs/synth
desc = "They look sludgy and disgusting."
gibs_reagent_id = "liquidsyntheticgibs"
gibs_bloodtype = "SY"
/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidsyntheticgibs", 5)
update_icon()
//IPCs
/obj/effect/decal/cleanable/blood/gibs/ipc
desc = "They look sharp yet oozing."
body_colors = "00ff00"
gibs_reagent_id = "liquidoilgibs"
gibs_bloodtype = "HF"
/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidoilgibs", 5)
if(!blood_DNA.len)
add_blood(list("Non-human DNA" = "HF"))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/ipc/update_icon()
@@ -4,16 +4,17 @@
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_DNA = list()
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
C.add_blood(return_blood_DNA())
if (bloodiness)
if (C.bloodiness < MAX_SHOE_BLOODINESS)
C.bloodiness += bloodiness
update_icon()
..()
return ..()
/obj/effect/decal/cleanable/blood/transfer_blood_dna()
..()
@@ -50,7 +51,6 @@
desc = "Your instincts say you shouldn't be following these."
random_icon_states = null
var/list/existing_dirs = list()
blood_DNA = list()
/obj/effect/decal/cleanable/trail_holder/update_icon()
color = blood_DNA_to_color()
-11
View File
@@ -541,17 +541,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
/obj/item/clean_blood()
. = ..()
if(.)
if(blood_splatter_icon)
cut_overlay(blood_splatter_icon)
/obj/item/clothing/gloves/clean_blood()
. = ..()
if(.)
transfer_blood = 0
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
+1 -1
View File
@@ -88,7 +88,7 @@
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
target.clean_blood()
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
return
+1 -1
View File
@@ -26,7 +26,7 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
A.clean_blood()
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
for(var/obj/effect/O in A)
if(is_cleanable(O))
qdel(O)
+5 -5
View File
@@ -388,10 +388,10 @@
else
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
blood_DNA = from.blood_DNA
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
add_blood(from.return_blood_DNA())
add_fingerprint_list(from.return_fingerprints())
add_hiddenprint_list(from.return_hiddenprints())
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
@@ -436,4 +436,4 @@
/datum/stack_recipe_list/New(title, recipes)
src.title = title
src.recipes = recipes
src.recipes = recipes
+2 -2
View File
@@ -346,7 +346,7 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
clean_blood()//blood overlays get weird otherwise, because the sprite changes.
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
@@ -881,4 +881,4 @@
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
user.client.pixel_y = 0
+9 -9
View File
@@ -317,7 +317,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
. = O.clean_blood()
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -328,7 +328,7 @@
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
tile.clean_blood()
SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
for(var/obj/effect/E in tile)
if(is_cleanable(E))
@@ -336,7 +336,7 @@
/obj/machinery/shower/proc/wash_mob(mob/living/L)
L.clean_blood()
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
L.wash_cream()
L.ExtinguishMob()
L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily
@@ -381,7 +381,7 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
H.clean_blood()
SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -398,9 +398,9 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
M.clean_blood()
SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else
L.clean_blood()
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -498,7 +498,7 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
user.clean_blood()
SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -554,7 +554,7 @@
busy = FALSE
return 1
busy = FALSE
O.clean_blood()
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
@@ -675,4 +675,4 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
playsound(loc, 'sound/items/welder.ogg', 80, 1)
+1 -1
View File
@@ -250,7 +250,7 @@
for(var/mob/living/simple_animal/slime/M in src)
M.apply_water()
clean_blood()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)