Adds some positive mutations (#90393)

## About The Pull Request

- Hypermetabolic Blood
   - You bleed 1.5x more, but regenerate blood 6x faster. 
- For reference: A moderate slash wound is ~2 blood loss per tick, a
crit slash wound is ~4 blood loss per tick, and you regenerate ~0.25
blood per tick.
- For weak bleed wounds, you will net lose less blood per tick with the
mutation than without.
- However, for strong bleed wounds you will net lose more blood per tick
with the mutation.
- Ultimately, you will (obviously) recover much faster once closing the
wound.
   - Affected by synchronizer and power
- Rock Eater
 	- You can eat materials like a golem.
- Rock Absorber
- You can eat materials like a golem, and you will also gain golem buffs
from them.
	- Combination gene from "Rock Eater" and "Stoner" 
- I didn't (deeply) vet if any of these effects would be OP combined
with other genes, but I'm chalking it up to emergent gameplay if I miss
something
- Farsight
	- Gives you an action button which lets you expand your view range
	- Affected by power
 - Inexorable
- Disables soft crit, but entering the threshold for soft crit will
cause ticking brute/toxin damage and force you to whisper.
       - No slimepeople can't cheese this 
    - Also is an innate "painkiller".
    - Affected by synchronizer

## Why It's Good For The Game

Just some random mutation ideas I had, for more genetics shenanigans.
They're all relatively unobtrusive but have some niche potential
(Bleeding more for Blood Cult? Farsight + Thermals? Inexorable +
Martyrdom?)

## Changelog

🆑 Melbert
add: "Hypermetabolic Blood" Mutation
add: "Rock Eater" Mutation
add: "Rock Absorber" Combination Mutation
add: "Farsight" Mutation
add: "Inexorable" Mutation
/🆑
This commit is contained in:
MrMelbert
2025-04-12 14:02:53 +10:00
committed by GitHub
parent f0c6772a4f
commit e99048d37f
10 changed files with 233 additions and 76 deletions
+5
View File
@@ -68,3 +68,8 @@
input_one = /datum/mutation/human/hulk
input_two = /datum/mutation/human/clumsy
result = /datum/mutation/human/hulk/ork
/datum/generecipe/rock_absorber
input_one = /datum/mutation/human/rock_eater
input_two = /datum/mutation/human/stoner
result = /datum/mutation/human/rock_absorber
+1 -1
View File
@@ -248,7 +248,7 @@
new_power.base_background_icon_state = new_power.background_icon_state
new_power.active_background_icon_state = "[new_power.base_background_icon_state]_active"
new_power.overlay_icon_state = "bg_tech_blue_border"
new_power.active_overlay_icon_state = null
new_power.active_overlay_icon_state = "bg_spell_border_active_blue"
new_power.panel = "Genetic"
new_power.Grant(owner)
+127 -57
View File
@@ -198,17 +198,7 @@
instability = NEGATIVE_STABILITY_MAJOR
quality = MINOR_NEGATIVE
text_gain_indication = span_danger("You feel lightheaded.")
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
ADD_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION)
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
if(..())
return
REMOVE_TRAIT(owner, TRAIT_CLUMSY, GENETIC_MUTATION)
mutation_traits = list(TRAIT_CLUMSY)
//Tourettes causes you to randomly stand in place and shout.
/datum/mutation/human/tourettes
@@ -239,17 +229,7 @@
instability = NEGATIVE_STABILITY_MAJOR
quality = NEGATIVE
text_gain_indication = span_danger("You can't seem to hear anything.")
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
ADD_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION)
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
if(..())
return
REMOVE_TRAIT(owner, TRAIT_DEAF, GENETIC_MUTATION)
mutation_traits = list(TRAIT_DEAF)
//Monified turns you into a monkey.
/datum/mutation/human/race
@@ -344,19 +324,7 @@
text_gain_indication = span_notice("You feel strong.")
instability = POSITIVE_INSTABILITY_MINI
difficulty = 16
/datum/mutation/human/strong/on_acquiring(mob/living/carbon/human/owner)
. = ..()
if(.)
return
ADD_TRAIT(owner, TRAIT_STRENGTH, GENETIC_MUTATION)
/datum/mutation/human/strong/on_losing(mob/living/carbon/human/owner)
. = ..()
if(.)
return
REMOVE_TRAIT(owner, TRAIT_STRENGTH, GENETIC_MUTATION)
mutation_traits = list(TRAIT_STRENGTH)
/datum/mutation/human/stimmed
name = "Stimmed"
@@ -365,18 +333,7 @@
instability = POSITIVE_INSTABILITY_MINI
text_gain_indication = span_notice("You feel stimmed.")
difficulty = 16
/datum/mutation/human/stimmed/on_acquiring(mob/living/carbon/human/owner)
. = ..()
if(.)
return
ADD_TRAIT(owner, TRAIT_STIMMED, GENETIC_MUTATION)
/datum/mutation/human/stimmed/on_losing(mob/living/carbon/human/owner)
. = ..()
if(.)
return
REMOVE_TRAIT(owner, TRAIT_STIMMED, GENETIC_MUTATION)
mutation_traits = list(TRAIT_STIMMED)
/datum/mutation/human/insulated
name = "Insulated"
@@ -386,16 +343,7 @@
text_lose_indication = span_notice("Your fingertips regain feeling.")
difficulty = 16
instability = POSITIVE_INSTABILITY_MODERATE
/datum/mutation/human/insulated/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, GENETIC_MUTATION)
/datum/mutation/human/insulated/on_losing(mob/living/carbon/human/owner)
if(..())
return
REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, GENETIC_MUTATION)
mutation_traits = list(TRAIT_SHOCKIMMUNE)
/datum/mutation/human/fire
name = "Fiery Sweat"
@@ -627,3 +575,125 @@
if(istype(new_limb, /obj/item/bodypart/head))
return COMPONENT_NO_ATTACH
// You bleed faster but regenerate blood faster
/datum/mutation/human/bloodier
name = "Hypermetabolic Blood"
desc = "The subject's blood is hypermetabolic, causing it to be produced at a much faster rate."
quality = POSITIVE
instability = POSITIVE_INSTABILITY_MINOR
text_gain_indication = span_notice("You can feel your heartbeat pick up.")
text_lose_indication = span_notice("You heartbeat slows back down.")
difficulty = 16
synchronizer_coeff = 1
power_coeff = 1
/// Modifies the bleed rate of the owner
var/bleed_rate = 1.5
/// Modifies the blood regeneration rate of the owner
var/blood_regen_rate = 6
/// Tracks if we've modified the physiology of the owner
VAR_PRIVATE/physiology_modified = FALSE
/datum/mutation/human/bloodier/on_acquiring(mob/living/carbon/human/owner)
. = ..()
if(.)
return
if(!physiology_modified)
owner.physiology.bleed_mod *= bleed_rate
owner.physiology.blood_regen_mod *= blood_regen_rate
physiology_modified = TRUE
/datum/mutation/human/bloodier/on_losing(mob/living/carbon/human/owner)
. = ..()
if(.)
return
if(physiology_modified)
owner.physiology.bleed_mod /= bleed_rate
owner.physiology.blood_regen_mod /= blood_regen_rate
physiology_modified = FALSE // just in case
/datum/mutation/human/bloodier/modify()
if(owner && physiology_modified)
owner.physiology.bleed_mod /= bleed_rate
owner.physiology.blood_regen_mod /= blood_regen_rate
physiology_modified = FALSE
bleed_rate = clamp(initial(bleed_rate) * GET_MUTATION_SYNCHRONIZER(src) * GET_MUTATION_POWER(src), 1, 2)
blood_regen_rate = clamp(initial(blood_regen_rate) * GET_MUTATION_POWER(src), 4, 12)
if(owner && !physiology_modified) // redundant but just in case
owner.physiology.bleed_mod *= bleed_rate
owner.physiology.blood_regen_mod *= blood_regen_rate
physiology_modified = TRUE
return TRUE
// You eat rocks
/datum/mutation/human/rock_eater
name = "Rock Eater"
desc = "The subject's body is able to digest rocks and minerals."
quality = POSITIVE
instability = POSITIVE_INSTABILITY_MINI
text_gain_indication = span_notice("You feel a craving for rocks.")
text_lose_indication = span_notice("You could go for a normal meal.")
difficulty = 12
mutation_traits = list(TRAIT_ROCK_EATER)
conflicts = list(/datum/mutation/human/rock_absorber)
// You eat rock but also get buffs from them
/datum/mutation/human/rock_absorber
name = "Rock Absorber"
desc = "The subject's body is able to digest rocks and minerals, taking on their properties."
quality = POSITIVE
instability = POSITIVE_INSTABILITY_MAJOR
text_gain_indication = span_notice("You feel a supreme craving for rocks.")
text_lose_indication = span_notice("You could go for a normal meal.")
mutation_traits = list(TRAIT_ROCK_EATER, TRAIT_ROCK_METAMORPHIC)
conflicts = list(/datum/mutation/human/rock_eater)
locked = TRUE
// Soft crit is disabed
/datum/mutation/human/inexorable
name = "Inexorable"
desc = "Your body can push on beyond the limits of normal human endurance. \
However, pushing it too far can cause severe damage to your body."
quality = POSITIVE
instability = POSITIVE_INSTABILITY_MODERATE
text_gain_indication = span_notice("You feel inexorable.")
text_lose_indication = span_notice("You suddenly feel more human.")
difficulty = 24
synchronizer_coeff = 1
mutation_traits = list(TRAIT_NOSOFTCRIT, TRAIT_ANALGESIA)
/datum/mutation/human/inexorable/on_acquiring(mob/living/carbon/human/acquirer)
. = ..()
if(.)
return
RegisterSignal(acquirer, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(check_health))
check_health()
/datum/mutation/human/inexorable/on_losing(mob/living/carbon/human/owner)
. = ..()
if(.)
return
UnregisterSignal(owner, COMSIG_LIVING_HEALTH_UPDATE)
REMOVE_TRAIT(owner, TRAIT_SOFTSPOKEN, REF(src))
/datum/mutation/human/inexorable/proc/check_health(...)
SIGNAL_HANDLER
if(owner.health > owner.crit_threshold || owner.stat != CONSCIOUS)
REMOVE_TRAIT(owner, TRAIT_SOFTSPOKEN, REF(src))
else
ADD_TRAIT(owner, TRAIT_SOFTSPOKEN, REF(src))
/datum/mutation/human/inexorable/on_life(seconds_per_tick, times_fired)
if(owner.health > owner.crit_threshold || owner.stat != CONSCIOUS || HAS_TRAIT(owner, TRAIT_STASIS))
return
// Gives you 30 seconds of being in soft crit... give or take
if(HAS_TRAIT(owner, TRAIT_TOXIMMUNE) || HAS_TRAIT(owner, TRAIT_TOXINLOVER))
owner.adjustBruteLoss(1 * seconds_per_tick * GET_MUTATION_SYNCHRONIZER(src), forced = TRUE)
else
owner.adjustToxLoss(0.5 * seconds_per_tick * GET_MUTATION_SYNCHRONIZER(src), forced = TRUE)
owner.adjustBruteLoss(0.5 * seconds_per_tick * GET_MUTATION_SYNCHRONIZER(src), forced = TRUE)
// Offsets suffocation but not entirely
owner.adjustOxyLoss(-0.5 * seconds_per_tick, forced = TRUE)
+61
View File
@@ -0,0 +1,61 @@
/datum/mutation/human/farsight
name = "Farsight"
desc = "The subject's eyes are able to see further than normal."
quality = POSITIVE
instability = POSITIVE_INSTABILITY_MINOR
text_gain_indication = span_notice("You feel your eyes tingle.")
text_lose_indication = span_notice("Your eyes feel normal.")
difficulty = 16
power_coeff = 1
power_path = /datum/action/cooldown/spell/farsight
/datum/mutation/human/farsight/modify()
. = ..()
var/datum/action/cooldown/spell/farsight/to_modify = .
if(istype(to_modify))
to_modify.set_sight_range(initial(to_modify.sight_range) * (GET_MUTATION_POWER(src) == 1 ? 1 : 3))
/datum/action/cooldown/spell/farsight
name = "Farsight"
desc = "You can see further than normal."
button_icon = 'icons/mob/actions/actions_ecult.dmi'
button_icon_state = "eye"
school = SCHOOL_TRANSMUTATION
cooldown_time = 8 SECONDS
invocation_type = INVOCATION_NONE
spell_requirements = NONE
antimagic_flags = NONE
/// How much to expand the view size by
var/sight_range = 1
/// If we are currently active
VAR_PRIVATE/active = FALSE
/datum/action/cooldown/spell/farsight/vv_edit_var(var_name, var_value)
. = ..()
if(var_name == NAMEOF(src, sight_range))
set_sight_range(sight_range)
/datum/action/cooldown/spell/farsight/proc/set_sight_range(new_value)
if(sight_range == new_value)
return
sight_range = new_value
if(active)
owner?.client?.view_size.setTo(sight_range)
/datum/action/cooldown/spell/farsight/cast(atom/cast_on)
. = ..()
var/mob/living/caster = cast_on
if(active)
caster.client?.view_size.resetToDefault()
active = FALSE
cooldown_time *= 2
else
caster.client?.view_size.setTo(sight_range)
active = TRUE
cooldown_time *= 0.5
build_all_button_icons(UPDATE_BUTTON_STATUS)
/datum/action/cooldown/spell/farsight/is_action_active(atom/movable/screen/movable/action_button/current_button)
return active