diff --git a/code/__DEFINES/mob_defines.dm b/code/__DEFINES/mob_defines.dm
index bca02adda14..3f6ef0995df 100644
--- a/code/__DEFINES/mob_defines.dm
+++ b/code/__DEFINES/mob_defines.dm
@@ -252,7 +252,7 @@
#define isbot(A) (istype((A), /mob/living/simple_animal/bot))
#define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian))
#define isnymph(A) (istype((A), /mob/living/simple_animal/diona))
-#define iscaterpillar(A) (istype((A), /mob/living/simple_animal/nian_caterpillar))
+#define iscaterpillar(A) (istype((A), /mob/living/basic/nian_caterpillar))
#define ishostile(A) (istype((A), /mob/living/simple_animal/hostile))
#define isretaliate(A) (istype((A), /mob/living/simple_animal/hostile/retaliate))
#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm
index 8c330c5b57f..04bfe0d1a14 100644
--- a/code/game/objects/structures/crates_lockers/crittercrate.dm
+++ b/code/game/objects/structures/crates_lockers/crittercrate.dm
@@ -112,7 +112,7 @@
/obj/structure/closet/critter/nian_caterpillar
name = "nian caterpillar crate"
- content_mob = /mob/living/simple_animal/nian_caterpillar
+ content_mob = /mob/living/basic/nian_caterpillar
/obj/structure/closet/critter/deer
name = "deer crate"
diff --git a/code/modules/food_and_drinks/food_base.dm b/code/modules/food_and_drinks/food_base.dm
index 1d656a550b1..cd8301cbf20 100644
--- a/code/modules/food_and_drinks/food_base.dm
+++ b/code/modules/food_and_drinks/food_base.dm
@@ -275,7 +275,7 @@
N.adjustHealth(-2)
N.taste(reagents)
else if(iscaterpillar(M))
- var/mob/living/simple_animal/nian_caterpillar/W = M
+ var/mob/living/basic/nian_caterpillar/W = M
W.taste(reagents)
W.consume(src)
diff --git a/code/modules/mob/living/simple_animal/friendly/nian_caterpillar.dm b/code/modules/mob/living/basic/friendly/nian_caterpillar.dm
similarity index 56%
rename from code/modules/mob/living/simple_animal/friendly/nian_caterpillar.dm
rename to code/modules/mob/living/basic/friendly/nian_caterpillar.dm
index 376ec0aabb0..b16847c5585 100644
--- a/code/modules/mob/living/simple_animal/friendly/nian_caterpillar.dm
+++ b/code/modules/mob/living/basic/friendly/nian_caterpillar.dm
@@ -1,4 +1,4 @@
-/mob/living/simple_animal/nian_caterpillar
+/mob/living/basic/nian_caterpillar
name = "nian caterpillar"
icon = 'icons/mob/monkey.dmi'
icon_state = "mothroach"
@@ -11,49 +11,65 @@
ventcrawler = VENTCRAWLER_ALWAYS
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
butcher_results = list(/obj/item/food/meat = 1)
- minbodytemp = 0
+ minimum_survivable_temperature = 0
blood_color = "#b9ae9c"
maxHealth = 50
health = 50
speed = 0.75
- turns_per_move = 4
// What they sound like
voice_name = "nian caterpillar"
speak_emote = list("flutters", "chitters", "chatters")
- emote_hear = list("flutters", "chitters", "chatters")
- emote_see = list("flutters", "chitters", "chatters")
// Special verbs for when someone interacts with a caterpillar
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "kicks"
+ response_help_continuous = "pets"
+ response_help_simple = "pet"
+ response_disarm_continuous = "shoos"
+ response_disarm_simple = "shoo"
+ response_harm_continuous = "kicks"
+ response_harm_simple = "kicks"
// Xenobiology and cargo are the only ways to get the caterpillar.
gold_core_spawnable = FRIENDLY_SPAWN
+ melee_attack_cooldown_min = 1.5 SECONDS
+ melee_attack_cooldown_max = 2.5 SECONDS
melee_damage_lower = 5
melee_damage_upper = 8
- attacktext = "bites"
+ attack_verb_continuous = "bites"
+ attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
holder_type = /obj/item/holder/nian_caterpillar
- /// Evolution action.
- var/datum/action/innate/nian_caterpillar_emerge/evolve_action = new()
+ ai_controller = /datum/ai_controller/basic_controller/mothroach
+
+ var/list/innate_actions = list(
+ /datum/action/innate/nian_caterpillar_emerge,
+ )
+
+ /// List of stuff that we want to eat
+ var/static/list/edibles = list(
+ /obj/item/food,
+ )
/// The amount of nutrition the nian caterpillar needs to evolve, default is 500.
var/nutrition_need = 500
-/mob/living/simple_animal/nian_caterpillar/Initialize(mapload)
+/mob/living/basic/nian_caterpillar/Initialize(mapload)
. = ..()
real_name = name
AddElement(/datum/element/wears_collar)
+ AddElement(/datum/element/ai_retaliate)
+ AddElement(/datum/element/basic_eating, heal_amt_ = 2, food_types_ = edibles)
+ ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles))
add_language("Tkachi")
- evolve_action.Grant(src)
+ grant_actions_by_list(innate_actions)
+ RegisterSignal(src, COMSIG_MOB_PRE_EAT, PROC_REF(check_full))
+ RegisterSignal(src, COMSIG_MOB_ATE, PROC_REF(consume))
-/mob/living/simple_animal/nian_caterpillar/proc/evolve(obj/structure/moth_cocoon/C, datum/mind/M)
+/mob/living/basic/nian_caterpillar/proc/evolve(obj/structure/moth_cocoon/C, datum/mind/M)
if(stat != CONSCIOUS)
return FALSE
@@ -80,10 +96,11 @@
adult.name = name
adult.real_name = name
- // Mind transfer to new worme.
- M.transfer_to(adult)
- // [Caterpillar -> worme -> nian] is from xenobio (or cargo) and does not give vampires usuble blood and cannot be converted by cult.
- ADD_TRAIT(adult.mind, TRAIT_XENOBIO_SPAWNED_HUMAN, ROUNDSTART_TRAIT)
+ if(M)
+ // Mind transfer to new worme.
+ M.transfer_to(adult)
+ // [Caterpillar -> worme -> nian] is from xenobio (or cargo) and does not give vampires usuble blood and cannot be converted by cult.
+ ADD_TRAIT(adult.mind, TRAIT_XENOBIO_SPAWNED_HUMAN, ROUNDSTART_TRAIT)
// Worme is placed into cacoon.
adult.forceMove(C)
@@ -103,18 +120,21 @@
qdel(src)
return TRUE
-/mob/living/simple_animal/nian_caterpillar/proc/consume(obj/item/food/G)
+/mob/living/basic/nian_caterpillar/proc/check_full(datum/source, obj/item/potential_food)
+ SIGNAL_HANDLER // COMSIG_MOB_PRE_EAT
if(nutrition >= nutrition_need) // Prevents griefing by overeating food items without evolving.
- return to_chat(src, "You're too full to consume this! Perhaps it's time to grow bigger...")
- visible_message("[src] ravenously consumes [G].", "You ravenously devour [G].")
- playsound(loc, 'sound/items/eatfood.ogg', 30, TRUE, frequency = 1.5)
- if(G.reagents.get_reagent_amount("nutriment") + G.reagents.get_reagent_amount("plantmatter") < 1)
+ to_chat(src, "You're too full to consume this! Perhaps it's time to grow bigger...")
+ return COMSIG_MOB_TERMINATE_EAT
+
+
+/mob/living/basic/nian_caterpillar/proc/consume(datum/source, obj/item/potential_food)
+ SIGNAL_HANDLER // COMSIG_MOB_ATE
+ if(potential_food.reagents.get_reagent_amount("nutriment") + potential_food.reagents.get_reagent_amount("plantmatter") < 1)
adjust_nutrition(2)
else
- adjust_nutrition((G.reagents.get_reagent_amount("nutriment") + G.reagents.get_reagent_amount("plantmatter")) * 2)
- qdel(G)
+ adjust_nutrition((potential_food.reagents.get_reagent_amount("nutriment") + potential_food.reagents.get_reagent_amount("plantmatter")) * 2)
-/mob/living/simple_animal/nian_caterpillar/attack_hand(mob/living/carbon/human/M)
+/mob/living/basic/nian_caterpillar/attack_hand(mob/living/carbon/human/M)
// Let people pick the little buggers up.
if(M.a_intent != INTENT_HELP)
return ..()
@@ -123,12 +143,16 @@
else
get_scooped(M)
-/mob/living/simple_animal/nian_caterpillar/attacked_by(obj/item/I, mob/living/user)
+/mob/living/basic/nian_caterpillar/attacked_by(obj/item/I, mob/living/user)
if(..())
return FINISH_ATTACK
if(istype(I, /obj/item/melee/flyswatter) && I.force)
gib() // Commit die.
+/mob/living/basic/nian_caterpillar/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ . = ..()
+
+
/datum/action/innate/nian_caterpillar_emerge
name = "Evolve"
desc = "Weave a cocoon around yourself to evolve into a greater form. The worme."
@@ -143,7 +167,7 @@
qdel(C)
/datum/action/innate/nian_caterpillar_emerge/Activate()
- var/mob/living/simple_animal/nian_caterpillar/user = owner
+ var/mob/living/basic/nian_caterpillar/user = owner
user.visible_message("[user] begins to hold still and concentrate on weaving a cocoon...", "You begin to focus on weaving a cocoon... (This will take [COCOON_WEAVE_DELAY / 10] seconds, and you must hold still.)")
if(do_after(user, COCOON_WEAVE_DELAY, FALSE, user))
@@ -151,3 +175,26 @@
var/datum/mind/H = user.mind
user.evolve(C, H)
addtimer(CALLBACK(src, PROC_REF(emerge), C), COCOON_EMERGE_DELAY, TIMER_UNIQUE)
+
+/datum/ai_controller/basic_controller/mothroach
+ blackboard = list(
+ BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
+ BB_EAT_FOOD_COOLDOWN = 1 MINUTES, // Moth wants to eat, but not too fast.
+ BB_SEARCH_RANGE = 3,
+ )
+
+ ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED | AI_FLAG_PAUSE_DURING_DO_AFTER
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/random_speech/moth_caterpillar,
+ /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
+ /datum/ai_planning_subtree/flee_target,
+ /datum/ai_planning_subtree/find_food,
+ )
+
+/datum/ai_planning_subtree/random_speech/moth_caterpillar
+ speech_chance = 2
+ emote_hear = list("flutters.", "chitters.", "chatters.")
+ emote_see = list("flutters.", "chitters.", "chatters.")
+
diff --git a/paradise.dme b/paradise.dme
index d1b37be4498..772467d1930 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2424,6 +2424,7 @@
#include "code\modules\mob\living\taste.dm"
#include "code\modules\mob\living\basic\basic_emotes.dm"
#include "code\modules\mob\living\basic\basic_mob.dm"
+#include "code\modules\mob\living\basic\friendly\nian_caterpillar.dm"
#include "code\modules\mob\living\basic\posessed_object.dm"
#include "code\modules\mob\living\basic\farm_animals\cow.dm"
#include "code\modules\mob\living\basic\farm_animals\deer.dm"
@@ -2661,7 +2662,6 @@
#include "code\modules\mob\living\simple_animal\friendly\fox.dm"
#include "code\modules\mob\living\simple_animal\friendly\friendly_emote.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
-#include "code\modules\mob\living\simple_animal\friendly\nian_caterpillar.dm"
#include "code\modules\mob\living\simple_animal\friendly\pet.dm"
#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\hostile\angel_statue.dm"