diff --git a/code/__DEFINES/~monkestation/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/~monkestation/dcs/signals/signals_mob/signals_mob_main.dm index 2030e073340f96..97350562fb5dfa 100644 --- a/code/__DEFINES/~monkestation/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/~monkestation/dcs/signals/signals_mob/signals_mob_main.dm @@ -23,3 +23,5 @@ #define COMSIG_STACK_MOVE "stack_move" #define COMSIG_CHECK_CAN_ADD_NEW_STACK "check_stack_add" #define COMSIG_MOBSTACKER_DESTROY "mobstack_destroy_stack" + +#define COMSIG_SLIME_REGEN_CALC "slime_regen_calc" diff --git a/code/__HELPERS/~monkestation-helpers/cmp.dm b/code/__HELPERS/~monkestation-helpers/cmp.dm index eea5c3be71a72f..c87af6cd520231 100644 --- a/code/__HELPERS/~monkestation-helpers/cmp.dm +++ b/code/__HELPERS/~monkestation-helpers/cmp.dm @@ -3,3 +3,8 @@ /proc/cmp_mob_playtime_dsc(mob/a, mob/b) return cmp_numeric_dsc(a?.client?.get_exp_living(TRUE), b?.client?.get_exp_living(TRUE)) + +/// Sorts between two wounds, descending by their severity. +/// Use when you want a list of most to least severe wounds. +/proc/cmp_wound_severity_dsc(datum/wound/a, datum/wound/b) + return cmp_numeric_dsc(a.severity, b.severity) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 26aa1fbf046a82..3440839745a4de 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -507,7 +507,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) update_mutations_overlay()// no lizard with human hulk overlay please. -/mob/proc/has_dna() +/mob/proc/has_dna() as /datum/dna + RETURN_TYPE(/datum/dna) return /mob/living/carbon/has_dna() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ae8a2a99b2a5e7..fde102d3d4ce71 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -885,7 +885,7 @@ set_handcuffed(null) update_handcuffed() - stamina.adjust(stamina.maximum, TRUE) + stamina.revitalize(forced = TRUE) return ..() /mob/living/carbon/can_be_revived() diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index d289de904a6c61..181e64b70c4be1 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -445,12 +445,18 @@ /// Colour of the extract providing the buff var/colour = "null" +/datum/status_effect/stabilized/Destroy() + if(linked_extract?.linked_effect == src) + linked_extract.linked_effect = null + linked_extract = null + return ..() + /datum/status_effect/stabilized/on_creation(mob/living/new_owner, obj/item/slimecross/stabilized/linked_extract) src.linked_extract = linked_extract return ..() /datum/status_effect/stabilized/tick() - if(isnull(linked_extract)) + if(QDELETED(linked_extract)) qdel(src) return if(linked_extract.get_held_mob() == owner) @@ -1070,6 +1076,7 @@ id = "stabilizedrainbow" colour = "rainbow" +/* monkestation edit: replaced in [monkestation\code\modules\slimecore\crossbreeding\stabilized.dm] /datum/status_effect/stabilized/rainbow/tick() if(owner.health <= 0) var/obj/item/slimecross/stabilized/rainbow/X = linked_extract @@ -1081,3 +1088,4 @@ qdel(src) qdel(linked_extract) return ..() +*/ diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index fb0e886f699512..98821ff7176fef 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -2,6 +2,8 @@ Regenerative extracts: Work like a legion regenerative core. Has a unique additional effect. + + HEAVILY REWORKED BY MONKESTATION, SEE [monkestation\code\modules\slimecore\crossbreeding\regenerative] */ /obj/item/slimecross/regenerative name = "regenerative extract" @@ -14,6 +16,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/proc/core_effect_before(mob/living/carbon/human/target, mob/user) return +/* monkestation edit: overriden in [monkestation\code\modules\slimecore\crossbreeding\regenerative\extract.dm] /obj/item/slimecross/regenerative/afterattack(atom/target,mob/user,prox) . = ..() if(!prox || !isliving(target)) @@ -33,30 +36,33 @@ Regenerative extracts: core_effect(H, user) playsound(target, 'sound/effects/splat.ogg', 40, TRUE) qdel(src) +*/ /obj/item/slimecross/regenerative/grey colour = "grey" //Has no bonus effect. - effect_desc = "Fully heals the target and does nothing else." + effect_desc = "Rapidly heals the target and does nothing else." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/orange colour = "orange" /obj/item/slimecross/regenerative/orange/core_effect_before(mob/living/target, mob/user) - target.visible_message(span_warning("The [src] boils over!")) + target.visible_message(span_warning("\The [src] boils over!")) for(var/turf/targetturf in RANGE_TURFS(1,target)) if(!locate(/obj/effect/hotspot) in targetturf) new /obj/effect/hotspot(targetturf) /obj/item/slimecross/regenerative/purple colour = "purple" - effect_desc = "Fully heals the target and injects them with some regen jelly." + effect_desc = "Rapidly heals the target at an even greater rate, and injects them with some regenerative jelly afterwards. Prevents softcrit while active." // monkestation edit: updates effect_desc to reflect the rework +/* monkestation edit: moved functionality to status effect /obj/item/slimecross/regenerative/purple/core_effect(mob/living/target, mob/user) target.reagents.add_reagent(/datum/reagent/medicine/regen_jelly,10) +*/ /obj/item/slimecross/regenerative/blue colour = "blue" - effect_desc = "Fully heals the target and makes the floor wet." + effect_desc = "Rapidly heals the target and makes the floor wet." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/blue/core_effect(mob/living/target, mob/user) if(isturf(target.loc)) @@ -66,7 +72,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/metal colour = "metal" - effect_desc = "Fully heals the target and encases the target in a locker." + effect_desc = "Rapidly heals the target and encases the target in a locker." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/metal/core_effect(mob/living/target, mob/user) target.visible_message(span_warning("The milky goo hardens and reshapes itself, encasing [target]!")) @@ -77,7 +83,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/yellow colour = "yellow" - effect_desc = "Fully heals the target and fully recharges a single item on the target." + effect_desc = "Rapidly heals the target and fully recharges a single item on the target. Provides shock immunity while active." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/yellow/core_effect(mob/living/target, mob/user) var/list/batteries = list() @@ -91,7 +97,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/darkpurple colour = "dark purple" - effect_desc = "Fully heals the target and gives them purple clothing if they are naked." + effect_desc = "Rapidly heals the target and gives them purple clothing if they are naked." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/darkpurple/core_effect(mob/living/target, mob/user) var/equipped = 0 @@ -104,7 +110,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/darkblue colour = "dark blue" - effect_desc = "Fully heals the target and fireproofs their clothes." + effect_desc = "Rapidly heals the target and fireproofs their clothes." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/darkblue/core_effect(mob/living/target, mob/user) if(!ishuman(target)) @@ -132,15 +138,17 @@ Regenerative extracts: /obj/item/slimecross/regenerative/silver colour = "silver" - effect_desc = "Fully heals the target and makes their belly feel round and full." + effect_desc = "Rapidly heals the target, regenerating their nutrition at a far greater rate than normal" // monkestation edit: updates effect_desc to reflect the rework +/* monkestation edit: replaced in [monkestation\code\modules\slimecore\crossbreeding\regenerative\extract.dm] /obj/item/slimecross/regenerative/silver/core_effect(mob/living/target, mob/user) target.set_nutrition(NUTRITION_LEVEL_FULL - 1) to_chat(target, span_notice("You feel satiated.")) +*/ /obj/item/slimecross/regenerative/bluespace colour = "bluespace" - effect_desc = "Fully heals the target and teleports them to where this core was created." + effect_desc = "Rapidly heals the target and teleports them to where this core was created." // monkestation edit: updates effect_desc to reflect the rework var/turf/open/T /obj/item/slimecross/regenerative/bluespace/core_effect(mob/living/target, mob/user) @@ -156,7 +164,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/sepia colour = "sepia" - effect_desc = "Fully heals the target. After 10 seconds, relocate the target to the initial position the core was used with their previous health status." + effect_desc = "Rapidly heals the target. After 10 seconds, relocate the target to the initial position the core was used with their previous health status." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/sepia/core_effect_before(mob/living/target, mob/user) to_chat(target, span_notice("You try to forget how you feel.")) @@ -164,11 +172,11 @@ Regenerative extracts: /obj/item/slimecross/regenerative/cerulean colour = "cerulean" - effect_desc = "Fully heals the target and makes a second regenerative core with no special effects." + effect_desc = "Rapidly heals the target and makes a second regenerative core with no special effects." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/cerulean/core_effect(mob/living/target, mob/user) src.forceMove(user.loc) - var/obj/item/slimecross/X = new /obj/item/slimecross/regenerative(user.loc) + var/obj/item/slimecross/X = new /obj/item/slimecross/regenerative(user.drop_location()) X.name = name X.desc = desc user.put_in_active_hand(X) @@ -176,7 +184,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/pyrite colour = "pyrite" - effect_desc = "Fully heals and randomly colors the target." + effect_desc = "Rapidly heals and randomly colors the target." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/pyrite/core_effect(mob/living/target, mob/user) target.visible_message(span_warning("The milky goo coating [target] leaves [target.p_them()] a different color!")) @@ -184,7 +192,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/red colour = "red" - effect_desc = "Fully heals the target and injects them with some ephedrine." + effect_desc = "Rapidly heals the target and injects them with some ephedrine." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/red/core_effect(mob/living/target, mob/user) to_chat(target, span_notice("You feel... faster.")) @@ -192,20 +200,20 @@ Regenerative extracts: /obj/item/slimecross/regenerative/green colour = "green" - effect_desc = "Fully heals the target and changes the spieces or color of a slime or jellyperson." + effect_desc = "Rapidly heals the target and changes the species or color of a slime or jellyperson." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/green/core_effect(mob/living/target, mob/user) if(isslime(target)) - target.visible_message(span_warning("The [target] suddenly changes color!")) + target.visible_message(span_warning("\The [target] suddenly changes color!")) var/mob/living/basic/slime/S = target S.start_mutating(TRUE) if(isjellyperson(target)) - target.reagents.add_reagent(/datum/reagent/mutationtoxin/jelly,5) + target.reagents.add_reagent(/datum/reagent/mutationtoxin/jelly, 5) /obj/item/slimecross/regenerative/pink colour = "pink" - effect_desc = "Fully heals the target and injects them with some krokodil." + effect_desc = "Rapidly heals the target and injects them with some krokodil." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/pink/core_effect(mob/living/target, mob/user) to_chat(target, span_notice("You feel more calm.")) @@ -213,7 +221,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/gold colour = "gold" - effect_desc = "Fully heals the target and produces a random coin." + effect_desc = "Rapidly heals the target and produces a random coin." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/gold/core_effect(mob/living/target, mob/user) var/newcoin = pick(/obj/item/coin/silver, /obj/item/coin/iron, /obj/item/coin/gold, /obj/item/coin/diamond, /obj/item/coin/plasma, /obj/item/coin/uranium) @@ -223,7 +231,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/oil colour = "oil" - effect_desc = "Fully heals the target and flashes everyone in sight." + effect_desc = "Rapidly heals the target and flashes everyone in sight." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/oil/core_effect(mob/living/target, mob/user) playsound(src, 'sound/weapons/flash.ogg', 100, TRUE) @@ -232,7 +240,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/black colour = "black" - effect_desc = "Fully heals the target and creates an imperfect duplicate of them made of slime, that fakes their death." + effect_desc = "Rapidly heals the target and creates an imperfect duplicate of them made of slime, that fakes their death." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/black/core_effect_before(mob/living/target, mob/user) var/dummytype = target.type @@ -255,7 +263,7 @@ Regenerative extracts: /obj/item/slimecross/regenerative/lightpink colour = "light pink" - effect_desc = "Fully heals the target and also heals the user." + effect_desc = "Rapidly heals the target and also heals the user." // monkestation edit: updates effect_desc to reflect the rework /obj/item/slimecross/regenerative/lightpink/core_effect(mob/living/target, mob/user) if(!isliving(user)) @@ -268,14 +276,14 @@ Regenerative extracts: /obj/item/slimecross/regenerative/adamantine colour = "adamantine" - effect_desc = "Fully heals the target and boosts their armor." + effect_desc = "Rapidly heals the target, while boosting their armor and general resilience." // monkestation edit: updates effect_desc to reflect the rework, also a typo fix /obj/item/slimecross/regenerative/adamantine/core_effect(mob/living/target, mob/user) //WIP - Find out why this doesn't work. target.apply_status_effect(/datum/status_effect/slimeskin) /obj/item/slimecross/regenerative/rainbow colour = "rainbow" - effect_desc = "Fully heals the target and temporarily makes them immortal, but pacifistic." + effect_desc = "Fully heals the target, including all forms of damage, wounds, brain traumas, sickness, blood loss, and unsafe body temperature. Does not regrow limbs (except for oozelings) or refresh organs. Temporarily makes them immortal, but pacifistic." // monkestation edit: updates effect_desc to reflect the rework, also a typo fix /obj/item/slimecross/regenerative/rainbow/core_effect(mob/living/target, mob/user) target.apply_status_effect(/datum/status_effect/rainbow_protection) diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm new file mode 100644 index 00000000000000..7c279e461d5528 --- /dev/null +++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm @@ -0,0 +1,44 @@ +/datum/status_effect/regenerative_extract/purple + base_healing_amt = 10 + diminishing_multiplier = 0.5 + diminish_time = 1.5 MINUTES + extra_traits = list(TRAIT_NOCRITOVERLAY, TRAIT_NOSOFTCRIT) + +/datum/status_effect/regenerative_extract/purple/on_remove() + . = ..() + if(owner.has_dna()?.species?.reagent_tag & PROCESS_ORGANIC) // won't work during cooldown, and won't waste effort injecting into IPCs + var/inject_amt = round(10 * multiplier) + if(inject_amt >= 1) + owner.reagents?.add_reagent(/datum/reagent/medicine/regen_jelly, inject_amt) + + +/datum/status_effect/regenerative_extract/silver + base_healing_amt = 4 + nutrition_heal_cap = NUTRITION_LEVEL_WELL_FED + 50 + diminishing_multiplier = 0.8 + diminish_time = 30 SECONDS + extra_traits = list(TRAIT_NOFAT) + +/datum/status_effect/regenerative_extract/yellow + extra_traits = list(TRAIT_SHOCKIMMUNE, TRAIT_TESLA_SHOCKIMMUNE, TRAIT_AIRLOCK_SHOCKIMMUNE) + +/datum/status_effect/regenerative_extract/adamantine + extra_traits = list(TRAIT_FEARLESS, TRAIT_HARDLY_WOUNDED) + +// rainbow extracts are similar to old regen extract effects, albeit it won't replace your organs, and won't heal limbs (unless you're an oozeling) +#define RAINBOW_HEAL_FLAGS ~(HEAL_ADMIN | HEAL_RESTRAINTS | HEAL_LIMBS | HEAL_REFRESH_ORGANS) + +/datum/status_effect/regenerative_extract/rainbow + alert_type = null + diminishing_multiplier = 0 // you can't use other extracts at all during this time + tick_interval = -1 + +/datum/status_effect/regenerative_extract/rainbow/on_apply() + var/heal_flags = RAINBOW_HEAL_FLAGS + if(isoozeling(owner)) // have some mercy on oozelings + heal_flags |= HEAL_LIMBS + owner.revive(heal_flags) + return FALSE // return false so we immediately clear the effect and start the cooldown + + +#undef RAINBOW_HEAL_FLAGS diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/cooldown.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/cooldown.dm new file mode 100644 index 00000000000000..0614d914d11685 --- /dev/null +++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/cooldown.dm @@ -0,0 +1,26 @@ +/datum/status_effect/slime_regen_cooldown + id = "slime_regen_cooldown" + status_type = STATUS_EFFECT_MULTIPLE + tick_interval = -1 + alert_type = null + remove_on_fullheal = TRUE + heal_flag_necessary = HEAL_ADMIN + /// The multiplier applied to the effect of a regen extract while this cooldown is active. + /// As multiple cooldowns can be active at the same time, these multipliers stack, resulting in exponentially diminishing returns. + var/multiplier = 1 + +/datum/status_effect/slime_regen_cooldown/on_creation(mob/living/new_owner, multiplier = 1, duration = 45 SECONDS) + src.multiplier = multiplier + src.duration = duration + return ..() + +/datum/status_effect/slime_regen_cooldown/on_apply() + RegisterSignal(owner, COMSIG_SLIME_REGEN_CALC, PROC_REF(apply_multiplier)) + return TRUE + +/datum/status_effect/slime_regen_cooldown/on_remove() + UnregisterSignal(owner, COMSIG_SLIME_REGEN_CALC) + +/datum/status_effect/slime_regen_cooldown/proc/apply_multiplier(datum/source, multiplier_ptr) + SIGNAL_HANDLER + *multiplier_ptr *= multiplier diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm new file mode 100644 index 00000000000000..6c03f1a7eba8ea --- /dev/null +++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm @@ -0,0 +1,96 @@ +/datum/status_effect/regenerative_extract + id = "Slime Regeneration" + status_type = STATUS_EFFECT_UNIQUE + duration = 15 SECONDS + tick_interval = 0.2 SECONDS + alert_type = /atom/movable/screen/alert/status_effect/regen_extract + /// The damage healed (for each type) per tick. + /// This is multipled against the multiplier derived from cooldowns. + var/base_healing_amt = 5 + /// The number multiplied against the base healing amount, + /// used for the "diminishing returns" cooldown effect. + var/multiplier = 1 + /// The multiplier that the cooldown applied after the effect ends will use. + var/diminishing_multiplier = 0.75 + /// How long the subsequent cooldown effect will last. + var/diminish_time = 45 SECONDS + /// The maximum nutrition level this regenerative extract can heal up to. + var/nutrition_heal_cap = NUTRITION_LEVEL_FED - 50 + /// Base traits given to the owner. + var/static/list/given_traits = list(TRAIT_ANALGESIA, TRAIT_NOCRITDAMAGE) + /// Extra traits given to the owner, added to the base traits. + var/list/extra_traits + +/datum/status_effect/regenerative_extract/on_apply() + // So this seems weird, but this allows us to have multiple things affect the regen multiplier, + // without doing something like hardcoding a `for(var/datum/status_effect/slime_regen_cooldown/cooldown in owner.status_effects)` + // Instead, cooldown effects register the [COMSIG_SLIME_REGEN_CALC] signal, and can affect our multiplier via the pointer we pass. + SEND_SIGNAL(owner, COMSIG_SLIME_REGEN_CALC, &multiplier) + if(multiplier < 1) + to_chat(owner, span_warning("The previous regenerative goo hasn't fully evaporated yet, weakening the new regenerative effect!")) + owner.add_traits(islist(extra_traits) ? (given_traits + extra_traits) : given_traits, id) + return TRUE + +/datum/status_effect/regenerative_extract/on_remove() + owner.remove_traits(islist(extra_traits) ? (given_traits + extra_traits) : given_traits, id) + owner.apply_status_effect(/datum/status_effect/slime_regen_cooldown, diminishing_multiplier, diminish_time) + +/datum/status_effect/regenerative_extract/tick(seconds_per_tick, times_fired) + var/heal_amt = base_healing_amt * seconds_per_tick * multiplier + heal_act(heal_amt) + owner.updatehealth() + +/datum/status_effect/regenerative_extract/proc/heal_act(heal_amt) + if(!heal_amt) + return + heal_damage(heal_amt) + heal_misc(heal_amt) + if(iscarbon(owner)) + heal_organs(heal_amt) + heal_wounds() + +/datum/status_effect/regenerative_extract/proc/heal_damage(heal_amt) + owner.heal_overall_damage(brute = heal_amt, burn = heal_amt, updating_health = FALSE) + owner.stamina?.adjust(-heal_amt, forced = TRUE) + owner.adjustOxyLoss(-heal_amt, updating_health = FALSE) + owner.adjustToxLoss(-heal_amt, updating_health = FALSE, forced = TRUE) + owner.adjustCloneLoss(-heal_amt, updating_health = FALSE) + +/datum/status_effect/regenerative_extract/proc/heal_misc(heal_amt) + owner.adjust_disgust(-heal_amt) + if(owner.blood_volume < BLOOD_VOLUME_NORMAL) + owner.blood_volume = min(owner.blood_volume + heal_amt, BLOOD_VOLUME_NORMAL) + if((owner.nutrition < nutrition_heal_cap) && !HAS_TRAIT(owner, TRAIT_NOHUNGER)) + owner.nutrition = min(owner.nutrition + heal_amt, nutrition_heal_cap) + +/datum/status_effect/regenerative_extract/proc/heal_organs(heal_amt) + var/static/list/ignored_traumas + if(!ignored_traumas) + ignored_traumas = typecacheof(list( + /datum/brain_trauma/hypnosis, + /datum/brain_trauma/special/obsessed, + /datum/brain_trauma/severe/split_personality/brainwashing, + )) + var/mob/living/carbon/carbon_owner = owner + for(var/obj/item/organ/organ in carbon_owner.organs) + organ.apply_organ_damage(-heal_amt) + // stupid manual trauma curing code, so you can't just remove trauma-based antags with one click + var/obj/item/organ/internal/brain/brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN) + for(var/datum/brain_trauma/trauma as anything in shuffle(brain?.traumas)) + if(!is_type_in_typecache(trauma, ignored_traumas) && trauma.resilience <= TRAUMA_RESILIENCE_MAGIC) + qdel(trauma) + return + +/datum/status_effect/regenerative_extract/proc/heal_wounds() + var/mob/living/carbon/carbon_owner = owner + if(length(carbon_owner.all_wounds)) + var/list/datum/wound/ordered_wounds = sort_list(carbon_owner.all_wounds, GLOBAL_PROC_REF(cmp_wound_severity_dsc)) + ordered_wounds[1]?.remove_wound() + +/datum/status_effect/regenerative_extract/get_examine_text() + return "[owner.p_They()] have a subtle, gentle glow to [owner.p_their()] skin, with slime soothing [owner.p_their()] wounds." + +/atom/movable/screen/alert/status_effect/regen_extract + name = "Slime Regeneration" + desc = "A milky slime covers your skin, soothing and regenerating your injuries!" + icon_state = "regenerative_core" diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/extract.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/extract.dm new file mode 100644 index 00000000000000..96b292669ee135 --- /dev/null +++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/extract.dm @@ -0,0 +1,54 @@ +/// Returns the typepath to the status effect that should be applied to the target when this extract is used on them. +/obj/item/slimecross/regenerative/proc/get_status_path() + var/color_path = text2path("/datum/status_effect/regenerative_extract/[colour]") + if(ispath(color_path, /datum/status_effect/regenerative_extract)) + return color_path + return /datum/status_effect/regenerative_extract + +/obj/item/slimecross/regenerative/proc/can_use(mob/living/target, mob/living/user) + if(target.stat == DEAD) + to_chat(user, span_warning("[src] will not work on the dead!")) + return FALSE + if(target.has_status_effect(/datum/status_effect/regenerative_extract)) + to_chat(user, span_warning("[target == user ? "You are" : "[target] is"] already being healed by a regenerative extract!")) + return FALSE + return TRUE + +/obj/item/slimecross/regenerative/afterattack(mob/living/target, mob/user, prox) + . = ..() + if(!prox || !isliving(target) || !can_use(target, user)) + return + if(target != user) + user.visible_message(span_notice("[user] crushes [src] over [target], the milky goo coating [target.p_their()] injuries!"), + span_notice("You squeeze [src], and it bursts over [target], the milky goo beginning to regenerate [target.p_their()] injuries.")) + else + user.visible_message(span_notice("[user] crushes [src] over [user.p_them()]self, the milky goo quickly regenerating all of [user.p_their()] injuries!"), + span_notice("You squeeze [src], and it bursts in your hand, splashing you with milky goo which quickly regenerates your injuries!")) + core_effect_before(target, user) + apply_effect(target) + core_effect(target, user) + playsound(target, 'sound/effects/splat.ogg', vol = 40, vary = TRUE) + qdel(src) + +/obj/item/slimecross/regenerative/proc/apply_effect(mob/living/target) + target.apply_status_effect(get_status_path()) + +/obj/item/slimecross/regenerative/silver/core_effect(mob/living/target, mob/user) + return // handled by the status effect + +/obj/item/slimecross/regenerative/lightpink/core_effect(mob/living/target, mob/living/user) + if(!isliving(user)) + return + if(target == user) + return + if(!user.has_status_effect(/datum/status_effect/regenerative_extract)) + apply_effect(user) + to_chat(user, span_notice("Some of the milky goo sprays onto you, as well!")) + else + to_chat(user, span_warning("Some of the milky goo sprays onto you, but slides off due to the regenerative effect...")) + +/obj/item/slimecross/regenerative/rainbow/can_use(mob/living/target, mob/living/user) + if(target.has_status_effect(/datum/status_effect/slime_regen_cooldown)) + to_chat(user, span_warning("[target == user ? "You are" : "[target] is"] still recovering from the last regenerative extract!")) + return FALSE + return ..() diff --git a/monkestation/code/modules/slimecore/crossbreeding/stabilized.dm b/monkestation/code/modules/slimecore/crossbreeding/stabilized.dm new file mode 100644 index 00000000000000..71ac69cbcd8587 --- /dev/null +++ b/monkestation/code/modules/slimecore/crossbreeding/stabilized.dm @@ -0,0 +1,29 @@ +/obj/item/slimecross/stabilized/rainbow/Destroy() + if(!QDELETED(regencore)) + regencore.forceMove(drop_location()) + regencore = null + return ..() + +/datum/status_effect/stabilized/rainbow/tick() + if(owner.health <= 0) + var/obj/item/slimecross/stabilized/rainbow/extract = linked_extract + if(!istype(extract) || QDELING(extract) || QDELETED(extract.regencore)) + return + // bypasses cooldowns, but also removes any existing regen effects + owner.remove_status_effect(/datum/status_effect/regenerative_extract) + owner.remove_status_effect(/datum/status_effect/slime_regen_cooldown) + owner.visible_message(span_hypnophrase("[owner] flashes a rainbow of colors, and [owner.p_their()] skin is coated in a milky regenerative goo!")) + playsound(owner, 'sound/effects/splat.ogg', vol = 40, vary = TRUE) + apply_regen(extract.regencore) + QDEL_NULL(linked_extract) + qdel(src) + return + return ..() + + +/datum/status_effect/stabilized/rainbow/proc/apply_regen(obj/item/slimecross/regenerative/regen_core) + regen_core.core_effect_before(owner, owner) + regen_core.apply_effect(owner) + regen_core.core_effect(owner, owner) + qdel(regen_core) + diff --git a/tgstation.dme b/tgstation.dme index 1d43beb90ebec6..d36331f81beaf8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7303,6 +7303,11 @@ #include "monkestation\code\modules\slimecore\corral\upgrades\human_docility_upgrade.dm" #include "monkestation\code\modules\slimecore\corral\upgrades\obliteration_upgrade.dm" #include "monkestation\code\modules\slimecore\crossbreeding\industrial.dm" +#include "monkestation\code\modules\slimecore\crossbreeding\stabilized.dm" +#include "monkestation\code\modules\slimecore\crossbreeding\regenerative\colors.dm" +#include "monkestation\code\modules\slimecore\crossbreeding\regenerative\cooldown.dm" +#include "monkestation\code\modules\slimecore\crossbreeding\regenerative\effect.dm" +#include "monkestation\code\modules\slimecore\crossbreeding\regenerative\extract.dm" #include "monkestation\code\modules\slimecore\items\crossbreeds.dm" #include "monkestation\code\modules\slimecore\items\mutation_syringe.dm" #include "monkestation\code\modules\slimecore\items\vacuum_pack.dm"