mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-24 21:40:55 +01:00
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:
@@ -141,5 +141,8 @@
|
||||
/// Signal raised against a character attempting to deliver a speech.
|
||||
#define COMSIG_GET_LEADERSHIP_MODIFIERS "get_leadership_modifiers"
|
||||
|
||||
/// Signal raised against a character attempting to butcher a mob, to check for butchering bonuses from skills.
|
||||
#define COMSIG_GET_BUTCHERING_MODIFIERS "get_butchering_modifiers"
|
||||
|
||||
// Crafting Signals
|
||||
#define COMSIG_GET_CRAFTING_MODIFIERS "get_crafting_modifiers"
|
||||
|
||||
@@ -224,3 +224,8 @@
|
||||
|
||||
/// Unlinks gliding from movement speed, meaning that there will be a delay between movements rather than a single move movement between tiles
|
||||
#define TRAIT_NO_GLIDE "no_glide"
|
||||
|
||||
// MOB CATEGORY traits used for pattern matching certain subtypes of mobs
|
||||
#define TRAIT_SOURCE_MOB_CATEGORY "mob_category"
|
||||
/// All "Space Fauna" EG: Space Carp
|
||||
#define TRAIT_MC_SPACE_FAUNA "space_fauna"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,11 +14,18 @@
|
||||
|
||||
/singleton/skill/cooking
|
||||
name = "Cooking"
|
||||
description = "Currently unimplemented."
|
||||
description = "Users of this skill gain bonuses when harvesting parts from animals."
|
||||
maximum_level = SKILL_LEVEL_PROFESSIONAL
|
||||
category = /singleton/skill_category/everyday
|
||||
subcategory = SKILL_SUBCATEGORY_SERVICE
|
||||
component_type = COOKING_SKILL_COMPONENT
|
||||
skill_level_descriptions = alist(
|
||||
SKILL_LEVEL_UNFAMILIAR = "You have no modifiers from cooking.",
|
||||
SKILL_LEVEL_FAMILIAR = "You gain +1 product when butchering any animal",
|
||||
SKILL_LEVEL_TRAINED = "You gain +2 products when butchering any animal",
|
||||
SKILL_LEVEL_PROFESSIONAL = "You gain +3 products when butchering any animal"
|
||||
)
|
||||
|
||||
|
||||
/singleton/skill/gardening
|
||||
name = "Gardening"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
uneducated_skill_cap = SKILL_LEVEL_TRAINED
|
||||
category = /singleton/skill_category/occupational
|
||||
subcategory = SKILL_SUBCATEGORY_SCIENCE
|
||||
required = TRUE
|
||||
component_type = RESEARCH_SKILL_COMPONENT
|
||||
|
||||
/singleton/skill/xenobotany
|
||||
@@ -33,14 +32,19 @@
|
||||
+ "Having this skill at least at the \"Trained\" rank is required to extract cores from slimes. " \
|
||||
+ "Ranks in this skill also provide small situational bonuses when interacting with aliens in general."
|
||||
maximum_level = SKILL_LEVEL_PROFESSIONAL
|
||||
uneducated_skill_cap = SKILL_LEVEL_TRAINED
|
||||
uneducated_skill_cap = SKILL_LEVEL_PROFESSIONAL
|
||||
category = /singleton/skill_category/occupational
|
||||
subcategory = SKILL_SUBCATEGORY_SCIENCE
|
||||
component_type = XENOBOTANY_SKILL_COMPONENT
|
||||
required = TRUE
|
||||
skill_level_descriptions = alist(
|
||||
SKILL_LEVEL_UNFAMILIAR = "You have no modifiers from this skill.",
|
||||
SKILL_LEVEL_FAMILIAR = "You have a very small bonus to both success rate and surgery speed when performing surgeries on aliens in general.",
|
||||
SKILL_LEVEL_TRAINED = "You have a small bonus to both success rate and surgery speed when performing surgeries on aliens in general.",
|
||||
SKILL_LEVEL_PROFESSIONAL = "You have a moderate bonus to both success rate and surgery speed when performing surgeries on aliens in general."
|
||||
SKILL_LEVEL_UNFAMILIAR = "You have little to no knowledge of Xenobiology",
|
||||
SKILL_LEVEL_FAMILIAR = "You have a passing experience with Xenobiology.<br>" \
|
||||
+ " - Your melee attacks made against Xenofauna such as Space Carp deal 10% more damage.<br>" \
|
||||
+ " - You harvest one additional part when butchering Xenofauna.",
|
||||
SKILL_LEVEL_TRAINED = "You have a moderate experience with Xenobiology.<br>" \
|
||||
+ " - Your melee attacks made against Xenofauna such as Space Carp deal 15% more damage.<br>" \
|
||||
+ " - You harvest two additional parts when butchering Xenofauna.",
|
||||
SKILL_LEVEL_PROFESSIONAL = "You have extensive experience with Xenobiology.<br>" \
|
||||
+ " - Your melee attacks made against Xenofauna such as Space Carp deal 20% more damage.<br>" \
|
||||
+ " - You harvest three additional parts when butchering Xenofauna.",
|
||||
)
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
. = ..()
|
||||
emote_sounds = quiet_sounds
|
||||
update_bearmode()
|
||||
ADD_TRAIT(src, TRAIT_MC_SPACE_FAUNA, TRAIT_SOURCE_MOB_CATEGORY)
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/proc/set_stance(var/input)
|
||||
var/previous = stance
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
add_language(LANGUAGE_GREIMORIAN_HIVEMIND)
|
||||
remove_language(LANGUAGE_TCB)
|
||||
default_language = GLOB.all_languages[LANGUAGE_GREIMORIAN]
|
||||
ADD_TRAIT(src, TRAIT_MC_SPACE_FAUNA, TRAIT_SOURCE_MOB_CATEGORY)
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/servant/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
|
||||
var/burrowing = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/phoron_worm/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_MC_SPACE_FAUNA, TRAIT_SOURCE_MOB_CATEGORY)
|
||||
|
||||
/mob/living/simple_animal/hostile/phoron_worm/death()
|
||||
..(null,"collapses under its own weight!")
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
smart_melee = FALSE
|
||||
sample_data = list("Cellular structure shows adaptation for survival in vacuum", "Genetic biomarkers identified linked with agressiveness", "Tissue sample contains micro-gas release structures")
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_MC_SPACE_FAUNA, TRAIT_SOURCE_MOB_CATEGORY)
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/update_icon()
|
||||
..()
|
||||
if(resting || stat == DEAD)
|
||||
@@ -319,3 +323,7 @@
|
||||
flying = TRUE
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE
|
||||
sample_data = list("Cellular structure shows adaptation for survival in vacuum", "Genetic biomarkers identified linked with agressiveness", "Tissue sample contains micro-gas release structures")
|
||||
|
||||
/mob/living/simple_animal/hostile/gnat/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_MC_SPACE_FAUNA, TRAIT_SOURCE_MOB_CATEGORY)
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
var/milk_type = /singleton/reagent/drink/milk
|
||||
|
||||
/// If anything else is created when butchering this creature, like bones and leather
|
||||
var/list/butchering_products
|
||||
var/alist/butchering_products
|
||||
|
||||
var/psi_pingable = TRUE
|
||||
|
||||
@@ -900,27 +900,33 @@
|
||||
return FALSE
|
||||
|
||||
/// Harvest an animal's delicious byproducts
|
||||
/mob/living/simple_animal/proc/harvest(var/mob/user)
|
||||
var/actual_meat_amount = max(1,(meat_amount*0.75))
|
||||
if(meat_type && actual_meat_amount>0 && (stat == DEAD))
|
||||
for(var/i=0;i<actual_meat_amount;i++)
|
||||
new meat_type(get_turf(src))
|
||||
/mob/living/simple_animal/proc/harvest(mob/user)
|
||||
if (!meat_type || (stat != DEAD))
|
||||
return
|
||||
|
||||
if(butchering_products)
|
||||
for(var/path in butchering_products)
|
||||
var/number = butchering_products[path]
|
||||
for(var/i in 1 to number)
|
||||
new path(get_turf(src))
|
||||
var/base_meat_amount = meat_amount - rand(0, 2)
|
||||
var/butchering_bonus = 0
|
||||
SEND_SIGNAL(user, COMSIG_GET_BUTCHERING_MODIFIERS, src, &base_meat_amount, &butchering_bonus)
|
||||
if (base_meat_amount <= 0)
|
||||
return
|
||||
|
||||
if(issmall(src))
|
||||
user.visible_message("<b>\The [user]</b> chops up \the [src]!")
|
||||
var/obj/effect/decal/cleanable/blood/splatter/S = new /obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
S.basecolor = blood_type
|
||||
S.update_icon()
|
||||
qdel(src)
|
||||
else
|
||||
user.visible_message("<b>\The [user]</b> butchers \the [src] messily!")
|
||||
gib()
|
||||
for (var/i = 0; i < base_meat_amount; i++)
|
||||
new meat_type(get_turf(src))
|
||||
|
||||
for (var/path, number in butchering_products)
|
||||
var/total_product = number + butchering_bonus
|
||||
for (var/i in 1 to total_product)
|
||||
new path(get_turf(src))
|
||||
|
||||
if (issmall(src))
|
||||
user.visible_message("<b>\The [user]</b> chops up \the [src]!")
|
||||
var/obj/effect/decal/cleanable/blood/splatter/S = new /obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
S.basecolor = blood_type
|
||||
S.update_icon()
|
||||
qdel(src)
|
||||
else
|
||||
user.visible_message("<b>\The [user]</b> butchers \the [src] messily!")
|
||||
gib()
|
||||
|
||||
/// For picking up small animals
|
||||
/mob/living/simple_animal/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
|
||||
|
||||
Reference in New Issue
Block a user