mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-08 05:34:30 +01:00
201592f6bd
Refactoring the entire destroy proc path from Mob Human all the way down to Atom while trying to find the causes for the damn mob human hard deletes. This PR comprehensively reorganizes every single stray snowflake var used by /atom/ all the way to /mob/living/carbon/human, and makes sure that every var that COULD store a reference, is now cleared during the entirety of the Mob Destroy() parent hierarchy. This may very well be the end of the lag war. In total, I've hunted down and cleared 39 hanging references between /atom and /mob/living/carbon/human --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com>
312 lines
11 KiB
Plaintext
312 lines
11 KiB
Plaintext
/obj/item/clothing/gloves
|
|
var/transfer_blood = 0
|
|
var/datum/weakref/bloody_hands_mob
|
|
|
|
/obj/item/clothing/shoes/
|
|
var/track_footprint = 0
|
|
|
|
/obj/item/reagent_containers/glass/rag
|
|
name = "rag"
|
|
desc = "For cleaning up messes, you suppose."
|
|
w_class = WEIGHT_CLASS_TINY
|
|
icon = 'icons/obj/janitor.dmi'
|
|
icon_state = "rag"
|
|
amount_per_transfer_from_this = 5
|
|
possible_transfer_amounts = list(5)
|
|
volume = 10
|
|
can_be_placed_into = null
|
|
atom_flags = ATOM_FLAG_OPEN_CONTAINER
|
|
item_flags = ITEM_FLAG_NO_BLUDGEON
|
|
unacidable = FALSE
|
|
fragile = FALSE
|
|
drop_sound = SFX_CLOTH_DROP
|
|
pickup_sound = SFX_CLOTH_PICKUP
|
|
|
|
var/on_fire = 0
|
|
var/burn_time = 20 //if the rag burns for too long it turns to ashes
|
|
var/cleantime = 30
|
|
var/last_clean
|
|
var/clean_msg = FALSE
|
|
|
|
/obj/item/reagent_containers/glass/rag/Initialize()
|
|
. = ..()
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/Destroy()
|
|
STOP_PROCESSING(SSprocessing, src) //so we don't continue turning to ash while gc'd
|
|
return ..()
|
|
|
|
/obj/item/reagent_containers/glass/rag/attack_self(mob/user)
|
|
if(on_fire)
|
|
user.visible_message(SPAN_WARNING("\The [user] stamps out \the [src]."), SPAN_WARNING("You stamp out \the [src]."))
|
|
user.unEquip(src)
|
|
extinguish()
|
|
else
|
|
remove_contents(user)
|
|
|
|
/obj/item/reagent_containers/glass/rag/attackby(obj/item/attacking_item, mob/user)
|
|
if(!on_fire && attacking_item.isFlameSource())
|
|
ignite()
|
|
if(on_fire)
|
|
visible_message(SPAN_WARNING("\The [user] lights \the [src] with \the [attacking_item]."))
|
|
else
|
|
to_chat(user, SPAN_WARNING("You manage to singe \the [src], but fail to light it."))
|
|
return TRUE
|
|
. = ..()
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/proc/update_name(var/base_name = initial(name))
|
|
SEND_SIGNAL(src, COMSIG_BASENAME_SETNAME, args)
|
|
if(on_fire)
|
|
name = "burning [base_name]"
|
|
else if(reagents.total_volume)
|
|
name = "damp [base_name]"
|
|
else
|
|
name = "dry [base_name]"
|
|
|
|
/obj/item/reagent_containers/glass/rag/update_icon()
|
|
if(on_fire)
|
|
icon_state = "[initial(icon_state)]_lit"
|
|
else if(reagents.total_volume)
|
|
icon_state = "[initial(icon_state)]_wet"
|
|
else
|
|
icon_state = "[initial(icon_state)]"
|
|
|
|
var/obj/item/reagent_containers/food/drinks/bottle/B = loc
|
|
if(istype(B))
|
|
B.update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/on_reagent_change()
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/proc/remove_contents(mob/user, atom/trans_dest = null)
|
|
if(!trans_dest && !user.loc)
|
|
return
|
|
|
|
if(reagents.total_volume)
|
|
var/target_text = trans_dest? "\the [trans_dest]" : "\the [user.loc]"
|
|
user.visible_message(SPAN_DANGER("\The [user] begins to wring out \the [src] over \the [target_text]."), SPAN_NOTICE("You begin to wring out \the [src] over \the [target_text]."))
|
|
|
|
if(do_after(user, reagents.total_volume*5)) //50 for a fully soaked rag
|
|
if(trans_dest)
|
|
reagents.trans_to(trans_dest, reagents.total_volume)
|
|
else
|
|
reagents.splash(user.loc, reagents.total_volume)
|
|
user.visible_message(SPAN_DANGER("\The [user] wrings out \the [src] over \the [target_text]."), SPAN_NOTICE("You finish wringing out \the [src]."))
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/proc/wipe_down(atom/A, mob/user)
|
|
if(!reagents.total_volume)
|
|
to_chat(user, SPAN_WARNING("\The [name] is dry!"))
|
|
else
|
|
if (!(last_clean && world.time < last_clean + 120) )
|
|
user.visible_message("<b>[user]</b> starts to wipe [A] with [src].")
|
|
clean_msg = TRUE
|
|
last_clean = world.time
|
|
else
|
|
clean_msg = FALSE
|
|
playsound(loc, 'sound/effects/mop.ogg', 25, 1)
|
|
update_name()
|
|
update_icon()
|
|
if(do_after(user,cleantime))
|
|
if(clean_msg)
|
|
user.visible_message("<b>[user]</b> finishes wiping [A].")
|
|
A.on_rag_wipe(src)
|
|
|
|
/obj/item/reagent_containers/glass/rag/attack(mob/living/target_mob, mob/living/user, target_zone)
|
|
if(isliving(target_mob))
|
|
var/mob/living/M = target_mob
|
|
if(on_fire)
|
|
user.visible_message(SPAN_DANGER("\The [user] hits \the [target_mob] with \the [src]!"))
|
|
user.do_attack_animation(src)
|
|
M.IgniteMob()
|
|
else if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
|
if(LAZYLEN(affecting.wounds))
|
|
for (var/datum/wound/W in affecting.wounds)
|
|
if(W.bandaged || W.clamped)
|
|
continue
|
|
to_chat(user, SPAN_NOTICE("You begin to bandage \a [W.desc] on [M]'s [affecting.name] with a rag."))
|
|
if(!do_mob(user, M, W.damage/10)) // takes twice as long as a normal bandage
|
|
to_chat(user, SPAN_NOTICE("You must stand still to bandage wounds."))
|
|
return
|
|
for(var/_R in reagents.reagent_volumes)
|
|
var/singleton/reagent/R = GET_SINGLETON(_R)
|
|
var/strength = R.germ_adjust * reagents.reagent_volumes[_R]/4
|
|
if(ispath(_R, /singleton/reagent/alcohol/ethanol))
|
|
var/singleton/reagent/alcohol/ethanol/A = R
|
|
strength = strength * (A.strength/100)
|
|
W.germ_level -= min(strength, W.germ_level)//Clean the wound a bit.
|
|
if (W.germ_level <= 0)
|
|
W.disinfected = TRUE//The wound becomes disinfected if fully cleaned
|
|
break
|
|
reagents.trans_to_mob(H, reagents.total_volume*0.75, CHEM_TOUCH) // most of it gets on the skin
|
|
reagents.trans_to_mob(H, reagents.total_volume*0.25, CHEM_BLOOD) // some gets in the wound
|
|
user.visible_message(SPAN_NOTICE("\The [user] bandages \a [W.desc] on [M]'s [affecting.name] with [src], tying it in place."), \
|
|
SPAN_NOTICE("You bandage \a [W.desc] on [M]'s [affecting.name] with [src], tying it in place."))
|
|
W.bandage()
|
|
qdel(src) // the rag is used up, it'll be all bloody and useless after
|
|
return // we can only do one at a time
|
|
else if(reagents.total_volume)
|
|
if(user.zone_sel.selecting == BP_MOUTH && !(M.wear_mask && M.wear_mask.item_flags & ITEM_FLAG_AIRTIGHT))
|
|
user.do_attack_animation(src)
|
|
user.visible_message(
|
|
SPAN_DANGER("\The [user] smothers [target_mob] with [src]!"),
|
|
SPAN_WARNING("You smother [target_mob] with [src]!"),
|
|
"You hear some struggling and muffled cries of surprise."
|
|
)
|
|
|
|
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now
|
|
//^HA HA HA
|
|
reagents.trans_to_mob(target_mob, amount_per_transfer_from_this, CHEM_BREATHE)
|
|
update_name()
|
|
update_icon()
|
|
else
|
|
wipe_down(target_mob, user)
|
|
return
|
|
|
|
return ..()
|
|
|
|
/obj/item/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity)
|
|
if(!proximity)
|
|
return
|
|
|
|
if(istype(A, /obj/structure/sink))
|
|
return
|
|
|
|
else if(istype(A, /obj/structure/reagent_dispensers) || istype(A, /obj/structure/mopbucket) || istype(A, /obj/item/reagent_containers/glass))
|
|
if(!REAGENTS_FREE_SPACE(reagents))
|
|
to_chat(user, SPAN_WARNING("\The [src] is already soaked."))
|
|
return
|
|
|
|
if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume))
|
|
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
|
user.visible_message(SPAN_NOTICE("\The [user] soaks \the [src] using \the [A]."), SPAN_NOTICE("You soak \the [src] using \the [A]."))
|
|
update_name()
|
|
update_icon()
|
|
return
|
|
|
|
else if(!on_fire && istype(A) && (src in user))
|
|
if(A.is_open_container() && !(A in user))
|
|
remove_contents(user, A)
|
|
else if(!ismob(A)) //mobs are handled in attack() - this prevents us from wiping down people while smothering them.
|
|
wipe_down(A, user)
|
|
return
|
|
|
|
/obj/item/reagent_containers/glass/rag/fire_act(exposed_temperature, exposed_volume)
|
|
. = ..()
|
|
|
|
if(exposed_temperature >= 50 + T0C)
|
|
ignite()
|
|
if(exposed_temperature >= 900 + T0C)
|
|
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
|
qdel(src)
|
|
|
|
//rag must have a minimum of 2 units fuel and at least 80% of the reagents must be fuel.
|
|
//maybe generalize flammable reagents someday
|
|
/obj/item/reagent_containers/glass/rag/proc/can_ignite()
|
|
var/fuel = 0
|
|
for(var/fuel_type in reagents.reagent_volumes)
|
|
if(ispath(fuel_type, /singleton/reagent/fuel) || ispath(fuel_type, /singleton/reagent/alcohol))
|
|
fuel += reagents.reagent_volumes[fuel_type]
|
|
return (fuel >= 2 && fuel >= reagents.total_volume*0.8)
|
|
|
|
/obj/item/reagent_containers/glass/rag/proc/ignite()
|
|
if(on_fire)
|
|
return
|
|
if(!can_ignite())
|
|
return
|
|
|
|
//also copied from matches
|
|
if(REAGENT_VOLUME(reagents, /singleton/reagent/toxin/phoron)) // the phoron explodes when exposed to fire
|
|
visible_message(SPAN_DANGER("\The [src] conflagrates violently!"))
|
|
var/datum/effect/effect/system/reagents_explosion/e = new()
|
|
e.set_up(round(REAGENT_VOLUME(reagents, /singleton/reagent/toxin/phoron) / 2.5, 1), get_turf(src), 0, 0)
|
|
e.start()
|
|
qdel(src)
|
|
return
|
|
|
|
START_PROCESSING(SSprocessing, src)
|
|
set_light(2, null, "#E38F46")
|
|
on_fire = 1
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/proc/extinguish()
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
set_light(0)
|
|
on_fire = 0
|
|
|
|
//rags sitting around with 1 second of burn time left is dumb.
|
|
//ensures players always have a few seconds of burn time left when they light their rag
|
|
if(burn_time <= 5)
|
|
visible_message(SPAN_WARNING("\The [src] falls apart!"))
|
|
if(istype(loc, /obj/item/reagent_containers/food/drinks/bottle))
|
|
var/obj/item/reagent_containers/food/drinks/bottle/B = loc
|
|
B.delete_rag()
|
|
else
|
|
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
|
qdel(src)
|
|
return
|
|
update_name()
|
|
update_icon()
|
|
|
|
/obj/item/reagent_containers/glass/rag/process(seconds_per_tick)
|
|
if(!can_ignite())
|
|
visible_message(SPAN_WARNING("\The [src] burns out."))
|
|
extinguish()
|
|
|
|
//copied from matches
|
|
if(isliving(loc))
|
|
var/mob/living/M = loc
|
|
M.IgniteMob()
|
|
var/turf/location = get_turf(src)
|
|
if(location)
|
|
location.hotspot_expose(700, 5)
|
|
|
|
if(burn_time <= 0)
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
if(istype(loc, /obj/item/reagent_containers/food/drinks/bottle))
|
|
var/obj/item/reagent_containers/food/drinks/bottle/B = loc
|
|
B.delete_rag()
|
|
else
|
|
new /obj/effect/decal/cleanable/ash(location)
|
|
qdel(src)
|
|
return
|
|
|
|
for(var/fuel_type in reagents.reagent_volumes)
|
|
if(ispath(fuel_type, /singleton/reagent/fuel) || ispath(fuel_type, /singleton/reagent/alcohol))
|
|
reagents.remove_reagent(fuel_type, ((reagents.maximum_volume/25) * seconds_per_tick))
|
|
break
|
|
update_name()
|
|
update_icon()
|
|
burn_time -= seconds_per_tick
|
|
|
|
/obj/item/reagent_containers/glass/rag/advanced
|
|
name = "microfiber cloth"
|
|
desc = "A synthetic fiber cloth; the split fibers and the size of the individual filaments make it more effective for cleaning purposes."
|
|
w_class = WEIGHT_CLASS_TINY
|
|
icon = 'icons/obj/janitor.dmi'
|
|
icon_state = "advrag"
|
|
amount_per_transfer_from_this = 10
|
|
possible_transfer_amounts = list(5)
|
|
volume = 10
|
|
cleantime = 15
|
|
|
|
/obj/item/reagent_containers/glass/rag/advanced/idris
|
|
name = "Idris advanced service cloth"
|
|
desc = "An advanced rag developed and sold by Idris Incorporated at a steep price. Its dry-clean design and advanced insulating synthetic weave make this the pinnacle of service cloths for any self-respecting chef or bartender!"
|
|
icon_state = "idrisrag"
|
|
volume = 15
|
|
|
|
/obj/item/reagent_containers/glass/rag/handkerchief
|
|
name = "handkerchief"
|
|
desc = "For cleaning a lady's hand, your bruised ego or a crime scene."
|
|
volume = 5
|
|
icon_state = "handkerchief"
|