mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-31 20:11:56 +00:00
 ## About The Pull Request There is a 10% chance of getting one of 3 new diseases when you eat dirty things. Things become dirty when left on the floor for [more than 5 seconds](https://en.wikipedia.org/wiki/Five-second_rule). But you can wash (with any method you know from spraying water to cleaning with soap) or cook them later to avoid this.  Packaged, bowled, canned food (any food that spawns package as trash afterwards) is protected from this effect. Makes crafted food spawn on nearby tables when the hands are full. Except the one behind you.  #### New diseases: 40% chance:  40% chance (Vomiting is of special type that does not stun):  20% chance:  ## Why It's Good For The Game Things that are left on the floor for too long intentionally are trash that should be disposed by janitor. If you make a meal or prepare a medication, it makes sense that you should keep your product sanitized. Things that are dropped unintentionally are supposed to be picked up quickly. "Oops I dropped this pie, need to pick it up quickly before the germs spread". 5 seconds are enough for this. If you didn't manage you will be like "Oh dammit, now I need to wash this pie in a sink". Now players will consider to not just throw items meant for eating onto the floor neglecting the fact that it looks odd. If they still ignore it, people who consume the items will receive a harmless but annoying disease. In general this PR aims to force some IC gameplay onto Medics, Chefs and Botanists so that they care a bit more about things they make for other players. The items have a warning message saying that they are dirty and dangerous, so the consumers have a way to detect dirty items and an option to wash them with soap/rag/sink/shower/fire extinguisher to remove the harmful part from the edible item. So to avoid this, players just need to examine an item before eating it. Botanists can spray a pile of fruits from a hose for the same effect, and washed items that stay on floor dont regain germs until moved to another tile. Food that converts into another item during cooking (like meat slab turning into steak) or crafting, will not retain the infection. This kinda simulates the sanitizing during cooking. Medics can use elevated structures (e.g. conveyor belt) to avoid getting their pills dirty during creation in plumbing. Or they can wash the pills they want to distribute in the shower before packaging them into pill bottles or a bag. ## Changelog 🆑 add: Food and pills have a 10% chance to infect with one of three new diseases on consumption when left for more than 5 seconds on the floor. You can wash it to avoid disease. ChemMaster and Pill Press are added to the list of elevated structures (Considered as tables for pills). Made harvest spawn on top of hydrotrays to stay protected from germs. add: Added three new advanced diseases: Gastritium, Carpellosis, Nebula Nausea with static cures obtained by digesting dirty food. fix: Food no longer decomposes on Hydrotrays, Grilles, Bonfires and all dense kitchen machinery code: Decomposition now uses `germ_sensitive` component and follows 5 second rule too. qol: Crafted food items spawns on nearby tables (except the one behind you) instead of dropping on floor when hands are full. /🆑
145 lines
5.0 KiB
Plaintext
145 lines
5.0 KiB
Plaintext
/datum/component/infective
|
|
var/list/datum/disease/diseases //make sure these are the static, non-processing versions!
|
|
var/expire_time
|
|
var/required_clean_types = CLEAN_TYPE_DISEASE
|
|
/// The infection is weak and can only infect on consumption with small chance
|
|
var/is_weak = FALSE
|
|
/// Chance of weak infection on consumption
|
|
var/weak_infection_chance = 10
|
|
|
|
|
|
/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in, weak = FALSE)
|
|
if(islist(_diseases))
|
|
diseases = _diseases
|
|
else
|
|
diseases = list(_diseases)
|
|
if(expire_in)
|
|
expire_time = world.time + expire_in
|
|
QDEL_IN(src, expire_in)
|
|
|
|
if(!ismovable(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
is_weak = weak
|
|
|
|
if(is_weak && isitem(parent))
|
|
RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat))
|
|
RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat))
|
|
else
|
|
var/static/list/disease_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(try_infect_crossed),
|
|
)
|
|
AddComponent(/datum/component/connect_loc_behalf, parent, disease_connections)
|
|
|
|
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, PROC_REF(try_infect_buckle))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(try_infect_collide))
|
|
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(try_infect_impact_zone))
|
|
if(isitem(parent))
|
|
RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(try_infect_attack_zone))
|
|
RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(try_infect_attack))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(try_infect_equipped))
|
|
RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat))
|
|
RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat))
|
|
if(istype(parent, /obj/item/reagent_containers/cup))
|
|
RegisterSignal(parent, COMSIG_GLASS_DRANK, PROC_REF(try_infect_drink))
|
|
else if(istype(parent, /obj/effect/decal/cleanable/blood/gibs))
|
|
RegisterSignal(parent, COMSIG_GIBS_STREAK, PROC_REF(try_infect_streak))
|
|
|
|
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
|
|
SIGNAL_HANDLER
|
|
|
|
eater.add_mood_event("disgust", /datum/mood_event/disgust/dirty_food)
|
|
|
|
if(is_weak && !prob(weak_infection_chance))
|
|
return
|
|
|
|
for(var/V in diseases)
|
|
eater.ForceContractDisease(V)
|
|
try_infect(feeder, BODY_ZONE_L_ARM)
|
|
|
|
/datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder)
|
|
SIGNAL_HANDLER
|
|
|
|
for(var/disease in diseases)
|
|
drinker.ForceContractDisease(disease)
|
|
var/appendage_zone = feeder.held_items.Find(source)
|
|
appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM
|
|
try_infect(feeder, appendage_zone)
|
|
|
|
/datum/component/infective/proc/clean(datum/source, clean_types)
|
|
SIGNAL_HANDLER
|
|
|
|
. = NONE
|
|
if(clean_types & required_clean_types)
|
|
qdel(src)
|
|
return COMPONENT_CLEANED
|
|
|
|
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
|
|
SIGNAL_HANDLER
|
|
|
|
if(isliving(M))
|
|
try_infect(M)
|
|
|
|
/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
|
|
SIGNAL_HANDLER
|
|
|
|
var/atom/movable/P = parent
|
|
if(P.throwing)
|
|
//this will be handled by try_infect_impact_zone()
|
|
return
|
|
if(isliving(A))
|
|
try_infect(A)
|
|
|
|
/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
|
|
SIGNAL_HANDLER
|
|
|
|
try_infect(target, hit_zone)
|
|
|
|
/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
|
|
SIGNAL_HANDLER
|
|
|
|
try_infect(user, BODY_ZONE_L_ARM)
|
|
try_infect(target, hit_zone)
|
|
|
|
/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user)
|
|
SIGNAL_HANDLER
|
|
if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone
|
|
try_infect(target)
|
|
try_infect(user, BODY_ZONE_L_ARM)
|
|
|
|
/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
|
|
SIGNAL_HANDLER
|
|
|
|
var/old_bio_armor
|
|
if(isitem(parent))
|
|
//if you are putting an infective item on, it obviously will not protect you, so set its bio armor low enough that it will never block ContactContractDisease()
|
|
var/obj/item/equipped_item = parent
|
|
old_bio_armor = equipped_item.get_armor_rating(BIO)
|
|
equipped_item.set_armor_rating(BIO, 0)
|
|
|
|
try_infect(L, slot2body_zone(slot))
|
|
|
|
if(isitem(parent))
|
|
var/obj/item/equipped_item = parent
|
|
equipped_item.set_armor_rating(BIO, old_bio_armor)
|
|
|
|
/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
|
|
if(isliving(arrived))
|
|
try_infect(arrived, BODY_ZONE_PRECISE_L_FOOT)
|
|
|
|
/datum/component/infective/proc/try_infect_streak(datum/source, list/directions, list/output_diseases)
|
|
SIGNAL_HANDLER
|
|
|
|
// This blood is not infectable / does not have a diseases list
|
|
if(!islist(output_diseases))
|
|
return
|
|
|
|
output_diseases |= diseases
|
|
|
|
/datum/component/infective/proc/try_infect(mob/living/L, target_zone)
|
|
for(var/V in diseases)
|
|
L.ContactContractDisease(V, target_zone)
|