mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-16 12:43:09 +00:00
AI actions won't unassign each other's movement targets & Mice stop being scared of people if fed cheese (#72130) ## About The Pull Request Fixes #72116 I've had a persistent issue with basic mob actions reporting this error and think I finally cracked it When replanning with `AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION` it can run `Setup` on one action leading to the plan changing, meaning that it runs `finishCommand` to cancel all other existing commands If you triggered a replan by setting up a movement action in the middle of another movement action, cancelling the existing action would remove the target already set by the current one. We want actions to be able to remove _their own_ movement target but not if it has been changed by something else in the intervening time. I fixed this by passing a source every time you set a movement target and adding a proc which only clears it if you are the source... but this feels kind of ugly. I couldn't think of anything but if you have a better idea let me know. Also while I was doing this I turned it into a feature because I'm crazy. If you feed a mouse cheese by hand it will stop being scared of humans and so will any other mice it attracts from eating more cheese. This is mostly because I think industrial mouse farming to pass cargo bounties is funny. Mice controlled by a Regal Rat lose this behaviour and forget any past loyalties they may have had. https://user-images.githubusercontent.com/7483112/208779368-3bd1da0f-4191-4405-86e5-b55a58c2cd00.mp4 Oh also I removed a block about cancelling if you have another target from the "hunt" behaviour, everywhere using this already achieves that simply by ordering the actions in expected priority order and it was messing with how I expected mice to work. Now if they happen to stop by some cheese they will correctly stop fleeing in order to eat it before continuing to run away. ## Why It's Good For The Game Fixes a bug I kept running into. Makes it possible to set up a mouse farm without them screaming constantly. Lets people more easily domesticate mice to support Ratatouille gameplay. ## Changelog 🆑 add: Mice who are fed cheese by hand will accept humans as friends, at least until reminded otherwise by their rightful lord. fix: Fixed a runtime preventing mice from acting correctly when trying to flee and also eat cheese at the same time. /🆑 Co-authored-by: Jacquerel <hnevard@gmail.com>
39 lines
2.0 KiB
Plaintext
39 lines
2.0 KiB
Plaintext
///Abstract class for an action an AI can take, can range from movement to grabbing a nearby weapon.
|
|
/datum/ai_behavior
|
|
///What distance you need to be from the target to perform the action
|
|
var/required_distance = 1
|
|
///Flags for extra behavior
|
|
var/behavior_flags = NONE
|
|
///Cooldown between actions performances, defaults to the value of CLICK_CD_MELEE because that seemed like a nice standard for the speed of AI behavior
|
|
var/action_cooldown = CLICK_CD_MELEE
|
|
|
|
/// Called by the ai controller when first being added. Additional arguments depend on the behavior type.
|
|
/// Return FALSE to cancel
|
|
/datum/ai_behavior/proc/setup(datum/ai_controller/controller, ...)
|
|
return TRUE
|
|
|
|
///Called by the AI controller when this action is performed
|
|
/datum/ai_behavior/proc/perform(delta_time, datum/ai_controller/controller, ...)
|
|
controller.behavior_cooldowns[src] = world.time + action_cooldown
|
|
return
|
|
|
|
///Called when the action is finished. This needs the same args as perform besides the default ones
|
|
/datum/ai_behavior/proc/finish_action(datum/ai_controller/controller, succeeded, ...)
|
|
LAZYREMOVE(controller.current_behaviors, src)
|
|
controller.behavior_args -= type
|
|
if(behavior_flags & AI_BEHAVIOR_REQUIRE_MOVEMENT) //If this was a movement task, reset our movement target if necessary
|
|
if(!(behavior_flags & AI_BEHAVIOR_KEEP_MOVE_TARGET_ON_FINISH))
|
|
clear_movement_target(controller)
|
|
if(!(behavior_flags & AI_BEHAVIOR_KEEP_MOVING_TOWARDS_TARGET_ON_FINISH))
|
|
controller.ai_movement.stop_moving_towards(controller)
|
|
|
|
/// Helper proc to ensure consistency in setting the source of the movement target
|
|
/datum/ai_behavior/proc/set_movement_target(datum/ai_controller/controller, atom/target, datum/ai_movement/new_movement)
|
|
controller.set_movement_target(type, target, new_movement)
|
|
|
|
/// Clear the controller's movement target only if it was us who last set it
|
|
/datum/ai_behavior/proc/clear_movement_target(datum/ai_controller/controller)
|
|
if (controller.movement_target_source != type)
|
|
return
|
|
controller.set_movement_target(type, null)
|