mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-26 05:27:01 +01:00
Converts a whole lot of friendly mobs to basic mob AI (#29815)
* Butterflies, Cockroaches, Slothes, Snakes, Penguins, and Bunny Basic Mobs * Lizards too * Oops * Lizard emote keybind * Updatepaths * Apply suggestions from code review Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> * Moved lizard emote to basic_emotes.dm, simplified hide action * New linters * Merge conflict resolution --------- Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
/datum/emote/lizard
|
||||
mob_type_allowed_typecache = /mob/living/basic/lizard
|
||||
mob_type_blacklist_typecache = list()
|
||||
|
||||
/datum/emote/lizard/whicker
|
||||
key = "tongue"
|
||||
message = "sticks its tongue out contentedly!"
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
|
||||
@@ -175,6 +175,9 @@ RESTRICT_TYPE(/mob/living/basic)
|
||||
apply_temperature_requirements()
|
||||
if(step_type)
|
||||
AddComponent(/datum/component/footstep, step_type)
|
||||
if(can_hide)
|
||||
var/datum/action/innate/hide/hide = new()
|
||||
hide.Grant(src)
|
||||
if(is_ranged)
|
||||
AddComponent(/datum/component/ranged_attacks, projectile_type = projectile_type, projectile_sound = projectile_sound, burst_shots = ranged_burst_count, burst_intervals = ranged_burst_interval)
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/mob/living/basic/pet
|
||||
icon = 'icons/mob/pets.dmi'
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BEAST
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
speed = 0 // same speed as a person.
|
||||
hud_type = /datum/hud/corgi
|
||||
|
||||
/mob/living/basic/pet/item_interaction(mob/living/user, obj/item/O, list/modifiers)
|
||||
if(!istype(O, /obj/item/newspaper))
|
||||
return ..()
|
||||
var/obj/item/newspaper/paper = O
|
||||
if(stat != CONSCIOUS || !paper.rolled)
|
||||
return ..()
|
||||
user.visible_message("<span class='notice'>[user] baps [name] on the nose with the rolled up [O].</span>")
|
||||
INVOKE_ASYNC(src, PROC_REF(spin), 7 DECISECONDS, 1)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
@@ -0,0 +1,64 @@
|
||||
/mob/living/basic/bunny
|
||||
name = "bunny"
|
||||
real_name = "bunny"
|
||||
desc = "Awww a cute bunny."
|
||||
icon_state = "m_bunny"
|
||||
icon_living = "m_bunny"
|
||||
icon_dead = "bunny_dead"
|
||||
icon_resting = "bunny_stretch"
|
||||
faction = list("neutral", "jungle")
|
||||
see_in_dark = 6
|
||||
maxHealth = 10
|
||||
health = 10
|
||||
ai_controller = /datum/ai_controller/basic_controller/bunny
|
||||
butcher_results = list(/obj/item/food/meat = 1)
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "gently pushes aside"
|
||||
response_disarm_simple = "gently push aside"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
density = FALSE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BEAST
|
||||
mob_size = MOB_SIZE_TINY
|
||||
atmos_requirements = list("min_oxy" = 16, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
minimum_survivable_temperature = 223 // Below -50 Degrees Celcius
|
||||
maximum_survivable_temperature = 323 // Above 50 Degrees Celcius
|
||||
can_hide = TRUE
|
||||
holder_type = /obj/item/holder/bunny
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
|
||||
/mob/living/basic/bunny/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/wears_collar)
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
|
||||
/mob/living/basic/bunny/attack_hand(mob/living/carbon/human/M)
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
get_scooped(M, TRUE)
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/bunny/syndi // for the syndicake factory bunny so its not being shot
|
||||
faction = list("syndicate")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/datum/ai_controller/basic_controller/bunny
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/random_speech/rabbit,
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/rabbit
|
||||
speech_chance = 10
|
||||
speak = list("Mrrp.", "CHIRP!", "Mrrp?") // rabbits make some weird noises dude i don't know what to tell you
|
||||
emote_hear = list("hops.", "thumps.")
|
||||
emote_see = list("hops around.", "bounces up and down.", "flips their ears up")
|
||||
@@ -0,0 +1,33 @@
|
||||
/mob/living/basic/butterfly
|
||||
name = "butterfly"
|
||||
desc = "A colorful butterfly, how'd it get up here?"
|
||||
icon_state = "butterfly"
|
||||
icon_living = "butterfly"
|
||||
icon_dead = "butterfly_dead"
|
||||
faction = list("neutral", "jungle")
|
||||
response_help_continuous = "shoos"
|
||||
response_help_simple = "shoo"
|
||||
response_disarm_continuous = "brushes aside"
|
||||
response_disarm_simple = "brush aside"
|
||||
response_harm_continuous = "squashes"
|
||||
response_harm_simple = "squash"
|
||||
ai_controller = /datum/ai_controller/basic_controller/butterfly
|
||||
maxHealth = 2
|
||||
health = 2
|
||||
harm_intent_damage = 1
|
||||
density = FALSE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
mob_size = MOB_SIZE_TINY
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BUG
|
||||
butcher_results = list(/obj/item/food/meat = 0)
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
initial_traits = list(TRAIT_FLYING, TRAIT_EDIBLE_BUG)
|
||||
|
||||
/mob/living/basic/butterfly/Initialize(mapload)
|
||||
. = ..()
|
||||
color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
|
||||
/datum/ai_controller/basic_controller/butterfly
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
@@ -0,0 +1,75 @@
|
||||
/mob/living/basic/cockroach
|
||||
name = "cockroach"
|
||||
desc = "This station is just crawling with bugs."
|
||||
icon_state = "cockroach"
|
||||
icon_dead = "cockroach"
|
||||
health = 1
|
||||
maxHealth = 1
|
||||
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)
|
||||
minimum_survivable_temperature = 270
|
||||
maximum_survivable_temperature = INFINITY
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BUG
|
||||
mob_size = MOB_SIZE_TINY
|
||||
ai_controller = /datum/ai_controller/basic_controller/cockroach
|
||||
response_disarm_continuous = "shoos"
|
||||
response_disarm_simple = "shoo"
|
||||
response_harm_continuous = "splats"
|
||||
response_harm_simple = "splat"
|
||||
density = FALSE
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
loot = list(/obj/effect/decal/cleanable/insectguts)
|
||||
basic_mob_flags = DEL_ON_DEATH
|
||||
/// Chance to get squished
|
||||
var/squish_chance = 50
|
||||
|
||||
/mob/living/basic/cockroach/can_die()
|
||||
return ..() && !SSticker.cinematic // If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
|
||||
|
||||
/mob/living/basic/cockroach/Initialize(mapload) // Lizards are a great way to deal with cockroaches
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_EDIBLE_BUG, "edible_bug")
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered)
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
|
||||
/mob/living/basic/cockroach/proc/on_atom_entered(datum/source, atom/movable/entered)
|
||||
if(isliving(entered))
|
||||
var/mob/living/A = entered
|
||||
if(A.mob_size > MOB_SIZE_SMALL)
|
||||
if(prob(squish_chance))
|
||||
A.visible_message("<span class='notice'>\The [A] squashed \the [name].</span>", "<span class='notice'>You squashed \the [name].</span>")
|
||||
death()
|
||||
else
|
||||
visible_message("<span class='notice'>\The [name] avoids getting crushed.</span>")
|
||||
else if(isstructure(entered))
|
||||
visible_message("<span class='notice'>As \the [entered] moved over \the [name], it was crushed.</span>")
|
||||
death()
|
||||
|
||||
/mob/living/basic/cockroach/ex_act() // Explosions are a terrible way to handle a cockroach.
|
||||
return
|
||||
|
||||
// mining pet
|
||||
/mob/living/basic/cockroach/brad
|
||||
name = "Brad"
|
||||
desc = "Lavaland's most resilient cockroach. Seeing this little guy walk through the wastes almost makes you wish for nuclear winter."
|
||||
response_help_continuous = "carefully pets"
|
||||
response_help_simple = "carefully pet"
|
||||
weather_immunities = list("ash")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/datum/ai_controller/basic_controller/cockroach
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/roach,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/roach
|
||||
hunt_targets = list(/obj/effect/decal/cleanable/ants)
|
||||
@@ -0,0 +1,105 @@
|
||||
/mob/living/basic/lizard
|
||||
name = "lizard"
|
||||
desc = "A cute tiny lizard."
|
||||
icon = 'icons/mob/critter.dmi'
|
||||
icon_state = "lizard"
|
||||
icon_living = "lizard"
|
||||
icon_dead = "lizard-dead"
|
||||
speak_emote = list("hisses")
|
||||
health = 10
|
||||
maxHealth = 10
|
||||
attack_verb_continuous = "bites"
|
||||
attack_verb_simple = "bite"
|
||||
attack_sound = 'sound/effects/bite.ogg'
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 2
|
||||
ai_controller = /datum/ai_controller/basic_controller/lizard
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "shoos"
|
||||
response_disarm_simple = "shoo"
|
||||
response_harm_continuous = "stomps on"
|
||||
response_harm_simple = "stomp on"
|
||||
faction = list("neutral", "jungle")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
density = FALSE
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
can_hide = TRUE
|
||||
pass_door_while_hidden = TRUE
|
||||
butcher_results = list(/obj/item/food/meat = 1)
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BEAST | MOB_REPTILE
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
/// List of stuff that we want to eat
|
||||
var/static/list/edibles = list(
|
||||
/mob/living/basic/butterfly,
|
||||
/mob/living/basic/cockroach,
|
||||
/obj/structure/spider/spiderling
|
||||
)
|
||||
/// Lizards start with a tail
|
||||
var/has_tail = TRUE
|
||||
|
||||
/mob/living/basic/lizard/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/wears_collar)
|
||||
AddElement(/datum/element/basic_eating, heal_amt_ = 5, food_types_ = edibles)
|
||||
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles))
|
||||
|
||||
/datum/ai_controller/basic_controller/lizard
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_food,
|
||||
/datum/ai_planning_subtree/random_speech/lizard,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/lizard // all of these have to be three words long or i'm killing you. you're dead.
|
||||
speech_chance = 3
|
||||
emote_hear = list("stamps around some.", "hisses a bit.")
|
||||
emote_see = list("blehs the tongue.", "tilts the head.", "does a spin.")
|
||||
|
||||
/mob/living/basic/lizard/verb/lose_tail()
|
||||
set name = "Lose tail"
|
||||
set desc = "Allows you to lose your tail and escape a sticky situation. Takes 5 minutes for your tail to grow back."
|
||||
set category = "Animal"
|
||||
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
if(!has_tail)
|
||||
to_chat(usr, "<span class='warning'>You have no tail to shed!</span>")
|
||||
return
|
||||
for(var/obj/item/grab/G in usr.grabbed_by)
|
||||
var/mob/living/carbon/M = G.assailant
|
||||
usr.visible_message("<span class='warning'>[usr] suddenly sheds their tail and slips out of [M]'s grasp!</span>")
|
||||
M.KnockDown(3 SECONDS) // FUCK I TRIPPED
|
||||
playsound(usr.loc, "sound/misc/slip.ogg", 75, 1)
|
||||
has_tail = FALSE
|
||||
addtimer(CALLBACK(src, PROC_REF(new_tail)), 5 MINUTES)
|
||||
|
||||
/mob/living/basic/lizard/proc/new_tail()
|
||||
has_tail = TRUE
|
||||
to_chat(src, "<span class='notice'>You regrow your tail!</span>")
|
||||
|
||||
/mob/living/basic/lizard/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!isdrone(user))
|
||||
user.visible_message("<span class='notice'>[user] sucks [src] into its decompiler. There's a horrible crunching noise.</span>", \
|
||||
"<span class='warning'>It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
C.stored_comms["metal"] += 2 // having more metal than glass because blood has iron in it
|
||||
C.stored_comms["glass"] += 1
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/basic/lizard/wags_his_tail
|
||||
name = "Wags-His-Tail"
|
||||
real_name = "Wags-His-Tail"
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/mob/living/basic/lizard/wags_his_tail/update_desc()
|
||||
. = ..()
|
||||
desc = "The official mascot of Janitalia."
|
||||
@@ -0,0 +1,90 @@
|
||||
// Penguins
|
||||
|
||||
/mob/living/basic/pet/penguin
|
||||
name = "penguin"
|
||||
real_name = "penguin"
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "bops"
|
||||
response_disarm_simple = "bop"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
speak_emote = list("squawks", "gakkers")
|
||||
faction = list("penguin")
|
||||
ai_controller = /datum/ai_controller/basic_controller/penguin
|
||||
see_in_dark = 5
|
||||
icon = 'icons/mob/penguins.dmi'
|
||||
step_type = FOOTSTEP_MOB_BAREFOOT
|
||||
|
||||
/mob/living/basic/pet/penguin/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/wears_collar)
|
||||
AddElement(/datum/element/waddling)
|
||||
|
||||
/mob/living/basic/pet/penguin/emperor
|
||||
name = "Emperor penguin"
|
||||
desc = "Emperor of all he surveys."
|
||||
icon_state = "penguin"
|
||||
icon_living = "penguin"
|
||||
icon_dead = "penguin_dead"
|
||||
butcher_results = list()
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
/mob/living/basic/pet/penguin/eldrich
|
||||
name = "Albino penguin"
|
||||
desc = "Found in the depths of mountains."
|
||||
response_help_continuous = "taps"
|
||||
response_help_simple = "tap"
|
||||
response_disarm_continuous = "pokes"
|
||||
response_disarm_simple = "poke"
|
||||
response_harm_continuous = "flails at"
|
||||
response_harm_simple = "flail at"
|
||||
icon_state = "penguin_elder"
|
||||
icon_living = "penguin_elder"
|
||||
icon_dead = "penguin_dead"
|
||||
faction = list("penguin", "cult")
|
||||
|
||||
/mob/living/basic/pet/penguin/emperor/shamebrero
|
||||
name = "Shamebrero penguin"
|
||||
desc = "Shameful of all he surveys."
|
||||
icon_state = "penguin_shamebrero"
|
||||
icon_living = "penguin_shamebrero"
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/mob/living/basic/pet/penguin/baby
|
||||
name = "Penguin chick"
|
||||
desc = "Can't fly and can barely waddles, but the prince of all chicks."
|
||||
icon_state = "penguin_baby"
|
||||
icon_living = "penguin_baby"
|
||||
icon_dead = "penguin_baby_dead"
|
||||
density = FALSE
|
||||
pass_flags = PASSMOB
|
||||
|
||||
/datum/ai_controller/basic_controller/penguin
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
/datum/ai_planning_subtree/random_speech/penguin,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/penguin
|
||||
speech_chance = 5
|
||||
speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
|
||||
emote_hear = list("squawks", "gakkers")
|
||||
emote_see = list("shakes its beak.", "flaps it's wings.", "preens itself.")
|
||||
|
||||
/datum/ai_controller/basic_controller/penguin/eldrich
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
/datum/ai_planning_subtree/random_speech/penguin/eldrich,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/penguin/eldrich
|
||||
speak = list("Gah Gah!", "Tekeli-li! Tekeli-li!", "Tekeli-li!", "Teke", "li")
|
||||
@@ -0,0 +1,55 @@
|
||||
/mob/living/basic/pet/sloth
|
||||
name = "sloth"
|
||||
desc = "An adorable, sleepy creature."
|
||||
icon_state = "sloth"
|
||||
icon_living = "sloth"
|
||||
icon_dead = "sloth_dead"
|
||||
gender = MALE
|
||||
speak_emote = list("yawns")
|
||||
faction = list("neutral", "jungle")
|
||||
butcher_results = list(/obj/item/food/meat = 3)
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "gently pushes aside"
|
||||
response_disarm_simple = "gently push aside"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
ai_controller = /datum/ai_controller/basic_controller/sloth
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
melee_damage_upper = 5
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
speed = 2
|
||||
step_type = FOOTSTEP_MOB_CLAW
|
||||
|
||||
/mob/living/basic/pet/sloth/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/wears_collar)
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
|
||||
//IAA Sloth
|
||||
/mob/living/basic/pet/sloth/paperwork
|
||||
name = "Paperwork"
|
||||
desc = "Internal Affairs' pet sloth. About as useful as the rest of the agents."
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/datum/ai_controller/basic_controller/sloth
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_FLEE_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate/to_flee,
|
||||
/datum/ai_planning_subtree/flee_target/from_flee_key,
|
||||
/datum/ai_planning_subtree/random_speech/sloth,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/sloth
|
||||
speech_chance = 1
|
||||
speak = list("Ahhhh")
|
||||
emote_hear = list("snores.", "yawns.")
|
||||
emote_see = list("dozes off.", "looks around sleepily.")
|
||||
@@ -0,0 +1,72 @@
|
||||
/mob/living/basic/snake
|
||||
name = "snake"
|
||||
desc = "A slithery snake. These legless reptiles are the bane of mice and adventurers alike."
|
||||
icon_state = "snake"
|
||||
icon_living = "snake"
|
||||
icon_dead = "snake_dead"
|
||||
speak_emote = list("hisses")
|
||||
health = 20
|
||||
maxHealth = 20
|
||||
attack_verb_continuous = "bites"
|
||||
attack_verb_simple = "bite"
|
||||
attack_sound = 'sound/effects/bite.ogg'
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 6
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "shoos"
|
||||
response_disarm_simple = "shoo"
|
||||
response_harm_continuous = "steps on"
|
||||
response_harm_simple = "step on"
|
||||
faction = list("hostile", "jungle")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
density = FALSE
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_biotypes = MOB_ORGANIC | MOB_BEAST | MOB_REPTILE
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/snake
|
||||
/// How much poison?
|
||||
var/poison_per_bite = 0
|
||||
/// What poison
|
||||
var/poison_type = "toxin"
|
||||
/// List of stuff (mice) that we want to eat
|
||||
var/static/list/edibles = list(
|
||||
/mob/living/simple_animal/mouse,
|
||||
)
|
||||
|
||||
/mob/living/basic/snake/Initialize(mapload)
|
||||
. = ..()
|
||||
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))
|
||||
|
||||
/mob/living/basic/snake/melee_attack(atom/target, list/modifiers, ignore_cooldown)
|
||||
. = ..()
|
||||
if(. && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents && poison_per_bite > 0)
|
||||
L.reagents.add_reagent(poison_type, poison_per_bite)
|
||||
|
||||
/// Snakes are primarily concerned with getting those tasty, tasty mice, but aren't afraid to strike back at those who attack them
|
||||
/datum/ai_controller/basic_controller/snake
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
|
||||
)
|
||||
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/find_food,
|
||||
/datum/ai_planning_subtree/random_speech/snake,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/snake
|
||||
speech_chance = 5
|
||||
speak = list("hsssss", "sssSSsssss...", "hiisssss")
|
||||
sound = list('sound/creatures/snake_hissing1.ogg', 'sound/creatures/snake_hissing2.ogg')
|
||||
emote_hear = list("hisses.")
|
||||
emote_see = list("slithers around.", "glances.", "stares.")
|
||||
Reference in New Issue
Block a user