diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 89a55b62229..5b68f267610 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -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"
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 803ac7785a3..210500adce1 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -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"
diff --git a/code/datums/components/skills/science/xenobiology_skill_component.dm b/code/datums/components/skills/science/xenobiology_skill_component.dm
index 8b667a1c5ea..7057982aec7 100644
--- a/code/datums/components/skills/science/xenobiology_skill_component.dm
+++ b/code/datums/components/skills/science/xenobiology_skill_component.dm
@@ -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
diff --git a/code/datums/components/skills/service/cooking_skill_component.dm b/code/datums/components/skills/service/cooking_skill_component.dm
index bcfc1bde97e..b5bbe18d777 100644
--- a/code/datums/components/skills/service/cooking_skill_component.dm
+++ b/code/datums/components/skills/service/cooking_skill_component.dm
@@ -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
diff --git a/code/datums/skills/everyday/service.dm b/code/datums/skills/everyday/service.dm
index ffde208532d..56962d34c1f 100644
--- a/code/datums/skills/everyday/service.dm
+++ b/code/datums/skills/everyday/service.dm
@@ -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"
diff --git a/code/datums/skills/occupational/science.dm b/code/datums/skills/occupational/science.dm
index 90817c256dc..94c66712377 100644
--- a/code/datums/skills/occupational/science.dm
+++ b/code/datums/skills/occupational/science.dm
@@ -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.
" \
+ + " - Your melee attacks made against Xenofauna such as Space Carp deal 10% more damage.
" \
+ + " - You harvest one additional part when butchering Xenofauna.",
+ SKILL_LEVEL_TRAINED = "You have a moderate experience with Xenobiology.
" \
+ + " - Your melee attacks made against Xenofauna such as Space Carp deal 15% more damage.
" \
+ + " - You harvest two additional parts when butchering Xenofauna.",
+ SKILL_LEVEL_PROFESSIONAL = "You have extensive experience with Xenobiology.
" \
+ + " - Your melee attacks made against Xenofauna such as Space Carp deal 20% more damage.
" \
+ + " - You harvest three additional parts when butchering Xenofauna.",
)
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index 2396d3ce6c8..15841eeb05d 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -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
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 31f17feaf23..71133f7e971 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -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()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm b/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm
index 8820fe979ae..b478bd13909 100644
--- a/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm
+++ b/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm
@@ -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)
diff --git a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm
index a20d846f789..892ee475c84 100644
--- a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm
@@ -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)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index bae3ce58457..b1cb0743ac4 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -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\The [user] 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("\The [user] 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("\The [user] 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("\The [user] 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)
diff --git a/html/changelogs/hellfirejag-cooking-xenobiology-skill.yml b/html/changelogs/hellfirejag-cooking-xenobiology-skill.yml
new file mode 100644
index 00000000000..f695eecbc5e
--- /dev/null
+++ b/html/changelogs/hellfirejag-cooking-xenobiology-skill.yml
@@ -0,0 +1,5 @@
+author: Hellfirejag
+delete-after: True
+changes:
+ - rscadd: "Cooking Skill now increases the amount of products gained from butchering animals."
+ - rscadd: "Xenobiology Skill now increases melee damage against Space Fauna (EG: Space Carp, Space Bears, etc). Additionally, it also increases butchering products gained from Space Fauna."