mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-15 12:11:45 +00:00
## About The Pull Request Melbert asked me to make this and I thought it'd be relatively easy and plausibly useful so I did. This PR adds a feature to the VV menu for mobs which allows you to apply and configure an AI controller from a list of templates. It's not as versatile as coding one would be, but it should be able to accomodate a lot of generic scenarios. Some examples of basic stuff you can set it up to do: - Give Ian a machine gun he will fire at nearby people while staying within a specified min/max range. - Have Poly fire brimstone beams on cooldown at whoever is nearby (although she won't bother trying to line up cardinally). - Assign a gorilla to be someone's personal bodyguard which will follow them around and attack anyone who hurts them. I have also made an executive decision to remove the restriction that basic ai controllers can only be placed on basic mobs. We've removed _most_ non-basic simple mobs from the game, and also have more recently updated most AI behaviours to work agnostically of whether they are assigned to a basic mob or not... which means that they'll largely work on carbons. Coincidentally, this feature makes sure to ask if you want an AI controller to remain active on a mob which already has a client. Assigning an active AI controller to a live player which forces their character to automatically attempt to run away from whoever the last person to attack them was is ~~not recommended behaviour because it's largely untested~~ highly recommended behaviour because I think it's very funny (makes it very hard to play though). I'm gonna do another PR some time which cleans up `random_speech` so it's configurable and then let you slap that on whoever as well. ## Why It's Good For The Game Enables a greater level of admin abuse. ## Changelog 🆑 admin: Added easier tooling for admins to add or change the AI controllers on mobs /🆑
51 lines
2.2 KiB
Plaintext
51 lines
2.2 KiB
Plaintext
/// Fire a ranged attack without interrupting movement.
|
|
/datum/ai_planning_subtree/ranged_skirmish
|
|
operational_datums = list(/datum/component/ranged_attacks)
|
|
/// Blackboard key holding target atom
|
|
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
|
|
/// What AI behaviour do we actually run?
|
|
var/attack_behavior = /datum/ai_behavior/ranged_skirmish
|
|
/// If target is further away than this we don't fire
|
|
var/max_range = 9
|
|
/// If target is closer than this we don't fire
|
|
var/min_range = 2
|
|
|
|
/datum/ai_planning_subtree/ranged_skirmish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
. = ..()
|
|
if(!controller.blackboard_key_exists(target_key))
|
|
return
|
|
controller.queue_behavior(attack_behavior, target_key, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range)
|
|
|
|
/// How often will we try to perform our ranged attack?
|
|
/datum/ai_behavior/ranged_skirmish
|
|
action_cooldown = 0.5 SECONDS
|
|
|
|
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
|
. = ..()
|
|
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
|
|
return !QDELETED(target)
|
|
|
|
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
|
var/atom/target = controller.blackboard[target_key]
|
|
if (QDELETED(target))
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
|
if(!targeting_strategy.can_attack(controller.pawn, target))
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target)
|
|
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
|
|
|
target = hiding_target || target
|
|
|
|
var/distance = get_dist(controller.pawn, target)
|
|
if (distance > max_range || distance < min_range)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
|
|
|
controller.ai_interact(target = target, combat_mode = TRUE)
|
|
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
|
|
|
/datum/ai_planning_subtree/ranged_skirmish/no_minimum
|
|
min_range = 0
|