mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
## About The Pull Request 1. Monkeys will only seek out food to eat if they are actually hungry, rather than on an arbitrary cooldown. 2. Monkeys will no longer teleport-yoink food out of your hands. Instead, they may get angry at you for stealing their food, and fight you over it. The hungrier the monkey, the more likely they are to fight. 3. Monkeys will discard trash and empty glasses (on the floor) after eating or drinking them. 4. Monkeys can target soup to eat 5. PunPun will no longer seek out drinks if they are hungry. 6. PunPun will now, if the bartender is absent and there are multiple patrons around, attempt to find filled glasses or food to hand out to patrons. 7. Several places that sought edible items no longer include drinking glasses as edible items <img width="656" height="185" alt="image" src="https://github.com/user-attachments/assets/8b3a6ac1-ae2c-41a0-919f-b471ad93bb0f" /> ## Why It's Good For The Game PunPun shouldn't be yoinking glasses out of patron's hands - their intended behavior is to serve drinks not steal them Otherwise, monkey eating was a bit jank due to it being some of our oldest ai code. I largely just brought it up to more modern ai standards. ## Changelog 🆑 Melbert add: If the bartender is absent, PunPun will serve filled drink glasses to patrons that don't have one. add: PunPun will now ignore filled drinks and items being held when looking for stuff to eat. add: Monkeys can eat soup. add: Monkeys will no longer seek out food if they are not hungry. add: Hungry monkeys might fight you over the food you are holding. The hungrier the monkey, the angrier the monkey. fix: Monkeys can no longer teleport items out of your hands to eat. /🆑
113 lines
5.0 KiB
Plaintext
113 lines
5.0 KiB
Plaintext
/datum/ai_planning_subtree/monkey_shenanigans/SelectBehaviors(datum/ai_controller/monkey/controller, seconds_per_tick)
|
|
|
|
if(prob(5))
|
|
controller.queue_behavior(/datum/ai_behavior/use_in_hand)
|
|
|
|
if(!SPT_PROB(MONKEY_SHENANIGAN_PROB, seconds_per_tick))
|
|
return
|
|
|
|
if(!controller.blackboard[BB_MONKEY_CURRENT_PRESS_TARGET])
|
|
if(controller.blackboard[BB_MONKEY_PRESS_TYPEPATH])
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_MONKEY_CURRENT_PRESS_TARGET, controller.blackboard[BB_MONKEY_PRESS_TYPEPATH], 2)
|
|
else
|
|
controller.queue_behavior(/datum/ai_behavior/find_nearby, BB_MONKEY_CURRENT_PRESS_TARGET)
|
|
else if(prob(50))
|
|
controller.queue_behavior(/datum/ai_behavior/use_on_object, BB_MONKEY_CURRENT_PRESS_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
if(!controller.blackboard[BB_MONKEY_CURRENT_GIVE_TARGET])
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/pawn_must_hold_item, BB_MONKEY_CURRENT_GIVE_TARGET, /mob/living/carbon/human, 2)
|
|
else if(prob(controller.blackboard[BB_MONKEY_GIVE_CHANCE]))
|
|
controller.queue_behavior(/datum/ai_behavior/give, BB_MONKEY_CURRENT_GIVE_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
if(!controller.blackboard[BB_MONKEY_TAMED])
|
|
controller.TryFindWeapon()
|
|
|
|
///monkey combat subtree.
|
|
/datum/ai_planning_subtree/monkey_combat/SelectBehaviors(datum/ai_controller/monkey/controller, seconds_per_tick)
|
|
var/mob/living/living_pawn = controller.pawn
|
|
var/list/enemies = controller.blackboard[BB_MONKEY_ENEMIES]
|
|
|
|
if((HAS_TRAIT(controller.pawn, TRAIT_PACIFISM)) || (!length(enemies) && !controller.blackboard[BB_MONKEY_AGGRESSIVE])) //Pacifist, or we have no enemies and we're not pissed
|
|
living_pawn.set_combat_mode(FALSE)
|
|
return
|
|
|
|
if(!controller.blackboard[BB_MONKEY_CURRENT_ATTACK_TARGET])
|
|
controller.queue_behavior(/datum/ai_behavior/monkey_set_combat_target, BB_MONKEY_CURRENT_ATTACK_TARGET, BB_MONKEY_ENEMIES)
|
|
living_pawn.set_combat_mode(FALSE)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
var/mob/living/selected_enemy = controller.blackboard[BB_MONKEY_CURRENT_ATTACK_TARGET]
|
|
|
|
if(QDELETED(selected_enemy))
|
|
living_pawn.set_combat_mode(FALSE)
|
|
return
|
|
|
|
if(!selected_enemy.stat) //He's up, get him!
|
|
if(living_pawn.health < MONKEY_FLEE_HEALTH) //Time to skeddadle
|
|
controller.queue_behavior(/datum/ai_behavior/monkey_flee)
|
|
return SUBTREE_RETURN_FINISH_PLANNING //I'm running fuck you guys
|
|
|
|
if(controller.TryFindWeapon()) //Getting a weapon is higher priority if im not fleeing.
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
if(controller.blackboard[BB_MONKEY_RECRUIT_COOLDOWN] < world.time)
|
|
controller.queue_behavior(/datum/ai_behavior/recruit_monkeys, BB_MONKEY_CURRENT_ATTACK_TARGET)
|
|
return
|
|
|
|
if(SPT_PROB(ismonkey(living_pawn) ? 25 : 10, seconds_per_tick))
|
|
controller.queue_behavior(/datum/ai_behavior/battle_screech/monkey)
|
|
controller.queue_behavior(/datum/ai_behavior/monkey_attack_mob, BB_MONKEY_CURRENT_ATTACK_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
//by this point we have a target but they're down, let's try dumpstering this loser
|
|
|
|
living_pawn.set_combat_mode(FALSE)
|
|
|
|
if(!controller.blackboard[BB_MONKEY_TARGET_DISPOSAL])
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_MONKEY_TARGET_DISPOSAL, /obj/machinery/disposal, MONKEY_ENEMY_VISION)
|
|
return
|
|
|
|
controller.queue_behavior(/datum/ai_behavior/disposal_mob, BB_MONKEY_CURRENT_ATTACK_TARGET, BB_MONKEY_TARGET_DISPOSAL)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
/// Finds food or drinks, picks them up, then gives them to nearby humans
|
|
/datum/ai_planning_subtree/serve_food
|
|
|
|
/datum/ai_planning_subtree/serve_food/SelectBehaviors(datum/ai_controller/monkey/controller, seconds_per_tick)
|
|
var/mob/living/living_pawn = controller.pawn
|
|
var/list/nearby_patrons = list()
|
|
for(var/mob/living/carbon/human/human_mob in oview(5, living_pawn))
|
|
if(istype(human_mob.mind?.assigned_role, /datum/job/bartender))
|
|
return // my boss is on duty!
|
|
if(human_mob.stat != CONSCIOUS || ismonkey(human_mob))
|
|
continue
|
|
if(!human_mob.get_empty_held_indexes())
|
|
continue
|
|
nearby_patrons += human_mob
|
|
|
|
// Need at least 2 patrons to bother serving (bearing in mind the
|
|
if(length(nearby_patrons) < 1)
|
|
return
|
|
|
|
var/obj/item/serving = controller.blackboard[BB_MONKEY_CURRENT_SERVED_ITEM]
|
|
if(QDELETED(serving) || serving.reagents.total_volume <= 0)
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/food_or_drink/to_serve, BB_MONKEY_CURRENT_SERVED_ITEM, /obj/item, 2)
|
|
return
|
|
|
|
// we have something to serve, pick a patron and go hand it over
|
|
if(living_pawn.is_holding(serving))
|
|
controller.blackboard[BB_MONKEY_CURRENT_GIVE_TARGET] ||= pick(nearby_patrons)
|
|
controller.queue_behavior(/datum/ai_behavior/give, BB_MONKEY_CURRENT_GIVE_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
// we have something to serve but aren't holding it yet
|
|
if(isturf(serving.loc))
|
|
// fetch the drink
|
|
controller.queue_behavior(/datum/ai_behavior/navigate_to_and_pick_up, BB_MONKEY_CURRENT_SERVED_ITEM, TRUE)
|
|
else
|
|
// give up on the dream
|
|
controller.clear_blackboard_key(BB_MONKEY_CURRENT_SERVED_ITEM)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|