From cd030b06907fed576ce46fccf01eed933c23a032 Mon Sep 17 00:00:00 2001 From: carlarctg <53100513+carlarctg@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:03:09 -0300 Subject: [PATCH] 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 :cl: 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. /:cl: --- code/__DEFINES/dcs/signals/signals_storage.dm | 2 + code/datums/components/bloody_spreader.dm | 45 +++++++++++++++++++ code/datums/materials/meat.dm | 28 ++++++++++-- code/datums/storage/storage.dm | 2 + code/game/objects/items/food/meatslab.dm | 40 +++++++++++++++++ code/game/objects/items/storage/backpack.dm | 16 ++++++- .../fugitive/hunters/hunter_gear.dm | 13 ++++++ .../heretic/items/heretic_blades.dm | 17 +++++++ .../mapfluff/ruins/spaceruin_code/meateor.dm | 8 ++++ .../space_fauna/meteor_heart/meteor_heart.dm | 6 +++ tgstation.dme | 1 + 11 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 code/datums/components/bloody_spreader.dm diff --git a/code/__DEFINES/dcs/signals/signals_storage.dm b/code/__DEFINES/dcs/signals/signals_storage.dm index b30039dc12f..45b6ec6bfe3 100644 --- a/code/__DEFINES/dcs/signals/signals_storage.dm +++ b/code/__DEFINES/dcs/signals/signals_storage.dm @@ -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" diff --git a/code/datums/components/bloody_spreader.dm b/code/datums/components/bloody_spreader.dm new file mode 100644 index 00000000000..951136c890c --- /dev/null +++ b/code/datums/components/bloody_spreader.dm @@ -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 diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 68d3c1d77ab..a742a9c7129 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -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 = "" diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index a61a8725a30..239ab4acac3 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -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) diff --git a/code/game/objects/items/food/meatslab.dm b/code/game/objects/items/food/meatslab.dm index 483aa736074..9959f20db7c 100644 --- a/code/game/objects/items/food/meatslab.dm +++ b/code/game/objects/items/food/meatslab.dm @@ -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" diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 0461d76cb99..ee0f232a216 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -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 diff --git a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm index 013359e9a68..acb31c08ac0 100644 --- a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm +++ b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm @@ -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) diff --git a/code/modules/antagonists/heretic/items/heretic_blades.dm b/code/modules/antagonists/heretic/items/heretic_blades.dm index 63493a5dc4b..6bd8d22fb9e 100644 --- a/code/modules/antagonists/heretic/items/heretic_blades.dm +++ b/code/modules/antagonists/heretic/items/heretic_blades.dm @@ -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" diff --git a/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm b/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm index fc79c82e780..59998bb53c8 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/meateor.dm @@ -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) diff --git a/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm b/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm index 5829b52e437..6a41993526e 100644 --- a/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm +++ b/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm @@ -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) diff --git a/tgstation.dme b/tgstation.dme index 4f2c02f3738..aa505747833 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -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"