mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-21 13:05:36 +01:00
5786289821
## About The Pull Request Adds a dirty quirk, as requested in a bounty in https://discord.com/channels/1059199070016655462/1415440129362886727/1415440129362886727. This quirk does a few things. 1. Walking around, you have a small chance to spread dirt to the floor. 2. If you are barefoot, you track colored footprints that fade out over 7 seconds. 3. If you are attacked, you have a puff of colored, opaque smoke fly off you. **This cannot be spammed and must be refreshed by digging in trash.** 4. People around you get a small mood debuff. 5. You get a small examine blurb telling people that you're dirty. Both the dirt color and flavor text can be customized in the quirk. If you are cleaned with soap... 1. You scream, flail, and get a -6 mood debuff. 2. **All above effects are disabled.** 3. You can refresh your filth by rummaging in trash Hygeinebots also always try to clean dirty people. ## Why It's Good For The Game We have filth goblins on station, and this lets them reflect who they are mechanically. Its also a small, but minor, way to give janitors just a bit more things to do - and a small source of conflict where you may have people running around trying to clean you because god you just smell so bad. ## Proof Of Testing <details> <summary>Screenshots/Videos</summary> https://github.com/user-attachments/assets/6c627e3f-0874-4609-84e8-d7137628ecf1 </details> ## Changelog 🆑 add: Dirty quirk - spreads dirt, makes everyone annoyed at you, defeated by soap. /🆑 --------- Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com>
150 lines
5.4 KiB
Plaintext
150 lines
5.4 KiB
Plaintext
#define BOT_FRUSTRATION_LIMIT 8
|
|
#define BOT_ANGER_THRESHOLD 5
|
|
|
|
/datum/ai_controller/basic_controller/bot/hygienebot
|
|
blackboard = list(
|
|
BB_SALUTE_MESSAGES = list(
|
|
"salutes",
|
|
"nods in appreciation towards",
|
|
),
|
|
BB_WASH_FRUSTRATION = 0,
|
|
)
|
|
planning_subtrees = list(
|
|
/datum/ai_planning_subtree/escape_captivity/pacifist,
|
|
/datum/ai_planning_subtree/respond_to_summon,
|
|
/datum/ai_planning_subtree/handle_trash_talk,
|
|
/datum/ai_planning_subtree/wash_people,
|
|
/datum/ai_planning_subtree/salute_authority,
|
|
/datum/ai_planning_subtree/find_patrol_beacon,
|
|
)
|
|
reset_keys = list(
|
|
BB_WASH_TARGET,
|
|
BB_BEACON_TARGET,
|
|
BB_PREVIOUS_BEACON_TARGET,
|
|
BB_BOT_SUMMON_TARGET,
|
|
)
|
|
|
|
/datum/ai_planning_subtree/handle_trash_talk
|
|
|
|
/datum/ai_planning_subtree/handle_trash_talk/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
if(!controller.blackboard_key_exists(BB_WASH_TARGET))
|
|
return
|
|
controller.queue_behavior(/datum/ai_behavior/commence_trashtalk, BB_WASH_TARGET)
|
|
|
|
/datum/ai_behavior/commence_trashtalk
|
|
action_cooldown = 4 SECONDS
|
|
|
|
/datum/ai_behavior/commence_trashtalk/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
|
if(!controller.blackboard_key_exists(target_key))
|
|
return AI_BEHAVIOR_FAILED | AI_BEHAVIOR_DELAY
|
|
|
|
var/frustration_count = controller.blackboard[BB_WASH_FRUSTRATION]
|
|
controller.set_blackboard_key(BB_WASH_FRUSTRATION, min(frustration_count + 1, BOT_FRUSTRATION_LIMIT))
|
|
if(controller.blackboard[BB_WASH_FRUSTRATION] < BOT_ANGER_THRESHOLD)
|
|
return AI_BEHAVIOR_FAILED | AI_BEHAVIOR_DELAY
|
|
var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY]
|
|
announcement?.announce(pick(controller.blackboard[BB_WASH_THREATS]))
|
|
return AI_BEHAVIOR_SUCCEEDED | AI_BEHAVIOR_DELAY
|
|
|
|
|
|
/datum/ai_planning_subtree/wash_people
|
|
|
|
/datum/ai_planning_subtree/wash_people/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick)
|
|
var/mob/living/basic/bot/bot_pawn = controller.pawn
|
|
|
|
var/atom/wash_target = controller.blackboard[BB_WASH_TARGET]
|
|
if(QDELETED(wash_target))
|
|
controller.queue_behavior(/datum/ai_behavior/find_valid_wash_targets, BB_WASH_TARGET, bot_pawn.bot_access_flags)
|
|
return
|
|
|
|
if(get_dist(bot_pawn, wash_target) < 9)
|
|
controller.queue_behavior(/datum/ai_behavior/wash_target, BB_WASH_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
controller.clear_blackboard_key(BB_WASH_TARGET) //delete if too far
|
|
|
|
/datum/ai_behavior/find_valid_wash_targets
|
|
action_cooldown = 5 SECONDS
|
|
|
|
/datum/ai_behavior/find_valid_wash_targets/perform(seconds_per_tick, datum/ai_controller/basic_controller/bot/controller, target_key, our_access_flags)
|
|
. = ..()
|
|
var/list/ignore_list = controller.blackboard[BB_TEMPORARY_IGNORE_LIST]
|
|
var/atom/found_target
|
|
for(var/mob/living/carbon/human/wash_potential in oview(5, controller.pawn))
|
|
|
|
if(found_target)
|
|
break
|
|
|
|
if(isnull(wash_potential.mind) || wash_potential.stat != CONSCIOUS)
|
|
continue
|
|
|
|
if(LAZYACCESS(ignore_list, wash_potential))
|
|
continue
|
|
|
|
|
|
// BUBBER EDIT ADDITION BEGIN - Dirty quirk
|
|
if (HAS_TRAIT(wash_potential, TRAIT_DIRTY))
|
|
found_target = wash_potential
|
|
break
|
|
// BUGGER EDIT ADDITION END
|
|
|
|
if(our_access_flags & BOT_COVER_EMAGGED)
|
|
controller.add_to_blacklist(wash_potential)
|
|
found_target = wash_potential
|
|
break
|
|
|
|
for(var/atom/clothing in wash_potential.get_equipped_items(INCLUDE_HELD|INCLUDE_PROSTHETICS))
|
|
if(GET_ATOM_BLOOD_DNA_LENGTH(clothing))
|
|
found_target = wash_potential
|
|
break
|
|
|
|
if(isnull(found_target))
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
controller.set_blackboard_key(target_key, found_target)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
|
|
|
/datum/ai_behavior/find_valid_wash_targets/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
|
. = ..()
|
|
if(!succeeded)
|
|
return
|
|
var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY]
|
|
announcement.announce(pick(controller.blackboard[BB_WASH_FOUND]))
|
|
|
|
/datum/ai_behavior/wash_target
|
|
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
|
required_distance = 0
|
|
|
|
/datum/ai_behavior/wash_target/setup(datum/ai_controller/controller, target_key)
|
|
. = ..()
|
|
var/atom/target = controller.blackboard[target_key]
|
|
if(QDELETED(target))
|
|
return FALSE
|
|
set_movement_target(controller, target)
|
|
|
|
/datum/ai_behavior/wash_target/perform(seconds_per_tick, datum/ai_controller/basic_controller/bot/controller, target_key)
|
|
. = ..()
|
|
var/mob/living/carbon/human/unclean_target = controller.blackboard[target_key]
|
|
var/mob/living/basic/living_pawn = controller.pawn
|
|
if(QDELETED(unclean_target))
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
if(living_pawn.loc == get_turf(unclean_target))
|
|
living_pawn.melee_attack(unclean_target)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
|
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
/datum/ai_behavior/wash_target/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
|
. = ..()
|
|
controller.clear_blackboard_key(target_key)
|
|
var/wash_frustration = controller.blackboard[BB_WASH_FRUSTRATION]
|
|
controller.clear_blackboard_key(BB_WASH_FRUSTRATION)
|
|
if(!succeeded || wash_frustration <= BOT_ANGER_THRESHOLD)
|
|
return
|
|
var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY]
|
|
announcement.announce(pick(controller.blackboard[BB_WASH_DONE]))
|
|
|
|
#undef BOT_ANGER_THRESHOLD
|
|
#undef BOT_FRUSTRATION_LIMIT
|