[MIRROR] Refactors genetic meltdowns into datums (#28588)

* Refactors genetic meltdowns into datums (#84558)

## About The Pull Request

Genetic meltdowns now use datums instead of a prob and switch
monstrocity, making them far more readable. Requested by Jacquerel on
discord.

Additionally, removed 0.83% chance for a meltdown to turn you into a
dullahan, as those are extremely broken right now.
Closes #83592

## Why It's Good For The Game

This system is much nicer, readable and more extendable than the current
one.

## Changelog
🆑
del: You can no longer get turned into a dullahan by a genetic meltdown
refactor: Refactored genetic meltdown code into datums, making it more
extendable.
/🆑

---------

Co-authored-by: Time-Green <7501474+Time-Green@ users.noreply.github.com>

* Refactors genetic meltdowns into datums

---------

Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: Time-Green <7501474+Time-Green@ users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-07-04 10:43:59 +05:30
committed by GitHub
co-authored by Time-Green SmArtKar
parent bfb3a21a01
commit 1ad5ec1fc3
3 changed files with 185 additions and 76 deletions
+21 -76
View File
@@ -107,7 +107,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
var/stability = 100
///Did we take something like mutagen? In that case we cant get our genes scanned to instantly cheese all the powers.
var/scrambled = FALSE
/// Weighted list of nonlethal meltdowns
var/static/list/nonfatal_meltdowns = list()
/// Weighted list of lethal meltdowns
var/static/list/fatal_meltdowns = list()
/datum/dna/New(mob/living/new_holder)
if(istype(new_holder))
@@ -958,81 +961,23 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
var/instability = -dna.stability
dna.remove_all_mutations()
dna.stability = 100
if(prob(max(70-instability,0)))
switch(rand(0,11)) //not complete and utter death
if(0)
monkeyize()
if(1)
gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic)
new/obj/vehicle/ridden/wheelchair(get_turf(src)) //don't buckle, because I can't imagine to plethora of things to go through that could otherwise break
to_chat(src, span_warning("My flesh turned into a wheelchair and I can't feel my legs."))
if(2)
corgize()
if(3)
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
if(4)
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
physiology.damage_resistance -= 20000 //you thought
if(5)
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
reagents.add_reagent(/datum/reagent/aslimetoxin, 10)
if(6)
apply_status_effect(/datum/status_effect/go_away)
if(7)
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
ForceContractDisease(new /datum/disease/decloning) // slow acting, non-viral GBS
if(8)
var/list/elligible_organs = list()
for(var/obj/item/organ/internal/internal_organ in organs) //make sure we dont get an implant or cavity item
elligible_organs += internal_organ
vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 10)
if(elligible_organs.len)
var/obj/item/organ/O = pick(elligible_organs)
O.Remove(src)
visible_message(span_danger("[src] vomits up [p_their()] [O.name]!"), span_danger("You vomit up your [O.name]")) //no "vomit up your heart"
O.forceMove(drop_location())
if(prob(20))
O.animate_atom_living()
if(9 to 10)
ForceContractDisease(new/datum/disease/gastrolosis())
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
if(11)
to_chat(src, span_notice("Your DNA mutates into the ultimate biological form!"))
crabize()
else
switch(rand(0,6))
if(0)
investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS)
gib(DROP_ALL_REMAINS)
if(1)
investigate_log("has been dusted by DNA instability.", INVESTIGATE_DEATHS)
dust()
if(2)
investigate_log("has been transformed into a statue by DNA instability.", INVESTIGATE_DEATHS)
death()
petrify(statue_timer = INFINITY, save_brain = FALSE)
ghostize(FALSE)
if(3)
if(prob(95))
var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD))
if(BP)
BP.dismember()
else
investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS)
gib(DROP_ALL_REMAINS)
else
set_species(/datum/species/dullahan)
if(4)
visible_message(span_warning("[src]'s skin melts off!"), span_boldwarning("Your skin melts off!"))
spawn_gibs()
set_species(/datum/species/skeleton)
if(prob(90))
addtimer(CALLBACK(src, PROC_REF(death)), 3 SECONDS)
if(5)
to_chat(src, span_phobia("LOOK UP!"))
addtimer(CALLBACK(src, PROC_REF(something_horrible_mindmelt)), 3 SECONDS)
if(6)
slow_psykerize()
var/nonfatal = prob(max(70-instability, 0))
if(!dna.nonfatal_meltdowns.len)
for(var/datum/instability_meltdown/meltdown_type as anything in typecacheof(/datum/instability_meltdown, ignore_root_path = TRUE))
if(initial(meltdown_type.abstract_type) == meltdown_type)
continue
if (initial(meltdown_type.fatal))
dna.fatal_meltdowns[meltdown_type] = initial(meltdown_type.meltdown_weight)
continue
dna.nonfatal_meltdowns[meltdown_type] = initial(meltdown_type.meltdown_weight)
var/picked_type = pick_weight(nonfatal ? dna.nonfatal_meltdowns : dna.fatal_meltdowns)
var/datum/instability_meltdown/meltdown = new picked_type
meltdown.meltdown(src)
/mob/living/carbon/human/proc/something_horrible_mindmelt()
if(!is_blind())
+163
View File
@@ -0,0 +1,163 @@
/// A possible genetic meltdown that occurs when someone exceeds 100 genetic instability
/datum/instability_meltdown
/// How likely a meltdown is to be picked
var/meltdown_weight = 1
/// If this meltdown is considered "fatal" or not
var/fatal = FALSE
/// Used to ensure that abstract subtypes do not get picked
var/abstract_type = /datum/instability_meltdown
/// Code that runs when this meltdown is picked
/datum/instability_meltdown/proc/meltdown(mob/living/carbon/human/victim)
return
// Nonfatal meltdowns
/// Turns you into a monkey
/datum/instability_meltdown/monkey
/datum/instability_meltdown/monkey/meltdown(mob/living/carbon/human/victim)
victim.monkeyize()
/// Gives you brain trauma that makes your legs disfunctional and gifts you a wheelchair
/datum/instability_meltdown/paraplegic
/datum/instability_meltdown/paraplegic/meltdown(mob/living/carbon/human/victim)
victim.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic)
new /obj/vehicle/ridden/wheelchair(get_turf(victim))
to_chat(victim, span_warning("My flesh turned into a wheelchair and I can't feel my legs."))
/// Turns you into a corgi
/datum/instability_meltdown/corgi
/datum/instability_meltdown/corgi/meltdown(mob/living/carbon/human/victim)
victim.corgize()
/// Does nothing
/datum/instability_meltdown/alright
/datum/instability_meltdown/alright/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_notice("Oh, I actually feel quite alright!"))
/// Gives you the same text as above but now when you're hit you take 200 times more damage
/datum/instability_meltdown/not_alright
/datum/instability_meltdown/not_alright/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_notice("Oh, I actually feel quite alright!"))
victim.physiology.damage_resistance -= 20000 //you thought
victim.log_message("has received x200 damage multiplier from [type] genetic meltdown")
/// Turns you into a slime
/datum/instability_meltdown/slime
/datum/instability_meltdown/slime/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_notice("Oh, I actually feel quite alright!"))
victim.reagents.add_reagent(/datum/reagent/aslimetoxin, 10)
/// Makes you phase through walls into a random direction
/datum/instability_meltdown/yeet
/datum/instability_meltdown/yeet/meltdown(mob/living/carbon/human/victim)
victim.apply_status_effect(/datum/status_effect/go_away)
/// Makes you take cell damage and gibs you after some time
/datum/instability_meltdown/decloning
/datum/instability_meltdown/decloning/meltdown(mob/living/carbon/human/victim)
to_chat(src, span_notice("Oh, I actually feel quite alright!"))
victim.ForceContractDisease(new /datum/disease/decloning) // slow acting, non-viral GBS
/// Makes you vomit up a random organ
/datum/instability_meltdown/organ_vomit
/datum/instability_meltdown/organ_vomit/meltdown(mob/living/carbon/human/victim)
var/list/elligible_organs = list()
for(var/obj/item/organ/internal/internal_organ in victim.organs) //make sure we dont get an implant or cavity item
elligible_organs += internal_organ
victim.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 10)
if(!elligible_organs.len)
return
var/obj/item/organ/picked_organ = pick(elligible_organs)
picked_organ.Remove(src)
victim.visible_message(span_danger("[victim] vomits up [p_their()] [picked_organ.name]!"), span_danger("You vomit up your [picked_organ.name]")) //no "vomit up your heart"
picked_organ.forceMove(victim.drop_location())
if(prob(20))
picked_organ.animate_atom_living()
/// Turns you into a snail
/datum/instability_meltdown/snail
meltdown_weight = 2
/datum/instability_meltdown/snail/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_notice("Oh, I actually feel quite alright!"))
victim.ForceContractDisease(new/datum/disease/gastrolosis())
/// Turns you into the ultimate lifeform
/datum/instability_meltdown/crab
/datum/instability_meltdown/crab/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_notice("Your DNA mutates into the ultimate biological form!"))
victim.crabize()
// Fatal meltdowns
/datum/instability_meltdown/fatal
fatal = TRUE
abstract_type = /datum/instability_meltdown/fatal
/// Instantly gibs you
/datum/instability_meltdown/fatal/gib
/datum/instability_meltdown/fatal/gib/meltdown(mob/living/carbon/human/victim)
victim.investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS)
victim.gib(DROP_ALL_REMAINS)
/// Dusts you
/datum/instability_meltdown/fatal/dust
/datum/instability_meltdown/fatal/dust/meltdown(mob/living/carbon/human/victim)
victim.investigate_log("has been dusted by DNA instability.", INVESTIGATE_DEATHS)
victim.dust()
/// Turns you into a statue
/datum/instability_meltdown/fatal/petrify
/datum/instability_meltdown/fatal/petrify/meltdown(mob/living/carbon/human/victim)
victim.investigate_log("has been transformed into a statue by DNA instability.", INVESTIGATE_DEATHS)
victim.death()
victim.petrify(statue_timer = INFINITY, save_brain = FALSE)
victim.ghostize(FALSE)
/// Either dismembers you, or if unable to, gibs you
/datum/instability_meltdown/fatal/dismember
/datum/instability_meltdown/fatal/dismember/meltdown(mob/living/carbon/human/victim)
var/obj/item/bodypart/part = victim.get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD))
if(part)
part.dismember()
return
victim.investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS)
victim.gib(DROP_ALL_REMAINS)
/// Turns you into a skeleton, with a high chance of killing you soon after
/datum/instability_meltdown/fatal/skeletonize
/datum/instability_meltdown/fatal/skeletonize/meltdown(mob/living/carbon/human/victim)
victim.visible_message(span_warning("[victim]'s skin melts off!"), span_boldwarning("Your skin melts off!"))
victim.spawn_gibs()
victim.set_species(/datum/species/skeleton)
if(prob(90))
addtimer(CALLBACK(victim, TYPE_PROC_REF(/mob/living, death)), 3 SECONDS)
/// Makes you look up and melts out your eyes
/datum/instability_meltdown/fatal/ceiling
/datum/instability_meltdown/fatal/ceiling/meltdown(mob/living/carbon/human/victim)
to_chat(victim, span_phobia("LOOK UP!"))
addtimer(CALLBACK(victim, TYPE_PROC_REF(/mob/living/carbon/human, something_horrible_mindmelt)), 3 SECONDS)
/// Slowly turns you into a psyker
/datum/instability_meltdown/fatal/psyker
/datum/instability_meltdown/fatal/psyker/meltdown(mob/living/carbon/human/victim)
victim.slow_psykerize()
+1
View File
@@ -880,6 +880,7 @@
#include "code\datums\hotkeys_help.dm"
#include "code\datums\http.dm"
#include "code\datums\hud.dm"
#include "code\datums\instability_meltdown.dm"
#include "code\datums\json_database.dm"
#include "code\datums\json_savefile.dm"
#include "code\datums\lazy_template.dm"