mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
About The Pull Request
Adds a skillchip to the chef's vendor. This vendor allows the chef to kiss their food to deliver a chef's kiss.
Chef's kissing your food will add the "love" reagent to the food, which makes people much happier when they eat it. Be careful, overdosing on love can cause heart attacks.
Refactors microwaving.
Separates microwaving out of the edible component and makes it its own element, like grillable and bakeable.
Also removes some magic numbers from microwave code.
Code improvements all around baking and grilling code.
Refactors edible component inheritance.
Inheriting the edible component is now a viable way to cleanly add food types, flags, and callbacks. This makes it much much easier to change the values of an edible item without adding hacky signals / procs / getcomponent.
Why It's Good For The Game
Emergent chef gameplay.
Being able to further enhance your food with mood buffs.
Better code.
Changelog
cl Melbert
add: Chefs can now make food with love. They can purchase a skillchip from their vendor which enhances their kiss emote. Using your kiss on food you create will add a special reagent to it which makes it nicer.
refactor: Separated Microwavable from the Edible component, refactored microwave act to accompany this
refactor: Refactored how grilled items are generated
refactor: Refactored how silver slime food items are generated
refactor: Refactored how edible items inherit new edible statuses
code: Removed some magic numbers from microwaves
code: General code improvements for grillable / bakeable / etc
/cl
1055 lines
34 KiB
Plaintext
1055 lines
34 KiB
Plaintext
/atom/movable/screen/alert/status_effect/rainbow_protection
|
|
name = "Rainbow Protection"
|
|
desc = "You are defended from harm, but so are those you might seek to injure!"
|
|
icon_state = "slime_rainbowshield"
|
|
|
|
/datum/status_effect/rainbow_protection
|
|
id = "rainbow_protection"
|
|
duration = 100
|
|
alert_type = /atom/movable/screen/alert/status_effect/rainbow_protection
|
|
var/originalcolor
|
|
|
|
/datum/status_effect/rainbow_protection/on_apply()
|
|
owner.status_flags |= GODMODE
|
|
ADD_TRAIT(owner, TRAIT_PACIFISM, /datum/status_effect/rainbow_protection)
|
|
owner.visible_message(span_warning("[owner] shines with a brilliant rainbow light."),
|
|
span_notice("You feel protected by an unknown force!"))
|
|
originalcolor = owner.color
|
|
return ..()
|
|
|
|
/datum/status_effect/rainbow_protection/tick()
|
|
owner.color = rgb(rand(0,255),rand(0,255),rand(0,255))
|
|
return ..()
|
|
|
|
/datum/status_effect/rainbow_protection/on_remove()
|
|
owner.status_flags &= ~GODMODE
|
|
owner.color = originalcolor
|
|
REMOVE_TRAIT(owner, TRAIT_PACIFISM, /datum/status_effect/rainbow_protection)
|
|
owner.visible_message(span_notice("[owner] stops glowing, the rainbow light fading away."),
|
|
span_warning("You no longer feel protected..."))
|
|
|
|
/atom/movable/screen/alert/status_effect/slimeskin
|
|
name = "Adamantine Slimeskin"
|
|
desc = "You are covered in a thick, non-neutonian gel."
|
|
icon_state = "slime_stoneskin"
|
|
|
|
/datum/status_effect/slimeskin
|
|
id = "slimeskin"
|
|
duration = 300
|
|
alert_type = /atom/movable/screen/alert/status_effect/slimeskin
|
|
var/originalcolor
|
|
|
|
/datum/status_effect/slimeskin/on_apply()
|
|
originalcolor = owner.color
|
|
owner.color = "#3070CC"
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.damage_resistance += 10
|
|
owner.visible_message(span_warning("[owner] is suddenly covered in a strange, blue-ish gel!"),
|
|
span_notice("You are covered in a thick, rubbery gel."))
|
|
return ..()
|
|
|
|
/datum/status_effect/slimeskin/on_remove()
|
|
owner.color = originalcolor
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.damage_resistance -= 10
|
|
owner.visible_message(span_warning("[owner]'s gel coating liquefies and dissolves away."),
|
|
span_notice("Your gel second-skin dissolves!"))
|
|
|
|
/datum/status_effect/slimerecall
|
|
id = "slime_recall"
|
|
duration = -1 //Will be removed by the extract.
|
|
tick_interval = -1
|
|
alert_type = null
|
|
var/interrupted = FALSE
|
|
var/mob/target
|
|
var/icon/bluespace
|
|
|
|
/datum/status_effect/slimerecall/on_apply()
|
|
RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/resistField)
|
|
to_chat(owner, span_danger("You feel a sudden tug from an unknown force, and feel a pull to bluespace!"))
|
|
to_chat(owner, span_notice("Resist if you wish avoid the force!"))
|
|
bluespace = icon('icons/effects/effects.dmi',"chronofield")
|
|
owner.add_overlay(bluespace)
|
|
return ..()
|
|
|
|
/datum/status_effect/slimerecall/proc/resistField()
|
|
SIGNAL_HANDLER
|
|
interrupted = TRUE
|
|
owner.remove_status_effect(src)
|
|
|
|
/datum/status_effect/slimerecall/on_remove()
|
|
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
|
|
owner.cut_overlay(bluespace)
|
|
if(interrupted || !ismob(target))
|
|
to_chat(owner, span_warning("The bluespace tug fades away, and you feel that the force has passed you by."))
|
|
return
|
|
var/turf/old_location = get_turf(owner)
|
|
if(do_teleport(owner, target.loc, channel = TELEPORT_CHANNEL_QUANTUM)) //despite being named a bluespace teleportation method the quantum channel is used to preserve precision teleporting with a bag of holding
|
|
old_location.visible_message(span_warning("[owner] disappears in a flurry of sparks!"))
|
|
to_chat(owner, span_warning("The unknown force snatches briefly you from reality, and deposits you next to [target]!"))
|
|
|
|
/atom/movable/screen/alert/status_effect/freon/stasis
|
|
desc = "You're frozen inside of a protective ice cube! While inside, you can't do anything, but are immune to harm! Resist to get out."
|
|
|
|
/datum/status_effect/frozenstasis
|
|
id = "slime_frozen"
|
|
status_type = STATUS_EFFECT_UNIQUE
|
|
duration = -1 //Will remove self when block breaks.
|
|
alert_type = /atom/movable/screen/alert/status_effect/freon/stasis
|
|
var/obj/structure/ice_stasis/cube
|
|
|
|
/datum/status_effect/frozenstasis/on_apply()
|
|
RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/breakCube)
|
|
cube = new /obj/structure/ice_stasis(get_turf(owner))
|
|
owner.forceMove(cube)
|
|
owner.status_flags |= GODMODE
|
|
return ..()
|
|
|
|
/datum/status_effect/frozenstasis/tick()
|
|
if(!cube || owner.loc != cube)
|
|
owner.remove_status_effect(src)
|
|
|
|
/datum/status_effect/frozenstasis/proc/breakCube()
|
|
SIGNAL_HANDLER
|
|
|
|
owner.remove_status_effect(src)
|
|
|
|
/datum/status_effect/frozenstasis/on_remove()
|
|
if(cube)
|
|
qdel(cube)
|
|
owner.status_flags &= ~GODMODE
|
|
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
|
|
|
|
/datum/status_effect/slime_clone
|
|
id = "slime_cloned"
|
|
status_type = STATUS_EFFECT_UNIQUE
|
|
duration = -1
|
|
alert_type = null
|
|
var/mob/living/clone
|
|
var/datum/mind/originalmind //For when the clone gibs.
|
|
|
|
/datum/status_effect/slime_clone/on_apply()
|
|
var/typepath = owner.type
|
|
clone = new typepath(owner.loc)
|
|
var/mob/living/carbon/O = owner
|
|
var/mob/living/carbon/C = clone
|
|
if(istype(C) && istype(O))
|
|
C.real_name = O.real_name
|
|
O.dna.transfer_identity(C)
|
|
C.updateappearance(mutcolor_update=1)
|
|
if(owner.mind)
|
|
originalmind = owner.mind
|
|
owner.mind.transfer_to(clone)
|
|
clone.apply_status_effect(/datum/status_effect/slime_clone_decay)
|
|
return ..()
|
|
|
|
/datum/status_effect/slime_clone/tick()
|
|
if(!istype(clone) || clone.stat != CONSCIOUS)
|
|
owner.remove_status_effect(src)
|
|
|
|
/datum/status_effect/slime_clone/on_remove()
|
|
if(clone?.mind && owner)
|
|
clone.mind.transfer_to(owner)
|
|
else
|
|
if(owner && originalmind)
|
|
originalmind.transfer_to(owner)
|
|
if(originalmind.key)
|
|
owner.ckey = originalmind.key
|
|
if(clone)
|
|
clone.unequip_everything()
|
|
qdel(clone)
|
|
|
|
/atom/movable/screen/alert/status_effect/clone_decay
|
|
name = "Clone Decay"
|
|
desc = "You are simply a construct, and cannot maintain this form forever. You will be returned to your original body if you should fall."
|
|
icon_state = "slime_clonedecay"
|
|
|
|
/datum/status_effect/slime_clone_decay
|
|
id = "slime_clonedecay"
|
|
status_type = STATUS_EFFECT_UNIQUE
|
|
duration = -1
|
|
alert_type = /atom/movable/screen/alert/status_effect/clone_decay
|
|
|
|
/datum/status_effect/slime_clone_decay/tick()
|
|
owner.adjustToxLoss(1, 0)
|
|
owner.adjustOxyLoss(1, 0)
|
|
owner.adjustBruteLoss(1, 0)
|
|
owner.adjustFireLoss(1, 0)
|
|
owner.color = "#007BA7"
|
|
|
|
/atom/movable/screen/alert/status_effect/bloodchill
|
|
name = "Bloodchilled"
|
|
desc = "You feel a shiver down your spine after getting hit with a glob of cold blood. You'll move slower and get frostbite for a while!"
|
|
icon_state = "bloodchill"
|
|
|
|
/datum/status_effect/bloodchill
|
|
id = "bloodchill"
|
|
duration = 100
|
|
alert_type = /atom/movable/screen/alert/status_effect/bloodchill
|
|
|
|
/datum/status_effect/bloodchill/on_apply()
|
|
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill)
|
|
return ..()
|
|
|
|
/datum/status_effect/bloodchill/tick()
|
|
if(prob(50))
|
|
owner.adjustFireLoss(2)
|
|
|
|
/datum/status_effect/bloodchill/on_remove()
|
|
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill)
|
|
|
|
/datum/status_effect/bonechill
|
|
id = "bonechill"
|
|
duration = 80
|
|
alert_type = /atom/movable/screen/alert/status_effect/bonechill
|
|
|
|
/datum/status_effect/bonechill/on_apply()
|
|
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill)
|
|
return ..()
|
|
|
|
/datum/status_effect/bonechill/tick()
|
|
if(prob(50))
|
|
owner.adjustFireLoss(1)
|
|
owner.set_jitter_if_lower(6 SECONDS)
|
|
owner.adjust_bodytemperature(-10)
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/humi = owner
|
|
humi.adjust_coretemperature(-10)
|
|
|
|
/datum/status_effect/bonechill/on_remove()
|
|
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill)
|
|
/atom/movable/screen/alert/status_effect/bonechill
|
|
name = "Bonechilled"
|
|
desc = "You feel a shiver down your spine after hearing the haunting noise of bone rattling. You'll move slower and get frostbite for a while!"
|
|
icon_state = "bloodchill"
|
|
|
|
/datum/status_effect/rebreathing
|
|
id = "rebreathing"
|
|
duration = -1
|
|
alert_type = null
|
|
|
|
/datum/status_effect/rebreathing/tick()
|
|
owner.adjustOxyLoss(-6, 0) //Just a bit more than normal breathing.
|
|
|
|
///////////////////////////////////////////////////////
|
|
//////////////////CONSUMING EXTRACTS///////////////////
|
|
///////////////////////////////////////////////////////
|
|
|
|
/datum/status_effect/firecookie
|
|
id = "firecookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/firecookie/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_RESISTCOLD,"firecookie")
|
|
owner.adjust_bodytemperature(110)
|
|
return ..()
|
|
|
|
/datum/status_effect/firecookie/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_RESISTCOLD,"firecookie")
|
|
|
|
/datum/status_effect/watercookie
|
|
id = "watercookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/watercookie/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie")
|
|
return ..()
|
|
|
|
/datum/status_effect/watercookie/tick()
|
|
for(var/turf/open/T in range(get_turf(owner),1))
|
|
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
|
|
|
|
/datum/status_effect/watercookie/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie")
|
|
|
|
/datum/status_effect/metalcookie
|
|
id = "metalcookie"
|
|
status_type = STATUS_EFFECT_REFRESH
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/metalcookie/on_apply()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.brute_mod *= 0.9
|
|
return ..()
|
|
|
|
/datum/status_effect/metalcookie/on_remove()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.brute_mod /= 0.9
|
|
|
|
/datum/status_effect/sparkcookie
|
|
id = "sparkcookie"
|
|
status_type = STATUS_EFFECT_REFRESH
|
|
alert_type = null
|
|
duration = 300
|
|
var/original_coeff
|
|
|
|
/datum/status_effect/sparkcookie/on_apply()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
original_coeff = H.physiology.siemens_coeff
|
|
H.physiology.siemens_coeff = 0
|
|
return ..()
|
|
|
|
/datum/status_effect/sparkcookie/on_remove()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.siemens_coeff = original_coeff
|
|
|
|
/datum/status_effect/toxincookie
|
|
id = "toxincookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 600
|
|
|
|
/datum/status_effect/toxincookie/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_TOXINLOVER,"toxincookie")
|
|
return ..()
|
|
|
|
/datum/status_effect/toxincookie/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_TOXINLOVER,"toxincookie")
|
|
|
|
/datum/status_effect/timecookie
|
|
id = "timecookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 600
|
|
|
|
/datum/status_effect/timecookie/on_apply()
|
|
owner.add_actionspeed_modifier(/datum/actionspeed_modifier/timecookie)
|
|
return ..()
|
|
|
|
/datum/status_effect/timecookie/on_remove()
|
|
owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/timecookie)
|
|
return ..()
|
|
|
|
/datum/status_effect/lovecookie
|
|
id = "lovecookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 300
|
|
|
|
/datum/status_effect/lovecookie/tick()
|
|
if(owner.stat != CONSCIOUS)
|
|
return
|
|
if(iscarbon(owner))
|
|
var/mob/living/carbon/C = owner
|
|
if(C.handcuffed)
|
|
return
|
|
var/list/huggables = list()
|
|
for(var/mob/living/carbon/L in range(get_turf(owner),1))
|
|
if(L != owner)
|
|
huggables += L
|
|
if(length(huggables))
|
|
var/mob/living/carbon/hugged = pick(huggables)
|
|
owner.visible_message(span_notice("[owner] hugs [hugged]!"), span_notice("You hug [hugged]!"))
|
|
|
|
/datum/status_effect/tarcookie
|
|
id = "tarcookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/tarcookie/tick()
|
|
for(var/mob/living/carbon/human/L in range(get_turf(owner),1))
|
|
if(L != owner)
|
|
L.apply_status_effect(/datum/status_effect/tarfoot)
|
|
|
|
/datum/status_effect/tarfoot
|
|
id = "tarfoot"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 30
|
|
|
|
/datum/status_effect/tarfoot/on_apply()
|
|
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot)
|
|
return ..()
|
|
|
|
/datum/status_effect/tarfoot/on_remove()
|
|
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot)
|
|
|
|
/datum/status_effect/spookcookie
|
|
id = "spookcookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 300
|
|
|
|
/datum/status_effect/spookcookie/on_apply()
|
|
var/image/I = image(icon = 'icons/mob/simple/simple_human.dmi', icon_state = "skeleton", layer = ABOVE_MOB_LAYER, loc = owner)
|
|
I.override = 1
|
|
owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "spookyscary", I)
|
|
return ..()
|
|
|
|
/datum/status_effect/spookcookie/on_remove()
|
|
owner.remove_alt_appearance("spookyscary")
|
|
|
|
/datum/status_effect/peacecookie
|
|
id = "peacecookie"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/peacecookie/tick()
|
|
for(var/mob/living/L in range(get_turf(owner),1))
|
|
L.apply_status_effect(/datum/status_effect/plur)
|
|
|
|
/datum/status_effect/plur
|
|
id = "plur"
|
|
status_type = STATUS_EFFECT_REPLACE
|
|
alert_type = null
|
|
duration = 30
|
|
|
|
/datum/status_effect/plur/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_PACIFISM, "peacecookie")
|
|
return ..()
|
|
|
|
/datum/status_effect/plur/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "peacecookie")
|
|
|
|
/datum/status_effect/adamantinecookie
|
|
id = "adamantinecookie"
|
|
status_type = STATUS_EFFECT_REFRESH
|
|
alert_type = null
|
|
duration = 100
|
|
|
|
/datum/status_effect/adamantinecookie/on_apply()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.burn_mod *= 0.9
|
|
return ..()
|
|
|
|
/datum/status_effect/adamantinecookie/on_remove()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.burn_mod /= 0.9
|
|
|
|
///////////////////////////////////////////////////////
|
|
//////////////////STABILIZED EXTRACTS//////////////////
|
|
///////////////////////////////////////////////////////
|
|
|
|
/datum/status_effect/stabilized //The base stabilized extract effect, has no effect of its' own.
|
|
id = "stabilizedbase"
|
|
duration = -1
|
|
alert_type = null
|
|
var/obj/item/slimecross/stabilized/linked_extract
|
|
var/colour = "null"
|
|
|
|
/datum/status_effect/stabilized/proc/location_check()
|
|
if(linked_extract.loc == owner)
|
|
return TRUE
|
|
if(linked_extract.loc.loc == owner)
|
|
return TRUE
|
|
for(var/atom/storage_loc as anything in get_storage_locs(linked_extract))
|
|
if(storage_loc == owner)
|
|
return TRUE
|
|
if(storage_loc.loc == owner)
|
|
return TRUE
|
|
for(var/atom/storage_loc_storage_loc as anything in get_storage_locs(storage_loc))
|
|
if(storage_loc_storage_loc == owner)
|
|
return TRUE
|
|
for(var/atom/loc_storage_loc as anything in get_storage_locs(linked_extract.loc))
|
|
if(loc_storage_loc == owner)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/status_effect/stabilized/tick()
|
|
if(!linked_extract || !linked_extract.loc) //Sanity checking
|
|
qdel(src)
|
|
return
|
|
if(linked_extract && !location_check())
|
|
linked_extract.linked_effect = null
|
|
if(!QDELETED(linked_extract))
|
|
linked_extract.owner = null
|
|
START_PROCESSING(SSobj,linked_extract)
|
|
qdel(src)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/null //This shouldn't ever happen, but just in case.
|
|
id = "stabilizednull"
|
|
|
|
|
|
//Stabilized effects start below.
|
|
/datum/status_effect/stabilized/grey
|
|
id = "stabilizedgrey"
|
|
colour = "grey"
|
|
|
|
/datum/status_effect/stabilized/grey/tick()
|
|
for(var/mob/living/simple_animal/slime/S in range(1, get_turf(owner)))
|
|
if(!(owner in S.Friends))
|
|
to_chat(owner, span_notice("[linked_extract] pulses gently as it communicates with [S]."))
|
|
S.set_friendship(owner, 1)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/orange
|
|
id = "stabilizedorange"
|
|
colour = "orange"
|
|
|
|
/datum/status_effect/stabilized/orange/tick()
|
|
var/body_temperature_difference = owner.get_body_temp_normal(apply_change=FALSE) - owner.bodytemperature
|
|
owner.adjust_bodytemperature(min(5, body_temperature_difference))
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/humi = owner
|
|
humi.adjust_coretemperature(min(5, humi.get_body_temp_normal(apply_change=FALSE) - humi.coretemperature))
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/purple
|
|
id = "stabilizedpurple"
|
|
colour = "purple"
|
|
/// Whether we healed from our last tick
|
|
var/healed_last_tick = FALSE
|
|
|
|
/datum/status_effect/stabilized/purple/tick()
|
|
healed_last_tick = FALSE
|
|
|
|
if(owner.getBruteLoss() > 0)
|
|
owner.adjustBruteLoss(-0.2)
|
|
healed_last_tick = TRUE
|
|
|
|
if(owner.getFireLoss() > 0)
|
|
owner.adjustFireLoss(-0.2)
|
|
healed_last_tick = TRUE
|
|
|
|
if(owner.getToxLoss() > 0)
|
|
// Forced, so slimepeople are healed as well.
|
|
owner.adjustToxLoss(-0.2, forced = TRUE)
|
|
healed_last_tick = TRUE
|
|
|
|
// Technically, "healed this tick" by now.
|
|
if(healed_last_tick)
|
|
new /obj/effect/temp_visual/heal(get_turf(owner), "#FF0000")
|
|
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/purple/get_examine_text()
|
|
if(healed_last_tick)
|
|
return span_warning("[owner.p_they(TRUE)] [owner.p_are()] regenerating slowly, purplish goo filling in small injuries!")
|
|
|
|
return null
|
|
|
|
/datum/status_effect/stabilized/blue
|
|
id = "stabilizedblue"
|
|
colour = "blue"
|
|
|
|
/datum/status_effect/stabilized/blue/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus")
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/blue/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus")
|
|
|
|
/datum/status_effect/stabilized/metal
|
|
id = "stabilizedmetal"
|
|
colour = "metal"
|
|
var/cooldown = 30
|
|
var/max_cooldown = 30
|
|
|
|
/datum/status_effect/stabilized/metal/tick()
|
|
if(cooldown > 0)
|
|
cooldown--
|
|
else
|
|
cooldown = max_cooldown
|
|
var/list/sheets = list()
|
|
for(var/obj/item/stack/sheet/S in owner.get_all_contents())
|
|
if(S.amount < S.max_amount)
|
|
sheets += S
|
|
|
|
if(sheets.len > 0)
|
|
var/obj/item/stack/sheet/S = pick(sheets)
|
|
S.amount++
|
|
S.update_custom_materials()
|
|
to_chat(owner, span_notice("[linked_extract] adds a layer of slime to [S], which metamorphosizes into another sheet of material!"))
|
|
return ..()
|
|
|
|
|
|
/datum/status_effect/stabilized/yellow
|
|
id = "stabilizedyellow"
|
|
colour = "yellow"
|
|
var/cooldown = 10
|
|
var/max_cooldown = 10
|
|
|
|
/datum/status_effect/stabilized/yellow/get_examine_text()
|
|
return span_warning("Nearby electronics seem just a little more charged wherever [owner.p_they()] go[owner.p_es()].")
|
|
|
|
/datum/status_effect/stabilized/yellow/tick()
|
|
if(cooldown > 0)
|
|
cooldown--
|
|
return ..()
|
|
cooldown = max_cooldown
|
|
var/list/batteries = list()
|
|
for(var/obj/item/stock_parts/cell/C in owner.get_all_contents())
|
|
if(C.charge < C.maxcharge)
|
|
batteries += C
|
|
if(batteries.len)
|
|
var/obj/item/stock_parts/cell/ToCharge = pick(batteries)
|
|
ToCharge.charge += min(ToCharge.maxcharge - ToCharge.charge, ToCharge.maxcharge/10) //10% of the cell, or to maximum.
|
|
to_chat(owner, span_notice("[linked_extract] discharges some energy into a device you have."))
|
|
return ..()
|
|
|
|
/obj/item/hothands
|
|
name = "burning fingertips"
|
|
desc = "You shouldn't see this."
|
|
|
|
/obj/item/hothands/get_temperature()
|
|
return 290 //Below what's required to ignite plasma.
|
|
|
|
/datum/status_effect/stabilized/darkpurple
|
|
id = "stabilizeddarkpurple"
|
|
colour = "dark purple"
|
|
var/obj/item/hothands/fire
|
|
|
|
/datum/status_effect/stabilized/darkpurple/on_apply()
|
|
ADD_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus")
|
|
fire = new(owner)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/darkpurple/tick()
|
|
var/obj/item/item = owner.get_active_held_item()
|
|
if(item)
|
|
if(IS_EDIBLE(item) && (item.microwave_act(microwaver = owner) & COMPONENT_MICROWAVE_SUCCESS))
|
|
to_chat(owner, span_warning("[linked_extract] flares up brightly, and your hands alone are enough cook [item]!"))
|
|
else
|
|
item.attackby(fire, owner)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/darkpurple/on_remove()
|
|
REMOVE_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus")
|
|
qdel(fire)
|
|
|
|
/datum/status_effect/stabilized/darkpurple/get_examine_text()
|
|
return span_notice("[owner.p_their(TRUE)] fingertips burn brightly!")
|
|
|
|
/datum/status_effect/stabilized/darkblue
|
|
id = "stabilizeddarkblue"
|
|
colour = "dark blue"
|
|
|
|
/datum/status_effect/stabilized/darkblue/tick()
|
|
if(owner.fire_stacks > 0 && prob(80))
|
|
owner.adjust_wet_stacks(1)
|
|
if(owner.fire_stacks <= 0)
|
|
to_chat(owner, span_notice("[linked_extract] coats you in a watery goo, extinguishing the flames."))
|
|
var/obj/O = owner.get_active_held_item()
|
|
if(O)
|
|
O.extinguish() //All shamelessly copied from water's expose_obj, since I didn't seem to be able to get it here for some reason.
|
|
O.wash(CLEAN_TYPE_ACID)
|
|
// Monkey cube
|
|
if(istype(O, /obj/item/food/monkeycube))
|
|
to_chat(owner, span_warning("[linked_extract] kept your hands wet! It makes [O] expand!"))
|
|
var/obj/item/food/monkeycube/cube = O
|
|
cube.Expand()
|
|
|
|
// Dehydrated carp
|
|
else if(istype(O, /obj/item/toy/plush/carpplushie/dehy_carp))
|
|
to_chat(owner, span_warning("[linked_extract] kept your hands wet! It makes [O] expand!"))
|
|
var/obj/item/toy/plush/carpplushie/dehy_carp/dehy = O
|
|
dehy.Swell() // Makes a carp
|
|
|
|
else if(istype(O, /obj/item/stack/sheet/hairlesshide))
|
|
to_chat(owner, span_warning("[linked_extract] kept your hands wet! It wets [O]!"))
|
|
var/obj/item/stack/sheet/hairlesshide/HH = O
|
|
new /obj/item/stack/sheet/wethide(get_turf(HH), HH.amount)
|
|
qdel(HH)
|
|
..()
|
|
|
|
/datum/status_effect/stabilized/silver
|
|
id = "stabilizedsilver"
|
|
colour = "silver"
|
|
|
|
/datum/status_effect/stabilized/silver/on_apply()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.hunger_mod *= 0.8 //20% buff
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/silver/on_remove()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.hunger_mod /= 0.8
|
|
|
|
//Bluespace has an icon because it's kinda active.
|
|
/atom/movable/screen/alert/status_effect/bluespaceslime
|
|
name = "Stabilized Bluespace Extract"
|
|
desc = "You shouldn't see this, since we set it to change automatically!"
|
|
icon_state = "slime_bluespace_on"
|
|
|
|
/datum/status_effect/bluespacestabilization
|
|
id = "stabilizedbluespacecooldown"
|
|
duration = 1200
|
|
alert_type = null
|
|
|
|
/datum/status_effect/stabilized/bluespace
|
|
id = "stabilizedbluespace"
|
|
colour = "bluespace"
|
|
alert_type = /atom/movable/screen/alert/status_effect/bluespaceslime
|
|
var/healthcheck
|
|
|
|
/datum/status_effect/stabilized/bluespace/tick()
|
|
if(owner.has_status_effect(/datum/status_effect/bluespacestabilization))
|
|
linked_alert.desc = "The stabilized bluespace extract is still aligning you with the bluespace axis."
|
|
linked_alert.icon_state = "slime_bluespace_off"
|
|
return ..()
|
|
else
|
|
linked_alert.desc = "The stabilized bluespace extract will try to redirect you from harm!"
|
|
linked_alert.icon_state = "slime_bluespace_on"
|
|
|
|
if(healthcheck && (healthcheck - owner.health) > 5)
|
|
owner.visible_message(span_warning("[linked_extract] notices the sudden change in [owner]'s physical health, and activates!"))
|
|
do_sparks(5,FALSE,owner)
|
|
var/F = find_safe_turf(zlevels = owner.z, extended_safety_checks = TRUE)
|
|
var/range = 0
|
|
if(!F)
|
|
F = get_turf(owner)
|
|
range = 50
|
|
if(do_teleport(owner, F, range, channel = TELEPORT_CHANNEL_BLUESPACE))
|
|
to_chat(owner, span_notice("[linked_extract] will take some time to re-align you on the bluespace axis."))
|
|
do_sparks(5,FALSE,owner)
|
|
owner.apply_status_effect(/datum/status_effect/bluespacestabilization)
|
|
healthcheck = owner.health
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/sepia
|
|
id = "stabilizedsepia"
|
|
colour = "sepia"
|
|
var/mod = 0
|
|
|
|
/datum/status_effect/stabilized/sepia/tick()
|
|
if(prob(50) && mod > -1)
|
|
mod--
|
|
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = -0.5)
|
|
else if(mod < 1)
|
|
mod++
|
|
// yeah a value of 0 does nothing but replacing the trait in place is cheaper than removing and adding repeatedly
|
|
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = 0)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/sepia/on_remove()
|
|
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia)
|
|
|
|
/datum/status_effect/stabilized/cerulean
|
|
id = "stabilizedcerulean"
|
|
colour = "cerulean"
|
|
var/mob/living/clone
|
|
|
|
/datum/status_effect/stabilized/cerulean/on_apply()
|
|
var/typepath = owner.type
|
|
clone = new typepath(owner.loc)
|
|
var/mob/living/carbon/O = owner
|
|
var/mob/living/carbon/C = clone
|
|
if(istype(C) && istype(O))
|
|
C.real_name = O.real_name
|
|
O.dna.transfer_identity(C)
|
|
C.updateappearance(mutcolor_update=1)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/cerulean/tick()
|
|
if(owner.stat == DEAD)
|
|
if(clone && clone.stat != DEAD)
|
|
owner.visible_message(span_warning("[owner] blazes with brilliant light, [linked_extract] whisking [owner.p_their()] soul away."),
|
|
span_notice("You feel a warm glow from [linked_extract], and you open your eyes... elsewhere."))
|
|
if(owner.mind)
|
|
owner.mind.transfer_to(clone)
|
|
clone = null
|
|
qdel(linked_extract)
|
|
if(!clone || clone.stat == DEAD)
|
|
to_chat(owner, span_notice("[linked_extract] desperately tries to move your soul to a living body, but can't find one!"))
|
|
qdel(linked_extract)
|
|
..()
|
|
|
|
/datum/status_effect/stabilized/cerulean/on_remove()
|
|
if(clone)
|
|
clone.visible_message(span_warning("[clone] dissolves into a puddle of goo!"))
|
|
clone.unequip_everything()
|
|
qdel(clone)
|
|
|
|
/datum/status_effect/stabilized/pyrite
|
|
id = "stabilizedpyrite"
|
|
colour = "pyrite"
|
|
var/originalcolor
|
|
|
|
/datum/status_effect/stabilized/pyrite/on_apply()
|
|
originalcolor = owner.color
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/pyrite/tick()
|
|
owner.color = rgb(rand(0,255),rand(0,255),rand(0,255))
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/pyrite/on_remove()
|
|
owner.color = originalcolor
|
|
|
|
/datum/status_effect/stabilized/red
|
|
id = "stabilizedred"
|
|
colour = "red"
|
|
|
|
/datum/status_effect/stabilized/red/on_apply()
|
|
. = ..()
|
|
owner.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/equipment_speedmod)
|
|
|
|
/datum/status_effect/stabilized/red/on_remove()
|
|
owner.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/equipment_speedmod)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/green
|
|
id = "stabilizedgreen"
|
|
colour = "green"
|
|
var/datum/dna/originalDNA
|
|
var/originalname
|
|
|
|
/datum/status_effect/stabilized/green/on_apply()
|
|
to_chat(owner, span_warning("You feel different..."))
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
originalDNA = new H.dna.type
|
|
originalname = H.real_name
|
|
H.dna.copy_dna(originalDNA)
|
|
randomize_human(H)
|
|
return ..()
|
|
|
|
// Only occasionally give examiners a warning.
|
|
/datum/status_effect/stabilized/green/get_examine_text()
|
|
if(prob(50))
|
|
return span_warning("[owner.p_they(TRUE)] look[owner.p_s()] a bit green and gooey...")
|
|
|
|
return null
|
|
|
|
/datum/status_effect/stabilized/green/on_remove()
|
|
to_chat(owner, span_notice("You feel more like yourself."))
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
originalDNA.transfer_identity(H)
|
|
H.real_name = originalname
|
|
H.updateappearance(mutcolor_update=1)
|
|
|
|
/datum/status_effect/brokenpeace
|
|
id = "brokenpeace"
|
|
duration = 1200
|
|
alert_type = null
|
|
|
|
/datum/status_effect/pinkdamagetracker
|
|
id = "pinkdamagetracker"
|
|
duration = -1
|
|
alert_type = null
|
|
var/damage = 0
|
|
var/lasthealth
|
|
|
|
/datum/status_effect/pinkdamagetracker/tick()
|
|
if((lasthealth - owner.health) > 0)
|
|
damage += (lasthealth - owner.health)
|
|
lasthealth = owner.health
|
|
|
|
/datum/status_effect/stabilized/pink
|
|
id = "stabilizedpink"
|
|
colour = "pink"
|
|
var/list/mobs = list()
|
|
var/faction_name
|
|
|
|
/datum/status_effect/stabilized/pink/on_apply()
|
|
faction_name = REF(owner)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/pink/tick()
|
|
for(var/mob/living/simple_animal/M in view(7,get_turf(owner)))
|
|
if(!(M in mobs))
|
|
mobs += M
|
|
M.apply_status_effect(/datum/status_effect/pinkdamagetracker)
|
|
M.faction |= faction_name
|
|
for(var/mob/living/simple_animal/M in mobs)
|
|
if(!(M in view(7,get_turf(owner))))
|
|
M.faction -= faction_name
|
|
M.remove_status_effect(/datum/status_effect/pinkdamagetracker)
|
|
mobs -= M
|
|
var/datum/status_effect/pinkdamagetracker/C = M.has_status_effect(/datum/status_effect/pinkdamagetracker)
|
|
if(istype(C) && C.damage > 0)
|
|
C.damage = 0
|
|
owner.apply_status_effect(/datum/status_effect/brokenpeace)
|
|
var/HasFaction = FALSE
|
|
for(var/i in owner.faction)
|
|
if(i == faction_name)
|
|
HasFaction = TRUE
|
|
|
|
if(HasFaction && owner.has_status_effect(/datum/status_effect/brokenpeace))
|
|
owner.faction -= faction_name
|
|
to_chat(owner, span_userdanger("The peace has been broken! Hostile creatures will now react to you!"))
|
|
if(!HasFaction && !owner.has_status_effect(/datum/status_effect/brokenpeace))
|
|
to_chat(owner, span_notice("[linked_extract] pulses, generating a fragile aura of peace."))
|
|
owner.faction |= faction_name
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/pink/on_remove()
|
|
for(var/mob/living/simple_animal/M in mobs)
|
|
M.faction -= faction_name
|
|
M.remove_status_effect(/datum/status_effect/pinkdamagetracker)
|
|
for(var/i in owner.faction)
|
|
if(i == faction_name)
|
|
owner.faction -= faction_name
|
|
|
|
/datum/status_effect/stabilized/oil
|
|
id = "stabilizedoil"
|
|
colour = "oil"
|
|
|
|
/datum/status_effect/stabilized/oil/tick()
|
|
if(owner.stat == DEAD)
|
|
explosion(owner, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 5, explosion_cause = src)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/oil/get_examine_text()
|
|
return span_warning("[owner.p_they(TRUE)] smell[owner.p_s()] of sulfer and oil!")
|
|
|
|
/// How much damage is dealt per healing done for the stabilized back.
|
|
/// This multiplier is applied to prevent two people from converting each other's damage away.
|
|
#define DRAIN_DAMAGE_MULTIPLIER 1.2
|
|
|
|
/datum/status_effect/stabilized/black
|
|
id = "stabilizedblack"
|
|
colour = "black"
|
|
/// How much we heal per tick (also how much we damage per tick times DRAIN_DAMAGE_MULTIPLIER).
|
|
var/heal_amount = 1
|
|
/// Weakref to the mob we're currently draining every tick.
|
|
var/datum/weakref/draining_ref
|
|
|
|
/datum/status_effect/stabilized/black/on_apply()
|
|
RegisterSignal(owner, COMSIG_MOVABLE_SET_GRAB_STATE, .proc/on_grab)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/black/on_remove()
|
|
UnregisterSignal(owner, COMSIG_MOVABLE_SET_GRAB_STATE)
|
|
return ..()
|
|
|
|
/// Whenever we grab someone by the neck, set "draining" to a weakref of them.
|
|
/datum/status_effect/stabilized/black/proc/on_grab(mob/living/source, new_state)
|
|
SIGNAL_HANDLER
|
|
|
|
if(new_state < GRAB_KILL || !isliving(source.pulling))
|
|
draining_ref = null
|
|
return
|
|
|
|
var/mob/living/draining = source.pulling
|
|
if(draining.stat == DEAD)
|
|
return
|
|
|
|
draining_ref = WEAKREF(draining)
|
|
to_chat(owner, span_boldnotice("You feel your hands melt around [draining]'s neck as you start to drain [draining.p_them()] of [draining.p_their()] life!"))
|
|
to_chat(draining, span_userdanger("[owner]'s hands melt around your neck as you can feel your life starting to drain away!"))
|
|
|
|
/datum/status_effect/stabilized/black/get_examine_text()
|
|
var/mob/living/draining = draining_ref?.resolve()
|
|
if(!draining)
|
|
return null
|
|
|
|
return span_warning("[owner.p_they(TRUE)] [owner.p_are()] draining health from [draining]!")
|
|
|
|
/datum/status_effect/stabilized/black/tick()
|
|
if(owner.grab_state < GRAB_KILL || !IS_WEAKREF_OF(owner.pulling, draining_ref))
|
|
return
|
|
|
|
var/mob/living/drained = draining_ref.resolve()
|
|
if(drained.stat == DEAD)
|
|
to_chat(owner, span_warning("[drained] is dead, you cannot drain anymore life from them!"))
|
|
draining_ref = null
|
|
return
|
|
|
|
var/list/healing_types = list()
|
|
if(owner.getBruteLoss() > 0)
|
|
healing_types += BRUTE
|
|
if(owner.getFireLoss() > 0)
|
|
healing_types += BURN
|
|
if(owner.getToxLoss() > 0)
|
|
healing_types += TOX
|
|
if(owner.getCloneLoss() > 0)
|
|
healing_types += CLONE
|
|
|
|
if(length(healing_types))
|
|
owner.apply_damage_type(-heal_amount, damagetype = pick(healing_types))
|
|
|
|
owner.adjust_nutrition(3)
|
|
drained.adjustCloneLoss(heal_amount * DRAIN_DAMAGE_MULTIPLIER)
|
|
return ..()
|
|
|
|
#undef DRAIN_DAMAGE_MULTIPLIER
|
|
|
|
/datum/status_effect/stabilized/lightpink
|
|
id = "stabilizedlightpink"
|
|
colour = "light pink"
|
|
|
|
/datum/status_effect/stabilized/lightpink/on_apply()
|
|
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/lightpink)
|
|
ADD_TRAIT(owner, TRAIT_PACIFISM, STABILIZED_LIGHT_PINK_TRAIT)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/lightpink/tick()
|
|
for(var/mob/living/carbon/human/H in range(1, get_turf(owner)))
|
|
if(H != owner && H.stat != DEAD && H.health <= 0 && !H.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
|
|
to_chat(owner, "[linked_extract] pulses in sync with [H]'s heartbeat, trying to keep [H.p_them()] alive.")
|
|
H.reagents.add_reagent(/datum/reagent/medicine/epinephrine,5)
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/lightpink/on_remove()
|
|
owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/lightpink)
|
|
REMOVE_TRAIT(owner, TRAIT_PACIFISM, STABILIZED_LIGHT_PINK_TRAIT)
|
|
|
|
/datum/status_effect/stabilized/adamantine
|
|
id = "stabilizedadamantine"
|
|
colour = "adamantine"
|
|
|
|
/datum/status_effect/stabilized/adamantine/get_examine_text()
|
|
return span_warning("[owner.p_they(TRUE)] [owner.p_have()] strange metallic coating on [owner.p_their()] skin.")
|
|
|
|
/datum/status_effect/stabilized/gold
|
|
id = "stabilizedgold"
|
|
colour = "gold"
|
|
var/mob/living/simple_animal/familiar
|
|
|
|
/datum/status_effect/stabilized/gold/tick()
|
|
var/obj/item/slimecross/stabilized/gold/linked = linked_extract
|
|
if(QDELETED(familiar))
|
|
familiar = new linked.mob_type(get_turf(owner.loc))
|
|
familiar.name = linked.mob_name
|
|
familiar.del_on_death = TRUE
|
|
familiar.copy_languages(owner, LANGUAGE_MASTER)
|
|
if(linked.saved_mind)
|
|
linked.saved_mind.transfer_to(familiar)
|
|
familiar.update_atom_languages()
|
|
familiar.ckey = linked.saved_mind.key
|
|
else
|
|
if(familiar.mind)
|
|
linked.saved_mind = familiar.mind
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/gold/on_remove()
|
|
if(familiar)
|
|
qdel(familiar)
|
|
|
|
/datum/status_effect/stabilized/adamantine/on_apply()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.damage_resistance += 5
|
|
return ..()
|
|
|
|
/datum/status_effect/stabilized/adamantine/on_remove()
|
|
if(ishuman(owner))
|
|
var/mob/living/carbon/human/H = owner
|
|
H.physiology.damage_resistance -= 5
|
|
|
|
/datum/status_effect/stabilized/rainbow
|
|
id = "stabilizedrainbow"
|
|
colour = "rainbow"
|
|
|
|
/datum/status_effect/stabilized/rainbow/tick()
|
|
if(owner.health <= 0)
|
|
var/obj/item/slimecross/stabilized/rainbow/X = linked_extract
|
|
if(istype(X))
|
|
if(X.regencore)
|
|
X.regencore.afterattack(owner,owner,TRUE)
|
|
X.regencore = null
|
|
owner.visible_message(span_warning("[owner] flashes a rainbow of colors, and [owner.p_their()] skin is coated in a milky regenerative goo!"))
|
|
qdel(src)
|
|
qdel(linked_extract)
|
|
return ..()
|