mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
Aquariums are now potential fishing spots. (#88243)
## About The Pull Request You can now fish from aquariums if you wish to. This includes some backend changes to make it possible for the fish table from get_fish_table() to contain instances, and all that it entails up to spawn_reward(), which is a requirement for the gimmick to respect the various traits and other variables of the already instantiated fish rather than read from cached properties. ## Why It's Good For The Game The fish progress score/index had only little nasty flaw that has been nagging me since day one: Not all fish species can be caught. Skipping McGill, which is a peculiar case that for cheevo purposes should be considered a standard goldfish, there is the one, unsignificant yet rare purple sludgefish which can only be gotten as a rare evolution of the generic sludgefish. Talk about petty, but this may be a long-term nit I prefer to handle right now. Also why not? The 'unmarine mastodon' is near impossible to get unless you somehow find a oil well which is locked behind a specific ruin. ## Changelog 🆑 fix: Aquariums are now potential fishing spots. /🆑
This commit is contained in:
@@ -187,7 +187,6 @@
|
||||
///Flag added when in an aquarium with the right fluid type.
|
||||
#define FISH_FLAG_SAFE_FLUID (1<<7)
|
||||
|
||||
|
||||
#define MIN_AQUARIUM_TEMP T0C
|
||||
#define MAX_AQUARIUM_TEMP (T0C + 100)
|
||||
#define DEFAULT_AQUARIUM_TEMP (T0C + 24)
|
||||
@@ -260,11 +259,8 @@
|
||||
#define FISH_SOURCE_FLAG_EXPLOSIVE_MALUS (1<<0)
|
||||
/// The fish source is not elegible for random rewards from bluespace fishing rods
|
||||
#define FISH_SOURCE_FLAG_NO_BLUESPACE_ROD (1<<1)
|
||||
/**
|
||||
* If present, fish that can be caught from this source won't be included in the 'fish caught' score, unless
|
||||
* present in other sources without this flag as well.
|
||||
*/
|
||||
#define FISH_SOURCE_FLAG_SKIP_CATCHABLES (1<<2)
|
||||
/// When examined by someone with enough fishing skill, this will also display fish that doesn't have FISH_FLAG_SHOW_IN_CATALOG
|
||||
#define FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG (1<<2)
|
||||
|
||||
/**
|
||||
* A macro to ensure the wikimedia filenames of fish icons are unique, especially since there're a couple fish that have
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
/proc/cmp_name_dsc(atom/a, atom/b)
|
||||
return sorttext(a.name, b.name)
|
||||
|
||||
/proc/cmp_init_name_asc(atom/a, atom/b)
|
||||
return sorttext(initial(b.name), initial(a.name))
|
||||
|
||||
/proc/cmp_records_asc(datum/record/a, datum/record/b)
|
||||
return sorttext(b.name, a.name)
|
||||
|
||||
|
||||
@@ -19,10 +19,13 @@ PROCESSING_SUBSYSTEM_DEF(fishing)
|
||||
cached_fish_icons = list()
|
||||
cached_unknown_fish_icons = list()
|
||||
fish_properties = list()
|
||||
catchable_fish = list()
|
||||
|
||||
var/icon/questionmark = icon('icons/effects/random_spawners.dmi', "questionmark")
|
||||
var/list/mark_dimension = get_icon_dimensions(questionmark)
|
||||
for(var/obj/item/fish/fish_type as anything in subtypesof(/obj/item/fish))
|
||||
var/list/spawned_fish = list()
|
||||
var/list/fish_subtypes = sortTim(subtypesof(/obj/item/fish), GLOBAL_PROC_REF(cmp_init_name_asc))
|
||||
for(var/obj/item/fish/fish_type as anything in fish_subtypes)
|
||||
var/list/fish_dimensions = get_icon_dimensions(fish_type::icon)
|
||||
var/icon/fish_icon = icon(fish_type::icon, fish_type::icon_state, frame = 1, moving = FALSE)
|
||||
cached_fish_icons[fish_type] = icon2base64(fish_icon)
|
||||
@@ -35,6 +38,7 @@ PROCESSING_SUBSYSTEM_DEF(fishing)
|
||||
cached_unknown_fish_icons[fish_type] = icon2base64(unknown_icon)
|
||||
|
||||
var/obj/item/fish/fish = new fish_type(null, FALSE)
|
||||
spawned_fish += fish
|
||||
var/list/properties = list()
|
||||
fish_properties[fish_type] = properties
|
||||
properties[FISH_PROPERTIES_FAV_BAIT] = fish.favorite_bait.Copy()
|
||||
@@ -67,36 +71,35 @@ PROCESSING_SUBSYSTEM_DEF(fishing)
|
||||
|
||||
properties[FISH_PROPERTIES_BEAUTY_SCORE] = beauty_score
|
||||
|
||||
qdel(fish)
|
||||
|
||||
catchable_fish = list()
|
||||
var/list/all_catchables = list()
|
||||
for(var/source_type as anything in GLOB.preset_fish_sources)
|
||||
var/datum/fish_source/source = GLOB.preset_fish_sources[source_type]
|
||||
if(!(source.fish_source_flags & FISH_SOURCE_FLAG_SKIP_CATCHABLES))
|
||||
all_catchables |= source.fish_table
|
||||
for(var/thing in all_catchables)
|
||||
if(!ispath(thing, /obj/item/fish))
|
||||
continue
|
||||
var/obj/item/fish/fishie = thing
|
||||
var/fish_id = initial(fishie.fish_id)
|
||||
var/fish_id
|
||||
if(fish.fish_id_redirect_path)
|
||||
var/obj/item/fish/other_path = fish.fish_id_redirect_path
|
||||
if(!ispath(other_path, /obj/item/fish))
|
||||
stack_trace("[fish.type] has a set 'fish_id_redirect_path' variable but it isn't a fish path but [other_path]")
|
||||
continue
|
||||
fish_id = initial(other_path.fish_id)
|
||||
else
|
||||
fish_id = fish.fish_id
|
||||
if(!fish_id)
|
||||
stack_trace("[fishie] doesn't have a set 'fish_id' variable despite being a catchable fish")
|
||||
stack_trace("[fish.type] doesn't have a set 'fish_id' variable despite being a catchable fish")
|
||||
continue
|
||||
if(fish.fish_id_redirect_path)
|
||||
continue
|
||||
if(catchable_fish[fish_id])
|
||||
stack_trace("[fishie] has a 'fish_id' value already assigned to [catchable_fish[fish_id]]. fish_id: [fish_id]")
|
||||
stack_trace("[fish.type] has a 'fish_id' value already assigned to [catchable_fish[fish_id]]. fish_id: [fish_id]")
|
||||
continue
|
||||
catchable_fish[fish_id] = fishie
|
||||
catchable_fish[fish_id] = fish.type
|
||||
|
||||
///init the list of things lures can catch
|
||||
lure_catchables = list()
|
||||
var/list/fish_types = subtypesof(/obj/item/fish)
|
||||
for(var/lure_type in typesof(/obj/item/fishing_lure))
|
||||
var/obj/item/fishing_lure/lure = new lure_type
|
||||
lure_catchables[lure_type] = list()
|
||||
for(var/obj/item/fish/fish_type as anything in fish_types)
|
||||
if(lure.is_catchable_fish(fish_type, fish_properties[fish_type]))
|
||||
lure_catchables[lure_type] += fish_type
|
||||
for(var/obj/item/fish/fish as anything in spawned_fish)
|
||||
if(lure.is_catchable_fish(fish, fish_properties[fish.type]))
|
||||
lure_catchables[lure_type] += fish.type
|
||||
qdel(lure)
|
||||
|
||||
QDEL_LIST(spawned_fish)
|
||||
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
@@ -470,13 +470,13 @@
|
||||
for(var/component_key in dc)
|
||||
var/component_or_list = dc[component_key]
|
||||
if(islist(component_or_list))
|
||||
for(var/datum/component/I in component_or_list)
|
||||
if(I.can_transfer)
|
||||
target.TakeComponent(I)
|
||||
for(var/datum/component/component in component_or_list)
|
||||
if(component.can_transfer)
|
||||
target.TakeComponent(component)
|
||||
else
|
||||
var/datum/component/C = component_or_list
|
||||
if(C.can_transfer)
|
||||
target.TakeComponent(C)
|
||||
var/datum/component/component = component_or_list
|
||||
if(!QDELETED(component) && component.can_transfer)
|
||||
target.TakeComponent(component)
|
||||
|
||||
/**
|
||||
* Return the object that is the host of any UI's that this component has
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
RegisterSignal(movable, COMSIG_ATOM_UI_INTERACT, PROC_REF(interact))
|
||||
|
||||
movable.AddElement(/datum/element/relay_attackers)
|
||||
movable.AddComponent(/datum/component/fishing_spot, /datum/fish_source/aquarium)
|
||||
|
||||
for(var/atom/movable/content as anything in movable.contents)
|
||||
if(content.flags_1 & INITIALIZED_1)
|
||||
@@ -150,6 +151,7 @@
|
||||
beauty_by_content = null
|
||||
tracked_fish_by_type = null
|
||||
movable.remove_traits(list(TRAIT_IS_AQUARIUM, TRAIT_AQUARIUM_PANEL_OPEN, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH), AQUARIUM_TRAIT)
|
||||
qdel(movable.GetComponent(/datum/component/fishing_spot))
|
||||
REMOVE_KEEP_TOGETHER(movable, AQUARIUM_TRAIT)
|
||||
|
||||
/datum/component/aquarium/PreTransfer(atom/movable/new_parent)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
if(!HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISHING_SPOT))
|
||||
return
|
||||
|
||||
if(!fish_source.has_known_fishes())
|
||||
if(!fish_source.has_known_fishes(source))
|
||||
return
|
||||
|
||||
examine_text += span_tinynoticeital("This is a fishing spot. You can look again to list its fishes...")
|
||||
|
||||
@@ -1883,11 +1883,12 @@
|
||||
return src
|
||||
|
||||
/// Checks if the bait is liked by the fish type or not. Returns a multiplier that affects the chance of catching it.
|
||||
/obj/item/proc/check_bait(obj/item/fish/fish_type)
|
||||
/obj/item/proc/check_bait(obj/item/fish/fish)
|
||||
if(HAS_TRAIT(src, TRAIT_OMNI_BAIT))
|
||||
return 1
|
||||
var/catch_multiplier = 1
|
||||
var/list/properties = SSfishing.fish_properties[fish_type]
|
||||
|
||||
var/list/properties = SSfishing.fish_properties[isfish(fish) ? fish.type : fish]
|
||||
//Bait matching likes doubles the chance
|
||||
var/list/fav_bait = properties[FISH_PROPERTIES_FAV_BAIT]
|
||||
for(var/bait_identifer in fav_bait)
|
||||
|
||||
@@ -836,7 +836,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
. = ..()
|
||||
if(!fish_source || !HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISHING_SPOT))
|
||||
return
|
||||
if(!GLOB.preset_fish_sources[fish_source].has_known_fishes())
|
||||
if(!GLOB.preset_fish_sources[fish_source].has_known_fishes(src))
|
||||
return
|
||||
. += span_tinynoticeital("This is a fishing spot. You can look again to list its fishes...")
|
||||
|
||||
|
||||
@@ -88,13 +88,11 @@
|
||||
rod.spin_frequency = null
|
||||
|
||||
///Called for every fish subtype by the fishing subsystem when initializing, to populate the list of fish that can be catched with this lure.
|
||||
/obj/item/fishing_lure/proc/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/avg_size = initial(fish_type.average_size)
|
||||
/obj/item/fishing_lure/proc/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
var/intermediate_size = FISH_SIZE_SMALL_MAX + (FISH_SIZE_NORMAL_MAX - FISH_SIZE_SMALL_MAX)
|
||||
if(!ISINRANGE(avg_size, FISH_SIZE_TINY_MAX * 0.5, intermediate_size))
|
||||
if(!ISINRANGE(fish.size, FISH_SIZE_TINY_MAX * 0.5, intermediate_size))
|
||||
return FALSE
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish_traits))
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish.fish_traits))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -120,11 +118,16 @@
|
||||
. += span_info("You can catch the following fish with this lure: [english_list(known_fishes)].")
|
||||
|
||||
///Check if the fish is in the list of catchable fish for this fishing lure. Return value is a multiplier.
|
||||
/obj/item/fishing_lure/check_bait(obj/item/fish/fish_type)
|
||||
/obj/item/fishing_lure/check_bait(obj/item/fish/fish)
|
||||
var/multiplier = 0
|
||||
if(is_type_in_list(/obj/item/fishing_lure, SSfishing.fish_properties[fish_type][FISH_PROPERTIES_FAV_BAIT]))
|
||||
var/is_instance = istype(fish)
|
||||
var/list/fish_properties = SSfishing.fish_properties[is_instance ? fish.type : fish]
|
||||
if(is_type_in_list(/obj/item/fishing_lure, fish_properties[FISH_PROPERTIES_FAV_BAIT]))
|
||||
multiplier += 2
|
||||
if(fish_type in SSfishing.lure_catchables[type])
|
||||
if(is_instance)
|
||||
if(is_catchable_fish(fish, fish_properties))
|
||||
multiplier += 10
|
||||
else if(fish in SSfishing.lure_catchables[type])
|
||||
multiplier += 10
|
||||
return multiplier
|
||||
|
||||
@@ -133,12 +136,10 @@
|
||||
desc = "A bigger fishing lure that may attract larger fish. Tiny or picky prey will remain uninterested."
|
||||
icon_state = "plug"
|
||||
|
||||
/obj/item/fishing_lure/plug/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/avg_size = initial(fish_type.average_size)
|
||||
if(avg_size <= FISH_SIZE_SMALL_MAX)
|
||||
/obj/item/fishing_lure/plug/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(fish.size <= FISH_SIZE_SMALL_MAX)
|
||||
return FALSE
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish_traits))
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish.fish_traits))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -148,17 +149,17 @@
|
||||
icon_state = "dropping"
|
||||
spin_frequency = list(1.5 SECONDS, 2.8 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/dropping/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
/obj/item/fishing_lure/dropping/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
var/list/sources = list(/datum/fish_source/toilet, /datum/fish_source/moisture_trap)
|
||||
for(var/datum/fish_source/source as anything in sources)
|
||||
var/datum/fish_source/instance = GLOB.preset_fish_sources[/datum/fish_source/toilet]
|
||||
if(fish_type in instance.fish_table)
|
||||
if(fish.type in instance.fish_table)
|
||||
return TRUE
|
||||
var/list/fav_baits = fish_properties[FISH_PROPERTIES_FAV_BAIT]
|
||||
for(var/list/identifier in fav_baits)
|
||||
if(identifier[FISH_BAIT_TYPE] == FISH_BAIT_FOODTYPE && (identifier[FISH_BAIT_VALUE] & (JUNKFOOD|GROSS|TOXIC)))
|
||||
return TRUE
|
||||
if(initial(fish_type.beauty) <= FISH_BEAUTY_DISGUSTING)
|
||||
if(fish.beauty <= FISH_BEAUTY_DISGUSTING)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -168,17 +169,15 @@
|
||||
icon_state = "spoon"
|
||||
spin_frequency = list(1.25 SECONDS, 2.25 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/spoon/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/avg_size = initial(fish_type.average_size)
|
||||
if(!ISINRANGE(avg_size, FISH_SIZE_TINY_MAX + 1, FISH_SIZE_NORMAL_MAX))
|
||||
/obj/item/fishing_lure/spoon/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(!ISINRANGE(fish.size, FISH_SIZE_TINY_MAX + 1, FISH_SIZE_NORMAL_MAX))
|
||||
return FALSE
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish_traits))
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater, /datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish.fish_traits))
|
||||
return FALSE
|
||||
var/fluid_type = initial(fish_type.required_fluid_type)
|
||||
var/fluid_type = fish.required_fluid_type
|
||||
if(fluid_type == AQUARIUM_FLUID_FRESHWATER || fluid_type == AQUARIUM_FLUID_ANADROMOUS || fluid_type == AQUARIUM_FLUID_ANY_WATER)
|
||||
return TRUE
|
||||
if((/datum/fish_trait/amphibious in fish_traits) && fluid_type == AQUARIUM_FLUID_AIR)
|
||||
if((/datum/fish_trait/amphibious in fish.fish_traits) && fluid_type == AQUARIUM_FLUID_AIR)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -188,9 +187,8 @@
|
||||
icon_state = "artificial_fly"
|
||||
spin_frequency = list(1.1 SECONDS, 2 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/artificial_fly/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(/datum/fish_trait/picky_eater in fish_traits)
|
||||
/obj/item/fishing_lure/artificial_fly/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(/datum/fish_trait/picky_eater in fish.fish_traits)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -216,9 +214,8 @@
|
||||
. = ..()
|
||||
REMOVE_TRAIT(rod, TRAIT_ROD_IGNORE_ENVIRONMENT, type)
|
||||
|
||||
/obj/item/fishing_lure/led/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(length(list(/datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish_traits))
|
||||
/obj/item/fishing_lure/led/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(length(list(/datum/fish_trait/nocturnal, /datum/fish_trait/heavy) & fish.fish_traits))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -236,9 +233,8 @@
|
||||
. = ..()
|
||||
REMOVE_TRAIT(rod, TRAIT_ROD_ATTRACT_SHINY_LOVERS, REF(src))
|
||||
|
||||
/obj/item/fishing_lure/lucky_coin/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(/datum/fish_trait/shiny_lover in fish_traits)
|
||||
/obj/item/fishing_lure/lucky_coin/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(/datum/fish_trait/shiny_lover in fish.fish_traits)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -248,9 +244,8 @@
|
||||
icon_state = "algae"
|
||||
spin_frequency = list(3 SECONDS, 5 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/algae/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(/datum/fish_trait/vegan in fish_traits)
|
||||
/obj/item/fishing_lure/algae/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(/datum/fish_trait/vegan in fish.fish_traits)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -260,11 +255,10 @@
|
||||
icon_state = "grub"
|
||||
spin_frequency = list(1 SECONDS, 2.7 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/grub/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
if(initial(fish_type.average_size) >= FISH_SIZE_SMALL_MAX)
|
||||
/obj/item/fishing_lure/grub/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(fish.size >= FISH_SIZE_SMALL_MAX)
|
||||
return FALSE
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater) & fish_traits))
|
||||
if(length(list(/datum/fish_trait/vegan, /datum/fish_trait/picky_eater) & fish.fish_traits))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -274,9 +268,8 @@
|
||||
icon_state = "buzzbait"
|
||||
spin_frequency = list(0.8 SECONDS, 1.7 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/buzzbait/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(/datum/fish_trait/electrogenesis in fish_traits)
|
||||
/obj/item/fishing_lure/buzzbait/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(HAS_TRAIT(fish, TRAIT_FISH_ELECTROGENESIS))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -286,14 +279,13 @@
|
||||
icon_state = "spinnerbait"
|
||||
spin_frequency = list(2 SECONDS, 4 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/spinnerbait/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(!(/datum/fish_trait/predator in fish_traits))
|
||||
/obj/item/fishing_lure/spinnerbait/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(!(/datum/fish_trait/predator in fish.fish_traits))
|
||||
return FALSE
|
||||
var/init_fluid_type = initial(fish_type.required_fluid_type)
|
||||
var/init_fluid_type = fish.required_fluid_type
|
||||
if(init_fluid_type == AQUARIUM_FLUID_FRESHWATER || init_fluid_type == AQUARIUM_FLUID_ANADROMOUS || init_fluid_type == AQUARIUM_FLUID_ANY_WATER)
|
||||
return TRUE
|
||||
if((/datum/fish_trait/amphibious in fish_traits) && init_fluid_type == AQUARIUM_FLUID_AIR) //fluid type is changed to freshwater on init
|
||||
if((/datum/fish_trait/amphibious in fish.fish_traits) && init_fluid_type == AQUARIUM_FLUID_AIR) //fluid type is changed to freshwater on init
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -303,11 +295,10 @@
|
||||
icon_state = "daisy_chain"
|
||||
spin_frequency = list(2 SECONDS, 4 SECONDS)
|
||||
|
||||
/obj/item/fishing_lure/daisy_chain/is_catchable_fish(obj/item/fish/fish_type, list/fish_properties)
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
if(!(/datum/fish_trait/predator in fish_traits))
|
||||
/obj/item/fishing_lure/daisy_chain/is_catchable_fish(obj/item/fish/fish, list/fish_properties)
|
||||
if(!(/datum/fish_trait/predator in fish.fish_traits))
|
||||
return FALSE
|
||||
var/init_fluid_type = initial(fish_type.required_fluid_type)
|
||||
var/init_fluid_type = fish.required_fluid_type
|
||||
if(init_fluid_type == AQUARIUM_FLUID_SALTWATER || init_fluid_type == AQUARIUM_FLUID_ANADROMOUS || init_fluid_type == AQUARIUM_FLUID_ANY_WATER)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -170,6 +170,8 @@
|
||||
* Once set, the value shouldn't be changed, so don't make typos.
|
||||
*/
|
||||
var/fish_id
|
||||
///Used to redirect to another fish path so that catching this fish unlocks its entry instead.
|
||||
var/obj/item/fish/fish_id_redirect_path
|
||||
|
||||
/obj/item/fish/Initialize(mapload, apply_qualities = TRUE)
|
||||
. = ..()
|
||||
|
||||
@@ -61,7 +61,9 @@ GLOBAL_LIST_INIT_TYPED(chasm_detritus_types, /datum/chasm_detritus, init_chasm_d
|
||||
var/default_spawn = pick(default_contents[default_contents_key])
|
||||
return new default_spawn(fisher_turf)
|
||||
|
||||
return determine_detritus(chasm_contents)
|
||||
var/atom/movable/detritus = determine_detritus(chasm_contents)
|
||||
detritus.forceMove(fisher_turf)
|
||||
return detritus
|
||||
|
||||
/datum/chasm_detritus/proc/get_chasm_contents(turf/fishing_spot)
|
||||
. = list()
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
/obj/item/fish/goldfish/gill
|
||||
name = "McGill"
|
||||
desc = "A great rubber duck tool for Lawyers who can't get a grasp over their case."
|
||||
fish_id_redirect_path = /obj/item/fish/goldfish
|
||||
stable_population = 1
|
||||
random_case_rarity = FISH_RARITY_NOPE
|
||||
fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG
|
||||
@@ -61,6 +62,7 @@
|
||||
/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..."
|
||||
fish_id_redirect_path = /obj/item/fish/goldfish/three_eyes
|
||||
compatible_types = list(/obj/item/fish/goldfish, /obj/item/fish/goldfish/three_eyes)
|
||||
beauty = FISH_BEAUTY_GREAT
|
||||
fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG
|
||||
@@ -163,6 +165,7 @@
|
||||
|
||||
/obj/item/fish/tadpole
|
||||
name = "tadpole"
|
||||
fish_id = "tadpole"
|
||||
desc = "The larval spawn of an amphibian. A very minuscle, round creature with a long tail it uses to swim around."
|
||||
icon_state = "tadpole"
|
||||
average_size = 3
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
|
||||
/obj/item/fish/sludgefish/purple
|
||||
name = "purple sludgefish"
|
||||
fish_id = "purple_sludgefish"
|
||||
desc = "A misshapen, fragile, loosely fish-like living goop. This one has developed sexual reproduction mechanisms, and a purple tint to boot."
|
||||
icon_state = "sludgefish_purple"
|
||||
random_case_rarity = FISH_RARITY_NOPE
|
||||
|
||||
@@ -215,8 +215,8 @@
|
||||
SIGNAL_HANDLER
|
||||
REMOVE_TRAIT(rod, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src))
|
||||
|
||||
/obj/item/fishing_hook/magnet/get_hook_bonus_multiplicative(fish_type, datum/fish_source/source)
|
||||
if(fish_type == FISHING_DUD || ispath(fish_type, /obj/item/fish))
|
||||
/obj/item/fishing_hook/magnet/get_hook_bonus_multiplicative(fish_type)
|
||||
if(fish_type == FISHING_DUD || ispath(fish_type, /obj/item/fish) || isfish(fish_type))
|
||||
return ..()
|
||||
|
||||
// We multiply the odds by five for everything that's not a fish nor a dud
|
||||
@@ -275,9 +275,9 @@
|
||||
return "The hook on your fishing rod wasn't meant for traditional fishing, rendering it useless at doing so!"
|
||||
|
||||
|
||||
/obj/item/fishing_hook/rescue/get_hook_bonus_multiplicative(fish_type, datum/fish_source/source)
|
||||
/obj/item/fishing_hook/rescue/get_hook_bonus_multiplicative(fish_type)
|
||||
// Sorry, you won't catch fish with this.
|
||||
if(ispath(fish_type, /obj/item/fish))
|
||||
if(ispath(fish_type, /obj/item/fish) || isfish(fish_type))
|
||||
return RESCUE_HOOK_FISH_MULTIPLIER
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -357,11 +357,12 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
if(win)
|
||||
if(reward_path != FISHING_DUD)
|
||||
playsound(location, 'sound/effects/bigsplash.ogg', 100)
|
||||
if(ispath(reward_path, /obj/item/fish))
|
||||
if(ispath(reward_path, /obj/item/fish) || isfish(reward_path))
|
||||
var/obj/item/fish/fish_reward = reward_path
|
||||
var/fish_id = initial(fish_reward.fish_id)
|
||||
var/obj/item/fish/redirect_path = initial(fish_reward.fish_id_redirect_path)
|
||||
var/fish_id = ispath(redirect_path, /obj/item/fish) ? initial(redirect_path.fish_id) : initial(fish_reward.fish_id)
|
||||
if(fish_id)
|
||||
user.client?.give_award(/datum/award/score/progress/fish, user, initial(fish_reward.fish_id))
|
||||
user.client?.give_award(/datum/award/score/progress/fish, user, fish_id)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, win)
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
@@ -397,7 +398,13 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
playsound(location, 'sound/effects/fish_splash.ogg', 100)
|
||||
|
||||
if(HAS_MIND_TRAIT(user, TRAIT_REVEAL_FISH))
|
||||
fish_icon = GLOB.specific_fish_icons[reward_path] || FISH_ICON_DEF
|
||||
var/possible_icon
|
||||
if(isatom(reward_path))
|
||||
var/atom/reward = reward_path
|
||||
possible_icon = GLOB.specific_fish_icons[reward.type]
|
||||
else
|
||||
possible_icon = GLOB.specific_fish_icons[reward_path]
|
||||
fish_icon = possible_icon || FISH_ICON_DEF
|
||||
switch(fish_icon)
|
||||
if(FISH_ICON_DEF)
|
||||
send_alert("fish!!!")
|
||||
@@ -455,11 +462,22 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
SIGNAL_HANDLER
|
||||
interrupt()
|
||||
|
||||
/datum/fishing_challenge/proc/on_reward_removed(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
send_alert("reward gone!")
|
||||
interrupt()
|
||||
|
||||
/datum/fishing_challenge/proc/on_fish_death(obj/item/fish/source)
|
||||
SIGNAL_HANDLER
|
||||
if(source.status == FISH_DEAD)
|
||||
win_anyway()
|
||||
|
||||
/datum/fishing_challenge/proc/win_anyway()
|
||||
if(!completed)
|
||||
//winning by timeout or idling around shouldn't give as much experience.
|
||||
experience_multiplier *= 0.5
|
||||
complete(TRUE)
|
||||
if(completed)
|
||||
return
|
||||
//winning by timeout / fish death shouldn't give as much experience.
|
||||
experience_multiplier *= 0.5
|
||||
complete(TRUE)
|
||||
|
||||
/datum/fishing_challenge/proc/hurt_fish(datum/source, obj/item/fish/reward)
|
||||
SIGNAL_HANDLER
|
||||
@@ -506,13 +524,15 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
if(difficulty > FISHING_DEFAULT_DIFFICULTY)
|
||||
completion -= MAX_FISH_COMPLETION_MALUS * (difficulty * 0.01)
|
||||
|
||||
var/is_fish_instance = isfish(reward_path)
|
||||
|
||||
/// Fish minigame properties
|
||||
if(ispath(reward_path,/obj/item/fish))
|
||||
if(ispath(reward_path,/obj/item/fish) || is_fish_instance)
|
||||
var/obj/item/fish/fish = reward_path
|
||||
var/movement_path = initial(fish.fish_movement_type)
|
||||
mover = new movement_path(src)
|
||||
// Apply fish trait modifiers
|
||||
var/list/fish_traits = SSfishing.fish_properties[fish][FISH_PROPERTIES_TRAITS]
|
||||
var/list/fish_traits = is_fish_instance ? fish.fish_traits : SSfishing.fish_properties[fish][FISH_PROPERTIES_TRAITS]
|
||||
for(var/fish_trait in fish_traits)
|
||||
var/datum/fish_trait/trait = GLOB.fish_traits[fish_trait]
|
||||
trait.minigame_mod(used_rod, user, src)
|
||||
@@ -552,6 +572,11 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
var/obj/item/fish/fish = reward_path
|
||||
var/wait_time = (initial(fish.health) / FISH_DAMAGE_PER_SECOND) SECONDS
|
||||
addtimer(CALLBACK(src, PROC_REF(win_anyway)), wait_time, TIMER_DELETE_ME)
|
||||
else if(ismovable(reward_path))
|
||||
var/atom/movable/reward = reward_path
|
||||
RegisterSignal(reward, COMSIG_MOVABLE_MOVED, PROC_REF(on_reward_removed))
|
||||
if(is_fish_instance)
|
||||
RegisterSignal(reward, COMSIG_FISH_STATUS_CHANGED, PROC_REF(on_fish_death))
|
||||
start_time = world.time
|
||||
|
||||
///Throws a stack with prefixed text.
|
||||
|
||||
@@ -180,16 +180,20 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
// Difficulty modifier added by the rod
|
||||
. += rod.difficulty_modifier
|
||||
|
||||
if(!ispath(result,/obj/item/fish))
|
||||
var/is_fish_instance = isfish(result)
|
||||
if(!ispath(result,/obj/item/fish) && !is_fish_instance)
|
||||
// In the future non-fish rewards can have variable difficulty calculated here
|
||||
return
|
||||
|
||||
var/obj/item/fish/caught_fish = result
|
||||
var/list/fish_properties = SSfishing.fish_properties[caught_fish]
|
||||
|
||||
//Just to clarify when we should use the path instead of the fish, which can be both a path and an instance.
|
||||
var/result_path = is_fish_instance ? caught_fish.type : result
|
||||
|
||||
// Baseline fish difficulty
|
||||
. += initial(caught_fish.fishing_difficulty_modifier)
|
||||
|
||||
|
||||
var/list/fish_properties = SSfishing.fish_properties[result_path]
|
||||
if(rod.bait)
|
||||
var/obj/item/bait = rod.bait
|
||||
//Fav bait makes it easier
|
||||
@@ -204,7 +208,11 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
. += DISLIKED_BAIT_DIFFICULTY_MOD
|
||||
|
||||
// Matching/not matching fish traits and equipment
|
||||
var/list/fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
var/list/fish_traits
|
||||
if(is_fish_instance)
|
||||
fish_traits = caught_fish.fish_traits
|
||||
else
|
||||
fish_traits = fish_properties[FISH_PROPERTIES_TRAITS]
|
||||
|
||||
var/additive_mod = 0
|
||||
var/multiplicative_mod = 1
|
||||
@@ -217,6 +225,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
. += additive_mod
|
||||
. *= multiplicative_mod
|
||||
|
||||
|
||||
///Comsig proc from the fishing minigame for 'roll_reward'
|
||||
/datum/fish_source/proc/roll_reward_minigame(datum/source, obj/item/fishing_rod/rod, mob/fisherman, atom/location, list/rewards)
|
||||
SIGNAL_HANDLER
|
||||
@@ -265,8 +274,6 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
else if(istype(reward, /obj/effect/spawner)) // Do not attempt to forceMove() a spawner. It will break things, and the spawned item should already be at the mob's turf by now.
|
||||
fisherman.balloon_alert(fisherman, "caught something!")
|
||||
return
|
||||
else // for fishing things like corpses, move them to the turf of the fisherman
|
||||
INVOKE_ASYNC(reward, TYPE_PROC_REF(/atom/movable, forceMove), get_turf(fisherman))
|
||||
fisherman.balloon_alert(fisherman, "caught [reward]!")
|
||||
|
||||
return reward
|
||||
@@ -306,6 +313,10 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
/datum/fish_source/proc/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot)
|
||||
if(reward_path == FISHING_DUD)
|
||||
return
|
||||
if(ismovable(reward_path))
|
||||
var/atom/movable/reward = reward_path
|
||||
reward.forceMove(spawn_location)
|
||||
return reward
|
||||
if(ispath(reward_path, /datum/chasm_detritus))
|
||||
return GLOB.chasm_detritus_types[reward_path].dispense_detritus(spawn_location, fishing_spot)
|
||||
if(!ispath(reward_path, /atom/movable))
|
||||
@@ -317,7 +328,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
return reward
|
||||
|
||||
/// Returns the fish table, with with the unavailable items from fish_counts removed.
|
||||
/datum/fish_source/proc/get_fish_table(from_explosion = FALSE)
|
||||
/datum/fish_source/proc/get_fish_table(atom/location, from_explosion = FALSE)
|
||||
var/list/table = fish_table.Copy()
|
||||
//message bottles cannot spawn from explosions. They're meant to be one-time messages (rarely) and photos from past rounds
|
||||
//and it would suck if the pool of bottle messages were constantly being emptied by explosive fishing.
|
||||
@@ -336,8 +347,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
///Multiplier used to make fishes more common compared to everything else.
|
||||
var/result_multiplier = 1
|
||||
|
||||
|
||||
var/list/final_table = get_fish_table()
|
||||
var/list/final_table = get_fish_table(location)
|
||||
|
||||
if(bait)
|
||||
for(var/trait in weight_result_multiplier)
|
||||
@@ -357,7 +367,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
final_table[result] *= rod.hook.get_hook_bonus_multiplicative(result)
|
||||
final_table[result] += rod.hook.get_hook_bonus_additive(result)//Decide on order here so it can be multiplicative
|
||||
|
||||
if(ispath(result, /obj/item/fish))
|
||||
if(ispath(result, /obj/item/fish) || isfish(result))
|
||||
if(bait)
|
||||
final_table[result] = round(final_table[result] * result_multiplier, 1)
|
||||
var/mult = bait.check_bait(result)
|
||||
@@ -384,7 +394,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
var/highest_fish_weight
|
||||
var/list/collected_fish_weights = list()
|
||||
for(var/fishable in table)
|
||||
if(ispath(fishable, /obj/item/fish))
|
||||
if(ispath(fishable, /obj/item/fish) || isfish(fishable))
|
||||
var/fish_weight = table[fishable]
|
||||
collected_fish_weights[fishable] = fish_weight
|
||||
if(fish_weight > highest_fish_weight)
|
||||
@@ -397,30 +407,38 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
table[fish] += round(difference**exponent, 1)
|
||||
|
||||
/datum/fish_source/proc/get_fish_trait_catch_mods(weight, obj/item/fish/fish, obj/item/fishing_rod/rod, mob/user, atom/location)
|
||||
if(!ispath(fish, /obj/item/fish))
|
||||
var/is_fish_instance = isfish(fish)
|
||||
if(!ispath(fish, /obj/item/fish) && !is_fish_instance)
|
||||
return weight
|
||||
var/multiplier = 1
|
||||
for(var/fish_trait in SSfishing.fish_properties[fish][FISH_PROPERTIES_TRAITS])
|
||||
var/list/fish_traits
|
||||
if(is_fish_instance)
|
||||
fish_traits = fish.fish_traits
|
||||
else
|
||||
fish_traits = SSfishing.fish_properties[fish][FISH_PROPERTIES_TRAITS]
|
||||
for(var/fish_trait in fish_traits)
|
||||
var/datum/fish_trait/trait = GLOB.fish_traits[fish_trait]
|
||||
var/list/mod = trait.catch_weight_mod(rod, user, location, fish)
|
||||
var/list/mod = trait.catch_weight_mod(rod, user, location, is_fish_instance ? fish.type : fish)
|
||||
weight += mod[ADDITIVE_FISHING_MOD]
|
||||
multiplier *= mod[MULTIPLICATIVE_FISHING_MOD]
|
||||
|
||||
return round(weight * multiplier, 1)
|
||||
|
||||
///returns true if this fishing spot has fish that are shown in the catalog.
|
||||
/datum/fish_source/proc/has_known_fishes()
|
||||
for(var/reward in fish_table)
|
||||
if(!ispath(reward, /obj/item/fish))
|
||||
/datum/fish_source/proc/has_known_fishes(atom/location)
|
||||
var/show_anyway = fish_source_flags & FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG
|
||||
for(var/reward in get_fish_table(location))
|
||||
if(!ispath(reward, /obj/item/fish) && !isfish(reward))
|
||||
continue
|
||||
var/obj/item/fish/prototype = reward
|
||||
if(initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG)
|
||||
if(!show_anyway && initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
///Add a string with the names of catchable fishes to the examine text.
|
||||
/datum/fish_source/proc/get_catchable_fish_names(mob/user, atom/location, list/examine_text)
|
||||
var/list/known_fishes = list()
|
||||
var/show_anyway = fish_source_flags & FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG
|
||||
|
||||
var/obj/item/fishing_rod/rod = user.get_active_held_item()
|
||||
var/list/final_table
|
||||
@@ -433,17 +451,18 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
var/list/rodless_weights = list()
|
||||
var/total_rod_weight = 0
|
||||
var/list/rod_weights = list()
|
||||
for(var/reward in fish_table)
|
||||
var/weight = fish_table[reward]
|
||||
var/list/table = get_fish_table(location)
|
||||
for(var/reward in table)
|
||||
var/weight = table[reward]
|
||||
var/final_weight
|
||||
if(rod)
|
||||
total_weight += weight
|
||||
final_weight = final_table[reward]
|
||||
total_rod_weight += final_weight
|
||||
if(!ispath(reward, /obj/item/fish))
|
||||
if(!ispath(reward, /obj/item/fish) && !isfish(reward))
|
||||
continue
|
||||
var/obj/item/fish/prototype = reward
|
||||
if(!(initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG))
|
||||
if(!show_anyway && !(initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG))
|
||||
continue
|
||||
if(rod)
|
||||
rodless_weights[reward] = weight
|
||||
@@ -472,7 +491,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
var/info = "You can catch the following fish here"
|
||||
|
||||
if(rod)
|
||||
info = span_tooltip("boldened are the fish you're more likely to catch with your current setup. The opposite is true for smaller names", info)
|
||||
info = span_tooltip("In bold are fish you're more likely to catch with the current setup. The opposite is true for the smaller font", info)
|
||||
examine_text += span_info("[info]: [english_list(known_fishes)].")
|
||||
|
||||
///How much the explosive_fishing_score impacts explosive fishing. The higher the value, the stronger the malus for repeated calls
|
||||
@@ -493,7 +512,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
for(var/i in 1 to (severity + 2))
|
||||
if(!prob((100 + 100 * severity)/i * multiplier))
|
||||
continue
|
||||
var/reward_loot = pick_weight(get_fish_table(from_explosion = TRUE))
|
||||
var/reward_loot = pick_weight(get_fish_table(location, from_explosion = TRUE))
|
||||
var/atom/spawn_location = isturf(location) ? location : location.drop_location()
|
||||
var/atom/movable/reward = simple_dispense_reward(reward_loot, spawn_location, location)
|
||||
if(isnull(reward))
|
||||
|
||||
@@ -698,6 +698,46 @@
|
||||
|
||||
return data
|
||||
|
||||
#define RANDOM_AQUARIUM_FISH "random_aquarium_fish"
|
||||
|
||||
/datum/fish_source/aquarium
|
||||
radial_state = "fish_tank"
|
||||
fish_table = list(
|
||||
FISHING_DUD = 10,
|
||||
)
|
||||
fish_source_flags = FISH_SOURCE_FLAG_NO_BLUESPACE_ROD|FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG
|
||||
fishing_difficulty = FISHING_EASY_DIFFICULTY - 5
|
||||
|
||||
#undef RANDOM_AQUARIUM_FISH
|
||||
|
||||
/datum/fish_source/aquarium/get_fish_table(atom/location, from_explosion = FALSE)
|
||||
if(istype(location, /obj/machinery/fishing_portal_generator))
|
||||
var/obj/machinery/fishing_portal_generator/portal = location
|
||||
location = portal.current_linked_atom
|
||||
var/list/table = list()
|
||||
for(var/obj/item/fish/fish in location)
|
||||
if(fish.status == FISH_DEAD) //dead fish cannot be caught
|
||||
continue
|
||||
table[fish] = 10
|
||||
if(!length(table))
|
||||
return fish_table
|
||||
return table
|
||||
|
||||
/datum/fish_source/aquarium/spawn_reward_from_explosion(atom/location, severity)
|
||||
return //If the aquarium breaks, all fish are released anyway.
|
||||
|
||||
/datum/fish_source/aquarium/generate_wiki_contents(datum/autowiki/fish_sources/wiki)
|
||||
var/list/data = list()
|
||||
|
||||
data += LIST_VALUE_WRAP_LISTS(list(
|
||||
FISH_SOURCE_AUTOWIKI_NAME = "Fish",
|
||||
FISH_SOURCE_AUTOWIKI_DUD = "",
|
||||
FISH_SOURCE_AUTOWIKI_WEIGHT = 100,
|
||||
FISH_SOURCE_AUTOWIKI_NOTES = "Any fish currently inside the aquarium, be they alive or dead.",
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
/datum/fish_source/hot_spring
|
||||
catalog_description = "Hot Springs"
|
||||
radial_state = "onsen"
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
stable_population = INFINITY
|
||||
breeding_timeout = 0
|
||||
fish_flags = parent_type::fish_flags & ~(FISH_FLAG_SHOW_IN_CATALOG|FISH_FLAG_EXPERIMENT_SCANNABLE)
|
||||
fish_id_redirect_path = /obj/item/fish/goldfish //Stops SSfishing from complaining
|
||||
var/expected_num_fillets = 0 //used to know how many fillets should be gotten out of this fish
|
||||
|
||||
/obj/item/fish/testdummy/add_fillet_type()
|
||||
@@ -368,6 +369,7 @@
|
||||
|
||||
/obj/item/fish/chasm_crab/instant_growth
|
||||
fish_traits = list() //We don't want to end up applying traits twice on the resulting lobstrosity
|
||||
fish_id_redirect_path = /obj/item/fish/chasm_crab
|
||||
|
||||
/datum/unit_test/fish_sources
|
||||
|
||||
@@ -419,10 +421,10 @@
|
||||
/datum/fish_source/unit_test_profound_fisher
|
||||
fish_table = list(/obj/item/fish/testdummy = 1)
|
||||
fish_counts = list(/obj/item/fish/testdummy = 2)
|
||||
fish_source_flags = parent_type::fish_source_flags | FISH_SOURCE_FLAG_SKIP_CATCHABLES
|
||||
fish_source_flags = parent_type::fish_source_flags
|
||||
|
||||
/datum/fish_source/unit_test_all_fish
|
||||
fish_source_flags = parent_type::fish_source_flags | FISH_SOURCE_FLAG_SKIP_CATCHABLES
|
||||
fish_source_flags = parent_type::fish_source_flags
|
||||
|
||||
/datum/fish_source/unit_test_all_fish/New()
|
||||
for(var/fish_type as anything in subtypesof(/obj/item/fish))
|
||||
|
||||
@@ -54,4 +54,5 @@ Fish can grow in size and weight if you fed them somewhat frequently. Giving the
|
||||
Feeding a fish mutagen can triple the probability of generating evolved offsprings, provided it has an evolution.
|
||||
You can print fishing rods of different materials from an autolathe, which can inrease or decrease fishing difficulty, casting range, experience gained and can have other, special effects.
|
||||
Albeit scarcely, it's possible to catch fish made of the same materials of a custom material fishing rod. Equipping a shiny fishing hook and the quality of the bait can improve your odds.
|
||||
You can use a fishing rod to snatch random organs during the "manipulate organs" step of the "organ manipulation" surgery.
|
||||
You can use a fishing rod to snatch random organs during the "manipulate organs" step of the "organ manipulation" surgery.
|
||||
Aquariums are also potential fishing spots. Only useful for catching fish you couldn't find in the wild, as a personal achievement and nothing more.
|
||||
Reference in New Issue
Block a user