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. /🆑
99 lines
4.3 KiB
Plaintext
99 lines
4.3 KiB
Plaintext
/**
|
|
* Generic Instrument Subtree, For your pawn playing instruments
|
|
*
|
|
* Requires at least a living mob that can hold items.
|
|
*
|
|
* relevant blackboards:
|
|
* * BB_SONG_INSTRUMENT - set by this subtree, is the song datum the pawn plays music from.
|
|
* * BB_SONG_LINES - not set by this subtree, is the song loaded into the song datum.
|
|
*/
|
|
/datum/ai_planning_subtree/generic_play_instrument/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
var/obj/item/instrument/song_player = controller.blackboard[BB_SONG_INSTRUMENT]
|
|
|
|
if(!song_player)
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/in_hands, BB_SONG_INSTRUMENT, /obj/item/instrument)
|
|
return //we can't play a song since we do not have an instrument
|
|
|
|
var/list/parsed_song_lines = splittext(controller.blackboard[BB_SONG_LINES], "\n")
|
|
popleft(parsed_song_lines) //remove BPM as it is parsed out
|
|
if(!compare_list(song_player.song.lines, parsed_song_lines) || !song_player.song.repeat)
|
|
controller.queue_behavior(/datum/ai_behavior/setup_instrument, BB_SONG_INSTRUMENT, BB_SONG_LINES)
|
|
|
|
if(!song_player.song.playing) //we may stop playing if we weren't playing before, were setting up dk theme, or ran out of repeats (also causing setup behavior)
|
|
controller.queue_behavior(/datum/ai_behavior/play_instrument, BB_SONG_INSTRUMENT)
|
|
|
|
/datum/ai_planning_subtree/generic_play_instrument/end_planning
|
|
|
|
/datum/ai_planning_subtree/generic_play_instrument/end_planning/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
. = ..()
|
|
if (controller.blackboard_key_exists(BB_SONG_INSTRUMENT))
|
|
return SUBTREE_RETURN_FINISH_PLANNING // Don't plan anything else if we're playing an instrument
|
|
|
|
|
|
/**
|
|
* Generic Resist Subtree, resist if it makes sense to!
|
|
*
|
|
* Requires nothing beyond a living pawn, makes sense on a good amount of mobs since anything can get buckled.
|
|
*
|
|
* relevant blackboards:
|
|
* * None!
|
|
*/
|
|
/datum/ai_planning_subtree/generic_resist/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
var/mob/living/living_pawn = controller.pawn
|
|
|
|
if(SHOULD_RESIST(living_pawn) && SPT_PROB(RESIST_SUBTREE_PROB, seconds_per_tick))
|
|
controller.queue_behavior(/datum/ai_behavior/resist) //BRO IM ON FUCKING FIRE BRO
|
|
return SUBTREE_RETURN_FINISH_PLANNING //IM NOT DOING ANYTHING ELSE BUT EXTINGUISH MYSELF, GOOD GOD HAVE MERCY.
|
|
|
|
/**
|
|
* Generic Hunger Subtree,
|
|
*
|
|
* Requires at least a living mob that can hold items.
|
|
*
|
|
* relevant blackboards:
|
|
* * BB_NEXT_HUNGRY - set by this subtree, is when the controller is next hungry
|
|
*/
|
|
/datum/ai_planning_subtree/generic_hunger
|
|
|
|
/datum/ai_planning_subtree/generic_hunger/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
var/mob/living/living_pawn = controller.pawn
|
|
if(living_pawn.nutrition > NUTRITION_LEVEL_HUNGRY)
|
|
return
|
|
|
|
var/next_eat = controller.blackboard[BB_NEXT_HUNGRY]
|
|
if(!next_eat)
|
|
//inits the blackboard timer
|
|
next_eat = world.time + rand(0, 30 SECONDS)
|
|
controller.set_blackboard_key(BB_NEXT_HUNGRY, next_eat)
|
|
|
|
if(world.time < next_eat)
|
|
return
|
|
|
|
// find food
|
|
var/atom/food_target = controller.blackboard[BB_FOOD_TARGET]
|
|
if(isnull(food_target))
|
|
controller.queue_behavior(/datum/ai_behavior/find_and_set/food_or_drink/to_eat, BB_FOOD_TARGET, /obj/item, 2)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
if(living_pawn.is_holding(food_target))
|
|
controller.queue_behavior(/datum/ai_behavior/consume, BB_FOOD_TARGET, BB_NEXT_HUNGRY)
|
|
// it's been moved since we found it
|
|
else if(!isturf(food_target.loc))
|
|
// someone took it. we will fight over it!
|
|
if(isliving(food_target.loc) && will_fight_for_food(food_target.loc, living_pawn, controller))
|
|
controller.add_blackboard_key_assoc(BB_MONKEY_ENEMIES, food_target.loc, MONKEY_FOOD_HATRED_AMOUNT)
|
|
// eh, find something else
|
|
else
|
|
controller.clear_blackboard_key(BB_FOOD_TARGET)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
else
|
|
controller.queue_behavior(/datum/ai_behavior/navigate_to_and_pick_up, BB_FOOD_TARGET, TRUE)
|
|
return SUBTREE_RETURN_FINISH_PLANNING
|
|
|
|
/datum/ai_planning_subtree/generic_hunger/proc/will_fight_for_food(mob/living/thief, mob/living/monkey, datum/ai_controller/controller)
|
|
if(controller.blackboard[BB_MONKEY_AGGRESSIVE])
|
|
return TRUE
|
|
if(controller.blackboard[BB_MONKEY_TAMED])
|
|
return FALSE
|
|
return prob(100 * ((NUTRITION_LEVEL_HUNGRY - monkey.nutrition) / NUTRITION_LEVEL_HUNGRY))
|