mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-30 19:11:52 +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 /🆑
53 lines
2.0 KiB
Plaintext
53 lines
2.0 KiB
Plaintext
/datum/ai_controller/basic_controller
|
|
movement_delay = 0.4 SECONDS
|
|
|
|
/datum/ai_controller/basic_controller/TryPossessPawn(atom/new_pawn)
|
|
if(!isliving(new_pawn))
|
|
return AI_CONTROLLER_INCOMPATIBLE
|
|
var/mob/living/basic/basic_mob = new_pawn
|
|
|
|
update_speed(basic_mob)
|
|
|
|
RegisterSignals(basic_mob, list(POST_BASIC_MOB_UPDATE_VARSPEED, COMSIG_MOB_MOVESPEED_UPDATED), PROC_REF(update_speed))
|
|
RegisterSignal(basic_mob, COMSIG_MOB_ATE, PROC_REF(on_mob_eat))
|
|
|
|
return ..() //Run parent at end
|
|
|
|
/datum/ai_controller/basic_controller/on_stat_changed(mob/living/source, new_stat)
|
|
. = ..()
|
|
update_able_to_run()
|
|
|
|
/datum/ai_controller/basic_controller/setup_able_to_run()
|
|
. = ..()
|
|
RegisterSignal(pawn, COMSIG_MOB_INCAPACITATE_CHANGED, PROC_REF(update_able_to_run))
|
|
if(ai_traits & PAUSE_DURING_DO_AFTER)
|
|
RegisterSignals(pawn, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_able_to_run))
|
|
|
|
|
|
/datum/ai_controller/basic_controller/clear_able_to_run()
|
|
UnregisterSignal(pawn, list(COMSIG_MOB_INCAPACITATE_CHANGED, COMSIG_MOB_STATCHANGE, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED))
|
|
return ..()
|
|
|
|
/datum/ai_controller/basic_controller/get_able_to_run()
|
|
. = ..()
|
|
if(. & AI_UNABLE_TO_RUN)
|
|
return .
|
|
var/mob/living/living_pawn = pawn
|
|
if(!(ai_traits & CAN_ACT_WHILE_DEAD))
|
|
// Unroll for flags here
|
|
if((ai_traits & CAN_ACT_IN_STASIS) && (living_pawn.stat || INCAPACITATED_IGNORING(living_pawn, INCAPABLE_STASIS)))
|
|
return AI_UNABLE_TO_RUN
|
|
if(IS_DEAD_OR_INCAP(living_pawn))
|
|
return AI_UNABLE_TO_RUN
|
|
if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters))
|
|
return AI_UNABLE_TO_RUN | AI_PREVENT_CANCEL_ACTIONS //dont erase targets post a do_after
|
|
|
|
/datum/ai_controller/basic_controller/proc/update_speed(mob/living/basic_mob)
|
|
SIGNAL_HANDLER
|
|
movement_delay = basic_mob.cached_multiplicative_slowdown
|
|
|
|
/datum/ai_controller/basic_controller/proc/on_mob_eat()
|
|
SIGNAL_HANDLER
|
|
var/food_cooldown = blackboard[BB_EAT_FOOD_COOLDOWN] || EAT_FOOD_COOLDOWN
|
|
set_blackboard_key(BB_NEXT_FOOD_EAT, world.time + food_cooldown)
|