mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 16:47:13 +01:00
Fish (ya know, from fishing) is now edible (#86110)
## About The Pull Request Fish (the item that you catch with a fishing rod) now has an edible component attached to it, making it possible to eat them if you really have to, at the cost of eventually killing and deleting the fish, however, you normally shouldn't. Along with the seafood and meat foodtypes flags, it possess the gore and raw foodtypes too, making them pretty awful to eat unless you're a (non-vegan) lizard, felinid, or wearing the strange bandana*, which can only be found in the cqc kit case. Furthermore, it carry diseases like the ones from food left on the floors for too long, so a strong stomach is required to safely eat it even if you actually like it, dummy... UNLESS you fry or grill it, thus killing the diseases (as well as the fish) and removing both the gore and raw food types, then it becomes an actually ok meal... UNLESS you're dumb enough to eat a pufferfish, a donkfish or a slimefish. That is more or less the general rule. A few fish stray for it. For example, lavaloops are never raw (still gorey). The skeleton fish are never edibles, and holodeck fish is, well, holographic and thus disappears if you try to eat it. *the strange bandana is a reference to MSG, and this is a reference to the MGS3 fish eating animation. This is WIP btw, I'll have to test it and add some then polish it. ## Why It's Good For The Game Whole unprocessed fish should be technically edible, even if not safe to eat nine times out of ten. Also I kinda need this if I want to add a tasty fishing spot to the kitchen deepfriers. ## Changelog 🆑 add: Whole, unprocessed fish is now edible. However it's pretty much reccomended to grill or fry it for over 30 spess seconds before attempting to eat it. fix: germ-covered, dirty food no longer tries to infect you through contact. /🆑
This commit is contained in:
@@ -40,8 +40,6 @@ Behavior that's still missing from this component that original food items had t
|
||||
var/volume = 50
|
||||
///The flavortext for taste (haha get it flavor text)
|
||||
var/list/tastes
|
||||
///Whether to tell the examiner that this is edible or not.
|
||||
var/show_examine = TRUE
|
||||
|
||||
/datum/component/edible/Initialize(
|
||||
list/initial_reagents,
|
||||
@@ -57,7 +55,6 @@ Behavior that's still missing from this component that original food items had t
|
||||
datum/callback/on_consume,
|
||||
datum/callback/check_liked,
|
||||
reagent_purity = 0.5,
|
||||
show_examine = TRUE,
|
||||
)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
@@ -73,7 +70,6 @@ Behavior that's still missing from this component that original food items had t
|
||||
src.on_consume = on_consume
|
||||
src.tastes = string_assoc_list(tastes)
|
||||
src.check_liked = check_liked
|
||||
src.show_examine = show_examine
|
||||
|
||||
setup_initial_reagents(initial_reagents, reagent_purity)
|
||||
|
||||
@@ -81,9 +77,9 @@ Behavior that's still missing from this component that original food items had t
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(UseByAnimal))
|
||||
RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(OnCraft))
|
||||
RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(OnProcessed))
|
||||
RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added))
|
||||
RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, PROC_REF(on_ooze_eat))
|
||||
RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added))
|
||||
RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(OnProcessed))
|
||||
|
||||
if(isturf(parent))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))
|
||||
@@ -216,7 +212,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/owner = parent
|
||||
if(!show_examine)
|
||||
if(food_flags & FOOD_NO_EXAMINE)
|
||||
return
|
||||
if(foodtypes)
|
||||
var/list/types = bitfield_to_list(foodtypes, FOOD_FLAGS)
|
||||
@@ -316,7 +312,6 @@ Behavior that's still missing from this component that original food items had t
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/this_food = parent
|
||||
|
||||
for(var/obj/item/food/crafted_part in parts_list)
|
||||
if(!crafted_part.reagents)
|
||||
continue
|
||||
@@ -325,7 +320,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
|
||||
this_food.reagents.maximum_volume = ROUND_UP(this_food.reagents.maximum_volume) // Just because I like whole numbers for this.
|
||||
|
||||
BLACKBOX_LOG_FOOD_MADE(this_food.type)
|
||||
BLACKBOX_LOG_FOOD_MADE(parent.type)
|
||||
|
||||
///Makes sure the thing hasn't been destroyed or fully eaten to prevent eating phantom edibles
|
||||
/datum/component/edible/proc/IsFoodGone(atom/owner, mob/living/feeder)
|
||||
@@ -462,7 +457,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
|
||||
var/atom/owner = parent
|
||||
|
||||
if(!owner?.reagents)
|
||||
if(!owner.reagents)
|
||||
stack_trace("[eater] failed to bite [owner], because [owner] had no reagents.")
|
||||
return FALSE
|
||||
if(eater.satiety > -200)
|
||||
@@ -479,7 +474,8 @@ Behavior that's still missing from this component that original food items had t
|
||||
if(bitecount == 0)
|
||||
apply_buff(eater)
|
||||
|
||||
var/fraction = min(bite_consumption / owner.reagents.total_volume, 1)
|
||||
var/fraction = 0.3
|
||||
fraction = min(bite_consumption / owner.reagents.total_volume, 1)
|
||||
owner.reagents.trans_to(eater, bite_consumption, transferred_by = feeder, methods = INGEST)
|
||||
bitecount++
|
||||
|
||||
@@ -489,8 +485,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
On_Consume(eater, feeder)
|
||||
|
||||
//Invoke our after eat callback if it is valid
|
||||
if(after_eat)
|
||||
after_eat.Invoke(eater, feeder, bitecount)
|
||||
after_eat?.Invoke(eater, feeder, bitecount)
|
||||
|
||||
//Invoke the eater's stomach's after_eat callback if valid
|
||||
if(iscarbon(eater))
|
||||
@@ -531,7 +526,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
if(recipe_complexity <= 0)
|
||||
return
|
||||
var/obj/item/food/food = parent
|
||||
if(!isnull(food.crafted_food_buff))
|
||||
if(istype(food) && !isnull(food.crafted_food_buff))
|
||||
buff = food.crafted_food_buff
|
||||
else
|
||||
buff = pick_weight(GLOB.food_buffs[min(recipe_complexity, FOOD_COMPLEXITY_5)])
|
||||
@@ -666,7 +661,7 @@ Behavior that's still missing from this component that original food items had t
|
||||
/datum/component/edible/proc/UseByAnimal(datum/source, mob/living/basic/pet/dog/doggy)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isdog(doggy))
|
||||
if(!isdog(doggy) || (food_flags & FOOD_NO_BITECOUNT)) //this entirely relies on bitecounts alas
|
||||
return
|
||||
|
||||
var/atom/food = parent
|
||||
|
||||
@@ -8,43 +8,78 @@
|
||||
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)
|
||||
/datum/component/infective/Initialize(list/datum/disease/diseases, expire_in, weak = FALSE, weak_infection_chance = 10)
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
if(!islist(diseases))
|
||||
diseases = islist(diseases)
|
||||
|
||||
///Make sure the diseases list is populated with instances of diseases so that it doesn't have to be for each AddComponent call.
|
||||
for(var/datum/disease/disease as anything in diseases)
|
||||
if(!disease) //empty entry, remove.
|
||||
diseases -= disease
|
||||
if(ispath(disease, /datum/disease))
|
||||
var/datum/disease/instance = new disease
|
||||
diseases -= disease
|
||||
diseases += instance
|
||||
else if(!istype(disease))
|
||||
stack_trace("found [isdatum(disease) ? "an instance of [disease.type]" : disease] inside the diseases list argument for [type]")
|
||||
diseases -= disease
|
||||
|
||||
src.diseases = diseases
|
||||
|
||||
if(expire_in)
|
||||
expire_time = world.time + expire_in
|
||||
QDEL_IN(src, expire_in)
|
||||
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
is_weak = weak
|
||||
src.weak_infection_chance = weak_infection_chance
|
||||
|
||||
/datum/component/infective/Destroy()
|
||||
QDEL_NULL(diseases)
|
||||
return ..()
|
||||
|
||||
/datum/component/infective/RegisterWithParent()
|
||||
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)
|
||||
return
|
||||
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))
|
||||
if(isorgan(parent))
|
||||
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion))
|
||||
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))
|
||||
if(isorgan(parent))
|
||||
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion))
|
||||
|
||||
/datum/component/infective/UnregisterFromParent()
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_FOOD_EATEN,
|
||||
COMSIG_PILL_CONSUMED,
|
||||
COMSIG_COMPONENT_CLEAN_ACT,
|
||||
COMSIG_MOVABLE_BUMP,
|
||||
COMSIG_MOVABLE_IMPACT_ZONE,
|
||||
COMSIG_ITEM_ATTACK_ZONE,
|
||||
COMSIG_ITEM_ATTACK,
|
||||
COMSIG_ITEM_EQUIPPED,
|
||||
COMSIG_GLASS_DRANK,
|
||||
COMSIG_ORGAN_IMPLANTED,
|
||||
))
|
||||
qdel(GetComponent(/datum/component/connect_loc_behalf))
|
||||
|
||||
/datum/component/infective/proc/on_organ_insertion(obj/item/organ/target, mob/living/carbon/receiver)
|
||||
SIGNAL_HANDLER
|
||||
@@ -62,16 +97,16 @@
|
||||
|
||||
eater.add_mood_event("disgust", /datum/mood_event/disgust/dirty_food)
|
||||
|
||||
if(is_weak && !prob(weak_infection_chance))
|
||||
return
|
||||
|
||||
for(var/datum/disease/disease in diseases)
|
||||
for(var/datum/disease/disease as anything in diseases)
|
||||
if(is_weak && !prob(weak_infection_chance))
|
||||
continue
|
||||
if(!disease.has_required_infectious_organ(eater, ORGAN_SLOT_STOMACH))
|
||||
continue
|
||||
|
||||
eater.ForceContractDisease(disease)
|
||||
|
||||
try_infect(feeder, BODY_ZONE_L_ARM)
|
||||
if(!is_weak)
|
||||
try_infect(feeder, BODY_ZONE_L_ARM)
|
||||
|
||||
/datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder)
|
||||
SIGNAL_HANDLER
|
||||
@@ -79,11 +114,14 @@
|
||||
if(HAS_TRAIT(drinker, TRAIT_STRONG_STOMACH))
|
||||
return
|
||||
|
||||
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)
|
||||
if(!is_weak)
|
||||
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)
|
||||
|
||||
for(var/datum/disease/disease in diseases)
|
||||
for(var/datum/disease/disease as anything in diseases)
|
||||
if(is_weak && !prob(weak_infection_chance))
|
||||
continue
|
||||
if(!disease.has_required_infectious_organ(drinker, ORGAN_SLOT_STOMACH))
|
||||
continue
|
||||
|
||||
@@ -163,19 +201,3 @@
|
||||
/datum/component/infective/proc/try_infect(mob/living/L, target_zone)
|
||||
for(var/V in diseases)
|
||||
L.ContactContractDisease(V, target_zone)
|
||||
|
||||
/datum/component/infective/UnregisterFromParent()
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_FOOD_EATEN,
|
||||
COMSIG_PILL_CONSUMED,
|
||||
COMSIG_COMPONENT_CLEAN_ACT,
|
||||
COMSIG_MOVABLE_BUMP,
|
||||
COMSIG_MOVABLE_IMPACT_ZONE,
|
||||
COMSIG_ITEM_ATTACK_ZONE,
|
||||
COMSIG_ITEM_ATTACK,
|
||||
COMSIG_ITEM_EQUIPPED,
|
||||
COMSIG_GLASS_DRANK,
|
||||
COMSIG_ORGAN_IMPLANTED,
|
||||
))
|
||||
qdel(GetComponent(/datum/component/connect_loc_behalf))
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(SPT_PROB(1, seconds_per_tick) && affected_mob.stat == CONSCIOUS)
|
||||
if(SPT_PROB(1, seconds_per_tick) && affected_mob.stat == CONSCIOUS && affected_mob.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL))
|
||||
to_chat(affected_mob, span_warning("You want to wag your tail..."))
|
||||
affected_mob.emote("wag")
|
||||
if(3)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
/datum/element/consumable_mob/proc/on_consume(atom/movable/source, mob/living/consumer)
|
||||
SIGNAL_HANDLER
|
||||
if(!consumer.combat_mode || !consumer.reagents)
|
||||
if(!consumer.combat_mode || !consumer.reagents || HAS_TRAIT(consumer, TRAIT_PACIFISM))
|
||||
return
|
||||
for(var/reagent_type in reagents_list)
|
||||
if(isnull(reagents_list[reagent_type]))
|
||||
|
||||
@@ -17,28 +17,27 @@
|
||||
var/atom/this_food = target
|
||||
|
||||
switch(fry_time)
|
||||
if(0 to 15)
|
||||
if(0 to 15 SECONDS)
|
||||
this_food.add_atom_colour(fried_colors[1], FIXED_COLOUR_PRIORITY)
|
||||
this_food.name = "lightly-fried [this_food.name]"
|
||||
this_food.desc += " It's been lightly fried in a deep fryer."
|
||||
|
||||
if(15 to 50)
|
||||
if(15 SECONDS to 50 SECONDS)
|
||||
this_food.add_atom_colour(fried_colors[2], FIXED_COLOUR_PRIORITY)
|
||||
this_food.name = "fried [this_food.name]"
|
||||
this_food.desc += " It's been fried, increasing its tastiness value by [rand(1, 75)]%."
|
||||
|
||||
if(50 to 85)
|
||||
if(50 SECONDS to 85 SECONDS)
|
||||
this_food.add_atom_colour(fried_colors[3], FIXED_COLOUR_PRIORITY)
|
||||
this_food.name = "deep-fried [this_food.name]"
|
||||
this_food.desc += " Deep-fried to perfection."
|
||||
|
||||
if(85 to INFINITY)
|
||||
if(85 SECONDS to INFINITY)
|
||||
this_food.add_atom_colour(fried_colors[4], FIXED_COLOUR_PRIORITY)
|
||||
this_food.name = "\proper the physical manifestation of the very concept of fried foods"
|
||||
this_food.desc = "A heavily-fried... something. Who can tell anymore?"
|
||||
|
||||
ADD_TRAIT(this_food, TRAIT_FOOD_FRIED, ELEMENT_TRAIT(type))
|
||||
SEND_SIGNAL(this_food, COMSIG_ITEM_FRIED, fry_time)
|
||||
// Already edible items will inherent these parameters
|
||||
// Otherwise, we will become edible.
|
||||
this_food.AddComponent( \
|
||||
@@ -49,6 +48,7 @@
|
||||
foodtypes = FRIED, \
|
||||
volume = this_food.reagents?.maximum_volume, \
|
||||
)
|
||||
SEND_SIGNAL(this_food, COMSIG_ITEM_FRIED, fry_time)
|
||||
|
||||
/datum/element/fried_item/Detach(atom/source, ...)
|
||||
for(var/color in fried_colors)
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
if(grill_time > 30 SECONDS && isnull(this_food.GetComponent(/datum/component/edible)))
|
||||
this_food.AddComponent(/datum/component/edible, foodtypes = FRIED)
|
||||
|
||||
SEND_SIGNAL(this_food, COMSIG_ITEM_BARBEQUE_GRILLED)
|
||||
SEND_SIGNAL(this_food, COMSIG_ITEM_BARBEQUE_GRILLED, grill_time)
|
||||
ADD_TRAIT(this_food, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type))
|
||||
|
||||
/datum/element/grilled_item/Detach(atom/source, ...)
|
||||
source.name = initial(source.name)
|
||||
source.desc = initial(source.desc)
|
||||
qdel(source.GetComponent(/datum/component/edible)) // Don't care if it was initially edible
|
||||
REMOVE_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type))
|
||||
return ..()
|
||||
|
||||
@@ -49,3 +49,8 @@
|
||||
|
||||
/datum/mood_event/food/top
|
||||
quality = FOOD_QUALITY_TOP
|
||||
|
||||
/datum/mood_event/pacifist_eating_fish_item
|
||||
description = "I shouldn't be eating living creatures..."
|
||||
mood_change = -1 //The disgusting food moodlet already has a pretty big negative value, this is just for context.
|
||||
timeout = 4 MINUTES
|
||||
|
||||
@@ -7,17 +7,4 @@
|
||||
lose_text = span_notice("You feel like eating meat isn't that bad.")
|
||||
medical_record_text = "Patient reports a vegetarian diet."
|
||||
mail_goodies = list(/obj/effect/spawner/random/food_or_drink/salad)
|
||||
|
||||
/datum/quirk/vegetarian/add(client/client_source)
|
||||
var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
|
||||
if(!tongue)
|
||||
return
|
||||
tongue.liked_foodtypes &= ~MEAT
|
||||
tongue.disliked_foodtypes |= MEAT
|
||||
|
||||
/datum/quirk/vegetarian/remove()
|
||||
var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE)
|
||||
if(!tongue)
|
||||
return
|
||||
tongue.liked_foodtypes = initial(tongue.liked_foodtypes)
|
||||
tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes)
|
||||
mob_trait = TRAIT_VEGETARIAN
|
||||
|
||||
Reference in New Issue
Block a user