Adds 'Bloody Spreader' component that bloodies everything it touches (#78743)

## About The Pull Request

Adds 'Bloody Spreader' component that bloodies everything it touches!

For example inserting an item into it if it is a storage item. Or
entering it if it's a turf, or bumping onto it, or... you get the point,
hopefully.

Added this component to the MEAT backpack, meat slabs, bouncy castles,
meateor fluff, meateor heart, and the heretic sanguine blade.

Gave most of these the blood walk component as well, which spreads blood
if it's dragged around.

Meat slabs contain a limited amount of both components, eventually they
will 'dry out'.
## Why It's Good For The Game

Meat isn't meaty and squelchy enough, this will make it meatier. It also
makes the janitor suffer.
## Changelog
🆑
code: Adds 'Bloody Spreader' component that bloodies everything it
touches!
code: For example inserting an item into it if it is a storage item. Or
entering it if it's a turf, or bumping onto it, or... you get the point,
hopefully.
add: Added this component to the MEAT backpack, meat slabs, bouncy
castles, meateor fluff, meateor heart, and the heretic sanguine blade.
add: Gave most of these the blood walk component as well, which spreads
blood if it's dragged around.
add: Meat slabs contain a limited amount of both components, eventually
they will 'dry out'.
code: Added a signal for when an item is entered into storage.
/🆑
This commit is contained in:
carlarctg
2023-10-19 21:03:09 +02:00
committed by GitHub
parent dca6a326fa
commit cd030b0690
11 changed files with 173 additions and 5 deletions
@@ -5,3 +5,5 @@
/// Sent after dumping into some other storage object: (atom/dest_object, mob/user)
#define COMSIG_STORAGE_DUMP_POST_TRANSFER "storage_dump_into_storage"
/// Sent to the STORAGE when an ITEM is STORED INSIDE.
#define COMSIG_STORAGE_STORED_ITEM "storage_storing_item"
+45
View File
@@ -0,0 +1,45 @@
/datum/component/bloody_spreader
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
// How many bloodening instances are left. Deleted on zero.
var/blood_left
// We will spread this blood DNA to targets!
var/list/blood_dna
// Blood splashed around everywhere will carry these diseases. Oh no...
var/list/diseases
/datum/component/bloody_spreader/Initialize(blood_left, list/blood_dna, list/diseases)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
var/list/signals_to_add = list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACKBY)
if(ismovable(parent))
signals_to_add += list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT)
if(isitem(parent))
signals_to_add += list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_ATOM, COMSIG_ITEM_HIT_REACT, COMSIG_ITEM_ATTACK_SELF, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)
var/atom/atom_parent = parent
if(atom_parent.atom_storage)
signals_to_add += list(COMSIG_STORAGE_STORED_ITEM)
else if(isstructure(parent))
signals_to_add += list(COMSIG_ATOM_ATTACK_HAND)
RegisterSignals(parent, signals_to_add, PROC_REF(spread_yucky_blood))
if(isclothing(parent))
parent.AddComponent(/datum/component/bloodysoles)
src.blood_left = blood_left
src.blood_dna = blood_dna
src.diseases = diseases
/datum/component/bloody_spreader/proc/spread_yucky_blood(atom/parent, atom/bloody_fool)
SIGNAL_HANDLER
bloody_fool.add_blood_DNA(blood_dna, diseases)
/datum/component/bloody_spreader/InheritComponent(/datum/component/new_comp, i_am_original, blood_left = 0)
if(!i_am_original)
return
if(src.blood_left >= INFINITY)
return
src.blood_left += blood_left
+24 -4
View File
@@ -18,25 +18,45 @@
/datum/material/meat/on_removed(atom/source, amount, material_flags)
. = ..()
qdel(source.GetComponent(/datum/component/edible))
qdel(source.GetComponent(/datum/component/blood_walk))
qdel(source.GetComponent(/datum/component/bloody_spreader))
/datum/material/meat/on_applied_obj(obj/O, amount, material_flags)
. = ..()
make_edible(O, amount, material_flags)
make_meaty(O, amount, material_flags)
/datum/material/meat/on_applied_turf(turf/T, amount, material_flags)
. = ..()
make_edible(T, amount, material_flags)
make_meaty(T, amount, material_flags)
/datum/material/meat/proc/make_edible(atom/source, amount, material_flags)
/datum/material/meat/proc/make_meaty(atom/source, amount, material_flags)
var/nutriment_count = 3 * (amount / SHEET_MATERIAL_AMOUNT)
var/oil_count = 2 * (amount / SHEET_MATERIAL_AMOUNT)
source.AddComponent(/datum/component/edible, \
initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
foodtypes = RAW | MEAT | GROSS, \
eat_time = 3 SECONDS, \
tastes = list("Fleshy"))
tastes = list("Meaty"))
source.AddComponent(
/datum/component/bloody_spreader,\
blood_left = (nutriment_count + oil_count) * 0.3,\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
// Turfs can't handle the meaty goodness of blood walk.
if(!ismovable(source))
return
source.AddComponent(
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 35,\
max_blood = (nutriment_count + oil_count) * 0.3,\
)
/datum/material/meat/mob_meat
init_flags = MATERIAL_INIT_BESPOKE
var/subjectname = ""
+2
View File
@@ -433,6 +433,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
if(!can_insert(to_insert, user, force = force))
return FALSE
SEND_SIGNAL(resolve_location, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force)
to_insert.item_flags |= IN_STORAGE
to_insert.forceMove(resolve_location)
item_insertion_feedback(user, to_insert, override)
+40
View File
@@ -4,6 +4,28 @@
icon = 'icons/obj/food/meat.dmi'
var/subjectname = ""
var/subjectjob = null
var/blood_decal_type = /obj/effect/decal/cleanable/blood
/obj/item/food/meat/Initialize(mapload)
. = ..()
if(!blood_decal_type)
return
AddComponent(
/datum/component/blood_walk,\
blood_type = blood_decal_type,\
blood_spawn_chance = 45,\
max_blood = custom_materials[custom_materials[1]],\
)
AddComponent(
/datum/component/bloody_spreader,\
blood_left = custom_materials[custom_materials[1]],\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
/obj/item/food/meat/slab
name = "meat"
@@ -55,6 +77,7 @@
tastes = list("slime" = 1, "jelly" = 1)
foodtypes = MEAT | RAW | TOXIC
venue_value = FOOD_MEAT_MUTANT_RARE
blood_decal_type = null
/obj/item/food/meat/slab/human/mutant/golem
icon_state = "golemmeat"
@@ -66,6 +89,7 @@
tastes = list("rock" = 1)
foodtypes = MEAT | RAW | GROSS
venue_value = FOOD_MEAT_MUTANT_RARE
blood_decal_type = null
/obj/item/food/meat/slab/human/mutant/golem/adamantine
icon_state = "agolemmeat"
@@ -89,6 +113,7 @@
tastes = list("salad" = 1, "wood" = 1)
foodtypes = VEGETABLES
venue_value = FOOD_MEAT_MUTANT_RARE
blood_decal_type = /obj/effect/decal/cleanable/food/plant_smudge
/obj/item/food/meat/slab/human/mutant/shadow
icon_state = "shadowmeat"
@@ -107,6 +132,7 @@
tastes = list("maggots" = 1, "the inside of a reactor" = 1)
foodtypes = MEAT | RAW | GROSS | BUGS | GORE
venue_value = FOOD_MEAT_MUTANT
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/slab/human/mutant/moth
icon_state = "mothmeat"
@@ -122,6 +148,7 @@
tastes = list("bone" = 1)
foodtypes = GROSS | GORE
venue_value = FOOD_MEAT_MUTANT_RARE
blood_decal_type = null
/obj/item/food/meat/slab/human/mutant/skeleton/make_processable()
return //skeletons dont have cutlets
@@ -140,6 +167,7 @@
tastes = list("pure electricity" = 2, "meat" = 1)
foodtypes = RAW | MEAT | TOXIC | GORE
venue_value = FOOD_MEAT_MUTANT
blood_decal_type = null
////////////////////////////////////// OTHER MEATS ////////////////////////////////////////////////////////
@@ -174,6 +202,7 @@
name = "bug meat"
icon_state = "spidermeat"
foodtypes = RAW | MEAT | BUGS
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/slab/mouse
name = "mouse meat"
@@ -219,6 +248,7 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 2)
tastes = list("tomato" = 1)
foodtypes = FRUIT
blood_decal_type = /obj/effect/decal/cleanable/food/tomato_smudge
/obj/item/food/meat/slab/killertomato/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/steak/killertomato, rand(70 SECONDS, 85 SECONDS), TRUE, TRUE)
@@ -260,6 +290,7 @@
bite_consumption = 4
tastes = list("meat" = 1, "acid" = 1)
foodtypes = RAW | MEAT
blood_decal_type = /obj/effect/decal/cleanable/xenoblood
/obj/item/food/meat/slab/xeno/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/xeno, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
@@ -278,6 +309,7 @@
)
tastes = list("cobwebs" = 1)
foodtypes = RAW | MEAT | TOXIC
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/slab/spider/make_processable()
AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/meat/rawcutlet/spider, 3, 3 SECONDS, table_required = TRUE, screentip_verb = "Cut")
@@ -512,10 +544,12 @@
/obj/item/food/meat/steak/xeno
name = "xeno steak"
tastes = list("meat" = 1, "acid" = 1)
blood_decal_type = /obj/effect/decal/cleanable/xenoblood
/obj/item/food/meat/steak/spider
name = "spider steak"
tastes = list("cobwebs" = 1)
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/steak/goliath
name = "goliath steak"
@@ -618,6 +652,7 @@
name = "raw killer tomato cutlet"
tastes = list("tomato" = 1)
foodtypes = FRUIT
blood_decal_type = /obj/effect/decal/cleanable/food/tomato_smudge
/obj/item/food/meat/rawcutlet/killertomato/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/cutlet/killertomato, rand(35 SECONDS, 50 SECONDS), TRUE, TRUE)
@@ -636,6 +671,7 @@
/obj/item/food/meat/rawcutlet/xeno
name = "raw xeno cutlet"
tastes = list("meat" = 1, "acid" = 1)
blood_decal_type = /obj/effect/decal/cleanable/xenoblood
/obj/item/food/meat/rawcutlet/xeno/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/cutlet/xeno, rand(35 SECONDS, 50 SECONDS), TRUE, TRUE)
@@ -643,6 +679,7 @@
/obj/item/food/meat/rawcutlet/spider
name = "raw spider cutlet"
tastes = list("cobwebs" = 1)
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/rawcutlet/spider/make_grillable()
AddComponent(/datum/component/grillable, /obj/item/food/meat/cutlet/spider, rand(35 SECONDS, 50 SECONDS), TRUE, TRUE)
@@ -719,6 +756,7 @@
name = "killer tomato cutlet"
tastes = list("tomato" = 1)
foodtypes = FRUIT
blood_decal_type = /obj/effect/decal/cleanable/food/tomato_smudge
/obj/item/food/meat/cutlet/bear
name = "bear cutlet"
@@ -727,10 +765,12 @@
/obj/item/food/meat/cutlet/xeno
name = "xeno cutlet"
tastes = list("meat" = 1, "acid" = 1)
blood_decal_type = /obj/effect/decal/cleanable/xenoblood
/obj/item/food/meat/cutlet/spider
name = "spider cutlet"
tastes = list("cobwebs" = 1)
blood_decal_type = /obj/effect/decal/cleanable/insectguts
/obj/item/food/meat/cutlet/gondola
name = "gondola cutlet"
+15 -1
View File
@@ -247,6 +247,7 @@
throwforce = 15
attack_verb_continuous = list("MEATS", "MEAT MEATS")
attack_verb_simple = list("MEAT", "MEAT MEAT")
custom_materials = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT * 25) // MEAT
///Sounds used in the squeak component
var/list/meat_sounds = list('sound/effects/blobattack.ogg' = 1)
///Reagents added to the edible component, ingested when you EAT the MEAT
@@ -263,13 +264,26 @@
/obj/item/storage/backpack/meat/Initialize(mapload)
. = ..()
AddComponent(/datum/component/edible,\
AddComponent(
/datum/component/edible,\
initial_reagents = meat_reagents,\
foodtypes = foodtypes,\
tastes = tastes,\
eatverbs = eatverbs,\
)
AddComponent(/datum/component/squeak, meat_sounds)
AddComponent(
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 15,\
max_blood = 300,\
)
AddComponent(
/datum/component/bloody_spreader,\
blood_left = INFINITY,\
blood_dna = list("MEAT DNA" = "MT+"),\
diseases = null,\
)
/*
* Satchel Types
@@ -139,6 +139,19 @@
if(gored)
name = gored.real_name
AddComponent(
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 66.6,\
max_blood = INFINITY,\
)
AddComponent(/datum/component/bloody_spreader,\
blood_left = INFINITY,\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
/obj/structure/bouncy_castle/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
@@ -88,6 +88,23 @@
inhand_icon_state = "flesh_blade"
after_use_message = "The Marshal hears your call..."
/obj/item/melee/sickly_blade/flesh/Initialize(mapload)
. = ..()
AddComponent(
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 66.6,\
max_blood = INFINITY,\
)
AddComponent(
/datum/component/bloody_spreader,\
blood_left = INFINITY,\
blood_dna = list("Unknown DNA" = "X*"),\
diseases = null,\
)
// Path of Void's blade
/obj/item/melee/sickly_blade/void
name = "\improper void blade"
@@ -44,6 +44,14 @@
icon = 'icons/mob/simple/meteor_heart.dmi'
anchored = TRUE
/obj/structure/meateor_fluff/Initialize(mapload)
. = ..()
AddComponent(/datum/component/bloody_spreader,\
blood_left = INFINITY,\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
/obj/structure/meateor_fluff/play_attack_sound(damage_amount, damage_type, damage_flag)
switch(damage_type)
if(BRUTE)
@@ -60,6 +60,12 @@
soundloop.pressure_affected = FALSE
soundloop.start()
AddComponent(/datum/component/bloody_spreader,\
blood_left = INFINITY,\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
/// Called when we get mad at something, either for attacking us or attacking the nearby area
/mob/living/basic/meteor_heart/proc/aggro()
if (ai_controller.ai_status == AI_STATUS_ON)
+1
View File
@@ -954,6 +954,7 @@
#include "code\datums\components\beetlejuice.dm"
#include "code\datums\components\blob_minion.dm"
#include "code\datums\components\blood_walk.dm"
#include "code\datums\components\bloody_spreader.dm"
#include "code\datums\components\bloodysoles.dm"
#include "code\datums\components\boomerang.dm"
#include "code\datums\components\boss_music.dm"