From 6b543476daeb35ade7e3ffe5708ac17eeee98755 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:11:59 +0100 Subject: [PATCH] Aquarium kits can now be printed + other tweaks. (#88068) ## About The Pull Request Aquarium kits can now be printed from service, cargo, science protolathes and the autolathe too, from half a sheet of metal. You still need the other materials to set it up but it should be fairy simple if you can access a proto/autolathe. The 'Growth/Reproduction' setting for aquariums has been renamed to "Safe Mode", which, on top of disabling features such as growth, reproduction, evolution, power generation etc etc, will also disable the water, temperature and food requirements for keeping the fish alive. Useful if you want a purely ornamental aquarium or you have to skidaddle somewhere else for a while. The lawyer, as well as prefilled aquariums start with 'Safe Mode' enabled. The 'Aggressive' fish trait has been replaced with 'Territorial', which is exactly the same but the fish won't lash out unless the aquarium is populated by five fishes or more. No more angelfish viciously attacking the guppy and goldfish in prefilled aquariums. Tweaked a couple values around hunger and fish health loss when starving or in a bad environment to cause slightly less damage. Lastly, added screentips to the aquarium component, which is something I've forgot to do in the PR that brought it. ## Why It's Good For The Game Aquariums may be a complex feature, but as far as I can tell, I had been neglecting the possibility of aquariums as simple room decoration for a while (outside of the beauty-related mechanics), and the constant maintenance (and perhaps a bit of knowhow) they require makes them awful at that. Also, the "growth/reproduction" setting really didn't have a reason to be before, since it didn't offer any tangible benifit to turn it off, so I had to revamped it. Also it's been proven by now that keeping aquariums as cargo-orderable stuff is just bad. As for the fish trait change, it just sucks to see the angelfish shank the goldfish with no way to solve it other than removing the hyper-aggressive killer fish from san diego fella. ## Changelog :cl: balance: Aquarium kits can now be printed from cargo, service, science protolathes as well as the autolathe. They no longer have to be ordered from cargo. balance: Revamped the "Growth/Reproduction" setting for aquarium to "Safe Mode", which also disables the food, temperature and water requiremenets of aquariums, making it useful for purely decorative aquariums. balance: Replaced the "Aggressive" fish trait with "Territorial". No more angelfish shanking the goldfish and guppy in prefilled aquariums with less than 5 fishes. qol: Added screentips to aquariums. /:cl: --- code/__DEFINES/fish.dm | 2 +- code/datums/components/aquarium.dm | 39 ++++++++++-- code/datums/elements/fish_safe_storage.dm | 8 +-- code/modules/cargo/packs/service.dm | 15 ----- code/modules/fishing/aquarium/aquarium.dm | 4 ++ code/modules/fishing/fish/_fish.dm | 61 +++++++++++-------- code/modules/fishing/fish/fish_evolution.dm | 8 +-- code/modules/fishing/fish/fish_traits.dm | 24 +++++--- code/modules/fishing/fish/types/air_space.dm | 2 +- code/modules/fishing/fish/types/anadromous.dm | 2 +- code/modules/fishing/fish/types/freshwater.dm | 2 +- code/modules/fishing/fish/types/ruins.dm | 2 +- code/modules/fishing/fish/types/syndicate.dm | 4 +- code/modules/fishing/fish/types/tiziran.dm | 2 +- .../spaceruin_code/hauntedtradingpost.dm | 3 +- .../designs/autolathe/service_designs.dm | 12 ++++ .../research/techweb/nodes/service_nodes.dm | 1 + strings/fishing_tips.txt | 1 + tgui/packages/tgui/interfaces/Aquarium.tsx | 13 ++-- 19 files changed, 128 insertions(+), 77 deletions(-) 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) => {
- +