diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index c9e410d9e9b..be101742dfa 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -428,6 +428,19 @@
flags = RESTRICTED | HIVEMIND
follow = 1
+
+/datum/language/terrorspider
+ name = "Spider Hivemind"
+ desc = "Terror spiders have a limited ability to commune over a psychic hivemind, similar to xenomorphs."
+ speech_verb = "chitters"
+ ask_verb = "chitters"
+ exclaim_verb = "chitters"
+ colour = "terrorspider"
+ key = "ts"
+ flags = RESTRICTED | HIVEMIND
+ follow = 1
+
+
/datum/language/ling
name = "Changeling"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
@@ -559,7 +572,7 @@
flags = RESTRICTED | HIVEMIND
drone_only = 1
follow = 1
-
+
/datum/language/drone
name = "Drone"
desc = "An encrypted stream of data converted to speech patterns."
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
new file mode 100644
index 00000000000..fafd30a4ae4
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
@@ -0,0 +1,11 @@
+
+#define SPINNING_WEB 1
+#define LAYING_EGGS 2
+#define MOVING_TO_TARGET 3
+#define SPINNING_COCOON 4
+
+#define TS_TIER_1 1
+#define TS_TIER_2 2
+#define TS_TIER_3 3
+#define TS_TIER_4 4
+#define TS_TIER_5 5
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
new file mode 100644
index 00000000000..963bfd472fd
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
@@ -0,0 +1,123 @@
+
+
+/datum/action/innate/terrorspider/web
+ name = "Web"
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "stickyweb1"
+
+/datum/action/innate/terrorspider/web/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
+ user.Web()
+
+/datum/action/innate/terrorspider/wrap
+ name = "Wrap"
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "cocoon_large1"
+
+/datum/action/innate/terrorspider/wrap/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
+ user.FindWrapTarget()
+ user.DoWrap()
+
+
+// ---------- WEB
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web()
+ visible_message("[src] begins to secrete a sticky substance.")
+ if(do_after(src, 40, target = loc))
+ new /obj/effect/spider/terrorweb(loc)
+
+/obj/effect/spider/terrorweb
+ name = "terror web"
+ desc = "it's stringy and sticky"
+ icon = 'icons/effects/effects.dmi'
+ anchored = 1 // prevents people dragging it
+ density = 0 // prevents it blocking all movement
+ health = 20 // two welders, or one laser shot (15 for the normal spider webs)
+ icon_state = "stickyweb1"
+
+
+/obj/effect/spider/terrorweb/New()
+ ..()
+ if(prob(50))
+ icon_state = "stickyweb2"
+
+
+/obj/effect/spider/terrorweb/CanPass(atom/movable/mover, turf/target)
+ if(istype(mover, /mob/living/simple_animal/hostile/poison/terror_spider))
+ return 1
+ if(isliving(mover))
+ if(prob(80))
+ to_chat(mover, "You get stuck in [src] for a moment.")
+ var/mob/living/M = mover
+ M.Stun(4) // 8 seconds.
+ M.Weaken(4) // 8 seconds.
+ return 1
+ else
+ return 0
+ if(istype(mover, /obj/item/projectile))
+ return prob(20)
+ return ..()
+
+
+
+
+// ---------- WRAP
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/FindWrapTarget()
+ if(!cocoon_target)
+ var/list/choices = list()
+ for(var/mob/living/L in oview(1,src))
+ if(Adjacent(L))
+ if(L.stat == DEAD)
+ choices += L
+ for(var/obj/O in oview(1,src))
+ if(Adjacent(O) && !O.anchored)
+ if(!istype(O, /obj/effect/spider/terrorweb) && !istype(O, /obj/effect/spider/cocoon))
+ choices += O
+ if(choices.len)
+ cocoon_target = input(src,"What do you wish to cocoon?") in null|choices
+ else
+ to_chat(src, "There is nothing nearby you can wrap.")
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoWrap()
+ if(cocoon_target && busy != SPINNING_COCOON)
+ busy = SPINNING_COCOON
+ visible_message("[src] begins to secrete a sticky substance around [cocoon_target].")
+ stop_automated_movement = 1
+ walk(src,0)
+ if(do_after(src, 40, target = cocoon_target.loc))
+ if(busy == SPINNING_COCOON)
+ if(cocoon_target && isturf(cocoon_target.loc) && 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/obj/O in C.loc)
+ if(istype(O, /obj/item))
+ O.loc = C
+ else if(istype(O, /obj/machinery) || istype(O, /obj/structure))
+ O.loc = C
+ large_cocoon = 1
+ for(var/mob/living/L in C.loc)
+ if(istype(L, /mob/living/simple_animal/hostile/poison/terror_spider))
+ continue
+ if(L.stat != DEAD)
+ continue
+ if(iscarbon(L))
+ regen_points += regen_points_per_kill
+ fed++
+ large_cocoon = 1
+ last_cocoon_object = 0
+ L.loc = C
+ C.pixel_x = L.pixel_x
+ C.pixel_y = L.pixel_y
+ visible_message("[src] sticks a proboscis into [L] and sucks a viscous substance out.")
+ break
+ if(large_cocoon)
+ C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
+ cocoon_target = null
+ busy = 0
+ stop_automated_movement = 0
+
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
new file mode 100644
index 00000000000..68d25a29492
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
@@ -0,0 +1,38 @@
+
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T2 BLACK TERROR ------------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: assassin, poisoner, DoT expert
+// -------------: AI: attacks to inject its venom, then retreats. Will inject its enemies multiple times then hang back to ensure they die.
+// -------------: SPECIAL: venom that does more damage the more of it is in you
+// -------------: TO FIGHT IT: if bitten once, retreat, get charcoal/etc treatment, and come back with a gun.
+// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
+
+/mob/living/simple_animal/hostile/poison/terror_spider/black
+ name = "Black Terror spider"
+ desc = "An ominous-looking spider, black as the darkest night, and with merciless eyes and a blood-red hourglass pattern on its back."
+ spider_role_summary = "Hit-and-run attacker with extremely venomous bite."
+
+ icon_state = "terror_widow"
+ icon_living = "terror_widow"
+ icon_dead = "terror_widow_dead"
+ maxHealth = 120 // same health as hunter spider, aka, pretty weak.. but its bite will kill you!
+ health = 120
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ move_to_delay = 5
+ stat_attack = 1 // ensures they will target people in crit, too!
+ spider_tier = TS_TIER_2
+
+/mob/living/simple_animal/hostile/poison/terror_spider/black/spider_specialattack(mob/living/carbon/human/L, poisonable)
+ if(!poisonable)
+ return ..()
+ if(L.reagents.has_reagent("terror_black_toxin", 50))
+ return ..()
+ var/inject_target = pick("chest", "head")
+ if(L.stunned || L.can_inject(null, 0, inject_target, 0))
+ L.reagents.add_reagent("terror_black_toxin", 15) // inject our special poison
+ visible_message("[src] buries its long fangs deep into the [inject_target] of [target]!")
+ else
+ visible_message("[src] bites [target], but cannot inject venom into their [inject_target]!")
+ L.attack_animal(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm
new file mode 100644
index 00000000000..8ad926a8729
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm
@@ -0,0 +1,33 @@
+// Terror Spider, Black, Deadly Venom
+
+/datum/reagent/terror_black_toxin
+ name = "Black Widow venom"
+ id = "terror_black_toxin"
+ description = "An incredibly toxic venom injected by the Black Widow spider."
+ color = "#CF3600"
+ metabolization_rate = 0.1
+
+/datum/reagent/terror_black_toxin/on_mob_life(mob/living/M)
+ if(volume < 15)
+ // bitten once, die slowly. Easy to survive a single bite - just go to medbay.
+ // total damage: 2/tick, human health 150 until crit, = 75 ticks, = 150 seconds = 2.5 minutes to get to medbay.
+ M.adjustToxLoss(2) // same damage/tick as tabun cycle 0 to 60
+ else if(volume < 30)
+ // bitten twice, die more quickly, muscle cramps make movement difficult. Call medics immediately.
+ // total damage: 4, human health 150 until crit, = 37.5 ticks, = 75s = 1m15s until death
+ M.adjustToxLoss(4)
+ M.Confused(3)
+ M.EyeBlurry(3)
+ else if(volume < 45)
+ // bitten thrice, die very quickly, severe muscle cramps make movement very difficult. Even calling for help probably won't save you.
+ // total damage: 8, human health 150 until crit, = 18.75 ticks, = 37s until death
+ M.adjustToxLoss(8) // a bit worse than coiine
+ M.Confused(6)
+ M.EyeBlurry(6)
+ else
+ // bitten 4 or more times, whole body goes into shock/death
+ // total damage: 12, human health 150 until crit, = 12.5 ticks, = 25s until death
+ M.adjustToxLoss(12)
+ M.EyeBlurry(6)
+ M.Paralyse(5)
+ ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm
new file mode 100644
index 00000000000..06703cc2106
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm
@@ -0,0 +1,43 @@
+
+/mob/living/simple_animal/hostile/poison/terror_spider/Topic(href, href_list)
+ if(href_list["activate"])
+ var/mob/dead/observer/ghost = usr
+ if(istype(ghost))
+ humanize_spider(ghost)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/attack_ghost(mob/user)
+ humanize_spider(user)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/humanize_spider(mob/user)
+ if(key)//Someone is in it
+ return
+ var/error_on_humanize = ""
+ var/humanize_prompt = "Take direct control of [src]?"
+ humanize_prompt += "Role: [spider_role_summary]"
+ if(user.ckey in ts_ckey_blacklist)
+ error_on_humanize = "You are not able to control any terror spider this round."
+ else if(!ai_playercontrol_allowingeneral)
+ error_on_humanize = "Terror spiders cannot currently be player-controlled."
+ else if(spider_awaymission)
+ error_on_humanize = "Terror spiders that are part of an away mission cannot be controlled by ghosts."
+ else if(!ai_playercontrol_allowtype)
+ error_on_humanize = "This specific type of terror spider is not player-controllable."
+ else if(stat == DEAD)
+ error_on_humanize = "Dead spiders are not player-controllable."
+ if(jobban_isbanned(user, "Syndicate") || jobban_isbanned(user, "alien"))
+ to_chat(user,"You are jobbanned from role of syndicate and/or alien lifeform.")
+ return
+ if(error_on_humanize == "")
+ var/spider_ask = alert(humanize_prompt, "Join as Terror Spider?", "Yes", "No")
+ if(spider_ask == "No" || !src || qdeleted(src))
+ return
+ else
+ to_chat(user, "Cannot inhabit spider: [error_on_humanize]")
+ return
+ if(key)
+ to_chat(user, "Someone else already took this spider.")
+ return
+ key = user.key
+ for(var/mob/dead/observer/G in player_list)
+ G.show_message("A ghost has taken control of [src]. ([ghost_follow_link(src, ghost=G)]).")
+
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
new file mode 100644
index 00000000000..42c16cc7666
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
@@ -0,0 +1,40 @@
+
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T1 GRAY TERROR -------------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: fast, weak terror spider
+// -------------: SPECIAL: silences targets
+// -------------: TO FIGHT IT: shoot it!
+// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray
+ name = "Gray Terror spider"
+ desc = "An ominous-looking gray spider, it seems jittery."
+ spider_role_summary = "Fast-moving but weak spider."
+ icon_state = "terror_gray"
+ icon_living = "terror_gray"
+ icon_dead = "terror_gray_dead"
+ maxHealth = 120 // same health as hunter spider, aka, pretty weak.. but silences its targets
+ health = 120
+ melee_damage_lower = 10
+ melee_damage_upper = 20
+ ventcrawler = 1
+ move_to_delay = 5 // normal speed
+ stat_attack = 1 // ensures they will target people in crit, too!
+ environment_smash = 1
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
+ if(!poisonable)
+ ..()
+ return
+ if(L.silent >= 10)
+ L.attack_animal(src)
+ else
+ var/inject_target = pick("chest","head")
+ if(L.stunned || L.can_inject(null,0,inject_target,0))
+ L.Silence(20) // instead of having a venom that only lasts seconds, we just add the silence directly.
+ visible_message("[src] buries grey fangs deep into the [inject_target] of [target]!")
+ else
+ visible_message("[src] bites [target], but cannot inject venom into their [inject_target]!")
+ L.attack_animal(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
new file mode 100644
index 00000000000..669449a6ae3
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
@@ -0,0 +1,35 @@
+
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T3 PRINCE OF TERROR --------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: boss
+// -------------: AI: no special ai
+// -------------: SPECIAL: massive health
+// -------------: TO FIGHT IT: a squad of at least 4 people with laser rifles.
+// -------------: SPRITES FROM: Travelling Merchant, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=2766
+
+/mob/living/simple_animal/hostile/poison/terror_spider/prince
+ name = "Prince of Terror spider"
+ desc = "An enormous, terrifying spider. It looks like it is judging everything it sees. Its hide seems armored, and it bears the scars of many battles."
+ spider_role_summary = "Boss-level terror spider. Lightning bruiser. Capable of taking on a squad by itself."
+ icon_state = "terror_allblack"
+ icon_living = "terror_allblack"
+ icon_dead = "terror_allblack_dead"
+ maxHealth = 400 // 20 laser shots.
+ health = 400
+ melee_damage_lower = 15
+ melee_damage_upper = 25
+ move_to_delay = 5
+ ventcrawler = 1
+ loot = list(/obj/item/clothing/accessory/medal)
+ spider_tier = TS_TIER_3
+ spider_opens_doors = 2
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/prince/spider_specialattack(mob/living/carbon/human/L)
+ if(prob(15))
+ visible_message("[src] rams into [L], knocking them to the floor!")
+ L.Weaken(5)
+ L.Stun(5)
+ else
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
new file mode 100644
index 00000000000..33480f9509c
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
@@ -0,0 +1,60 @@
+
+
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T1 RED TERROR --------------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: generic attack spider
+// -------------: AI: uses very powerful fangs to wreck people in melee
+// -------------: SPECIAL: the more you hurt it, the harder it bites you
+// -------------: TO FIGHT IT: shoot it from range. Kite it.
+// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
+
+/mob/living/simple_animal/hostile/poison/terror_spider/red
+ name = "Red Terror spider"
+ desc = "An ominous-looking red spider, it has eight beady red eyes, and nasty, big, pointy fangs! It looks like it has a vicious streak a mile wide."
+
+ spider_role_summary = "High health, high damage, very slow, melee juggernaut"
+
+ icon_state = "terror_red"
+ icon_living = "terror_red"
+ icon_dead = "terror_red_dead"
+ maxHealth = 200
+ health = 200
+ melee_damage_lower = 15
+ melee_damage_upper = 20
+ move_to_delay = 20
+ spider_opens_doors = 2
+ var/enrage = 0
+ var/melee_damage_lower_rage0 = 15
+ var/melee_damage_upper_rage0 = 20
+ var/melee_damage_lower_rage1 = 15
+ var/melee_damage_upper_rage1 = 35
+ var/melee_damage_lower_rage2 = 35
+ var/melee_damage_upper_rage2 = 40
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/red/AttackingTarget()
+ if(enrage == 0)
+ if(health < maxHealth)
+ enrage = 1
+ visible_message("[src] growls, flexing its fangs!")
+ melee_damage_lower = melee_damage_lower_rage1
+ melee_damage_upper = melee_damage_upper_rage1
+ else if(enrage == 1)
+ if(health == maxHealth)
+ enrage = 0
+ visible_message("[src] retracts its fangs a little.")
+ melee_damage_lower = melee_damage_lower_rage0
+ melee_damage_upper = melee_damage_upper_rage0
+ else if(health < (maxHealth/2))
+ enrage = 2
+ visible_message("[src] growls, spreading its fangs wide!")
+ melee_damage_lower = melee_damage_lower_rage2
+ melee_damage_upper = melee_damage_upper_rage2
+ else if(enrage == 2)
+ if(health > (maxHealth/2))
+ enrage = 1
+ visible_message("[src] retracts its fangs a little.")
+ melee_damage_lower = melee_damage_lower_rage0
+ melee_damage_upper = melee_damage_upper_rage0
+ ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
new file mode 100644
index 00000000000..67683d39b39
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -0,0 +1,329 @@
+
+var/global/list/ts_ckey_blacklist = list()
+var/global/ts_count_dead = 0
+var/global/ts_count_alive_awaymission = 0
+var/global/ts_count_alive_station = 0
+var/global/ts_death_last = 0
+var/global/ts_death_window = 9000 // 15 minutes
+var/global/list/ts_spiderlist = list()
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: DEFAULTS ---------------------------------
+// --------------------------------------------------------------------------------
+// Because: http://tvtropes.org/pmwiki/pmwiki.php/Main/SpidersAreScary
+
+/mob/living/simple_animal/hostile/poison/terror_spider
+ // Name / Description
+ name = "terror spider"
+ desc = "The generic parent of all other terror spider types. If you see this in-game, it is a bug."
+
+ // Icons
+ icon = 'icons/mob/terrorspider.dmi'
+ icon_state = "terror_red"
+ icon_living = "terror_red"
+ icon_dead = "terror_red_dead"
+
+ // Health
+ maxHealth = 120
+ health = 120
+
+ // Melee attacks
+ melee_damage_lower = 15
+ melee_damage_upper = 20
+ attacktext = "bites"
+ attack_sound = 'sound/weapons/bite.ogg'
+ poison_type = "" // we do not use that silly system.
+
+ // Movement
+ move_to_delay = 6
+ turns_per_move = 5
+ pass_flags = PASSTABLE
+
+ // Ventcrawling
+ ventcrawler = 1 // allows player ventcrawling
+
+ // Speech
+ speak_chance = 0 // quiet but deadly
+ speak_emote = list("hisses")
+ emote_hear = list("hisses")
+
+ // Languages are handled in terror_spider/New()
+
+ // Interaction keywords
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+
+ // regeneration settings - overridable by child classes
+ var/regen_points = 0 // number of regen points they have by default
+ var/regen_points_max = 100 // max number of points they can accumulate
+ var/regen_points_per_tick = 1 // gain one regen point per tick
+ var/regen_points_per_kill = 90 // gain extra regen points if you kill something
+ var/regen_points_per_hp = 3 // every X regen points = 1 health point you can regen
+ // desired: 20hp/minute unmolested, 40hp/min on food boost, assuming one tick every 2 seconds
+ // 90/kill means bonus 30hp/kill regenerated over the next 1-2 minutes
+
+ // Vision
+ idle_vision_range = 10
+ aggro_vision_range = 10
+ see_in_dark = 10
+ nightvision = 1
+ vision_type = new /datum/vision_override/nightvision/thermals/ling_augmented_eyesight
+ see_invisible = 5
+
+ // player control by ghosts
+ var/ai_playercontrol_allowingeneral = 1 // if 0, no spiders are player controllable. Default set in code, can be changed by queens.
+ var/ai_playercontrol_allowtype = 1 // if 0, this specific class of spider is not player-controllable. Default set in code for each class, cannot be changed.
+
+ var/spider_opens_doors = 1 // all spiders can open firedoors (they have no security). 1 = can open depowered doors. 2 = can open powered doors
+ faction = list("terrorspiders")
+ var/spider_awaymission = 0 // if 1, limits certain behavior in away missions
+ var/spider_role_summary = "UNDEFINED"
+ var/spider_placed = 0
+
+ // AI variables designed for use in procs
+ var/atom/cocoon_target // for queen and nurse
+ var/obj/machinery/atmospherics/unary/vent_pump/entry_vent // nearby vent they are going to try to get to, and enter
+ var/obj/machinery/atmospherics/unary/vent_pump/exit_vent // remote vent they intend to come out of
+ var/obj/machinery/atmospherics/unary/vent_pump/nest_vent // home vent, usually used by queens
+ var/fed = 0
+ var/travelling_in_vent = 0
+ var/busy = 0 // leave this alone!
+ var/spider_tier = TS_TIER_1 // 1 for red,gray,green. 2 for purple,black,white, 3 for prince, mother. 4 for queen, 5 for empress.
+ var/hasdied = 0
+ var/attackstep = 0
+ var/attackcycles = 0
+ var/mylocation = null
+ var/chasecycles = 0
+ var/last_cocoon_object = 0 // leave this, changed by procs.
+ var/killcount = 0
+
+ // Breathing, Pressure & Fire
+ // - No breathing / cannot be suffocated (spiders can hold their breath, look it up)
+ // - No pressure damage either - they have effectively exoskeletons
+ // - HOWEVER they can be burned to death!
+ // - Normal SPACE spiders should probably be immune to SPACE too, but meh, we try to leave the base spiders alone.
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = 1500
+ heat_damage_per_tick = 5 //amount of damage applied if animal's body temperature is higher than maxbodytemp
+
+ // DEBUG OPTIONS & COMMANDS
+ var/spider_debug = 0
+
+ var/datum/action/innate/terrorspider/web/web_action
+ var/datum/action/innate/terrorspider/wrap/wrap_action
+
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: SHARED ATTACK CODE -----------------------
+// --------------------------------------------------------------------------------
+
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/AttackingTarget()
+ if(istype(target, /mob/living/simple_animal/hostile/poison/terror_spider))
+ var/mob/living/simple_animal/hostile/poison/terror_spider/T = target
+ if(T.spider_tier > spider_tier)
+ visible_message("[src] bows in respect for the terrifying presence of [target].")
+ else if(T.spider_tier == spider_tier)
+ visible_message("[src] nuzzles [target].")
+ else if(T.spider_tier < spider_tier && spider_tier >= 4)
+ visible_message("[src] gives [target] a stern look.")
+ else
+ visible_message("[src] harmlessly nuzzles [target].")
+ T.CheckFaction()
+ CheckFaction()
+ else if(istype(target, /obj/effect/spider/cocoon))
+ to_chat(src, "Destroying our own cocoons would not help us.")
+ else if(istype(target, /obj/machinery/door/firedoor))
+ var/obj/machinery/door/firedoor/F = target
+ if(F.density)
+ if(F.blocked)
+ to_chat(src, "The fire door is welded shut.")
+ else
+ visible_message("\The [src] pries open the firedoor!")
+ F.open()
+ else
+ to_chat(src, "Closing fire doors does not help.")
+ else if(istype(target, /obj/machinery/door/airlock))
+ var/obj/machinery/door/airlock/A = target
+ if(A.density)
+ try_open_airlock(A)
+ else if(isliving(target))
+ var/mob/living/G = target
+ if(issilicon(G))
+ G.attack_animal(src)
+ return
+ else if(G.reagents && (iscarbon(G)))
+ var/can_poison = 1
+ if(ishuman(G))
+ var/mob/living/carbon/human/H = G
+ if(!(H.species.reagent_tag & PROCESS_ORG) || (H.species.flags & NO_POISON))
+ can_poison = 0
+ spider_specialattack(G,can_poison)
+ else
+ G.attack_animal(src)
+ else
+ target.attack_animal(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_specialattack(mob/living/carbon/human/L, var/poisonable)
+ L.attack_animal(src)
+
+
+
+
+
+
+// --------------------------------------------------------------------------------
+// --------------------- TERROR SPIDERS: PROC OVERRIDES ---------------------------
+// --------------------------------------------------------------------------------
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/examine(mob/user)
+ ..()
+ var/list/msgs = list()
+ if(stat == DEAD)
+ msgs += "It appears to be dead.\n"
+ else
+ if(key)
+ msgs += "Its eyes regard you with a curious intelligence."
+ if(health > (maxHealth*0.95))
+ msgs += "It is in excellent health."
+ else if(health > (maxHealth*0.75))
+ msgs += "It has a few injuries."
+ else if(health > (maxHealth*0.55))
+ msgs += "It has many injuries."
+ else if(health > (maxHealth*0.25))
+ msgs += "It is barely clinging on to life!"
+ else if(health < maxHealth && regen_points > regen_points_per_kill)
+ msgs += "It appears to be regenerating quickly."
+ if(killcount >= 1)
+ msgs += "It has blood dribbling from its mouth."
+ to_chat(usr,msgs.Join("
"))
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/New()
+ ..()
+ ts_spiderlist += src
+ add_language("Spider Hivemind")
+ add_language("Galactic Common")
+ default_language = all_languages["Spider Hivemind"]
+
+ web_action = new()
+ web_action.Grant(src)
+ wrap_action = new()
+ wrap_action.Grant(src)
+
+ name += " ([rand(1, 1000)])"
+ msg_terrorspiders("[src] has grown in [get_area(src)].")
+ if(is_away_level(z))
+ spider_awaymission = 1
+ ts_count_alive_awaymission++
+ else
+ ts_count_alive_station++
+ // after 30 seconds, assuming nobody took control of it yet, offer it to ghosts.
+ addtimer(src, "CheckFaction", 150)
+ addtimer(src, "announcetoghosts", 300)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/announcetoghosts()
+ if(spider_awaymission)
+ return
+ if(stat == DEAD)
+ return
+ if(ckey)
+ var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state)
+ notify_ghosts("[src] has appeared in [get_area(src)]. (already player-controlled)", source = src, alert_overlay = alert_overlay)
+ else if(ai_playercontrol_allowingeneral && ai_playercontrol_allowtype)
+ var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state)
+ notify_ghosts("[src] has appeared in [get_area(src)].", enter_link = "(Click to control)", source = src, alert_overlay = alert_overlay, attack_not_jump = 1)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/Destroy()
+ ts_spiderlist -= src
+ handle_dying()
+ return ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/Life()
+ ..()
+ if(stat == DEAD)
+ if(prob(2))
+ // 2% chance every cycle to decompose
+ visible_message("\The dead body of the [src] decomposes!")
+ gib()
+ else
+ if(regen_points < regen_points_max)
+ regen_points += regen_points_per_tick
+ if((bruteloss > 0) || (fireloss > 0))
+ if(regen_points > regen_points_per_hp)
+ if(bruteloss > 0)
+ adjustBruteLoss(-1)
+ regen_points -= regen_points_per_hp
+ else if(fireloss > 0)
+ adjustFireLoss(-1)
+ regen_points -= regen_points_per_hp
+ if(prob(5))
+ CheckFaction()
+
+
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/handle_dying()
+ if(!hasdied)
+ hasdied = 1
+ ts_count_dead++
+ ts_death_last = world.time
+ if(spider_awaymission)
+ ts_count_alive_awaymission--
+ else
+ ts_count_alive_station--
+
+/mob/living/simple_animal/hostile/poison/terror_spider/death(gibbed)
+ if(!gibbed)
+ msg_terrorspiders("[src] has died in [get_area(src)].")
+ handle_dying()
+ ..()
+
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_special_action()
+ return
+
+/mob/living/simple_animal/hostile/poison/terror_spider/Bump(atom/A)
+ if(istype(A, /obj/machinery/door/airlock))
+ var/obj/machinery/door/airlock/L = A
+ if(L.density)
+ try_open_airlock(L)
+ if(istype(A, /obj/machinery/door/firedoor))
+ var/obj/machinery/door/firedoor/F = A
+ if(F.density && !F.blocked)
+ F.open()
+ ..()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/msg_terrorspiders(msgtext)
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
+ if(T.stat != DEAD)
+ to_chat(T, "TerrorSense: [msgtext]")
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/CheckFaction()
+ if(faction.len != 1 || (!("terrorspiders" in faction)) || master_commander != null)
+ visible_message("[src] writhes in pain!")
+ log_runtime(EXCEPTION("Terror spider created with incorrect faction list at: [atom_loc_line(src)]"))
+ death()
+
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/try_open_airlock(obj/machinery/door/airlock/D)
+ if(D.operating)
+ return
+ if(!D.density)
+ to_chat(src, "Closing doors does not help us.")
+ else if(D.welded)
+ to_chat(src, "The door is welded shut.")
+ else if(D.locked)
+ to_chat(src, "The door is bolted shut.")
+ else if(D.allowed(src))
+ D.open(1)
+ else if(D.arePowerSystemsOn() && (spider_opens_doors != 2))
+ to_chat(src, "The door's motors resist your efforts to force it.")
+ else if(!spider_opens_doors)
+ to_chat(src, "Your type of spider is not strong enough to force open doors.")
+ else
+ visible_message("[src] pries open the door!")
+ playsound(src.loc, "sparks", 100, 1)
+ D.open(1)
\ No newline at end of file
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index dad1ab1a340..3a4ff4c3770 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -291,6 +291,8 @@ h1.alert, h2.alert {color: #000000;}
.alien {color: #543354;}
.noticealien {color: #00c000;}
.alertalien {color: #00c000; font-weight: bold;}
+.terrorspider {color: #320E32;}
+
.sinister {color: #800080; font-weight: bold; font-style: italic;} /* /vg/ */
.blob {color: #006221; font-weight: bold; font-style: italic;}
diff --git a/icons/mob/terrorspider.dmi b/icons/mob/terrorspider.dmi
new file mode 100644
index 00000000000..a5d678f3f38
Binary files /dev/null and b/icons/mob/terrorspider.dmi differ
diff --git a/paradise.dme b/paradise.dme
index e18f8500930..1f9b3430ba4 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1679,6 +1679,15 @@
#include "code\modules\mob\living\simple_animal\hostile\retaliate\pet.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\undead.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\__defines.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\actions.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\black.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\chem.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\ghost.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\gray.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\prince.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\red.dm"
+#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\terror_spiders.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
#include "code\modules\mob\new_player\new_player.dm"