diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index f9f390f95a1..efa29f98dc2 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -166,7 +166,7 @@ ///The breeding timeout for newly instantiated fish is multiplied by this. #define NEW_FISH_BREEDING_TIMEOUT_MULT 2 ///The last feeding timestamp of newly instantiated fish is multiplied by this: ergo, they spawn 50% hungry. -#define NEW_FISH_LAST_FEEDING_MULT 0.5 +#define NEW_FISH_LAST_FEEDING_MULT 0.33 //IF YOU ADD ANY NEW FLAG, ADD IT TO THE RESPECTIVE BITFIELD in _globalvars/bitfields.dm TOO! diff --git a/code/datums/components/aquarium.dm b/code/datums/components/aquarium.dm index 00a47695956..cf86c6b56b4 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -120,6 +120,10 @@ movable.AddElement(/datum/element/relay_attackers) movable.AddComponent(/datum/component/fishing_spot, /datum/fish_source/aquarium) + + movable.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(movable, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) + for(var/atom/movable/content as anything in movable.contents) if(content.flags_1 & INITIALIZED_1) on_entered(movable, content) @@ -144,6 +148,7 @@ COMSIG_ATOM_ATTACK_ROBOT_SECONDARY, COMSIG_ATOM_ATTACK_HAND_SECONDARY, COMSIG_ATOM_UI_INTERACT, + COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, )) if(movable.reagents) UnregisterSignal(movable, COMSIG_REAGENTS_NEW_REAGENT) @@ -216,7 +221,7 @@ source.balloon_alert(user, "fed the fish") return ITEM_INTERACT_SUCCESS - if(!HAS_TRAIT(item, TRAIT_AQUARIUM_CONTENT)) + if(!HAS_TRAIT(item, TRAIT_AQUARIUM_CONTENT) || (!isitem(parent) && user.combat_mode)) return //proceed with normal interactions var/broken = source.get_integrity_percentage() <= source.integrity_failure @@ -240,6 +245,10 @@ ///Feed the fish at defined intervals until the feed storage is empty. /datum/component/aquarium/process(seconds_per_tick) + //safe mode, no need to feed the fishes + if(HAS_TRAIT_FROM(parent, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT)) + last_feeding += seconds_per_tick SECONDS + return var/atom/movable/movable = parent if(!movable.reagents?.total_volume) if(movable.reagents) @@ -255,6 +264,7 @@ /datum/component/aquarium/proc/on_plunger_act(atom/movable/source, obj/item/plunger/plunger, mob/living/user, reinforced) SIGNAL_HANDLER if(!HAS_TRAIT(source, TRAIT_AQUARIUM_PANEL_OPEN)) + source.balloon_alert(user, "open panel first!") return INVOKE_ASYNC(src, PROC_REF(do_plunging), source, user) return COMPONENT_NO_AFTERATTACK @@ -463,7 +473,7 @@ var/atom/movable/aquarium = parent .["fluidType"] = fluid_type .["temperature"] = fluid_temp - .["allowBreeding"] = HAS_TRAIT_FROM(aquarium, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) + .["safe_mode"] = !HAS_TRAIT_FROM(aquarium, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) .["fishData"] = list() .["feedingInterval"] = feeding_interval / (1 MINUTES) .["propData"] = list() @@ -512,8 +522,8 @@ if(params["fluid"] != fluid_type && (params["fluid"] in fluid_types)) set_fluid_type(params["fluid"]) . = TRUE - if("allow_breeding") - if(HAS_TRAIT(movable, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH)) + if("safe_mode") + if(HAS_TRAIT_FROM(movable, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT)) REMOVE_TRAIT(movable, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) else ADD_TRAIT(movable, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) @@ -563,5 +573,26 @@ else if(dead_fish > 0) user.add_mood_event("aquarium", morb ? /datum/mood_event/morbid_aquarium_good : /datum/mood_event/aquarium_negative) +/datum/component/aquarium/proc/on_requesting_context_from_item(atom/source, list/context, obj/item/held_item, mob/user) + SIGNAL_HANDLER + var/open_panel = HAS_TRAIT(source, TRAIT_AQUARIUM_PANEL_OPEN) + if(!held_item) + var/isitem = isitem(source) + if(!isitem || open_panel) + context[SCREENTIP_CONTEXT_LMB] = open_panel ? "Adjust settings" : "Admire" + if(isitem) + context[SCREENTIP_CONTEXT_RMB] = "Admire" + context[SCREENTIP_CONTEXT_ALT_LMB] = "[open_panel ? "Open" : "Close"] settings panel" + return CONTEXTUAL_SCREENTIP_SET + if(istype(held_item, /obj/item/plunger)) + context[SCREENTIP_CONTEXT_LMB] = "Empty feed storage" + return CONTEXTUAL_SCREENTIP_SET + if(istype(held_item, /obj/item/reagent_containers/cup/fish_feed) && (!source.reagents || !open_panel)) + context[SCREENTIP_CONTEXT_LMB] = "Feed fishes" + return CONTEXTUAL_SCREENTIP_SET + if(HAS_TRAIT(held_item, TRAIT_AQUARIUM_CONTENT)) + context[SCREENTIP_CONTEXT_LMB] = "Insert in aquarium" + return CONTEXTUAL_SCREENTIP_SET + #undef MIN_AQUARIUM_BEAUTY #undef MAX_AQUARIUM_BEAUTY diff --git a/code/datums/elements/fish_safe_storage.dm b/code/datums/elements/fish_safe_storage.dm index bb7864ced0e..ec5c5984864 100644 --- a/code/datums/elements/fish_safe_storage.dm +++ b/code/datums/elements/fish_safe_storage.dm @@ -22,7 +22,7 @@ /datum/element/fish_safe_storage/Detach(atom/source) for(var/obj/item/fish/fish in source) tracked_fish -= fish - fish.exit_stasis() + REMOVE_TRAIT(fish, TRAIT_FISH_STASIS, REF(src)) UnregisterSignal(source, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON)) return ..() @@ -30,19 +30,19 @@ SIGNAL_HANDLER if(isfish(arrived)) tracked_fish |= arrived - arrived.enter_stasis() + ADD_TRAIT(arrived, TRAIT_FISH_STASIS, REF(src)) /datum/element/fish_safe_storage/proc/on_init_on(datum/source, obj/item/fish/created) SIGNAL_HANDLER if(isfish(created) && !QDELETED(created)) tracked_fish |= created - created.enter_stasis() + ADD_TRAIT(created, TRAIT_FISH_STASIS, REF(src)) /datum/element/fish_safe_storage/proc/on_exit(datum/source, obj/item/fish/gone) SIGNAL_HANDLER if(isfish(gone)) tracked_fish -= gone - gone.exit_stasis() + REMOVE_TRAIT(gone, TRAIT_FISH_STASIS, REF(src)) /datum/element/fish_safe_storage/process(seconds_per_tick) for(var/obj/item/fish/fish as anything in tracked_fish) diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm index 0e704a62df4..89ce9a5c371 100644 --- a/code/modules/cargo/packs/service.dm +++ b/code/modules/cargo/packs/service.dm @@ -285,21 +285,6 @@ crate_type = /obj/structure/closet/crate/large discountable = SUPPLY_PACK_UNCOMMON_DISCOUNTABLE -/datum/supply_pack/service/aquarium_kit - name = "Aquarium Kit" - desc = "Everything you need to start your own aquarium. Contains aquarium construction kit, \ - fish catalog, fish food and three freshwater fish from our collection." - cost = CARGO_CRATE_VALUE * 5 - contains = list(/obj/item/book/manual/fish_catalog, - /obj/item/storage/fish_case/random/freshwater = 3, - /obj/item/reagent_containers/cup/fish_feed, - /obj/item/storage/box/aquarium_props, - /obj/item/aquarium_kit, - ) - crate_name = "aquarium kit crate" - crate_type = /obj/structure/closet/crate/wooden - discountable = SUPPLY_PACK_UNCOMMON_DISCOUNTABLE - /// Spare bar sign wallmount /datum/supply_pack/service/bar_sign name = "Bar Sign Replacement Kit" diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 15c7d226932..d8386549780 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -104,6 +104,8 @@ /obj/structure/aquarium/prefilled/Initialize(mapload) . = ..() + ADD_TRAIT(src, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) //start with safe mode on + new /obj/item/aquarium_prop/sand(src) new /obj/item/aquarium_prop/seaweed(src) @@ -246,6 +248,8 @@ /obj/item/fish_tank/lawyer/Initialize(mapload) . = ..() + ADD_TRAIT(src, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) //start with safe mode on + new /obj/item/aquarium_prop/sand(src) new /obj/item/aquarium_prop/seaweed(src) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 1521eb4cc77..3d91e1173fc 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -191,6 +191,9 @@ ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, REF(src)) //Composting a food that is not real food wouldn't work anyway. START_PROCESSING(SSobj, src) + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_FISH_STASIS), PROC_REF(enter_stasis)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_FISH_STASIS), PROC_REF(exit_stasis)) + //Adding this because not all fish have the gore foodtype that makes them automatically eligible for dna infusion. ADD_TRAIT(src, TRAIT_VALID_DNA_INFUSION, INNATE_TRAIT) @@ -473,7 +476,7 @@ return span_deadsay("It's [HAS_MIND_TRAIT(user, TRAIT_NAIVE) ? "taking the big snooze" : "dead"].") var/list/warnings = list() - if(is_starving()) + if(get_starvation_mult()) warnings += "starving" if(!HAS_TRAIT(src, TRAIT_FISH_STASIS) && !proper_environment()) warnings += "drowning" @@ -797,25 +800,29 @@ . = ..() check_flopping() -/obj/item/fish/proc/enter_stasis() - ADD_TRAIT(src, TRAIT_FISH_STASIS, INNATE_TRAIT) - // Stop processing until inserted into aquarium again. +/// Stop processing once the stasis trait is added +/obj/item/fish/proc/enter_stasis(datum/source) + SIGNAL_HANDLER stop_flopping() STOP_PROCESSING(SSobj, src) -/obj/item/fish/proc/exit_stasis() - REMOVE_TRAIT(src, TRAIT_FISH_STASIS, INNATE_TRAIT) - if(status != FISH_DEAD) - START_PROCESSING(SSobj, src) +/// Start processing again when the stasis trait is removed +/obj/item/fish/proc/exit_stasis(datum/source) + SIGNAL_HANDLER + if(status == FISH_DEAD) + return + START_PROCESSING(SSobj, src) + check_flopping() -///Returns the 0-1 value for hunger -/obj/item/fish/proc/get_hunger() - . = CLAMP01((world.time - last_feeding) / feeding_frequency) +///Returns the value for hunger ranging from 0 to the cap (by default 1) +/obj/item/fish/proc/get_hunger(cap = 1) + . = clamp((world.time - last_feeding) / feeding_frequency, 0, cap) if(HAS_TRAIT(src, TRAIT_FISH_NO_HUNGER)) return min(., 0.2) -/obj/item/fish/proc/is_starving() - return get_hunger() >= 1 +/obj/item/fish/proc/get_starvation_mult() + var/hunger = get_hunger(cap = 2) + return hunger >= 1 ? hunger : 0 ///Feed the fishes with the contents of the fish feed /obj/item/fish/proc/feed(datum/reagents/fed_reagents) @@ -912,12 +919,17 @@ if(HAS_TRAIT(src, TRAIT_FISH_STASIS) || status != FISH_ALIVE) return - process_health(seconds_per_tick) - if(ready_to_reproduce()) - try_to_reproduce() + //safe mode, don't do much except a few things that don't involve growing or reproducing. + if(loc && HAS_TRAIT_FROM(loc, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT)) + last_feeding += seconds_per_tick SECONDS + breeding_wait += seconds_per_tick SECONDS + else + process_health(seconds_per_tick) + if(ready_to_reproduce()) + try_to_reproduce() - if(HAS_TRAIT(src, TRAIT_FISH_ELECTROGENESIS) && COOLDOWN_FINISHED(src, electrogenesis_cooldown)) - try_electrogenesis() + if(HAS_TRAIT(src, TRAIT_FISH_ELECTROGENESIS) && COOLDOWN_FINISHED(src, electrogenesis_cooldown)) + try_electrogenesis() SEND_SIGNAL(src, COMSIG_FISH_LIFE, seconds_per_tick) @@ -1137,13 +1149,14 @@ /obj/item/fish/proc/process_health(seconds_per_tick) var/health_change_per_second = 0 if(!proper_environment()) - health_change_per_second -= 3 //Dying here - if(is_starving()) - health_change_per_second -= 0.5 //Starving + health_change_per_second -= 2.5 //Dying here + var/starvation_mult = get_starvation_mult() + if(starvation_mult) + health_change_per_second -= 0.25 * starvation_mult //Starving else health_change_per_second += 0.5 //Slowly healing if(HAS_TRAIT(src, TRAIT_FISH_ON_TESLIUM)) - health_change_per_second -= 0.65 //This becomes - 0.15 if safe and not starving. + health_change_per_second -= 0.65 adjust_health(health + health_change_per_second * seconds_per_tick) @@ -1362,7 +1375,7 @@ flop_animation() /obj/item/fish/proc/try_electrogenesis() - if(status == FISH_DEAD || is_starving()) + if(status == FISH_DEAD || get_starvation_mult()) return COOLDOWN_START(src, electrogenesis_cooldown, ELECTROGENESIS_DURATION + ELECTROGENESIS_VARIANCE) var/fish_zap_range = 1 @@ -1446,7 +1459,7 @@ user.electrocute_act(5, src) //was it all worth it? fish_flags |= FISH_FLAG_PETTED new /obj/effect/temp_visual/heart(get_turf(src)) - if((/datum/fish_trait/aggressive in fish_traits) && prob(50)) + if((/datum/fish_trait/predator in fish_traits) && prob(50)) if(!in_aquarium) user.visible_message( span_warning("[src] dances around before biting [user]!"), diff --git a/code/modules/fishing/fish/fish_evolution.dm b/code/modules/fishing/fish/fish_evolution.dm index 8dd9bb0ffcd..09ce6452f75 100644 --- a/code/modules/fishing/fish/fish_evolution.dm +++ b/code/modules/fishing/fish/fish_evolution.dm @@ -96,7 +96,7 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution) name = "???" //The resulting fish is not shown on the catalog. probability = 40 new_fish_type = /obj/item/fish/mastodon - new_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/amphibious, /datum/fish_trait/predator, /datum/fish_trait/aggressive) + new_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/amphibious, /datum/fish_trait/predator, /datum/fish_trait/territorial) conditions_note = "The fish (and its mate) needs to be unusually big both in size and weight." show_result_on_wiki = FALSE @@ -125,13 +125,13 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution) /datum/fish_evolution/chainsawfish probability = 30 new_fish_type = /obj/item/fish/chainsawfish - new_traits = list(/datum/fish_trait/predator, /datum/fish_trait/aggressive) - conditions_note = "The fish needs to be unusually big and aggressive" + new_traits = list(/datum/fish_trait/predator, /datum/fish_trait/territorial) + conditions_note = "The fish needs to be unusually big and territorial" /datum/fish_evolution/chainsawfish/check_conditions(obj/item/fish/source, obj/item/fish/mate, atom/movable/aquarium) var/double_avg_size = /obj/item/fish/goldfish::average_size * 2 var/double_avg_weight = /obj/item/fish/goldfish::average_weight * 2 - if(source.size >= double_avg_size && source.weight >= double_avg_weight && (/datum/fish_trait/aggressive in source.fish_traits)) + if(source.size >= double_avg_size && source.weight >= double_avg_weight && (/datum/fish_trait/territorial in source.fish_traits)) return ..() return FALSE diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index c3b813b5b48..72110419154 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -184,11 +184,12 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/nocturnal/proc/check_light(obj/item/fish/source, seconds_per_tick) SIGNAL_HANDLER - if(source.loc && (HAS_TRAIT(source.loc, TRAIT_IS_AQUARIUM) || isturf(source.loc))) - var/turf/turf = get_turf(source) - var/light_amount = turf.get_lumcount() - if(light_amount > SHADOW_SPECIES_LIGHT_THRESHOLD) - source.adjust_health(source.health - 0.5 * seconds_per_tick) + if(!source.loc || (!HAS_TRAIT(source.loc, TRAIT_IS_AQUARIUM) && !isturf(source.loc))) + return + var/turf/turf = get_turf(source) + var/light_amount = turf.get_lumcount() + if(light_amount > SHADOW_SPECIES_LIGHT_THRESHOLD) + source.adjust_health(source.health - 0.5 * seconds_per_tick) /datum/fish_trait/nocturnal/apply_to_mob(mob/living/basic/mob) . = ..() @@ -518,20 +519,23 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) . = ..() ADD_TRAIT(fish, TRAIT_FISH_CROSSBREEDER, FISH_TRAIT_DATUM) -/datum/fish_trait/aggressive - name = "Aggressive" +/datum/fish_trait/territorial + name = "Territorial" inheritability = 80 diff_traits_inheritability = 40 - catalog_description = "This fish is aggressively territorial, and may attack fish that come close to it." + catalog_description = "This fish will start attacking other fish if the aquarium has five or more." -/datum/fish_trait/aggressive/apply_to_fish(obj/item/fish/fish) +/datum/fish_trait/territorial/apply_to_fish(obj/item/fish/fish) . = ..() RegisterSignal(fish, COMSIG_FISH_LIFE, PROC_REF(try_attack_fish)) -/datum/fish_trait/aggressive/proc/try_attack_fish(obj/item/fish/source, seconds_per_tick) +/datum/fish_trait/territorial/proc/try_attack_fish(obj/item/fish/source, seconds_per_tick) SIGNAL_HANDLER if(!source.loc || !HAS_TRAIT(source.loc, TRAIT_IS_AQUARIUM) || !SPT_PROB(1, seconds_per_tick)) return + var/list/fishes = source.get_aquarium_fishes(TRUE, source) + if(length(fishes) < 5) + return for(var/obj/item/fish/victim as anything in source.get_aquarium_fishes(TRUE, source)) if(victim.status != FISH_ALIVE) continue diff --git a/code/modules/fishing/fish/types/air_space.dm b/code/modules/fishing/fish/types/air_space.dm index 3b053dc4c25..95418f5248a 100644 --- a/code/modules/fishing/fish/types/air_space.dm +++ b/code/modules/fishing/fish/types/air_space.dm @@ -122,7 +122,7 @@ fillet_type = /obj/item/food/fishmeat/carp/no_tox fish_traits = list( /datum/fish_trait/carnivore, - /datum/fish_trait/aggressive, + /datum/fish_trait/territorial, /datum/fish_trait/predator, /datum/fish_trait/necrophage, /datum/fish_trait/no_mating, diff --git a/code/modules/fishing/fish/types/anadromous.dm b/code/modules/fishing/fish/types/anadromous.dm index 7f9e6b4d2e2..02d126bb301 100644 --- a/code/modules/fishing/fish/types/anadromous.dm +++ b/code/modules/fishing/fish/types/anadromous.dm @@ -55,7 +55,7 @@ fishing_difficulty_modifier = 10 required_temperature_min = MIN_AQUARIUM_TEMP+12 required_temperature_max = MIN_AQUARIUM_TEMP+27 - fish_traits = list(/datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/aggressive) + fish_traits = list(/datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/territorial) evolution_types = list(/datum/fish_evolution/armored_pike) compatible_types = list(/obj/item/fish/pike/armored) favorite_bait = list( diff --git a/code/modules/fishing/fish/types/freshwater.dm b/code/modules/fishing/fish/types/freshwater.dm index 4e7a7d9c9eb..cb4546e7961 100644 --- a/code/modules/fishing/fish/types/freshwater.dm +++ b/code/modules/fishing/fish/types/freshwater.dm @@ -82,7 +82,7 @@ average_size = 30 average_weight = 500 stable_population = 3 - fish_traits = list(/datum/fish_trait/aggressive) + fish_traits = list(/datum/fish_trait/territorial) required_temperature_min = MIN_AQUARIUM_TEMP+22 required_temperature_max = MIN_AQUARIUM_TEMP+30 diff --git a/code/modules/fishing/fish/types/ruins.dm b/code/modules/fishing/fish/types/ruins.dm index 233c6961d26..da2d2ef7729 100644 --- a/code/modules/fishing/fish/types/ruins.dm +++ b/code/modules/fishing/fish/types/ruins.dm @@ -24,7 +24,7 @@ average_size = 180 average_weight = 5000 death_text = "%SRC stops moving." - 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) + 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/territorial) beauty = FISH_BEAUTY_BAD /obj/item/fish/mastodon/Initialize(mapload, apply_qualities = TRUE) diff --git a/code/modules/fishing/fish/types/syndicate.dm b/code/modules/fishing/fish/types/syndicate.dm index 81366c2ba8f..b36efd4a0c2 100644 --- a/code/modules/fishing/fish/types/syndicate.dm +++ b/code/modules/fishing/fish/types/syndicate.dm @@ -97,7 +97,7 @@ FISH_BAIT_VALUE = GORE, ), ) - fish_traits = list(/datum/fish_trait/aggressive, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/stinger) + fish_traits = list(/datum/fish_trait/territorial, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/stinger) required_temperature_min = MIN_AQUARIUM_TEMP+18 required_temperature_max = MIN_AQUARIUM_TEMP+26 @@ -207,7 +207,7 @@ random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS beauty = FISH_BEAUTY_GREAT fishing_difficulty_modifier = 20 - fish_traits = list(/datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/aggressive, /datum/fish_trait/picky_eater, /datum/fish_trait/stinger) + fish_traits = list(/datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/territorial, /datum/fish_trait/picky_eater, /datum/fish_trait/stinger) evolution_types = null compatible_types = list(/obj/item/fish/pike) favorite_bait = list( diff --git a/code/modules/fishing/fish/types/tiziran.dm b/code/modules/fishing/fish/types/tiziran.dm index 7cc3ea94e68..fdfbd578083 100644 --- a/code/modules/fishing/fish/types/tiziran.dm +++ b/code/modules/fishing/fish/types/tiziran.dm @@ -37,7 +37,7 @@ /obj/item/fish/moonfish/proc/egg_checks(datum/source, seconds_per_tick, growth, result_path) if(result_path != /obj/item/food/moonfish_eggs) //Don't stop the growth of the dwarf subtype. return - if(!proper_environment() || is_starving()) + if(!proper_environment() || get_starvation_mult()) return COMPONENT_DONT_GROW var/count = 0 for(var/obj/item/food/moonfish_eggs/egg in loc) diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm index ac4f257dc2a..30cb60cc243 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hauntedtradingpost.dm @@ -88,12 +88,11 @@ /obj/structure/aquarium/donkfish/Initialize(mapload) . = ..() + ADD_TRAIT(src, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) new /obj/item/aquarium_prop/rocks(src) new /obj/item/aquarium_prop/seaweed(src) new /obj/item/fish/donkfish(src) new /obj/item/fish/donkfish(src) - create_reagents(20, SEALED_CONTAINER) - reagents.add_reagent(/datum/reagent/consumable/nutriment, 20) //gimmick ketchup bottle for healing minor injuries /obj/item/reagent_containers/condiment/donksauce diff --git a/code/modules/research/designs/autolathe/service_designs.dm b/code/modules/research/designs/autolathe/service_designs.dm index 21fda49fc1b..38e36d26914 100644 --- a/code/modules/research/designs/autolathe/service_designs.dm +++ b/code/modules/research/designs/autolathe/service_designs.dm @@ -562,6 +562,18 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SCIENCE +/datum/design/aquarium_kit + name = "Aquarium Kit" + id = "aquarium_kit" + build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT) + build_path = /obj/item/aquarium_kit + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_SERVICE, + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SCIENCE + /datum/design/ticket_machine name = "Ticket Machine Frame" id = "ticket_machine" diff --git a/code/modules/research/techweb/nodes/service_nodes.dm b/code/modules/research/techweb/nodes/service_nodes.dm index 824cd611b83..6786c2f9e1e 100644 --- a/code/modules/research/techweb/nodes/service_nodes.dm +++ b/code/modules/research/techweb/nodes/service_nodes.dm @@ -159,6 +159,7 @@ "fishing_portal_generator", "fishing_rod", "fish_case", + "aquarium_kit", ) /datum/techweb_node/fishing_equip_adv diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index 466540bb187..fd2e0dccc81 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -55,4 +55,5 @@ Feeding a fish mutagen can triple the probability of generating evolved offsprin 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. +By opening the aquarium panel and turning "Safe Mode" on, you can easily set up a purely decorative aquarium without having to worry about food, temperature and type of water. 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. \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/Aquarium.tsx b/tgui/packages/tgui/interfaces/Aquarium.tsx index bbdc7532634..c5eb08e5644 100644 --- a/tgui/packages/tgui/interfaces/Aquarium.tsx +++ b/tgui/packages/tgui/interfaces/Aquarium.tsx @@ -24,7 +24,7 @@ type Data = { fluidTypes: string[]; fishData: FishData[]; propData: PropData[]; - allowBreeding: BooleanLike; + safe_mode: BooleanLike; feedingInterval: number; heartIcon: string; heartIconState: string; @@ -270,7 +270,7 @@ const Settings = (props) => { maxTemperature, fluidTypes, fluidType, - allowBreeding, + safe_mode, feedingInterval, } = data; @@ -319,13 +319,14 @@ const Settings = (props) => {
- +