Files
RikuTheKillerandGitHub c7cb0674cc Preliminary blood refactor (#93854)
## About The Pull Request

Moves all blood handling into procs and adds ways to easily hook into
basically every basic blood behavior.

This PR is not meant to fix every single case of janky blood logic in
the game. The main point and motivation of this PR is to add hooks for
blood behaviors. This allows for way more flexibility with blood code.

I am not going to fix our 3000 instances of single-letter vars, wacky
blood transfers, etc. This is just the groundwork for future PRs to
build off of, and by itself, should do very little to change blood
behavior.

I also added a rigorous set of unit tests for verifying that all of the
basic blood volume procs work correctly.

## Why It's Good For The Game

Previously, blood was handled via directly reading/writing
[var/blood_volume]. This was INCREDIBLY inconsistent and there was no
way to hook into it. This PR makes blood handling way more consistent,
which is great for all sorts of features.
2025-11-13 11:45:36 -06:00

94 lines
3.0 KiB
Plaintext

/mob/living/basic/sheep
name = "sheep"
desc = "Known for their soft wool and use in sacrificial rituals. Big fan of grass."
icon = 'icons/mob/simple/sheep.dmi'
icon_state = "sheep"
icon_dead = "sheep_dead"
base_icon_state = "sheep"
gender = FEMALE
mob_biotypes = MOB_ORGANIC | MOB_BEAST
speak_emote = list("baas","bleats")
speed = 1.1
butcher_results = list(/obj/item/food/meat/slab/grassfed = 3)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
attack_sound = 'sound/items/weapons/punch1.ogg'
attack_vis_effect = ATTACK_EFFECT_KICK
health = 50
maxHealth = 50
gold_core_spawnable = FRIENDLY_SPAWN
default_blood_volume = BLOOD_VOLUME_NORMAL
ai_controller = /datum/ai_controller/basic_controller/sheep
/// Were we sacrificed by cultists?
var/cult_converted = FALSE
/mob/living/basic/sheep/Initialize(mapload)
. = ..()
AddComponent(/datum/component/mob_harvest, \
harvest_tool = /obj/item/razor, \
fed_item = /obj/item/food/grown/grass, \
produced_item_typepath = /obj/item/stack/sheet/cotton/wool, \
produced_item_desc = "soft wool", \
max_ready = 10, \
item_generation_wait = 3 MINUTES, \
item_reduction_time = 30 SECONDS, \
item_harvest_time = 5 SECONDS, \
item_harvest_sound = 'sound/items/handling/surgery/scalpel1.ogg', \
)
AddElement(/datum/element/ai_retaliate)
RegisterSignal(src, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(on_sacrificed))
/mob/living/basic/sheep/update_overlays()
. = ..()
if(stat == DEAD)
return
if(cult_converted)
. += "hat"
/// Signal proc for [COMSIG_LIVING_CULT_SACRIFICED] to have special interaction with sacrificing a lamb
/mob/living/basic/sheep/proc/on_sacrificed(datum/source, list/invokers)
SIGNAL_HANDLER
if(cult_converted)
for(var/mob/living/cultist as anything in invokers)
to_chat(cultist, span_cult_italic("[src] has already been sacrificed!"))
return STOP_SACRIFICE|SILENCE_SACRIFICE_MESSAGE
for(var/mob/living/cultist as anything in invokers)
to_chat(cultist, span_cult_italic("This feels a bit too cliché, don't you think?"))
cult_converted = TRUE
INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, say), "BAAAAAAAAH!")
update_appearance(UPDATE_ICON)
return STOP_SACRIFICE
/mob/living/basic/sheep/vv_edit_var(vname, vval)
if(vname != NAMEOF(src, cult_converted))
return ..()
if(vval == cult_converted)
return FALSE
. = ..()
if(.)
update_appearance(UPDATE_ICON)
/datum/ai_controller/basic_controller/sheep
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = PASSIVE_AI_FLAGS
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/random_speech/sheep,
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
)