From 00e2f6cd7b0b0816ba4484207ed4825a2ccbb5c4 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:49:48 +0200 Subject: [PATCH] Fish sources are more thoroughfully stressed during unit tests. (#86637) ## About The Pull Request The profound fisher component (for both mobs and gloves) as well as the proc responsible for rolling rewards are now being tested too. This is something I've meant to do in a while, #86633 just happened to kick it off now. ## Why It's Good For The Game More tests, fewer mistakes flying under the radar. ## Changelog N/A --- code/datums/components/fishing_spot.dm | 1 + code/datums/components/profound_fisher.dm | 29 +++++++------ code/modules/fishing/fish/_fish.dm | 4 +- code/modules/unit_tests/fish_unit_tests.dm | 47 ++++++++++++++++++++-- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 816d940487f..6ecea18976c 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -24,6 +24,7 @@ /datum/component/fishing_spot/Destroy() fish_source.on_fishing_spot_del(src) fish_source = null + REMOVE_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) return ..() /datum/component/fishing_spot/proc/handle_cast(datum/source, obj/item/fishing_rod/rod, mob/user) diff --git a/code/datums/components/profound_fisher.dm b/code/datums/components/profound_fisher.dm index 3766d32b14a..6f656cd2542 100644 --- a/code/datums/components/profound_fisher.dm +++ b/code/datums/components/profound_fisher.dm @@ -64,9 +64,12 @@ /datum/component/profound_fisher/proc/on_unarmed_attack(mob/living/source, atom/attack_target, proximity_flag, list/modifiers) SIGNAL_HANDLER - if(!source.client || !should_fish_on(source, attack_target)) + if(!should_fish_on(source, attack_target)) return - INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, attack_target) + if(source.client) + INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, attack_target) + else + INVOKE_ASYNC(src, PROC_REF(pretend_fish), source, attack_target) return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/profound_fisher/proc/pre_attack(mob/living/source, atom/target) @@ -77,7 +80,7 @@ if(source.client) INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, target) else - INVOKE_ASYNC(src, PROC_REF(pretend_fish), target) + INVOKE_ASYNC(src, PROC_REF(pretend_fish), source, target) return COMPONENT_HOSTILE_NO_ATTACK /datum/component/profound_fisher/proc/should_fish_on(mob/living/user, atom/target) @@ -102,9 +105,8 @@ REMOVE_TRAIT(source, TRAIT_PROFOUND_FISHER, TRAIT_GENERIC) UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING)) -/datum/component/profound_fisher/proc/pretend_fish(atom/target) - var/mob/living/living_parent = parent - if(DOING_INTERACTION_WITH_TARGET(living_parent, target)) +/datum/component/profound_fisher/proc/pretend_fish(mob/living/source, atom/target) + if(DOING_INTERACTION_WITH_TARGET(source, target)) return var/list/fish_spot_container[NPC_FISHING_SPOT] SEND_SIGNAL(target, COMSIG_NPC_FISHING, fish_spot_container) @@ -113,13 +115,14 @@ return null var/obj/effect/fishing_float/float = new(get_turf(target), target) playsound(float, 'sound/effects/splash.ogg', 100) - var/happiness_percentage = living_parent.ai_controller?.blackboard[BB_BASIC_HAPPINESS] / 100 - var/fishing_speed = 10 SECONDS - round(4 SECONDS * happiness_percentage) - if(!do_after(living_parent, fishing_speed, target = target) && !QDELETED(fish_spot)) - qdel(float) - return - var/reward_loot = fish_spot.roll_reward(our_rod, parent) - fish_spot.dispense_reward(reward_loot, parent, target) + if(!PERFORM_ALL_TESTS(fish_sources)) + var/happiness_percentage = source.ai_controller?.blackboard[BB_BASIC_HAPPINESS] * 0.01 + var/fishing_speed = 10 SECONDS - round(4 SECONDS * happiness_percentage) + if(!do_after(source, fishing_speed, target = target) && !QDELETED(fish_spot)) + qdel(float) + return + var/reward_loot = fish_spot.roll_reward(our_rod, source) + fish_spot.dispense_reward(reward_loot, source, target) playsound(float, 'sound/effects/bigsplash.ogg', 100) qdel(float) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 12a2ad2d448..bfae7f36829 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -452,7 +452,7 @@ var/make_edible = TRUE if(weight) for(var/reagent_type in grind_results) - grind_results[reagent_type] /= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1) + grind_results[reagent_type] /= max(FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1), 0.1) if(reagents) //This fish has reagents. Adjust the maximum volume of the reagent holder and do some math to adjut the reagents too. var/new_weight_ratio = new_weight / weight var/volume_diff = reagents.maximum_volume * new_weight_ratio - reagents.maximum_volume @@ -486,7 +486,7 @@ mob.update_equipment_speed_mods() for(var/reagent_type in grind_results) - grind_results[reagent_type] *= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1) + grind_results[reagent_type] *= max(FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1), 0.1) update_fish_force() diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index 63bb5e30616..0c02c0c3a90 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -280,15 +280,43 @@ growth_rate = 100 fish_traits = list() //We don't want to end up applying traits twice on the resulting lobstrosity -/datum/unit_test/explosive_fishing +/datum/unit_test/fish_sources -/datum/unit_test/explosive_fishing/Run() - var/datum/fish_source/source = GLOB.preset_fish_sources[/datum/fish_source/unit_test] +/datum/unit_test/fish_sources/Run() + var/datum/fish_source/source = GLOB.preset_fish_sources[/datum/fish_source/unit_test_explosive] source.spawn_reward_from_explosion(run_loc_floor_bottom_left, 1) if(source.fish_counts[/obj/item/wrench]) TEST_FAIL("The unit test item wasn't removed/spawned from fish_table during 'spawn_reward_from_explosion'.") -/datum/fish_source/unit_test + ///From here, we check that the profound_fisher as well as fish source procs for rolling rewards don't fail. + source = GLOB.preset_fish_sources[/datum/fish_source/unit_test_profound_fisher] + run_loc_floor_bottom_left.AddElement(/datum/element/lazy_fishing_spot, /datum/fish_source/unit_test_profound_fisher) + var/mob/living/basic/fisher = allocate(/mob/living/basic) + fisher.AddComponent(/datum/component/profound_fisher) + fisher.set_combat_mode(FALSE) + fisher.melee_attack(run_loc_floor_bottom_left, ignore_cooldown = TRUE) + if(source.fish_counts[/obj/item/fish/testdummy] != 1) + TEST_FAIL("The unit test profound fisher didn't catch the test fish on a lazy fishing spot (element)") + + ///For good measure, let's try it again, but with the component this time, and a human mob and gloves + run_loc_floor_bottom_left.RemoveElement(/datum/element/lazy_fishing_spot, /datum/fish_source/unit_test_profound_fisher) + var/datum/component/comp = run_loc_floor_bottom_left.AddComponent(/datum/component/fishing_spot, source) + var/mob/living/carbon/human/consistent/angler = allocate(/mob/living/carbon/human/consistent) + var/obj/item/clothing/gloves/noodling = allocate(/obj/item/clothing/gloves) + noodling.AddComponent(/datum/component/profound_fisher) + angler.equip_to_slot(noodling, ITEM_SLOT_GLOVES) + + angler.UnarmedAttack(run_loc_floor_bottom_left, proximity_flag = TRUE) + if(source.fish_counts[/obj/item/fish/testdummy]) + TEST_FAIL("The unit test profound fisher didn't catch the test fish on a fishing spot (component)") + qdel(comp) + + ///As a final test, let's see how it goes with a fish source containing every single fish subtype. + comp = run_loc_floor_bottom_left.AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/unit_test_all_fish]) + fisher.melee_attack(run_loc_floor_bottom_left, ignore_cooldown = TRUE) + qdel(comp) + +/datum/fish_source/unit_test_explosive fish_table = list( /obj/item/wrench = 1, /obj/item/screwdriver = INFINITY, //infinite weight, so if fish counts doesn't work as intended, this'll be always picked. @@ -298,6 +326,17 @@ /obj/item/screwdriver = 0, //this should never be picked. ) +/datum/fish_source/unit_test_profound_fisher + fish_table = list(/obj/item/fish/testdummy = 1) + fish_counts = list(/obj/item/fish/testdummy = 2) + +/datum/fish_source/unit_test_all_fish + +/datum/fish_source/unit_test_all_fish/New() + for(var/fish_type as anything in subtypesof(/obj/item/fish)) + fish_table[fish_type] = 10 + return ..() + /datum/unit_test/edible_fish /datum/unit_test/edible_fish/Run()