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:
Ghom
2024-09-15 13:13:47 +02:00
committed by GitHub
parent d460c4a9ef
commit 8d0e6734fe
45 changed files with 692 additions and 161 deletions
+229 -5
View File
@@ -20,8 +20,6 @@
drop_sound = 'sound/creatures/fish/fish_drop1.ogg'
pickup_sound = SFX_FISH_PICKUP
sound_vary = TRUE
///The grind results of the fish. They scale with the weight of the fish.
grind_results = list(/datum/reagent/blood = 5, /datum/reagent/consumable/liquidgibs = 5)
obj_flags = UNIQUE_RENAME
item_flags = IMMUTABLE_SLOW|SLOWS_WHILE_IN_HAND
@@ -150,6 +148,14 @@
///have we recently pet this fish
var/recently_petted = FALSE
/**
* If you wonder why this isn't being tracked by the edible component instead:
* We reset the this value when revived, and slowly chip it away as we heal.
* Of course, it would be daunting to get this to be handled by the edible component
* given its complexity.
*/
var/bites_amount = 0
/obj/item/fish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
//It's important that we register the signals before the component is attached.
@@ -163,6 +169,7 @@
RegisterSignal(src, COMSIG_ATOM_TEMPORARY_ANIMATION_START, PROC_REF(on_temp_animation))
check_environment()
if(status != FISH_DEAD)
ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, REF(src)) //Composting a food that is not real food wouldn't work anyway.
START_PROCESSING(SSobj, src)
//stops new fish from being able to reproduce right away.
@@ -175,6 +182,174 @@
register_evolutions()
///Main proc that makes the fish edible.
/obj/item/fish/proc/make_edible()
var/foodtypes = get_food_types()
if(foodtypes & RAW)
AddComponent(/datum/component/infective, GLOB.floor_diseases.Copy(), weak = TRUE, weak_infection_chance = PERFORM_ALL_TESTS(edible_fish) ? 100 : 15)
else
AddComponent(/datum/component/germ_sensitive)
var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR
create_reagents(INFINITY) //We'll set this to the total volume of the reagents right after generate_fish_reagents() is over
generate_fish_reagents(bites_to_finish)
reagents.maximum_volume = round(reagents.total_volume * 1.25) //make some meager space for condiments.
AddComponent(/datum/component/edible, \
food_flags = FOOD_NO_EXAMINE|FOOD_NO_BITECOUNT, \
foodtypes = foodtypes, \
volume = reagents.total_volume, \
eat_time = 1.5 SECONDS, \
bite_consumption = reagents.total_volume / bites_to_finish, \
after_eat = CALLBACK(src, PROC_REF(after_eat)), \
check_liked = CALLBACK(src, PROC_REF(check_liked)), \
reagent_purity = 1, \
)
RegisterSignals(src, list(COMSIG_ITEM_FRIED, COMSIG_ITEM_BARBEQUE_GRILLED), PROC_REF(on_fish_cooked))
///A proc that returns the food types the edible component has when initialized.
/obj/item/fish/proc/get_food_types()
return SEAFOOD|MEAT|RAW|GORE
///Kill the fish, remove the raw and gore food types, and the infectiveness too if not under-cooked.
/obj/item/fish/proc/on_fish_cooked(datum/source, cooking_time)
SIGNAL_HANDLER
SHOULD_NOT_OVERRIDE(TRUE)
adjust_health(0)
//Remove the blood from the reagents holder and reward the player with some extra nutriment added to the fish.
var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE)
var/datum/reagent/blood/blood = reagents.has_reagent(/datum/reagent/blood)
var/old_blood_volume = blood?.volume
reagents.del_reagent(/datum/reagent/blood)
///Make space for the additional nutriment
var/volume_mult = 1
if(bites_amount)
var/initial_bites_left = weight / FISH_WEIGHT_BITE_DIVISOR
var/bites_left = initial_bites_left - bites_amount
volume_mult = initial_bites_left / bites_left
adjust_reagents_capacity((protein?.volume - old_blood_volume) * volume_mult)
///Add the extra nutriment
if(protein)
reagents.multiply_single_reagent(/datum/reagent/consumable/nutriment/protein, 2)
var/datum/component/edible/edible = GetComponent(/datum/component/edible)
edible.foodtypes &= ~(RAW|GORE)
if(cooking_time >= FISH_SAFE_COOKING_DURATION)
well_cooked()
///override the signals so they don't mess with blood and proteins again.
RegisterSignals(src, list(COMSIG_ITEM_FRIED, COMSIG_ITEM_BARBEQUE_GRILLED), PROC_REF(on_fish_cooked_again), TRUE)
///Just kill the fish, again, and perhaps remove the infective comp.
/obj/item/fish/proc/on_fish_cooked_again(datum/source, cooking_time)
SIGNAL_HANDLER
adjust_health(0)
if(cooking_time >= FISH_SAFE_COOKING_DURATION)
well_cooked()
///The fish is well cooked. Change how the fish tastes, remove the infective comp and add the relative trait.
/obj/item/fish/proc/well_cooked()
qdel(GetComponent(/datum/component/infective))
AddComponent(/datum/component/germ_sensitive)
ADD_TRAIT(src, TRAIT_FISH_WELL_COOKED, INNATE_TRAIT)
var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE)
if(protein)
protein.data = get_fish_taste_cooked()
///Checks if the fish is liked or not when eaten by a human.
/obj/item/fish/proc/check_liked(mob/living/eater)
if(HAS_TRAIT(eater, TRAIT_PACIFISM) && (status == FISH_ALIVE ||HAS_MIND_TRAIT(eater, TRAIT_NAIVE)))
eater.add_mood_event("eating_fish", /datum/mood_event/pacifist_eating_fish_item)
return FOOD_TOXIC
if(HAS_TRAIT(eater, TRAIT_AGEUSIA))
return
if(HAS_TRAIT(eater, TRAIT_FISH_EATER) && !HAS_TRAIT(eater, TRAIT_VEGETARIAN))
return FOOD_LIKED
/**
* Fish is not a reagent holder yet it's edible, so it doen't behave like most other snacks
* which means it has its own way of handling being bitten, which is defined here.
*/
/obj/item/fish/proc/after_eat(mob/living/eater, mob/living/feeder)
SHOULD_CALL_PARENT(TRUE)
if(!reagents.total_volume)
return
bites_amount++
var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR
adjust_health(health - (initial(health) / bites_to_finish) * 3)
if(status == FISH_ALIVE && prob(50) && feeder.is_holding(src) && feeder.dropItemToGround(src))
to_chat(feeder, span_warning("[src] slips out of your hands in pain!"))
var/turf/target_turf = get_ranged_target_turf(get_turf(src), pick(GLOB.alldirs), 2)
throw_at(target_turf)
///A proc that returns a static reagent holder with a set reagents that you'd get when eating this fish.
/obj/item/fish/proc/generate_fish_reagents(multiplier = 1)
SHOULD_NOT_OVERRIDE(TRUE)
var/list/reagents_to_add = get_base_edible_reagents_to_add()
SEND_SIGNAL(src, COMSIG_GENERATE_REAGENTS_TO_ADD, reagents_to_add)
if(multiplier != 1)
for(var/reagent in reagents_to_add)
reagents_to_add[reagent] *= multiplier
reagents.add_reagent_list(reagents_to_add, added_purity = 1)
var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE)
if(protein)
protein.data = HAS_TRAIT(src, TRAIT_FISH_WELL_COOKED) ? get_fish_taste_cooked() : get_fish_taste()
/obj/item/fish/proc/get_fish_taste()
return list("raw fish" = 2.5, "scales" = 1)
/obj/item/fish/proc/get_fish_taste_cooked()
return list("cooked fish" = 2)
///The proc that adds in the main reagents this fish has when eaten (without accounting for traits)
/obj/item/fish/proc/get_base_edible_reagents_to_add()
var/return_list = list(
/datum/reagent/consumable/nutriment/protein = 2,
/datum/reagent/blood = 1,
)
//It has been at the very least under-cooked.
if(HAS_TRAIT(src, TRAIT_FOOD_FRIED) || HAS_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED))
return_list[/datum/reagent/consumable/nutriment/protein] *= 2
return_list -= /datum/reagent/blood
if(required_fluid_type == AQUARIUM_FLUID_SALTWATER)
return_list[/datum/reagent/consumable/salt] = 0.4
return return_list
///adjusts the maximum volume of the fish reagents holder and update the amount of food to bite
/obj/item/fish/proc/adjust_reagents_capacity(amount_to_add)
if(!reagents)
return
reagents.maximum_volume += amount_to_add
var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR
///updates how many units of reagent one bite takes if edible.
if(IS_EDIBLE(src))
AddComponent(/datum/component/edible, bite_consumption = reagents.maximum_volume / bites_to_finish)
///Grinding a fish replaces some the protein it has with blood and gibs. You ain't getting a clean smoothie out of it.
/obj/item/fish/on_grind()
. = ..()
if(!reagents)
return
reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/consumable/liquidgibs, 0.4, include_source_subtypes = TRUE)
reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/blood, 0.2, include_source_subtypes = TRUE)
///When processed, the reagents inside this fish will be passed to the created atoms.
/obj/item/fish/UsedforProcessing(mob/living/user, obj/item/used_item, list/chosen_option, list/created_atoms)
var/created_len = length(created_atoms)
for(var/atom/movable/created as anything in created_atoms)
if(!created.reagents)
continue
for(var/datum/reagent/reagent as anything in reagents.reagent_list)
var/transfer_vol = reagent.volume / created_len
var/datum/reagent/result_reagent = created.reagents.has_reagent(reagent.type)
if(!result_reagent)
created.reagents.add_reagent(reagent.type, transfer_vol, reagents.copy_data(reagent), reagents.chem_temp, reagent.purity, reagent.ph, no_react = TRUE)
continue
var/multiplier = transfer_vol / result_reagent.volume
created.reagents.multiply_single_reagent(reagent.type, multiplier)
return ..()
/obj/item/fish/update_icon_state()
if(status == FISH_DEAD && icon_state_dead)
icon_state = icon_state_dead
@@ -214,6 +389,8 @@
. += span_notice("It weighs [weight] g.")
if(HAS_TRAIT(src, TRAIT_FISHING_BAIT))
. += span_smallnoticeital("It can be used as a fishing bait.")
if(bites_amount)
. += span_warning("It's been bitten by someone.")
///Randomizes weight and size.
/obj/item/fish/proc/randomize_size_and_weight(base_size = average_size, base_weight = average_weight, deviation = weight_size_deviation)
@@ -272,11 +449,32 @@
num_fillets = amount
AddElement(/datum/element/processable, TOOL_KNIFE, fillet_type, num_fillets, 0.5 SECONDS * num_fillets, screentip_verb = "Cut")
var/make_edible = TRUE
if(weight)
for(var/reagent_type in grind_results)
grind_results[reagent_type] /= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1)
if(reagents) //This fish has reagents. Adjust the maximum volume of the reagent holder and do some math to adjut the reagents too.
var/new_weight_ratio = new_weight / weight
var/volume_diff = reagents.maximum_volume * new_weight_ratio - reagents.maximum_volume
if(new_weight_ratio > weight)
adjust_reagents_capacity(volume_diff)
///As always, we want to maintain proportions here, so we need to get the ratio of bites left and initial bites left.
var/weight_diff = new_weight - weight
var/multiplier = weight_diff / FISH_WEIGHT_BITE_DIVISOR
var/initial_bites_left = weight / FISH_WEIGHT_BITE_DIVISOR
var/bites_left = initial_bites_left - bites_amount
var/amount_to_gen = bites_left / initial_bites_left * multiplier
generate_fish_reagents(amount_to_gen)
else
reagents.multiply_reagents(new_weight_ratio)
adjust_reagents_capacity(volume_diff)
make_edible = FALSE
weight = new_weight
if(make_edible)
make_edible()
if(weight >= FISH_WEIGHT_SLOWDOWN)
slowdown = round(((weight/FISH_WEIGHT_SLOWDOWN_DIVISOR)**FISH_WEIGHT_SLOWDOWN_EXPONENT)-1.3, 0.1)
drag_slowdown = round(slowdown * 0.5, 1)
@@ -492,12 +690,15 @@
if(FISH_ALIVE)
status = FISH_ALIVE
health = initial(health) // since the fishe has been revived
regenerate_bites(bites_amount)
last_feeding = world.time //reset hunger
check_environment()
START_PROCESSING(SSobj, src)
ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT)
if(FISH_DEAD)
status = FISH_DEAD
STOP_PROCESSING(SSobj, src)
REMOVE_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT)
stop_flopping()
if(!silent)
var/message = span_notice(replacetext(death_text, "%SRC", "[src]"))
@@ -652,10 +853,28 @@
health_change_per_second += 0.5 //Slowly healing
adjust_health(health + health_change_per_second * seconds_per_tick)
/obj/item/fish/proc/adjust_health(amt)
health = clamp(amt, 0, initial(health))
/obj/item/fish/proc/adjust_health(amount)
if(status == FISH_DEAD || amount == health)
return
var/pre_health = health
var/initial_health = initial(health)
health = clamp(amount, 0, initial_health)
if(health <= 0)
set_status(FISH_DEAD)
return
if(amount < pre_health || !bites_amount)
return
var/health_to_pre_health_diff = amount - pre_health
var/init_health_to_pre_diff = initial_health - pre_health
var/bites_to_recover = bites_amount * (health_to_pre_health_diff / init_health_to_pre_diff)
regenerate_bites(bites_to_recover)
/obj/item/fish/proc/regenerate_bites(amount)
amount = min(amount, bites_amount)
if(amount <= 0)
return
bites_amount -= amount
generate_fish_reagents(amount)
/obj/item/fish/proc/ready_to_reproduce(being_targeted = FALSE)
var/obj/structure/aquarium/aquarium = loc
@@ -845,6 +1064,7 @@
if(HAS_TRAIT(src, TRAIT_FISH_FROM_CASE)) //Avoid printing money by simply ordering fish and sending it back.
calculated_price *= 0.05
return round(calculated_price)
/obj/item/fish/proc/get_happiness_value()
var/happiness_value = 0
if(recently_petted)
@@ -858,7 +1078,11 @@
happiness_value++
if(ISINRANGE(aquarium.fluid_temp, required_temperature_min, required_temperature_max))
happiness_value++
return happiness_value
if(bites_amount) // ouch
happiness_value -= 2
if(health < initial(health) * 0.6)
happiness_value -= 1
return clamp(happiness_value, FISH_SAD, FISH_VERY_HAPPY)
/obj/item/fish/proc/pet_fish(mob/living/user)
if(recently_petted)
+40 -23
View File
@@ -37,7 +37,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
var/list/fish_whitelist
/// Depending on the value, fish with trait will be reported as more or less difficult in the catalog.
var/added_difficulty = 0
/// Reagents added to the fish when gained
/// Reagents to add to the fish whenever the COMSIG_GENERATE_REAGENTS_TO_ADD signal is sent. Their values will be multiplied later.
var/list/reagents_to_add
/// Difficulty modifier from this mod, needs to return a list with two values
@@ -57,10 +57,8 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
/// Applies some special qualities to the fish that has been spawned
/datum/fish_trait/proc/apply_to_fish(obj/item/fish/fish)
SHOULD_CALL_PARENT(TRUE)
if(reagents_to_add)
for(var/reagent in reagents_to_add)
add_to_reagents(fish, reagent, reagents_to_add[reagent])
RegisterSignal(fish, COMSIG_ATOM_PROCESSED, PROC_REF(process_reagents))
if(length(reagents_to_add))
RegisterSignal(fish, COMSIG_GENERATE_REAGENTS_TO_ADD, PROC_REF(add_reagents))
/// Applies some special qualities to basic mobs generated by fish (i.e. chasm chrab --> young lobstrosity --> lobstrosity).
/datum/fish_trait/proc/apply_to_mob(mob/living/basic/mob)
@@ -79,25 +77,15 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
SEND_SIGNAL(prey, COMSIG_FISH_EATEN_BY_OTHER_FISH, predator)
qdel(prey)
/// Proc that inserts a reagent to the grind_results list of the fish. You'll still have to set the processed comsig proc yourself.
/datum/fish_trait/proc/add_to_reagents(obj/item/fish/fish, reagent_type, amount)
LAZYINITLIST(fish.grind_results)
fish.grind_results.Insert(1, reagent_type)
fish.grind_results[reagent_type] = amount
/// Proc that handles adding reagents from the trait to the fillets from butchered fish.
/datum/fish_trait/proc/process_reagents(obj/item/fish/source, mob/living/user, obj/item/process_item, list/results)
/**
* Signal sent when we need to generate an abstract holder containing
* reagents to be transfered, usually as a result of the fish being eaten by someone
*/
/datum/fish_trait/proc/add_reagents(obj/item/fish/fish, list/reagents)
SIGNAL_HANDLER
var/results_with_reagents = 0
for(var/atom/result as anything in results)
if(result.reagents)
results_with_reagents++
if(!results_with_reagents)
return
for(var/reagent in reagents_to_add)
var/amount = round(source.grind_results[reagent] / results_with_reagents, 0.1)
for(var/atom/result as anything in results)
result.reagents?.add_reagent(reagent, amount)
reagents[reagent] += reagents_to_add[reagent]
/// Proc that adds or changes the venomous when the fish size and/or weight are updated
/datum/fish_trait/proc/add_venom(obj/item/fish/source, venom_path, new_weight, mult = 0.25)
@@ -413,7 +401,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
/datum/fish_trait/yucky
name = "Yucky"
catalog_description = "This fish tastes so repulsive, other fishes won't try to eat it."
reagents_to_add = list(/datum/reagent/yuck = 3)
reagents_to_add = list(/datum/reagent/yuck = 1.2)
/datum/fish_trait/yucky/apply_to_fish(obj/item/fish/fish)
. = ..()
@@ -423,7 +411,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
name = "Toxic"
catalog_description = "This fish contains toxins. Feeding it to predatory fishes or people is not recommended."
diff_traits_inheritability = 25
reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 2.5)
reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 1)
/datum/fish_trait/toxic/apply_to_fish(obj/item/fish/fish)
. = ..()
@@ -512,6 +500,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
spontaneous_manifest_types = list(/obj/item/fish/clownfish/lube = 100)
catalog_description = "This fish exudes a viscous, slippery lubrificant. It's recommended not to step on it."
added_difficulty = 5
reagents_to_add = list(/datum/reagent/lube = 1.2)
/datum/fish_trait/lubed/apply_to_fish(obj/item/fish/fish)
. = ..()
@@ -597,11 +586,30 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
inheritability = 60
diff_traits_inheritability = 30
catalog_description = "This fish is electroreceptive, and will generate electric fields. Can be harnessed inside a bioelectric generator."
reagents_to_add = list(/datum/reagent/consumable/liquidelectricity = 1.5)
/datum/fish_trait/electrogenesis/apply_to_fish(obj/item/fish/fish)
. = ..()
ADD_TRAIT(fish, TRAIT_FISH_ELECTROGENESIS, FISH_TRAIT_DATUM)
RegisterSignal(fish, COMSIG_FISH_FORCE_UPDATED, PROC_REF(on_force_updated))
RegisterSignals(fish, list(COMSIG_ITEM_FRIED, TRAIT_FOOD_BBQ_GRILLED), PROC_REF(on_fish_cooked))
/datum/fish_trait/electrogenesis/proc/on_fish_cooked(obj/item/fish/fish, cooked_time)
SIGNAL_HANDLER
if(cooked_time >= FISH_SAFE_COOKING_DURATION)
fish.reagents.del_reagent(/datum/reagent/consumable/liquidelectricity)
else
fish.reagents.multiply_single_reagent(/datum/reagent/consumable/liquidelectricity, 0.66)
/datum/fish_trait/electrogenesis/add_reagents(obj/item/fish/fish, list/reagents)
. = ..()
if(HAS_TRAIT(fish, TRAIT_FISH_WELL_COOKED)) // Cooking it well removes all liquid electricity
reagents -= /datum/reagent/consumable/liquidelectricity
else
reagents -= /datum/reagent/blood
//Otherwise, undercooking it will remove 2/3 of it.
if(!HAS_TRAIT(fish, TRAIT_FOOD_FRIED) && !HAS_TRAIT(fish, TRAIT_FOOD_BBQ_GRILLED))
reagents[/datum/reagent/consumable/liquidelectricity] -= 1
/datum/fish_trait/electrogenesis/proc/on_force_updated(obj/item/fish/fish, weight_rank, bonus_or_malus)
SIGNAL_HANDLER
@@ -670,6 +678,15 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
return
change_venom_on_death(source, /datum/reagent/toxin/venom, 0.7, 0.3)
/datum/fish_trait/hallucinogenic
name = "Hallucinogenic"
catalog_description = "This fish is coated with hallucinogenic neurotoxin. We advise cooking it before consumption."
reagents_to_add = list(/datum/reagent/toxin/mindbreaker/fish = 1)
/datum/fish_trait/hallucinogenic/add_reagents(obj/item/fish/fish, list/reagents)
if(!HAS_TRAIT(src, TRAIT_FOOD_FRIED) && !HAS_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED))
return ..()
/datum/fish_trait/ink
name = "Ink Production"
catalog_description = "This fish possess a sac that produces ink."
@@ -40,6 +40,12 @@
),
)
/obj/item/fish/sand_crab/get_fish_taste()
return list("raw crab" = 2)
/obj/item/fish/sand_crab/get_fish_taste_cooked()
return list("cooked crab" = 2)
/obj/item/fish/bumpy
name = "bump-fish"
desc = "An misshapen fish-thing all covered in stubby little tendrils"
@@ -11,6 +11,11 @@
fillet_type = /obj/item/food/fishmeat/salmon
beauty = FISH_BEAUTY_GOOD
/obj/item/fish/sockeye_salmon/get_base_edible_reagents_to_add()
var/return_list = ..()
return_list[/datum/reagent/consumable/nutriment/fat] = 1
return return_list
/obj/item/fish/arctic_char
name = "arctic char"
desc = "A cold-water anadromous fish widespread around the Northern Hemisphere of Earth, yet it has somehow found a way here."
@@ -31,6 +31,9 @@
compatible_types = list(/obj/item/fish/goldfish, /obj/item/fish/goldfish/three_eyes)
fish_traits = list(/datum/fish_trait/recessive)
/obj/item/fish/goldfish/gill/get_fish_taste()
return list("raw fish" = 2.5, "objection" = 1)
/obj/item/fish/goldfish/three_eyes
name = "three-eyed goldfish"
desc = "A goldfish with an extra half a pair of eyes. You wonder what it's been feeding on lately..."
@@ -50,6 +53,9 @@
),
)
/obj/item/fish/goldfish/three_eyes/get_fish_taste()
return list("raw fish" = 2.5, "chemical waste" = 0.5)
/obj/item/fish/goldfish/three_eyes/gill
name = "McGill"
desc = "A great rubber duck tool for Lawyers who can't get a grasp over their case. It looks kinda different today..."
@@ -59,6 +65,9 @@
stable_population = 1
random_case_rarity = FISH_RARITY_NOPE
/obj/item/fish/goldfish/three_eyes/gill/get_fish_taste()
return list("raw fish" = 2.5, "objection" = 1)
/obj/item/fish/angelfish
name = "angelfish"
desc = "Young Angelfish often live in groups, while adults prefer solitary life. They become territorial and aggressive toward other fish when they reach adulthood."
@@ -142,6 +151,9 @@
electrogenesis_power = 6.7 MEGA JOULES
beauty = FISH_BEAUTY_GOOD
/obj/item/fish/zipzap/get_fish_taste()
return list("raw fish" = 2, "anxiety" = 1)
/obj/item/fish/tadpole
name = "tadpole"
desc = "The larval spawn of an amphibian. A very minuscle, round creature with a long tail it uses to swim around."
@@ -167,6 +179,9 @@
RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks))
RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth))
/obj/item/fish/tadpole/make_edible()
return
/obj/item/fish/tadpole/set_status(new_status, silent = FALSE)
. = ..()
if(status == FISH_DEAD)
@@ -13,7 +13,6 @@
average_size = /obj/item/fish/goldfish::average_size
average_weight = /obj/item/fish/goldfish::average_weight
required_fluid_type = AQUARIUM_FLUID_ANADROMOUS
grind_results = null
fillet_type = null
death_text = "%SRC gently disappears."
fish_traits = list(/datum/fish_trait/no_mating) //just to be sure, these shouldn't reproduce
@@ -28,6 +27,9 @@
return
holo_area.linked.add_to_spawned(src)
/obj/item/fish/holo/make_edible(weight_val)
return
/obj/item/fish/holo/set_status(new_status, silent = FALSE)
. = ..()
if(status == FISH_DEAD)
+15
View File
@@ -37,6 +37,12 @@
RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks))
RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth))
/obj/item/fish/chasm_crab/get_fish_taste()
return list("raw crab" = 2)
/obj/item/fish/chasm_crab/get_fish_taste_cooked()
return list("cooked crab" = 2)
///A chasm crab growth speed is determined by its initial weight and size, ergo bigger crabs for faster lobstrosities
/obj/item/fish/chasm_crab/update_size_and_weight(new_size = average_size, new_weight = average_weight)
. = ..()
@@ -125,6 +131,9 @@
evolution_types = list(/datum/fish_evolution/mastodon)
beauty = FISH_BEAUTY_UGLY
/obj/item/fish/boned/make_edible(weight_val)
return //it's all bones and no meat.
/obj/item/fish/lavaloop
name = "lavaloop fish"
desc = "Due to its curvature, it can be used as make-shift boomerang."
@@ -164,6 +173,12 @@
effect_on_success = /obj/effect/temp_visual/guardian/phase,\
)
/obj/item/fish/lavaloop/get_fish_taste()
return list("chewy fish" = 2)
/obj/item/fish/lavaloop/get_food_types()
return SEAFOOD|MEAT|GORE //Well-cooked in lava
/obj/item/fish/lavaloop/proc/explode_on_user(mob/living/user)
var/obj/item/bodypart/arm/active_arm = user.get_active_hand()
active_arm?.dismember()
+17
View File
@@ -26,6 +26,9 @@
fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/amphibious, /datum/fish_trait/revival, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/aggressive)
beauty = FISH_BEAUTY_BAD
/obj/item/fish/mastodon/make_edible(weight_val)
return //it's all bones and gibs.
///From the cursed spring
/obj/item/fish/soul
name = "soulfish"
@@ -50,6 +53,15 @@
required_temperature_max = MIN_AQUARIUM_TEMP+38
random_case_rarity = FISH_RARITY_NOPE
/obj/item/fish/soul/get_food_types()
return MEAT|RAW|GORE //Not-so-quite-seafood
/obj/item/fish/soul/get_fish_taste()
return list("meat" = 2, "soulfulness" = 1)
/obj/item/fish/soul/get_fish_taste_cooked()
return list("cooked meat" = 2)
///From the cursed spring
/obj/item/fish/skin_crab
name = "skin crab"
@@ -71,3 +83,8 @@
fillet_type = /obj/item/food/meat/slab/rawcrab
random_case_rarity = FISH_RARITY_NOPE
/obj/item/fish/skin_crab/get_fish_taste()
return list("raw crab" = 2)
/obj/item/fish/skin_crab/get_fish_taste_cooked()
return list("cooked crab" = 2)
+10 -1
View File
@@ -14,6 +14,9 @@
required_temperature_min = MIN_AQUARIUM_TEMP+22
required_temperature_max = MIN_AQUARIUM_TEMP+30
/obj/item/fish/clownfish/get_fish_taste()
return list("raw fish" = 2, "something funny" = 1)
/obj/item/fish/clownfish/lube
name = "lubefish"
desc = "A clownfish exposed to cherry-flavored lube for far too long. First discovered the days following a cargo incident around the seas of Europa, when thousands of thousands of thousands..."
@@ -227,9 +230,15 @@
required_temperature_max = MIN_AQUARIUM_TEMP+26
fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/ink, /datum/fish_trait/camouflage, /datum/fish_trait/wary)
/obj/item/fish/squid/get_fish_taste()
return list("raw mollusk" = 2)
/obj/item/fish/squid/get_fish_taste_cooked()
return list("cooked mollusk" = 2, "tenderness" = 0.5)
/obj/item/fish/monkfish
name = "monkfish"
desc = "A member of the Lophiid family of anglerfish. It goes by several different names, however none of them will make it look any prettier, nor any less delicious."
desc = "A member of the Lophiid family of anglerfish. It goes by several different names, however none of them will make it look any prettier, nor be any less delicious."
icon_state = "monkfish"
required_fluid_type = AQUARIUM_FLUID_SALTWATER
sprite_height = 7
+23 -1
View File
@@ -20,6 +20,20 @@
)
beauty = FISH_BEAUTY_DISGUSTING
/obj/item/fish/ratfish/get_fish_taste()
return list("vermin" = 2, "maintenance" = 1)
/obj/item/fish/ratfish/get_fish_taste_cooked()
return list("cooked vermin" = 2, "burned fur" = 0.5)
/obj/item/fish/ratfish/get_food_types()
return MEAT|RAW|GORE //Not-so-quite-seafood
/obj/item/fish/ratfish/get_base_edible_reagents_to_add()
var/list/return_list = ..()
return_list[/datum/reagent/rat_spit] = 1
return return_list
/obj/item/fish/ratfish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
//stable pop reflects the config for how many mice migrate. powerful...
@@ -43,6 +57,9 @@
evolution_types = list(/datum/fish_evolution/purple_sludgefish)
beauty = FISH_BEAUTY_NULL
/obj/item/fish/sludgefish/get_fish_taste()
return list("raw fish" = 2, "eau de toilet" = 1)
/obj/item/fish/sludgefish/purple
name = "purple sludgefish"
desc = "A misshapen, fragile, loosely fish-like living goop. This one has developed sexual reproduction mechanisms, and a purple tint to boot."
@@ -63,7 +80,6 @@
stable_population = 4
health = 150
fillet_type = /obj/item/slime_extract/grey
grind_results = list(/datum/reagent/toxin/slimejelly = 10)
fish_traits = list(/datum/fish_trait/toxin_immunity, /datum/fish_trait/crossbreeder)
favorite_bait = list(
list(
@@ -78,3 +94,9 @@
)
required_temperature_min = MIN_AQUARIUM_TEMP+20
beauty = FISH_BEAUTY_GREAT
/obj/item/fish/slimefish/get_food_types()
return SEAFOOD|TOXIC
/obj/item/fish/slimefish/get_base_edible_reagents_to_add()
return list(/datum/reagent/toxin/slimejelly = 5)
@@ -13,6 +13,9 @@
required_temperature_max = MIN_AQUARIUM_TEMP+40
beauty = FISH_BEAUTY_BAD
/obj/item/fish/emulsijack/get_fish_taste()
return list("raw fish" = 2, "acid" = 1) //no scales
/obj/item/fish/donkfish
name = "donk co. company patent donkfish"
desc = "A lab-grown donkfish. Its invention was an accident for the most part, as it was intended to be consumed in donk pockets. Unfortunately, it tastes horrible, so it has now become a pseudo-mascot."
@@ -94,6 +97,9 @@
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/fish/chainsawfish/get_fish_taste()
return list("raw fish" = 2.5, "anger" = 1)
/obj/item/fish/chainsawfish/update_icon_state()
if(status == FISH_DEAD)
inhand_icon_state = "chainsawfish_dead"
@@ -202,6 +208,12 @@
/obj/item/fish,
)
/obj/item/fish/pike/armored/get_fish_taste()
return list("raw fish" = 2.5, "metal" = 1)
/obj/item/fish/pike/armored/get_fish_taste()
return list("cooked fish" = 2.5, "metal" = 1)
/obj/item/fish/swordfish/get_force_rank()
switch(w_class)
if(WEIGHT_CLASS_TINY)
@@ -24,10 +24,21 @@
required_fluid_type = AQUARIUM_FLUID_SALTWATER
stable_population = 4
fillet_type = /obj/item/food/fishmeat/gunner_jellyfish
fish_traits = list(/datum/fish_trait/hallucinogenic)
required_temperature_min = MIN_AQUARIUM_TEMP+24
required_temperature_max = MIN_AQUARIUM_TEMP+32
beauty = FISH_BEAUTY_GOOD
/obj/item/fish/gunner_jellyfish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
AddElement(/datum/element/quality_food_ingredient, FOOD_COMPLEXITY_2)
/obj/item/fish/gunner_jellyfish/get_fish_taste()
return list("cold jelly" = 2)
/obj/item/fish/gunner_jellyfish/get_fish_taste_cooked()
return list("crunchy tenderness" = 2)
/obj/item/fish/needlefish
name = "needlefish"
desc = "A tiny, transparent fish which resides in large schools in the oceans of Tizira. A common food for other, larger fish."
@@ -67,3 +78,9 @@
/obj/item/fish/armorfish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
add_traits(list(TRAIT_FISHING_BAIT, TRAIT_GOOD_QUALITY_BAIT), INNATE_TRAIT)
/obj/item/fish/chasm_crab/get_fish_taste()
return list("raw prawn" = 2)
/obj/item/fish/chasm_crab/get_fish_taste_cooked()
return list("cooked prawn" = 2)
+3
View File
@@ -704,4 +704,7 @@
override_origin_pixel_x = lefthand ? lefthand_n_px : righthand_n_px
override_origin_pixel_y = lefthand ? lefthand_n_py : righthand_n_py
override_origin_pixel_x += origin.pixel_x
override_origin_pixel_y += origin.pixel_y
#undef FISHING_ROD_REEL_CAST_RANGE