mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +01:00
## About The Pull Request Soooooooooooooooooooooooooooooooo tasting code has been jank for a good damn while, and with this we aim to fix that- let's start from the beginning. Earlier when I was making a food item, I noticed that it'd never actually have the taste I gave it, just tasting indescribable as things without tastes do. Weird, cause it definitely has a taste set, and plenty of nutriment subtype reagents!... When looking into it, I noticed that we only copy the tastes to *specifically* the base nutriment and the vitamin subtype: https://github.com/tgstation/tgstation/blob/57b718ad20c3b6af02dbdbc87f3cae4dd4d7e297/code/datums/components/food/edible.dm#L215-L216 But! Surely the other reagents should have tastes, right?.... No: https://github.com/tgstation/tgstation/blob/57b718ad20c3b6af02dbdbc87f3cae4dd4d7e297/code/modules/reagents/chemistry/reagents/food_reagents.dm#L119-L120 we were always returning the tastes data, but never actually setting it except for those two reagents, overriding any and all tastes. This caused the non-taste of the proteins and fats to override the food taste applied to the vitamins with their volume. So, to fix this, we replace these hardcoded ids with a check for `carry_food_tastes` on the nutriment reagent, such that each can individually define whether they carry food tastes. This lets oils have their own tastes, while letting all other nutriments carry the tastes. We then make `get_taste_description(...)` return the base flavour if no special flavour is found, and add base flavours to proteins and vitamins based on what pure proteins/vitamins with no further additives would roughly taste like. This fixes our issue!....... Except, we now always taste something "rich earthy pungent" when we eat. Looking into it, that's the organ tissue reagent, used in our stomachs: https://github.com/tgstation/tgstation/blob/57b718ad20c3b6af02dbdbc87f3cae4dd4d7e297/code/modules/reagents/chemistry/reagents/food_reagents.dm#L232-L236 ....Because whenever we ingest something, we taste the contents of our stomach. This was previously less noticeable, as while it *did* count, it only added a weight for _no flavour_. To fix this we just, well, make it so you taste what you're eating and not the container itself. It's as simple as separating the tasting code from the reagent holder, and making the tasting that happens on ingest exposure use that logic instead. We keep the old logic for the INTJ skillchip and tasting machine, just re-routed through this, and split up some procs to avoid too much duplication. This fixes our issue! Though, there's still some minor issues. This lets us add organ tissue instead of nutriment to other organs so they no longer taste indescribable, as it actually works properly now, but letting organ tissue hold flavours would risk having the stomach organ tissue permanently leech the flavours of the organ tissue you eat. So we make a subtype of organ tissue for the stomach, stomach lining, which cannot hold flavours. This lets us apply the base organ tissue to all other organs without risking stomach contamination. ## Why It's Good For The Game It's jank to taste your stomach contents. It's jank for organs to taste like nothing. It's jank for reagents with flavours to never taste like anything. It's jank for tasteless reagents to block out food flavours. It's jank for organs to only sometimes contain organ tissues. yeah. ## Changelog 🆑 refactor: Refactored tasting code. Please report any jank tasting behaviours. fix: You taste what you eat instead of the contents of your own stomach. fix: Other basic nutriment subtypes also carry food flavours, instead of outweighing the food flavours with their lack of flavour. fix: Basic nutriment subtypes have a flavour they default to, in case of not carrying any food flavours. fix: Oils taste like oil instead of tasting indescribable. fix: Clothing eaten by moths actually carries its flavours instead of tasting indescribable. fix: Organs use organ tissue instead of nutriment. fix: You can actually taste organ tissue. qol: Mineral slurry tastes like minerals instead of tasting indescribable. fix: Tasted flavours can actually be "strong" in addition to mild or "a hint of", as intended. qol: Flavours are only strong when their percentage of what you're tasting is more than 4x taste sensitivity instead of 3x, for most default tongues being 60% and lizards 40% of the drink. qol: Tasted flavours are sorted by strength, stronger flavours coming first. qol: Tasted flavours are grouped into "strong", "mild", and "hint" in the message, replacing "You can taste a hint of bitterness, alcohol, a hint of sweetness, and a hint of cola" with "You can taste alcohol and a hint of bitterness, sweetness, and cola". /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
190 lines
6.2 KiB
Plaintext
190 lines
6.2 KiB
Plaintext
#define DEFAULT_TASTE_SENSITIVITY 15
|
|
|
|
/mob/living
|
|
var/last_taste_time
|
|
var/last_taste_text
|
|
|
|
/**
|
|
* Gets taste sensitivity of given mob
|
|
*
|
|
* This is used in calculating what flavours the mob can pick up,
|
|
* with a lower number being able to pick up more distinct flavours.
|
|
*/
|
|
/mob/living/proc/get_taste_sensitivity()
|
|
return DEFAULT_TASTE_SENSITIVITY
|
|
|
|
/mob/living/carbon/get_taste_sensitivity()
|
|
var/obj/item/organ/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE)
|
|
if(istype(tongue))
|
|
. = tongue.taste_sensitivity
|
|
else
|
|
// carbons without tongues normally have TRAIT_AGEUSIA but sensible fallback
|
|
. = DEFAULT_TASTE_SENSITIVITY
|
|
|
|
/**
|
|
* Non-destructively tastes a reagent container
|
|
* and gives feedback to the user.
|
|
* Arguments:
|
|
* * datum/reagents/from - Reagent holder to taste from.
|
|
**/
|
|
/mob/living/proc/taste_container(datum/reagents/from)
|
|
if(check_tasting_blocks())
|
|
return
|
|
|
|
var/taste_sensitivity = get_taste_sensitivity()
|
|
var/text_output = from.generate_taste_message(src, taste_sensitivity)
|
|
send_taste_message(text_output)
|
|
|
|
/**
|
|
* Non-destructively tastes a reagent list
|
|
* and gives feedback to the user.
|
|
* Arguments:
|
|
* * list/from - List of reagents to taste from.
|
|
**/
|
|
/mob/living/proc/taste_list(list/from)
|
|
if(check_tasting_blocks())
|
|
return
|
|
|
|
var/taste_sensitivity = get_taste_sensitivity()
|
|
var/text_output = generate_reagents_taste_message(from, src, taste_sensitivity)
|
|
send_taste_message(text_output)
|
|
|
|
/**
|
|
* Check for anything blocking/overriding our tasting.
|
|
* Returns TRUE on a block, FALSE if not.
|
|
**/
|
|
/mob/living/proc/check_tasting_blocks()
|
|
if(HAS_TRAIT(src, TRAIT_AGEUSIA))
|
|
return TRUE
|
|
if(last_taste_time + 50 >= world.time)
|
|
return TRUE
|
|
|
|
// Sometimes, try send a replacement message if we're hallucinating
|
|
if(get_timed_status_effect_duration(/datum/status_effect/hallucination) > 100 SECONDS && prob(25))
|
|
var/text_output = pick("spiders","dreams","nightmares","the future","the past","victory",\
|
|
"defeat","pain","bliss","revenge","poison","time","space","death","life","truth","lies","justice","memory",\
|
|
"regrets","your soul","suffering","music","noise","blood","hunger","the american way")
|
|
send_taste_message(text_output)
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/**
|
|
* Attempt to send a taste message using given tastes text.
|
|
**/
|
|
/mob/living/proc/send_taste_message(tastes_text)
|
|
if(tastes_text == last_taste_text && last_taste_time + 100 >= world.time)
|
|
return
|
|
|
|
to_chat(src, span_notice("You can taste [tastes_text]."))
|
|
// "something indescribable" -> too many tastes, not enough flavor.
|
|
|
|
last_taste_time = world.time
|
|
last_taste_text = tastes_text
|
|
|
|
/**
|
|
* Gets food flags that this mob likes
|
|
**/
|
|
/mob/living/proc/get_liked_foodtypes()
|
|
return NONE
|
|
|
|
/mob/living/carbon/get_liked_foodtypes()
|
|
if(HAS_TRAIT(src, TRAIT_AGEUSIA))
|
|
return NONE
|
|
// Handled in here since the brain trauma can't modify taste directly (/datum/brain_trauma/severe/flesh_desire)
|
|
if(HAS_TRAIT(src, TRAIT_FLESH_DESIRE))
|
|
return GORE | MEAT
|
|
var/obj/item/organ/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE)
|
|
. = tongue.liked_foodtypes
|
|
if(HAS_TRAIT(src, TRAIT_VEGETARIAN))
|
|
. &= ~MEAT
|
|
|
|
/**
|
|
* Gets food flags that this mob dislikes
|
|
**/
|
|
/mob/living/proc/get_disliked_foodtypes()
|
|
if(HAS_TRAIT(src, TRAIT_VEGETARIAN))
|
|
return MEAT
|
|
return NONE
|
|
|
|
/mob/living/carbon/get_disliked_foodtypes()
|
|
if(HAS_TRAIT(src, TRAIT_AGEUSIA))
|
|
return NONE
|
|
var/obj/item/organ/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE)
|
|
. = tongue.disliked_foodtypes
|
|
if(HAS_TRAIT(src, TRAIT_VEGETARIAN))
|
|
. |= MEAT
|
|
|
|
/**
|
|
* Gets food flags that this mob hates
|
|
* Toxic food is the only category that ignores ageusia, KEEP IT LIKE THAT!
|
|
**/
|
|
/mob/living/proc/get_toxic_foodtypes()
|
|
return TOXIC
|
|
|
|
/mob/living/carbon/get_toxic_foodtypes()
|
|
var/obj/item/organ/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE)
|
|
if(!tongue)
|
|
return ..()
|
|
if(HAS_TRAIT(src, TRAIT_FLESH_DESIRE))
|
|
return VEGETABLES | DAIRY | FRUIT | FRIED
|
|
return tongue.toxic_foodtypes
|
|
|
|
/**
|
|
* Gets food this mob is allergic to
|
|
* Essentially toxic food+, not only disgusting but outright lethal
|
|
*/
|
|
/mob/living/proc/get_allergic_foodtypes()
|
|
var/datum/quirk/item_quirk/food_allergic/allergy = get_quirk(/datum/quirk/item_quirk/food_allergic)
|
|
return allergy?.target_foodtypes || NONE
|
|
|
|
/**
|
|
* Checks if the mob has an allergic reaction to the given food type.
|
|
* If so, the mob will contract anaphylaxis.
|
|
*
|
|
* * to_foodtype: The food type to check for an allergic reaction to.
|
|
* * chance: The chance of an allergic reaction occurring. Default is 100 (guaranteed).
|
|
* * histamine_add: The amount of histamine to add to the mob if they are already experiencing an allergic reaction.
|
|
*
|
|
* Returns TRUE if the mob had an allergic reaction, FALSE otherwise.
|
|
*/
|
|
/mob/living/proc/check_allergic_reaction(to_foodtype = NONE, chance = 100, histamine_add = 0)
|
|
if(!(get_allergic_foodtypes() & to_foodtype))
|
|
return FALSE
|
|
if(!prob(chance))
|
|
return FALSE
|
|
if(ForceContractDisease(new /datum/disease/anaphylaxis(), make_copy = FALSE, del_on_fail = TRUE))
|
|
to_chat(src, span_warning("You feel your throat start to itch."))
|
|
add_mood_event("allergic_food", /datum/mood_event/allergic_food)
|
|
else if(histamine_add)
|
|
reagents.add_reagent(/datum/reagent/toxin/histamine, histamine_add)
|
|
return TRUE
|
|
|
|
/**
|
|
* Gets the food reaction a mob would normally have from the given food item,
|
|
* assuming that no check_liked callback was used in the edible component.
|
|
*
|
|
* Does not get called if the owner has ageusia.
|
|
**/
|
|
/mob/living/proc/get_food_taste_reaction(obj/item/food, foodtypes)
|
|
var/food_taste_reaction
|
|
if(foodtypes & get_toxic_foodtypes())
|
|
food_taste_reaction = FOOD_TOXIC
|
|
else if(foodtypes & get_disliked_foodtypes())
|
|
food_taste_reaction = FOOD_DISLIKED
|
|
else if(foodtypes & get_liked_foodtypes())
|
|
food_taste_reaction = FOOD_LIKED
|
|
return food_taste_reaction
|
|
|
|
/mob/living/carbon/get_food_taste_reaction(obj/item/food, foodtypes)
|
|
var/obj/item/organ/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE)
|
|
// No tongue, no tastin'
|
|
if(!tongue?.sense_of_taste || HAS_TRAIT(src, TRAIT_AGEUSIA))
|
|
// i hate that i have to do this, but we want to ensure toxic food is still BAD
|
|
if(foodtypes & get_toxic_foodtypes())
|
|
return FOOD_TOXIC
|
|
return
|
|
return tongue.get_food_taste_reaction(food, foodtypes)
|
|
|
|
#undef DEFAULT_TASTE_SENSITIVITY
|