From 48de09b7a4f72b21690601fcbbfb3c30064c86c0 Mon Sep 17 00:00:00 2001 From: Qustinnus Date: Tue, 4 Feb 2020 07:05:55 +0100 Subject: [PATCH] Edible component; be gone vile organ code (#48596) * component * progress * stuff * Makes minor progress on edible component * Finishes component and applies it to organs * newline * forgot to send signal * domob addition * wave that organ flag * return adde * fixes some minor issues * fixes * done * done * done * added last one * done * done * fix --- code/__DEFINES/components.dm | 3 + code/__DEFINES/food.dm | 4 + code/__DEFINES/obj_flags.dm | 3 +- code/_onclick/other_mobs.dm | 2 +- code/datums/components/edible.dm | 237 ++++++++++++++++++ code/game/objects/items.dm | 1 + .../antagonists/abductor/equipment/gland.dm | 1 + code/modules/food_and_drinks/food.dm | 3 - .../mining/equipment/regenerative_core.dm | 3 - code/modules/mob/living/brain/brain_item.dm | 4 - .../modules/mob/living/carbon/alien/organs.dm | 12 +- .../carbon/alien/special/alien_embryo.dm | 6 +- code/modules/surgery/organ_manipulation.dm | 11 +- code/modules/surgery/organs/appendix.dm | 6 - code/modules/surgery/organs/heart.dm | 8 +- code/modules/surgery/organs/liver.dm | 237 +++++++++--------- code/modules/surgery/organs/lungs.dm | 7 +- code/modules/surgery/organs/organ_internal.dm | 42 +--- code/modules/surgery/organs/tongue.dm | 1 + tgstation.dme | 1 + 20 files changed, 395 insertions(+), 197 deletions(-) create mode 100644 code/datums/components/edible.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 943e9c005e5..eed6589f7f2 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -84,6 +84,7 @@ #define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called #define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) +#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal" //from base of atom/animal_attack(): (/mob/user) #define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) #define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) //Positions for overrides list @@ -299,6 +300,8 @@ #define COMPONENT_BLOCK_MARK_RETRIEVAL 1 #define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) #define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable, mob/living/crossed) +#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M) + // /obj/item/clothing signals #define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 60f99c4c750..62bdd1d8c38 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -19,3 +19,7 @@ #define DRINK_VERYGOOD 3 #define DRINK_FANTASTIC 4 #define FOOD_AMAZING 5 + +#define FOOD_IN_CONTAINER (1<<0) + +#define STOP_SERVING_BREAKFAST (15 MINUTES) diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index a4b07f97e20..6ef4d0ca692 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -51,4 +51,5 @@ #define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed #define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change. #define ORGAN_VITAL (1<<4) //Currently only the brain -#define ORGAN_SYNTHETIC_EMP (1<<5) //Synthetic organ affected by an EMP. Deteriorates over time. +#define ORGAN_EDIBLE (1<<5) //is a snack? :D +#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time. diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index f6668eef33e..1d6c4d82852 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -97,7 +97,7 @@ A.attack_animal(src) /atom/proc/attack_animal(mob/user) - return + SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_ANIMAL, user) /mob/living/RestrainedClickOn(atom/A) return diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm new file mode 100644 index 00000000000..22825fe3de2 --- /dev/null +++ b/code/datums/components/edible.dm @@ -0,0 +1,237 @@ +/*! + +This component makes it possible to make things edible. What this means is that you can take a bite or force someone to take a bite (in the case of items). +These items take a specific time to eat, and can do most of the things our original food items could. + +Behavior that's still missing from this component that original food items had that should either be put into seperate components or somewhere else: + Components: + Drying component (jerky etc) + Customizable component (custom pizzas etc) + Processable component (Slicing and cooking behavior essentialy, making it go from item A to B when conditions are met.) + Dunkable component (Dunking things into reagent containers to absorb a specific amount of reagents) + + Misc: + Something for cakes (You can store things inside) + +*/ +/datum/component/edible + ///Amount of reagents taken per bite + var/bite_consumption = 2 + ///Amount of bites taken so far + var/bitecount = 0 + ///Flags for food + var/food_flags = NONE + ///Bitfield of the types of this food + var/foodtypes = NONE + ///Amount of seconds it takes to eat this food + var/eat_time = 30 + ///Defines how much it lowers someones satiety (Need to eat, essentialy) + var/junkiness = 0 + ///Message to send when eating + var/list/eatverbs + ///Callback to be ran for when you take a bite of something + var/datum/callback/after_eat + ///Last time we checked for food likes + var/last_check_time + +/datum/component/edible/Initialize(list/initial_reagents, food_flags = NONE, foodtypes = NONE, volume = 50, eat_time = 30, list/tastes, list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), bite_consumption = 2, datum/callback/after_eat) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, .proc/UseByAnimal) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/UseFromHand) + else if(isturf(parent)) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/TryToEatTurf) + + src.bite_consumption = bite_consumption + src.food_flags = food_flags + src.foodtypes = foodtypes + src.eat_time = eat_time + src.eatverbs = eatverbs + src.junkiness = junkiness + src.after_eat = after_eat + + var/atom/owner = parent + + owner.create_reagents(volume, INJECTABLE) + + if(initial_reagents) + for(var/rid in initial_reagents) + var/amount = initial_reagents[rid] + if(tastes && tastes.len && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin)) + owner.reagents.add_reagent(rid, amount, tastes.Copy()) + else + owner.reagents.add_reagent(rid, amount) + +/datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list) + if(!food_flags & FOOD_IN_CONTAINER) + switch (bitecount) + if (0) + return + if(1) + examine_list += "[parent] was bitten by someone!" + if(2,3) + examine_list += "[parent] was bitten [bitecount] times!" + else + examine_list += "[parent] was bitten multiple times!" + +/datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user) + return TryToEat(M, user) + +/datum/component/edible/proc/TryToEatTurf(datum/source, mob/user) + return TryToEat(user, user) + +///All the checks for the act of eating itself and +/datum/component/edible/proc/TryToEat(mob/living/eater, mob/living/feeder) + + var/atom/owner = parent + + if(feeder.a_intent == INTENT_HARM) + return + if(!owner.reagents.total_volume)//Shouldn't be needed but it checks to see if it has anything left in it. + to_chat(feeder, "None of [owner] left, oh no!") + qdel(parent) + return + if(!CanConsume(eater, feeder)) + return + var/fullness = eater.nutrition + 10 //The theoretical fullness of the person eating if they were to eat this + for(var/datum/reagent/consumable/C in eater.reagents.reagent_list) //we add the nutrition value of what we're currently digesting + fullness += C.nutriment_factor * C.volume / C.metabolization_rate + + . = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose + + if(eater == feeder)//If you're eating it yourself. + if(!do_mob(feeder, eater, eat_time)) //Gotta pass the minimal eat time + return + var/eatverb = pick(eatverbs) + if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS)) + to_chat(eater, "You don't feel like eating any more junk food at the moment!") + return + else if(fullness <= 50) + eater.visible_message("[eater] hungrily [eatverb]s \the [parent], gobbling it down!", "You hungrily [eatverb] \the [parent], gobbling it down!") + else if(fullness > 50 && fullness < 150) + eater.visible_message("[eater] hungrily [eatverb]s \the [parent].", "You hungrily [eatverb] \the [parent].") + else if(fullness > 150 && fullness < 500) + eater.visible_message("[eater] [eatverb]s \the [parent].", "You [eatverb] \the [parent].") + else if(fullness > 500 && fullness < 600) + eater.visible_message("[eater] unwillingly [eatverb]s a bit of \the [parent].", "You unwillingly [eatverb] a bit of \the [parent].") + else if(fullness > (600 * (1 + eater.overeatduration / 2000))) // The more you eat - the more you can eat + eater.visible_message("[eater] cannot force any more of \the [parent] to go down [eater.p_their()] throat!", "You cannot force any more of \the [parent] to go down your throat!") + return + else //If you're feeding it to someone else. + if(isbrain(eater)) + to_chat(feeder, "[eater] doesn't seem to have a mouth!") + return + if(fullness <= (600 * (1 + eater.overeatduration / 1000))) + eater.visible_message("[feeder] attempts to feed [eater] [parent].", \ + "[feeder] attempts to feed you [parent].") + else + eater.visible_message("[feeder] cannot force any more of [parent] down [eater]'s throat!", \ + "[feeder] cannot force any more of [parent] down your throat!") + return + if(!do_mob(feeder, eater)) //Wait 3 seconds before you can feed + return + + log_combat(feeder, eater, "fed", owner.reagents.log_list()) + eater.visible_message("[feeder] forces [eater] to eat [parent]!", \ + "[feeder] forces you to eat [parent]!") + + TakeBite(eater, feeder) + +///This function lets the eater take a bite and transfers the reagents to the eater. +/datum/component/edible/proc/TakeBite(mob/living/eater, mob/living/feeder) + + var/atom/owner = parent + + if(!owner.reagents) + return FALSE + if(eater.satiety > -200) + eater.satiety -= junkiness + playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE) + if(owner.reagents.total_volume) + SEND_SIGNAL(parent, COMSIG_FOOD_EATEN, eater, feeder) + var/fraction = min(bite_consumption / owner.reagents.total_volume, 1) + owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, method = INGEST) + bitecount++ + On_Consume(eater) + checkLiked(fraction, eater) + + //Invoke our after eat callback if it is valid + if(after_eat) + after_eat.Invoke(eater, feeder) + + return TRUE + +///Checks whether or not the eater can actually consume the food +/datum/component/edible/proc/CanConsume(mob/living/eater, mob/living/feeder) + if(!iscarbon(eater)) + return FALSE + var/mob/living/carbon/C = eater + var/covered = "" + if(C.is_mouth_covered(head_only = 1)) + covered = "headgear" + else if(C.is_mouth_covered(mask_only = 1)) + covered = "mask" + if(covered) + var/who = (isnull(feeder) || eater == feeder) ? "your" : "[eater.p_their()]" + to_chat(feeder, "You have to remove [who] [covered] first!") + return FALSE + return TRUE + +///Check foodtypes to see if we should send a moodlet +/datum/component/edible/proc/checkLiked(var/fraction, mob/M) + if(last_check_time + 50 > world.time) + return FALSE + if(!ishuman(M)) + return FALSE + var/mob/living/carbon/human/H = M + if(HAS_TRAIT(H, TRAIT_AGEUSIA) && foodtypes & H.dna.species.toxic_food) + to_chat(H, "You don't feel so good...") + H.adjust_disgust(25 + 30 * fraction) + else + if(foodtypes & H.dna.species.toxic_food) + to_chat(H,"What the hell was that thing?!") + H.adjust_disgust(25 + 30 * fraction) + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food) + else if(foodtypes & H.dna.species.disliked_food) + to_chat(H,"That didn't taste very good...") + H.adjust_disgust(11 + 15 * fraction) + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food) + else if(foodtypes & H.dna.species.liked_food) + to_chat(H,"I love this taste!") + H.adjust_disgust(-5 + -2.5 * fraction) + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food) + if((foodtypes & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST) + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast) + last_check_time = world.time + +///Delete the item when it is fully eaten +/datum/component/edible/proc/On_Consume(mob/living/eater) + + var/atom/owner = parent + + if(!eater) + return + if(!owner.reagents.total_volume) + qdel(parent) + +///Ability to feed food to puppers +/datum/component/edible/proc/UseByAnimal(datum/source, mob/user) + + var/atom/owner = parent + + if(!isdog(user)) + return + var/mob/living/L = user + if(bitecount == 0 || prob(50)) + L.emote("me", 1, "nibbles away at \the [parent]") + bitecount++ + . = COMPONENT_ITEM_NO_ATTACK + L.taste(owner.reagents) // why should carbons get all the fun? + if(bitecount >= 5) + var/sattisfaction_text = pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where \the [parent] was") + if(sattisfaction_text) + L.emote("me", 1, "[sattisfaction_text]") + qdel(parent) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 1a8415c549c..6eba8746a31 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -702,6 +702,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) ..() /obj/item/proc/microwave_act(obj/machinery/microwave/M) + SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M) if(istype(M) && M.dirty < 100) M.dirty++ diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index b1cd2c8ff71..a9f31b8ecc6 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/abductor.dmi' icon_state = "gland" status = ORGAN_ROBOTIC + organ_flags = NONE beating = TRUE var/true_name = "baseline placebo referencer" var/cooldown_low = 300 diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index 0c79f436033..037a64f3480 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -5,7 +5,6 @@ /// the parent to the exclusion list in code/__HELPERS/unsorted.dm's /// get_random_food proc. //////////////////////////////////////////////////////////////////////////////// -#define STOP_SERVING_BREAKFAST (15 MINUTES) /obj/item/reagent_containers/food possible_transfer_amounts = list() @@ -46,5 +45,3 @@ if((foodtype & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST) SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast) last_check_time = world.time - -#undef STOP_SERVING_BREAKFAST diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index e755393d1e3..386fb930a44 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -110,9 +110,6 @@ go_inert() return ..() -/obj/item/organ/regenerative_core/prepare_eat() - return null - /*************************Legion core********************/ /obj/item/organ/regenerative_core/legion desc = "A strange rock that crackles with power. It can be used to heal completely, but it will rapidly decay into uselessness." diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 39464265edb..cfafea6ca42 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -69,10 +69,6 @@ transfer_identity(C) C.update_hair() -/obj/item/organ/brain/prepare_eat(mob/living/carbon/human/H) - if(iszombie(H))//braaaaaains... otherwise, too important to eat. - ..() - /obj/item/organ/brain/proc/transfer_identity(mob/living/L) name = "[L.name]'s brain" if(brainmob || decoy_override) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 5f59ee1cd89..290df6982a9 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -1,5 +1,6 @@ /obj/item/organ/alien icon_state = "xgibmid2" + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/toxin/acid = 10) var/list/alien_powers = list() /obj/item/organ/alien/Initialize() @@ -24,11 +25,6 @@ M.RemoveAbility(P) ..() -/obj/item/organ/alien/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent(/datum/reagent/toxin/acid, 10) - return S - /obj/item/organ/alien/plasmavessel name = "plasma vessel" @@ -37,17 +33,13 @@ zone = BODY_ZONE_CHEST slot = "plasmavessel" alien_powers = list(/obj/effect/proc_holder/alien/plant, /obj/effect/proc_holder/alien/transfer) + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/toxin/plasma = 10) var/storedPlasma = 100 var/max_plasma = 250 var/heal_rate = 5 var/plasma_rate = 10 -/obj/item/organ/alien/plasmavessel/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent(/datum/reagent/toxin/plasma, storedPlasma/10) - return S - /obj/item/organ/alien/plasmavessel/large name = "large plasma vessel" icon_state = "plasma_large" diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 6090f5b35fa..a8904eef6a8 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -4,6 +4,7 @@ name = "alien embryo" icon = 'icons/mob/alien.dmi' icon_state = "larva0_dead" + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/toxin/acid = 10) var/stage = 0 var/bursting = FALSE @@ -16,11 +17,6 @@ if(prob(10)) AttemptGrow(0) -/obj/item/organ/body_egg/alien_embryo/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent(/datum/reagent/toxin/acid, 10) - return S - /obj/item/organ/body_egg/alien_embryo/on_life() . = ..() switch(stage) diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 173420aecd4..e02df6b395f 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -68,7 +68,7 @@ time = 64 name = "manipulate organs" repeatable = 1 - implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100) + implements = list(/obj/item/organ = 100, /obj/item/organ_storage = 100) var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55) var/current_type var/obj/item/organ/I = null @@ -94,7 +94,10 @@ if(target_zone != I.zone || target.getorganslot(I.slot)) to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!") return -1 - + var/obj/item/organ/meatslab = tool + if(!meatslab.useable) + to_chat(user, "[I] seems to have been chewed on, you can't use this!") + return -1 display_results(user, target, "You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...", "[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].", "[user] begins to insert something into [target]'s [parse_zone(target_zone)].") @@ -122,10 +125,6 @@ else return -1 - else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ)) - to_chat(user, "[tool] was bitten by someone! It's too damaged to use!") - return -1 - /datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) if(current_type == "insert") if(istype(tool, /obj/item/organ_storage)) diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm index 23d3a2ceb08..89937e7b5fc 100644 --- a/code/modules/surgery/organs/appendix.dm +++ b/code/modules/surgery/organs/appendix.dm @@ -39,9 +39,3 @@ ..() if(inflamed) M.ForceContractDisease(new /datum/disease/appendicitis(), FALSE, TRUE) - -/obj/item/organ/appendix/prepare_eat() - var/obj/S = ..() - if(inflamed) - S.reagents.add_reagent(/datum/reagent/toxin/bad_food, 5) - return S diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index f9a1436d840..311b14e9585 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -54,10 +54,10 @@ update_icon() return 1 -/obj/item/organ/heart/prepare_eat() - var/obj/S = ..() - S.icon_state = "heart-off" - return S +/obj/item/organ/heart/OnEatFrom(eater, feeder) + . = ..() + beating = FALSE + update_icon() /obj/item/organ/heart/on_life() ..() diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 45d71eb2fff..fca2b6092a7 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -1,120 +1,117 @@ -#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out -#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver - -/obj/item/organ/liver - name = "liver" - icon_state = "liver" - w_class = WEIGHT_CLASS_SMALL - zone = BODY_ZONE_CHEST - slot = ORGAN_SLOT_LIVER - desc = "Pairing suggestion: chianti and fava beans." - - maxHealth = STANDARD_ORGAN_THRESHOLD - healing_factor = STANDARD_ORGAN_HEALING - decay_factor = STANDARD_ORGAN_DECAY - - var/alcohol_tolerance = ALCOHOL_RATE //affects how much damage the liver takes from alcohol - var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE //maximum amount of toxins the liver can just shrug off - var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY //affects how much damage toxins do to the liver - var/filterToxins = TRUE //whether to filter toxins - -#define HAS_SILENT_TOXIN 0 //don't provide a feedback message if this is the only toxin present -#define HAS_NO_TOXIN 1 -#define HAS_PAINFUL_TOXIN 2 - -/obj/item/organ/liver/on_life() - var/mob/living/carbon/C = owner - ..() //perform general on_life() - if(istype(C)) - if(!(organ_flags & ORGAN_FAILING) && !HAS_TRAIT(C, TRAIT_NOMETABOLISM))//can't process reagents with a failing liver - - var/provide_pain_message = HAS_NO_TOXIN - if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER)) - //handle liver toxin filtration - for(var/datum/reagent/toxin/T in C.reagents.reagent_list) - var/thisamount = C.reagents.get_reagent_amount(T.type) - if (thisamount && thisamount <= toxTolerance) - C.reagents.remove_reagent(T.type, 1) - else - damage += (thisamount*toxLethality) - if(provide_pain_message != HAS_PAINFUL_TOXIN) - provide_pain_message = T.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN - - //metabolize reagents - C.reagents.metabolize(C, can_overdose=TRUE) - - if(provide_pain_message && damage > 10 && prob(damage/3))//the higher the damage the higher the probability - to_chat(C, "You feel a dull pain in your abdomen.") - - else //for when our liver's failing - C.liver_failure() - - if(damage > maxHealth)//cap liver damage - damage = maxHealth - -#undef HAS_SILENT_TOXIN -#undef HAS_NO_TOXIN -#undef HAS_PAINFUL_TOXIN - -/obj/item/organ/liver/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent(/datum/reagent/iron, 5) - return S - -/obj/item/organ/liver/fly - name = "insectoid liver" - icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits. - desc = "A mutant liver designed to handle the unique diet of a flyperson." - alcohol_tolerance = 0.007 //flies eat vomit, so a lower alcohol tolerance is perfect! - -/obj/item/organ/liver/plasmaman - name = "reagent processing crystal" - icon_state = "liver-p" - desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen." - -/obj/item/organ/liver/alien - name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage - icon_state = "liver-x" // Same sprite as fly-person liver. - desc = "A liver that used to belong to a killer alien, who knows what it used to eat." - toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 2.5 // rejects its owner early after too much punishment - toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful - -/obj/item/organ/liver/cybernetic - name = "basic cybernetic liver" - icon_state = "liver-c" - desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver." - organ_flags = ORGAN_SYNTHETIC - toxTolerance = 2 - toxLethality = 0.011 - maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 - - var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. - -/obj/item/organ/liver/cybernetic/tier2 - name = "cybernetic liver" - icon_state = "liver-c-u" - desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver." - maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD - toxTolerance = 5 //can shrug off up to 5u of toxins - toxLethality = 0.008 //20% less damage than a normal liver - emp_vulnerability = 40 - -/obj/item/organ/liver/cybernetic/tier3 - name = "upgraded cybernetic liver" - icon_state = "liver-c-u2" - desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." - alcohol_tolerance = 0.001 - maxHealth = 2 * STANDARD_ORGAN_THRESHOLD - toxTolerance = 10 //can shrug off up to 10u of toxins - toxLethality = 0.008 //20% less damage than a normal liver - emp_vulnerability = 20 - -/obj/item/organ/liver/cybernetic/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - if(world.time > severe_cooldown) //So we cant just spam emp to kill people. - owner.adjustToxLoss(10) - severe_cooldown = world.time + 10 SECONDS - if(prob(emp_vulnerability/severity)) //Chance of permanent effects - organ_flags = ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. +#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out +#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver + +/obj/item/organ/liver + name = "liver" + icon_state = "liver" + w_class = WEIGHT_CLASS_SMALL + zone = BODY_ZONE_CHEST + slot = ORGAN_SLOT_LIVER + desc = "Pairing suggestion: chianti and fava beans." + + maxHealth = STANDARD_ORGAN_THRESHOLD + healing_factor = STANDARD_ORGAN_HEALING + decay_factor = STANDARD_ORGAN_DECAY + + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/iron = 5) + + var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol + var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off + var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver + var/filterToxins = TRUE //whether to filter toxins + +#define HAS_SILENT_TOXIN 0 //don't provide a feedback message if this is the only toxin present +#define HAS_NO_TOXIN 1 +#define HAS_PAINFUL_TOXIN 2 + +/obj/item/organ/liver/on_life() + var/mob/living/carbon/C = owner + ..() //perform general on_life() + if(istype(C)) + if(!(organ_flags & ORGAN_FAILING) && !HAS_TRAIT(C, TRAIT_NOMETABOLISM))//can't process reagents with a failing liver + + var/provide_pain_message = HAS_NO_TOXIN + if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER)) + //handle liver toxin filtration + for(var/datum/reagent/toxin/T in C.reagents.reagent_list) + var/thisamount = C.reagents.get_reagent_amount(T.type) + if (thisamount && thisamount <= toxTolerance) + C.reagents.remove_reagent(T.type, 1) + else + damage += (thisamount*toxLethality) + if(provide_pain_message != HAS_PAINFUL_TOXIN) + provide_pain_message = T.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN + + //metabolize reagents + C.reagents.metabolize(C, can_overdose=TRUE) + + if(provide_pain_message && damage > 10 && prob(damage/3))//the higher the damage the higher the probability + to_chat(C, "You feel a dull pain in your abdomen.") + + else //for when our liver's failing + C.liver_failure() + + if(damage > maxHealth)//cap liver damage + damage = maxHealth + +#undef HAS_SILENT_TOXIN +#undef HAS_NO_TOXIN +#undef HAS_PAINFUL_TOXIN + +/obj/item/organ/liver/fly + name = "insectoid liver" + icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits. + desc = "A mutant liver designed to handle the unique diet of a flyperson." + alcohol_tolerance = 0.007 //flies eat vomit, so a lower alcohol tolerance is perfect! + +/obj/item/organ/liver/plasmaman + name = "reagent processing crystal" + icon_state = "liver-p" + desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen." + +/obj/item/organ/liver/alien + name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage + icon_state = "liver-x" // Same sprite as fly-person liver. + desc = "A liver that used to belong to a killer alien, who knows what it used to eat." + toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 2.5 // rejects its owner early after too much punishment + toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful + +/obj/item/organ/liver/cybernetic + name = "basic cybernetic liver" + icon_state = "liver-c" + desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver." + organ_flags = ORGAN_SYNTHETIC + toxTolerance = 2 + toxLethality = 0.011 + maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 + + var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + +/obj/item/organ/liver/cybernetic/tier2 + name = "cybernetic liver" + icon_state = "liver-c-u" + desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver." + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + toxTolerance = 5 //can shrug off up to 5u of toxins + toxLethality = 0.008 //20% less damage than a normal liver + emp_vulnerability = 40 + +/obj/item/organ/liver/cybernetic/tier3 + name = "upgraded cybernetic liver" + icon_state = "liver-c-u2" + desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." + alcohol_tolerance = 0.001 + maxHealth = 2 * STANDARD_ORGAN_THRESHOLD + toxTolerance = 10 //can shrug off up to 10u of toxins + toxLethality = 0.008 //20% less damage than a normal liver + emp_vulnerability = 20 + +/obj/item/organ/liver/cybernetic/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(world.time > severe_cooldown) //So we cant just spam emp to kill people. + owner.adjustToxLoss(10) + severe_cooldown = world.time + 10 SECONDS + if(prob(emp_vulnerability/severity)) //Chance of permanent effects + organ_flags = ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 26c54d188d1..1a2496bbb05 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -15,6 +15,9 @@ now_fixed = "Your lungs seem to once again be able to hold air." high_threshold_cleared = "The constriction around your chest loosens as your breathing calms down." + + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5) + //Breath damage var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa @@ -402,10 +405,6 @@ failed = FALSE return -/obj/item/organ/lungs/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 5) - return S /obj/item/organ/lungs/plasmaman name = "plasma filter" diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index f795ba8aa03..1a4b6b96e51 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -8,7 +8,7 @@ var/zone = BODY_ZONE_CHEST var/slot // DO NOT add slots with matching names to different zones - it will break internal_organs_slot list! - var/organ_flags = 0 + var/organ_flags = ORGAN_EDIBLE var/maxHealth = STANDARD_ORGAN_THRESHOLD var/damage = 0 //total damage this organ has sustained ///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick @@ -26,6 +26,15 @@ var/high_threshold_cleared var/low_threshold_cleared + ///When you take a bite you cant jam it in for surgery anymore. + var/useable = TRUE + var/list/food_reagents = list(/datum/reagent/consumable/nutriment = 5) + +/obj/item/organ/Initialize() + . = ..() + if(organ_flags & ORGAN_EDIBLE) + AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GROSS, null, 10, null, null, null, CALLBACK(src, .proc/OnEatFrom)) + /obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE) if(!iscarbon(M) || owner == M) return @@ -101,24 +110,6 @@ if(damage > high_threshold) . += "[src] is starting to look discolored." - -/obj/item/organ/proc/prepare_eat() - var/obj/item/reagent_containers/food/snacks/organ/S = new - S.name = name - S.desc = desc - S.icon = icon - S.icon_state = icon_state - S.w_class = w_class - - return S - -/obj/item/reagent_containers/food/snacks/organ - name = "appendix" - icon_state = "appendix" - icon = 'icons/obj/surgery.dmi' - list_reagents = list(/datum/reagent/consumable/nutriment = 5) - foodtype = RAW | MEAT | GROSS - /obj/item/organ/Initialize() . = ..() START_PROCESSING(SSobj, src) @@ -132,17 +123,8 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/organ/attack(mob/living/carbon/M, mob/user) - if(M == user && ishuman(user)) - var/mob/living/carbon/human/H = user - if(status == ORGAN_ORGANIC) - var/obj/item/reagent_containers/food/snacks/S = prepare_eat(H) - if(S) - qdel(src) - if(H.put_in_active_hand(S)) - S.attack(H, H) - else - ..() +/obj/item/organ/proc/OnEatFrom(eater, feeder) + useable = FALSE //You can't use it anymore after eating it you spaztic /obj/item/organ/item_action_slot_check(slot,mob/user) return //so we don't grant the organ's action to mobs who pick up the organ. diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index d6e2a313d75..8c020ccfa85 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -248,6 +248,7 @@ name = "robotic voicebox" desc = "A voice synthesizer that can interface with organic lifeforms." status = ORGAN_ROBOTIC + organ_flags = NONE icon_state = "tonguerobot" say_mod = "states" attack_verb = list("beeped", "booped") diff --git a/tgstation.dme b/tgstation.dme index 6871a49bbdc..d1f5933768d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -382,6 +382,7 @@ #include "code\datums\components\decal.dm" #include "code\datums\components\dejavu.dm" #include "code\datums\components\earprotection.dm" +#include "code\datums\components\edible.dm" #include "code\datums\components\edit_complainer.dm" #include "code\datums\components\empprotection.dm" #include "code\datums\components\explodable.dm"