mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
## About The Pull Request this refactors honkbots into basic mobs. its mostly a faithful 1:1 refactor but i couldnt keep my hands to myselves so i gave them some new behaviors. honkbots now love playing with clowns, they will go seek out for clowns and celebrate around them. also, if the honkbot finds a banana peel or a slippery item near it, it will actively drag people onto them honkbots will now go out of theirway to mess with secbots and annoy them ## Why It's Good For The Game refactors hinkbots into basic bots and also undoes some of the silliness i did in the previous basic bot prs. i also added lazylist support to remove_thing_from_list. ## Changelog 🆑 refactor: honkbots are now basic mobs, please report any bugs add: honkbots will try to slip people on banana peels /🆑
229 lines
9.2 KiB
Plaintext
229 lines
9.2 KiB
Plaintext
#define BOT_CLEAN_PATH_LIMIT 15
|
|
#define POST_CLEAN_COOLDOWN 5 SECONDS
|
|
|
|
/datum/ai_controller/basic_controller/bot/cleanbot
|
|
blackboard = list(
|
|
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items,
|
|
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
|
|
BB_UNREACHABLE_LIST_COOLDOWN = 3 MINUTES,
|
|
BB_SALUTE_MESSAGES = list(
|
|
"salutes",
|
|
"nods in appreciation towards",
|
|
"mops the dirt away in the path of",
|
|
),
|
|
BB_FRIENDLY_MESSAGE = "empathetically acknowledges your hardwork and tough circumstances",
|
|
)
|
|
planning_subtrees = list(
|
|
/datum/ai_planning_subtree/respond_to_summon,
|
|
/datum/ai_planning_subtree/manage_unreachable_list,
|
|
/datum/ai_planning_subtree/pet_planning/cleanbot,
|
|
/datum/ai_planning_subtree/cleaning_subtree,
|
|
/datum/ai_planning_subtree/befriend_janitors,
|
|
/datum/ai_planning_subtree/acid_spray,
|
|
/datum/ai_planning_subtree/use_mob_ability/foam_area,
|
|
/datum/ai_planning_subtree/salute_authority,
|
|
/datum/ai_planning_subtree/find_patrol_beacon/cleanbot,
|
|
)
|
|
reset_keys = list(
|
|
BB_ACTIVE_PET_COMMAND,
|
|
BB_CLEAN_TARGET,
|
|
BB_BEACON_TARGET,
|
|
BB_PREVIOUS_BEACON_TARGET,
|
|
BB_BOT_SUMMON_TARGET,
|
|
)
|
|
///list that ties each flag to its list key
|
|
var/static/list/clean_flags = list(
|
|
BB_CLEANABLE_BLOOD = CLEANBOT_CLEAN_BLOOD,
|
|
BB_HUNTABLE_PESTS = CLEANBOT_CLEAN_PESTS,
|
|
BB_CLEANABLE_DRAWINGS = CLEANBOT_CLEAN_DRAWINGS,
|
|
BB_HUNTABLE_TRASH = CLEANBOT_CLEAN_TRASH,
|
|
)
|
|
ai_traits = PAUSE_DURING_DO_AFTER
|
|
|
|
/datum/ai_planning_subtree/pet_planning/cleanbot/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
var/mob/living/basic/bot/bot_pawn = controller.pawn
|
|
//we are DONE listening to orders
|
|
if(bot_pawn.bot_access_flags & BOT_COVER_EMAGGED)
|
|
return
|
|
return ..()
|
|
|
|
|
|
/datum/ai_planning_subtree/cleaning_subtree
|
|
|
|
/datum/ai_planning_subtree/cleaning_subtree/SelectBehaviors(datum/ai_controller/basic_controller/bot/cleanbot/controller, seconds_per_tick)
|
|
if(controller.blackboard_key_exists(BB_CLEAN_TARGET))
|
|
controller.queue_behavior(/datum/ai_behavior/execute_clean, BB_CLEAN_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
var/list/final_hunt_list = list()
|
|
|
|
final_hunt_list += controller.blackboard[BB_CLEANABLE_DECALS]
|
|
var/list/flag_list = controller.clean_flags
|
|
var/mob/living/basic/bot/cleanbot/bot_pawn = controller.pawn
|
|
for(var/list_key in flag_list)
|
|
if(!(bot_pawn.janitor_mode_flags & flag_list[list_key]))
|
|
continue
|
|
final_hunt_list += controller.blackboard[list_key]
|
|
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/in_list/clean_targets, BB_CLEAN_TARGET, final_hunt_list)
|
|
|
|
/datum/ai_behavior/find_and_set/in_list/clean_targets
|
|
action_cooldown = 3 SECONDS
|
|
|
|
/datum/ai_behavior/find_and_set/in_list/clean_targets/search_tactic(datum/ai_controller/controller, locate_paths, search_range)
|
|
var/list/found = typecache_filter_list(oview(search_range, controller.pawn), locate_paths)
|
|
var/list/ignore_list = controller.blackboard[BB_TEMPORARY_IGNORE_LIST]
|
|
for(var/atom/found_item in found)
|
|
if(QDELETED(controller.pawn))
|
|
break
|
|
if(LAZYACCESS(ignore_list, found_item))
|
|
continue
|
|
if(get_turf(found_item) == get_turf(controller.pawn))
|
|
return found_item
|
|
var/list/path = get_path_to(controller.pawn, found_item, max_distance = BOT_CLEAN_PATH_LIMIT, access = controller.get_access())
|
|
if(!length(path))
|
|
controller.set_blackboard_key_assoc_lazylist(BB_TEMPORARY_IGNORE_LIST, found_item, TRUE)
|
|
continue
|
|
return found_item
|
|
|
|
/datum/ai_planning_subtree/acid_spray
|
|
|
|
/datum/ai_planning_subtree/acid_spray/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
var/mob/living/basic/bot/cleanbot/bot_pawn = controller.pawn
|
|
if(!(bot_pawn.bot_access_flags & BOT_COVER_EMAGGED))
|
|
return
|
|
if(controller.blackboard_key_exists(BB_ACID_SPRAY_TARGET))
|
|
controller.queue_behavior(/datum/ai_behavior/execute_clean, BB_ACID_SPRAY_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/spray_target, BB_ACID_SPRAY_TARGET, /mob/living/carbon/human, 5)
|
|
|
|
/datum/ai_behavior/find_and_set/spray_target
|
|
action_cooldown = 30 SECONDS
|
|
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
|
|
|
/datum/ai_behavior/find_and_set/spray_target/search_tactic(datum/ai_controller/controller, locate_path, search_range)
|
|
var/list/ignore_list = controller.blackboard[BB_TEMPORARY_IGNORE_LIST]
|
|
for(var/mob/living/carbon/human/human_target in oview(search_range, controller.pawn))
|
|
if(LAZYACCESS(ignore_list, human_target))
|
|
continue
|
|
if(human_target.stat != CONSCIOUS || isnull(human_target.mind))
|
|
continue
|
|
return human_target
|
|
return null
|
|
|
|
/datum/ai_behavior/execute_clean
|
|
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION | AI_BEHAVIOR_REQUIRE_REACH
|
|
|
|
/datum/ai_behavior/execute_clean/setup(datum/ai_controller/controller, target_key)
|
|
. = ..()
|
|
var/turf/target = controller.blackboard[target_key]
|
|
if(isnull(target))
|
|
return FALSE
|
|
set_movement_target(controller, target)
|
|
|
|
/datum/ai_behavior/execute_clean/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
|
var/mob/living/basic/living_pawn = controller.pawn
|
|
var/atom/target = controller.blackboard[target_key]
|
|
|
|
if(QDELETED(target))
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
living_pawn.UnarmedAttack(target, proximity_flag = TRUE)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
|
|
|
/datum/ai_behavior/execute_clean/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
|
|
. = ..()
|
|
controller.set_blackboard_key(BB_POST_CLEAN_COOLDOWN, POST_CLEAN_COOLDOWN + world.time)
|
|
var/atom/target = controller.blackboard[target_key]
|
|
if(!succeeded && !isnull(target))
|
|
controller.clear_blackboard_key(target_key)
|
|
controller.set_blackboard_key_assoc_lazylist(BB_TEMPORARY_IGNORE_LIST, target, TRUE)
|
|
return
|
|
if(QDELETED(target) || is_type_in_typecache(target, controller.blackboard[BB_HUNTABLE_TRASH]))
|
|
return
|
|
if(!iscarbon(target))
|
|
controller.clear_blackboard_key(target_key)
|
|
return
|
|
var/list/speech_list = controller.blackboard[BB_CLEANBOT_EMAGGED_PHRASES]
|
|
if(!length(speech_list))
|
|
return
|
|
var/mob/living/living_pawn = controller.pawn
|
|
if(QDELETED(living_pawn)) // pawn can be null at this point
|
|
controller.clear_blackboard_key(target_key)
|
|
return
|
|
living_pawn.say(pick(controller.blackboard[BB_CLEANBOT_EMAGGED_PHRASES]), forced = "ai controller")
|
|
controller.clear_blackboard_key(target_key)
|
|
|
|
/datum/ai_planning_subtree/use_mob_ability/foam_area
|
|
ability_key = BB_CLEANBOT_FOAM
|
|
finish_planning = FALSE
|
|
|
|
/datum/ai_planning_subtree/use_mob_ability/foam_area/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
var/mob/living/basic/bot/bot_pawn = controller.pawn
|
|
if(!(bot_pawn.bot_access_flags & BOT_COVER_EMAGGED))
|
|
return
|
|
return ..()
|
|
|
|
/datum/ai_planning_subtree/befriend_janitors
|
|
|
|
/datum/ai_planning_subtree/befriend_janitors/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
var/mob/living/basic/bot/bot_pawn = controller.pawn
|
|
//we are now evil. dont befriend the janitors
|
|
if(bot_pawn.bot_access_flags & BOT_COVER_EMAGGED)
|
|
return
|
|
if(controller.blackboard_key_exists(BB_FRIENDLY_JANITOR))
|
|
controller.queue_behavior(/datum/ai_behavior/befriend_target, BB_FRIENDLY_JANITOR, BB_FRIENDLY_MESSAGE)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/friendly_janitor, BB_FRIENDLY_JANITOR, /mob/living/carbon/human, 5)
|
|
|
|
/datum/ai_behavior/find_and_set/friendly_janitor
|
|
action_cooldown = 30 SECONDS
|
|
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
|
|
|
/datum/ai_behavior/find_and_set/friendly_janitor/search_tactic(datum/ai_controller/controller, locate_path, search_range)
|
|
var/mob/living/living_pawn = controller.pawn
|
|
for(var/mob/living/carbon/human/human_target in oview(search_range, living_pawn))
|
|
if(human_target.stat != CONSCIOUS || isnull(human_target.mind))
|
|
continue
|
|
if(!HAS_TRAIT(human_target, TRAIT_CLEANBOT_WHISPERER))
|
|
continue
|
|
if((living_pawn.faction.Find(REF(human_target))))
|
|
continue
|
|
return human_target
|
|
return null
|
|
|
|
/datum/ai_planning_subtree/find_patrol_beacon/cleanbot
|
|
|
|
/datum/ai_planning_subtree/find_patrol_beacon/cleanbot/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
if(controller.blackboard[BB_POST_CLEAN_COOLDOWN] >= world.time)
|
|
return
|
|
return ..()
|
|
|
|
/datum/pet_command/point_targeting/clean
|
|
command_name = "Clean"
|
|
command_desc = "Command a cleanbot to clean the mess."
|
|
radial_icon = 'icons/obj/service/janitor.dmi'
|
|
radial_icon_state = "mop"
|
|
speech_commands = list("clean", "mop")
|
|
|
|
/datum/pet_command/point_targeting/clean/set_command_target(mob/living/parent, atom/target)
|
|
if(isnull(target) || !istype(target, /obj/effect/decal/cleanable))
|
|
return
|
|
if(isnull(parent.ai_controller))
|
|
return
|
|
if(LAZYACCESS(parent.ai_controller.blackboard[BB_TEMPORARY_IGNORE_LIST], target))
|
|
return
|
|
return ..()
|
|
|
|
/datum/pet_command/point_targeting/clean/execute_action(datum/ai_controller/basic_controller/bot/controller)
|
|
if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET))
|
|
controller.queue_behavior(/datum/ai_behavior/execute_clean, BB_CURRENT_PET_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
|
|
|
|
#undef BOT_CLEAN_PATH_LIMIT
|
|
#undef POST_CLEAN_COOLDOWN
|