Xenobiology Cross Skill Interactions (#22643)

This PR adds new Cross-Skill Interactions for both Cooking and
Xenobiology, the latter of which now provides a new Situational Skill
Modifier.

Cooking Skill now causes animals butchered by the character to drop
additional meat. A pretty simple small interaction that doesn't change
much in the grand scheme of things.

Xenobiology has gained two new interactions, aimed at making it a skill
"potentially useful" for players who think their character might be
fighting Space Fauna. The first is that it provides a melee damage
modifier (which can offset the penalties from low melee skill), but only
when attacking Space Fauna (that aren't player controlled). Normally
direct damage modifiers are very hard to balance as a consequence of
brainmed, but since this applies exclusively to a PVE interaction, the
balance concerns are significantly lessened. Its second new interaction
is to situationally modify the amount of butchering products gained from
Space Fauna (and only Space Fauna).

Particularly in the case of Xenobiology, this helps position the skill
in such a way that it provides Opportunity Cost for characters in
Cooking, Mining, and Security (to a much lesser extent, given they
almost never engage carp in melee). If points spent in Xenobiology helps
a miner fight off space fauna, then points spent in Surgery are not
points they're spending on being better at fighting carp. Almost all of
the skills in general should have care put into making sure that they
can provide viable Opportunity Cost against other skills in their same
category. Cross-Skill Interactions like this are an incredibly effective
method of doing so.

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
This commit is contained in:
VMSolidus
2026-06-19 14:21:03 -04:00
committed by GitHub
parent 662fecfc79
commit acdbcad005
12 changed files with 121 additions and 28 deletions
@@ -1,22 +1,30 @@
/datum/component/skill/xenobiology
/// Bonus surgery success rate, to be applied only when performing surgeries on a creature of a different species.
var/success_rate_bonus_per_level = 2.5
/// Bonus surgery speed (as a percent increase) per skill level, to be applied only when performing surgeries on a creature of a different species.
var/surgery_speed_mod_per_level = 0.05
/// +%bonus damage versus Space Fauna (EG: Space Carp, Space Bears, Asteroid Worms, Gnats, Etc.)
var/bonus_damage_per_rank = 0.05
/datum/component/skill/xenobiology/Initialize(level)
. = ..()
if (!parent)
return
RegisterSignal(parent, COMSIG_GET_SURGERY_SUCCESS_MODIFIERS, PROC_REF(handle_surgery_modifiers))
RegisterSignal(parent, COMSIG_APPLY_HIT_EFFECT, PROC_REF(modify_hit_effect), override = TRUE)
RegisterSignal(parent, COMSIG_GET_BUTCHERING_MODIFIERS, PROC_REF(modify_butchering), override = TRUE)
/datum/component/skill/xenobiology/Destroy(force)
if (!parent)
return ..()
UnregisterSignal(parent, COMSIG_GET_SURGERY_SUCCESS_MODIFIERS)
UnregisterSignal(parent, COMSIG_APPLY_HIT_EFFECT)
UnregisterSignal(parent, COMSIG_GET_BUTCHERING_MODIFIERS)
return ..()
/datum/component/skill/xenobiology/proc/handle_surgery_modifiers(mob/living/user, mob/living/carbon/target, success_rate, duration)
@@ -28,3 +36,25 @@
var/effective_skill = skill_level - 1
*success_rate = *success_rate + success_rate_bonus_per_level * effective_skill
*duration = *duration * (1 - surgery_speed_mod_per_level * effective_skill)
/datum/component/skill/xenobiology/proc/modify_hit_effect(owner, mob/living/target, obj/item/weapon, power, hit_zone)
SIGNAL_HANDLER
if (target.ckey || !HAS_TRAIT(target, TRAIT_MC_SPACE_FAUNA))
return
if (prob(20))
// Give the player some feedback that the skill is providing a damage bonus, but no need to spam the chat.
to_chat(owner, SPAN_NOTICE("Your attack exploits a weak spot on [target]"))
*power = *power * (1 + bonus_damage_per_rank * (skill_level))
/datum/component/skill/xenobiology/proc/modify_butchering(owner, mob/living/simple_animal/target, base_meat_amount, butchering_bonus)
SIGNAL_HANDLER
if (!HAS_TRAIT(target, TRAIT_MC_SPACE_FAUNA) || skill_level <= SKILL_LEVEL_UNFAMILIAR)
return
to_chat(owner, SPAN_NOTICE("Your familiarity with [target] lets you harvest more parts."))
var/skill_difference = skill_level - SKILL_LEVEL_UNFAMILIAR
*base_meat_amount = *base_meat_amount + skill_difference
if (skill_level >= SKILL_LEVEL_PROFESSIONAL)
*butchering_bonus = *butchering_bonus + skill_difference
@@ -1 +1,20 @@
/datum/component/skill/cooking
/datum/component/skill/cooking/Initialize(level)
. = ..()
RegisterSignal(parent, COMSIG_GET_BUTCHERING_MODIFIERS, PROC_REF(modify_butchering), override = TRUE)
/datum/component/skill/cooking/Destroy(force)
UnregisterSignal(parent, COMSIG_GET_BUTCHERING_MODIFIERS)
return ..()
/datum/component/skill/cooking/proc/modify_butchering(owner, mob/living/simple_animal/target, base_meat_amount, butchering_bonus)
SIGNAL_HANDLER
if (skill_level <= SKILL_LEVEL_UNFAMILIAR)
return
to_chat(owner, SPAN_NOTICE("Your skill with cooking lets you harvest more parts."))
var/skill_difference = skill_level - SKILL_LEVEL_UNFAMILIAR
*base_meat_amount = *base_meat_amount + skill_difference
if (skill_level >= SKILL_LEVEL_PROFESSIONAL)
*butchering_bonus = *butchering_bonus + skill_difference