Carps, frogs and young lobstrosities now fear the fishing hat! (#85380)

## About The Pull Request
Carps, frogs and young lobstrosities now fear legendary anglers wearing
the legendary fishing hat and will flee. The item is skill-locked, so
only those that have maxxed out the skill can wear it.

Differently, adult lobstrosities and megacarps (and suicide frogs, which
are used nowhere) do not flee but will still prioritize them over the
rest.

## Why It's Good For The Game
I'm putting some emphasis on the "fish fear me" _(lobstrosities and
frogs aren't exactly fish but it'd been quite boring to only include
carps)_ and also making the hat a bit more than just some cosmetic
novelty.

## Changelog

🆑
add: Carps, frogs and young lobstrosities now fear people wearing
fishing hats! Adults and megacarp favour the 'fight' part of the fear
reflex however.
fix: The hat stabilizer module now inherits the clothing traits of the
attached hat.
/🆑
This commit is contained in:
Ghom
2024-07-31 14:38:37 +01:00
committed by GitHub
parent dfbf94ca09
commit 2535df375d
20 changed files with 161 additions and 34 deletions
@@ -14,6 +14,7 @@
BB_LOBSTROSITY_FINGER_LUST = 0,
BB_LOBSTROSITY_NAIVE_HUNTER = FALSE,
BB_BASIC_MOB_FLEE_DISTANCE = 8,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_OWNER_SELF_HARM_RESPONSES = SHRIMP_HARM_RESPONSES,
)
ai_traits = PAUSE_DURING_DO_AFTER
@@ -24,7 +25,7 @@
/datum/ai_planning_subtree/random_speech/insect,
/datum/ai_planning_subtree/hoard_fingers,
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/targeted_mob_ability/lobster,
/datum/ai_planning_subtree/flee_target/lobster,
/datum/ai_planning_subtree/attack_obstacle_in_path,
@@ -43,13 +44,14 @@
BB_LOBSTROSITY_FINGER_LUST = 0,
BB_LOBSTROSITY_NAIVE_HUNTER = TRUE,
BB_BASIC_MOB_FLEE_DISTANCE = 4,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_OWNER_SELF_HARM_RESPONSES = SHRIMP_HARM_RESPONSES,
)
planning_subtrees = list(
/datum/ai_planning_subtree/random_speech/insect,
/datum/ai_planning_subtree/hoard_fingers,
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/targeted_mob_ability/lobster,
/datum/ai_planning_subtree/flee_target/lobster,
/datum/ai_planning_subtree/attack_obstacle_in_path,
@@ -100,14 +102,17 @@
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lobster
/datum/ai_planning_subtree/basic_melee_attack_subtree/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
if(!isliving(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]))
var/atom/movable/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if(!isliving(target))
return ..()
if (!controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
return
if (!isnull(controller.blackboard[BB_LOBSTROSITY_TARGET_LIMB]))
return
if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))
return //juvenile lobstrosities fear me.
var/mob/living/living_pawn = controller.pawn
if (DOING_INTERACTION_WITH_TARGET(living_pawn, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]))
if (DOING_INTERACTION_WITH_TARGET(living_pawn, target))
return
return ..()
@@ -118,9 +123,14 @@
if (isnull(target) || !istype(target))
return ..()
var/is_vulnerable = FALSE
if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && target.body_position == LYING_DOWN)
is_vulnerable = TRUE
else
if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER])
if(HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))
//Trigger lobstrosity PTSD. Don't clear the target so we can run away.
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE)
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
if(target.body_position == LYING_DOWN)
is_vulnerable = TRUE
if(!is_vulnerable)
for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS])
if (!HAS_TRAIT(target, trait))
continue
@@ -137,9 +147,12 @@
flee_behaviour = /datum/ai_behavior/run_away_from_target/lobster
/datum/ai_planning_subtree/flee_target/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/atom/movable/target = controller.blackboard[target_key]
if(!QDELETED(target) && controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))
return ..()
var/datum/action/cooldown/using_action = controller.blackboard[BB_TARGETED_ACTION]
if (using_action?.IsAvailable())
return
return FALSE
return ..()
/datum/ai_behavior/run_away_from_target/lobster
@@ -147,19 +160,23 @@
/datum/ai_behavior/run_away_from_target/lobster/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key)
var/atom/target = controller.blackboard[target_key]
if(isnull(target))
if(QDELETED(target))
return ..()
if(isliving(target))
var/mob/living/living_target = target
if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && living_target.body_position == LYING_DOWN)
var/is_naive = controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER]
var/is_scary = HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)
if(!is_naive || !is_scary) //the lobstrosity isn't naive/young and the target isn't a scary fisherman.
if(isliving(target))
var/mob/living/living_target = target
if(is_naive && living_target.body_position == LYING_DOWN)
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE)
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS])
if (!HAS_TRAIT(target, trait))
continue
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE)
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS])
if (!HAS_TRAIT(target, trait))
continue
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE)
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/mob/living/us = controller.pawn
if (us.pulling == target)
@@ -174,7 +191,9 @@
/datum/ai_planning_subtree/targeted_mob_ability/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target) || in_range(controller.pawn, target))
return FALSE
return
if(controller.blackboard[BB_LOBSTROSITY_NAIVE_HUNTER] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))
return
return ..()
@@ -55,6 +55,12 @@
/// This subtype only exists because if you queue multiple of the same action with different arguments it deletes their stored arguments
/datum/ai_behavior/find_potential_targets/nearest/magicarp
/datum/ai_behavior/find_potential_targets/nearest/magicarp/pick_final_target(datum/ai_controller/controller, list/enemies_list)
for(var/atom/atom as anything in enemies_list)
if(HAS_TRAIT(atom, TRAIT_SCARY_FISHERMAN))
enemies_list -= atom
return ..()
/// Then use it on that target
/datum/ai_planning_subtree/targeted_mob_ability/magicarp
ability_key = BB_MAGICARP_SPELL
@@ -31,6 +31,9 @@
finish_planning = TRUE
/datum/ai_planning_subtree/make_carp_rift/panic_teleport/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/atom/movable/fleeing_from = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if(!QDELETED(fleeing_from) && controller.blackboard[BB_CARPS_FEAR_FISHERMAN] && HAS_TRAIT(fleeing_from, TRAIT_SCARY_FISHERMAN))
return ..()
if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
return
return ..()
@@ -42,6 +45,14 @@
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport
rift_behaviour = /datum/ai_behavior/make_carp_rift/towards/aggressive
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/atom/movable/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if(QDELETED(target) || !controller.blackboard[BB_CARPS_FEAR_FISHERMAN] || !HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN))
return ..()
if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
return
return ..()
/**
* # Make carp rift
* Make a carp rift somewhere
@@ -174,7 +185,7 @@
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if (QDELETED(target))
if (QDELETED(target) || (controller.blackboard[BB_CARPS_FEAR_FISHERMAN] && HAS_TRAIT(target, TRAIT_SCARY_FISHERMAN)))
return
var/distance_to_target = get_dist(controller.pawn, target)
@@ -12,24 +12,48 @@
BB_BASIC_MOB_STOP_FLEEING = TRUE,
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_CARPS_FEAR_FISHERMAN = TRUE,
)
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/make_carp_rift/panic_teleport,
/datum/ai_planning_subtree/flee_target/from_fisherman,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman,
/datum/ai_planning_subtree/carp_migration,
)
///Megacarps. The only difference is that they don't flee from scary fishermen and prioritize them.
/datum/ai_controller/basic_controller/carp/mega
blackboard = list(
BB_BASIC_MOB_STOP_FLEEING = TRUE,
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_CARPS_FEAR_FISHERMAN = FALSE,
)
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/make_carp_rift/panic_teleport,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/carp_migration,
)
/**
* Carp which bites back, but doesn't look for targets.
* 'Not hunting targets' includes food (and can rings), because they have been well trained.
@@ -39,18 +63,20 @@
BB_BASIC_MOB_STOP_FLEEING = TRUE,
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_CARPS_FEAR_FISHERMAN = TRUE,
)
ai_traits = STOP_MOVING_WHEN_PULLED
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/make_carp_rift/panic_teleport,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/flee_target/from_fisherman,
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman,
)
/**
@@ -61,12 +87,12 @@
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/make_carp_rift/panic_teleport,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/flee_target/from_fisherman,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/find_nearest_magicarp_spell_target,
/datum/ai_planning_subtree/targeted_mob_ability/magicarp,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
@@ -83,17 +109,19 @@
BB_BASIC_MOB_STOP_FLEEING = TRUE,
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN,
BB_CARPS_FEAR_FISHERMAN = TRUE,
)
ai_traits = STOP_MOVING_WHEN_PULLED
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/make_carp_rift/panic_teleport,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/flee_target/from_fisherman,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/attack_obstacle_in_path/carp,
/datum/ai_planning_subtree/shortcut_to_target_through_carp_rift,
/datum/ai_planning_subtree/make_carp_rift/aggressive_teleport,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman,
/datum/ai_planning_subtree/carp_migration,
)
@@ -24,6 +24,7 @@
ridable_data = /datum/component/riding/creature/megacarp
greyscale_config = /datum/greyscale_config/carp_mega
butcher_results = list(/obj/item/food/fishmeat/carp = 2, /obj/item/stack/sheet/animalhide/carp = 3)
ai_controller = /datum/ai_controller/basic_controller/carp/mega
/mob/living/basic/carp/mega/Initialize(mapload)
. = ..()
+12 -3
View File
@@ -109,6 +109,7 @@
/datum/ai_controller/basic_controller/frog
blackboard = list(
BB_BASIC_MOB_STOP_FLEEING = TRUE, //We only flee from scary fishermen.
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_OWNER_SELF_HARM_RESPONSES = list(
@@ -122,7 +123,8 @@
planning_subtrees = list(
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/random_speech/frog,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman,
/datum/ai_planning_subtree/flee_target/from_fisherman,
/datum/ai_planning_subtree/go_for_swim,
)
@@ -131,11 +133,18 @@
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/random_speech/frog,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/basic_melee_attack_subtree/no_fisherman,
/datum/ai_planning_subtree/flee_target/from_fisherman,
)
/datum/ai_controller/basic_controller/frog/suicide_frog
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, //No fear, only hatred. It has nothing to lose
)
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/find_target_prioritize_traits,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
)