Converts giant spiders to basic mobs (#29796)

* Giant spiders initial

* Ling spiders, araneous, conversion to basic

* Removed some extra

* Fixes cling spiders

* Linters

* Do_afters

* Nurse AI works now

* Cling spider AI

* Forgot an element

* Updatepaths

* New Linters

* AI New linters

* Fixed action buttons

* No longer wraps spiderlings, adds a movement delay

* Fixes the sarge hatching from eggs, increases action cooldown on eggs

* Improved cling spider AI, improved insect random speech

---------

Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
PollardTheDragon
2025-07-31 06:08:18 +00:00
committed by GitHub
co-authored by Burzah
parent 435637e257
commit 8976c80adc
30 changed files with 732 additions and 438 deletions
+31 -6
View File
@@ -70,6 +70,11 @@ RESTRICT_TYPE(/datum/ai_controller)
var/can_idle = TRUE
/// What distance should we be checking for interesting things when considering idling/deidling? Defaults to AI_DEFAULT_INTERESTING_DIST
var/interesting_dist = AI_DEFAULT_INTERESTING_DIST
/// TRUE if we're able to run, FALSE if we aren't
/// Should not be set manually, override get_able_to_run() instead
/// Make sure you hook update_able_to_run() in setup_able_to_run() to whatever parameters changing that you added
/// Otherwise we will not pay attention to them changing
var/able_to_run = FALSE
/// are we currently on failed planning timeout?
var/on_failed_planning_timeout = FALSE
@@ -166,6 +171,8 @@ RESTRICT_TYPE(/datum/ai_controller)
RegisterSignal(pawn, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed))
RegisterSignal(pawn, COMSIG_MOB_LOGIN, PROC_REF(on_sentience_gained))
RegisterSignal(pawn, COMSIG_PARENT_QDELETING, PROC_REF(on_pawn_qdeleted))
update_able_to_run()
setup_able_to_run()
/datum/ai_controller/proc/on_movement_target_move(datum/source)
SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED
@@ -254,13 +261,30 @@ RESTRICT_TYPE(/datum/ai_controller)
if(destroy)
qdel(src)
/// Returns TRUE if the ai controller can actually run at the moment.
/datum/ai_controller/proc/able_to_run()
/datum/ai_controller/proc/setup_able_to_run()
// paused_until is handled by PauseAi() manually
RegisterSignals(pawn, list(SIGNAL_ADDTRAIT(TRAIT_AI_PAUSED), SIGNAL_REMOVETRAIT(TRAIT_AI_PAUSED)), PROC_REF(update_able_to_run))
/datum/ai_controller/proc/clear_able_to_run()
UnregisterSignal(pawn, list(SIGNAL_ADDTRAIT(TRAIT_AI_PAUSED), SIGNAL_REMOVETRAIT(TRAIT_AI_PAUSED)))
/datum/ai_controller/proc/update_able_to_run()
SIGNAL_HANDLER
var/run_flags = get_able_to_run()
if(run_flags & AI_UNABLE_TO_RUN)
able_to_run = FALSE
GLOB.move_manager.stop_looping(pawn) //stop moving
else
able_to_run = TRUE
set_ai_status(get_expected_ai_status(), run_flags)
/// Returns TRUE if the ai controller can actually run at the moment, FALSE otherwise
/datum/ai_controller/proc/get_able_to_run()
if(HAS_TRAIT(pawn, TRAIT_AI_PAUSED))
return FALSE
return AI_UNABLE_TO_RUN
if(world.time < paused_until)
return FALSE
return TRUE
return AI_UNABLE_TO_RUN
return NONE
/datum/ai_controller/proc/ai_can_interact()
SHOULD_CALL_PARENT(TRUE)
@@ -295,7 +319,7 @@ RESTRICT_TYPE(/datum/ai_controller)
// in the AI controller implementation are actually the managing subsystem's `wait`.
seconds_per_tick /= (1 SECONDS)
if(!able_to_run())
if(!able_to_run)
GLOB.move_manager.stop_looping(pawn) //stop moving
return //this should remove them from processing in the future through event-based stuff.
@@ -457,6 +481,7 @@ RESTRICT_TYPE(/datum/ai_controller)
/datum/ai_controller/proc/on_stat_changed(mob/living/source, new_stat)
SIGNAL_HANDLER // COMSIG_MOB_STATCHANGE
reset_ai_status()
update_able_to_run()
/datum/ai_controller/proc/on_sentience_gained()
SIGNAL_HANDLER // COMSIG_MOB_LOGIN
@@ -17,3 +17,24 @@
SIGNAL_HANDLER
var/food_cooldown = blackboard[BB_EAT_FOOD_COOLDOWN] || EAT_FOOD_COOLDOWN
set_blackboard_key(BB_NEXT_FOOD_EAT, world.time + food_cooldown)
/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()
. = ..()
if(ai_traits & AI_FLAG_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_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 & AI_FLAG_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
@@ -14,3 +14,6 @@
return FALSE
living_pawn.Move(destination_turf, move_dir)
return TRUE
/datum/idle_behavior/idle_random_walk/less_walking
walk_chance = 10
+1 -1
View File
@@ -56,7 +56,7 @@
var/datum/ai_controller/controller = source.extra_info
// Check if this controller can actually run, so we don't chase people with corpses
if(!controller.able_to_run())
if(!controller.able_to_run)
controller.cancel_actions()
qdel(source) // stop moving
return MOVELOOP_SKIP_STEP
+33
View File
@@ -0,0 +1,33 @@
/**
* # Pet bonus element!
*
* Bespoke element that plays a fun message, and sends a heart out when you pet this animal.
*/
/datum/element/pet_bonus
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
///string key of the emote to do when pet.
var/emote_name
/datum/element/pet_bonus/Attach(datum/target, emote_name)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
src.emote_name = emote_name
RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand))
/datum/element/pet_bonus/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_ATOM_ATTACK_HAND)
/datum/element/pet_bonus/proc/on_attack_hand(mob/living/pet, mob/living/petter, list/modifiers)
SIGNAL_HANDLER
if(pet.stat != CONSCIOUS || petter.intent != INTENT_HELP || LAZYACCESS(modifiers, RIGHT_CLICK))
return
new /obj/effect/temp_visual/heart(get_turf(pet))
if(emote_name && prob(33))
pet.emote("me", EMOTE_VISIBLE, emote_name)