Refactoring aquariums into components (feat: portable fish tanks) (#87866)

## About The Pull Request
I've been meaning to do this for some time. I need this for
portable/handheld aquariums/fishtanks to be possible. I'll sprite and
code them before I call this PR ready, however suggestions and code
reviews are welcome in the meantime.

Being a pretty heavy refactor, some things might break (we have more
than a few unit tests so perhaps not) while others, coincidentally,
might be fixed without me knowing. Anyway I'm sure this PR fixes
aquarium beauty, which wasn't really working to begin with because the
code was so fucking bad. Nothing really worth of a CL entry tho.


TODO:
- [x] handheld aquariums, craftable with a kit and little plastic or
buyable from the fun vendor ig.
- [x] an aquarium upgrade for handheld aquariums to bypass possible
restrictions.
- [x] update the beauty element to consider items, which shouldn't
contribute to the area beauty when held or otherwise not on a turf.

## Why It's Good For The Game
This should make handheld aquariums possible.

## Changelog

🆑
refactor: refactored aquariums heavily. Please report any fishy bug.
add: Added portable/handheld fish tanks to the game. They can be crafted
with an aquarium kit and 5 sheets of plastic. While portable, they
cannot store fish that are too big or if there're too many already. This
restriction can be removed by using the new "bluespace fish tank kit"
techweb item.
map: Replaced the lawyer's stationary pet aquarium with a fish tank, so
you can carry McGill around.
balance: Reduced the iron cost of stationary aquariums a little.
/🆑
This commit is contained in:
Ghom
2024-11-21 09:45:49 +13:00
committed by GitHub
parent 941b117d3f
commit 7663b39cc8
58 changed files with 1246 additions and 743 deletions
+1 -6
View File
@@ -1,12 +1,7 @@
/datum/unit_test/component_duping/Run()
var/list/bad_dms = list()
var/list/bad_dts = list()
for(var/t in typesof(/datum/component))
var/datum/component/comp = t
if(!isnum(initial(comp.dupe_mode)))
bad_dms += t
var/dupe_type = initial(comp.dupe_type)
if(dupe_type && !ispath(dupe_type))
bad_dts += t
TEST_ASSERT(!length(bad_dms) && !length(bad_dts),
"Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
TEST_ASSERT(!length(bad_dms), "Components with invalid dupe modes: ([bad_dms.Join(",")])")
+32 -4
View File
@@ -128,7 +128,6 @@
description = "It smells fishy."
/obj/structure/aquarium/traits
reproduction_and_growth = TRUE
var/obj/item/fish/testdummy/crossbreeder/crossbreeder
var/obj/item/fish/testdummy/cloner/cloner
var/obj/item/fish/testdummy/sterile/sterile
@@ -155,7 +154,6 @@
fish_traits = list(/datum/fish_trait/no_mating)
/obj/structure/aquarium/evolution
reproduction_and_growth = TRUE
var/obj/item/fish/testdummy/evolve/evolve
var/obj/item/fish/testdummy/evolve_two/evolve_two
@@ -195,7 +193,7 @@
///During the fish_growth unit test, we spawn a fish outside of the aquarium and check that this actually stops it from growing
/datum/fish_evolution/dummy/two/growth_checks(obj/item/fish/source, seconds_per_tick, growth)
. = ..()
if(!isaquarium(source.loc))
if(!source.loc || !HAS_TRAIT(source.loc, TRAIT_IS_AQUARIUM))
return COMPONENT_DONT_GROW
///A test that checks that fishing portals can be linked and function as expected
@@ -353,7 +351,6 @@
TEST_ASSERT(dummy_boogaloo, "The new fish type cannot be found inside the aquarium")
/obj/structure/aquarium/crab
reproduction_and_growth = TRUE //needed for growing up
///Our test subject
var/obj/item/fish/chasm_crab/instant_growth/crabbie
@@ -489,5 +486,36 @@
for(var/obj/item/fish/fish as anything in box)
fish.randomize_size_and_weight()
/datum/unit_test/aquarium_upgrade
/datum/unit_test/aquarium_upgrade/Run()
var/mob/living/carbon/human/dummy/user = allocate(__IMPLIED_TYPE__)
var/obj/item/aquarium_upgrade/bioelec_gen/upgrade = allocate(__IMPLIED_TYPE__)
var/obj/structure/aquarium/aquarium = allocate(upgrade::upgrade_from_type)
var/datum/component/aquarium/comp = aquarium.GetComponent(__IMPLIED_TYPE__)
TEST_ASSERT(comp, "[aquarium.type] doesn't have an aquarium component")
comp.set_fluid_type(AQUARIUM_FLUID_AIR)
comp.fluid_temp = MAX_AQUARIUM_TEMP
aquarium.add_traits(list(TRAIT_AQUARIUM_PANEL_OPEN, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH), AQUARIUM_TRAIT)
var/type_to_check = upgrade::upgrade_to_type
var/turf/aquarium_loc = aquarium.loc
user.put_in_hands(upgrade)
upgrade.melee_attack_chain(user, aquarium)
TEST_ASSERT(QDELETED(aquarium), "Old [aquarium.type] was not deleted after upgrade")
var/obj/structure/aquarium/upgraded_aquarium = locate(type_to_check) in aquarium_loc
TEST_ASSERT(upgraded_aquarium, "New [upgraded_aquarium.type] was not spawned after upgrade")
comp = upgraded_aquarium.GetComponent(/datum/component/aquarium)
TEST_ASSERT(comp, "New [upgraded_aquarium.type] doesn't have an aquarium component")
TEST_ASSERT_EQUAL(comp.fluid_type, AQUARIUM_FLUID_AIR, "Inherited aquarium fluid type should be [AQUARIUM_FLUID_AIR]")
TEST_ASSERT_EQUAL(comp.fluid_temp, MAX_AQUARIUM_TEMP, "Inherited aquarium fluid temperature should be [MAX_AQUARIUM_TEMP]")
TEST_ASSERT(HAS_TRAIT(upgraded_aquarium, TRAIT_AQUARIUM_PANEL_OPEN), "The new aquarium should have its panel open")
TEST_ASSERT(HAS_TRAIT(upgraded_aquarium, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH), "The 'growth and reproduction' setting for this aquarium should be disabled")
TEST_ASSERT(QDELETED(upgrade), "Aquarium upgrade wasn't deleted afterward")
#undef FISH_REAGENT_AMOUNT
#undef TRAIT_FISH_TESTING