\the [src] knocks down \the [L]!")
-
-/mob/living/simple_animal/hostile/faithless/cult
- faction = "cult"
- supernatural = 1
-
-/mob/living/simple_animal/hostile/faithless/cult/cultify()
- return
-
-/mob/living/simple_animal/hostile/faithless/cult/Life()
- ..()
- check_horde()
-
-/mob/living/simple_animal/hostile/faithless/strong
- maxHealth = 100
- health = 100
-
- harm_intent_damage = 5
- melee_damage_lower = 13
- melee_damage_upper = 28
-
-/mob/living/simple_animal/hostile/faithless/strong/cult
- faction = "cult"
- supernatural = 1
-
-/mob/living/simple_animal/hostile/faithless/cult/cultify()
- return
-
-/mob/living/simple_animal/hostile/faithless/cult/Life()
- ..()
- check_horde()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/aliens/hivebot.dm b/code/modules/mob/living/simple_animal/aliens/hivebot.dm
deleted file mode 100644
index 876f5927a2..0000000000
--- a/code/modules/mob/living/simple_animal/aliens/hivebot.dm
+++ /dev/null
@@ -1,241 +0,0 @@
-// Hivebots are tuned towards how many default lasers are needed to kill them.
-// As such, if laser damage is ever changed, you should change this define.
-#define LASERS_TO_KILL * 40
-
-// Default hivebot is melee, and a bit more meaty, so it can meatshield for their ranged friends.
-/mob/living/simple_animal/hostile/hivebot
- name = "hivebot"
- desc = "A robot. It appears to be somewhat resilient, but lacks a true weapon."
- icon = 'icons/mob/hivebot.dmi'
- icon_state = "basic"
- icon_living = "basic"
- icon_dead = "basic"
-
- faction = "hivebot"
- intelligence_level = SA_ROBOTIC
- maxHealth = 3 LASERS_TO_KILL
- health = 3 LASERS_TO_KILL
- speed = 4
-
- melee_damage_lower = 15
- melee_damage_upper = 15
-
- attacktext = list("clawed")
- projectilesound = 'sound/weapons/Gunshot.ogg'
- projectiletype = /obj/item/projectile/bullet/hivebot
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- cooperative = TRUE
- firing_lines = TRUE
- investigates = TRUE
-
- speak_chance = 1
- speak = list(
- "Resuming task: Protect area.",
- "No threats found.",
- "Error: No targets found."
- )
- emote_hear = list("hums ominously", "whirrs softly", "grinds a gear")
- emote_see = list("looks around the area", "turns from side to side")
- say_understood = list("Affirmative.", "Positive.")
- say_cannot = list("Denied.", "Negative.")
- say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
- say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
-
-/mob/living/simple_animal/hostile/hivebot/isSynthetic()
- return TRUE
-
-// Subtypes.
-
-// Melee like the base type, but more fragile.
-/mob/living/simple_animal/hostile/hivebot/swarm
- name = "swarm hivebot"
- desc = "A robot. It looks fragile and weak"
- maxHealth = 1 LASERS_TO_KILL
- health = 1 LASERS_TO_KILL
- melee_damage_lower = 8
- melee_damage_upper = 8
-
-// This one has a semi-weak ranged attack.
-/mob/living/simple_animal/hostile/hivebot/range
- name = "ranged hivebot"
- desc = "A robot. It has a simple ballistic weapon."
- ranged = 1
- maxHealth = 2 LASERS_TO_KILL
- health = 2 LASERS_TO_KILL
-
-// This one shoots a burst of three, and is considerably more dangerous.
-/mob/living/simple_animal/hostile/hivebot/range/rapid
- name = "rapid hivebot"
- desc = "A robot. It has a fast firing ballistic rifle."
- icon_living = "strong"
- rapid = 1
- maxHealth = 2 LASERS_TO_KILL
- health = 2 LASERS_TO_KILL
-
-// Shoots EMPs, to screw over other robots.
-/mob/living/simple_animal/hostile/hivebot/range/ion
- name = "engineering hivebot"
- desc = "A robot. It has a tool which emits focused electromagnetic pulses, which are deadly to synthetic adverseries."
- projectiletype = /obj/item/projectile/ion
- projectilesound = 'sound/weapons/Laser.ogg'
- icon_living = "engi"
- ranged = TRUE
- maxHealth = 2 LASERS_TO_KILL
- health = 2 LASERS_TO_KILL
-
-// Shoots deadly lasers.
-/mob/living/simple_animal/hostile/hivebot/range/laser
- name = "laser hivebot"
- desc = "A robot. It has an energy weapon."
- projectiletype = /obj/item/projectile/beam/blue
- projectilesound = 'sound/weapons/Laser.ogg'
- maxHealth = 2 LASERS_TO_KILL
- health = 2 LASERS_TO_KILL
-
-// Beefy and ranged.
-/mob/living/simple_animal/hostile/hivebot/range/strong
- name = "strong hivebot"
- desc = "A robot. This one has reinforced plating, and looks tougher."
- icon_living = "strong"
- maxHealth = 4 LASERS_TO_KILL
- health = 4 LASERS_TO_KILL
- melee_damage_lower = 15
- melee_damage_upper = 15
-
-// Also beefy, but tries to stay at their 'home', ideal for base defense.
-/mob/living/simple_animal/hostile/hivebot/range/guard
- name = "guard hivebot"
- desc = "A robot. It seems to be guarding something."
- returns_home = TRUE
- maxHealth = 4 LASERS_TO_KILL
- health = 4 LASERS_TO_KILL
-
-// This one is intended for players to use. Well rounded and can make other hivebots follow them with verbs.
-/mob/living/simple_animal/hostile/hivebot/range/player
- name = "commander hivebot"
- desc = "A robot. This one seems to direct the others, and it has a laser weapon."
- icon_living = "commander"
- maxHealth = 5 LASERS_TO_KILL
- health = 5 LASERS_TO_KILL
- projectiletype = /obj/item/projectile/beam/blue
- projectilesound = 'sound/weapons/Laser.ogg'
- melee_damage_lower = 15 // Needed to force open airlocks.
- melee_damage_upper = 15
-
-// Procs.
-
-/mob/living/simple_animal/hostile/hivebot/death()
- ..()
- visible_message("[src] blows apart!")
- new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- qdel(src)
-
-/mob/living/simple_animal/hostile/hivebot/speech_bubble_appearance()
- return "synthetic_evil"
-
-/mob/living/simple_animal/hostile/hivebot/verb/command_follow()
- set name = "Command - Follow"
- set category = "Hivebot"
- set desc = "This will ask other hivebots to follow you."
-
- say("Delegating new task: Follow.")
-
- for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
- if(buddy.faction != faction)
- continue
- if(buddy == src)
- continue
- buddy.set_follow(src)
- buddy.FollowTarget()
- spawn(rand(5, 10))
- buddy.say( pick(buddy.say_understood) )
-
-/mob/living/simple_animal/hostile/hivebot/verb/command_stop()
- set name = "Command - Stop Following"
- set category = "Hivebot"
- set desc = "This will ask other hivebots to cease following you."
-
- say("Delegating new task: Stop following.")
-
- for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
- if(buddy.faction != faction)
- continue
- if(buddy == src)
- continue
- buddy.LoseFollow()
- spawn(rand(5, 10))
- buddy.say( pick(buddy.say_understood) )
-
-/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
- name = "Beacon"
- desc = "Some odd beacon thing"
- icon = 'icons/mob/hivebot.dmi'
- icon_state = "def_radar-off"
- icon_living = "def_radar-off"
-
- health = 200
- maxHealth = 200
- status_flags = 0
-
- anchored = 1
- wander = 0
- stop_automated_movement = 1
-
- var/bot_type = "norm"
- var/bot_amt = 10
- var/spawn_delay = 600
- var/turn_on = 0
- var/auto_spawn = 1
- proc
- warpbots()
-
-
- New()
- ..()
- var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
- smoke.set_up(5, 0, src.loc)
- smoke.start()
- visible_message("The [src] warps in!")
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
-
- warpbots()
- icon_state = "def_radar"
- visible_message("The [src] turns on!")
- while(bot_amt > 0)
- bot_amt--
- switch(bot_type)
- if("norm")
- new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
- if("range")
- new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
- if("rapid")
- new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src))
- spawn(100)
- qdel(src)
- return
-
-
- Life()
- ..()
- if(stat == 0)
- if(prob(2))//Might be a bit low, will mess with it likely
- warpbots()
-
-/obj/item/projectile/bullet/hivebot
- damage = 10
- damage_type = BRUTE
-
-#undef LASERS_TO_KILL
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm
deleted file mode 100644
index 2dc3a4afe7..0000000000
--- a/code/modules/mob/living/simple_animal/aliens/mimic.dm
+++ /dev/null
@@ -1,201 +0,0 @@
-//
-// Abstract Class
-//
-
-/mob/living/simple_animal/hostile/mimic
- name = "crate"
- desc = "A rectangular steel crate."
- icon = 'icons/obj/storage.dmi'
- icon_state = "crate"
- icon_living = "crate"
-
- faction = "mimic"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 250
- health = 250
- speed = 4
- move_to_delay = 8
-
- response_help = "touches"
- response_disarm = "pushes"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 8
- melee_damage_upper = 12
- attacktext = list("attacked")
- attack_sound = 'sound/weapons/bite.ogg'
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
-
-/mob/living/simple_animal/hostile/mimic/set_target()
- . = ..()
- if(.)
- audible_emote("growls at [.]")
-
-/mob/living/simple_animal/hostile/mimic/death()
- ..()
- qdel(src)
-
-/mob/living/simple_animal/hostile/mimic/will_show_tooltip()
- return FALSE
-
-
-//
-// Crate Mimic
-//
-
-// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
-/mob/living/simple_animal/hostile/mimic/crate
-
- attacktext = list("bitten")
-
- stop_automated_movement = 1
- wander = 0
- var/attempt_open = 0
-
-// Pickup loot
-/mob/living/simple_animal/hostile/mimic/crate/Initialize()
- . = ..()
- for(var/obj/item/I in loc)
- I.forceMove(src)
-
-/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings()
- ..()
- if(prob(90))
- icon_state = "[initial(icon_state)]open"
- else
- icon_state = initial(icon_state)
-
-/mob/living/simple_animal/hostile/mimic/crate/ListTargets()
- if(attempt_open)
- return ..()
- else
- return ..(1)
-
-/mob/living/simple_animal/hostile/mimic/crate/set_target()
- . = ..()
- if(.)
- trigger()
-
-/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
- . = ..()
- if(.)
- icon_state = initial(icon_state)
-
-/mob/living/simple_animal/hostile/mimic/crate/proc/trigger()
- if(!attempt_open)
- visible_message("[src] starts to move!")
- attempt_open = 1
-
-/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage)
- trigger()
- ..(damage)
-
-/mob/living/simple_animal/hostile/mimic/crate/LoseTarget()
- ..()
- icon_state = initial(icon_state)
-
-/mob/living/simple_animal/hostile/mimic/crate/LostTarget()
- ..()
- icon_state = initial(icon_state)
-
-/mob/living/simple_animal/hostile/mimic/crate/death()
- var/obj/structure/closet/crate/C = new(get_turf(src))
- // Put loot in crate
- for(var/obj/O in src)
- O.forceMove(C)
- ..()
-
-/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
- . =..()
- var/mob/living/L = .
- if(istype(L))
- if(prob(15))
- L.Weaken(2)
- L.visible_message("\the [src] knocks down \the [L]!")
-
-//
-// Copy Mimic
-//
-
-var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
-
-/mob/living/simple_animal/hostile/mimic/copy
-
- health = 100
- maxHealth = 100
- var/mob/living/creator = null // the creator
- var/destroy_objects = 0
- var/knockdown_people = 0
-
-/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
- ..(loc)
- CopyObject(copy, creator)
-
-/mob/living/simple_animal/hostile/mimic/copy/death()
-
- for(var/atom/movable/M in src)
- M.forceMove(get_turf(src))
- ..()
-
-/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
- // Return a list of targets that isn't the creator
- . = ..()
- return . - creator
-
-/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
-
- if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
-
- O.forceMove(src)
- name = O.name
- desc = O.desc
- icon = O.icon
- icon_state = O.icon_state
- icon_living = icon_state
-
- if(istype(O, /obj/structure))
- health = (anchored * 50) + 50
- destroy_objects = 1
- if(O.density && O.anchored)
- knockdown_people = 1
- melee_damage_lower *= 2
- melee_damage_upper *= 2
- else if(istype(O, /obj/item))
- var/obj/item/I = O
- health = 15 * I.w_class
- melee_damage_lower = 2 + I.force
- melee_damage_upper = 2 + I.force
- move_to_delay = 2 * I.w_class
-
- maxHealth = health
- if(creator)
- src.creator = creator
- faction = "\ref[creator]" // very unique
- return 1
- return
-
-/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
- if(destroy_objects)
- ..()
-
-/mob/living/simple_animal/hostile/mimic/copy/PunchTarget()
- . =..()
- if(knockdown_people)
- var/mob/living/L = .
- if(istype(L))
- if(prob(15))
- L.Weaken(1)
- L.visible_message("\the [src] knocks down \the [L]!")
diff --git a/code/modules/mob/living/simple_animal/aliens/shade.dm b/code/modules/mob/living/simple_animal/aliens/shade.dm
deleted file mode 100644
index c1c2f1dc01..0000000000
--- a/code/modules/mob/living/simple_animal/aliens/shade.dm
+++ /dev/null
@@ -1,61 +0,0 @@
-/mob/living/simple_animal/shade
- name = "Shade"
- real_name = "Shade"
- desc = "A bound spirit"
- icon = 'icons/mob/mob.dmi'
- icon_state = "shade"
- icon_living = "shade"
- icon_dead = "shade_dead"
-
- faction = "cult"
- intelligence_level = SA_HUMANOID
-
- maxHealth = 50
- health = 50
- speed = -1
-
- response_help = "puts their hand through"
- response_disarm = "flails at"
- response_harm = "punches"
-
- melee_damage_lower = 5
- melee_damage_upper = 15
- attack_armor_pen = 100 //It's a ghost/horror from beyond, I ain't gotta explain 100 AP
- attacktext = list("drained the life from")
-
- minbodytemp = 0
- maxbodytemp = 4000
- min_oxy = 0
- max_co2 = 0
- max_tox = 0
-
- stop_automated_movement = 1
- wander = 0
- status_flags = 0
-
- speak_chance = 5
- universal_speak = 1
- speak_emote = list("hisses")
- emote_hear = list("wails","screeches")
-
- loot_list = list(/obj/item/weapon/ectoplasm = 100)
-
-/mob/living/simple_animal/shade/cultify()
- return
-
-/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/device/soulstone))
- var/obj/item/device/soulstone/S = O;
- S.transfer_soul("SHADE", src, user)
- return
- ..()
-
-/mob/living/simple_animal/shade/death()
- ..()
- for(var/mob/M in viewers(src, null))
- if((M.client && !( M.blinded )))
- M.show_message("[src] lets out a contented sigh as their form unwinds.")
-
- ghostize()
- qdel(src)
- return
diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm
deleted file mode 100644
index f80181bdb0..0000000000
--- a/code/modules/mob/living/simple_animal/aliens/statue.dm
+++ /dev/null
@@ -1,457 +0,0 @@
-// A mob which only moves when it isn't being watched by living beings.
-//Weeping angels/SCP-173 hype
-//Horrible shitcoding and stolen code adaptations below. You have been warned.
-
-/mob/living/simple_animal/hostile/statue
- name = "statue" // matches the name of the statue with the flesh-to-stone spell
- desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description
- icon = 'icons/obj/statue.dmi'
- tt_desc = "angelum weepicus"
- icon_state = "human_male"
- icon_living = "human_male"
- icon_dead = "human_male"
- intelligence_level = SA_HUMANOID
- stop_automated_movement = 1
- var/annoyance = 30 //stop staring you creep
- var/respond = 1
- var/banishable = 0
- faction = "statue"
- mob_size = MOB_HUGE
- response_help = "touches"
- response_disarm = "pushes"
- environment_smash = 2
- can_be_antagged = 1
- speed = -1
- maxHealth = 3000
- health = 3000
- status_flags = CANPUSH
-// investigates = 1
- a_intent = I_HURT
- density = 1
- mob_bump_flag = HEAVY
- mob_push_flags = ~HEAVY
- mob_swap_flags = ~HEAVY
- harm_intent_damage = 60
- melee_damage_lower = 50
- melee_damage_upper = 70
- attacktext = "clawed"
- attack_sound = 'sound/hallucinations/growl1.ogg'
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
- maxbodytemp = 9000
- run_at_them = 0
-
- move_to_delay = 0 // Very fast
-
- animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue.
-
- see_in_dark = 13
- view_range = 35 //So it can run at the victim when out of the view
-
- melee_miss_chance = 0
-
- armor = list(
- "melee" = 30,
- "bullet" = 60,
- "laser" = 80,
- "energy" = 30,
- "bomb" = 30,
- "bio" = 100,
- "rad" = 100)
-
- resistance = 20
-
- see_invisible = SEE_INVISIBLE_NOLIGHTING
- sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
- var/last_hit = 0
- var/cannot_be_seen = 1
- var/mob/living/creator = null
- var/drilled = FALSE
-
-
-// No movement while seen code.
-
-/mob/living/simple_animal/hostile/statue/New(loc)
- ..()
- // Give spells
- add_spell(new/spell/aoe_turf/flicker_lights)
- add_spell(new/spell/aoe_turf/blindness)
- add_spell(new/spell/aoe_turf/shatter)
-
-/mob/living/simple_animal/hostile/statue/DestroySurroundings()
- if(can_be_seen(get_turf(loc)))
- if(client)
- to_chat(src, "You cannot move, there are eyes on you!")
- return 0
- return ..()
-
-/mob/living/simple_animal/hostile/statue/attackby(var/obj/item/O as obj, var/mob/user as mob) //banishing the statue is a risky job
- if(istype(O, /obj/item/weapon/nullrod))
- visible_message("[user] tries to banish [src] with [O]!")
- if(do_after(user, 15, src))
- if(banishable)
- visible_message("[src] crumbles into dust!")
- gib()
- else
- visible_message("[src] is too strong to be banished!")
- Paralyse(rand(8,15))
- if(istype(O, /obj/item/weapon/pickaxe) || istype(O, /obj/item/weapon/pickaxe/plasmacutter) && !drilled)
- drilled = TRUE
- resistance = 0
- spawn(300)
- drilled = FALSE
- resistance = initial(resistance)
- ..()
-
-/mob/living/simple_animal/hostile/statue/death()
- var/chunks_to_spawn = rand(2,5)
- for(var/I = 1 to chunks_to_spawn)
- new /obj/item/stack/material/marble(get_turf(loc))
- new /obj/item/cursed_marble(get_turf(loc))
- ..()
-
-/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc)
- if(can_be_seen(NewLoc))
- if(client)
- to_chat(src, "You cannot move, there are eyes on you!")
- return 0
- return ..()
-
-/mob/living/simple_animal/hostile/statue/Life()
- ..()
- handle_target()
- handleAnnoyance()
- if(target_mob) //if there's a victim, statue will use its powers
- if((annoyance + 4) < 800)
- annoyance += 4
- if(drilled && (annoyance + 4) < 800) //Being hit with a drill makes them weaker, and angrier.
- annoyance += 4
- else if ((annoyance - 2) > 0)
- annoyance -= 2
-
-/mob/living/simple_animal/hostile/statue/proc/handle_target()
- if(target_mob) // If we have a target and we're AI controlled
- var/mob/watching = can_be_seen()
- // If they're not our target
- if(watching && (watching != target_mob))
- // This one is closer.
- if(get_dist(watching, src) > get_dist(target_mob, src))
- LoseTarget()
- target_mob = watching
-
-
-/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance()
- if(respond) //so it won't blind people 24/7
- respond = 0
- if (annoyance > 30)
- AI_blind()
- annoyance -= 30
- if (prob(30) && annoyance > 30)
- var/turf/T = get_turf(loc)
- if(T.get_lumcount() * 10 > 1.5)
- AI_flash()
- annoyance -= 30
- spawn(20)
- respond = 1
-
-
-/mob/living/simple_animal/hostile/statue/proc/AI_blind()
- for(var/mob/living/L in oviewers(12, src)) //the range is so big, because it tries to keep out of sight and can't reengage if you get too far
- if (prob(70))
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if (H.species == "Diona" || H.species == "Promethean" || H == creator)// can't blink and organic
- return
- to_chat(L, pick("Your eyes feel very heavy.", "You blink suddenly!", "Your eyes close involuntarily!"))
- L.Blind(2)
- return
-
-/mob/living/simple_animal/hostile/statue/proc/AI_flash()
- if (prob(60))
- visible_message("The statue slowly points at the light.")
- for(var/obj/machinery/light/L in oview(12, src))
- L.flicker()
- return
-
-
-/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash()
- for(var/obj/structure/mirror/M in oview(4, src))
- if ((!M.shattered )||(!M.glass))
- visible_message("The statue slowly points at the mirror!")
- sleep(5)
- M.shatter()
- return
-
-
-
-/mob/living/simple_animal/hostile/statue/AttackTarget()
- if(can_be_seen(get_turf(loc)))
- if(client)
- to_chat(src, "You cannot attack, there are eyes on you!")
- return
- else
- spawn(3) //a small delay
- ..()
-
-
-
-/mob/living/simple_animal/hostile/statue/DoPunch(var/atom/A) //had to redo that, since it's supposed to target only head and upper body
- if(!Adjacent(A)) // They could've moved in the meantime.
- return FALSE
-
- var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
-
- for(var/datum/modifier/M in modifiers)
- if(!isnull(M.outgoing_melee_damage_percent))
- damage_to_do *= M.outgoing_melee_damage_percent
-
- // SA attacks can be blocked with shields.
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- H.adjustBruteLossByPart(damage_to_do*0.9, pick(BP_HEAD, BP_TORSO))
- playsound(src, attack_sound, 75, 1)
-
- else if(A.attack_generic(src, damage_to_do, pick(attacktext), attack_armor_type, attack_armor_pen, attack_sharp, attack_edge) && attack_sound)
- playsound(src, attack_sound, 75, 1)
-
- return TRUE
-
-
-
-
-
-/mob/living/simple_animal/hostile/statue/face_atom()
- if(!can_be_seen(get_turf(loc)))
- ..()
-
-/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination)
- if(!cannot_be_seen)
- return null
-
- var/turf/T = get_turf(loc)
-/* if(T && destination && T.lighting_overlay)
- if(T.get_lumcount() * 10 < 0.9 && destination.get_lumcount() * 10 < 0.9) // No one can see us in the darkness, right?
- return null
- if(T == destination)
- destination = null*/
-
- // loop for viewers.
- var/list/check_list = list(src)
- if(destination)
- check_list += destination
-//&& (M.see_in_dark > 5)
- // This loop will, at most, loop twice.
- for(var/atom/check in check_list)
- for(var/mob/living/M in viewers(world.view + 1, check) - src)
- if(M != creator)
- if(!(M.sdisabilities & BLIND) || !(M.blinded)) //if not blinded
- if(M.has_vision() && !M.isSynthetic()) //is able to see the statue
- if(T && destination && T.lighting_overlay) // Check for darkness
- if(T.get_lumcount() * 10 < 0.9 && destination.get_lumcount() * 10 < 0.9) // No one can see us in the darkness, right? WRONG! Damn cats.
- if(M.see_in_dark > 5)
- return M
- return null
- return M
- for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
- if(M.occupant && M.occupant.client && M.occupant != creator)
- if(M.occupant.has_vision() && !M.occupant.isSynthetic())
- return M.occupant
- for(var/obj/structure/mirror/M in view(3, check)) //Weeping angels hate mirrors. Probably because they're ugly af
- if ((!M.shattered )||(!M.glass))
- annoyance += 3
- if (prob(5) && (ai_inactive == 0))
- AI_mirrorshmash()
- annoyance -= 50
- return src //if it sees the mirror, it sees itself, right?
- return null
-
-// Cannot talk
-
-/mob/living/simple_animal/hostile/statue/say()
- return 0
-
-// Turn to dust when gibbed
-
-/mob/living/simple_animal/hostile/statue/gib()
- dust()
-
-
-// Stop attacking clientless mobs
-
-/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs
- if(isliving(the_target))
- var/mob/living/L = the_target
- if(!L.client && !L.ckey)
- return 0
- return ..()
-
-// Statue powers
-
-// Flicker lights
-/spell/aoe_turf/flicker_lights
- name = "Flicker Lights"
- desc = "You will trigger a large amount of lights around you to flicker."
- spell_flags = 0
- charge_max = 400
- range = 10
-
-/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr)
- for(var/turf/T in targets)
- for(var/obj/machinery/light/L in T)
- L.flicker()
- return
-
-//Blind AOE
-/spell/aoe_turf/blindness
- name = "Blindness"
- desc = "Your prey will be momentarily blind for you to advance on them."
-
- message = "You glare your eyes."
- charge_max = 250
- spell_flags = 0
- range = 10
-
-/spell/aoe_turf/blindness/cast(list/targets, mob/living/simple_animal/hostile/statue/user = usr)
- for(var/mob/living/L in targets)
- if(L == user || L == user.creator)
- continue
- var/turf/T = get_turf(L.loc)
- if(T && T in targets)
- L.Blind(4)
- return
-
-
-/spell/aoe_turf/shatter
- name = "Shatter mirrors!"
- desc = "That handsome devil has to wait. You have people to make into corpses."
-
- message = "You glare your eyes."
- charge_max = 300
- spell_flags = 0
- range = 8
-
-
-
-
-/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr)
- spawn(50)
- for(var/obj/structure/mirror/M in view(5, src))
- if ((!M.shattered )||(!M.glass))
- M.shatter()
- return
-
-
-
-/mob/living/simple_animal/hostile/statue/verb/toggle_darkness()
- set name = "Toggle Darkness"
- set desc = "You ARE the darkness."
- set category = "Abilities"
- seedarkness = !seedarkness
- plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness)
- to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.")
-
-
-
-/mob/living/simple_animal/hostile/statue/restrained()
- . = ..()
- if(can_be_seen(loc))
- return 1
-
-
-/mob/living/simple_animal/hostile/statue/ListTargets(dist = view_range)
- var/list/L = mobs_in_xray_view(dist, src)
-
- for(var/obj/mecha/M in mechas_list)
- if ((M.z == src.z) && (get_dist(src, M) <= dist) && (isInSight(src,M)))
- L += M
- if(creator)
- L -= creator
-
- return L
-
-
-
-/obj/item/cursed_marble //slime cube copypaste
- name = "marble slab"
- desc = "A peculiar slab of marble, radiating with dark energy."
- icon = 'icons/obj/stacks.dmi'
- icon_state = "sheet-marble"
- description_info = "Summons the Statue - a mysterious powerful creature, that can move only when unsurveyed by living eyes."
- var/searching = 0
-
-/obj/item/cursed_marble/attack_self(mob/user as mob)
- if(!searching)
- to_chat(user, "You rub the slab in hopes a wandering spirit wishes to inhabit it. [src] starts to sparkle!")
- icon_state = "sheet-snowbrick"
- searching = 1
- request_player(user)
- spawn(60 SECONDS)
- reset_search()
-
-
-/obj/item/cursed_marble/proc/request_player(var/mob/user)
- for(var/mob/observer/dead/O in player_list)
- if(!O.MayRespawn())
- continue
- if(O.client)
- if(O.client.prefs.be_special & BE_ALIEN)
- question(O.client, user)
-
-/obj/item/cursed_marble/proc/question(var/client/C, var/mob/user)
- spawn(0)
- if(!C)
- return
- var/response = alert(C, "Someone is requesting a soul for the statue. Would you like to play as one?", "Statue request", "Yes", "No", "Never for this round")
- if(response == "Yes")
- response = alert(C, "Are you sure you want to play as the statue?", "Statue request", "Yes", "No")
- if(!C || 2 == searching)
- return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
- if(response == "Yes")
- transfer_personality(C.mob, user)
- else if(response == "Never for this round")
- C.prefs.be_special ^= BE_ALIEN
-
-/obj/item/cursed_marble/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
- icon_state = "sheet-marble"
- if(searching == 1)
- searching = 0
- var/turf/T = get_turf_or_move(src.loc)
- for (var/mob/M in viewers(T))
- M.show_message("[src] fades. Maybe it will spark another time.")
-
-/obj/item/cursed_marble/proc/transfer_personality(var/mob/candidate, var/mob/user)
- announce_ghost_joinleave(candidate, 0, "They are a statue now.")
- src.searching = 2
- var/mob/living/simple_animal/hostile/statue/S = new(get_turf(src))
- S.client = candidate.client
- if(user)
- S.creator = user
- to_chat(S, "You are \a [S], brought into existence on [station_name()] by [user]! Obey all their orders.")
- S.mind.assigned_role = "The Statue"
- visible_message("The slab suddenly takes the shape of a humanoid!")
- qdel(src)
-
-
-/obj/item/cursed_marble/verb/crush() //if there's no ghosts to respond to your request/you want to use the statue for malicious stuff
- set name = "Crush the marble slab"
- set category = "Object"
- set src in usr
- summonmob(usr)
-
-/obj/item/cursed_marble/proc/summonmob(mob/user as mob)
- if(searching == 0)
- var/choice = alert(user, "Are you sure you want to crush the marble? (this will spawn a clientless version of the statue, hostile to everyone, but you)", "Crush it?", "Yes", "No")
- if(choice)
- if(choice == "Yes")
- var/mob/living/simple_animal/hostile/statue/S = new /mob/living/simple_animal/hostile/statue(get_turf(user))
- visible_message("The slab suddenly takes the shape of a humanoid!")
- S.creator = user
- qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm
deleted file mode 100644
index 680091010e..0000000000
--- a/code/modules/mob/living/simple_animal/animals/bat.dm
+++ /dev/null
@@ -1,85 +0,0 @@
-/mob/living/simple_animal/hostile/scarybat
- name = "space bats"
- desc = "A swarm of cute little blood sucking bats that looks pretty upset."
- tt_desc = "N Bestia gregaria" //Nispean swarm bats, because of course Nisp has swarm bats
- icon = 'icons/mob/bats.dmi'
- icon_state = "bat"
- icon_living = "bat"
- icon_dead = "bat_dead"
- icon_gib = "bat_dead"
-
- faction = "scarybat"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 20
- health = 20
- turns_per_move = 3
- speed = 4
-
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "hits the"
-
- harm_intent_damage = 10
-
- melee_damage_lower = 5
- melee_damage_upper = 5
- attack_sharp = 1
-
- environment_smash = 1
-
- attacktext = list("bites")
- attack_sound = 'sound/weapons/bite.ogg'
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- has_langs = list("Mouse")
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/mob/living/owner
-
-/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
- ..()
- if(istype(L))
- owner = L
-
-/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
- return ..()
-
-/mob/living/simple_animal/hostile/scarybat/set_target()
- . = ..()
- if(.)
- emote("flutters towards [.]")
-
-/mob/living/simple_animal/hostile/scarybat/ListTargets()
- . = ..()
- if(owner)
- return . - owner
-
-/mob/living/simple_animal/hostile/scarybat/PunchTarget()
- . =..()
- var/mob/living/L = .
- if(istype(L))
- if(prob(15))
- L.Stun(1)
- L.visible_message("\the [src] scares \the [L]!")
-
-/mob/living/simple_animal/hostile/scarybat/cult
- faction = "cult"
- supernatural = 1
-
-/mob/living/simple_animal/hostile/scarybat/cult/cultify()
- return
-
-/mob/living/simple_animal/hostile/scarybat/cult/Life()
- ..()
- check_horde()
diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm
deleted file mode 100644
index e399419602..0000000000
--- a/code/modules/mob/living/simple_animal/animals/bear.dm
+++ /dev/null
@@ -1,141 +0,0 @@
-//Space bears!
-/mob/living/simple_animal/hostile/bear
- name = "space bear"
- desc = "A product of Space Russia?"
- tt_desc = "U Ursinae aetherius" //...bearspace? Maybe.
- icon_state = "bear"
- icon_living = "bear"
- icon_dead = "bear_dead"
- icon_gib = "bear_gib"
-
- faction = "russian"
- intelligence_level = SA_ANIMAL
- cooperative = 1
-
- maxHealth = 120
- health = 120
- turns_per_move = 5
- see_in_dark = 6
- stop_when_pulled = 0
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "pokes"
-
- melee_damage_lower = 20
- melee_damage_upper = 30
- attack_sharp = 1
- attack_edge = 1
-
- //Space bears aren't affected by atmos.
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- speak_chance = 1
- speak = list("RAWR!","Rawr!","GRR!","Growl!")
- speak_emote = list("growls", "roars")
- emote_hear = list("rawrs","grumbles","grawls")
- emote_see = list("stares ferociously", "stomps")
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
-
-// var/stance_step = 0
-
-/mob/living/simple_animal/hostile/bear/handle_stance(var/new_stance)
- // Below was a bunch of code that made this specific mob be 'alert' and will hurt you when it gets closer.
- // It's commented out because it made infinite loops and the AI is going to be moved/rewritten sometime soon (famous last words)
- // and it would be better if this 'alert before attacking' behaviour was on the parent instead of a specific type of mob anyways.
-
- // Instead we're just gonna get angry if we're dying.
- ..(new_stance)
- if(stance == STANCE_ATTACK || stance == STANCE_ATTACKING)
- if((health / maxHealth) <= 0.5) // At half health, and fighting someone currently.
- add_modifier(/datum/modifier/berserk, 30 SECONDS)
-
- /*
- switch(stance)
- if(STANCE_TIRED)
- stop_automated_movement = 1
- stance_step++
- if(stance_step >= 10) //rests for 10 ticks
- if(target_mob && target_mob in ListTargets(10))
- handle_stance(STANCE_ATTACK) //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
- else
- handle_stance(STANCE_IDLE)
-
- if(STANCE_ALERT)
- stop_automated_movement = 1
- var/found_mob = 0
- if(target_mob && target_mob in ListTargets(10))
- if(!(SA_attackable(target_mob)))
- stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
- stance_step++
- found_mob = 1
- src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
-
- if(stance_step in list(1,4,7)) //every 3 ticks
- var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
- if(action)
- custom_emote(1,action)
- if(!found_mob)
- stance_step--
-
- if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
- handle_stance(STANCE_IDLE)
- if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
- handle_stance(STANCE_ATTACK)
-
- if(STANCE_ATTACKING)
- if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
- custom_emote(1, "is worn out and needs to rest." )
- handle_stance(STANCE_TIRED)
- stance_step = 0
- walk(src, 0) //This stops the bear's walking
- return
- else
- ..()
- */
-
-/mob/living/simple_animal/hostile/bear/update_icons()
- ..()
- if(!stat)
- if(loc && istype(loc,/turf/space))
- icon_state = "bear"
- else
- icon_state = "bearfloor"
-
-/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
- return
-
-/mob/living/simple_animal/hostile/bear/FindTarget()
- . = ..()
- if(.)
- custom_emote(1,"stares alertly at [.]")
-// handle_stance(STANCE_ALERT)
-
-/mob/living/simple_animal/hostile/bear/PunchTarget()
- if(!Adjacent(target_mob))
- return
- custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
-
- var/damage = rand(melee_damage_lower, melee_damage_upper)
-
- if(ishuman(target_mob))
- var/mob/living/carbon/human/H = target_mob
- var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
- var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1, edge=1)
- return H
- else if(isliving(target_mob))
- var/mob/living/L = target_mob
- L.adjustBruteLoss(damage)
- return L
- else
- ..()
diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm
deleted file mode 100644
index 7e7ae92876..0000000000
--- a/code/modules/mob/living/simple_animal/animals/carp.dm
+++ /dev/null
@@ -1,93 +0,0 @@
-/mob/living/simple_animal/hostile/carp
- name = "space carp"
- desc = "A ferocious, fang-bearing creature that resembles a fish."
- tt_desc = "U Cyprinus aetherius" //carpspace? maybe
- icon_state = "carp"
- icon_living = "carp"
- icon_dead = "carp_dead"
- icon_gib = "carp_gib"
-
- faction = "carp"
- intelligence_level = SA_ANIMAL
- hovering = TRUE
- maxHealth = 25
- health = 25
- speed = 4
- turns_per_move = 5
-
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "hits the"
-
- harm_intent_damage = 8
- melee_damage_lower = 15
- melee_damage_upper = 15
- attacktext = list("bitten")
- attack_sound = 'sound/weapons/bite.ogg'
-
- //Space carp aren't affected by atmos.
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
-
-/mob/living/simple_animal/hostile/carp/large
- name = "elder carp"
- desc = "An older, more matured carp. Few survive to this age due to their aggressiveness."
- icon = 'icons/mob/64x32.dmi'
- icon_state = "shark"
- icon_living = "shark"
- icon_dead = "shark_dead"
- turns_per_move = 2
- move_to_delay = 2
- mob_size = MOB_LARGE
-
- pixel_x = -16
- old_x = -16
-
- health = 50
- maxHealth = 50
-
-
-/mob/living/simple_animal/hostile/carp/large/huge
- name = "great white carp"
- desc = "A very rare breed of carp- and a very aggressive one."
- icon = 'icons/mob/64x64.dmi'
- icon_dead = "megacarp_dead"
- icon_living = "megacarp"
- icon_state = "megacarp"
- maxHealth = 230
- health = 230
- attack_same = 1
- speed = 1
-
- meat_amount = 10
-
- melee_damage_lower = 15
- melee_damage_upper = 25
- old_y = -16
- pixel_y = -16
-
-/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0)
- return 1 //No drifting in space for space carp! //original comments do not steal
-
-/mob/living/simple_animal/hostile/carp/set_target()
- . = ..()
- if(.)
- custom_emote(1,"nashes at [.]")
-
-/mob/living/simple_animal/hostile/carp/PunchTarget()
- . =..()
- var/mob/living/L = .
- if(istype(L))
- if(prob(15))
- L.Weaken(3)
- L.visible_message("\the [src] knocks down \the [L]!")
-
diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm
deleted file mode 100644
index 140deb0b24..0000000000
--- a/code/modules/mob/living/simple_animal/animals/cat.dm
+++ /dev/null
@@ -1,193 +0,0 @@
-//Cat
-/mob/living/simple_animal/cat
- name = "cat"
- desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
- tt_desc = "E Felis silvestris catus"
- intelligence_level = SA_ANIMAL
- icon_state = "cat2"
- item_state = "cat2"
- icon_living = "[initial(icon_state)]"
- icon_dead = "[initial(icon_state)]_dead"
- icon_rest = "[initial(icon_state)]_rest"
-
- investigates = 1
- specific_targets = 1 //Only targets with Found()
- run_at_them = 0 //DOMESTICATED
- view_range = 5
-
- turns_per_move = 5
- see_in_dark = 6
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
-
- min_oxy = 16 //Require atleast 16kPA oxygen
- minbodytemp = 223 //Below -50 Degrees Celcius
- maxbodytemp = 323 //Above 50 Degrees Celcius
-
- holder_type = /obj/item/weapon/holder/cat
- mob_size = MOB_SMALL
-
- has_langs = list("Cat")
- speak_chance = 1
- speak = list("Meow!","Esp!","Purr!","HSSSSS")
- speak_emote = list("purrs", "meows")
- emote_hear = list("meows","mews")
- emote_see = list("shakes their head", "shivers")
- say_maybe_target = list("Meow?","Mew?","Mao?")
- say_got_target = list("MEOW!","HSSSS!","REEER!")
-
- meat_amount = 1
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/turns_since_scan = 0
- var/mob/flee_target
-
-/mob/living/simple_animal/cat/Life()
- . = ..()
- if(!.) return
-
- if(prob(2)) //spooky
- var/mob/observer/dead/spook = locate() in range(src,5)
- if(spook)
- var/turf/T = spook.loc
- var/list/visible = list()
- for(var/obj/O in T.contents)
- if(!O.invisibility && O.name)
- visible += O
- if(visible.len)
- var/atom/A = pick(visible)
- visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].")
-
- handle_flee_target()
-
-/mob/living/simple_animal/cat/PunchTarget()
- if(ismouse(target_mob))
- var/mob/living/simple_mob/animal/passive/mouse/mouse = target_mob
- mouse.splat()
- visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!"))
- return mouse
- else
- ..()
-
-/mob/living/simple_animal/cat/Found(var/atom/found_atom)
- if(ismouse(found_atom) && SA_attackable(found_atom))
- return found_atom
-
-/mob/living/simple_animal/cat/proc/handle_flee_target()
- //see if we should stop fleeing
- if (flee_target && !(flee_target in ListTargets(view_range)))
- flee_target = null
- GiveUpMoving()
-
- if (flee_target && !stat && !buckled)
- if (resting)
- lay_down()
- if(prob(25)) say("HSSSSS")
- stop_automated_movement = 1
- walk_away(src, flee_target, 7, 2)
-
-/mob/living/simple_animal/cat/react_to_attack(var/atom/A)
- if(A == src) return
- flee_target = A
- turns_since_scan = 5
-
-/mob/living/simple_animal/cat/ex_act()
- . = ..()
- react_to_attack(src.loc)
-
-//Basic friend AI
-/mob/living/simple_animal/cat/fluff
- var/mob/living/carbon/human/friend
- var/befriend_job = null
- var/friend_name = null
-
-/mob/living/simple_animal/cat/fluff/Life()
- . = ..()
- if(!. || ai_inactive || !friend) return
-
- var/friend_dist = get_dist(src,friend)
-
- if (friend_dist <= 4)
- if(stance == STANCE_IDLE)
- if(set_follow(friend))
- handle_stance(STANCE_FOLLOW)
-
- if (friend_dist <= 1)
- if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
- if (prob((friend.stat < DEAD)? 50 : 15))
- var/verb = pick("meows", "mews", "mrowls")
- audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
- else
- if (prob(5))
- visible_emote(pick("nuzzles [friend].",
- "brushes against [friend].",
- "rubs against [friend].",
- "purrs."))
- else if (friend.health <= 50)
- if (prob(10))
- var/verb = pick("meows", "mews", "mrowls")
- audible_emote("[verb] anxiously.")
-
-/mob/living/simple_animal/cat/fluff/verb/become_friends()
- set name = "Become Friends"
- set category = "IC"
- set src in view(1)
-
- if(!friend)
- var/mob/living/carbon/human/H = usr
- if(istype(H) && (!befriend_job || H.job == befriend_job) && (!friend_name || H.real_name == friend_name))
- friend = usr
- . = 1
- else if(usr == friend)
- . = 1 //already friends, but show success anyways
-
- if(.)
- set_dir(get_dir(src, friend))
- visible_emote(pick("nuzzles [friend].",
- "brushes against [friend].",
- "rubs against [friend].",
- "purrs."))
- else
- usr << "[src] ignores you."
- return
-
-//RUNTIME IS ALIVE! SQUEEEEEEEE~
-/mob/living/simple_animal/cat/fluff/Runtime
- name = "Runtime"
- desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
- tt_desc = "E Felis silvestris medicalis" //a hypoallergenic breed produced by NT for... medical purposes? Sure.
- gender = FEMALE
- icon_state = "cat"
- item_state = "cat"
- befriend_job = "Chief Medical Officer"
-
-/mob/living/simple_animal/cat/kitten
- name = "kitten"
- desc = "D'aaawwww"
- icon_state = "kitten"
- item_state = "kitten"
- icon_living = "kitten"
- icon_dead = "kitten_dead"
- gender = NEUTER
-
-// Leaving this here for now.
-/obj/item/weapon/holder/cat/fluff/bones
- name = "Bones"
- desc = "It's Bones! Meow."
- gender = MALE
- icon_state = "cat3"
-
-/mob/living/simple_animal/cat/fluff/bones
- name = "Bones"
- desc = "That's Bones the cat. He's a laid back, black cat. Meow."
- gender = MALE
- icon_state = "cat3"
- item_state = "cat3"
- holder_type = /obj/item/weapon/holder/cat/fluff/bones
- friend_name = "Erstatz Vryroxes"
-
-/mob/living/simple_animal/cat/kitten/New()
- gender = pick(MALE, FEMALE)
- ..()
diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm
deleted file mode 100644
index 6cc1f80523..0000000000
--- a/code/modules/mob/living/simple_animal/animals/corgi.dm
+++ /dev/null
@@ -1,231 +0,0 @@
-//Corgi
-/mob/living/simple_animal/corgi
- name = "corgi"
- real_name = "corgi"
- desc = "It's a corgi."
- tt_desc = "E Canis lupus familiaris"
- intelligence_level = SA_ANIMAL
- icon_state = "corgi"
- icon_living = "corgi"
- icon_dead = "corgi_dead"
-
- run_at_them = 0
- turns_per_move = 10
-
- response_help = "pets"
- response_disarm = "bops"
- response_harm = "kicks"
-
- see_in_dark = 5
- mob_size = 8
-
- has_langs = list("Dog")
- speak_chance = 1
- speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
- speak_emote = list("barks", "woofs")
- emote_hear = list("barks", "woofs", "yaps","pants")
- emote_see = list("shakes its head", "shivers")
-
- meat_amount = 3
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
-
- var/obj/item/inventory_head
- var/obj/item/inventory_back
-
-//IAN! SQUEEEEEEEEE~
-/mob/living/simple_animal/corgi/Ian
- name = "Ian"
- real_name = "Ian" //Intended to hold the name without altering it.
- gender = MALE
- desc = "It's a corgi."
- var/turns_since_scan = 0
- var/obj/movement_target
- response_help = "pets"
- response_disarm = "bops"
- response_harm = "kicks"
-
-/mob/living/simple_animal/corgi/Ian/Life()
- ..()
-
- //Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically.
-
- //Feeding, chasing food, FOOOOODDDD
- if(!stat && !resting && !buckled)
- turns_since_scan++
- if(turns_since_scan > 5)
- turns_since_scan = 0
- if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
- movement_target = null
- stop_automated_movement = 0
- if( !movement_target || !(movement_target.loc in oview(src, 3)) )
- movement_target = null
- stop_automated_movement = 0
- for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3))
- if(isturf(S.loc) || ishuman(S.loc))
- movement_target = S
- break
- if(movement_target)
- stop_automated_movement = 1
- step_to(src,movement_target,1)
- sleep(3)
- step_to(src,movement_target,1)
- sleep(3)
- step_to(src,movement_target,1)
-
- if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
- if (movement_target.loc.x < src.x)
- set_dir(WEST)
- else if (movement_target.loc.x > src.x)
- set_dir(EAST)
- else if (movement_target.loc.y < src.y)
- set_dir(SOUTH)
- else if (movement_target.loc.y > src.y)
- set_dir(NORTH)
- else
- set_dir(SOUTH)
-
- if(isturf(movement_target.loc) )
- UnarmedAttack(movement_target)
- else if(ishuman(movement_target.loc) && prob(20))
- visible_emote("stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.")
-
- if(prob(1))
- visible_emote(pick("dances around","chases their tail"))
- spawn(0)
- for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
- set_dir(i)
- sleep(1)
-
-/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
- name = "corgi meat"
- desc = "Tastes like... well, you know..."
-
-/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
- if(istype(O, /obj/item/weapon/newspaper))
- if(!stat)
- for(var/mob/M in viewers(user, null))
- if ((M.client && !( M.blinded )))
- M.show_message("[user] baps [name] on the nose with the rolled up [O]")
- spawn(0)
- for(var/i in list(1,2,4,8,4,2,1,2))
- set_dir(i)
- sleep(1)
- else
- ..()
-
-/mob/living/simple_animal/corgi/regenerate_icons()
- overlays = list()
-
- if(inventory_head)
- var/head_icon_state = inventory_head.icon_state
- if(health <= 0)
- head_icon_state += "2"
-
- var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state)
- if(head_icon)
- overlays += head_icon
-
- if(inventory_back)
- var/back_icon_state = inventory_back.icon_state
- if(health <= 0)
- back_icon_state += "2"
-
- var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
- if(back_icon)
- overlays += back_icon
-
- return
-
-
-/mob/living/simple_animal/corgi/puppy
- name = "corgi puppy"
- real_name = "corgi"
- desc = "It's a corgi puppy."
- icon_state = "puppy"
- icon_living = "puppy"
- icon_dead = "puppy_dead"
-
-//pupplies cannot wear anything.
-/mob/living/simple_animal/corgi/puppy/Topic(href, href_list)
- if(href_list["remove_inv"] || href_list["add_inv"])
- usr << "You can't fit this on [src]"
- return
- ..()
-
-
-//LISA! SQUEEEEEEEEE~
-/mob/living/simple_animal/corgi/Lisa
- name = "Lisa"
- real_name = "Lisa"
- gender = FEMALE
- desc = "It's a corgi with a cute pink bow."
- icon_state = "lisa"
- icon_living = "lisa"
- icon_dead = "lisa_dead"
- response_help = "pets"
- response_disarm = "bops"
- response_harm = "kicks"
- var/turns_since_scan = 0
- var/puppies = 0
-
-//Lisa already has a cute bow!
-/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list)
- if(href_list["remove_inv"] || href_list["add_inv"])
- to_chat(usr, "[src] already has a cute bow!")
- return
- ..()
-
-/mob/living/simple_animal/corgi/Lisa/Life()
- ..()
-
- if(!stat && !resting && !buckled)
- turns_since_scan++
- if(turns_since_scan > 15)
- turns_since_scan = 0
- var/alone = 1
- var/ian = 0
- for(var/mob/M in oviewers(7, src))
- if(istype(M, /mob/living/simple_animal/corgi/Ian))
- if(M.client)
- alone = 0
- break
- else
- ian = M
- else
- alone = 0
- break
- if(alone && ian && puppies < 4)
- if(near_camera(src) || near_camera(ian))
- return
- new /mob/living/simple_animal/corgi/puppy(loc)
-
-
- if(prob(1))
- visible_emote(pick("dances around","chases her tail"))
- spawn(0)
- for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
- set_dir(i)
- sleep(1)
-
-
-//Technically this should be like, its own file or something or a subset of dog but whatever. Not a coder.
-/mob/living/simple_animal/corgi/tamaskan
- name = "tamaskan"
- real_name = "tamaskan"
- desc = "It's a tamaskan."
- icon_state = "tamaskan"
- icon_living = "tamaskan"
- icon_dead = "tamaskan_dead"
-
- retaliate = 1 //Tamaskans are bigass dogs, okay?
-
-/mob/living/simple_animal/corgi/tamaskan/spice
- name = "Spice"
- real_name = "Spice" //Intended to hold the name without altering it.
- gender = FEMALE
- desc = "It's a tamaskan, the name Spice can be found on its collar."
- var/turns_since_scan = 0
- var/obj/movement_target
- response_help = "pets"
- response_disarm = "bops"
- response_harm = "kicks"
diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm
deleted file mode 100644
index c369aa375a..0000000000
--- a/code/modules/mob/living/simple_animal/animals/crab.dm
+++ /dev/null
@@ -1,87 +0,0 @@
-//Look Sir, free crabs!
-/mob/living/simple_animal/crab
- name = "crab"
- desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
- tt_desc = "E Cancer bellianus"
- icon_state = "crab"
- icon_living = "crab"
- icon_dead = "crab_dead"
- faction = "crabs"
- intelligence_level = SA_ANIMAL
-
- wander = 0
- stop_automated_movement = 1
- turns_per_move = 5
- mob_size = MOB_SMALL
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "stomps"
- friendly = "pinches"
-
- speak_chance = 1
- speak_emote = list("clicks")
- emote_hear = list("clicks")
- emote_see = list("clacks")
-
- var/obj/item/inventory_head
- var/obj/item/inventory_mask
-
-/mob/living/simple_animal/crab/Life()
- ..()
- //CRAB movement, I'm not porting this up to SA because... "sideways-only movement" var nothanks
- if(!ckey && !stat)
- if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
- lifes_since_move++
- if(lifes_since_move >= turns_per_move)
- Move(get_step(src,pick(4,8)))
- lifes_since_move = 0
- regenerate_icons()
-
-//COFFEE! SQUEEEEEEEEE!
-/mob/living/simple_animal/crab/Coffee
- name = "Coffee"
- real_name = "Coffee"
- desc = "It's Coffee, the other pet!"
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "stomps"
-
-//Sif Crabs
-/mob/living/simple_animal/giant_crab
- name = "giant crab"
- desc = "A large, hard-shelled crustacean. This one is mostly grey."
- tt_desc = "S Cancer holligus"
- icon_state = "sif_crab"
- icon_living = "sif_crab"
- icon_dead = "sif_crab_dead"
- faction = "crabs"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 200
- health = 200
-
- mob_size = MOB_LARGE
- cooperative = 1
- retaliate = 1
- turns_per_move = 3
-
- minbodytemp = 175
-
- melee_damage_lower = 22
- melee_damage_upper = 35
- attack_armor_pen = 35
- attack_sharp = 1
- attack_edge = 1
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "stomps"
- friendly = "pinches"
-
- speak_chance = 1
- speak_emote = list("clicks")
- emote_hear = list("clicks")
- emote_see = list("clacks")
diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm
deleted file mode 100644
index 534bbf6000..0000000000
--- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm
+++ /dev/null
@@ -1,292 +0,0 @@
-//goat
-/mob/living/simple_animal/retaliate/goat
- name = "goat"
- desc = "Not known for their pleasant disposition."
- tt_desc = "E Oreamnos americanus"
- icon_state = "goat"
- icon_living = "goat"
- icon_dead = "goat_dead"
-
- faction = "goat"
- intelligence_level = SA_ANIMAL
-
- health = 40
- turns_per_move = 5
- see_in_dark = 6
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
-
- melee_damage_lower = 1
- melee_damage_upper = 5
- attacktext = list("kicked")
-
- speak_chance = 1
- speak = list("EHEHEHEHEH","eh?")
- speak_emote = list("brays")
- emote_hear = list("brays")
- emote_see = list("shakes its head", "stamps a foot", "glares around")
-
- meat_amount = 4
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/datum/reagents/udder = null
-
-/mob/living/simple_animal/retaliate/goat/New()
- udder = new(50)
- udder.my_atom = src
- ..()
-
-/mob/living/simple_animal/retaliate/goat/Life()
- . = ..()
- if(.)
- if(stat == CONSCIOUS)
- if(udder && prob(5))
- udder.add_reagent("milk", rand(5, 10))
-
- if(locate(/obj/effect/plant) in loc)
- var/obj/effect/plant/SV = locate() in loc
- SV.die_off(1)
-
- if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc)
- var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc
- qdel(SP)
-
- if(!pulledby)
- var/obj/effect/plant/food
- food = locate(/obj/effect/plant) in oview(5,loc)
- if(food)
- var/step = get_step_to(src, food, 0)
- Move(step)
-
-/mob/living/simple_animal/retaliate/goat/react_to_attack()
- . = ..()
- if(.)
- visible_message("[src] gets an evil-looking gleam in their eye.")
-
-/mob/living/simple_animal/retaliate/goat/Move()
- ..()
- if(!stat)
- for(var/obj/effect/plant/SV in loc)
- SV.die_off(1)
-
-/mob/living/simple_animal/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
- var/obj/item/weapon/reagent_containers/glass/G = O
- if(stat == CONSCIOUS && istype(G) && G.is_open_container())
- user.visible_message("[user] milks [src] using \the [O].")
- var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
- if(G.reagents.total_volume >= G.volume)
- user << "The [O] is full."
- if(!transfered)
- user << "The udder is dry. Wait a bit longer..."
- else
- ..()
-//cow
-/mob/living/simple_animal/cow
- name = "cow"
- desc = "Known for their milk, just don't tip them over."
- tt_desc = "E Bos taurus"
- icon_state = "cow"
- icon_living = "cow"
- icon_dead = "cow_dead"
- icon_gib = "cow_gib"
- intelligence_level = SA_ANIMAL
-
- health = 50
- turns_per_move = 5
- see_in_dark = 6
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
- attacktext = list("kicked")
-
- speak_chance = 1
- speak = list("moo?","moo","MOOOOOO")
- speak_emote = list("moos","moos hauntingly")
- emote_hear = list("brays")
- emote_see = list("shakes its head")
-
- meat_amount = 6
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/datum/reagents/udder = null
-
-/mob/living/simple_animal/cow/New()
- udder = new(50)
- udder.my_atom = src
- ..()
-
-/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob)
- var/obj/item/weapon/reagent_containers/glass/G = O
- if(stat == CONSCIOUS && istype(G) && G.is_open_container())
- user.visible_message("[user] milks [src] using \the [O].")
- var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
- if(G.reagents.total_volume >= G.volume)
- user << "The [O] is full."
- if(!transfered)
- user << "The udder is dry. Wait a bit longer..."
- else
- ..()
-
-/mob/living/simple_animal/cow/Life()
- . = ..()
- if(stat == CONSCIOUS)
- if(udder && prob(5))
- udder.add_reagent("milk", rand(5, 10))
-
-/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
- if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead)
- M.visible_message("[M] tips over [src].","You tip over [src].")
- Weaken(30)
- icon_state = icon_dead
- spawn(rand(20,50))
- if(!stat && M)
- icon_state = icon_living
- var/list/responses = list( "[src] looks at you imploringly.",
- "[src] looks at you pleadingly",
- "[src] looks at you with a resigned expression.",
- "[src] seems resigned to its fate.")
- M << pick(responses)
- else
- ..()
-
-/mob/living/simple_animal/chick
- name = "\improper chick"
- desc = "Adorable! They make such a racket though."
- tt_desc = "E Gallus gallus"
- icon_state = "chick"
- icon_living = "chick"
- icon_dead = "chick_dead"
- icon_gib = "chick_gib"
- intelligence_level = SA_ANIMAL
-
- health = 1
- turns_per_move = 2
-
- pass_flags = PASSTABLE | PASSGRILLE
- mob_size = MOB_MINISCULE
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
- attacktext = list("kicked")
-
- has_langs = list("Bird")
- speak_chance = 2
- speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
- speak_emote = list("cheeps")
- emote_hear = list("cheeps")
- emote_see = list("pecks at the ground","flaps its tiny wings")
-
- meat_amount = 1
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/amount_grown = 0
-
-/mob/living/simple_animal/chick/New()
- ..()
- pixel_x = rand(-6, 6)
- pixel_y = rand(0, 10)
-
-/mob/living/simple_animal/chick/Life()
- . =..()
- if(!.)
- return
- if(!stat)
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- new /mob/living/simple_animal/chicken(src.loc)
- qdel(src)
-
-var/const/MAX_CHICKENS = 50
-var/global/chicken_count = 0
-
-/mob/living/simple_animal/chicken
- name = "\improper chicken"
- desc = "Hopefully the eggs are good this season."
- tt_desc = "E Gallus gallus"
- icon_state = "chicken"
- icon_living = "chicken"
- icon_dead = "chicken_dead"
- intelligence_level = SA_ANIMAL
-
- health = 10
- turns_per_move = 3
- pass_flags = PASSTABLE
- mob_size = MOB_SMALL
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
- attacktext = list("kicked")
-
- has_langs = list("Bird")
- speak_chance = 2
- speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
- speak_emote = list("clucks","croons")
- emote_hear = list("clucks")
- emote_see = list("pecks at the ground","flaps its wings viciously")
-
- meat_amount = 2
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/eggsleft = 0
- var/body_color
-
-/mob/living/simple_animal/chicken/New()
- ..()
- if(!body_color)
- body_color = pick( list("brown","black","white") )
- icon_state = "chicken_[body_color]"
- icon_living = "chicken_[body_color]"
- icon_dead = "chicken_[body_color]_dead"
- pixel_x = rand(-6, 6)
- pixel_y = rand(0, 10)
- chicken_count += 1
-
-/mob/living/simple_animal/chicken/death()
- ..()
- chicken_count -= 1
-
-/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens
- var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
- if(G.seed && G.seed.kitchen_tag == "wheat")
- if(!stat && eggsleft < 8)
- user.visible_message("[user] feeds [O] to [name]! It clucks happily.","You feed [O] to [name]! It clucks happily.")
- user.drop_item()
- qdel(O)
- eggsleft += rand(1, 4)
- else
- user << "[name] doesn't seem hungry!"
- else
- user << "[name] doesn't seem interested in that."
- else
- ..()
-
-/mob/living/simple_animal/chicken/Life()
- . =..()
- if(!.)
- return
- if(!stat && prob(3) && eggsleft > 0)
- visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
- eggsleft--
- var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src))
- E.pixel_x = rand(-6,6)
- E.pixel_y = rand(-6,6)
- if(chicken_count < MAX_CHICKENS && prob(10))
- START_PROCESSING(SSobj, E)
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
-/obj/item/weapon/reagent_containers/food/snacks/egg/process()
- if(isturf(loc))
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- visible_message("[src] hatches with a quiet cracking sound.")
- new /mob/living/simple_animal/chick(get_turf(src))
- STOP_PROCESSING(SSobj, src)
- qdel(src)
- else
- STOP_PROCESSING(SSobj, src)
diff --git a/code/modules/mob/living/simple_animal/animals/fish.dm b/code/modules/mob/living/simple_animal/animals/fish.dm
deleted file mode 100644
index 547b095bfd..0000000000
--- a/code/modules/mob/living/simple_animal/animals/fish.dm
+++ /dev/null
@@ -1,80 +0,0 @@
-// Different types of fish! They are all subtypes of this tho
-/mob/living/simple_animal/fish
- name = "fish"
- desc = "Its a fishy. No touchy fishy."
- icon = 'icons/mob/fish.dmi'
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
- intelligence_level = SA_ANIMAL
-
- // By defautl they can be in any water turf. Subtypes might restrict to deep/shallow etc
- var/global/list/suitable_turf_types = list(
- /turf/simulated/floor/beach/water,
- /turf/simulated/floor/beach/coastline,
- /turf/simulated/floor/holofloor/beach/water,
- /turf/simulated/floor/holofloor/beach/coastline,
- /turf/simulated/floor/water
- )
-
-// Don't swim out of the water
-/mob/living/simple_animal/fish/handle_wander_movement()
- if(isturf(src.loc) && !resting && !buckled && canmove) //Physically capable of moving?
- lifes_since_move++ //Increment turns since move (turns are life() cycles)
- if(lifes_since_move >= turns_per_move)
- if(!(stop_when_pulled && pulledby)) //Some animals don't move when pulled
- var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
- moving_to = pick(cardinal)
- dir = moving_to //How about we turn them the direction they are moving, yay.
- var/turf/T = get_step(src,moving_to)
- if(T && is_type_in_list(T, suitable_turf_types))
- Move(T)
- lifes_since_move = 0
-
-// Take damage if we are not in water
-/mob/living/simple_animal/fish/handle_breathing()
- var/turf/T = get_turf(src)
- if(T && !is_type_in_list(T, suitable_turf_types))
- if(prob(50))
- say(pick("Blub", "Glub", "Burble"))
- adjustBruteLoss(unsuitable_atoms_damage)
-
-/mob/living/simple_animal/fish/bass
- name = "bass"
- tt_desc = "E Micropterus notius"
- icon_state = "bass-swim"
- icon_living = "bass-swim"
- icon_dead = "bass-dead"
-
-/mob/living/simple_animal/fish/trout
- name = "trout"
- tt_desc = "E Salmo trutta"
- icon_state = "trout-swim"
- icon_living = "trout-swim"
- icon_dead = "trout-dead"
-
-/mob/living/simple_animal/fish/salmon
- name = "salmon"
- tt_desc = "E Oncorhynchus nerka"
- icon_state = "salmon-swim"
- icon_living = "salmon-swim"
- icon_dead = "salmon-dead"
-
-/mob/living/simple_animal/fish/perch
- name = "perch"
- tt_desc = "E Perca flavescens"
- icon_state = "perch-swim"
- icon_living = "perch-swim"
- icon_dead = "perch-dead"
-
-/mob/living/simple_animal/fish/pike
- name = "pike"
- tt_desc = "E Esox aquitanicus"
- icon_state = "pike-swim"
- icon_living = "pike-swim"
- icon_dead = "pike-dead"
-
-/mob/living/simple_animal/fish/koi
- name = "koi"
- tt_desc = "E Cyprinus rubrofuscus"
- icon_state = "koi-swim"
- icon_living = "koi-swim"
- icon_dead = "koi-dead"
diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm
deleted file mode 100644
index 587edeb0f8..0000000000
--- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm
+++ /dev/null
@@ -1,580 +0,0 @@
-
-#define SPINNING_WEB 1
-#define LAYING_EGGS 2
-#define MOVING_TO_TARGET 3
-#define SPINNING_COCOON 4
-
-//basic spider mob, these generally guard nests
-/mob/living/simple_animal/hostile/giant_spider
- name = "giant spider"
- desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes."
- tt_desc = "X Brachypelma phorus"
- icon_state = "guard"
- icon_living = "guard"
- icon_dead = "guard_dead"
-
- faction = "spiders"
- intelligence_level = SA_ANIMAL
- maxHealth = 200
- health = 200
- pass_flags = PASSTABLE
- move_to_delay = 6
- speed = 3
-
- stop_when_pulled = 0
- turns_per_move = 5
- see_in_dark = 10
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "punches"
-
- melee_damage_lower = 18
- melee_damage_upper = 30
- attack_sharp = 1
- attack_edge = 1
-
- heat_damage_per_tick = 20
- cold_damage_per_tick = 20
-
- speak_chance = 5
- speak_emote = list("chitters")
- emote_hear = list("chitters")
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat
-
- var/busy = 0
- var/poison_per_bite = 5
- var/poison_chance = 10
- var/poison_type = "spidertoxin"
- var/image/eye_layer = null
-
-/mob/living/simple_animal/hostile/giant_spider/proc/add_eyes()
- if(!eye_layer)
- eye_layer = image(icon, "[icon_state]-eyes")
- eye_layer.plane = PLANE_LIGHTING_ABOVE
-
- overlays += eye_layer
-
-/mob/living/simple_animal/hostile/giant_spider/proc/remove_eyes()
- overlays -= eye_layer
-
-/*
-Nurse Family
-*/
-
-//nursemaids - these create webs and eggs
-/mob/living/simple_animal/hostile/giant_spider/nurse
- desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes."
- tt_desc = "X Brachypelma phorus laetus"
- icon_state = "nurse"
- icon_living = "nurse"
- icon_dead = "nurse_dead"
-
- maxHealth = 40
- health = 40
-
- melee_damage_lower = 8
- melee_damage_upper = 15
- poison_per_bite = 7
- poison_type = "stoxin"
-
- var/fed = 0
- var/atom/cocoon_target
- var/egg_inject_chance = 5
-
-/mob/living/simple_animal/hostile/giant_spider/nurse/hat
- desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes and a tiny nurse hat"
- icon_state = "nursemed"
- icon_living = "nursemed"
- icon_dead = "nursemed_dead"
-
- maxHealth = 50
- health = 50
-
-/mob/living/simple_animal/hostile/giant_spider/nurse/queen
- desc = "Absolutely gigantic, this creature is horror itself."
- tt_desc = "X Brachypelma phorus tyrannus"
- icon = 'icons/mob/64x64.dmi'
- icon_state = "spider_queen"
- icon_living = "spider_queen"
- icon_dead = "spider_queen_dead"
-
- maxHealth = 320
- health = 320
-
- melee_damage_lower = 20
- melee_damage_upper = 30
- attack_armor_pen = 25
-
- poison_per_bite = 10
- egg_inject_chance = 10
-
- pixel_x = -16
- pixel_y = -16
- old_x = -16
- old_y = -16
-
-/mob/living/simple_animal/hostile/giant_spider/webslinger
- desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes, and a cloak of web."
- tt_desc = "X Brachypelma phorus balisticus"
- icon_state = "webslinger"
- icon_living = "webslinger"
- icon_dead = "webslinger_dead"
-
- maxHealth = 90
- health = 90
-
- projectilesound = 'sound/weapons/thudswoosh.ogg'
- projectiletype = /obj/item/projectile/bola
- ranged = 1
- firing_lines = 1
- cooperative = 1
- shoot_range = 5
-
- melee_damage_lower = 8
- melee_damage_upper = 15
- poison_per_bite = 2
- poison_type = "psilocybin"
-
- spattack_prob = 15
- spattack_min_range = 0
- spattack_max_range = 5
-
-/mob/living/simple_animal/hostile/giant_spider/webslinger/AttackTarget() //One day.
- var/mob/living/carbon/human/victim = null //Webslinger needs to know if its target is human later.
- if(ishuman(target_mob))
- victim = target_mob
- if(!victim.legcuffed)
- projectiletype = /obj/item/projectile/bola
- shoot_range = 7
- else
- projectiletype = /obj/item/projectile/webball
- shoot_range = 5
- else
- projectiletype = /obj/item/projectile/webball
- shoot_range = 5
- return ..()
-
-/mob/living/simple_animal/hostile/giant_spider/carrier
- desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes."
- tt_desc = "X Brachypelma phorus gerulus"
- icon_state = "carrier"
- icon_living = "carrier"
- icon_dead = "carrier_dead"
-
- maxHealth = 100
- health = 100
-
- melee_damage_lower = 8
- melee_damage_upper = 25
-
- poison_per_bite = 3
- poison_type = "chloralhydrate"
-
- var/spiderling_count = 0
- var/spiderling_type = /obj/effect/spider/spiderling
- var/swarmling_type = /mob/living/simple_animal/hostile/giant_spider/hunter
- var/swarmling_faction = "spiders"
-
-/mob/living/simple_animal/hostile/giant_spider/carrier/New()
- spiderling_count = rand(5,10)
- adjust_scale(1.2)
- ..()
-
-/mob/living/simple_animal/hostile/giant_spider/carrier/death()
- visible_message("\The [src]'s abdomen splits as it rolls over, spiderlings crawling from the wound.")
- spawn(1)
- for(var/I = 1 to spiderling_count)
- if(prob(10) && src)
- var/mob/living/simple_animal/hostile/giant_spider/swarmling = new swarmling_type(src.loc)
- var/swarm_health = FLOOR(swarmling.maxHealth * 0.4, 1)
- var/swarm_dam_lower = FLOOR(melee_damage_lower * 0.4, 1)
- var/swarm_dam_upper = FLOOR(melee_damage_upper * 0.4, 1)
- swarmling.name = "spiderling"
- swarmling.maxHealth = swarm_health
- swarmling.health = swarm_health
- swarmling.melee_damage_lower = swarm_dam_lower
- swarmling.melee_damage_upper = swarm_dam_upper
- swarmling.faction = swarmling_faction
- swarmling.adjust_scale(0.75)
- else if(src)
- var/obj/effect/spider/spiderling/child = new spiderling_type(src.loc)
- child.skitter()
- else
- break
- return ..()
-
-/mob/living/simple_animal/hostile/giant_spider/carrier/recursive
- desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes. You have a distinctly bad feeling about this."
-
- swarmling_type = /mob/living/simple_animal/hostile/giant_spider/carrier/recursive
-
-/*
-Hunter Family
-*/
-
-//hunters have the most poison and move the fastest, so they can find prey
-
-/mob/living/simple_animal/hostile/giant_spider/hunter
- desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
- tt_desc = "X Brachypelma phorus venandi"
- icon_state = "hunter"
- icon_living = "hunter"
- icon_dead = "hunter_dead"
-
- maxHealth = 120
- health = 120
- move_to_delay = 4
-
- poison_per_bite = 5
-
-/mob/living/simple_animal/hostile/giant_spider/lurker
- desc = "Translucent and white, it makes you shudder to look at it. This one has incandescent red eyes."
- tt_desc = "X Brachypelma phorus insidator"
- icon_state = "lurker"
- icon_living = "lurker"
- icon_dead = "lurker_dead"
- alpha = 45
-
- maxHealth = 100
- health = 100
- move_to_delay = 4
-
- melee_damage_lower = 8
- melee_damage_upper = 20
-
-
- poison_chance = 20
- poison_type = "cryptobiolin"
- poison_per_bite = 2
-
-/mob/living/simple_animal/hostile/giant_spider/lurker/death()
- alpha = 255
- return ..()
-
-/mob/living/simple_animal/hostile/giant_spider/tunneler
- desc = "Sandy and brown, it makes you shudder to look at it. This one has glittering yellow eyes."
- tt_desc = "X Brachypelma phorus cannalis"
- icon_state = "tunneler"
- icon_living = "tunneler"
- icon_dead = "tunneler_dead"
-
- maxHealth = 120
- health = 120
- move_to_delay = 4
-
- melee_damage_lower = 10
- melee_damage_upper = 20
-
- poison_chance = 15
- poison_per_bite = 3
- poison_type = "serotrotium_v"
-
-/mob/living/simple_animal/hostile/giant_spider/tunneler/death()
- spawn(1)
- for(var/I = 1 to rand(3,6))
- if(src)
- new/obj/item/weapon/ore/glass(src.loc)
- else
- break
- return ..()
-
-/*
-Guard Family
-*/
-
-/mob/living/simple_animal/hostile/giant_spider/pepper
- desc = "Red and brown, it makes you shudder to look at it. This one has glinting red eyes."
- tt_desc = "X Brachypelma phorus ignis"
- icon_state = "pepper"
- icon_living = "pepper"
- icon_dead = "pepper_dead"
-
- maxHealth = 210
- health = 210
-
- melee_damage_lower = 8
- melee_damage_upper = 15
-
- poison_chance = 20
- poison_per_bite = 5
- poison_type = "condensedcapsaicin_v"
-
-/mob/living/simple_animal/hostile/giant_spider/pepper/New()
- adjust_scale(1.1)
- ..()
-
-/mob/living/simple_animal/hostile/giant_spider/thermic
- desc = "Mirage-cloaked and orange, it makes you shudder to look at it. This one has simmering orange eyes."
- tt_desc = "X Brachypelma phorus incaendium"
- icon_state = "pit"
- icon_living = "pit"
- icon_dead = "pit_dead"
-
- maxHealth = 175
- health = 175
-
- melee_damage_lower = 10
- melee_damage_upper = 25
-
- poison_chance = 30
- poison_per_bite = 1
- poison_type = "thermite_v"
-
-/mob/living/simple_animal/hostile/giant_spider/electric
- desc = "Spined and yellow, it makes you shudder to look at it. This one has flickering gold eyes."
- tt_desc = "X Brachypelma phorus aromatitis"
- icon_state = "spark"
- icon_living = "spark"
- icon_dead = "spark_dead"
-
- maxHealth = 210
- health = 210
- taser_kill = 0 //It -is- the taser.
-
- melee_damage_lower = 10
- melee_damage_upper = 25
-
- ranged = 1
- projectilesound = 'sound/weapons/taser2.ogg'
- projectiletype = /obj/item/projectile/beam/stun/weak
- firing_lines = 1
- cooperative = 1
-
- poison_chance = 15
- poison_per_bite = 3
- poison_type = "stimm"
-
-/mob/living/simple_animal/hostile/giant_spider/phorogenic
- desc = "Crystalline and purple, it makes you shudder to look at it. This one has haunting purple eyes."
- tt_desc = "X Brachypelma phorus phorus"
- icon_state = "phoron"
- icon_living = "phoron"
- icon_dead = "phoron_dead"
-
- maxHealth = 225
- health = 225
- taser_kill = 0 //You will need more than a peashooter to kill the juggernaut.
-
- melee_damage_lower = 25
- melee_damage_upper = 40
- attack_armor_pen = 15
-
- poison_chance = 30
- poison_per_bite = 0.5
- poison_type = "phoron"
-
- var/exploded = 0
-
-/mob/living/simple_animal/hostile/giant_spider/phorogenic/New()
- adjust_scale(1.25)
- return ..()
-
-/mob/living/simple_animal/hostile/giant_spider/phorogenic/death()
- visible_message("\The [src]'s body begins to rupture!")
- spawn(rand(1,5))
- if(src && !exploded)
- visible_message("\The [src]'s body detonates!")
- exploded = 1
- explosion(src.loc, 1, 2, 4, 6)
- return ..()
-
-/mob/living/simple_animal/hostile/giant_spider/frost
- desc = "Icy and blue, it makes you shudder to look at it. This one has brilliant blue eyes."
- tt_desc = "X Brachypelma phorus pruinae"
- icon_state = "frost"
- icon_living = "frost"
- icon_dead = "frost_dead"
-
- maxHealth = 175
- health = 175
-
- poison_per_bite = 5
- poison_type = "cryotoxin"
-
-/*
-Spider Procs
-*/
-
-/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent)
- get_light_and_color(parent)
- add_eyes()
- ..()
-
-/mob/living/simple_animal/hostile/giant_spider/death()
- remove_eyes()
- ..()
-
-/mob/living/simple_animal/hostile/giant_spider/DoPunch(var/atom/A)
- . = ..()
- if(.) // If we succeeded in hitting.
- if(isliving(A))
- var/mob/living/L = A
- if(L.reagents)
- var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
- if(L.can_inject(src, null, target_zone))
- L.reagents.add_reagent(poison_type, poison_per_bite)
- if(prob(poison_chance))
- to_chat(L, "You feel a tiny prick.")
- L.reagents.add_reagent(poison_type, poison_per_bite)
-
-/mob/living/simple_animal/hostile/giant_spider/nurse/DoPunch(var/atom/A)
- . = ..()
- if(.) // If we succeeded in hitting.
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(prob(egg_inject_chance))
- var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
- if(H.can_inject(src, null, target_zone))
- var/obj/item/organ/external/O = H.get_organ(target_zone)
- var/eggcount
- for(var/obj/I in O.implants)
- if(istype(I, /obj/effect/spider/eggcluster))
- eggcount ++
- if(!eggcount)
- var/eggs = new /obj/effect/spider/eggcluster/small(O, src)
- O.implants += eggs
- to_chat(H, "\The [src] injects something into your [O.name]!")
-
-/mob/living/simple_animal/hostile/giant_spider/webslinger/DoPunch(var/atom/A)
- . = ..()
- if(.) // If we succeeded in hitting.
- if(isliving(A))
- var/mob/living/L = A
- var/obj/effect/spider/stickyweb/W = locate() in get_turf(L)
- if(!W && prob(75))
- visible_message("\The [src] throws a layer of web at \the [L]!")
- new /obj/effect/spider/stickyweb(L.loc)
-
-/mob/living/simple_animal/hostile/giant_spider/handle_stance()
- . = ..()
- if(ai_inactive) return
-
- switch(stance)
- if(STANCE_IDLE)
- //1% chance to skitter madly away
- if(!busy && prob(1))
- /*var/list/move_targets = list()
- for(var/turf/T in orange(20, src))
- move_targets.Add(T)*/
- stop_automated_movement = 1
- walk_to(src, pick(orange(20, src)), 1, move_to_delay)
- spawn(5 SECONDS)
- stop_automated_movement = 0
- walk(src,0)
-
-/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C)
- spawn(10 SECONDS)
- if(busy == MOVING_TO_TARGET)
- if(cocoon_target == C && get_dist(src,cocoon_target) > 1)
- cocoon_target = null
- busy = 0
- stop_automated_movement = 0
-
-/mob/living/simple_animal/hostile/giant_spider/nurse/Life()
- . = ..()
- if(!. || ai_inactive) return
-
- if(stance == STANCE_IDLE)
- var/list/can_see = view(src, 10)
- //30% chance to stop wandering and do something
- if(!busy && prob(30))
- //first, check for potential food nearby to cocoon
- for(var/mob/living/C in can_see)
- if(C.stat)
- cocoon_target = C
- busy = MOVING_TO_TARGET
- walk_to(src, C, 1, move_to_delay)
- //give up if we can't reach them after 10 seconds
- GiveUp(C)
- return
-
- //second, spin a sticky spiderweb on this tile
- var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
- if(!W)
- busy = SPINNING_WEB
- src.visible_message("\The [src] begins to secrete a sticky substance.")
- stop_automated_movement = 1
- spawn(40)
- if(busy == SPINNING_WEB)
- new /obj/effect/spider/stickyweb(src.loc)
- busy = 0
- stop_automated_movement = 0
- else
- //third, lay an egg cluster there
- var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
- if(!E && fed > 0)
- busy = LAYING_EGGS
- src.visible_message("\The [src] begins to lay a cluster of eggs.")
- stop_automated_movement = 1
- spawn(50)
- if(busy == LAYING_EGGS)
- E = locate() in get_turf(src)
- if(!E)
- new /obj/effect/spider/eggcluster(loc, src)
- fed--
- busy = 0
- stop_automated_movement = 0
- else
- //fourthly, cocoon any nearby items so those pesky pinkskins can't use them
- for(var/obj/O in can_see)
-
- if(O.anchored)
- continue
-
- if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
- cocoon_target = O
- busy = MOVING_TO_TARGET
- stop_automated_movement = 1
- walk_to(src, O, 1, move_to_delay)
- //give up if we can't reach them after 10 seconds
- GiveUp(O)
-
- else if(busy == MOVING_TO_TARGET && cocoon_target)
- if(get_dist(src, cocoon_target) <= 1)
- busy = SPINNING_COCOON
- src.visible_message("\The [src] begins to secrete a sticky substance around \the [cocoon_target].")
- stop_automated_movement = 1
- walk(src,0)
- spawn(50)
- if(busy == SPINNING_COCOON)
- if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
- var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
- var/large_cocoon = 0
- C.pixel_x = cocoon_target.pixel_x
- C.pixel_y = cocoon_target.pixel_y
- for(var/mob/living/M in C.loc)
- if(istype(M, /mob/living/simple_animal/hostile/giant_spider))
- continue
- large_cocoon = 1
- fed++
- src.visible_message("\The [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.")
- M.forceMove(C)
- C.pixel_x = M.pixel_x
- C.pixel_y = M.pixel_y
- break
- for(var/obj/item/I in C.loc)
- I.forceMove(C)
- for(var/obj/structure/S in C.loc)
- if(!S.anchored)
- S.forceMove(C)
- large_cocoon = 1
- for(var/obj/machinery/M in C.loc)
- if(!M.anchored)
- M.forceMove(C)
- large_cocoon = 1
- if(large_cocoon)
- C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
- busy = 0
- stop_automated_movement = 0
-
- else
- busy = 0
- stop_automated_movement = 0
-
-
-#undef SPINNING_WEB
-#undef LAYING_EGGS
-#undef MOVING_TO_TARGET
-#undef SPINNING_COCOON
diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm
deleted file mode 100644
index 7ac8dfd45d..0000000000
--- a/code/modules/mob/living/simple_animal/animals/goose.dm
+++ /dev/null
@@ -1,59 +0,0 @@
-/mob/living/simple_animal/hostile/goose //hey are these even in the game
- name = "goose"
- desc = "It looks pretty angry!"
- tt_desc = "E Branta canadensis" //that iconstate is just a regular goose
- icon_state = "goose"
- icon_living = "goose"
- icon_dead = "goose_dead"
-
- faction = "geese"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 15
- health = 15
- speed = 4
-
- turns_per_move = 5
-
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "hits the"
-
- harm_intent_damage = 5
- melee_damage_lower = 5 //they're meant to be annoying, not threatening.
- melee_damage_upper = 5 //unless there's like a dozen of them, then you're screwed.
- attacktext = list("pecked")
- attack_sound = 'sound/weapons/bite.ogg'
-
- //SPACE geese aren't affected by atmos.
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- has_langs = list("Bird")
- speak_chance = 10
- speak = list("HONK!")
- emote_hear = list("honks loudly!")
- emote_see = list()
- say_understood = list()
- say_cannot = list()
- say_maybe_target = list("Honk?")
- say_got_target = list("HONK!!!")
- reactions = list()
-
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
-/mob/living/simple_animal/hostile/goose/set_target()
- . = ..()
- if(.)
- custom_emote(1,"flaps and honks at [.]!")
-
-/mob/living/simple_animal/hostile/goose/Process_Spacemove(var/check_drift = 0)
- return
diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm
deleted file mode 100644
index 3cceeb4da4..0000000000
--- a/code/modules/mob/living/simple_animal/animals/lizard.dm
+++ /dev/null
@@ -1,24 +0,0 @@
-/mob/living/simple_animal/lizard
- name = "Lizard"
- desc = "A cute tiny lizard."
- tt_desc = "E Anolis cuvieri"
- icon = 'icons/mob/critter.dmi'
- icon_state = "lizard"
- icon_living = "lizard"
- icon_dead = "lizard-dead"
- intelligence_level = SA_ANIMAL
-
- health = 5
- maxHealth = 5
- mob_size = MOB_MINISCULE
-
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "stomps on"
-
- attacktext = list("bitten")
- melee_damage_lower = 1
- melee_damage_upper = 2
-
- speak_chance = 1
- speak_emote = list("hisses")
diff --git a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm b/code/modules/mob/living/simple_animal/animals/miscellaneous.dm
deleted file mode 100644
index 29bb7a3da3..0000000000
--- a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm
+++ /dev/null
@@ -1,21 +0,0 @@
-/mob/living/simple_animal/yithian
- name = "yithian"
- desc = "A friendly creature vaguely resembling an oversized snail without a shell."
- tt_desc = "J Escargot escargot" // a product of Jade, which is a planet that totally exists
- icon_state = "yithian"
- icon_living = "yithian"
- icon_dead = "yithian_dead"
- icon = 'icons/jungle.dmi'
-
- faction = "yithian"
-
-/mob/living/simple_animal/tindalos
- name = "tindalos"
- desc = "It looks like a large, flightless grasshopper."
- tt_desc = "J Locusta bruchus"
- icon_state = "tindalos"
- icon_living = "tindalos"
- icon_dead = "tindalos_dead"
- icon = 'icons/jungle.dmi'
-
- faction = "tindalos"
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm
deleted file mode 100644
index 370001a7ca..0000000000
--- a/code/modules/mob/living/simple_animal/animals/mouse.dm
+++ /dev/null
@@ -1,137 +0,0 @@
-/mob/living/simple_animal/mouse
- name = "mouse"
- real_name = "mouse"
- desc = "It's a small rodent."
- tt_desc = "E Mus musculus"
- icon_state = "mouse_gray"
- item_state = "mouse_gray"
- icon_living = "mouse_gray"
- icon_dead = "mouse_gray_dead"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 5
- health = 5
-
- turns_per_move = 5
- see_in_dark = 6
- universal_understand = 1
-
- mob_size = MOB_SMALL
- pass_flags = PASSTABLE
-// can_pull_size = ITEMSIZE_TINY
-// can_pull_mobs = MOB_PULL_NONE
- layer = MOB_LAYER
- density = 0
-
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "stamps on"
-
- min_oxy = 16 //Require atleast 16kPA oxygen
- minbodytemp = 223 //Below -50 Degrees Celcius
- maxbodytemp = 323 //Above 50 Degrees Celcius
-
- has_langs = list("Mouse")
- speak_chance = 1
- speak = list("Squeek!","SQUEEK!","Squeek?")
- speak_emote = list("squeeks","squeeks","squiks")
- emote_hear = list("squeeks","squeaks","squiks")
- emote_see = list("runs in a circle", "shakes", "scritches at something")
-
- holder_type = /obj/item/weapon/holder/mouse
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
-
- var/body_color //brown, gray and white, leave blank for random
-
-/mob/living/simple_animal/mouse/Life()
- . = ..()
- if(!. || ai_inactive) return
-
- if(prob(speak_chance))
- for(var/mob/M in view())
- M << 'sound/effects/mouse_squeak.ogg'
-
- if(!resting && prob(0.5))
- lay_down()
- speak_chance = 0
- //snuffles
-
- else if(resting)
- if(prob(1))
- lay_down()
- speak_chance = initial(speak_chance)
- else if(prob(1))
- audible_emote("snuffles.")
-
-/mob/living/simple_animal/mouse/New()
- ..()
-
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
-
- if(name == initial(name))
- name = "[name] ([rand(1, 1000)])"
- real_name = name
-
- if(!body_color)
- body_color = pick( list("brown","gray","white") )
- icon_state = "mouse_[body_color]"
- item_state = "mouse_[body_color]"
- icon_living = "mouse_[body_color]"
- icon_dead = "mouse_[body_color]_dead"
- icon_rest = "mouse_[body_color]_sleep"
- desc = "A small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
-
-/mob/living/simple_animal/mouse/proc/splat()
- src.health = 0
- src.stat = DEAD
- src.icon_dead = "mouse_[body_color]_splat"
- src.icon_state = "mouse_[body_color]_splat"
- layer = MOB_LAYER
- if(client)
- client.time_died_as_mouse = world.time
-
-
-/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
- if( ishuman(AM) )
- if(!stat)
- var/mob/M = AM
- M.visible_message("\icon[src] Squeek!")
- M << 'sound/effects/mouse_squeak.ogg'
- ..()
-
-/mob/living/simple_animal/mouse/death()
- layer = MOB_LAYER
- playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 35, 1)
- if(client)
- client.time_died_as_mouse = world.time
- ..()
-
-/*
- * Mouse types
- */
-
-/mob/living/simple_animal/mouse/white
- body_color = "white"
- icon_state = "mouse_white"
-
-/mob/living/simple_animal/mouse/gray
- body_color = "gray"
- icon_state = "mouse_gray"
-
-/mob/living/simple_animal/mouse/brown
- body_color = "brown"
- icon_state = "mouse_brown"
-
-//TOM IS ALIVE! SQUEEEEEEEE~K :)
-/mob/living/simple_animal/mouse/brown/Tom
- name = "Tom"
- desc = "Jerry the cat is not amused."
-
-/mob/living/simple_animal/mouse/brown/Tom/New()
- ..()
- // Change my name back, don't want to be named Tom (666)
- name = initial(name)
-
-/mob/living/simple_animal/mouse/cannot_use_vents()
- return
diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm
deleted file mode 100644
index 42796c8cee..0000000000
--- a/code/modules/mob/living/simple_animal/animals/parrot.dm
+++ /dev/null
@@ -1,768 +0,0 @@
-/* Parrots!
- * Contains
- * Defines
- * Inventory (headset stuff)
- * Attack responces
- * AI
- * Procs / Verbs (usable by players)
- * Sub-types
- */
-
-/*
- * Defines
- */
-
-//Parrot is too snowflake for me to rewrite right now, someone should make it use the new
-//simple_animal movement stuff. -Aro
-
-//Only a maximum of one action and one intent should be active at any given time.
-//Actions
-#define PARROT_PERCH 1 //Sitting/sleeping, not moving
-#define PARROT_SWOOP 2 //Moving towards or away from a target
-#define PARROT_WANDER 4 //Moving without a specific target in mind
-
-//Intents
-#define PARROT_STEAL 8 //Flying towards a target to steal it/from it
-#define PARROT_ATTACK 16 //Flying towards a target to attack it
-#define PARROT_RETURN 32 //Flying towards its perch
-#define PARROT_FLEE 64 //Flying away from its attacker
-
-
-/mob/living/simple_animal/parrot
- name = "parrot"
- desc = "The parrot squawks, \"It's a parrot! BAWWK!\""
- tt_desc = "E Ara macao"
- icon = 'icons/mob/animal.dmi'
- icon_state = "parrot_fly"
- icon_living = "parrot_fly"
- icon_dead = "parrot_dead"
- intelligence_level = SA_ANIMAL
-
- turns_per_move = 5
- pass_flags = PASSTABLE
- mob_size = MOB_SMALL
-
- response_help = "pets"
- response_disarm = "gently moves aside"
- response_harm = "swats"
- stop_automated_movement = 1
- universal_speak = 1
-
- has_langs = list("Bird", "Galactic Common")
- speak_chance = 2
- speak = list("Hi","Hello!","Cracker?","Bawk!")
- speak_emote = list("squawks","says","yells")
- emote_hear = list("squawks","bawks")
- emote_see = list("flutters its wings")
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker
-
- hovering = TRUE
- softfall = TRUE
- parachuting = TRUE
-
- var/parrot_state = PARROT_WANDER //Hunt for a perch when created
- var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
- var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
- var/parrot_dam_zone = list(BP_TORSO, BP_HEAD, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) //For humans, select a bodypart to attack
-
- var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower.
- var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.
-
- var/list/speech_buffer = list()
- var/list/available_channels = list()
-
- //Headset for Poly to yell at engineers :)
- var/obj/item/device/radio/headset/ears = null
-
- //The thing the parrot is currently interested in. This gets used for items the parrot wants to pick up, mobs it wants to steal from,
- //mobs it wants to attack or mobs that have attacked it
- var/atom/movable/parrot_interest = null
-
- //Parrots will generally sit on their pertch unless something catches their eye.
- //These vars store their preffered perch and if they dont have one, what they can use as a perch
- var/obj/parrot_perch = null
- var/obj/desired_perches = list(/obj/structure/frame, /obj/structure/displaycase, \
- /obj/structure/filingcabinet, /obj/machinery/teleport, \
- /obj/machinery/computer, /obj/machinery/clonepod, \
- /obj/machinery/dna_scannernew, /obj/machinery/telecomms, \
- /obj/machinery/nuclearbomb, /obj/machinery/particle_accelerator, \
- /obj/machinery/recharge_station, /obj/machinery/smartfridge, \
- /obj/machinery/suit_storage_unit)
-
- //Parrots are kleptomaniacs. This variable ... stores the item a parrot is holding.
- var/obj/item/held_item = null
-
-
-/mob/living/simple_animal/parrot/New()
- ..()
- if(!ears)
- var/headset = pick(/obj/item/device/radio/headset/headset_sec, \
- /obj/item/device/radio/headset/headset_eng, \
- /obj/item/device/radio/headset/headset_med, \
- /obj/item/device/radio/headset/headset_sci, \
- /obj/item/device/radio/headset/headset_cargo)
- ears = new headset(src)
-
- parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var
-
- verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \
- /mob/living/simple_animal/parrot/proc/steal_from_mob, \
- /mob/living/simple_animal/parrot/verb/drop_held_item_player, \
- /mob/living/simple_animal/parrot/proc/perch_player)
-
-
-/mob/living/simple_animal/parrot/death()
- if(held_item)
- held_item.forceMove(src.loc)
- held_item = null
- walk(src,0)
- ..()
-
-/mob/living/simple_animal/parrot/Stat()
- ..()
- stat("Held Item", held_item)
-
-/*
- * Inventory
- */
-/mob/living/simple_animal/parrot/show_inv(mob/user as mob)
- user.set_machine(src)
- if(user.stat) return
-
- var/dat = "Inventory of [name]
"
- if(ears)
- dat += "
Headset: [ears] (Remove)"
- else
- dat += "
Headset: Nothing"
-
- user << browse(dat, text("window=mob[];size=325x500", name))
- onclose(user, "mob[real_name]")
- return
-
-/mob/living/simple_animal/parrot/Topic(href, href_list)
-
- //Can the usr physically do this?
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
- return
-
- //Is the usr's mob type able to do this?
- if(ishuman(usr) || issmall(usr) || isrobot(usr))
-
- //Removing from inventory
- if(href_list["remove_inv"])
- var/remove_from = href_list["remove_inv"]
- switch(remove_from)
- if("ears")
- if(ears)
- if(available_channels.len)
- src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
- else
- src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
- ears.forceMove(src.loc)
- ears = null
- for(var/possible_phrase in speak)
- if(copytext(possible_phrase,1,3) in department_radio_keys)
- possible_phrase = copytext(possible_phrase,3,length(possible_phrase))
- else
- to_chat(usr, "There is nothing to remove from its [remove_from].")
- return
-
- //Adding things to inventory
- else if(href_list["add_inv"])
- var/add_to = href_list["add_inv"]
- if(!usr.get_active_hand())
- to_chat(usr, "You have nothing in your hand to put on its [add_to].")
- return
- switch(add_to)
- if("ears")
- if(ears)
- to_chat(usr, "It's already wearing something.")
- return
- else
- var/obj/item/item_to_add = usr.get_active_hand()
- if(!item_to_add)
- return
-
- if( !istype(item_to_add, /obj/item/device/radio/headset) )
- to_chat(usr, "This object won't fit.")
- return
-
- var/obj/item/device/radio/headset/headset_to_add = item_to_add
-
- usr.drop_item()
- headset_to_add.forceMove(src)
- src.ears = headset_to_add
- to_chat(usr, "You fit the headset onto [src].")
-
- clearlist(available_channels)
- for(var/ch in headset_to_add.channels)
- switch(ch)
- if("Engineering")
- available_channels.Add(":e")
- if("Command")
- available_channels.Add(":c")
- if("Security")
- available_channels.Add(":s")
- if("Science")
- available_channels.Add(":n")
- if("Medical")
- available_channels.Add(":m")
- if("Mining")
- available_channels.Add(":d")
- if("Cargo")
- available_channels.Add(":q")
-
- if(headset_to_add.translate_binary)
- available_channels.Add("#b")
- else
- ..()
-
-
-/*
- * Attack responces
- */
-//Humans, monkeys, aliens
-/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob)
- ..()
- if(client) return
- if(!stat && M.a_intent == I_HURT)
-
- icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks
-
- if(parrot_state == PARROT_PERCH)
- parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
-
- parrot_interest = M
- parrot_state = PARROT_SWOOP //The parrot just got hit, it WILL move, now to pick a direction..
-
- if(M.health < 50) //Weakened mob? Fight back!
- parrot_state |= PARROT_ATTACK
- else
- parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell!
- drop_held_item(0)
- return
-
-//Mobs with objects
-/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob)
- ..()
- if(!stat && !client && !istype(O, /obj/item/stack/medical))
- if(O.force)
- if(parrot_state == PARROT_PERCH)
- parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
-
- parrot_interest = user
- parrot_state = PARROT_SWOOP | PARROT_FLEE
- icon_state = "parrot_fly"
- drop_held_item(0)
- return
-
-//Bullets
-/mob/living/simple_animal/parrot/bullet_act(var/obj/item/projectile/Proj)
- ..()
- if(!stat && !client)
- if(parrot_state == PARROT_PERCH)
- parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
-
- parrot_interest = null
- parrot_state = PARROT_WANDER //OWFUCK, Been shot! RUN LIKE HELL!
- parrot_been_shot += 5
- icon_state = "parrot_fly"
- drop_held_item(0)
- return
-
-
-/*
- * AI - Not really intelligent, but I'm calling it AI anyway.
- */
-/mob/living/simple_animal/parrot/Life()
- ..()
-
- //Sprite and AI update for when a parrot gets pulled
- if(pulledby && stat == CONSCIOUS)
- icon_state = "parrot_fly"
- if(!client)
- parrot_state = PARROT_WANDER
- return
-
- if(client || stat)
- return //Lets not force players or dead/incap parrots to move
-
- if(!isturf(src.loc) || !canmove || buckled)
- return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
-
-
-//-----SPEECH
- /* Parrot speech mimickry!
- Phrases that the parrot hears in mob/living/say() get added to speach_buffer.
- Every once in a while, the parrot picks one of the lines from the buffer and replaces an element of the 'speech' list.
- Then it clears the buffer to make sure they dont magically remember something from hours ago. */
- if(speech_buffer.len && prob(10))
- if(speak.len)
- speak.Remove(pick(speak))
-
- speak.Add(pick(speech_buffer))
- clearlist(speech_buffer)
-
-
-//-----SLEEPING
- if(parrot_state == PARROT_PERCH)
- if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us
- if(parrot_perch in view(src))
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- icon_state = "parrot_fly"
- return
- else
- parrot_state = PARROT_WANDER
- icon_state = "parrot_fly"
- return
-
- if(--parrot_sleep_dur) //Zzz
- return
-
- else
- //This way we only call the stuff below once every [sleep_max] ticks.
- parrot_sleep_dur = parrot_sleep_max
-
- //Cycle through message modes for the headset
- if(speak.len)
- var/list/newspeak = list()
-
- if(available_channels.len && src.ears)
- for(var/possible_phrase in speak)
-
- //50/50 chance to not use the radio at all
- var/useradio = 0
- if(prob(50))
- useradio = 1
-
- if(copytext(possible_phrase,1,3) in department_radio_keys)
- possible_phrase = "[useradio?pick(available_channels):""] [copytext(possible_phrase,3,length(possible_phrase)+1)]" //crop out the channel prefix
- else
- possible_phrase = "[useradio?pick(available_channels):""] [possible_phrase]"
-
- newspeak.Add(possible_phrase)
-
- else //If we have no headset or channels to use, dont try to use any!
- for(var/possible_phrase in speak)
- if(copytext(possible_phrase,1,3) in department_radio_keys)
- possible_phrase = "[copytext(possible_phrase,3,length(possible_phrase)+1)]" //crop out the channel prefix
- newspeak.Add(possible_phrase)
- speak = newspeak
-
- //Search for item to steal
- parrot_interest = search_for_item()
- if(parrot_interest)
- visible_emote("looks in [parrot_interest]'s direction and takes flight")
- parrot_state = PARROT_SWOOP | PARROT_STEAL
- icon_state = "parrot_fly"
- return
-
-//-----WANDERING - This is basically a 'I dont know what to do yet' state
- else if(parrot_state == PARROT_WANDER)
- //Stop movement, we'll set it later
- walk(src, 0)
- parrot_interest = null
-
- //Wander around aimlessly. This will help keep the loops from searches down
- //and possibly move the mob into a new are in view of something they can use
- if(prob(90))
- step(src, pick(cardinal))
- return
-
- if(!held_item && !parrot_perch) //If we've got nothing to do.. look for something to do.
- var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item
- if(AM)
- if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
- parrot_interest = AM
- visible_emote("turns and flies towards [parrot_interest]")
- parrot_state = PARROT_SWOOP | PARROT_STEAL
- return
- else //Else it's a perch
- parrot_perch = AM
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
- return
-
- if(parrot_interest && parrot_interest in view(src))
- parrot_state = PARROT_SWOOP | PARROT_STEAL
- return
-
- if(parrot_perch && parrot_perch in view(src))
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
-
- else //Have an item but no perch? Find one!
- parrot_perch = search_for_perch()
- if(parrot_perch)
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
-//-----STEALING
- else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL))
- walk(src,0)
- if(!parrot_interest || held_item)
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
-
- if(!(parrot_interest in view(src)))
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
-
- if(in_range(src, parrot_interest))
-
- if(isliving(parrot_interest))
- steal_from_mob()
-
- else //This should ensure that we only grab the item we want, and make sure it's not already collected on our perch
- if(!parrot_perch || parrot_interest.loc != parrot_perch.loc)
- held_item = parrot_interest
- parrot_interest.forceMove(src)
- visible_message("[src] grabs the [held_item]!", "You grab the [held_item]!", "You hear the sounds of wings flapping furiously.")
-
- parrot_interest = null
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- return
-
- walk_to(src, parrot_interest, 1, parrot_speed)
- return
-
-//-----RETURNING TO PERCH
- else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN))
- walk(src, 0)
- if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else.
- parrot_perch = null
- parrot_state = PARROT_WANDER
- return
-
- if(in_range(src, parrot_perch))
- src.forceMove(parrot_perch.loc)
- drop_held_item()
- parrot_state = PARROT_PERCH
- icon_state = "parrot_sit"
- return
-
- walk_to(src, parrot_perch, 1, parrot_speed)
- return
-
-//-----FLEEING
- else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE))
- walk(src,0)
- if(!parrot_interest || !isliving(parrot_interest)) //Sanity
- parrot_state = PARROT_WANDER
-
- walk_away(src, parrot_interest, 1, parrot_speed-parrot_been_shot)
- parrot_been_shot--
- return
-
-//-----ATTACKING
- else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK))
-
- //If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander
- if(!parrot_interest || !isliving(parrot_interest))
- parrot_interest = null
- parrot_state = PARROT_WANDER
- return
-
- var/mob/living/L = parrot_interest
-
- //If the mob is close enough to interact with
- if(in_range(src, parrot_interest))
-
- //If the mob we've been chasing/attacking dies or falls into crit, check for loot!
- if(L.stat)
- parrot_interest = null
- if(!held_item)
- held_item = steal_from_ground()
- if(!held_item)
- held_item = steal_from_mob() //Apparently it's possible for dead mobs to hang onto items in certain circumstances.
- if(parrot_perch in view(src)) //If we have a home nearby, go to it, otherwise find a new home
- parrot_state = PARROT_SWOOP | PARROT_RETURN
- else
- parrot_state = PARROT_WANDER
- return
-
- //Time for the hurt to begin!
- var/damage = rand(5,10)
-
- if(ishuman(parrot_interest))
- var/mob/living/carbon/human/H = parrot_interest
- var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
-
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1)
- visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
-
- else
- L.adjustBruteLoss(damage)
- visible_emote(pick("pecks at [L].", "claws [L]."))
- return
-
- //Otherwise, fly towards the mob!
- else
- walk_to(src, parrot_interest, 1, parrot_speed)
- return
-//-----STATE MISHAP
- else //This should not happen. If it does lets reset everything and try again
- walk(src,0)
- parrot_interest = null
- parrot_perch = null
- drop_held_item()
- parrot_state = PARROT_WANDER
- return
-
-/*
- * Procs
- */
-
-/mob/living/simple_animal/parrot/movement_delay()
- if(client && stat == CONSCIOUS && parrot_state != "parrot_fly")
- icon_state = "parrot_fly"
- ..()
-
-/mob/living/simple_animal/parrot/proc/search_for_item()
- for(var/atom/movable/AM in view(src))
- //Skip items we already stole or are wearing or are too big
- if(parrot_perch && AM.loc == parrot_perch.loc || AM.loc == src)
- continue
-
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- if(I.w_class < ITEMSIZE_SMALL)
- return I
-
- if(iscarbon(AM))
- var/mob/living/carbon/C = AM
- if((C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL) || (C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL))
- return C
- return null
-
-/mob/living/simple_animal/parrot/proc/search_for_perch()
- for(var/obj/O in view(src))
- for(var/path in desired_perches)
- if(istype(O, path))
- return O
- return null
-
-//This proc was made to save on doing two 'in view' loops seperatly
-/mob/living/simple_animal/parrot/proc/search_for_perch_and_item()
- for(var/atom/movable/AM in view(src))
- for(var/perch_path in desired_perches)
- if(istype(AM, perch_path))
- return AM
-
- //Skip items we already stole or are wearing or are too big
- if(parrot_perch && AM.loc == parrot_perch.loc || AM.loc == src)
- continue
-
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- if(I.w_class <= ITEMSIZE_SMALL)
- return I
-
- if(iscarbon(AM))
- var/mob/living/carbon/C = AM
- if(C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL || C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL)
- return C
- return null
-
-
-/*
- * Verbs - These are actually procs, but can be used as verbs by player-controlled parrots.
- */
-/mob/living/simple_animal/parrot/proc/steal_from_ground()
- set name = "Steal from ground"
- set category = "Parrot"
- set desc = "Grabs a nearby item."
-
- if(stat)
- return -1
-
- if(held_item)
- to_chat(src, "You are already holding the [held_item]")
- return 1
-
- for(var/obj/item/I in view(1,src))
- //Make sure we're not already holding it and it's small enough
- if(I.loc != src && I.w_class <= ITEMSIZE_SMALL)
-
- //If we have a perch and the item is sitting on it, continue
- if(!client && parrot_perch && I.loc == parrot_perch.loc)
- continue
-
- held_item = I
- I.forceMove(src)
- visible_message("[src] grabs the [held_item]!", "You grab the [held_item]!", "You hear the sounds of wings flapping furiously.")
- return held_item
-
- to_chat(src, "There is nothing of interest to take.")
- return 0
-
-/mob/living/simple_animal/parrot/proc/steal_from_mob()
- set name = "Steal from mob"
- set category = "Parrot"
- set desc = "Steals an item right out of a person's hand!"
-
- if(stat)
- return -1
-
- if(held_item)
- to_chat(src, "You are already holding the [held_item]")
- return 1
-
- var/obj/item/stolen_item = null
-
- for(var/mob/living/carbon/C in view(1,src))
- if(C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL)
- stolen_item = C.l_hand
-
- if(C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL)
- stolen_item = C.r_hand
-
- if(stolen_item)
- C.remove_from_mob(stolen_item)
- held_item = stolen_item
- stolen_item.forceMove(src)
- visible_message("[src] grabs the [held_item] out of [C]'s hand!", "You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.")
- return held_item
-
- to_chat(src, "There is nothing of interest to take.")
- return 0
-
-/mob/living/simple_animal/parrot/verb/drop_held_item_player()
- set name = "Drop held item"
- set category = "Parrot"
- set desc = "Drop the item you're holding."
-
- if(stat)
- return
-
- src.drop_held_item()
-
- return
-
-/mob/living/simple_animal/parrot/proc/drop_held_item(var/drop_gently = 1)
- set name = "Drop held item"
- set category = "Parrot"
- set desc = "Drop the item you're holding."
-
- if(stat)
- return -1
-
- if(!held_item)
- to_chat(usr, "You have nothing to drop!")
- return 0
-
- if(!drop_gently)
- if(istype(held_item, /obj/item/weapon/grenade))
- var/obj/item/weapon/grenade/G = held_item
- G.forceMove(src.loc)
- G.detonate()
- to_chat(src, "You let go of the [held_item]!")
- held_item = null
- return 1
-
- to_chat(src, "You drop the [held_item].")
-
- held_item.forceMove(src.loc)
- held_item = null
- return 1
-
-/mob/living/simple_animal/parrot/proc/perch_player()
- set name = "Sit"
- set category = "Parrot"
- set desc = "Sit on a nice comfy perch."
-
- if(stat || !client)
- return
-
- if(icon_state == "parrot_fly")
- for(var/atom/movable/AM in view(src,1))
- for(var/perch_path in desired_perches)
- if(istype(AM, perch_path))
- src.forceMove(AM.loc)
- icon_state = "parrot_sit"
- return
- to_chat(src, "There is no perch nearby to sit on.")
- return
-
-/*
- * Sub-types
- */
-/mob/living/simple_animal/parrot/Poly
- name = "Poly"
- desc = "Poly the Parrot. An expert on quantum cracker theory."
- speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE")
-
-/mob/living/simple_animal/parrot/Poly/New()
- ears = new /obj/item/device/radio/headset/headset_eng(src)
- available_channels = list(":e")
- ..()
-
-/mob/living/simple_animal/parrot/say(var/message)
-
- if(stat)
- return
-
- var/verb = "says"
- if(speak_emote.len)
- verb = pick(speak_emote)
-
-
- var/message_mode=""
- if(copytext(message,1,2) == ";")
- message_mode = "headset"
- message = copytext(message,2)
-
- if(length(message) >= 2)
- var/channel_prefix = copytext(message, 1 ,3)
- message_mode = department_radio_keys[channel_prefix]
-
- if(copytext(message,1,2) == ":")
- var/positioncut = 3
- message = trim(copytext(message,positioncut))
-
- message = capitalize(trim_left(message))
-
- if(message_mode)
- if(message_mode in radiochannels)
- if(ears && istype(ears,/obj/item/device/radio))
- ears.talk_into(src,sanitize(message), message_mode, verb, null)
-
-
- ..(message)
-
-
-/mob/living/simple_animal/parrot/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
- if(prob(50))
- parrot_hear(message)
- ..(message,verb,language,alt_name,italics,speaker)
-
-
-
-/mob/living/simple_animal/parrot/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0)
- if(prob(50))
- parrot_hear("[pick(available_channels)] [message]")
- ..(message,verb,language,part_a,part_b,speaker,hard_to_hear)
-
-
-/mob/living/simple_animal/parrot/proc/parrot_hear(var/message="")
- if(!message || stat)
- return
- speech_buffer.Add(message)
-
-/mob/living/simple_animal/parrot/attack_generic(var/mob/user, var/damage, var/attack_message)
-
- var/success = ..()
-
- if(client)
- return success
-
- if(parrot_state == PARROT_PERCH)
- parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
-
- if(!success)
- return 0
-
- parrot_interest = user
- parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
- icon_state = "parrot_fly"
- return success
diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm
deleted file mode 100644
index da7c9c4328..0000000000
--- a/code/modules/mob/living/simple_animal/animals/penguin.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/mob/living/simple_animal/penguin
- name = "space penguin"
- desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
- tt_desc = "E Aptenodytes forsteri"
- icon_state = "penguin"
- icon_living = "penguin"
- icon_dead = "penguin_dead"
- intelligence_level = SA_ANIMAL
-
- maxHealth = 20
- health = 20
-
- turns_per_move = 5
-
- response_help = "pets"
- response_disarm = "pushes aside"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 10
- melee_damage_upper = 15
- attacktext = list("pecked")
-
- has_langs = list("Bird")
- speak_chance = 0
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm
deleted file mode 100644
index 86b2a261e7..0000000000
--- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/mob/living/simple_animal/retaliate/diyaab
- name = "diyaab"
- desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
- tt_desc = "S Choeros hirtus" //diyaab and shantak are technically reletives!
- faction = "diyaab"
- icon_state = "diyaab"
- icon_living = "diyaab"
- icon_dead = "diyaab_dead"
- icon = 'icons/jungle.dmi'
-
- faction = "diyaab"
- cooperative = 1
-
- maxHealth = 25
- health = 25
- speed = 1
- move_to_delay = 1
-
- melee_damage_lower = 4
- melee_damage_upper = 12
- attack_sharp = 1 //Bleeds, but it shouldn't rip off a limb?
-
- attacktext = list("gouged")
- cold_damage_per_tick = 0
-
- speak_chance = 5
- speak = list("Awrr?","Aowrl!","Worrl")
- emote_see = list("sniffs the air cautiously","looks around")
- emote_hear = list("snuffles")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm
deleted file mode 100644
index b451901b60..0000000000
--- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm
+++ /dev/null
@@ -1,36 +0,0 @@
-/mob/living/simple_animal/hostile/savik
- name = "savik"
- desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
- tt_desc = "S Pistris tellus" //landshark
- faction = "savik"
- icon_state = "savik"
- icon_living = "savik"
- icon_dead = "savik_dead"
- icon = 'icons/jungle.dmi'
-
- faction = "savik"
-
- maxHealth = 125
- health = 125
- speed = 2
- move_to_delay = 2
-
- melee_damage_lower = 15
- melee_damage_upper = 35
- attack_armor_pen = 15
- attack_sharp = 1
- attack_edge = 1
-
- attacktext = list("mauled")
- cold_damage_per_tick = 0
-
- speak_chance = 5
- speak = list("Hruuugh!","Hrunnph")
- emote_see = list("paws the ground","shakes its mane","stomps")
- emote_hear = list("snuffles")
-
-/mob/living/simple_animal/hostile/savik/handle_stance(var/new_stance)
- ..(new_stance)
- if(stance == STANCE_ATTACK || stance == STANCE_ATTACKING)
- if((health / maxHealth) <= 0.5) // At half health, and fighting someone currently.
- add_modifier(/datum/modifier/berserk, 30 SECONDS)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm
deleted file mode 100644
index 999916bbe6..0000000000
--- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/mob/living/simple_animal/hostile/shantak
- name = "shantak"
- desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
- tt_desc = "S Choeros shantak"
- faction = "shantak"
- icon_state = "shantak"
- icon_living = "shantak"
- icon_dead = "shantak_dead"
- icon = 'icons/jungle.dmi'
-
- faction = "shantak"
-
- maxHealth = 75
- health = 75
- speed = 1
- move_to_delay = 1
-
- melee_damage_lower = 12
- melee_damage_upper = 28
- attack_armor_pen = 5
- attack_sharp = 1
- attack_edge = 1
-
- attacktext = list("gouged")
- cold_damage_per_tick = 0
-
- speak_chance = 5
- speak = list("Shuhn","Shrunnph?","Shunpf")
- emote_see = list("scratches the ground","shakes out its mane","clinks gently as it moves")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm
deleted file mode 100644
index 0449146a7e..0000000000
--- a/code/modules/mob/living/simple_animal/animals/slime.dm
+++ /dev/null
@@ -1,70 +0,0 @@
-/mob/living/simple_animal/slime
- name = "pet slime"
- desc = "A lovable, domesticated slime."
- tt_desc = "Amorphidae proteus"
- icon = 'icons/mob/slimes.dmi'
- icon_state = "grey baby slime"
- icon_living = "grey baby slime"
- icon_dead = "grey baby slime dead"
-
- maxHealth = 100
- health = 100
-
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "stomps on"
-
- speak_chance = 1
- speak_emote = list("chirps")
- emote_see = list("jiggles", "bounces in place")
-
- var/colour = "grey"
-
-/mob/living/simple_animal/slime/science
- name = "Kendrick"
- colour = "rainbow"
- icon_state = "rainbow baby slime"
- icon_living = "rainbow baby slime"
- icon_dead = "rainbow baby slime dead"
-
-/mob/living/simple_animal/slime/science/Initialize()
- . = ..()
- overlays.Cut()
- overlays += "aslime-:33"
-
-/mob/living/simple_animal/adultslime
- name = "pet slime"
- desc = "A lovable, domesticated slime."
- icon = 'icons/mob/slimes.dmi'
- icon_state = "grey adult slime"
- icon_living = "grey adult slime"
- icon_dead = "grey baby slime dead"
-
- maxHealth = 200
- health = 200
-
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "stomps on"
-
- speak_chance = 1
- emote_see = list("jiggles", "bounces in place")
-
- var/colour = "grey"
-
-/mob/living/simple_animal/adultslime/New()
- ..()
- overlays += "aslime-:33"
-
-/mob/living/simple_animal/adultslime/death()
- var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
- S1.icon_state = "[src.colour] baby slime"
- S1.icon_living = "[src.colour] baby slime"
- S1.icon_dead = "[src.colour] baby slime dead"
- S1.colour = "[src.colour]"
- var/mob/living/simple_animal/slime/S2 = new /mob/living/simple_animal/slime (src.loc)
- S2.icon_state = "[src.colour] baby slime"
- S2.icon_living = "[src.colour] baby slime"
- S2.icon_dead = "[src.colour] baby slime dead"
- S2.colour = "[src.colour]"
- qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
deleted file mode 100644
index 5aa5f50e94..0000000000
--- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm
+++ /dev/null
@@ -1,302 +0,0 @@
-/mob/living/simple_animal/spiderbot
- name = "spider-bot"
- desc = "A skittering robotic friend!"
- tt_desc = "Maintenance Robot"
- icon = 'icons/mob/robots.dmi'
- icon_state = "spiderbot-chassis"
- icon_living = "spiderbot-chassis"
- icon_dead = "spiderbot-smashed"
- intelligence_level = SA_HUMANOID // Because its piloted by players.
-
- health = 10
- maxHealth = 10
-
- wander = 0
- speed = -1 //Spiderbots gotta go fast.
- pass_flags = PASSTABLE
- mob_size = MOB_SMALL
-
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "stomps on"
-
- melee_damage_lower = 1
- melee_damage_upper = 3
- attacktext = list("shocked")
-
- min_oxy = 0
- max_tox = 0
- max_co2 = 0
- minbodytemp = 0
- maxbodytemp = 500
-
- speak_chance = 1
- speak_emote = list("beeps","clicks","chirps")
-
- var/obj/item/device/radio/borg/radio = null
- var/mob/living/silicon/ai/connected_ai = null
- var/obj/item/weapon/cell/cell = null
- var/obj/machinery/camera/camera = null
- var/obj/item/device/mmi/mmi = null
- var/list/req_access = list(access_robotics) //Access needed to pop out the brain.
- var/positronic
-
- can_enter_vent_with = list(
- /obj/item/weapon/implant,
- /obj/item/device/radio/borg,
- /obj/item/weapon/holder,
- /obj/machinery/camera,
- /mob/living/simple_mob/animal/borer,
- /obj/item/device/mmi,
- )
-
- var/emagged = 0
- var/obj/item/held_item = null //Storage for single item they can hold.
-
-/mob/living/simple_animal/spiderbot/New()
- ..()
- add_language(LANGUAGE_GALCOM)
- default_language = all_languages[LANGUAGE_GALCOM]
- verbs |= /mob/living/proc/ventcrawl
- verbs |= /mob/living/proc/hide
-
-/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
-
- if(istype(O, /obj/item/device/mmi))
- var/obj/item/device/mmi/B = O
- if(src.mmi)
- user << "There's already a brain in [src]!"
- return
- if(!B.brainmob)
- user << "Sticking an empty MMI into the frame would sort of defeat the purpose."
- return
- if(!B.brainmob.key)
- var/ghost_can_reenter = 0
- if(B.brainmob.mind)
- for(var/mob/observer/dead/G in player_list)
- if(G.can_reenter_corpse && G.mind == B.brainmob.mind)
- ghost_can_reenter = 1
- break
- if(!ghost_can_reenter)
- user << "[O] is completely unresponsive; there's no point."
- return
-
- if(B.brainmob.stat == DEAD)
- user << "[O] is dead. Sticking it into the frame would sort of defeat the purpose."
- return
-
- if(jobban_isbanned(B.brainmob, "Cyborg"))
- user << "\The [O] does not seem to fit."
- return
-
- user << "You install \the [O] in \the [src]!"
-
- if(istype(O, /obj/item/device/mmi/digital))
- positronic = 1
- add_language("Robot Talk")
-
- user.drop_item()
- src.mmi = O
- src.transfer_personality(O)
-
- O.forceMove(src)
- src.update_icon()
- return 1
-
- if (istype(O, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = O
- if (WT.remove_fuel(0))
- if(health < getMaxHealth())
- health += pick(1,1,1,2,2,3)
- if(health > getMaxHealth())
- health = getMaxHealth()
- add_fingerprint(user)
- src.visible_message("\The [user] has spot-welded some of the damage to \the [src]!")
- else
- user << "\The [src] is undamaged!"
- else
- user << "You need more welding fuel for this task!"
- return
- else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda))
- if (!mmi)
- user << "There's no reason to swipe your ID - \the [src] has no brain to remove."
- return 0
-
- var/obj/item/weapon/card/id/id_card
-
- if(istype(O, /obj/item/weapon/card/id))
- id_card = O
- else
- var/obj/item/device/pda/pda = O
- id_card = pda.id
-
- if(access_robotics in id_card.access)
- user << "You swipe your access card and pop the brain out of \the [src]."
- eject_brain()
- if(held_item)
- held_item.forceMove(src.loc)
- held_item = null
- return 1
- else
- user << "You swipe your card with no effect."
- return 0
-
- else
- O.attack(src, user, user.zone_sel.selecting)
-
-/mob/living/simple_animal/spiderbot/emag_act(var/remaining_charges, var/mob/user)
- if (emagged)
- user << "[src] is already overloaded - better run."
- return 0
- else
- user << "You short out the security protocols and overload [src]'s cell, priming it to explode in a short time."
- spawn(100)
- to_chat(src, "Your cell seems to be outputting a lot of power...")
- spawn(200)
- to_chat(src, "Internal heat sensors are spiking! Something is badly wrong with your cell!")
- spawn(300) src.explode()
-
-/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj)
-
- src.mind = M.brainmob.mind
- src.mind.key = M.brainmob.key
- src.ckey = M.brainmob.ckey
- src.name = "spider-bot ([M.brainmob.name])"
- src.languages = M.brainmob.languages
-
-/mob/living/simple_animal/spiderbot/proc/explode() //When emagged.
- src.visible_message("\The [src] makes an odd warbling noise, fizzles, and explodes!")
- explosion(get_turf(loc), -1, -1, 3, 5)
- eject_brain()
- death()
-
-/mob/living/simple_animal/spiderbot/update_icon()
- if(mmi)
- if(positronic)
- icon_state = "spiderbot-chassis-posi"
- icon_living = "spiderbot-chassis-posi"
- else
- icon_state = "spiderbot-chassis-mmi"
- icon_living = "spiderbot-chassis-mmi"
- else
- icon_state = "spiderbot-chassis"
- icon_living = "spiderbot-chassis"
-
-/mob/living/simple_animal/spiderbot/proc/eject_brain()
- if(mmi)
- var/turf/T = get_turf(loc)
- if(T)
- mmi.forceMove(T)
- if(mind) mind.transfer_to(mmi.brainmob)
- mmi = null
- real_name = initial(real_name)
- name = real_name
- update_icon()
- remove_language("Robot Talk")
- positronic = null
-
-/mob/living/simple_animal/spiderbot/Destroy()
- eject_brain()
- ..()
-
-/mob/living/simple_animal/spiderbot/New()
-
- radio = new /obj/item/device/radio/borg(src)
- camera = new /obj/machinery/camera(src)
- camera.c_tag = "spiderbot-[real_name]"
- camera.replace_networks(list("SS13"))
-
- ..()
-
-/mob/living/simple_animal/spiderbot/death()
-
- living_mob_list -= src
- dead_mob_list += src
-
- if(camera)
- camera.status = 0
-
- held_item.forceMove(src.loc)
- held_item = null
-
- gibs(loc, null, null, /obj/effect/gibspawner/robot) //TODO: use gib() or refactor spiderbots into synthetics.
- qdel(src)
- return
-
-//Cannibalized from the parrot mob. ~Zuhayr
-/mob/living/simple_animal/spiderbot/verb/drop_held_item()
- set name = "Drop held item"
- set category = "Spiderbot"
- set desc = "Drop the item you're holding."
-
- if(stat)
- return
-
- if(!held_item)
- usr << "You have nothing to drop!"
- return 0
-
- if(istype(held_item, /obj/item/weapon/grenade))
- visible_message("\The [src] launches \the [held_item]!", \
- "You launch \the [held_item]!", \
- "You hear a skittering noise and a thump!")
- var/obj/item/weapon/grenade/G = held_item
- G.forceMove(src.loc)
- G.detonate()
- held_item = null
- return 1
-
- visible_message("\The [src] drops \the [held_item].", \
- "You drop \the [held_item].", \
- "You hear a skittering noise and a soft thump.")
-
- held_item.forceMove(src.loc)
- held_item = null
- return 1
-
- return
-
-/mob/living/simple_animal/spiderbot/verb/get_item()
- set name = "Pick up item"
- set category = "Spiderbot"
- set desc = "Allows you to take a nearby small item."
-
- if(stat)
- return -1
-
- if(held_item)
- to_chat(src, "You are already holding \the [held_item]")
- return 1
-
- var/list/items = list()
- for(var/obj/item/I in view(1,src))
- if(I.loc != src && I.w_class <= ITEMSIZE_SMALL && I.Adjacent(src) )
- items.Add(I)
-
- var/obj/selection = input("Select an item.", "Pickup") in items
-
- if(selection)
- for(var/obj/item/I in view(1, src))
- if(selection == I)
- held_item = selection
- selection.forceMove(src)
- visible_message("\The [src] scoops up \the [held_item].", \
- "You grab \the [held_item].", \
- "You hear a skittering noise and a clink.")
- return held_item
- to_chat(src, "\The [selection] is too far away.")
- return 0
-
- to_chat(src, "There is nothing of interest to take.")
- return 0
-
-/mob/living/simple_animal/spiderbot/examine(mob/user)
- ..(user)
- if(src.held_item)
- user << "It is carrying \icon[src.held_item] \a [src.held_item]."
-
-/mob/living/simple_animal/spiderbot/cannot_use_vents()
- return
-
-/mob/living/simple_animal/spiderbot/binarycheck()
- return positronic
diff --git a/code/modules/mob/living/simple_animal/animals/tomato.dm b/code/modules/mob/living/simple_animal/animals/tomato.dm
deleted file mode 100644
index 711922eeb0..0000000000
--- a/code/modules/mob/living/simple_animal/animals/tomato.dm
+++ /dev/null
@@ -1,24 +0,0 @@
-/mob/living/simple_animal/hostile/tomato
- name = "tomato"
- desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!"
- tt_desc = "X Solanum abominable"
- icon_state = "tomato"
- icon_living = "tomato"
- icon_dead = "tomato_dead"
- intelligence_level = SA_PLANT
-
- faction = "plants"
- maxHealth = 15
- health = 15
- turns_per_move = 5
-
- response_help = "prods"
- response_disarm = "pushes aside"
- response_harm = "smacks"
-
- harm_intent_damage = 5
- melee_damage_upper = 15
- melee_damage_lower = 10
- attacktext = list("mauled")
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat
diff --git a/code/modules/mob/living/simple_animal/animals/tree.dm b/code/modules/mob/living/simple_animal/animals/tree.dm
deleted file mode 100644
index 09c8451811..0000000000
--- a/code/modules/mob/living/simple_animal/animals/tree.dm
+++ /dev/null
@@ -1,60 +0,0 @@
-/mob/living/simple_animal/hostile/tree
- name = "pine tree"
- desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
- tt_desc = "X Festivus tyrannus"
- icon = 'icons/obj/flora/pinetrees.dmi'
- icon_state = "pine_1"
- icon_living = "pine_1"
- icon_dead = "pine_1"
- icon_gib = "pine_1"
- intelligence_level = SA_PLANT
-
- faction = "carp" //Trees can be carp friends?
- maxHealth = 250
- health = 250
- speed = -1
-
- turns_per_move = 5
-
- response_help = "brushes"
- response_disarm = "pushes"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 8
- melee_damage_upper = 12
- attacktext = list("bitten")
- attack_sound = 'sound/weapons/bite.ogg'
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
-
- pixel_x = -16
-
-/mob/living/simple_animal/hostile/tree/FindTarget()
- . = ..()
- if(.)
- audible_emote("growls at [.]")
-
-/mob/living/simple_animal/hostile/tree/PunchTarget()
- . =..()
- var/mob/living/L = .
- if(istype(L))
- if(prob(15))
- L.Weaken(3)
- L.visible_message("\the [src] knocks down \the [L]!")
-
-/mob/living/simple_animal/hostile/tree/death()
- ..(null,"is hacked into pieces!")
- playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
- new /obj/item/stack/material/wood(loc)
- qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/animals/worm.dm b/code/modules/mob/living/simple_animal/animals/worm.dm
deleted file mode 100644
index da30dbf8fd..0000000000
--- a/code/modules/mob/living/simple_animal/animals/worm.dm
+++ /dev/null
@@ -1,199 +0,0 @@
-/mob/living/simple_animal/space_worm
- name = "space worm segment"
- desc = "A part of a space worm."
- icon = 'icons/mob/animal.dmi'
- icon_state = "spaceworm"
- icon_living = "spaceworm"
- icon_dead = "spacewormdead"
- intelligence_level = SA_ANIMAL
-
-
- maxHealth = 30
- health = 30
- speed = -1
-
- status_flags = 0
- universal_speak = 1
- stop_automated_movement = 1
- wander = 0
- animate_movement = SYNC_STEPS
-
- response_help = "touches"
- response_disarm = "flails at"
- response_harm = "punches the"
-
- harm_intent_damage = 2
-
- minbodytemp = 0
- maxbodytemp = 350
- min_oxy = 0
- max_co2 = 0
- max_tox = 0
-
- environment_smash = 2
-
- speak_emote = list("transmits") //not supposed to be used under AI control
- emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks
-
- var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly
- var/mob/living/simple_animal/space_worm/next //head is the nextest segment
-
- var/stomachProcessProbability = 50
- var/digestionProbability = 20
- var/flatPlasmaValue = 5 //flat plasma amount given for non-items
-
- var/atom/currentlyEating //what the worm is currently eating
- var/eatingDuration = 0 //how long he's been eating it for
-
- head
- name = "space worm head"
- icon_state = "spacewormhead"
- icon_living = "spacewormhead"
- icon_dead = "spacewormdead"
-
- maxHealth = 20
- health = 20
-
- melee_damage_lower = 10
- melee_damage_upper = 15
- attacktext = list("bitten")
-
- animate_movement = SLIDE_STEPS
-
- New(var/location, var/segments = 6)
- ..()
-
- var/mob/living/simple_animal/space_worm/current = src
-
- for(var/i = 1 to segments)
- var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc)
- current.Attach(newSegment)
- current = newSegment
-
- update_icon()
- if(stat == CONSCIOUS || stat == UNCONSCIOUS)
- icon_state = "spacewormhead[previous?1:0]"
- if(previous)
- set_dir(get_dir(previous,src))
- else
- icon_state = "spacewormheaddead"
-
- Life()
- ..()
-
- if(next && !(next in view(src,1)))
- Detach()
-
- if(stat == DEAD) //dead chunks fall off and die immediately
- if(previous)
- previous.Detach()
- if(next)
- Detach(1)
-
- if(prob(stomachProcessProbability))
- ProcessStomach()
-
- update_icon()
-
- return
-
- Destroy() //if a chunk a destroyed, make a new worm out of the split halves
- if(previous)
- previous.Detach()
- ..()
-
- Move()
- var/attachementNextPosition = loc
- if(..())
- if(previous)
- previous.Move(attachementNextPosition)
- update_icon()
-
- Bump(atom/obstacle)
- if(currentlyEating != obstacle)
- currentlyEating = obstacle
- eatingDuration = 0
-
- if(!AttemptToEat(obstacle))
- eatingDuration++
- else
- currentlyEating = null
- eatingDuration = 0
-
- return
-
- update_icon() //only for the sake of consistency with the other update icon procs
- if(stat == CONSCIOUS || stat == UNCONSCIOUS)
- if(previous) //midsection
- icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below
- else //tail
- icon_state = "spacewormtail"
- set_dir(get_dir(src,next)) //next will always be present since it's not a head and if it's dead, it goes in the other if branch
- else
- icon_state = "spacewormdead"
-
- return
-
- proc/AttemptToEat(var/atom/target)
- if(istype(target,/turf/simulated/wall))
- var/turf/simulated/wall/W = target
- if((!W.reinf_material && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
- W.dismantle_wall()
- return 1
- else if(istype(target,/atom/movable))
- if(istype(target,/mob) || eatingDuration >= 50) //5 ticks to eat stuff like airlocks
- var/atom/movable/objectOrMob = target
- contents += objectOrMob
- return 1
-
- return 0
-
- proc/Attach(var/mob/living/simple_animal/space_worm/attachement)
- if(!attachement)
- return
-
- previous = attachement
- attachement.next = src
-
- return
-
- proc/Detach(die = 0)
- var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0)
- var/mob/living/simple_animal/space_worm/newHeadPrevious = previous
-
- previous = null //so that no extra heads are spawned
-
- newHead.Attach(newHeadPrevious)
-
- if(die)
- newHead.death()
-
- qdel(src)
-
- proc/ProcessStomach()
- for(var/atom/movable/stomachContent in contents)
- if(prob(digestionProbability))
- if(istype(stomachContent,/obj/item/stack)) //converts to plasma, keeping the stack value
- if(!istype(stomachContent,/obj/item/stack/material/phoron))
- var/obj/item/stack/oldStack = stomachContent
- new /obj/item/stack/material/phoron(src, oldStack.get_amount())
- qdel(oldStack)
- continue
- else if(istype(stomachContent,/obj/item)) //converts to plasma, keeping the w_class
- var/obj/item/oldItem = stomachContent
- new /obj/item/stack/material/phoron(src, oldItem.w_class)
- qdel(oldItem)
- continue
- else
- new /obj/item/stack/material/phoron(src, flatPlasmaValue) //just flat amount
- qdel(stomachContent)
- continue
-
- if(previous)
- for(var/atom/movable/stomachContent in contents) //transfer it along the digestive tract
- previous.contents += stomachContent
- else
- for(var/atom/movable/stomachContent in contents) //or poop it out
- loc.contents += stomachContent
-
- return
diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm
deleted file mode 100644
index 8b28544b9e..0000000000
--- a/code/modules/mob/living/simple_animal/borer/borer.dm
+++ /dev/null
@@ -1,213 +0,0 @@
-/mob/living/simple_mob/animal/borer
- name = "cortical borer"
- real_name = "cortical borer"
- desc = "A small, quivering sluglike creature."
- speak_emote = list("chirrups")
- emote_hear = list("chirrups")
- intelligence_level = SA_HUMANOID // Player controlled.
- response_help = "pokes"
- response_disarm = "prods"
- response_harm = "stomps on"
- icon_state = "brainslug"
- item_state = "brainslug"
- icon_living = "brainslug"
- icon_dead = "brainslug_dead"
- speed = 5
- a_intent = I_HURT
- stop_automated_movement = 1
- status_flags = CANPUSH
- attacktext = list("nipped")
- friendly = "prods"
- wander = 0
- pass_flags = PASSTABLE
- universal_understand = 1
- holder_type = /obj/item/weapon/holder/borer
-
- var/used_dominate
- var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin.
- var/mob/living/carbon/human/host // Human host for the brain worm.
- var/truename // Name used for brainworm-speak.
- var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth.
- var/controlling // Used in human death check.
- var/docile = 0 // Sugar can stop borers from acting.
- var/has_reproduced
- var/roundstart
-
- can_be_antagged = TRUE
-
-/mob/living/simple_mob/animal/borer/roundstart
- roundstart = 1
-
-/mob/living/simple_mob/animal/borer/Login()
- ..()
- if(mind)
- borers.add_antagonist(mind)
-
-/mob/living/simple_mob/animal/borer/New()
- ..()
-
- add_language("Cortical Link")
- verbs += /mob/living/proc/ventcrawl
- verbs += /mob/living/proc/hide
-
- truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]"
- if(!roundstart) request_player()
-
-/mob/living/simple_mob/animal/borer/Life()
-
- ..()
-
- if(host)
-
- if(!stat && !host.stat)
-
- if(host.reagents.has_reagent("sugar"))
- if(!docile)
- if(controlling)
- host << "You feel the soporific flow of sugar in your host's blood, lulling you into docility."
- else
- to_chat(src, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.")
- docile = 1
- else
- if(docile)
- if(controlling)
- host << "You shake off your lethargy as the sugar leaves your host's blood."
- else
- to_chat(src, "You shake off your lethargy as the sugar leaves your host's blood.")
- docile = 0
-
- if(chemicals < 250)
- chemicals++
- if(controlling)
-
- if(docile)
- host << "You are feeling far too docile to continue controlling your host..."
- host.release_control()
- return
-
- if(prob(5))
- host.adjustBrainLoss(0.1)
-
- if(prob(host.brainloss/20))
- host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]")
-
-/mob/living/simple_mob/animal/borer/Stat()
- ..()
- statpanel("Status")
-
- if(emergency_shuttle)
- var/eta_status = emergency_shuttle.get_status_panel_eta()
- if(eta_status)
- stat(null, eta_status)
-
- if (client.statpanel == "Status")
- stat("Chemicals", chemicals)
-
-/mob/living/simple_mob/animal/borer/proc/detatch()
-
- if(!host || !controlling) return
-
- if(istype(host,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = host
- var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
- head.implants -= src
-
- controlling = 0
-
- host.remove_language("Cortical Link")
- host.verbs -= /mob/living/carbon/proc/release_control
- host.verbs -= /mob/living/carbon/proc/punish_host
- host.verbs -= /mob/living/carbon/proc/spawn_larvae
-
- if(host_brain)
-
- // these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
- // computer_id and IP are not updated magically on their own in offline mobs -walter0o
-
- // host -> self
- var/h2s_id = host.computer_id
- var/h2s_ip= host.lastKnownIP
- host.computer_id = null
- host.lastKnownIP = null
-
- src.ckey = host.ckey
-
- if(!src.computer_id)
- src.computer_id = h2s_id
-
- if(!host_brain.lastKnownIP)
- src.lastKnownIP = h2s_ip
-
- // brain -> host
- var/b2h_id = host_brain.computer_id
- var/b2h_ip= host_brain.lastKnownIP
- host_brain.computer_id = null
- host_brain.lastKnownIP = null
-
- host.ckey = host_brain.ckey
-
- if(!host.computer_id)
- host.computer_id = b2h_id
-
- if(!host.lastKnownIP)
- host.lastKnownIP = b2h_ip
-
- qdel(host_brain)
-
-/mob/living/simple_mob/animal/borer/proc/leave_host()
-
- if(!host) return
-
- if(host.mind)
- borers.remove_antagonist(host.mind)
-
- src.forceMove(get_turf(host))
-
- reset_view(null)
- machine = null
-
- host.reset_view(null)
- host.machine = null
- host = null
- return
-
-//Procs for grabbing players.
-/mob/living/simple_mob/animal/borer/proc/request_player()
- for(var/mob/observer/dead/O in player_list)
- if(jobban_isbanned(O, "Borer"))
- continue
- if(O.client)
- if(O.client.prefs.be_special & BE_ALIEN)
- question(O.client)
-
-/mob/living/simple_mob/animal/borer/proc/question(var/client/C)
- spawn(0)
- if(!C) return
- var/response = alert(C, "A cortical borer needs a player. Are you interested?", "Cortical borer request", "Yes", "No", "Never for this round")
- if(!C || ckey)
- return
- if(response == "Yes")
- transfer_personality(C)
- else if (response == "Never for this round")
- C.prefs.be_special ^= BE_ALIEN
-
-/mob/living/simple_mob/animal/borer/proc/transfer_personality(var/client/candidate)
-
- if(!candidate || !candidate.mob || !candidate.mob.mind)
- return
-
- src.mind = candidate.mob.mind
- candidate.mob.mind.current = src
- src.ckey = candidate.ckey
-
- if(src.mind)
- src.mind.assigned_role = "Cortical Borer"
- src.mind.special_role = "Cortical Borer"
-
- to_chat(src, "You are a cortical borer! You are a brain slug that worms its way \
- into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, \
- your host and your eventual spawn safe and warm.")
- to_chat(src, "You can speak to your victim with say, to other borers with say :x, and use your Abilities tab to access powers.")
-
-/mob/living/simple_mob/animal/borer/cannot_use_vents()
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm
deleted file mode 100644
index c7088bc715..0000000000
--- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm
+++ /dev/null
@@ -1,57 +0,0 @@
-/mob/living/captive_brain
- name = "host brain"
- real_name = "host brain"
- universal_understand = 1
-
-/mob/living/captive_brain/say(var/message)
-
- if (src.client)
- if(client.prefs.muted & MUTE_IC)
- to_chat(src, "You cannot speak in IC (muted).")
- return
-
- if(istype(src.loc,/mob/living/simple_mob/animal/borer))
-
- message = sanitize(message)
- if (!message)
- return
- log_say(message,src)
- if (stat == 2)
- return say_dead(message)
-
- var/mob/living/simple_mob/animal/borer/B = src.loc
- to_chat(src, "You whisper silently, \"[message]\"")
- B.host << "The captive mind of [src] whispers, \"[message]\""
-
- for (var/mob/M in player_list)
- if (istype(M, /mob/new_player))
- continue
- else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
- M << "The captive mind of [src] whispers, \"[message]\""
-
-/mob/living/captive_brain/emote(var/message)
- return
-
-/mob/living/captive_brain/process_resist()
- //Resisting control by an alien mind.
- if(istype(src.loc,/mob/living/simple_mob/animal/borer))
- var/mob/living/simple_mob/animal/borer/B = src.loc
- var/mob/living/captive_brain/H = src
-
- H << "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)."
- B.host << "You feel the captive mind of [src] begin to resist your control."
-
- spawn(rand(200,250)+B.host.brainloss)
- if(!B || !B.controlling) return
-
- B.host.adjustBrainLoss(rand(0.1,0.5))
- H << "With an immense exertion of will, you regain control of your body!"
- B.host << "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you."
- B.detatch()
- verbs -= /mob/living/carbon/proc/release_control
- verbs -= /mob/living/carbon/proc/punish_host
- verbs -= /mob/living/carbon/proc/spawn_larvae
-
- return
-
- ..()
diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm
deleted file mode 100644
index d5575f78e7..0000000000
--- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm
+++ /dev/null
@@ -1,337 +0,0 @@
-/mob/living/simple_mob/animal/borer/verb/release_host()
- set category = "Abilities"
- set name = "Release Host"
- set desc = "Slither out of your host."
-
- if(!host)
- to_chat(src, "You are not inside a host body.")
- return
-
- if(stat)
- to_chat(src, "You cannot leave your host in your current state.")
-
- if(docile)
- to_chat(src, "You are feeling far too docile to do that.")
- return
-
- if(!host || !src) return
-
- to_chat(src, "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal.")
-
- if(!host.stat)
- host << "An odd, uncomfortable pressure begins to build inside your skull, behind your ear..."
-
- spawn(100)
-
- if(!host || !src) return
-
- if(src.stat)
- to_chat(src, "You cannot release your host in your current state.")
- return
-
- to_chat(src, "You wiggle out of [host]'s ear and plop to the ground.")
- if(host.mind)
- if(!host.stat)
- host << "Something slimy wiggles out of your ear and plops to the ground!"
- host << "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again."
-
- detatch()
- leave_host()
-
-/mob/living/simple_mob/animal/borer/verb/infest()
- set category = "Abilities"
- set name = "Infest"
- set desc = "Infest a suitable humanoid host."
-
- if(host)
- to_chat(src, "You are already within a host.")
- return
-
- if(stat)
- to_chat(src, "You cannot infest a target in your current state.")
- return
-
- var/list/choices = list()
- for(var/mob/living/carbon/C in view(1,src))
- if(src.Adjacent(C))
- choices += C
-
- if(!choices.len)
- to_chat(src, "There are no viable hosts within range...")
- return
-
- var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices
-
- if(!M || !src) return
-
- if(!(src.Adjacent(M))) return
-
- if(M.has_brain_worms())
- to_chat(src, "You cannot infest someone who is already infested!")
- return
-
- if(istype(M,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
-
- var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD]
- if(!E || E.is_stump())
- to_chat(src, "\The [H] does not have a head!")
-
- if(!H.should_have_organ("brain"))
- to_chat(src, "\The [H] does not seem to have an ear canal to breach.")
- return
-
- if(H.check_head_coverage())
- to_chat(src, "You cannot get through that host's protective gear.")
- return
-
- M << "Something slimy begins probing at the opening of your ear canal..."
- to_chat(src, "You slither up [M] and begin probing at their ear canal...")
-
- if(!do_after(src,30))
- to_chat(src, "As [M] moves away, you are dislodged and fall to the ground.")
- return
-
- if(!M || !src) return
-
- if(src.stat)
- to_chat(src, "You cannot infest a target in your current state.")
- return
-
- if(M in view(1, src))
- to_chat(src, "You wiggle into [M]'s ear.")
- if(!M.stat)
- M << "Something disgusting and slimy wiggles into your ear!"
-
- src.host = M
- src.forceMove(M)
-
- //Update their traitor status.
- if(host.mind)
- borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome)
-
- if(istype(M,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- var/obj/item/organ/I = H.internal_organs_by_name["brain"]
- if(!I) // No brain organ, so the borer moves in and replaces it permanently.
- replace_brain()
- else
- // If they're in normally, implant removal can get them out.
- var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
- head.implants += src
-
- return
- else
- to_chat(src, "They are no longer in range!")
- return
-
-/*
-/mob/living/simple_mob/animal/borer/verb/devour_brain()
- set category = "Abilities"
- set name = "Devour Brain"
- set desc = "Take permanent control of a dead host."
-
- if(!host)
- to_chat(src, "You are not inside a host body.")
- return
-
- if(host.stat != 2)
- to_chat(src, "Your host is still alive.")
- return
-
- if(stat)
- to_chat(src, "You cannot do that in your current state.")
-
- if(docile)
- to_chat(src, "You are feeling far too docile to do that.")
- return
-
-
- to_chat(src, "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry...")
- replace_brain()
-*/
-
-// BRAIN WORM ZOMBIES AAAAH.
-/mob/living/simple_mob/animal/borer/proc/replace_brain()
-
- var/mob/living/carbon/human/H = host
-
- if(!istype(host))
- to_chat(src, "This host does not have a suitable brain.")
- return
-
- to_chat(src, "You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H].")
-
- H.add_language("Cortical Link")
-
- if(host.stat == 2)
- H.verbs |= /mob/living/carbon/human/proc/jumpstart
-
- H.verbs |= /mob/living/carbon/human/proc/psychic_whisper
- H.verbs |= /mob/living/carbon/human/proc/tackle
- H.verbs |= /mob/living/carbon/proc/spawn_larvae
-
- if(H.client)
- H.ghostize(0)
-
- if(src.mind)
- src.mind.special_role = "Borer Husk"
- src.mind.transfer_to(host)
-
- H.ChangeToHusk()
-
- var/obj/item/organ/internal/borer/B = new(H)
- H.internal_organs_by_name["brain"] = B
- H.internal_organs |= B
-
- var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD)
- affecting.implants -= src
-
- var/s2h_id = src.computer_id
- var/s2h_ip= src.lastKnownIP
- src.computer_id = null
- src.lastKnownIP = null
-
- if(!H.computer_id)
- H.computer_id = s2h_id
-
- if(!H.lastKnownIP)
- H.lastKnownIP = s2h_ip
-
-/mob/living/simple_mob/animal/borer/verb/secrete_chemicals()
- set category = "Abilities"
- set name = "Secrete Chemicals"
- set desc = "Push some chemicals into your host's bloodstream."
-
- if(!host)
- to_chat(src, "You are not inside a host body.")
- return
-
- if(stat)
- to_chat(src, "You cannot secrete chemicals in your current state.")
-
- if(docile)
- to_chat(src, "You are feeling far too docile to do that.")
- return
-
- if(chemicals < 50)
- to_chat(src, "You don't have enough chemicals!")
-
- var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol")
-
- if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check.
- return
-
- to_chat(src, "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream.")
- host.reagents.add_reagent(chem, 10)
- chemicals -= 50
-
-/mob/living/simple_mob/animal/borer/verb/dominate_victim()
- set category = "Abilities"
- set name = "Paralyze Victim"
- set desc = "Freeze the limbs of a potential host with supernatural fear."
-
- if(world.time - used_dominate < 150)
- to_chat(src, "You cannot use that ability again so soon.")
- return
-
- if(host)
- to_chat(src, "You cannot do that from within a host body.")
- return
-
- if(src.stat)
- to_chat(src, "You cannot do that in your current state.")
- return
-
- var/list/choices = list()
- for(var/mob/living/carbon/C in view(3,src))
- if(C.stat != 2)
- choices += C
-
- if(world.time - used_dominate < 150)
- to_chat(src, "You cannot use that ability again so soon.")
- return
-
- var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices
-
- if(!M || !src) return
-
- if(M.has_brain_worms())
- to_chat(src, "You cannot infest someone who is already infested!")
- return
-
- to_chat(src, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.")
- M << "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing."
- M.Weaken(10)
-
- used_dominate = world.time
-
-/mob/living/simple_mob/animal/borer/verb/bond_brain()
- set category = "Abilities"
- set name = "Assume Control"
- set desc = "Fully connect to the brain of your host."
-
- if(!host)
- to_chat(src, "You are not inside a host body.")
- return
-
- if(src.stat)
- to_chat(src, "You cannot do that in your current state.")
- return
-
- if(docile)
- to_chat(src, "You are feeling far too docile to do that.")
- return
-
- to_chat(src, "You begin delicately adjusting your connection to the host brain...")
-
- spawn(100+(host.brainloss*5))
-
- if(!host || !src || controlling)
- return
- else
-
- to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.")
- host << "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours."
- host.add_language("Cortical Link")
-
- // host -> brain
- var/h2b_id = host.computer_id
- var/h2b_ip= host.lastKnownIP
- host.computer_id = null
- host.lastKnownIP = null
-
- qdel(host_brain)
- host_brain = new(src)
-
- host_brain.ckey = host.ckey
-
- host_brain.name = host.name
-
- if(!host_brain.computer_id)
- host_brain.computer_id = h2b_id
-
- if(!host_brain.lastKnownIP)
- host_brain.lastKnownIP = h2b_ip
-
- // self -> host
- var/s2h_id = src.computer_id
- var/s2h_ip= src.lastKnownIP
- src.computer_id = null
- src.lastKnownIP = null
-
- host.ckey = src.ckey
-
- if(!host.computer_id)
- host.computer_id = s2h_id
-
- if(!host.lastKnownIP)
- host.lastKnownIP = s2h_ip
-
- controlling = 1
-
- host.verbs += /mob/living/carbon/proc/release_control
- host.verbs += /mob/living/carbon/proc/punish_host
- host.verbs += /mob/living/carbon/proc/spawn_larvae
-
- return
diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm
deleted file mode 100644
index 41229d9bd2..0000000000
--- a/code/modules/mob/living/simple_animal/borer/say.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-/mob/living/simple_mob/animal/borer/say(var/message)
-
- message = sanitize(message)
- message = capitalize(message)
-
- if(!message)
- return
-
- if (stat == 2)
- return say_dead(message)
-
- if (stat)
- return
-
- if (src.client)
- if(client.prefs.muted & MUTE_IC)
- to_chat(src, "You cannot speak in IC (muted).")
- return
-
- if (copytext(message, 1, 2) == "*")
- return emote(copytext(message, 2))
-
- var/datum/language/L = parse_language(message)
- if(L && L.flags & HIVEMIND)
- L.broadcast(src,trim(copytext(message,3)),src.truename)
- return
-
- if(!host)
- //TODO: have this pick a random mob within 3 tiles to speak for the borer.
- to_chat(src, "You have no host to speak to.")
- return //No host, no audible speech.
-
- to_chat(src, "You drop words into [host]'s mind: \"[message]\"")
- host << "Your own thoughts speak: \"[message]\""
-
- for (var/mob/M in player_list)
- if (istype(M, /mob/new_player))
- continue
- else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
- M << "[src.truename] whispers to [host], \"[message]\""
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/humanoids/clown.dm b/code/modules/mob/living/simple_animal/humanoids/clown.dm
deleted file mode 100644
index d94fa47c77..0000000000
--- a/code/modules/mob/living/simple_animal/humanoids/clown.dm
+++ /dev/null
@@ -1,49 +0,0 @@
-/mob/living/simple_animal/hostile/clown
- name = "clown"
- desc = "A denizen of clown planet"
- tt_desc = "E Homo sapiens corydon" //this is an actual clown, as opposed to someone dressed up as one
- icon_state = "clown"
- icon_living = "clown"
- icon_dead = "clown_dead"
- icon_gib = "clown_gib"
- intelligence_level = SA_HUMANOID
-
- faction = "clown"
- maxHealth = 75
- health = 75
- speed = -1
- move_to_delay = 2
-
- run_at_them = 0
- cooperative = 1
-
- turns_per_move = 5
- stop_when_pulled = 0
-
- response_help = "pokes"
- response_disarm = "gently pushes aside"
- response_harm = "hits"
-
- harm_intent_damage = 8
- melee_damage_lower = 10
- melee_damage_upper = 10
- attacktext = list("attacked")
- attack_sound = 'sound/items/bikehorn.ogg'
-
- min_oxy = 5
- max_oxy = 0
- min_tox = 0
- max_tox = 1
- min_co2 = 0
- max_co2 = 5
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 270
- maxbodytemp = 370
- heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
- cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- unsuitable_atoms_damage = 10
-
- speak_chance = 1
- speak = list("HONK", "Honk!", "Welcome to clown planet!")
- emote_see = list("honks")
diff --git a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm
deleted file mode 100644
index 1bc4b985a4..0000000000
--- a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm
+++ /dev/null
@@ -1,123 +0,0 @@
-/mob/living/simple_animal/hostile/mecha
- name = "mercenary gygax"
- desc = "Well that's forboding."
- icon = 'icons/mecha/mecha.dmi'
- icon_state = "darkgygax"
- icon_living = "darkgygax"
- icon_dead = "darkgygax-broken"
- intelligence_level = SA_HUMANOID // Piloted by a human.
-
- faction = "syndicate"
- maxHealth = 300
- health = 300
- speed = 7
- move_to_delay = 8
-
- run_at_them = 0
- cooperative = 1
- investigates = 1
- firing_lines = 1
-
- turns_per_move = 5
- stop_when_pulled = 0
-
- response_help = "taps on"
- response_disarm = "knocks on"
- response_harm = "uselessly hits"
-
- harm_intent_damage = 0
- melee_damage_lower = 35
- melee_damage_upper = 35
- attacktext = list("slashed")
- attack_sound = 'sound/weapons/bladeslice.ogg'
-
- armor = list(melee = 40, bullet = 40, laser = 50, energy = 45, bomb = 20, bio = 100, rad = 100) // As close to the actual Dark Gygax as possible
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- unsuitable_atoms_damage = 0
-
- ranged = 1
- rapid = 1
- projectiletype = /obj/item/projectile/beam/midlaser
- projectilesound = 'sound/weapons/laser.ogg'
-
- speak_chance = 1
- speak = list("Know what we need? More meatshields.",
- "Glad I finally got a mech.",
- "I'll stomp those NanoTrasen dogs into paste.",
- "Glad I didn't become a line chef.",
- "This anti-fog visor is nice...",
- "Did I refill the air tank?")
- emote_hear = list("humms ominously","whirrs softly","grinds a gear")
- emote_see = list("looks around the area","turns from side to side")
- say_understood = list()
- say_cannot = list()
- say_maybe_target = list("Just my sensors?","Detecting something?","Is that...?","What was that?")
- say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
- reactions = list()
-
- var/datum/effect/effect/system/spark_spread/sparks
- var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark
-
-/mob/living/simple_animal/hostile/mecha/New()
- ..()
- sparks = new (src)
- sparks.set_up(3, 1, src)
-
-/mob/living/simple_animal/hostile/mecha/Destroy()
- qdel(sparks)
- ..()
-
-/mob/living/simple_animal/hostile/mecha/Life()
- . = ..()
- if(!.) return
- if((health < getMaxHealth()*0.3) && prob(10))
- sparks.start()
-
-/mob/living/simple_animal/hostile/mecha/bullet_act()
- ..()
- sparks.start()
-
-/mob/living/simple_animal/hostile/mecha/death()
- ..(0,"explodes!")
- sparks.start()
- explosion(get_turf(src), 0, 0, 1, 3)
- qdel(src)
- new /obj/effect/decal/mecha_wreckage/gygax/dark(get_turf(src))
-
-/mob/living/simple_animal/hostile/mecha/Move()
- ..()
- playsound(src,'sound/mecha/mechstep.ogg',40,1)
-
-// This is a PoI mob, not the normal, floaty drones that hang out around windows
-/mob/living/simple_animal/hostile/mecha/malf_drone
- name = "autonomous mechanized drone"
- desc = "It appears to be an exosuit, piloted by a drone intelligence. It looks scary."
- intelligence_level = SA_ROBOTIC
- faction = "malf_drone"
- speak_chance = 1
- speak = list(
- "Resuming task: Protect area.",
- "No threats found.",
- "Error: No targets found."
- )
- emote_hear = list("humms ominously", "whirrs softly", "grinds a gear")
- emote_see = list("looks around the area", "turns from side to side")
- say_understood = list("Affirmative.", "Positive.")
- say_cannot = list("Denied.", "Negative.")
- say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
- say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
- returns_home = TRUE
-
-/mob/living/simple_animal/hostile/mecha/malf_drone/isSynthetic()
- return TRUE
-
-/mob/living/simple_animal/hostile/mecha/malf_drone/speech_bubble_appearance()
- return "synthetic_evil"
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/humanoids/pirate.dm b/code/modules/mob/living/simple_animal/humanoids/pirate.dm
deleted file mode 100644
index a02e4382bb..0000000000
--- a/code/modules/mob/living/simple_animal/humanoids/pirate.dm
+++ /dev/null
@@ -1,72 +0,0 @@
-/mob/living/simple_animal/hostile/pirate
- name = "Pirate"
- desc = "Does what he wants cause a pirate is free."
- tt_desc = "E Homo sapiens"
- icon_state = "piratemelee"
- icon_living = "piratemelee"
- icon_dead = "piratemelee_dead"
- intelligence_level = SA_HUMANOID
-
- faction = "pirate"
- maxHealth = 100
- health = 100
- speed = 4
-
- run_at_them = 0
- cooperative = 1
- investigates = 1
- firing_lines = 1
- returns_home = 1
- reacts = 1
-
- turns_per_move = 5
- stop_when_pulled = 0
-
- response_help = "pushes"
- response_disarm = "shoves"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 30
- melee_damage_upper = 30
- attack_armor_pen = 50
- attack_sharp = 1
- attack_edge = 1
-
- attacktext = list("slashed")
- attack_sound = 'sound/weapons/bladeslice.ogg'
-
- min_oxy = 5
- max_oxy = 0
- min_tox = 0
- max_tox = 1
- min_co2 = 0
- max_co2 = 5
- min_n2 = 0
- max_n2 = 0
- unsuitable_atoms_damage = 15
-
- loot_list = list(/obj/item/weapon/melee/energy/sword/pirate = 100)
-
- var/corpse = /obj/effect/landmark/mobcorpse/pirate
-
-/mob/living/simple_animal/hostile/pirate/ranged
- name = "Pirate Gunner"
- icon_state = "pirateranged"
- icon_living = "pirateranged"
- icon_dead = "piratemelee_dead"
-
- ranged = 1
- projectiletype = /obj/item/projectile/beam
- projectilesound = 'sound/weapons/laser.ogg'
-
- loot_list = list(/obj/item/weapon/gun/energy/laser = 100)
-
- corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
-
-/mob/living/simple_animal/hostile/pirate/death()
- ..()
- if(corpse)
- new corpse (src.loc)
- qdel(src)
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/humanoids/russian.dm b/code/modules/mob/living/simple_animal/humanoids/russian.dm
deleted file mode 100644
index d02c36de5a..0000000000
--- a/code/modules/mob/living/simple_animal/humanoids/russian.dm
+++ /dev/null
@@ -1,68 +0,0 @@
-/mob/living/simple_animal/hostile/russian
- name = "russian"
- desc = "For the Motherland!"
- tt_desc = "E Homo sapiens"
- icon_state = "russianmelee"
- icon_living = "russianmelee"
- icon_dead = "russianmelee_dead"
- icon_gib = "syndicate_gib"
- intelligence_level = SA_HUMANOID
-
- faction = "russian"
- maxHealth = 100
- health = 100
- speed = 4
-
- run_at_them = 0
- cooperative = 1
- investigates = 1
- firing_lines = 1
- returns_home = 1
- reacts = 1
-
- turns_per_move = 5
- stop_when_pulled = 0
- status_flags = CANPUSH
-
- response_help = "pokes"
- response_disarm = "shoves"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 15
- melee_damage_upper = 15
- attacktext = list("punched")
-
- min_oxy = 5
- max_oxy = 0
- min_tox = 0
- max_tox = 1
- min_co2 = 0
- max_co2 = 5
- min_n2 = 0
- max_n2 = 0
- unsuitable_atoms_damage = 15
-
- loot_list = list(/obj/item/weapon/material/knife = 100)
-
- var/corpse = /obj/effect/landmark/mobcorpse/russian
-
-/mob/living/simple_animal/hostile/russian/ranged
- icon_state = "russianranged"
- icon_living = "russianranged"
-
- ranged = 1
- projectiletype = /obj/item/projectile/bullet
- casingtype = /obj/item/ammo_casing/spent
- projectilesound = 'sound/weapons/Gunshot.ogg'
-
- loot_list = list(/obj/item/weapon/gun/projectile/revolver/mateba = 100)
-
- corpse = /obj/effect/landmark/mobcorpse/russian/ranged
-
-/mob/living/simple_animal/hostile/russian/death()
- ..()
- if(corpse)
- new corpse (src.loc)
- qdel(src)
- return
diff --git a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm b/code/modules/mob/living/simple_animal/humanoids/syndicate.dm
deleted file mode 100644
index 9a11178e66..0000000000
--- a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm
+++ /dev/null
@@ -1,265 +0,0 @@
-/mob/living/simple_animal/hostile/syndicate
- name = "mercenary"
- desc = "Death to the Company."
- tt_desc = "E Homo sapiens"
- icon_state = "syndicate"
- icon_living = "syndicate"
- icon_dead = "syndicate_dead"
- icon_gib = "syndicate_gib"
- intelligence_level = SA_HUMANOID
-
- faction = "syndicate"
- maxHealth = 100
- health = 100
- speed = 4
-
- run_at_them = 0
- cooperative = 1
- investigates = 1
- firing_lines = 1
- returns_home = 1
- reacts = 1
-
- turns_per_move = 5
- stop_when_pulled = 0
- status_flags = CANPUSH
-
- response_help = "pokes"
- response_disarm = "shoves"
- response_harm = "hits"
-
- harm_intent_damage = 5
- melee_damage_lower = 15 //Tac Knife damage
- melee_damage_upper = 15
- environment_smash = 1
- attack_sharp = 1
- attack_edge = 1
- attacktext = list("slashed", "stabbed")
-
- armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 100) // Same armor values as the vest they drop, plus simple mob immunities
-
- min_oxy = 5
- max_oxy = 0
- min_tox = 0
- max_tox = 1
- min_co2 = 0
- max_co2 = 5
- min_n2 = 0
- max_n2 = 0
- unsuitable_atoms_damage = 15
-
- speak_chance = 1
- speak = list("Fuckin' NT, man.",
- "When are we gonna get out of this chicken-shit outfit?",
- "Wish I had better equipment...",
- "I knew I should have been a line chef...",
- "Fuckin' helmet keeps fogging up.",
- "Anyone else smell that?")
- emote_hear = list("sniffs","coughs","taps his foot")
- emote_see = list("looks around","checks his equipment")
- say_understood = list()
- say_cannot = list()
- say_maybe_target = list("What's that?","Is someone there?","Is that...?","Hmm?")
- say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
- reactions = list("Hey guys, you ready?" = "Fuck yeah!")
-
- var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
-
-/mob/living/simple_animal/hostile/syndicate/death()
- if(corpse)
- ..()
- new corpse (src.loc)
- else
- ..(0,"explodes!")
- new /obj/effect/gibspawner/human(src.loc)
- explosion(get_turf(src), -1, 0, 1, 3)
- qdel(src)
- return
-
-///////////////Sword and shield////////////
-
-/mob/living/simple_animal/hostile/syndicate/melee
- icon_state = "syndicatemelee"
- icon_living = "syndicatemelee"
-
- melee_damage_lower = 30
- melee_damage_upper = 30
- attack_armor_pen = 50
- attack_sharp = 1
- attack_edge = 1
- attacktext = list("slashed")
-
- status_flags = 0
-
- loot_list = list(/obj/item/weapon/melee/energy/sword/red = 100, /obj/item/weapon/shield/energy = 100)
-
-/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(O.force)
- if(prob(20))
- visible_message("\The [src] blocks \the [O] with its shield!")
- if(user)
- react_to_attack(user)
- return
- else
- ..()
- else
- usr << "This weapon is ineffective, it does no damage."
- visible_message("\The [user] gently taps [src] with \the [O].")
-
-/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj)
- if(!Proj) return
- if(prob(35))
- visible_message("[src] blocks [Proj] with its shield!")
- if(Proj.firer)
- react_to_attack(Proj.firer)
- return
- else
- ..()
-
-/mob/living/simple_animal/hostile/syndicate/melee/space
- name = "syndicate commando"
- icon_state = "syndicatemeleespace"
- icon_living = "syndicatemeleespace"
-
- speed = 0
-
- armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 100) // Same armor as their voidsuit
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
-
-/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0)
- return
-
-/mob/living/simple_animal/hostile/syndicate/ranged
- icon_state = "syndicateranged"
- icon_living = "syndicateranged"
-
- ranged = 1
- rapid = 1
- projectiletype = /obj/item/projectile/bullet/pistol/medium
-// casingtype = /obj/item/ammo_casing/spent //Makes infinite stacks of bullets when put in PoIs.
- projectilesound = 'sound/weapons/Gunshot_light.ogg'
-
- loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100)
-
-/mob/living/simple_animal/hostile/syndicate/ranged/laser
- icon_state = "syndicateranged_laser"
- icon_living = "syndicateranged_laser"
- rapid = 0
- projectiletype = /obj/item/projectile/beam/midlaser
- projectilesound = 'sound/weapons/Laser.ogg'
-
- loot_list = list(/obj/item/weapon/gun/energy/laser = 100)
-
-/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle
- icon_state = "syndicateranged_ionrifle"
- icon_living = "syndicateranged_ionrifle"
- rapid = 0
- projectiletype = /obj/item/projectile/ion
- projectilesound = 'sound/weapons/Laser.ogg'
-
- loot_list = list(/obj/item/weapon/gun/energy/ionrifle = 100)
-
-/mob/living/simple_animal/hostile/syndicate/ranged/space
- name = "syndicate sommando"
- icon_state = "syndicaterangedpsace"
- icon_living = "syndicaterangedpsace"
-
- speed = 0
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
- corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
-
-/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0)
- return
-
-///////////////////////////////////////////////
-// POI Mobs
-// Don't leave corpses, to help balance loot.
-///////////////////////////////////////////////
-
-/mob/living/simple_animal/hostile/syndicate/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/melee/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/melee/space/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/ranged/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle/poi
- loot_list = list()
- corpse = null
-
-/mob/living/simple_animal/hostile/syndicate/ranged/space/poi
- loot_list = list()
- corpse = null
-
-
-//Viscerators
-
-/mob/living/simple_animal/hostile/viscerator
- name = "viscerator"
- desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
- icon = 'icons/mob/critter.dmi'
- icon_state = "viscerator_attack"
- icon_living = "viscerator_attack"
- intelligence_level = SA_ROBOTIC
- hovering = TRUE
-
- faction = "syndicate"
- maxHealth = 15
- health = 15
-
- pass_flags = PASSTABLE
-
- melee_damage_lower = 15
- melee_damage_upper = 15
- attack_sharp = 1
- attack_edge = 1
- attack_sound = 'sound/weapons/bladeslice.ogg'
- attacktext = list("cut")
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- minbodytemp = 0
-
-/mob/living/simple_animal/hostile/viscerator/death()
- ..(null,"is smashed into pieces!")
- qdel(src)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
deleted file mode 100644
index 741f32f3fd..0000000000
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ /dev/null
@@ -1,1732 +0,0 @@
-#define ai_log(M,V) if(debug_ai) ai_log_output(M,V)
-
-//Talky things
-#define try_say_list(L) if(L.len) say(pick(L))
-
-/mob/living/simple_animal
- name = "animal"
- desc = ""
- icon = 'icons/mob/animal.dmi'
- health = 20
- maxHealth = 20
-
- mob_bump_flag = SIMPLE_ANIMAL
- mob_swap_flags = MONKEY|SLIME|HUMAN
- mob_push_flags = MONKEY|SLIME|HUMAN
-
- var/tt_desc = "Uncataloged Life Form" //Tooltip description
-
- //Settings for played mobs
- var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob
- var/ai_inactive = 0 // Set to 1 to turn off most AI actions
- var/has_hands = 0 // Set to 1 to enable the use of hands and the hands hud
- var/humanoid_hands = 0 // Can a player in this mob use things like guns or AI cards?
- var/hand_form = "hands" // Used in IsHumanoidToolUser. 'Your X are not fit-'.
- var/list/hud_gears // Slots to show on the hud (typically none)
- var/ui_icons // Icon file path to use for the HUD, otherwise generic icons are used
- var/r_hand_sprite // If they have hands,
- var/l_hand_sprite // they could use some icons.
- var/player_msg // Message to print to players about 'how' to play this mob on login.
-
- //Mob icon/appearance settings
- var/icon_living = "" // The iconstate if we're alive, required
- var/icon_dead = "" // The iconstate if we're dead, required
- var/icon_gib = "generic_gib" // The iconstate for being gibbed, optional. Defaults to a generic gib animation.
- var/icon_rest = null // The iconstate for resting, optional
- var/image/modifier_overlay = null // Holds overlays from modifiers.
- attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim
- attack_icon_state = "slash" //Just the default
-
- //Mob talking settings
- universal_speak = 0 // Can all mobs in the entire universe understand this one?
- var/has_langs = list(LANGUAGE_GALCOM)// Text name of their language if they speak something other than galcom. They speak the first one.
- var/speak_chance = 0 // Probability that I talk (this is 'X in 200' chance since even 1/100 is pretty noisy)
- var/reacts = 0 // Reacts to some things being said
- var/list/speak = list() // Things I might say if I talk
- var/list/emote_hear = list() // Hearable emotes I might perform
- var/list/emote_see = list() // Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
- var/list/say_understood = list()// List of things to say when accepting an order
- var/list/say_cannot = list() // List of things to say when they cannot comply
- var/list/say_maybe_target = list()// List of things to say when they spot something barely
- var/list/say_got_target = list()// List of things to say when they engage a target
- var/list/reactions = list() // List of "string" = "reaction" and things they hear will be searched for string.
-
- //Mob movement settings
- var/wander = 1 // Does the mob wander around when idle?
- var/wander_distance = 3 // How far the mob will wander before going home (assuming they are allowed to do that)
- var/returns_home = 0 // Mob knows how to return to wherever it started
- var/turns_per_move = 1 // How many life() cycles to wait between each wander mov?
- var/stop_when_pulled = 1 // When set to 1 this stops the animal from moving when someone is pulling it.
- var/follow_dist = 2 // Distance the mob tries to follow a friend
- var/obstacles = list() // Things this mob refuses to move through
- var/speed = 0 // Higher speed is slower, negative speed is faster.
- var/obj/item/weapon/card/id/myid// An ID card if they have one to give them access to stuff.
- var/turf/home_turf // Set when they spawned, they try to come back here sometimes.
-
- //Mob interaction
- var/response_help = "tries to help" // If clicked on help intent
- var/response_disarm = "tries to disarm" // If clicked on disarm intent
- var/response_harm = "tries to hurt" // If clicked on harm intent
- var/harm_intent_damage = 3 // How much an unarmed harm click does to this mob.
- var/meat_amount = 0 // How much meat to drop from this mob when butchered
- var/obj/meat_type // The meat object to drop
- var/list/loot_list = list() // The list of lootable objects to drop, with "/path = prob%" structure
- var/recruitable = 0 // Mob can be bossed around
- var/recruit_cmd_str = "Hey," // The thing you prefix commands with when bossing them around
- var/intelligence_level = SA_ANIMAL// How 'smart' the mob is ICly, used to deliniate between animal, robot, and humanoid SAs.
-
- //Mob environment settings
- var/minbodytemp = 250 // Minimum "okay" temperature in kelvin
- var/maxbodytemp = 350 // Maximum of above
- var/heat_damage_per_tick = 3 // Amount of damage applied if animal's body temperature is higher than maxbodytemp
- var/cold_damage_per_tick = 2 // Same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- var/fire_alert = 0 // 0 = fine, 1 = hot, 2 = cold
-
- var/min_oxy = 5 // Oxygen in moles, minimum, 0 is 'no minimum'
- var/max_oxy = 0 // Oxygen in moles, maximum, 0 is 'no maximum'
- var/min_tox = 0 // Phoron min
- var/max_tox = 1 // Phoron max
- var/min_co2 = 0 // CO2 min
- var/max_co2 = 5 // CO2 max
- var/min_n2 = 0 // N2 min
- var/max_n2 = 0 // N2 max
- var/unsuitable_atoms_damage = 2 // This damage is taken when atmos doesn't fit all the requirements above
-
- //Hostility settings
- var/hostile = 0 // Do I even attack?
- var/retaliate = 0 // I respond to damage against specific targets.
- var/view_range = 7 // Scan for targets in this range.
- var/specific_targets = 0 // Only use Found() targets, ignore others.
- var/investigates = 0 // Do I investigate if I saw someone briefly?
- var/attack_same = 0 // Do I attack members of my own faction?
- var/cooperative = 0 // Do I ask allies to help me?
- var/assist_distance = 25 // Radius in which I'll ask my comrades for help.
- var/supernatural = 0 // If the mob is supernatural (used in null-rod stuff for banishing?)
- var/grab_resist = 75 // Chance of me resisting a grab attempt.
- var/taser_kill = 1 // Is the mob weak to tasers
-
- //Attack ranged settings
- var/ranged = 0 // Do I attack at range?
- var/shoot_range = 7 // How far away do I start shooting from?
- var/rapid = 0 // Three-round-burst fire mode
- var/firing_lines = 0 // Avoids shooting allies
- var/projectiletype // The projectiles I shoot
- var/projectilesound // The sound I make when I do it
- var/casingtype // What to make the hugely laggy casings pile out of
-
- //Mob melee settings
- var/melee_damage_lower = 2 // Lower bound of randomized melee damage
- var/melee_damage_upper = 6 // Upper bound of randomized melee damage
- var/list/attacktext = list("attacked") // "You are [attacktext] by the mob!"
- var/list/friendly = list("nuzzles") // "The mob [friendly] the person."
- var/attack_sound = null // Sound to play when I attack
- var/environment_smash = 0 // How much environment damage do I do when I hit stuff?
- var/melee_miss_chance = 15 // percent chance to miss a melee attack.
- var/melee_attack_minDelay = 5 // How long between attacks at least
- var/melee_attack_maxDelay = 10 // How long between attacks at most
- var/attack_armor_type = "melee" // What armor does this check?
- var/attack_armor_pen = 0 // How much armor pen this attack has.
- var/attack_sharp = 0 // Is the attack sharp?
- var/attack_edge = 0 // Does the attack have an edge?
-
- //Special attacks
- var/spattack_prob = 0 // Chance of the mob doing a special attack (0 for never)
- var/spattack_min_range = 0 // Min range to perform the special attacks from
- var/spattack_max_range = 0 // Max range to perform special attacks from
-
- //Attack movement settings
- var/run_at_them = 1 // Don't use A* pathfinding, use walk_to
- var/move_to_delay = 4 // Delay for the automated movement (deciseconds)
- var/destroy_surroundings = 1 // Should I smash things to get to my target?
- var/astar_adjacent_proc = /turf/proc/CardinalTurfsWithAccess // Proc to use when A* pathfinding. Default makes them bound to cardinals.
-
- //Damage resistances
- var/shock_resistance = 0 // Siemens modifier, directly subtracted from 1. Value of 0.4 means 0.6 siemens on shocks.
- var/resistance = 0 // Damage reduction for all types
- var/list/armor = list( // Values for normal getarmor() checks
- "melee" = 0,
- "bullet" = 0,
- "laser" = 0,
- "energy" = 0,
- "bomb" = 0,
- "bio" = 100,
- "rad" = 100)
-
- //Scary debug things
- var/debug_ai = 0 // Logging level for this mob (1,2,3)
- var/path_display = 0 // Will display the path in green when pathing
- var/path_icon = 'icons/misc/debug_group.dmi' // What icon to use for the overlay
- var/path_icon_state = "red" // What state to use for the overlay
- var/icon/path_overlay // A reference to restart
-
- ////// These are used for inter-proc communications so don't edit them manually //////
- var/stance = STANCE_IDLE // Used to determine behavior
- var/stop_automated_movement = 0 // Use this to temporarely stop random movement or to if you write special movement code for animals.
- var/lifes_since_move = 0 // A counter for how many life() cycles since move
- var/shuttletarget = null // Shuttle's here, time to get to it
- var/enroute = 0 // If the shuttle is en-route
- var/purge = 0 // A counter used for null-rod stuff
- var/mob/living/target_mob // Who I'm trying to attack
- var/mob/living/follow_mob // Who I'm recruited by
- var/mob/living/list/friends = list() // People who are immune to my wrath, for now
- var/mob/living/simple_animal/list/faction_friends = list() // Other simple mobs I am friends with
- var/turf/list/walk_list = list()// List of turfs to walk through to get somewhere
- var/astarpathing = 0 // Am I currently pathing to somewhere?
- var/stance_changed = 0 // When our stance last changed (world.time)
- var/last_target_time = 0 // When we last set our target, to prevent juggles
- var/last_follow_time = 0 // When did we last get asked to follow someone?
- var/last_helpask_time = 0 // When did we last call for help?
- var/follow_until_time = 0 // Give up following when we reach this time (0 = never)
- var/annoyed = 0 // Do people keep distract-kiting us?
- ////// ////// //////
-
-/mob/living/simple_animal/New()
- ..()
- verbs -= /mob/verb/observe
- home_turf = get_turf(src)
- path_overlay = new(path_icon,path_icon_state)
- move_to_delay = max(2,move_to_delay) //Protection against people coding things incorrectly and A* pathing 100% of the time
- maxHealth = health
-
- for(var/L in has_langs)
- languages |= all_languages[L]
- if(languages.len)
- default_language = languages[1]
-
- if(cooperative)
- var/mob/living/simple_animal/first_friend
- for(var/mob/living/simple_animal/M in living_mob_list)
- if(M.faction == src.faction)
- first_friend = M
- break
- if(first_friend)
- faction_friends = first_friend.faction_friends
- faction_friends |= src
- else
- faction_friends |= src
-
-/mob/living/simple_animal/Destroy()
- home_turf = null
- path_overlay = null
- default_language = null
- target_mob = null
- follow_mob = null
- if(myid)
- qdel(myid)
- myid = null
-
- if(faction_friends.len) //This list is shared amongst the faction
- faction_friends -= src
-
- friends.Cut() //This one is not
- walk_list.Cut()
- languages.Cut()
- return ..()
-
-//Client attached
-/mob/living/simple_animal/Login()
- . = ..()
- ai_inactive = 1
- handle_stance(STANCE_IDLE)
- LoseTarget()
- to_chat(src,"Mob AI disabled while you are controlling the mob.
You are \the [src]. [player_msg]")
-
-//Client detatched
-/mob/living/simple_animal/Logout()
- spawn(15 SECONDS) //15 seconds to get back into the mob before it goes wild
- if(src && !src.client)
- ai_inactive = initial(ai_inactive) //So if they never have an AI, they stay that way.
- ..()
-
-//For debug purposes!
-/mob/living/simple_animal/proc/ai_log_output(var/msg = "missing message", var/ver = 1)
- if(ver <= debug_ai)
- log_debug("SA-AI: ([src]:[x],[y],[z])(@[world.time]): [msg] ")
-
-//Should we be dead?
-/mob/living/simple_animal/updatehealth()
- health = getMaxHealth() - getToxLoss() - getFireLoss() - getBruteLoss()
-
- //Alive, becoming dead
- if((stat < DEAD) && (health <= 0))
- death()
-
- //Overhealth
- if(health > getMaxHealth())
- health = getMaxHealth()
-
- //Update our hud if we have one
- if(healths)
- if(stat != DEAD)
- var/heal_per = (health / getMaxHealth()) * 100
- switch(heal_per)
- if(100 to INFINITY)
- healths.icon_state = "health0"
- if(80 to 100)
- healths.icon_state = "health1"
- if(60 to 80)
- healths.icon_state = "health2"
- if(40 to 60)
- healths.icon_state = "health3"
- if(20 to 40)
- healths.icon_state = "health4"
- if(0 to 20)
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
- else
- healths.icon_state = "health7"
-
- //Updates the nutrition while we're here
- if(nutrition_icon)
- var/food_per = (nutrition / initial(nutrition)) * 100
- switch(food_per)
- if(90 to INFINITY)
- nutrition_icon.icon_state = "nutrition0"
- if(75 to 90)
- nutrition_icon.icon_state = "nutrition1"
- if(50 to 75)
- nutrition_icon.icon_state = "nutrition2"
- if(25 to 50)
- nutrition_icon.icon_state = "nutrition3"
- if(0 to 25)
- nutrition_icon.icon_state = "nutrition4"
-
-/mob/living/simple_animal/update_icon()
- . = ..()
- var/mutable_appearance/ma = new(src)
- ma.layer = layer
- ma.plane = plane
-
- ma.overlays = list(modifier_overlay)
-
- //Awake and normal
- if((stat == CONSCIOUS) && (!icon_rest || !resting || !incapacitated(INCAPACITATION_DISABLED) ))
- ma.icon_state = icon_living
-
- //Dead
- else if(stat >= DEAD)
- ma.icon_state = icon_dead
-
- //Resting or KO'd
- else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest)
- ma.icon_state = icon_rest
-
- //Backup
- else
- ma.icon_state = initial(icon_state)
-
- if(has_hands)
- if(r_hand_sprite)
- ma.overlays += r_hand_sprite
- if(l_hand_sprite)
- ma.overlays += l_hand_sprite
-
- appearance = ma
-
-// If your simple mob's update_icon() call calls overlays.Cut(), this needs to be called after this, or manually apply modifier_overly to overlays.
-/mob/living/simple_animal/update_modifier_visuals()
- var/image/effects = null
- if(modifier_overlay)
- overlays -= modifier_overlay
- modifier_overlay.overlays.Cut()
- effects = modifier_overlay
- else
- effects = new()
-
- for(var/datum/modifier/M in modifiers)
- if(M.mob_overlay_state)
- var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state)
- I.appearance_flags = RESET_COLOR // So colored mobs don't affect the overlay.
- effects.overlays += I
-
- modifier_overlay = effects
- overlays += modifier_overlay
-
-
-/mob/living/simple_animal/Life()
- ..()
-
- //Health
- updatehealth()
- if(stat >= DEAD)
- return 0
-
- handle_stunned()
- handle_weakened()
- handle_paralysed()
- handle_supernatural()
- handle_atmos() //Atmos
-
- ai_log("Life() - stance=[stance] ai_inactive=[ai_inactive]", 4)
-
- //AI Actions
- if(!ai_inactive)
- //Stanceyness
- handle_stance()
-
- //Movement
- if(!stop_automated_movement && wander && !anchored) //Allowed to move?
- handle_wander_movement()
-
- //Speaking
- if(speak_chance && stance == STANCE_IDLE) // Allowed to chatter?
- handle_idle_speaking()
-
- //Resisting out buckles
- if(stance != STANCE_IDLE && incapacitated(INCAPACITATION_BUCKLED_PARTIALLY))
- handle_resist()
-
- //Resisting out of closets
- if(istype(loc,/obj/structure/closet))
- var/obj/structure/closet/C = loc
- if(C.sealed)
- handle_resist()
- else
- C.open()
-
- return 1
-
-// Resists out of things.
-// Sometimes there are times you want SAs to be buckled to something, so override this for when that is needed.
-/mob/living/simple_animal/proc/handle_resist()
- resist()
-
-// Peforms the random walk wandering
-/mob/living/simple_animal/proc/handle_wander_movement()
- if(isturf(src.loc) && !resting && !buckled && canmove) //Physically capable of moving?
- lifes_since_move++ //Increment turns since move (turns are life() cycles)
- if(lifes_since_move >= turns_per_move)
- if(!(stop_when_pulled && pulledby)) //Some animals don't move when pulled
- var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
- moving_to = pick(cardinal)
- dir = moving_to //How about we turn them the direction they are moving, yay.
- Move(get_step(src,moving_to))
- lifes_since_move = 0
-
-// Handles random chatter, called from Life() when stance = STANCE_IDLE
-/mob/living/simple_animal/proc/handle_idle_speaking()
- if(rand(0,200) < speak_chance)
- if(speak && speak.len)
- if((emote_hear && emote_hear.len) || (emote_see && emote_see.len))
- var/length = speak.len
- if(emote_hear && emote_hear.len)
- length += emote_hear.len
- if(emote_see && emote_see.len)
- length += emote_see.len
- var/randomValue = rand(1,length)
- if(randomValue <= speak.len)
- try_say_list(speak)
- else
- randomValue -= speak.len
- if(emote_see && randomValue <= emote_see.len)
- visible_emote("[pick(emote_see)].")
- else
- audible_emote("[pick(emote_hear)].")
- else
- try_say_list(speak)
- else
- if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
- visible_emote("[pick(emote_see)].")
- if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
- audible_emote("[pick(emote_hear)].")
- if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
- var/length = emote_hear.len + emote_see.len
- var/pick = rand(1,length)
- if(pick <= emote_see.len)
- visible_emote("[pick(emote_see)].")
- else
- audible_emote("[pick(emote_hear)].")
-
-// Handle interacting with and taking damage from atmos
-// TODO - Refactor this to use handle_environment() like a good /mob/living
-/mob/living/simple_animal/proc/handle_atmos()
- var/atmos_unsuitable = 0
-
- var/atom/A = src.loc
-
- if(istype(A,/turf))
- var/turf/T = A
-
- var/datum/gas_mixture/Environment = T.return_air()
-
- if(Environment)
-
- if( abs(Environment.temperature - bodytemperature) > 40 )
- bodytemperature += ((Environment.temperature - bodytemperature) / 5)
-
- if(min_oxy)
- if(Environment.gas["oxygen"] < min_oxy)
- atmos_unsuitable = 1
- if(max_oxy)
- if(Environment.gas["oxygen"] > max_oxy)
- atmos_unsuitable = 1
- if(min_tox)
- if(Environment.gas["phoron"] < min_tox)
- atmos_unsuitable = 2
- if(max_tox)
- if(Environment.gas["phoron"] > max_tox)
- atmos_unsuitable = 2
- if(min_n2)
- if(Environment.gas["nitrogen"] < min_n2)
- atmos_unsuitable = 1
- if(max_n2)
- if(Environment.gas["nitrogen"] > max_n2)
- atmos_unsuitable = 1
- if(min_co2)
- if(Environment.gas["carbon_dioxide"] < min_co2)
- atmos_unsuitable = 1
- if(max_co2)
- if(Environment.gas["carbon_dioxide"] > max_co2)
- atmos_unsuitable = 1
-
- //Atmos effect
- if(bodytemperature < minbodytemp)
- fire_alert = 2
- adjustBruteLoss(cold_damage_per_tick)
- if(fire)
- fire.icon_state = "fire1"
- else if(bodytemperature > maxbodytemp)
- fire_alert = 1
- adjustBruteLoss(heat_damage_per_tick)
- if(fire)
- fire.icon_state = "fire2"
- else
- fire_alert = 0
- if(fire)
- fire.icon_state = "fire0"
-
- if(atmos_unsuitable)
- adjustBruteLoss(unsuitable_atoms_damage)
- if(oxygen)
- oxygen.icon_state = "oxy1"
- else if(oxygen)
- if(oxygen)
- oxygen.icon_state = "oxy0"
-
-// For setting the stance WITHOUT processing it
-/mob/living/simple_animal/proc/set_stance(var/new_stance)
- stance = new_stance
- stance_changed = world.time
- ai_log("set_stance() changing to [new_stance]",2)
-
-// For proccessing the current stance, or setting and processing a new one
-/mob/living/simple_animal/proc/handle_stance(var/new_stance)
- if(ai_inactive)
- stance = STANCE_IDLE
- return
-
- if(new_stance)
- set_stance(new_stance)
-
- switch(stance)
- if(STANCE_IDLE)
- target_mob = null
- a_intent = I_HELP
- annoyed = max(0,annoyed--)
-
- //Yes I'm breaking this into two if()'s for ease of reading
- //If we ARE ALLOWED TO
- if(returns_home && home_turf && !astarpathing && (world.time - stance_changed) > 10 SECONDS)
- if(get_dist(src,home_turf) > wander_distance)
- move_to_delay = initial(move_to_delay)*2 //Walk back.
- GoHome()
- else
- stop_automated_movement = 0
-
- //Search for targets while idle
- if(hostile || specific_targets)
- FindTarget()
- if(STANCE_FOLLOW)
- annoyed = 15
- FollowTarget()
- if(follow_until_time && world.time > follow_until_time)
- LoseFollow()
- return
- if(hostile || specific_targets)
- FindTarget()
- if(STANCE_ATTACK)
- annoyed = 50
- a_intent = I_HURT
- RequestHelp()
- MoveToTarget()
- if(STANCE_ATTACKING)
- annoyed = 50
- AttackTarget()
-
-/mob/living/simple_animal/proc/handle_supernatural()
- if(purge)
- purge -= 1
-
-/mob/living/simple_animal/gib()
- ..(icon_gib,1,icon) // we need to specify where the gib animation is stored
-
-/mob/living/simple_animal/emote(var/act, var/type, var/desc)
- if(act)
- ..(act, type, desc)
-
-/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
- ai_log("bullet_act() I was shot by: [Proj.firer]",2)
-
- //Projectiles with bonus SA damage
- if(!Proj.nodamage)
- if(!Proj.SA_vulnerability || Proj.SA_vulnerability == intelligence_level)
- Proj.damage += Proj.SA_bonus_damage
-
- . = ..()
-
- if(Proj.firer)
- react_to_attack(Proj.firer)
-
-// When someone clicks us with an empty hand
-/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob)
- ..()
-
- switch(M.a_intent)
-
- if(I_HELP)
- if (health > 0)
- M.visible_message("[M] [response_help] \the [src].")
-
- if(I_DISARM)
- M.visible_message("[M] [response_disarm] \the [src].")
- M.do_attack_animation(src)
- //TODO: Push the mob away or something
-
- if(I_GRAB)
- if (M == src)
- return
- if (!(status_flags & CANPUSH))
- return
- if(!incapacitated(INCAPACITATION_ALL) && (stance != STANCE_IDLE) && prob(grab_resist))
- M.visible_message("[M] tries to grab [src] but fails!")
- return
-
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
-
- M.put_in_active_hand(G)
-
- G.synch()
- G.affecting = src
- LAssailant = M
-
- M.visible_message("[M] has grabbed [src] passively!")
- M.do_attack_animation(src)
- ai_log("attack_hand() I was grabbed by: [M]",2)
- react_to_attack(M)
-
- if(I_HURT)
- var/armor = run_armor_check(def_zone = null, attack_flag = "melee")
- apply_damage(damage = harm_intent_damage, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE)
- M.visible_message("[M] [response_harm] \the [src]!")
- M.do_attack_animation(src)
- ai_log("attack_hand() I was hit by: [M]",2)
- react_to_attack(M)
-
- return
-
-// When somoene clicks us with an item in hand
-/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user)
- if(istype(O, /obj/item/stack/medical))
- if(stat != DEAD)
- var/obj/item/stack/medical/MED = O
- if(health < getMaxHealth())
- if(MED.amount >= 1)
- adjustBruteLoss(-MED.heal_brute)
- MED.amount -= 1
- if(MED.amount <= 0)
- qdel(MED)
- for(var/mob/M in viewers(src, null))
- if ((M.client && !( M.blinded )))
- M.show_message("[user] applies the [MED] on [src].")
- else
- var/datum/gender/T = gender_datums[src.get_visible_gender()]
- user << "\The [src] is dead, medical items won't bring [T.him] back to life." // the gender lookup is somewhat overkill, but it functions identically to the obsolete gender macros and future-proofs this code
- if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
- if(istype(O, /obj/item/weapon/material/knife) || istype(O, /obj/item/weapon/material/knife/butch))
- harvest(user)
- else
- ai_log("attackby() I was weapon'd by: [user]",2)
- if(O.force)
- react_to_attack(user)
-
- return ..()
-
-/mob/living/simple_animal/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
-
- //Animals can't be stunned(?)
- if(O.damtype == HALLOSS)
- effective_force = 0
- if(supernatural && istype(O,/obj/item/weapon/nullrod))
- effective_force *= 2
- purge = 3
- if(O.force <= resistance)
- to_chat(user,"This weapon is ineffective, it does no damage.")
- return 2
-
- ai_log("hit_with_weapon() I was h_w_weapon'd by: [user]",2)
- react_to_attack(user)
-
- . = ..()
-
-// When someone throws something at us
-/mob/living/simple_animal/hitby(atom/movable/AM)
- ..()
- if(AM.thrower)
- react_to_attack(AM.thrower)
-
-//SA vs SA basically
-/mob/living/simple_animal/attack_generic(var/mob/attacker)
- if(attacker)
- react_to_attack(attacker)
- return ..()
-
-/mob/living/simple_animal/movement_delay()
- var/tally = 0 //Incase I need to add stuff other than "speed" later
-
- tally = speed
-
- if(force_max_speed)
- return -3
-
- for(var/datum/modifier/M in modifiers)
- if(!isnull(M.haste) && M.haste == TRUE)
- return -3
- if(!isnull(M.slowdown))
- tally += M.slowdown
-
- if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
- if(tally <= 0)
- tally = 1
- tally *= purge
-
- if(m_intent == "walk")
- tally *= 1.5
-
- return tally+config.animal_delay
-
-/mob/living/simple_animal/Stat()
- ..()
-
- if(statpanel("Status") && show_stat_health)
- stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
-
-/mob/living/simple_animal/lay_down()
- ..()
- if(resting && icon_rest)
- icon_state = icon_rest
- else
- icon_state = icon_living
- update_icon()
-
-/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
- density = 0 //We don't block even if we did before
- walk(src, 0) //We stop any background-processing walks
- resting = 0 //We can rest in peace later.
-
- if(faction_friends.len)
- faction_friends -= src
-
- if(loot_list.len) //Drop any loot
- for(var/path in loot_list)
- if(prob(loot_list[path]))
- new path(get_turf(src))
-
- spawn(3) //We'll update our icon in a sec
- update_icon()
-
- return ..(gibbed,deathmessage)
-
-/mob/living/simple_animal/ex_act(severity)
- if(!blinded)
- flash_eyes()
- var/armor = run_armor_check(def_zone = null, attack_flag = "bomb")
- var/bombdam = 500
- switch (severity)
- if (1.0)
- bombdam = 500
- if (2.0)
- bombdam = 60
- if (3.0)
- bombdam = 30
-
- apply_damage(damage = bombdam, damagetype = BRUTE, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE)
-
- if(bombdam > maxHealth)
- gib()
-
-// Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha)
-/mob/living/simple_animal/proc/SA_attackable(target_mob)
- ai_log("SA_attackable([target_mob])",3)
- if (isliving(target_mob))
- var/mob/living/L = target_mob
- if(L.stat != DEAD)
- return 1
- if (istype(target_mob,/obj/mecha))
- var/obj/mecha/M = target_mob
- if (M.occupant)
- return 1
- ai_log("SA_attackable([target_mob]): no",3)
- return 0
-
-/mob/living/simple_animal/say(var/message,var/datum/language/language)
- var/verb = "says"
- if(speak_emote.len)
- verb = pick(speak_emote)
-
- message = sanitize(message)
-
- ..(message, null, verb)
-
-/mob/living/simple_animal/get_speech_ending(verb, var/ending)
- return verb
-
-/mob/living/simple_animal/put_in_hands(var/obj/item/W) // No hands.
- if(has_hands)
- put_in_active_hand(W)
- return 1
- W.forceMove(get_turf(src))
- return 1
-
-// Harvest an animal's delicious byproducts
-/mob/living/simple_animal/proc/harvest(var/mob/user)
- var/actual_meat_amount = max(1,(meat_amount/2))
- if(meat_type && actual_meat_amount>0 && (stat == DEAD))
- for(var/i=0;i[user] chops up \the [src]!")
- new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
- qdel(src)
- else
- user.visible_message("[user] butchers \the [src] messily!")
- gib()
-
-/mob/living/simple_animal/handle_fire()
- return
-/mob/living/simple_animal/update_fire()
- return
-/mob/living/simple_animal/IgniteMob()
- return
-/mob/living/simple_animal/ExtinguishMob()
- return
-
-//We got hit! Consider hitting them back!
-/mob/living/simple_animal/proc/react_to_attack(var/mob/living/M)
- if(ai_inactive || stat || M == target_mob) return //Not if we're dead or already hitting them
- if(M in friends || M.faction == faction) return //I'll overlook it THIS time...
- ai_log("react_to_attack([M])",1)
- if(retaliate && set_target(M, 1))
- handle_stance(STANCE_ATTACK)
- return M
-
- return 0
-
-/mob/living/simple_animal/proc/set_target(var/mob/M, forced = 0)
- ai_log("SetTarget([M])",2)
- if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob)
- ai_log("SetTarget() can't set it again so soon",3)
- return 0
-
- var/turf/seen = get_turf(M)
-
- if(investigates && (annoyed < 10))
- try_say_list(say_maybe_target)
- face_atom(seen)
- annoyed += 14
- sleep(1 SECOND) //For realism
-
- if(forced || (M in ListTargets(view_range)))
- try_say_list(say_got_target)
- target_mob = M
- last_target_time = world.time
- return M
- else if(investigates)
- spawn(1)
- WanderTowards(seen)
-
- return 0
-
-// Set a follow target, with optional time for how long to follow them.
-/mob/living/simple_animal/proc/set_follow(var/mob/M, var/follow_for = 0)
- ai_log("SetFollow([M]) for=[follow_for]",2)
- if(!M || (world.time - last_target_time < 4 SECONDS) && follow_mob)
- ai_log("SetFollow() can't set it again so soon",3)
- return 0
-
- follow_mob = M
- last_follow_time = world.time
- follow_until_time = !follow_for ? 0 : world.time + follow_for
- return 1
-
-//Scan surroundings for a valid target
-/mob/living/simple_animal/proc/FindTarget()
- var/atom/T = null
- for(var/atom/A in ListTargets(view_range))
-
- if(A == src)
- continue
-
- var/atom/F = Found(A)
- if(F)
- T = F
- break
- else if(specific_targets)
- return 0
-
- if(isliving(A))
- var/mob/living/L = A
- if(L.faction == src.faction && !attack_same)
- continue
- else if(L in friends)
- continue
- else if(L.alpha <= EFFECTIVE_INVIS)
- continue
- else if(!SA_attackable(L))
- continue
- else if(!special_target_check(L))
- continue
- else
- T = L
- break
-
- else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets().
- var/obj/mecha/M = A
- if(!SA_attackable(M))
- continue
- else if(!special_target_check(M))
- continue
- if((M.occupant.faction != src.faction) || attack_same)
- T = M
- break
-
- //You found one!
- if(T)
- ai_log("FindTarget() found [T]!",1)
- if(set_target(T))
- handle_stance(STANCE_ATTACK)
-
- return T
-
-//Used for special targeting or reactions
-/mob/living/simple_animal/proc/Found(var/atom/A)
- return
-
-// Used for somewhat special targeting, but not to the extent of using Found()
-/mob/living/simple_animal/proc/special_target_check(var/atom/A)
- return TRUE
-
-//Requesting help from like-minded individuals
-/mob/living/simple_animal/proc/RequestHelp()
- if(!cooperative || ((world.time - last_helpask_time) < 10 SECONDS))
- return
-
- ai_log("RequestHelp() to [faction_friends.len] friends",2)
- last_helpask_time = world.time
- for(var/mob/living/simple_animal/F in faction_friends)
- if(F == src) continue
- if(get_dist(src,F) <= F.assist_distance)
- spawn(0)
- if(F) //They could have died by now and some mobs delete themselves on death
- ai_log("RequestHelp() to [F]",3)
- F.HelpRequested(src)
-
-//Someone wants help?
-/mob/living/simple_animal/proc/HelpRequested(var/mob/living/simple_animal/F)
- if(target_mob || stat)
- ai_log("HelpRequested() by [F] but we're busy/dead",2)
- return
- if(get_dist(src,F) <= follow_dist)
- ai_log("HelpRequested() by [F] but we're already here",2)
- return
- if(get_dist(src,F) <= view_range)
- ai_log("HelpRequested() by [F] and within targetshare range",2)
- if(F.target_mob && set_target(F.target_mob))
- handle_stance(STANCE_ATTACK)
- return
-
- if(set_follow(F, 10 SECONDS))
- handle_stance(STANCE_FOLLOW)
-
-// Can be used to conditionally do a ranged or melee attack.
-// Note that the SA must be able to do an attack at the specified range or else it may get trapped in a loop of switching
-// between STANCE_ATTACK and STANCE_ATTACKING, due to being told by MoveToTarget() that they're in range but being told by AttackTarget() that they're not.
-/mob/living/simple_animal/proc/ClosestDistance()
- return ranged ? shoot_range - 1 : 1 // Shoot range -1 just because we don't want to constantly get kited
-
-//Move to a target (or near if we're ranged)
-/mob/living/simple_animal/proc/MoveToTarget()
- if(incapacitated(INCAPACITATION_DISABLED))
- ai_log("MoveToTarget() Bailing because we're disabled",2)
- return
-
- //If we were chasing someone and we can't anymore, give up.
- if(!target_mob || !SA_attackable(target_mob))
- ai_log("MoveToTarget() Losing target at top",2)
- LoseTarget()
- return
-
- //Don't wander
- stop_automated_movement = 1
- move_to_delay = initial(move_to_delay)
-
- //We recompute our path every time we're called if we can still see them
- if(target_mob in ListTargets(view_range))
-
- //Recompute the path if we were using one since we can still see them.
- if(astarpathing)
- ForgetPath()
-
- //Find out where we're getting to
- var/get_to = ClosestDistance()
- var/distance = get_dist(src,target_mob)
- ai_log("MoveToTarget() [src] get_to: [get_to] distance: [distance]",2)
-
- //We're here!
- if(distance <= get_to)
- ai_log("MoveToTarget() [src] attack range",2)
- handle_stance(STANCE_ATTACKING)
- return
-
- //We're just setting out, making a new path, or we can't path with A*
- if(!walk_list.len)
- ai_log("SA: MoveToTarget() pathing to [target_mob]",2)
-
- //GetPath failed for whatever reason, just smash into things towards them
- if(run_at_them || !GetPath(get_turf(target_mob),get_to))
-
- //We try the built-in way to stay close
- walk_to(src, target_mob, get_to, move_to_delay)
- ai_log("MoveToTarget() walk_to([src],[target_mob],[get_to],[move_to_delay])",3)
-
- //Break shit in their direction! LEME SMAHSH
- var/dir_to_mob = get_dir(src,target_mob)
- face_atom(target_mob)
- DestroySurroundings(dir_to_mob)
- ai_log("MoveToTarget() DestroySurroundings([get_dir(src,target_mob)])",3)
-
- //We have a path! We aren't already pathing it!
- if(!astarpathing && walk_list.len)
- ai_log("MoveToTarget() going to start a path",2)
- spawn(1)
-
- //Do the path!
- var/result = WalkPath(target_thing = target_mob, target_dist = get_to)
- ai_log("MoveToTarget() WalkPath r:[result]",2)
-
- //WalkPath failed, either interrupted for recalc, or something else
- if(!result)
- return
-
- //WalkPath either got close enough or we ran out of path
- else
- spawn(1)
- ai_log("MoveToTarget() resetting",2)
- MoveToTarget()
-
- //We can't see them, and we don't have a path we're trying to follow to find them
- else if(!astarpathing)
- ai_log("MoveToTarget() Losing target at bottom",2)
- LoseTarget() //Just forget it.
-
-//Follow a target (and don't attempt to murder it horribly)
-/mob/living/simple_animal/proc/FollowTarget()
- ai_log("FollowTarget() [follow_mob]",1)
- stop_automated_movement = 1
- //If we were chasing someone and we can't anymore, give up.
- if(!follow_mob || follow_mob.stat)
- ai_log("FollowTarget() Losing follow at top",2)
- LoseFollow()
- return
-
- if(incapacitated(INCAPACITATION_DISABLED))
- ai_log("FollowTarget() Bailing because we're disabled",2)
- LoseFollow()
- return
-
- if((get_dist(src,follow_mob) <= follow_dist))
- ai_log("FollowTarget() Already at target",2)
- return
-
- move_to_delay = initial(move_to_delay)
- var/start_distance = get_dist(src,follow_mob)
-
- //Bad pathing
- if(run_at_them)
- walk_to(src, follow_mob, follow_dist, move_to_delay)
- ai_log("FollowTarget() walk_to([src],[target_mob],2,[move_to_delay])",3)
- spawn(3 SECONDS)
- if(src && follow_mob && (stance == STANCE_FOLLOW) && (get_dist(src,follow_mob) >= start_distance))
- ai_log("FollowTarget() walk_to not making headway, giving up",3)
- LoseFollow()
-
- //Good pathing
- else
- GetPath(get_turf(follow_mob),follow_dist)
- if(!astarpathing && walk_list.len)
- spawn(1)
- ai_log("FollowTarget() A* path getting underway",2)
- //Do the path!
- var/result = WalkPath(target_thing = follow_mob, target_dist = follow_dist)
- ai_log("FollowTarget() WalkPath r:[result]",3)
-
- else
- ai_log("FollowTarget() GetPath can't path, giving up",3)
- LoseFollow()
-
-//Just try one time to go look at something. Don't really focus much on it.
-/mob/living/simple_animal/proc/WanderTowards(var/turf/T)
- if(!T) return
- ai_log("WanderTowards() [T.x],[T.y]",1)
-
- stop_automated_movement = 1
- GetPath(T,1)
-
- if(run_at_them || !walk_list.len)
- ai_log("WanderTowards() walk_to getting underway",2)
- walk_to(src, T, 1, move_to_delay)
- else
- if(!astarpathing)
- spawn(1)
- ai_log("WanderTowards() A* path getting underway",2)
- WalkPath(target_thing = T, target_dist = 1)
-
-//A* now, try to a path to a target
-/mob/living/simple_animal/proc/GetPath(var/turf/target,var/get_to = 1,var/max_distance = world.view*6)
- ai_log("GetPath([target],[get_to],[max_distance])",2)
- ForgetPath()
- var/list/new_path = AStar(get_turf(loc), target, astar_adjacent_proc, /turf/proc/Distance, min_target_dist = get_to, max_node_depth = max_distance, id = myid, exclude = obstacles)
-
- if(new_path && new_path.len)
- walk_list = new_path
- if(path_display)
- for(var/turf/T in walk_list)
- T.overlays |= path_overlay
- else
- return 0
-
- return walk_list.len
-
-//Walk along our A* path, target_thing allows us to stop early if we're nearby
-/mob/living/simple_animal/proc/WalkPath(var/atom/target_thing, var/target_dist = 1, var/proc/steps_callback = null, var/every_steps = 4)
- ai_log("WalkPath() (steps:[walk_list.len])",2)
- if(!walk_list || !walk_list.len)
- return
-
- astarpathing = 1
- var/step_count = 0
- var/failed_steps = 0
- while(1)
- //We're supposed to stop
- if(!astarpathing || incapacitated(INCAPACITATION_DISABLED))
- astarpathing = 0
- ai_log("WalkPath() was interrupted",2)
- return 0
- //Finished the path
- if(!walk_list.len)
- astarpathing = 0
- ai_log("WalkPath() exited naturally",2)
- return 1
- if(failed_steps >= 3)
- astarpathing = 0
- ai_log("WalkPath() failed too many steps",2)
- return 0
-
- //Take a step
- if(!MoveOnce())
- ai_log("WalkPath() failed a step",3)
- failed_steps++
- else
- ai_log("WalkPath() took a step",3)
- failed_steps = 0
- step_count++
-
- //If we have a particular target we care about, look for them
- if(target_thing && (get_dist(src,target_thing) <= target_dist))
- ai_log("WalkPath() returning due to proximity",2)
- return target_thing
-
- //If we have a callback
- if(steps_callback && (step_count >= every_steps))
- ai_log("WalkPath() doing callback",3)
- call(steps_callback)()
-
- //And wait for the time to our next step
- sleep(move_to_delay)
-
-//Take one step along a path
-/mob/living/simple_animal/proc/MoveOnce()
- if(!walk_list.len)
- return
-
- if(path_display)
- var/turf/T = src.walk_list[1]
- T.overlays -= path_overlay
-
- step_towards(src, src.walk_list[1])
- if(src.loc != src.walk_list[1])
- ai_log("MoveOnce() step_towards returning 0",3)
- return 0
- else
- walk_list -= src.walk_list[1]
- ai_log("MoveOnce() step_towards returning 1",3)
- return 1
-
-//Forget the path entirely
-/mob/living/simple_animal/proc/ForgetPath()
- ai_log("ForgetPath()",2)
- if(path_display)
- for(var/turf/T in walk_list)
- T.overlays -= path_overlay
- astarpathing = 0
- walk_list.Cut()
-
-//Giving up on moving
-/mob/living/simple_animal/proc/GiveUpMoving()
- ai_log("GiveUpMoving()",1)
- ForgetPath()
- walk(src, 0)
- stop_automated_movement = 0
-
-//Return home, all-in-one proc (though does target scan and drop out if they see one)
-/mob/living/simple_animal/proc/GoHome()
- if(!home_turf) return
- if(astarpathing) ForgetPath()
- ai_log("GoHome()",1)
- var/close_enough = 2
- var/look_in = 50
- if(GetPath(home_turf,close_enough,look_in))
- stop_automated_movement = 1
- spawn(1)
- if(WalkPath()) //If we made it without interruption
- ai_log("GoHome() got home",2)
- GiveUpMoving() //Go back to wandering
-
-//Get into attack mode on a target
-/mob/living/simple_animal/proc/AttackTarget()
- stop_automated_movement = 1
- if(incapacitated(INCAPACITATION_DISABLED))
- ai_log("AttackTarget() Bailing because we're disabled",2)
- LoseTarget()
- return 0
- if(!target_mob || !SA_attackable(target_mob) || (target_mob.alpha <= EFFECTIVE_INVIS)) //if the target went invisible, you can't follow it
- LoseTarget()
- return 0
- if(!(target_mob in ListTargets(view_range)))
- LostTarget()
- return 0
-
- ai_log("AttackTarget() vs. [target_mob]",1)
- var/distance = get_dist(src, target_mob)
- face_atom(target_mob)
-
- //Hadoooooken!
- if(prob(spattack_prob) && (distance >= spattack_min_range) && (distance <= spattack_max_range))
- ai_log("AttackTarget() special",3)
- if(SpecialAtkTarget()) //Might not succeed/be allowed, do something else.
- return 1
- //AAAAH!
- if(distance <= 1)
- ai_log("AttackTarget() melee",3)
- PunchTarget()
- return 1
- //Open fire!
- else if(ranged && (distance <= shoot_range))
- ai_log("AttackTarget() ranged",3)
- ShootTarget(target_mob)
- return 1
- //They ran away!
- else
- ai_log("AttackTarget() out of range!",3)
- stoplag(1) // Unfortunately this is needed to protect from ClosestDistance() sometimes not updating fast enough to prevent an infinite loop.
- handle_stance(STANCE_ATTACK)
- return 0
-
-//Attack the target in melee
-/mob/living/simple_animal/proc/PunchTarget()
- if(!Adjacent(target_mob))
- return
- if(!canClick())
- return
- setClickCooldown(get_attack_speed())
-// if(!client)
-// sleep(rand(melee_attack_minDelay, melee_attack_maxDelay))
- if(isliving(target_mob))
- var/mob/living/L = target_mob
-
- if(prob(melee_miss_chance))
- add_attack_logs(src,L,"Animal-attacked (miss)", admin_notify = FALSE)
- visible_message("[src] misses [L]!")
- do_attack_animation(src)
- return L
- else
- DoPunch(L)
- return L
- if(istype(target_mob,/obj/mecha))
- var/obj/mecha/M = target_mob
- DoPunch(M)
- return M
-
-// This is the actual act of 'punching'. Override for special behaviour.
-/mob/living/simple_animal/proc/DoPunch(var/atom/A)
- if(!Adjacent(A) && !istype(A, /obj/structure/window) && !istype(A, /obj/machinery/door/window)) // They could've moved in the meantime. But a Window probably wouldn't have. This allows player simple-mobs to attack windows.
- return FALSE
-
- var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
-
- for(var/datum/modifier/M in modifiers)
- if(!isnull(M.outgoing_melee_damage_percent))
- damage_to_do *= M.outgoing_melee_damage_percent
-
- // SA attacks can be blocked with shields.
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.check_shields(damage = damage_to_do, damage_source = src, attacker = src, def_zone = null, attack_text = "the attack"))
- return FALSE
-
- if(A.attack_generic(src, damage_to_do, pick(attacktext), attack_armor_type, attack_armor_pen, attack_sharp, attack_edge) && attack_sound)
- playsound(src, attack_sound, 75, 1)
-
- return TRUE
-
-//The actual top-level ranged attack proc
-/mob/living/simple_animal/proc/ShootTarget()
- if(!canClick())
- return FALSE
-
- setClickCooldown(get_attack_speed())
-
- var/target = target_mob
- var/tturf = get_turf(target)
-
- if((firing_lines && !client) && !CheckFiringLine(tturf))
- step_rand(src)
- face_atom(tturf)
- return FALSE
-
- visible_message("[src] fires at [target]!")
- if(rapid)
- spawn(1)
- Shoot(target, src.loc, src)
- if(casingtype)
- new casingtype(get_turf(src))
- spawn(4)
- Shoot(target, src.loc, src)
- if(casingtype)
- new casingtype(get_turf(src))
- spawn(6)
- Shoot(target, src.loc, src)
- if(casingtype)
- new casingtype(get_turf(src))
- else
- Shoot(target, src.loc, src)
- if(casingtype)
- new casingtype
-
- return TRUE
-
-//Check firing lines for faction_friends (if we're not cooperative, we don't care)
-/mob/living/simple_animal/proc/CheckFiringLine(var/turf/tturf)
- if(!tturf) return
-
- var/turf/list/crosses = list()
- var/this_turf = get_turf(src)
-
- while(this_turf != tturf)
- this_turf = get_step(this_turf,get_dir(this_turf,tturf))
- crosses += this_turf
-
- for(var/mob/living/FF in faction_friends)
- if(FF.loc in crosses)
- return 0
-
- for(var/mob/living/F in friends)
- if(F.loc in crosses)
- return 0
-
- return 1
-
-//Special attacks, like grenades or blinding spit or whatever
-/mob/living/simple_animal/proc/SpecialAtkTarget()
- return 0
-
-//Shoot a bullet at someone
-/mob/living/simple_animal/proc/Shoot(atom/target, atom/start, mob/user, var/bullet = 0)
- if(target == start)
- return
-
- var/obj/item/projectile/A = new projectiletype(user.loc)
- playsound(user, projectilesound, 100, 1)
- if(!A) return
-
-// if (!istype(target, /turf))
-// qdel(A)
-// return
- A.old_style_target(target)
- A.fire()
-
-//We can't see the target
-/mob/living/simple_animal/proc/LoseTarget()
- ai_log("LoseTarget() [target_mob]",2)
- target_mob = null
- handle_stance(STANCE_IDLE)
- GiveUpMoving()
-
-//Target is no longer valid (?)
-/mob/living/simple_animal/proc/LostTarget()
- handle_stance(STANCE_IDLE)
- GiveUpMoving()
-
-//Forget a follow mode
-/mob/living/simple_animal/proc/LoseFollow()
- ai_log("LoseFollow() [target_mob]",2)
- stop_automated_movement = 0
- follow_mob = null
- handle_stance(STANCE_IDLE)
- GiveUpMoving()
-
-// Makes the simple mob stop everything. Useful for when it get stunned.
-/mob/living/simple_animal/proc/Disable()
- ai_log("Disable() [target_mob]",2)
- spawn(0)
- LoseTarget()
- LoseFollow()
-
-/mob/living/simple_animal/Stun(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-/mob/living/simple_animal/AdjustStunned(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-/mob/living/simple_animal/Weaken(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-/mob/living/simple_animal/AdjustWeakened(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-/mob/living/simple_animal/Paralyse(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-/mob/living/simple_animal/AdjustParalysis(amount)
- if(amount > 0)
- Disable()
- ..(amount)
-
-//Find me some targets
-/mob/living/simple_animal/proc/ListTargets(var/dist = view_range)
- var/list/L = hearers(src, dist)
-
- for(var/obj/mecha/M in mechas_list)
- if ((M.z == src.z) && (get_dist(src, M) <= dist) && (isInSight(src,M)))
- L += M
-
- return L
-
-//Break through windows/other things
-/mob/living/simple_animal/proc/DestroySurroundings(var/direction)
- if(!direction)
- direction = pick(cardinal) //FLAIL WILDLY
-
- var/turf/problem_turf = get_step(src, direction)
-
- ai_log("DestroySurroundings([direction])",3)
- var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
-
- for(var/datum/modifier/M in modifiers)
- if(!isnull(M.outgoing_melee_damage_percent))
- damage_to_do *= M.outgoing_melee_damage_percent
-
- for(var/obj/structure/window/obstacle in problem_turf)
- if(obstacle.dir == reverse_dir[dir]) // So that windows get smashed in the right order
- ai_log("DestroySurroundings() directional window hit",3)
- obstacle.attack_generic(src, damage_to_do, pick(attacktext))
- return
- else if(obstacle.is_fulltile())
- ai_log("DestroySurroundings() full tile window hit",3)
- obstacle.attack_generic(src, damage_to_do, pick(attacktext))
- return
-
- var/obj/structure/obstacle = locate(/obj/structure, problem_turf)
- if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
- ai_log("DestroySurroundings() generic structure hit [obstacle]",3)
- obstacle.attack_generic(src, damage_to_do, pick(attacktext))
- return
-
- for(var/obj/machinery/door/baddoor in problem_turf) //Required since firelocks take up the same turf
- if(baddoor.density)
- ai_log("DestroySurroundings() door hit [baddoor]",3)
- baddoor.attack_generic(src, damage_to_do, pick(attacktext))
- return
-
-//Check for shuttle bumrush
-/mob/living/simple_animal/proc/check_horde()
- return 0
- if(emergency_shuttle.shuttle.location)
- if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway
- if(!shuttletarget && escape_list.len) //Make sure we didn't already assign it a target, and that there are targets to pick
- shuttletarget = pick(escape_list) //Pick a shuttle target
- enroute = 1
- stop_automated_movement = 1
- spawn()
- if(!src.stat)
- horde()
-
- if(get_dist(src, shuttletarget) <= 2) //The monster reached the escape hallway
- enroute = 0
- stop_automated_movement = 0
-
-//Shuttle bumrush
-/mob/living/simple_animal/proc/horde()
- var/turf/T = get_step_to(src, shuttletarget)
- for(var/atom/A in T)
- if(istype(A,/obj/machinery/door/airlock))
- var/obj/machinery/door/airlock/D = A
- D.open(1)
- else if(istype(A,/obj/structure/simple_door))
- var/obj/structure/simple_door/D = A
- if(D.density)
- D.Open()
- else if(istype(A,/obj/structure/cult/pylon))
- A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper))
- else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille))
- A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper))
- Move(T)
- FindTarget()
- if(!target_mob || enroute)
- spawn(10)
- if(!src.stat)
- horde()
-
-//Touches a wire, etc
-/mob/living/simple_animal/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
- shock_damage *= max(siemens_coeff - shock_resistance, 0)
- if (shock_damage < 1)
- return 0
-
- apply_damage(damage = shock_damage, damagetype = BURN, def_zone = null, blocked = null, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE)
- playsound(loc, "sparks", 50, 1, -1)
-
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, loc)
- s.start()
-
-//Shot with taser/stunvolver
-/mob/living/simple_animal/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null)
- if(taser_kill)
- var/stunDam = 0
- var/agonyDam = 0
- var/armor = run_armor_check(def_zone = null, attack_flag = "energy")
-
- if(stun_amount)
- stunDam += stun_amount * 0.5
- apply_damage(damage = stunDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE)
-
- if(agony_amount)
- agonyDam += agony_amount * 0.5
- apply_damage(damage = agonyDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE)
-
-/mob/living/simple_animal/emp_act(severity)
- if(!isSynthetic())
- return
- switch(severity)
- if(1)
- adjustFireLoss(rand(15, 25))
- if(2)
- adjustFireLoss(rand(10, 18))
- if(3)
- adjustFireLoss(rand(5, 12))
- if(4)
- adjustFireLoss(rand(1, 6))
-
-/mob/living/simple_animal/getarmor(def_zone, attack_flag)
- var/armorval = armor[attack_flag]
- if(!armorval)
- return 0
- else
- return armorval
-/*
-// Force it to target something
-/mob/living/simple_animal/proc/taunt(var/mob/living/new_target, var/forced = FALSE)
- if(intelligence_level == SA_HUMANOID && !forced)
- return
- set_target(new_target)
-*/
-/mob/living/simple_animal/is_sentient()
- return intelligence_level != SA_PLANT && intelligence_level != SA_ROBOTIC
-
-// Hand procs for player-controlled SA's
-/mob/living/simple_animal/swap_hand()
- src.hand = !( src.hand )
- if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
- if(hand) //This being 1 means the left hand is in use
- hud_used.l_hand_hud_object.icon_state = "l_hand_active"
- hud_used.r_hand_hud_object.icon_state = "r_hand_inactive"
- else
- hud_used.l_hand_hud_object.icon_state = "l_hand_inactive"
- hud_used.r_hand_hud_object.icon_state = "r_hand_active"
- return
-/*
-/mob/living/simple_animal/put_in_active_hand(var/obj/item/I)
- if(!has_hands || !istype(I))
- return
-*/
-//Puts the item into our active hand if possible. returns 1 on success.
-/mob/living/simple_animal/put_in_active_hand(var/obj/item/W)
- if(!has_hands)
- return FALSE
- return (hand ? put_in_l_hand(W) : put_in_r_hand(W))
-
-/mob/living/simple_animal/put_in_l_hand(var/obj/item/W)
- if(!..() || l_hand)
- return 0
- W.forceMove(src)
- l_hand = W
- W.equipped(src,slot_l_hand)
- W.add_fingerprint(src)
- update_inv_l_hand()
- return TRUE
-
-/mob/living/simple_animal/put_in_r_hand(var/obj/item/W)
- if(!..() || r_hand)
- return 0
- W.forceMove(src)
- r_hand = W
- W.equipped(src,slot_r_hand)
- W.add_fingerprint(src)
- update_inv_r_hand()
- return TRUE
-
-/mob/living/simple_animal/update_inv_r_hand()
- if(QDESTROYING(src))
- return
-
- if(r_hand)
- r_hand.screen_loc = ui_rhand //TODO
-
- //determine icon state to use
- var/t_state
- if(r_hand.item_state_slots && r_hand.item_state_slots[slot_r_hand_str])
- t_state = r_hand.item_state_slots[slot_r_hand_str]
- else if(r_hand.item_state)
- t_state = r_hand.item_state
- else
- t_state = r_hand.icon_state
-
- //determine icon to use
- var/icon/t_icon
- if(r_hand.item_icons && (slot_r_hand_str in r_hand.item_icons))
- t_icon = r_hand.item_icons[slot_r_hand_str]
- else if(r_hand.icon_override)
- t_state += "_r"
- t_icon = r_hand.icon_override
- else
- t_icon = INV_R_HAND_DEF_ICON
-
- //apply color
- var/image/standing = image(icon = t_icon, icon_state = t_state)
- standing.color = r_hand.color
-
- r_hand_sprite = standing
-
- else
- r_hand_sprite = null
-
- update_icon()
-
-/mob/living/simple_animal/update_inv_l_hand()
- if(QDESTROYING(src))
- return
-
- if(l_hand)
- l_hand.screen_loc = ui_lhand //TODO
-
- //determine icon state to use
- var/t_state
- if(l_hand.item_state_slots && l_hand.item_state_slots[slot_l_hand_str])
- t_state = l_hand.item_state_slots[slot_l_hand_str]
- else if(l_hand.item_state)
- t_state = l_hand.item_state
- else
- t_state = l_hand.icon_state
-
- //determine icon to use
- var/icon/t_icon
- if(l_hand.item_icons && (slot_l_hand_str in l_hand.item_icons))
- t_icon = l_hand.item_icons[slot_l_hand_str]
- else if(l_hand.icon_override)
- t_state += "_l"
- t_icon = l_hand.icon_override
- else
- t_icon = INV_L_HAND_DEF_ICON
-
- //apply color
- var/image/standing = image(icon = t_icon, icon_state = t_state)
- standing.color = l_hand.color
-
- l_hand_sprite = standing
-
- else
- l_hand_sprite = null
-
- update_icon()
-
-//Can insert extra huds into the hud holder here.
-/mob/living/simple_animal/proc/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements)
- return
-
-//If they can or cannot use tools/machines/etc
-/mob/living/simple_animal/IsAdvancedToolUser()
- return has_hands
-
-/mob/living/simple_animal/proc/IsHumanoidToolUser(var/atom/tool)
- if(!humanoid_hands)
- var/display_name = null
- if(tool)
- display_name = tool
- else
- display_name = "object"
- to_chat(src, "Your [hand_form] are not fit for use of \the [display_name].")
- return humanoid_hands
-
-/mob/living/simple_animal/drop_from_inventory(var/obj/item/W, var/atom/target = null)
- . = ..(W, target)
- if(!target)
- target = src.loc
- if(.)
- W.forceMove(src.loc)
-
-//Commands, reactions, etc
-/mob/living/simple_animal/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
- ..()
- if(!ai_inactive && reacts && speaker && (message in reactions) && (!hostile || isliving(speaker)) && say_understands(speaker,language))
- var/mob/living/L = speaker
- if(L.faction == faction)
- spawn(10)
- face_atom(speaker)
- say(reactions[message])
-
-//Just some subpaths for easy searching
-/mob/living/simple_animal/hostile
- faction = "not yours"
- hostile = 1
- retaliate = 1
- stop_when_pulled = 0
- destroy_surroundings = 1
-
-/mob/living/simple_animal/retaliate
- retaliate = 1
- destroy_surroundings = 1
-
-/mob/living/simple_animal/get_nametag_desc(mob/user)
- return "[tt_desc]"
diff --git a/code/modules/mob/living/simple_animal/simple_hud.dm b/code/modules/mob/living/simple_animal/simple_hud.dm
deleted file mode 100644
index 5da7e8a696..0000000000
--- a/code/modules/mob/living/simple_animal/simple_hud.dm
+++ /dev/null
@@ -1,311 +0,0 @@
-/mob/living/simple_animal/instantiate_hud(var/datum/hud/hud)
- if(!client)
- return //Why bother.
-
- var/ui_style = 'icons/mob/screen1_animal.dmi'
- if(ui_icons)
- ui_style = ui_icons
-
- var/ui_color = "#ffffff"
- var/ui_alpha = 255
-
- var/list/adding = list()
- var/list/other = list()
- var/list/hotkeybuttons = list()
- var/list/slot_info = list()
-
- hud.adding = adding
- hud.other = other
- hud.hotkeybuttons = hotkeybuttons
-
- var/list/hud_elements = list()
- var/obj/screen/using
- var/obj/screen/inventory/inv_box
-
- var/has_hidden_gear
- if(LAZYLEN(hud_gears))
- for(var/gear_slot in hud_gears)
- inv_box = new /obj/screen/inventory()
- inv_box.icon = ui_style
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
-
- var/list/slot_data = hud_gears[gear_slot]
- inv_box.name = gear_slot
- inv_box.screen_loc = slot_data["loc"]
- inv_box.slot_id = slot_data["slot"]
- inv_box.icon_state = slot_data["state"]
- slot_info["[inv_box.slot_id]"] = inv_box.screen_loc
-
- if(slot_data["dir"])
- inv_box.set_dir(slot_data["dir"])
-
- if(slot_data["toggle"])
- other += inv_box
- has_hidden_gear = 1
- else
- adding += inv_box
-
- if(has_hidden_gear)
- using = new /obj/screen()
- using.name = "toggle"
- using.icon = ui_style
- using.icon_state = "other"
- using.screen_loc = ui_inventory
- using.hud_layerise()
- using.color = ui_color
- using.alpha = ui_alpha
- adding += using
-
- //Intent Backdrop
- using = new /obj/screen()
- using.name = "act_intent"
- using.icon = ui_style
- using.icon_state = "intent_"+a_intent
- using.screen_loc = ui_acti
- using.color = ui_color
- using.alpha = ui_alpha
- hud.adding += using
- hud.action_intent = using
-
- hud_elements |= using
-
- //Small intent quarters
- var/icon/ico
-
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
- using = new /obj/screen()
- using.name = I_HELP
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = LAYER_HUD_ITEM //These sit on the intent box
- hud.adding += using
- hud.help_intent = using
-
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
- using = new /obj/screen()
- using.name = I_DISARM
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = LAYER_HUD_ITEM
- hud.adding += using
- hud.disarm_intent = using
-
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
- using = new /obj/screen()
- using.name = I_GRAB
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = LAYER_HUD_ITEM
- hud.adding += using
- hud.grab_intent = using
-
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
- using = new /obj/screen()
- using.name = I_HURT
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = LAYER_HUD_ITEM
- hud.adding += using
- hud.hurt_intent = using
-
- //Move intent (walk/run)
- using = new /obj/screen()
- using.name = "mov_intent"
- using.icon = ui_style
- using.icon_state = (m_intent == "run" ? "running" : "walking")
- using.screen_loc = ui_movi
- using.color = ui_color
- using.alpha = ui_alpha
- hud.adding += using
- hud.move_intent = using
-
- //Resist button
- using = new /obj/screen()
- using.name = "resist"
- using.icon = ui_style
- using.icon_state = "act_resist"
- using.screen_loc = ui_pull_resist
- using.color = ui_color
- using.alpha = ui_alpha
- hud.hotkeybuttons += using
-
- //Pull button
- pullin = new /obj/screen()
- pullin.icon = ui_style
- pullin.icon_state = "pull0"
- pullin.name = "pull"
- pullin.screen_loc = ui_pull_resist
- hud.hotkeybuttons += pullin
- hud_elements |= pullin
-
- //Health status
- healths = new /obj/screen()
- healths.icon = ui_style
- healths.icon_state = "health0"
- healths.name = "health"
- healths.screen_loc = ui_health
- hud_elements |= healths
-
- //Oxygen dep icon
- oxygen = new /obj/screen()
- oxygen.icon = ui_style
- oxygen.icon_state = "oxy0"
- oxygen.name = "oxygen"
- oxygen.screen_loc = ui_oxygen
- hud_elements |= oxygen
-
- //Toxins present icon
- toxin = new /obj/screen()
- toxin.icon = ui_style
- toxin.icon_state = "tox0"
- toxin.name = "toxin"
- toxin.screen_loc = ui_toxin
- hud_elements |= toxin
-
- //Fire warning
- fire = new /obj/screen()
- fire.icon = ui_style
- fire.icon_state = "fire0"
- fire.name = "fire"
- fire.screen_loc = ui_fire
- hud_elements |= fire
-
- //Pressure warning
- pressure = new /obj/screen()
- pressure.icon = ui_style
- pressure.icon_state = "pressure0"
- pressure.name = "pressure"
- pressure.screen_loc = ui_pressure
- hud_elements |= pressure
-
- //Body temp warning
- bodytemp = new /obj/screen()
- bodytemp.icon = ui_style
- bodytemp.icon_state = "temp0"
- bodytemp.name = "body temperature"
- bodytemp.screen_loc = ui_temp
- hud_elements |= bodytemp
-
- //Nutrition status
- nutrition_icon = new /obj/screen()
- nutrition_icon.icon = ui_style
- nutrition_icon.icon_state = "nutrition0"
- nutrition_icon.name = "nutrition"
- nutrition_icon.screen_loc = ui_nutrition
- hud_elements |= nutrition_icon
-
- pain = new /obj/screen( null )
-
- zone_sel = new /obj/screen/zone_sel( null )
- zone_sel.icon = ui_style
- zone_sel.color = ui_color
- zone_sel.alpha = ui_alpha
- zone_sel.overlays.Cut()
- zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
- hud_elements |= zone_sel
-
- //Hand things
- if(has_hands)
- //Drop button
- using = new /obj/screen()
- using.name = "drop"
- using.icon = ui_style
- using.icon_state = "act_drop"
- using.screen_loc = ui_drop_throw
- using.color = ui_color
- using.alpha = ui_alpha
- hud.hotkeybuttons += using
-
- //Equip detail
- using = new /obj/screen()
- using.name = "equip"
- using.icon = ui_style
- using.icon_state = "act_equip"
- using.screen_loc = ui_equip
- using.color = ui_color
- using.alpha = ui_alpha
- hud.adding += using
-
- //Hand slots themselves
- inv_box = new /obj/screen/inventory/hand()
- inv_box.hud = src
- inv_box.name = "r_hand"
- inv_box.icon = ui_style
- inv_box.icon_state = "r_hand_inactive"
- if(!hand) //This being 0 or null means the right hand is in use
- inv_box.icon_state = "r_hand_active"
- inv_box.screen_loc = ui_rhand
- inv_box.slot_id = slot_r_hand
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- hud.r_hand_hud_object = inv_box
- hud.adding += inv_box
- slot_info["[slot_r_hand]"] = inv_box.screen_loc
-
- inv_box = new /obj/screen/inventory/hand()
- inv_box.hud = src
- inv_box.name = "l_hand"
- inv_box.icon = ui_style
- inv_box.icon_state = "l_hand_inactive"
- if(hand) //This being 1 means the left hand is in use
- inv_box.icon_state = "l_hand_active"
- inv_box.screen_loc = ui_lhand
- inv_box.slot_id = slot_l_hand
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- hud.l_hand_hud_object = inv_box
- hud.adding += inv_box
- slot_info["[slot_l_hand]"] = inv_box.screen_loc
-
- //Swaphand titlebar
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.icon = ui_style
- using.icon_state = "hand1"
- using.screen_loc = ui_swaphand1
- using.color = ui_color
- using.alpha = ui_alpha
- hud.adding += using
-
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.icon = ui_style
- using.icon_state = "hand2"
- using.screen_loc = ui_swaphand2
- using.color = ui_color
- using.alpha = ui_alpha
- hud.adding += using
-
- //Throw button
- throw_icon = new /obj/screen()
- throw_icon.icon = ui_style
- throw_icon.icon_state = "act_throw_off"
- throw_icon.name = "throw"
- throw_icon.screen_loc = ui_drop_throw
- throw_icon.color = ui_color
- throw_icon.alpha = ui_alpha
- hud.hotkeybuttons += throw_icon
- hud_elements |= throw_icon
-
- extra_huds(hud,ui_style,hud_elements)
-
- client.screen = list()
-
- client.screen += hud_elements
- client.screen += adding + hotkeybuttons
- client.screen += client.void
-
- return
diff --git a/code/modules/mob/living/simple_animal/slime/ai.dm b/code/modules/mob/living/simple_animal/slime/ai.dm
deleted file mode 100644
index 3a8718c997..0000000000
--- a/code/modules/mob/living/simple_animal/slime/ai.dm
+++ /dev/null
@@ -1,91 +0,0 @@
-/mob/living/simple_animal/slime/FindTarget()
- if(victim) // Don't worry about finding another target if we're eatting someone.
- return
- if(follow_mob && can_command(follow_mob)) // If following someone, don't attack until the leader says so, something hits you, or the leader is no longer worthy.
- return
- ..()
-
-/mob/living/simple_animal/slime/Found(mob/living/L)
- if(isliving(L))
- if(SA_attackable(L))
- if(L.faction == faction && !attack_same)
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
- return H // Monkeys are always food.
- else
- return
-
- if(L in friends)
- return
-
- if(istype(L, /mob/living/simple_animal/slime))
- var/mob/living/simple_animal/slime/buddy = L
- if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity)
- return // Don't hurt same colored slimes.
- else
- return buddy //do hurt others
-
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
- return H // Monkeys are always food.
-
- if(issilicon(L) || isbot(L))
- if(discipline && !rabid)
- return // We're a good slime. For now at least.
- return
- return
-
-/mob/living/simple_animal/slime/special_target_check(mob/living/L)
- if(L.faction == faction && !attack_same && !istype(L, /mob/living/simple_animal/slime))
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
- return TRUE // Monkeys are always food.
- else
- return FALSE
- if(L in friends)
- return FALSE
-
- if(istype(L, /mob/living/simple_animal/slime))
- var/mob/living/simple_animal/slime/buddy = L
- if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity)
- return FALSE // Don't hurt same colored slimes.
-
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(H.species && H.species.name == "Promethean")
- return FALSE // Prometheans are always our friends.
- else if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
- return TRUE // Monkeys are always food.
- if(discipline && !rabid)
- return FALSE // We're a good slime. For now at least
-
- if(issilicon(L) || isbot(L) )
- if(discipline && !rabid)
- return FALSE // We're a good slime. For now at least.
- return ..() // Other colors and nonslimes are jerks however.
-
-/mob/living/simple_animal/slime/ClosestDistance()
- if(target_mob.stat == DEAD)
- return 1 // Melee (eat) the target if dead, don't shoot it.
- return ..()
-
-/mob/living/simple_animal/slime/HelpRequested(var/mob/living/simple_animal/slime/buddy)
- if(istype(buddy))
- if(buddy.slime_color != src.slime_color && (!unity || !buddy.unity)) // We only help slimes of the same color, if it's another slime calling for help.
- ai_log("HelpRequested() by [buddy] but they are a [buddy.slime_color] while we are a [src.slime_color].",2)
- return
- if(buddy.target_mob)
- if(!special_target_check(buddy.target_mob))
- ai_log("HelpRequested() by [buddy] but special_target_check() failed when passed [buddy.target_mob].",2)
- return
- ..()
-
-
-/mob/living/simple_animal/slime/handle_resist()
- if(buckled && victim && isliving(buckled) && victim == buckled) // If it's buckled to a living thing it's probably eating it.
- return
- else
- ..()
diff --git a/code/modules/mob/living/simple_animal/slime/combat.dm b/code/modules/mob/living/simple_animal/slime/combat.dm
deleted file mode 100644
index d13e81cd30..0000000000
--- a/code/modules/mob/living/simple_animal/slime/combat.dm
+++ /dev/null
@@ -1,277 +0,0 @@
-
-
-/*
-// Check target_mob if worthy of attack
-/mob/living/simple_animal/slime/SA_attackable(target_mob)
- ai_log("SA_attackable([target_mob])",3)
- if(isliving(target_mob))
- var/mob/living/L = target_mob
- if(L.stat == DEAD)
- if(can_consume(L)) // If we can eat them, then it doesn't matter if they're dead.
- return TRUE
- ..()
-*/
-
-/mob/living/simple_animal/slime/PunchTarget()
- if(victim)
- return // Already eatting someone.
- if(!client) // AI controlled.
- if( (!target_mob.lying && prob(60 + (power_charge * 4) ) || (!target_mob.lying && optimal_combat) )) // "Smart" slimes always stun first.
- a_intent = I_DISARM // Stun them first.
- else if(can_consume(target_mob) && target_mob.lying)
- a_intent = I_GRAB // Then eat them.
- else
- a_intent = I_HURT // Otherwise robust them.
- ai_log("PunchTarget() will [a_intent] [target_mob]",2)
- ..()
-
-/mob/living/simple_animal/slime/proc/can_consume(var/mob/living/L)
- if(!L || !istype(L))
- to_chat(src, "This subject is incomparable...")
- return FALSE
- if(L.isSynthetic())
- to_chat(src, "This subject is not biological...")
- return FALSE
- if(L.getarmor(null, "bio") >= 75)
- to_chat(src, "I cannot reach this subject's biological matter...")
- return FALSE
- if(istype(L, /mob/living/simple_animal/slime))
- to_chat(src, "I cannot feed on other slimes...")
- return FALSE
- if(!Adjacent(L))
- to_chat(src, "This subject is too far away...")
- return FALSE
- if(istype(L, /mob/living/carbon) && L.getCloneLoss() >= L.getMaxHealth() * 1.5 || istype(L, /mob/living/simple_animal) && L.stat == DEAD)
- to_chat(src, "This subject does not have an edible life energy...")
- return FALSE
- if(L.has_buckled_mobs())
- for(var/A in L.buckled_mobs)
- if(istype(A, /mob/living/simple_animal/slime))
- if(A != src)
- to_chat(src, "\The [A] is already feeding on this subject...")
- return FALSE
- return TRUE
-
-/mob/living/simple_animal/slime/proc/start_consuming(var/mob/living/L)
- if(!can_consume(L))
- return
- if(!Adjacent(L))
- return
- step_towards(src, L) // Get on top of them to feed.
- if(loc != L.loc)
- return
- if(L.buckle_mob(src, forced = TRUE))
- victim = L
- update_icon()
- victim.visible_message("\The [src] latches onto [victim]!",
- "\The [src] latches onto you!")
-
-/mob/living/simple_animal/slime/proc/stop_consumption()
- if(!victim)
- return
- victim.unbuckle_mob()
- victim.visible_message("\The [src] slides off of [victim]!",
- "\The [src] slides off of you!")
- victim = null
- update_icon()
-
-
-/mob/living/simple_animal/slime/proc/handle_consumption()
- if(victim && can_consume(victim) && !stat)
-
- var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1)
- if(istype(victim, /mob/living/carbon))
- victim.adjustCloneLoss(rand(5,6) * armor_modifier)
- victim.adjustToxLoss(rand(1,2) * armor_modifier)
- if(victim.health <= 0)
- victim.adjustToxLoss(rand(2,4) * armor_modifier)
-
- else if(istype(victim, /mob/living/simple_animal))
- victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12))
-
- else
- to_chat(src, "[pick("This subject is incompatable", \
- "This subject does not have a life energy", "This subject is empty", "I am not satisified", \
- "I can not feed from this subject", "I do not feel nourished", "This subject is not food")]...")
- stop_consumption()
-
- adjust_nutrition(50 * armor_modifier)
-
- adjustOxyLoss(-10 * armor_modifier) //Heal yourself
- adjustBruteLoss(-10 * armor_modifier)
- adjustFireLoss(-10 * armor_modifier)
- adjustCloneLoss(-10 * armor_modifier)
- updatehealth()
- if(victim)
- victim.updatehealth()
- else
- stop_consumption()
-
-/mob/living/simple_animal/slime/DoPunch(var/mob/living/L)
- if(!Adjacent(L)) // Might've moved away in the meantime.
- return
-
- if(istype(L))
-
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- // Slime attacks can be blocked with shields.
- if(H.check_shields(damage = 0, damage_source = null, attacker = src, def_zone = null, attack_text = "the attack"))
- return
-
- switch(a_intent)
- if(I_HELP)
- ai_log("DoPunch() against [L], helping.",2)
- L.visible_message("[src] gently pokes [L]!",
- "[src] gently pokes you!")
- do_attack_animation(L)
- post_attack(L, a_intent)
-
- if(I_DISARM)
- ai_log("DoPunch() against [L], disarming.",2)
- var/stun_power = between(0, power_charge + rand(0, 3), 10)
-
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- stun_power *= max(H.species.siemens_coefficient,0)
-
-
- if(prob(stun_power * 10))
- power_charge = max(0, power_charge - 3)
- L.visible_message("[src] has shocked [L]!", "[src] has shocked you!")
- playsound(src, 'sound/weapons/Egloves.ogg', 75, 1)
- L.Weaken(4)
- L.Stun(4)
- do_attack_animation(L)
- if(L.buckled)
- L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you.
- L.stuttering = max(L.stuttering, stun_power)
-
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, L)
- s.start()
-
- if(prob(stun_power * 10) && stun_power >= 8)
- L.adjustFireLoss(power_charge * rand(1, 2))
- post_attack(L, a_intent)
-
- else if(prob(40))
- L.visible_message("[src] has pounced at [L]!", "[src] has pounced at you!")
- playsound(src, 'sound/weapons/thudswoosh.ogg', 75, 1)
- L.Weaken(2)
- do_attack_animation(L)
- if(L.buckled)
- L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you.
- post_attack(L, a_intent)
- else
- L.visible_message("[src] has tried to pounce at [L]!", "[src] has tried to pounce at you!")
- playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
- do_attack_animation(L)
- L.updatehealth()
- return L
-
- if(I_GRAB)
- ai_log("DoPunch() against [L], grabbing.",2)
- start_consuming(L)
- post_attack(L, a_intent)
-
- if(I_HURT)
- ai_log("DoPunch() against [L], hurting.",2)
- var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
- var/armor_modifier = abs((L.getarmor(null, "bio") / 100) - 1)
-
- L.attack_generic(src, damage_to_do, pick(attacktext))
- playsound(src, 'sound/weapons/bite.ogg', 75, 1)
-
- // Give the slime some nutrition, if applicable.
- if(!L.isSynthetic())
- if(ishuman(L))
- if(L.getCloneLoss() < L.getMaxHealth() * 1.5)
- adjust_nutrition(damage_to_do * armor_modifier)
-
- else if(istype(L, /mob/living/simple_animal))
- if(!isslime(L))
- var/mob/living/simple_animal/SA = L
- if(!SA.stat)
- adjust_nutrition(damage_to_do)
-
- post_attack(L, a_intent)
-
- if(istype(L,/obj/mecha))
- var/obj/mecha/M = L
- M.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), pick(attacktext))
-
-/mob/living/simple_animal/slime/proc/post_attack(var/mob/living/L, var/intent = I_HURT)
- if(intent != I_HELP)
- if(L.reagents && L.can_inject() && reagent_injected)
- L.reagents.add_reagent(reagent_injected, injection_amount)
-
-/mob/living/simple_animal/slime/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/clothing/head)) // Handle hat simulator.
- give_hat(W, user)
- return
-
- // Otherwise they're probably fighting the slime.
- if(prob(25))
- visible_message("\The [user]'s [W] passes right through [src]!")
- user.setClickCooldown(user.get_attack_speed(W))
- return
- ..()
-
-/mob/living/simple_animal/slime/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
- ..()
- if(!stat)
- if(O.force > 0 && discipline && !rabid) // wow, buddy, why am I getting attacked??
- adjust_discipline(1)
- return
- if(O.force >= 3)
- if(victim || target_mob) // We've been a bad slime.
- if(is_adult)
- if(prob(5 + round(O.force / 2)) )
- if(prob(80) && !client)
- adjust_discipline(2)
- if(user)
- step_away(src, user)
- else
- if(prob(10 + O.force * 2))
- if(prob(80) && !client)
- adjust_discipline(2)
- if(user)
- step_away(src, user)
- else
- if(user in friends) // Friend attacking us for no reason.
- if(prob(25))
- friends -= user
- say("[user]... not friend...")
-
-/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M as mob)
- if(victim) // Are we eating someone?
- var/fail_odds = 30
- if(victim == M) // Harder to get the slime off if its eating you right now.
- fail_odds = 60
-
- if(prob(fail_odds))
- visible_message("[M] attempts to wrestle \the [name] off!")
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
-
- else
- visible_message(" [M] manages to wrestle \the [name] off!")
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
-
- if(prob(40) && !client)
- adjust_discipline(1)
- stop_consumption()
- step_away(src,M)
- else
- if(M.a_intent == I_HELP)
- if(hat)
- remove_hat(M)
- else
- ..()
- else
- ..()
-
-// Shocked grilles don't hurt slimes, and in fact give them charge.
-/mob/living/simple_animal/slime/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
- power_charge = between(0, power_charge + round(shock_damage / 10), 10)
- to_chat(src, "\The [source] shocks you, and it charges you.")
diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm
deleted file mode 100644
index 622b12a859..0000000000
--- a/code/modules/mob/living/simple_animal/slime/death.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/mob/living/simple_animal/slime/death(gibbed)
-
- if(stat == DEAD)
- return
-
- if(!gibbed && is_adult)
- var/death_type = type_on_death
- if(!death_type)
- death_type = src.type
- var/mob/living/simple_animal/slime/S = make_new_slime(death_type)
- S.rabid = TRUE
- step_away(S, src)
- is_adult = FALSE
- maxHealth = initial(maxHealth)
- revive()
- if(!client)
- rabid = TRUE
- number = rand(1, 1000)
- update_name()
- return
-
- stop_consumption()
- . = ..(gibbed, "stops moving and partially dissolves...")
-
- update_icon()
-
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
deleted file mode 100644
index 691b880574..0000000000
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ /dev/null
@@ -1,183 +0,0 @@
-/mob/living/simple_animal/slime/proc/adjust_nutrition(input)
- nutrition = between(0, nutrition + input, get_max_nutrition())
-
- if(input > 0)
- if(prob(input * 2)) // Gain around one level per 50 nutrition
- power_charge = min(power_charge++, 10)
- if(power_charge == 10)
- adjustToxLoss(-10)
-
-
-/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it
- if(is_adult)
- return 1200
- return 1000
-
-/mob/living/simple_animal/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
- if(is_adult)
- return 1000
- return 800
-
-/mob/living/simple_animal/slime/proc/get_hunger_nutrition() // Below it we will always eat
- if(is_adult)
- return 600
- return 500
-
-/mob/living/simple_animal/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
- if(is_adult)
- return 300
- return 200
-
-/mob/living/simple_animal/slime/proc/handle_nutrition()
- if(docile)
- return
- if(prob(15))
- adjust_nutrition(-1 - is_adult)
-
- if(nutrition <= get_starve_nutrition())
- handle_starvation()
-
- else if(nutrition >= get_grow_nutrition() && amount_grown < 10)
- adjust_nutrition(-20)
- amount_grown = between(0, amount_grown + 1, 10)
-
-/mob/living/simple_animal/slime/proc/handle_starvation()
- if(nutrition < get_starve_nutrition() && !client) // if a slime is starving, it starts losing its friends
- if(friends.len && prob(1))
- var/mob/nofriend = pick(friends)
- if(nofriend)
- friends -= nofriend
- say("[nofriend]... food now...")
-
- if(nutrition <= 0)
- adjustToxLoss(rand(1,3))
- if(client && prob(5))
- to_chat(src, "You are starving!")
-
-/mob/living/simple_animal/slime/proc/handle_discipline()
- if(discipline > 0)
- update_mood()
- // if(discipline >= 5 && rabid)
- // if(prob(60))
- // rabid = 0
- // adjust_discipline(1) // So it stops trying to murder everyone.
-
- // Handle discipline decay.
- if(!prob(75 + (obedience * 5)))
- adjust_discipline(-1)
- if(!discipline)
- update_mood()
-
-/mob/living/simple_animal/slime/handle_regular_status_updates()
- if(stat != DEAD)
- handle_nutrition()
-
- handle_discipline()
-
- if(prob(30))
- adjustOxyLoss(-1)
- adjustToxLoss(-1)
- adjustFireLoss(-1)
- adjustCloneLoss(-1)
- adjustBruteLoss(-1)
-
- if(victim)
- handle_consumption()
-
- if(amount_grown >= 10 && !target_mob && !client)
- if(is_adult)
- reproduce()
- else
- evolve()
-
- handle_stuttering()
-
- ..()
-
-
-// This is to make slime responses feel a bit more natural and not instant.
-/mob/living/simple_animal/slime/proc/delayed_say(var/message, var/mob/target)
- spawn(rand(1 SECOND, 2 SECONDS))
- if(target)
- face_atom(target)
- say(message)
-
-//Commands, reactions, etc
-/mob/living/simple_animal/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
- ..()
- if((findtext(message, num2text(number)) || findtext(message, name) || findtext(message, "slimes"))) // Talking to us
-
- // First make sure it's not just another slime repeating things.
- if(istype(speaker, /mob/living/simple_animal/slime))
- if(!speaker.client)
- return
-
- //Are all slimes being referred to?
- var/mass_order = 0
- if(findtext(message, "slimes"))
- mass_order = 1
-
- // Say hello back.
- if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings"))
- delayed_say(pick("Hello...", "Hi..."), speaker)
-
- // Follow request.
- if(findtext(message, "follow") || findtext(message, "come with me"))
- if(!can_command(speaker))
- delayed_say(pick("No...", "I won't follow..."), speaker)
- return
-
- delayed_say("Yes... I follow \the [speaker]...", speaker)
- set_follow(speaker)
- FollowTarget()
-
- // Stop request.
- if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease"))
- if(victim) // We're being asked to stop eatting someone.
- if(!can_command(speaker))
- delayed_say("No...", speaker)
- return
- else
- delayed_say("Fine...", speaker)
- stop_consumption()
- adjust_discipline(1, TRUE)
-
- if(target_mob) // We're being asked to stop chasing someone.
- if(!can_command(speaker))
- delayed_say("No...", speaker)
- return
- else
- delayed_say("Fine...", speaker)
- LoseTarget()
- adjust_discipline(1, TRUE)
-
- if(follow_mob) // We're being asked to stop following someone.
- if(can_command(speaker) == SLIME_COMMAND_FRIEND || follow_mob == speaker)
- delayed_say("Yes... I'll stop...", speaker)
- LoseFollow()
- else
- delayed_say("No... I'll keep following \the [follow_mob]...", speaker)
-
- // Murder request
- if(findtext(message, "harm") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume"))
- if(can_command(speaker) < SLIME_COMMAND_FACTION)
- delayed_say("No...", speaker)
- return
-
- for(var/mob/living/L in view(7, src) - list(src, speaker))
- if(L == src)
- continue // Don't target ourselves.
- var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example.
- for(var/line in valid_names) // Check each part of someone's name.
- if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to.
- if(!(mass_order && line == "slime")) //don't think random other slimes are target
- if(special_target_check(L))
- delayed_say("Okay... I attack \the [L]...", speaker)
- LoseFollow()
- set_target(L, 1)
- return
- else
- delayed_say("No... I won't attack \the [L].", speaker)
- return
- // If we're here, it couldn't find anyone with that name.
- delayed_say("No... I don't know who to attack...", speaker)
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
deleted file mode 100644
index 2b5d44ded9..0000000000
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ /dev/null
@@ -1,470 +0,0 @@
-/mob/living/simple_animal/slime
- name = "slime"
- desc = "The most basic of slimes. The grey slime has no remarkable qualities, however it remains one of the most useful colors for scientists."
- tt_desc = "A Macrolimbus vulgaris"
- icon = 'icons/mob/slime2.dmi'
- icon_state = "grey baby slime"
- intelligence_level = SA_ANIMAL
- pass_flags = PASSTABLE
- var/shiny = FALSE // If true, will add a 'shiny' overlay.
- var/glows = FALSE // If true, will glow in the same color as the color var.
- var/icon_state_override = null // Used for special slime appearances like the rainbow slime.
- pass_flags = PASSTABLE
-
- makes_dirt = FALSE // Goop
-
- speak_emote = list("chirps")
-
- maxHealth = 150
- var/maxHealth_adult = 200
- melee_damage_lower = 10
- melee_damage_upper = 15
- melee_miss_chance = 0
- gender = NEUTER
-
- // Atmos stuff.
- minbodytemp = T0C-30
- heat_damage_per_tick = 0
- cold_damage_per_tick = 40
-
- min_oxy = 0
- max_oxy = 0
- min_tox = 0
- max_tox = 0
- min_co2 = 0
- max_co2 = 0
- min_n2 = 0
- max_n2 = 0
- unsuitable_atoms_damage = 0
-
- response_help = "pets"
-
- speak = list(
- "Blorp...",
- "Blop..."
-
- )
- emote_hear = list(
-
- )
- emote_see = list(
- "bounces",
- "jiggles",
- "sways"
- )
-
- hostile = 1
- retaliate = 1
- attack_same = 1
- cooperative = 1
- faction = "slime" // Slimes will help other slimes, provided they share the same color.
-
- color = "#CACACA"
- var/is_adult = FALSE
- var/cores = 1 // How many cores you get when placed in a Processor.
- var/power_charge = 0 // 0-10 controls how much electricity they are generating. High numbers encourage the slime to stun someone with electricity.
- var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
- var/number = 0 // This is used to make the slime semi-unique for indentification.
-
- var/mob/living/victim = null // the person the slime is currently feeding on
- var/rabid = FALSE // If true, will attack anyone and everyone.
- var/docile = FALSE // Basically the opposite of above. If true, will never harm anything and won't get hungry.
- var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory.
- var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go berserk.
- var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slowly, potentially making it not decay at all.
- var/unity = FALSE // If true, slimes will consider other colors as their own. Other slimes will see this slime as the same color as well. A rainbow slime is required to get this.
- var/optimal_combat = FALSE // Used to dumb down the combat AI somewhat. If true, the slime tends to be really dangerous to fight alone due to stunlocking.
- var/mood = ":3" // Icon to use to display 'mood'.
- var/obj/item/clothing/head/hat = null // The hat the slime may be wearing.
-
- var/slime_color = "grey"
- var/mutation_chance = 25 // Odds of spawning as a new color when reproducing. Can be modified by certain xenobio products. Carried across generations of slimes.
- var/coretype = /obj/item/slime_extract/grey
- // List of potential slime color mutations. This must have exactly four types.
- var/list/slime_mutation = list(
- /mob/living/simple_animal/slime/orange,
- /mob/living/simple_animal/slime/metal,
- /mob/living/simple_animal/slime/blue,
- /mob/living/simple_animal/slime/purple
- )
- var/type_on_death = null // Set this if you want dying slimes to split into a specific type and not their type.
- var/rainbow_core_candidate = TRUE // If false, rainbow cores cannot make this type randomly.
-
- var/reagent_injected = null // Some slimes inject reagents on attack. This tells the game what reagent to use.
- var/injection_amount = 5 // This determines how much.
-
-
- can_enter_vent_with = list(
- /obj/item/clothing/head,
- )
-
-/mob/living/simple_animal/slime/New(var/location, var/start_as_adult = FALSE)
- verbs += /mob/living/proc/ventcrawl
- if(start_as_adult)
- make_adult()
- health = maxHealth
-// slime_mutation = mutation_table(slime_color)
- update_icon()
- number = rand(1, 1000)
- update_name()
- ..(location)
-
-/mob/living/simple_animal/slime/Destroy()
- if(hat)
- drop_hat()
- return ..()
-
-/mob/living/simple_animal/slime/proc/make_adult()
- if(is_adult)
- return
-
- is_adult = TRUE
- melee_damage_lower = 20
- melee_damage_upper = 40
- maxHealth = maxHealth_adult
- amount_grown = 0
- update_icon()
- update_name()
-
-/mob/living/simple_animal/slime/proc/update_name()
- if(docile) // Docile slimes are generally named, so we shouldn't mess with it.
- return
- name = "[slime_color] [is_adult ? "adult" : "baby"] [initial(name)] ([number])"
- real_name = name
-
-/mob/living/simple_animal/slime/update_icon()
- if(stat == DEAD)
- icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead"
- set_light(0)
- else
- if(incapacitated(INCAPACITATION_DISABLED))
- icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead"
- else
- icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"][victim ? " eating":""]"
-
- overlays.Cut()
- if(stat != DEAD)
- var/image/I = image(icon, src, "slime light")
- I.appearance_flags = RESET_COLOR
- overlays += I
-
- if(shiny)
- I = image(icon, src, "slime shiny")
- I.appearance_flags = RESET_COLOR
- overlays += I
-
- I = image(icon, src, "aslime-[mood]")
- I.appearance_flags = RESET_COLOR
- overlays += I
-
- if(glows)
- set_light(3, 2, color)
-
- if(hat)
- var/hat_state = hat.item_state ? hat.item_state : hat.icon_state
- var/image/I = image('icons/mob/head.dmi', src, hat_state)
- I.pixel_y = -7 // Slimes are small.
- I.appearance_flags = RESET_COLOR
- overlays += I
-
- if(modifier_overlay) // Restore our modifier overlay.
- overlays += modifier_overlay
-
-/mob/living/simple_animal/slime/proc/update_mood()
- var/old_mood = mood
- if(incapacitated(INCAPACITATION_DISABLED))
- mood = "sad"
- else if(rabid)
- mood = "angry"
- else if(target_mob)
- mood = "mischevous"
- else if(discipline)
- mood = "pout"
- else if(docile)
- mood = ":33"
- else
- mood = ":3"
- if(old_mood != mood)
- update_icon()
-
-// Makes the slime very angry and dangerous.
-/mob/living/simple_animal/slime/proc/enrage()
- if(docile)
- return
- rabid = TRUE
- update_mood()
- visible_message("\The [src] enrages!")
-
-// Makes the slime safe and harmless.
-/mob/living/simple_animal/slime/proc/pacify()
- rabid = FALSE
- docile = TRUE
- hostile = FALSE
- retaliate = FALSE
- cooperative = FALSE
-
- // If for whatever reason the mob AI decides to try to attack something anyways.
- melee_damage_upper = 0
- melee_damage_lower = 0
-
- update_mood()
-
-/mob/living/simple_animal/slime/proc/unify()
- unity = TRUE
- attack_same = FALSE
-
-/mob/living/simple_animal/slime/examine(mob/user)
- ..()
- if(hat)
- to_chat(user, "It is wearing \a [hat].")
-
- if(stat == DEAD)
- to_chat(user, "It appears to be dead.")
- else if(incapacitated(INCAPACITATION_DISABLED))
- to_chat(user, "It appears to be incapacitated.")
- else if(rabid)
- to_chat(user, "It seems very, very angry and upset.")
- else if(obedience >= 5)
- to_chat(user, "It looks rather obedient.")
- else if(discipline)
- to_chat(user, "It has been subjugated by force, at least for now.")
- else if(docile)
- to_chat(user, "It appears to have been pacified.")
-
-/mob/living/simple_animal/slime/water_act(amount) // This is called if a slime enters a water tile.
- adjustBruteLoss(40 * amount)
-
-/mob/living/simple_animal/slime/proc/adjust_discipline(amount, silent)
- if(amount > 0)
- if(!rabid)
- var/justified = is_justified_to_discipline()
- spawn(0)
- stop_consumption()
- LoseTarget()
- if(!silent)
- if(justified)
- say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy..."))
- else
- say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo..."))
- if(justified)
- obedience++
- else
- if(prob(resentment * 20))
- enrage() // Pushed the slime too far.
- say(pick("Evil...", "Kill...", "Tyrant..."))
- resentment++ // Done after check so first time will never enrage.
-
- discipline = between(0, discipline + amount, 10)
-
-/mob/living/simple_animal/slime/movement_delay()
- if(bodytemperature >= 330.23) // 135 F or 57.08 C
- return -1 // slimes become supercharged at high temperatures
-
- . = ..()
-
- var/health_deficiency = (maxHealth - health)
- if(health_deficiency >= 45)
- . += (health_deficiency / 25)
-
- if(bodytemperature < 183.222)
- . += (283.222 - bodytemperature) / 10 * 1.75
-
- . += config.slime_delay
-
-/mob/living/simple_animal/slime/Process_Spacemove()
- return 2
-
-/mob/living/simple_animal/slime/verb/evolve()
- set category = "Slime"
- set desc = "This will let you evolve from baby to adult slime."
-
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return
-
- if(docile)
- to_chat(src, "I have been pacified. I cannot evolve...")
- return
-
- if(!is_adult)
- if(amount_grown >= 10)
- make_adult()
- else
- to_chat(src, "I am not ready to evolve yet...")
- else
- to_chat(src, "I have already evolved...")
-
-/mob/living/simple_animal/slime/verb/reproduce()
- set category = "Slime"
- set desc = "This will make you split into four Slimes."
-
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return
-
- if(docile)
- to_chat(src, "I have been pacified. I cannot reproduce...")
- return
-
- if(is_adult)
- if(amount_grown >= 10)
- // Check if there's enough 'room' to split.
- var/list/nearby_things = orange(1, src)
- var/free_tiles = 0
- for(var/turf/T in nearby_things)
- var/free = TRUE
- if(T.density) // No walls.
- continue
- for(var/atom/movable/AM in T)
- if(AM.density)
- free = FALSE
- break
-
- if(free)
- free_tiles++
-
- if(free_tiles < 3) // Three free tiles are needed, as four slimes are made and the 4th tile is from the center tile that the current slime occupies.
- to_chat(src, "It is too cramped here to reproduce...")
- return
-
- var/list/babies = list()
- for(var/i = 1 to 4)
- babies.Add(make_new_slime())
-
- var/mob/living/simple_animal/slime/new_slime = pick(babies)
- new_slime.universal_speak = universal_speak
- if(src.mind)
- src.mind.transfer_to(new_slime)
- else
- new_slime.key = src.key
- qdel(src)
- else
- to_chat(src, "I am not ready to reproduce yet...")
- else
- to_chat(src, "I am not old enough to reproduce yet...")
-
-// Used for reproducing and dying.
-/mob/living/simple_animal/slime/proc/make_new_slime(var/desired_type)
- var/t = src.type
- if(desired_type)
- t = desired_type
- if(prob(mutation_chance / 10))
- t = /mob/living/simple_animal/slime/rainbow
-
- else if(prob(mutation_chance) && slime_mutation.len)
- t = slime_mutation[rand(1, slime_mutation.len)]
- var/mob/living/simple_animal/slime/baby = new t(loc)
-
- // Handle 'inheriting' from parent slime.
- baby.mutation_chance = mutation_chance
- baby.power_charge = round(power_charge / 4)
- baby.resentment = max(resentment - 1, 0)
- if(!istype(baby, /mob/living/simple_animal/slime/light_pink))
- baby.discipline = max(discipline - 1, 0)
- baby.obedience = max(obedience - 1, 0)
- if(!istype(baby, /mob/living/simple_animal/slime/rainbow))
- baby.unity = unity
- baby.faction = faction
- baby.attack_same = attack_same
- baby.friends = friends.Copy()
- if(rabid)
- baby.enrage()
-
- step_away(baby, src)
- return baby
-
-/mob/living/simple_animal/slime/speech_bubble_appearance()
- return "slime"
-
-// Called after they finish eatting someone.
-/mob/living/simple_animal/slime/proc/befriend(var/mob/living/friend)
- if(!(friend in friends))
- friends |= friend
- say("[friend]... friend...")
-
-/mob/living/simple_animal/slime/proc/can_command(var/mob/living/commander)
- if(rabid)
- return FALSE
- if(docile)
- return SLIME_COMMAND_OBEY
- if(commander in friends)
- return SLIME_COMMAND_FRIEND
- if(faction == commander.faction)
- return SLIME_COMMAND_FACTION
- if(discipline > resentment && obedience >= 5)
- return SLIME_COMMAND_OBEY
- return FALSE
-
-/mob/living/simple_animal/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user)
- if(!istype(new_hat))
- to_chat(user, "\The [new_hat] isn't a hat.")
- return
- if(hat)
- to_chat(user, "\The [src] is already wearing \a [hat].")
- return
- else
- user.drop_item(new_hat)
- hat = new_hat
- new_hat.forceMove(src)
- to_chat(user, "You place \a [new_hat] on \the [src]. How adorable!")
- update_icon()
- return
-
-/mob/living/simple_animal/slime/proc/remove_hat(var/mob/living/user)
- if(!hat)
- to_chat(user, "\The [src] doesn't have a hat to remove.")
- else
- hat.forceMove(get_turf(src))
- user.put_in_hands(hat)
- to_chat(user, "You take away \the [src]'s [hat.name]. How mean.")
- hat = null
- update_icon()
-
-/mob/living/simple_animal/slime/proc/drop_hat()
- if(!hat)
- return
- hat.forceMove(get_turf(src))
- hat = null
- update_icon()
-
-// Checks if disciplining the slime would be 'justified' right now.
-/mob/living/simple_animal/slime/proc/is_justified_to_discipline()
- if(rabid)
- return TRUE
- if(target_mob)
- if(ishuman(target_mob))
- var/mob/living/carbon/human/H = target_mob
- if(istype(H.species, /datum/species/monkey))
- return FALSE
- return TRUE
- return FALSE
-
-
-/mob/living/simple_animal/slime/get_description_interaction()
- var/list/results = list()
-
- if(!stat)
- results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad."
-
- results += ..()
-
- return results
-
-/mob/living/simple_animal/slime/get_description_info()
- var/list/lines = list()
- var/intro_line = "Slimes are generally the test subjects of Xenobiology, with different colors having different properties. \
- They can be extremely dangerous if not handled properly."
- lines.Add(intro_line)
- lines.Add(null) // To pad the line breaks.
-
- var/list/rewards = list()
- for(var/potential_color in slime_mutation)
- var/mob/living/simple_animal/slime/S = potential_color
- rewards.Add(initial(S.slime_color))
- var/reward_line = "This color of slime can mutate into [english_list(rewards)] colors, when it reproduces. It will do so when it has eatten enough."
- lines.Add(reward_line)
- lines.Add(null)
-
- lines.Add(description_info)
- return lines.Join("\n")
-
diff --git a/code/modules/mob/living/simple_animal/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm
deleted file mode 100644
index 75f33cdcef..0000000000
--- a/code/modules/mob/living/simple_animal/slime/subtypes.dm
+++ /dev/null
@@ -1,748 +0,0 @@
-// Tier 1
-
-/mob/living/simple_animal/slime/purple
- desc = "This slime is rather toxic to handle, as it is poisonous."
- color = "#CC23FF"
- slime_color = "purple"
- coretype = /obj/item/slime_extract/purple
- reagent_injected = "toxin"
-
- description_info = "This slime spreads a toxin when it attacks. A biosuit or other thick armor can protect from the toxic attack."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/dark_purple,
- /mob/living/simple_animal/slime/dark_blue,
- /mob/living/simple_animal/slime/green,
- /mob/living/simple_animal/slime
- )
-
-
-/mob/living/simple_animal/slime/orange
- desc = "This slime is known to be flammable and can ignite enemies."
- color = "#FFA723"
- slime_color = "orange"
- coretype = /obj/item/slime_extract/orange
-
- description_info = "Attacks from this slime can ignite you. A firesuit can protect from the burning attacks of this slime."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/dark_purple,
- /mob/living/simple_animal/slime/yellow,
- /mob/living/simple_animal/slime/red,
- /mob/living/simple_animal/slime
- )
-
-/mob/living/simple_animal/slime/orange/post_attack(mob/living/L, intent)
- if(intent != I_HELP)
- L.adjust_fire_stacks(1)
- if(prob(25))
- L.IgniteMob()
- ..()
-
-/mob/living/simple_animal/slime/blue
- desc = "This slime produces 'cryotoxin' and uses it against their foes. Very deadly to other slimes."
- color = "#19FFFF"
- slime_color = "blue"
- coretype = /obj/item/slime_extract/blue
- reagent_injected = "cryotoxin"
-
- description_info = "Attacks from this slime can chill you. A biosuit or other thick armor can protect from the chilling attack."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/dark_blue,
- /mob/living/simple_animal/slime/silver,
- /mob/living/simple_animal/slime/pink,
- /mob/living/simple_animal/slime
- )
-
-
-/mob/living/simple_animal/slime/metal
- desc = "This slime is a lot more resilient than the others, due to having a metamorphic metallic and sloped surface."
- color = "#5F5F5F"
- slime_color = "metal"
- shiny = 1
- coretype = /obj/item/slime_extract/metal
-
- description_info = "This slime is a lot more durable and tough to damage than the others."
-
- resistance = 10 // Sloped armor is strong.
- maxHealth = 250
- maxHealth_adult = 350
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/silver,
- /mob/living/simple_animal/slime/yellow,
- /mob/living/simple_animal/slime/gold,
- /mob/living/simple_animal/slime
- )
-
-// Tier 2
-
-/mob/living/simple_animal/slime/yellow
- desc = "This slime is very conductive, and is known to use electricity as a means of defense moreso than usual for slimes."
- color = "#FFF423"
- slime_color = "yellow"
- coretype = /obj/item/slime_extract/yellow
-
- ranged = 1
- shoot_range = 3
- firing_lines = 1
- projectiletype = /obj/item/projectile/beam/lightning/slime
- projectilesound = 'sound/weapons/gauss_shoot.ogg' // Closest thing to a 'thunderstrike' sound we have.
- glows = TRUE
-
- description_info = "This slime will fire lightning attacks at enemies if they are at range, and generate electricity \
- for their stun attack faster than usual. Insulative or reflective armor can protect from the lightning."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/bluespace,
- /mob/living/simple_animal/slime/bluespace,
- /mob/living/simple_animal/slime/metal,
- /mob/living/simple_animal/slime/orange
- )
-
-/mob/living/simple_animal/slime/yellow/handle_regular_status_updates()
- if(stat == CONSCIOUS)
- if(prob(25))
- power_charge = between(0, power_charge + 1, 10)
- ..()
-
-/obj/item/projectile/beam/lightning/slime
- power = 15
-
-/mob/living/simple_animal/slime/yellow/ClosestDistance() // Needed or else they won't eat monkeys outside of melee range.
- if(target_mob && ishuman(target_mob))
- var/mob/living/carbon/human/H = target_mob
- if(istype(H.species, /datum/species/monkey))
- return 1
- return ..()
-
-
-/mob/living/simple_animal/slime/dark_purple
- desc = "This slime produces ever-coveted phoron. Risky to handle but very much worth it."
- color = "#660088"
- slime_color = "dark purple"
- coretype = /obj/item/slime_extract/dark_purple
- reagent_injected = "phoron"
-
- description_info = "This slime applies phoron to enemies it attacks. A biosuit or other thick armor can protect from the toxic attack. \
- If hit with a burning attack, it will erupt in flames."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/purple,
- /mob/living/simple_animal/slime/orange,
- /mob/living/simple_animal/slime/ruby,
- /mob/living/simple_animal/slime/ruby
- )
-
-/mob/living/simple_animal/slime/dark_purple/proc/ignite()
- visible_message("\The [src] erupts in an inferno!")
- for(var/turf/simulated/target_turf in view(2, src))
- target_turf.assume_gas("phoron", 30, 1500+T0C)
- spawn(0)
- target_turf.hotspot_expose(1500+T0C, 400)
- qdel(src)
-
-/mob/living/simple_animal/slime/dark_purple/ex_act(severity)
- log_and_message_admins("[src] ignited due to a chain reaction with an explosion.")
- ignite()
-
-/mob/living/simple_animal/slime/dark_purple/fire_act(datum/gas_mixture/air, temperature, volume)
- log_and_message_admins("[src] ignited due to exposure to fire.")
- ignite()
-
-/mob/living/simple_animal/slime/dark_purple/bullet_act(var/obj/item/projectile/P, var/def_zone)
- if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security.
- log_and_message_admins("[src] ignited due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].")
- ignite()
- else
- ..()
-
-/mob/living/simple_animal/slime/dark_purple/attackby(var/obj/item/weapon/W, var/mob/user)
- if(istype(W) && W.force && W.damtype == BURN)
- log_and_message_admins("[src] ignited due to being hit with a burning weapon ([W]) by [key_name(user)].")
- ignite()
- else
- ..()
-
-
-
-
-/mob/living/simple_animal/slime/dark_blue
- desc = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It tends to kill other slimes rather quickly."
- color = "#2398FF"
- glows = TRUE
- slime_color = "dark blue"
- coretype = /obj/item/slime_extract/dark_blue
-
- description_info = "This slime is immune to the cold, however water will still kill it. A winter coat or other cold-resistant clothing can protect from the chilling aura."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/purple,
- /mob/living/simple_animal/slime/blue,
- /mob/living/simple_animal/slime/cerulean,
- /mob/living/simple_animal/slime/cerulean
- )
-
- minbodytemp = 0
- cold_damage_per_tick = 0
-
-/mob/living/simple_animal/slime/dark_blue/Life()
- if(stat != DEAD)
- cold_aura()
- ..()
-
-/mob/living/simple_animal/slime/dark_blue/proc/cold_aura()
- for(var/mob/living/L in view(2, src))
- var/protection = L.get_cold_protection()
-
- if(protection < 1)
- var/cold_factor = abs(protection - 1)
- var/delta = -20
- delta *= cold_factor
- L.bodytemperature = max(50, L.bodytemperature + delta)
- var/turf/T = get_turf(src)
- var/datum/gas_mixture/env = T.return_air()
- if(env)
- env.add_thermal_energy(-10 * 1000)
-
-/mob/living/simple_animal/slime/dark_blue/get_cold_protection()
- return 1 // This slime is immune to cold.
-
-// Surface variant
-/mob/living/simple_animal/slime/dark_blue/feral
- name = "feral slime"
- desc = "The result of slimes escaping containment from some xenobiology lab. The slime makes other entities near it feel much colder, \
- and it is more resilient to the cold. These qualities have made this color of slime able to thrive on a harsh, cold world and is able to rival \
- the ferocity of other apex predators in this region of Sif. As such, it is a very invasive species."
- description_info = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It also has learned advanced combat tactics from \
- having to endure the harsh world outside its lab. Note that processing this large slime will give six cores."
- icon_scale_x = 2
- icon_scale_y = 2
- optimal_combat = TRUE // Gotta be sharp to survive out there.
- rabid = TRUE
- rainbow_core_candidate = FALSE
- cores = 6
- maxHealth = 150
- maxHealth_adult = 250
- type_on_death = /mob/living/simple_animal/slime/dark_blue // Otherwise infinite slimes might occur.
- pixel_y = -10 // Since the base sprite isn't centered properly, the pixel auto-adjustment needs some help.
-
-/mob/living/simple_animal/slime/dark_blue/feral/New()
- ..()
- make_adult()
-
-/mob/living/simple_animal/slime/silver
- desc = "This slime is shiny, and can deflect lasers or other energy weapons directed at it."
- color = "#AAAAAA"
- slime_color = "silver"
- coretype = /obj/item/slime_extract/silver
- shiny = TRUE
-
- description_info = "Tasers, including the slime version, are ineffective against this slime. The slimebation still works."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/metal,
- /mob/living/simple_animal/slime/blue,
- /mob/living/simple_animal/slime/amber,
- /mob/living/simple_animal/slime/amber
- )
-
-/mob/living/simple_animal/slime/silver/bullet_act(var/obj/item/projectile/P, var/def_zone)
- if(istype(P,/obj/item/projectile/beam) || istype(P, /obj/item/projectile/energy))
- visible_message("\The [src] reflects \the [P]!")
-
- // Find a turf near or on the original location to bounce to
- var/new_x = P.starting.x + pick(0, 0, 0, -1, 1, -2, 2)
- var/new_y = P.starting.y + pick(0, 0, 0, -1, 1, -2, 2)
- var/turf/curloc = get_turf(src)
-
- // redirect the projectile
- P.redirect(new_x, new_y, curloc, src)
- return PROJECTILE_CONTINUE // complete projectile permutation
- else
- ..()
-
-
-// Tier 3
-
-/mob/living/simple_animal/slime/bluespace
- desc = "Trapping this slime in a cell is generally futile, as it can teleport at will."
- color = null
- slime_color = "bluespace"
- icon_state_override = "bluespace"
- coretype = /obj/item/slime_extract/bluespace
-
- description_info = "This slime will teleport to attack something if it is within a range of seven tiles. The teleport has a cooldown of five seconds."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/bluespace,
- /mob/living/simple_animal/slime/bluespace,
- /mob/living/simple_animal/slime/yellow,
- /mob/living/simple_animal/slime/yellow
- )
-
- spattack_prob = 100
- spattack_min_range = 3
- spattack_max_range = 7
- var/last_tele = null // Uses world.time
- var/tele_cooldown = 5 SECONDS
-
-/mob/living/simple_animal/slime/bluespace/ClosestDistance() // Needed or the SA AI won't ever try to teleport.
- if(world.time > last_tele + tele_cooldown)
- return spattack_max_range - 1
- return ..()
-
-/mob/living/simple_animal/slime/bluespace/SpecialAtkTarget()
- // Teleport attack.
- if(!target_mob)
- to_chat(src, "There's nothing to teleport to.")
- return FALSE
-
- if(world.time < last_tele + tele_cooldown)
- to_chat(src, "You can't teleport right now, wait a few seconds.")
- return FALSE
-
- var/list/nearby_things = range(1, target_mob)
- var/list/valid_turfs = list()
-
- // All this work to just go to a non-dense tile.
- for(var/turf/potential_turf in nearby_things)
- var/valid_turf = TRUE
- if(potential_turf.density)
- continue
- for(var/atom/movable/AM in potential_turf)
- if(AM.density)
- valid_turf = FALSE
- if(valid_turf)
- valid_turfs.Add(potential_turf)
-
-
-
- var/turf/T = get_turf(src)
- var/turf/target_turf = pick(valid_turfs)
-
- if(!target_turf)
- to_chat(src, "There wasn't an unoccupied spot to teleport to.")
- return FALSE
-
- var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
- s1.set_up(5, 1, T)
- var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
- s2.set_up(5, 1, target_turf)
-
-
- T.visible_message("\The [src] vanishes!")
- s1.start()
-
- forceMove(target_turf)
- playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1)
- to_chat(src, "You teleport to \the [target_turf].")
-
- target_turf.visible_message("\The [src] appears!")
- s2.start()
-
- last_tele = world.time
-
- if(Adjacent(target_mob))
- PunchTarget()
- return TRUE
-
-/mob/living/simple_animal/slime/ruby
- desc = "This slime has great physical strength."
- color = "#FF3333"
- slime_color = "ruby"
- shiny = TRUE
- glows = TRUE
- coretype = /obj/item/slime_extract/ruby
-
- description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time. \
- Their glomp attacks also send the victim flying."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/dark_purple,
- /mob/living/simple_animal/slime/dark_purple,
- /mob/living/simple_animal/slime/ruby,
- /mob/living/simple_animal/slime/ruby
- )
-
-/mob/living/simple_animal/slime/ruby/New()
- ..()
- add_modifier(/datum/modifier/slime_strength, null, src) // Slime is always swole.
-
-/mob/living/simple_animal/slime/ruby/DoPunch(var/mob/living/L)
- ..() // Do regular attacks.
-
- if(istype(L))
- if(a_intent == I_HURT)
- visible_message("\The [src] sends \the [L] flying with the impact!")
- playsound(src, "punch", 50, 1)
- L.Weaken(1)
- var/throwdir = get_dir(src, L)
- L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src)
-
-
-/mob/living/simple_animal/slime/amber
- desc = "This slime seems to be an expert in the culinary arts, as they create their own food to share with others. \
- They would probably be very important to other slimes, if the other colors didn't try to kill them."
- color = "#FFBB00"
- slime_color = "amber"
- shiny = TRUE
- glows = TRUE
- coretype = /obj/item/slime_extract/amber
-
- description_info = "This slime feeds nearby entities passively while it is alive. This can cause uncontrollable \
- slime growth and reproduction if not kept in check. The amber slime cannot feed itself, but can be fed by other amber slimes."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/silver,
- /mob/living/simple_animal/slime/silver,
- /mob/living/simple_animal/slime/amber,
- /mob/living/simple_animal/slime/amber
- )
-
-/mob/living/simple_animal/slime/amber/Life()
- if(stat != DEAD)
- feed_aura()
- ..()
-
-/mob/living/simple_animal/slime/amber/proc/feed_aura()
- for(var/mob/living/L in view(2, src))
- if(L == src) // Don't feed themselves, or it is impossible to stop infinite slimes without killing all of the ambers.
- continue
- if(isslime(L))
- var/mob/living/simple_animal/slime/S = L
- S.adjust_nutrition(rand(15, 25))
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(H.isSynthetic())
- continue
- H.nutrition = between(0, H.nutrition + rand(15, 25), 600)
-
-
-
-/mob/living/simple_animal/slime/cerulean
- desc = "This slime is generally superior in a wide range of attributes, compared to the common slime. The jack of all trades, but master of none."
- color = "#4F7EAA"
- slime_color = "cerulean"
- coretype = /obj/item/slime_extract/cerulean
-
- // Less than the specialized slimes, but higher than the rest.
- maxHealth = 200
- maxHealth_adult = 250
-
- melee_damage_lower = 10
- melee_damage_upper = 30
-
- move_to_delay = 3
-
-
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/dark_blue,
- /mob/living/simple_animal/slime/dark_blue,
- /mob/living/simple_animal/slime/cerulean,
- /mob/living/simple_animal/slime/cerulean
- )
-
-// Tier 4
-
-/mob/living/simple_animal/slime/red
- desc = "This slime is full of energy, and very aggressive. 'The red ones go faster.' seems to apply here."
- color = "#FF3333"
- slime_color = "red"
- coretype = /obj/item/slime_extract/red
- move_to_delay = 3 // The red ones go faster.
-
- description_info = "This slime is faster than the others. Attempting to discipline this slime will always cause it to go berserk."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/red,
- /mob/living/simple_animal/slime/oil,
- /mob/living/simple_animal/slime/oil,
- /mob/living/simple_animal/slime/orange
- )
-
-
-/mob/living/simple_animal/slime/red/adjust_discipline(amount)
- if(amount > 0)
- if(!rabid)
- enrage() // How dare you try to control the red slime.
- say("Grrr...!")
-
-/mob/living/simple_animal/slime/red/enrage()
- ..()
- add_modifier(/datum/modifier/berserk, 30 SECONDS)
-
-
-/mob/living/simple_animal/slime/green
- desc = "This slime is radioactive."
- color = "#14FF20"
- slime_color = "green"
- coretype = /obj/item/slime_extract/green
- glows = TRUE
- reagent_injected = "radium"
- var/rads = 25
-
- description_info = "This slime will irradiate anything nearby passively, and will inject radium on attack. \
- A radsuit or other thick and radiation-hardened armor can protect from this. It will only radiate while alive."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/purple,
- /mob/living/simple_animal/slime/green,
- /mob/living/simple_animal/slime/emerald,
- /mob/living/simple_animal/slime/emerald
- )
-
-/mob/living/simple_animal/slime/green/Life()
- if(stat != DEAD)
- irradiate()
- ..()
-
-/mob/living/simple_animal/slime/green/proc/irradiate()
- SSradiation.radiate(src, rads)
-
-
-/mob/living/simple_animal/slime/pink
- desc = "This slime has regenerative properties."
- color = "#FF0080"
- slime_color = "pink"
- coretype = /obj/item/slime_extract/pink
- glows = TRUE
-
- description_info = "This slime will passively heal nearby entities within two tiles, including itself. It will only do this while alive."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/blue,
- /mob/living/simple_animal/slime/light_pink,
- /mob/living/simple_animal/slime/light_pink,
- /mob/living/simple_animal/slime/pink
- )
-
-/mob/living/simple_animal/slime/pink/Life()
- if(stat != DEAD)
- heal_aura()
- ..()
-
-/mob/living/simple_animal/slime/pink/proc/heal_aura()
- for(var/mob/living/L in view(src, 2))
- if(L.stat == DEAD || L == target_mob)
- continue
- L.add_modifier(/datum/modifier/slime_heal, 5 SECONDS, src)
-
-/datum/modifier/slime_heal
- name = "slime mending"
- desc = "You feel somewhat gooy."
- mob_overlay_state = "pink_sparkles"
-
- on_created_text = "Twinkling spores of goo surround you. It makes you feel healthier."
- on_expired_text = "The spores of goo have faded, although you feel much healthier than before."
- stacks = MODIFIER_STACK_EXTEND
-
-/datum/modifier/slime_heal/tick()
- if(holder.stat == DEAD) // Required or else simple animals become immortal.
- expire()
-
- if(ishuman(holder)) // Robolimbs need this code sadly.
- var/mob/living/carbon/human/H = holder
- for(var/obj/item/organ/external/E in H.organs)
- var/obj/item/organ/external/O = E
- O.heal_damage(2, 2, 0, 1)
- else
- holder.adjustBruteLoss(-2)
- holder.adjustFireLoss(-2)
-
- holder.adjustToxLoss(-2)
- holder.adjustOxyLoss(-2)
- holder.adjustCloneLoss(-1)
-
-
-
-/mob/living/simple_animal/slime/gold
- desc = "This slime absorbs energy, and cannot be stunned by normal means."
- color = "#EEAA00"
- shiny = TRUE
- slime_color = "gold"
- coretype = /obj/item/slime_extract/gold
- description_info = "This slime is immune to the slimebaton and taser, and will actually charge the slime, however it will still discipline the slime."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/metal,
- /mob/living/simple_animal/slime/gold,
- /mob/living/simple_animal/slime/sapphire,
- /mob/living/simple_animal/slime/sapphire
- )
-
-/mob/living/simple_animal/slime/gold/Weaken(amount)
- power_charge = between(0, power_charge + amount, 10)
- return
-
-/mob/living/simple_animal/slime/gold/Stun(amount)
- power_charge = between(0, power_charge + amount, 10)
- return
-
-/mob/living/simple_animal/slime/gold/get_description_interaction() // So it doesn't say to use a baton on them.
- return list()
-
-
-// Tier 5
-
-/mob/living/simple_animal/slime/oil
- desc = "This slime is explosive and volatile. Smoking near it is probably a bad idea."
- color = "#333333"
- slime_color = "oil"
- shiny = TRUE
- coretype = /obj/item/slime_extract/oil
-
- description_info = "If this slime suffers damage from a fire or heat based source, or if it is caught inside \
- an explosion, it will explode. Rabid oil slimes will charge at enemies, then suicide-bomb themselves. \
- Bomb suits can protect from the explosion."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/oil,
- /mob/living/simple_animal/slime/oil,
- /mob/living/simple_animal/slime/red,
- /mob/living/simple_animal/slime/red
- )
-
-/mob/living/simple_animal/slime/oil/proc/explode()
- if(stat != DEAD)
- // explosion(src.loc, 1, 2, 4)
- explosion(src.loc, 0, 2, 4) // A bit weaker since the suicide charger tended to gib the poor sod being targeted.
- if(src) // Delete ourselves if the explosion didn't do it.
- qdel(src)
-
-/mob/living/simple_animal/slime/oil/post_attack(var/mob/living/L, var/intent = I_HURT)
- if(!rabid)
- return ..()
- if(intent == I_HURT || intent == I_GRAB)
- say(pick("Sacrifice...!", "Sssss...", "Boom...!"))
- sleep(2 SECOND)
- log_and_message_admins("[src] has suicide-bombed themselves while trying to kill \the [L].")
- explode()
-
-/mob/living/simple_animal/slime/oil/ex_act(severity)
- log_and_message_admins("[src] exploded due to a chain reaction with another explosion.")
- explode()
-
-/mob/living/simple_animal/slime/oil/fire_act(datum/gas_mixture/air, temperature, volume)
- log_and_message_admins("[src] exploded due to exposure to fire.")
- explode()
-
-/mob/living/simple_animal/slime/oil/bullet_act(var/obj/item/projectile/P, var/def_zone)
- if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security.
- log_and_message_admins("[src] exploded due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].")
- explode()
- else
- ..()
-
-/mob/living/simple_animal/slime/oil/attackby(var/obj/item/weapon/W, var/mob/user)
- if(istype(W) && W.force && W.damtype == BURN)
- log_and_message_admins("[src] exploded due to being hit with a burning weapon ([W]) by [key_name(user)].")
- explode()
- else
- ..()
-
-
-/mob/living/simple_animal/slime/sapphire
- desc = "This slime seems a bit brighter than the rest, both figuratively and literally."
- color = "#2398FF"
- slime_color = "sapphire"
- shiny = TRUE
- glows = TRUE
- coretype = /obj/item/slime_extract/sapphire
-
- optimal_combat = TRUE // Lift combat AI restrictions to look smarter.
- run_at_them = FALSE // Use fancy A* pathing.
- astar_adjacent_proc = /turf/proc/TurfsWithAccess // Normal slimes don't care about cardinals (because BYOND) so smart slimes shouldn't as well.
- move_to_delay = 3 // A* chasing is slightly slower in terms of movement speed than regular pathing so reducing this hopefully makes up for that.
-
- description_info = "This slime uses more robust tactics when fighting and won't hold back, so it is dangerous to be alone \
- with one if hostile, and especially dangerous if they outnumber you."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/sapphire,
- /mob/living/simple_animal/slime/sapphire,
- /mob/living/simple_animal/slime/gold,
- /mob/living/simple_animal/slime/gold
- )
-
-/mob/living/simple_animal/slime/emerald
- desc = "This slime is faster than usual, even more so than the red slimes."
- color = "#22FF22"
- shiny = TRUE
- glows = TRUE
- slime_color = "emerald"
- coretype = /obj/item/slime_extract/emerald
-
- description_info = "This slime will make everything around it, and itself, faster for a few seconds, if close by."
- move_to_delay = 2
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/green,
- /mob/living/simple_animal/slime/green,
- /mob/living/simple_animal/slime/emerald,
- /mob/living/simple_animal/slime/emerald
- )
-
-/mob/living/simple_animal/slime/emerald/Life()
- if(stat != DEAD)
- zoom_aura()
- ..()
-
-/mob/living/simple_animal/slime/emerald/proc/zoom_aura()
- for(var/mob/living/L in view(src, 2))
- if(L.stat == DEAD || L == target_mob)
- continue
- L.add_modifier(/datum/modifier/technomancer/haste, 5 SECONDS, src)
-
-/mob/living/simple_animal/slime/light_pink
- desc = "This slime seems a lot more peaceful than the others."
- color = "#FF8888"
- slime_color = "light pink"
- coretype = /obj/item/slime_extract/light_pink
-
- description_info = "This slime is effectively always disciplined initially."
- obedience = 5
- discipline = 5
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/pink,
- /mob/living/simple_animal/slime/pink,
- /mob/living/simple_animal/slime/light_pink,
- /mob/living/simple_animal/slime/light_pink
- )
-
-// Special
-/mob/living/simple_animal/slime/rainbow
- desc = "This slime changes colors constantly."
- color = null // Only slime subtype that uses a different icon_state.
- slime_color = "rainbow"
- coretype = /obj/item/slime_extract/rainbow
- icon_state_override = "rainbow"
- unity = TRUE
-
- description_info = "This slime is considered to be the same color as all other slime colors at the same time for the purposes of \
- other slimes being friendly to them, and therefore will never be harmed by another slime. \
- Attacking this slime will provoke the wrath of all slimes within range."
-
- slime_mutation = list(
- /mob/living/simple_animal/slime/rainbow,
- /mob/living/simple_animal/slime/rainbow,
- /mob/living/simple_animal/slime/rainbow,
- /mob/living/simple_animal/slime/rainbow
- )
-
-/mob/living/simple_animal/slime/rainbow/New()
- unify()
- ..()
-
-// The RD's pet slime.
-/mob/living/simple_animal/slime/rainbow/kendrick
- name = "Kendrick"
- desc = "The Research Director's pet slime. It shifts colors constantly."
- rainbow_core_candidate = FALSE
-
-/mob/living/simple_animal/slime/rainbow/kendrick/New()
- pacify()
- ..()
\ No newline at end of file
diff --git a/polaris.dme b/polaris.dme
index e2ea7c5fb4..b1b773a612 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -1857,6 +1857,7 @@
#include "code\modules\mob\_modifiers\traits.dm"
#include "code\modules\mob\_modifiers\traits_phobias.dm"
#include "code\modules\mob\_modifiers\unholy.dm"
+#include "code\modules\mob\dead\corpse.dm"
#include "code\modules\mob\dead\death.dm"
#include "code\modules\mob\dead\observer\login.dm"
#include "code\modules\mob\dead\observer\logout.dm"
@@ -2053,7 +2054,6 @@
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm"
-#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_mob\appearance.dm"
#include "code\modules\mob\living\simple_mob\combat.dm"
#include "code\modules\mob\living\simple_mob\defense.dm"