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()