diff --git a/_maps/map_files/RandomZLevels/terrorspiders.dmm b/_maps/map_files/RandomZLevels/terrorspiders.dmm
index cdf7377b0bf..903698004dc 100644
--- a/_maps/map_files/RandomZLevels/terrorspiders.dmm
+++ b/_maps/map_files/RandomZLevels/terrorspiders.dmm
@@ -2470,9 +2470,6 @@
icon_state = "cafeteria"
},
/area/awaymission/UO71/centralhall)
-"ga" = (
-/turf/simulated/wall/r_wall,
-/area/awaymission/UO71/mother)
"gb" = (
/obj/structure/cable{
d1 = 1;
@@ -2583,17 +2580,6 @@
icon_state = "vault"
},
/area/awaymission/UO71/gateway)
-"gp" = (
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
-"gq" = (
-/obj/machinery/camera{
- c_tag = "Research Lab";
- dir = 2;
- network = list("UO71")
- },
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
"gr" = (
/obj/machinery/gateway{
dir = 1
@@ -2879,10 +2865,6 @@
icon_state = "dark"
},
/area/awaymission/UO71/gateway)
-"gU" = (
-/mob/living/simple_animal/hostile/poison/terror_spider/mother,
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
"gV" = (
/obj/structure/chair{
icon_state = "chair";
@@ -3234,12 +3216,6 @@
},
/turf/simulated/floor/plasteel,
/area/awaymission/UO71/science)
-"hG" = (
-/obj/machinery/atmospherics/unary/vent_pump{
- on = 1
- },
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
"hH" = (
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
dir = 4
@@ -3356,22 +3332,6 @@
icon_state = "dark"
},
/area/awaymission/UO71/gateway)
-"hU" = (
-/obj/machinery/firealarm{
- dir = 8;
- pixel_x = -24
- },
-/obj/machinery/atmospherics/unary/vent_scrubber,
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
-"hV" = (
-/obj/machinery/light/small,
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
-"hW" = (
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
"hX" = (
/obj/structure/window/reinforced,
/obj/effect/decal/cleanable/dirt,
@@ -3650,19 +3610,6 @@
},
/turf/simulated/mineral/random/labormineral,
/area/awaymission/UO71/outside)
-"iC" = (
-/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
- dir = 4;
- level = 1
- },
-/turf/simulated/wall/r_wall,
-/area/awaymission/UO71/mother)
-"iD" = (
-/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
- dir = 9
- },
-/turf/simulated/wall/r_wall,
-/area/awaymission/UO71/mother)
"iE" = (
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,
/obj/structure/chair{
@@ -3705,12 +3652,6 @@
icon_state = "white"
},
/area/awaymission/UO71/gateway)
-"iO" = (
-/obj/structure/window/reinforced{
- dir = 1
- },
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"iP" = (
/obj/structure/table,
/obj/machinery/cell_charger,
@@ -3882,10 +3823,6 @@
icon_state = "neutral"
},
/area/awaymission/UO71/centralhall)
-"jg" = (
-/obj/structure/sign/biohazard,
-/turf/simulated/wall/r_wall,
-/area/awaymission/UO71/mother)
"jh" = (
/obj/structure/chair/comfy/black{
dir = 4
@@ -3921,9 +3858,6 @@
icon_state = "white"
},
/area/awaymission/UO71/gateway)
-"jn" = (
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"jo" = (
/obj/structure/table,
/obj/item/folder/white,
@@ -4098,13 +4032,6 @@
icon_state = "white"
},
/area/awaymission/UO71/gateway)
-"jK" = (
-/obj/machinery/door/poddoor{
- id_tag = "UO71_Containment";
- name = "Containment 1"
- },
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"jM" = (
/obj/structure/grille,
/obj/structure/window/full/basic,
@@ -4363,20 +4290,6 @@
},
/turf/simulated/wall,
/area/awaymission/UO71/science)
-"kf" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/plasteel{
- icon_state = "whitepurple";
- dir = 9
- },
-/area/awaymission/UO71/science)
-"kg" = (
-/turf/simulated/floor/plasteel{
- icon_state = "whitepurple";
- dir = 5
- },
-/area/awaymission/UO71/science)
"ki" = (
/obj/structure/dispenser/oxygen,
/turf/simulated/floor/plating,
@@ -4685,17 +4598,6 @@
heat_capacity = 1e+006
},
/area/awaymission/UO71/science)
-"kP" = (
-/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/plasteel{
- icon_state = "whitepurplecorner";
- dir = 4;
- heat_capacity = 1e+006
- },
-/area/awaymission/UO71/science)
"kQ" = (
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
@@ -5623,17 +5525,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/simulated/floor/plasteel,
/area/awaymission/UO71/centralhall)
-"mx" = (
-/obj/machinery/alarm/monitor{
- dir = 8;
- frequency = 1439;
- locked = 0;
- pixel_x = 23;
- pixel_y = 0;
- req_access = null
- },
-/turf/simulated/floor/vault,
-/area/awaymission/UO71/mother)
"mz" = (
/obj/machinery/light/small{
dir = 1
@@ -12744,14 +12635,6 @@
icon_state = "green"
},
/area/awaymission/UO71/plaza)
-"BE" = (
-/obj/machinery/door/poddoor{
- id_tag = "UO71_Containment";
- name = "Containment 1"
- },
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"CA" = (
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
@@ -12787,13 +12670,6 @@
},
/turf/simulated/floor/vault,
/area/awaymission/UO71/prince)
-"Fu" = (
-/obj/structure/window/reinforced{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"Gl" = (
/obj/machinery/atmospherics/pipe/manifold/hidden/supply{
dir = 4;
@@ -12924,10 +12800,6 @@
},
/turf/simulated/floor/plasteel,
/area/awaymission/UO71/plaza)
-"PS" = (
-/obj/machinery/atmospherics/pipe/simple/hidden/supply,
-/turf/simulated/floor/plasteel,
-/area/awaymission/UO71/mother)
"Rk" = (
/obj/structure/bed,
/obj/item/bedsheet,
@@ -16953,12 +16825,12 @@ ab
ab
ab
ab
-ga
-ga
-ga
-ga
-ga
-iC
+ab
+ab
+ab
+ab
+ab
+ab
ab
ab
fO
@@ -17103,12 +16975,12 @@ ab
ab
ab
ab
-ga
-gp
-gp
-gp
-hU
-iD
+ab
+ab
+ab
+ab
+ab
+ab
ab
ab
fO
@@ -17253,12 +17125,12 @@ ab
ab
ab
ab
-ga
-gp
-gp
-gp
-gp
-ga
+ab
+ab
+ab
+ab
+ab
+ab
ab
ab
fO
@@ -17403,15 +17275,15 @@ ab
ab
ab
ab
-ga
-gq
-gU
-gp
-hV
-ga
-jg
-jG
-ke
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+fO
kM
lJ
fN
@@ -17553,17 +17425,17 @@ ab
ab
ab
ab
-ga
-hG
-hW
-hW
-hW
-Fu
-PS
-BE
-kf
-kP
-lI
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+fO
+kJ
+lH
fO
fO
fO
@@ -17703,15 +17575,15 @@ ab
ab
ab
ab
-ga
-gp
-gp
-gp
-gp
-iO
-jn
-jK
-kg
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+fN
kN
lL
fO
@@ -17853,15 +17725,15 @@ ab
ab
ab
ab
-ga
-gp
-gp
-gp
-hV
-ga
-jg
-jG
-ke
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+fN
kO
lK
mq
@@ -18003,14 +17875,14 @@ ab
ab
ab
ab
-ga
-gp
-gp
-gp
-mx
-ga
-fO
-fO
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
fN
kJ
lN
@@ -18153,13 +18025,13 @@ ab
ab
ab
ab
-ga
-ga
-ga
-ga
-ga
-ga
-fO
+ab
+ab
+ab
+ab
+ab
+ab
+ab
fO
fN
kQ
diff --git a/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm
index 9cc60009deb..37924f36064 100644
--- a/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm
+++ b/code/modules/awaymissions/mission_code/UO71-terrorspiders.dm
@@ -68,14 +68,6 @@
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
-/area/awaymission/UO71/mother
- name = "UO71 Mother Containment"
- icon_state = "awaycontent10"
- fire = TRUE
- requires_power = FALSE
- tele_proof = TRUE
- dynamic_lighting = DYNAMIC_LIGHTING_FORCED
-
/area/awaymission/UO71/loot
name = "UO71 Loot Vault"
icon_state = "awaycontent11"
@@ -98,12 +90,9 @@
info = {"Status Report on the 'Terrors'
All the spiders are deadly. We know this much already. Within an hour of their appearance, they have killed several staff.
- Three, however, bear particular mention, as they appear to be leading the spider hivemind.
+ Two, however, bear particular mention, as they appear to be leading the spider hivemind.
- The Mother is held in containment 1. Advise leaving her alone.
- It is likely that the hundreds of tiny spiders swarming over her back would come to her defense if she was threatened.
-
- The Prince is held in containment 2. He appears very aggressive, incredibly fast, strong, and durable. Extreme force and agility would be required to neutralize him.
+ The Prince is held in containment. He appears very aggressive, incredibly fast, strong, and durable. Extreme force and agility would be required to neutralize him.
It is likely the appearance of the prince was related to our initial aggression against the Queen. These things can THINK.
The Queen cannot be contained. She lives in the old bar, south of mining. She continues to breed dangerous spiders at an alarming rate.
@@ -124,8 +113,8 @@
I have seeded the Terror Queen egg in a dingy looking bar that bored engineers constructed near the mining tunnels.
No doubt she will grow soon.
- I have also placed the Mother and Prince eggs nearby, injected with sedative. Hopefully the dimwitted NT scientists bring them back for study.
- With any luck, the Queen will sense them telepathically, think NT is holding her children hostage, and attack.
+ I have also placed the Prince egg nearby, injected with sedative. Hopefully the dimwitted NT scientists bring them back for study.
+ With any luck, the Queen will sense them telepathically, think NT is holding her prince hostage, and attack.
I am going to extract out of the gateway before this all goes down.
I don't imagine the staff have very long to live once the Queen declares war on this place.
@@ -151,8 +140,7 @@
Black
Even a single bite is enough to kill a humanoid, given time.
White
Injects a parasitic agent. Deemed to pose too great an infection risk to study.
Purple
Seen guarding key areas and important spiders. Appear to be territorial, and very dangerous.
- Prince
Held in containment 2. Appears to be a sort of super-warrior. Fast, strong, and thickly armored.
- Mother
Carries hordes of spiderlings on its back. Held in containment 1.
+ Prince
Held in containment. Appears to be a sort of super-warrior. Fast, strong, and thickly armored.
Queen
Unable to contain. Present south of Cargo before contact was lost. Presumed ruler of the local hive.
"}
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
index c2b420c2511..3dff4e6a75c 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/__defines.dm
@@ -15,9 +15,9 @@
#define TS_DESC_BLACK "Black - Poison"
#define TS_DESC_PURPLE "Purple - Guard"
#define TS_DESC_BROWN "Brown - Breacher"
-#define TS_DESC_PRINCE "Prince - WAR"
+#define TS_DESC_PRINCE "Prince - HERO"
#define TS_DESC_PRINCESS "Princess - HORDE"
-#define TS_DESC_MOTHER "Mother - HORROR"
+#define TS_DESC_MOTHER "Mother - SUPPORT"
#define TS_DESC_QUEEN "Queen - LEADER"
#define TS_TIER_1 1
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
index eb0d1a37b60..51edd639d46 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
@@ -42,6 +42,44 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
user.DoVentSmash()
+/datum/action/innate/terrorspider/remoteview
+ name = "Remote View"
+ icon_icon = 'icons/obj/eyes.dmi'
+ button_icon_state = "heye"
+
+/datum/action/innate/terrorspider/remoteview/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
+ user.DoRemoteView()
+
+
+// ---------- MOTHER ACTIONS
+
+/datum/action/innate/terrorspider/mother/royaljelly
+ name = "Lay Royal Jelly"
+ icon_icon = 'icons/mob/actions/actions.dmi'
+ button_icon_state = "spiderjelly"
+
+/datum/action/innate/terrorspider/mother/royaljelly/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/mother/user = owner
+ user.DoCreateJelly()
+
+/datum/action/innate/terrorspider/mother/gatherspiderlings
+ name = "Gather Spiderlings"
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "spiderling"
+
+/datum/action/innate/terrorspider/mother/gatherspiderlings/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/mother/user = owner
+ user.PickupSpiderlings()
+
+/datum/action/innate/terrorspider/mother/incubateeggs
+ name = "Incubate Eggs"
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "eggs"
+
+/datum/action/innate/terrorspider/mother/incubateeggs/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/mother/user = owner
+ user.IncubateEggs()
// ---------- QUEEN ACTIONS
@@ -189,7 +227,7 @@
choices += L
for(var/obj/O in oview(1,src))
if(Adjacent(O) && !O.anchored)
- if(!istype(O, /obj/structure/spider/terrorweb) && !istype(O, /obj/structure/spider/cocoon) && !istype(O, /obj/structure/spider/spiderling/terror_spiderling))
+ if(!istype(O, /obj/structure/spider))
choices += O
if(choices.len)
cocoon_target = input(src,"What do you wish to cocoon?") in null|choices
@@ -216,7 +254,10 @@
if(!O.anchored)
if(istype(O, /obj/item))
O.loc = C
- else if(istype(O, /obj/machinery) || istype(O, /obj/structure))
+ else if(istype(O, /obj/machinery))
+ O.loc = C
+ large_cocoon = 1
+ else if(istype(O, /obj/structure) && !istype(O, /obj/structure/spider)) // can't wrap spiderlings/etc
O.loc = C
large_cocoon = 1
for(var/mob/living/L in C.loc)
@@ -271,3 +312,4 @@
C.visible_message("[src] smashes the welded cover off [C]!")
return
to_chat(src, "There is no welded vent or scrubber close enough to do this.")
+
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
index 7135d6e95ab..92b9b11a33b 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
@@ -2,56 +2,135 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T3 MOTHER OF TERROR --------------------------
// --------------------------------------------------------------------------------
-// -------------: ROLE: living schmuck bait
-// -------------: AI: no special ai
-// -------------: SPECIAL: spawns an ungodly number of spiderlings when killed
-// -------------: TO FIGHT IT: don't! Just leave it alone! It is harmless by itself... but god help you if you aggro it.
+// -------------: ROLE: support (team medic)
+// -------------: AI: none (only effective under player control, alongside other player-controlled spiders)
+// -------------: SPECIAL: picks up / carries spiderlings to prevent them being killed. Creates royal jellies to heal spiders.
+// -------------: TO FIGHT IT: shoot it, it will die quickly
// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos
/mob/living/simple_animal/hostile/poison/terror_spider/mother
name = "Mother of Terror spider"
- desc = "An enormous spider. Hundreds of tiny spiderlings are crawling all over it. Their beady little eyes all stare at you. The horror!"
- spider_role_summary = "Schmuck bait. Extremely weak in combat, but spawns many spiderlings when it dies."
+ desc = "An enormous spider. Tiny spiderlings are crawling all over it. Their beady little eyes all stare at you. The horror!"
+ spider_role_summary = "Carries spiderlings to protect them. Creates royal jelly that heals other spiders."
ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_mother"
icon_living = "terror_mother"
icon_dead = "terror_mother_dead"
- maxHealth = 50
- health = 50
+ maxHealth = 120 // same combat stats as an unboosted T1 gray. Very weak in combat.
+ health = 120
melee_damage_lower = 10
melee_damage_upper = 20
+ regen_points_per_tick = 2
+ regen_points_max = 400 // enough to lay 4 jellies, if fully charged
+ regen_points_per_kill = 200 // >2x normal, since they're food reprocessors
idle_ventcrawl_chance = 5
spider_tier = TS_TIER_3
spider_opens_doors = 2
- web_type = null
- var/canspawn = TRUE
- var/spawn_count = 30
- var/spawn_pc_stillborn = 50
+ web_type = /obj/structure/spider/terrorweb/mother
var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
+ var/datum/action/innate/terrorspider/remoteview/remoteview_action
+ var/datum/action/innate/terrorspider/mother/royaljelly/royaljelly_action
+ var/datum/action/innate/terrorspider/mother/gatherspiderlings/gatherspiderlings_action
+ var/datum/action/innate/terrorspider/mother/incubateeggs/incubateeggs_action
+ var/jelly_cost = 100
+
/mob/living/simple_animal/hostile/poison/terror_spider/mother/New()
..()
ventsmash_action = new()
ventsmash_action.Grant(src)
+ remoteview_action = new()
+ remoteview_action.Grant(src)
+ royaljelly_action = new()
+ royaljelly_action.Grant(src)
+ gatherspiderlings_action = new()
+ gatherspiderlings_action.Grant(src)
+ incubateeggs_action = new()
+ incubateeggs_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/mother/death(gibbed)
- if(can_die())
- if(spider_awaymission && !is_away_level(z))
- canspawn = FALSE
- if(degenerate)
- canspawn = FALSE
- if(canspawn)
- canspawn = FALSE
- for(var/i in 0 to spawn_count)
- var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
- if(prob(spawn_pc_stillborn))
- S.stillborn = 1
- S.grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green)
- S.amount_grown = 50 // double speed growth
- visible_message("[src] breaks apart, the many spiders on its back scurrying everywhere!")
- degenerate = TRUE
- return ..()
+ DropSpiderlings()
+ . = ..()
-/mob/living/simple_animal/hostile/poison/terror_spider/mother/Destroy()
- canspawn = FALSE
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/Stat()
+ ..()
+ // Provides a status panel indicator, showing mothers how many regen points they have.
+ if(statpanel("Status") && ckey && stat == CONSCIOUS)
+ stat(null, "Regeneration Points: [regen_points]")
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/examine(mob/user)
+ . = ..()
+ if(!key || stat == DEAD)
+ return
+ if(!isobserver(user) && !isterrorspider(user))
+ return
+ . += "[p_they(TRUE)] is carrying [length(contents)] spiderlings."
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/proc/DoCreateJelly()
+ // Mothers create jellies, which other terrors eat to get regeneration points, just like they get from wrapping corpses.
+ // Jellies are essentially health packs that provide healing over time.
+ if(regen_points < jelly_cost)
+ to_chat(src, "You only have [regen_points] of the [jelly_cost] regeneration points you need to do this.")
+ return
+ var/turf/mylocation = get_turf(src)
+ if(isspaceturf(mylocation))
+ to_chat(src, "Cannot secrete jelly in space.")
+ return
+ visible_message("[src] begins to secrete royal jelly.")
+ if(do_after(src, 100, target = loc))
+ if(loc != mylocation)
+ return
+ new /obj/structure/spider/royaljelly(loc)
+ regen_points -= jelly_cost
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/consume_jelly(obj/structure/spider/royaljelly/J)
+ // Jellies give more regeneration points to the spider who eats them than they cost the mother to create.
+ // This makes them cost-efficient. But it also means we can't let mothers eat jellies, or they could keep cycling them for infinite points.
+ to_chat(src, "Mothers cannot consume royal jelly.")
+ return
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/proc/PickupSpiderlings()
+ // Mothers can pick up spiderlings, carrying them on their back and stopping them from wandering into trouble.
+ var/pickup_count = 0
+ for(var/obj/structure/spider/spiderling/terror_spiderling/S in orange(2, src))
+ var/turf/T = get_turf(S)
+ new /obj/effect/temp_visual/heal(T)
+ S.movement_disabled = TRUE
+ S.forceMove(src)
+ pickup_count++
+ if(pickup_count)
+ to_chat(src, "You pick up [pickup_count] spiderling(s), storing them safely on your back.")
+ else
+ to_chat(src, "There are no spiderlings close enough for you to pick up.")
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/proc/DropSpiderlings()
+ // Called when a mother dies.
+ var/turf/T = get_turf(src)
+ for(var/obj/structure/spider/spiderling/terror_spiderling/S in src)
+ S.movement_disabled = FALSE
+ S.forceMove(T)
+ S.immediate_ventcrawl = TRUE
+
+/mob/living/simple_animal/hostile/poison/terror_spider/mother/proc/IncubateEggs()
+ // Mothers can spend regen points to make existing eggs mature faster.
+ // This lets mothers save the spiderlings from eggs that would otherwise be lost when a nest is about to get wiped out.
+ if(regen_points < 50)
+ to_chat(src, "You only have [regen_points] of the 50 regeneration points required to do this.")
+ return
+ for(var/obj/structure/spider/eggcluster/terror_eggcluster/C in orange(0, src))
+ var/turf/T = get_turf(C)
+ new /obj/effect/temp_visual/heal(T)
+ C.amount_grown += 25
+ regen_points -= 25
+ to_chat(src, "You warm [C], encouraging faster growth.")
+ return
+ to_chat(src, "The 'incubate eggs' ability can only be used on top of existing eggs.")
+
+/obj/structure/spider/terrorweb/mother
+ name = "mother web"
+ desc = "This web is coated in pheromones which prevent spiderlings from passing it."
+
+/obj/structure/spider/terrorweb/mother/CanPass(atom/movable/mover, turf/target)
+ if(istype(mover, /obj/structure/spider/spiderling/terror_spiderling))
+ return FALSE
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
index 586983b5d06..73e75ffa403 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
@@ -50,12 +50,15 @@
var/datum/action/innate/terrorspider/queen/queensense/queensense_action
var/datum/action/innate/terrorspider/queen/queeneggs/queeneggs_action
var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
+ var/datum/action/innate/terrorspider/remoteview/remoteview_action
/mob/living/simple_animal/hostile/poison/terror_spider/queen/New()
..()
ventsmash_action = new()
ventsmash_action.Grant(src)
+ remoteview_action = new()
+ remoteview_action.Grant(src)
grant_queen_subtype_abilities()
spider_myqueen = src
if(spider_awaymission)
@@ -316,7 +319,7 @@
if(MinutesAlive() >= 20)
var/list/spider_array = CountSpidersDetailed(TRUE, list(/mob/living/simple_animal/hostile/poison/terror_spider/mother, /mob/living/simple_animal/hostile/poison/terror_spider/prince, /mob/living/simple_animal/hostile/poison/terror_spider/queen/princess))
if(spider_array["all"] == 0)
- return list(TS_DESC_PRINCE, TS_DESC_PRINCESS) // Mother will be added to this list.... AFTER mothers are reworked.
+ return list(TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_MOTHER)
var/list/valid_types = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN)
var/list/spider_array = CountSpidersDetailed(FALSE, list(/mob/living/simple_animal/hostile/poison/terror_spider/brown, /mob/living/simple_animal/hostile/poison/terror_spider/purple, /mob/living/simple_animal/hostile/poison/terror_spider/black))
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
index 6f7da65a1eb..cf73b35a64a 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
@@ -20,6 +20,7 @@
var/spider_awaymission = FALSE
var/frustration = 0
var/debug_ai_choices = FALSE
+ var/movement_disabled = FALSE
/obj/structure/spider/spiderling/terror_spiderling/New()
..()
@@ -81,6 +82,25 @@
new /obj/effect/temp_visual/cult/sparks(T) // red sparks, this is an unsafe area, I won't go here unless fleeing something worse
/obj/structure/spider/spiderling/terror_spiderling/process()
+ var/turf/T = get_turf(src)
+ amount_grown += rand(0,2)
+ if(amount_grown >= 100)
+ if(spider_awaymission && !is_away_level(T.z))
+ stillborn = TRUE
+ if(stillborn)
+ if(amount_grown >= 300)
+ // Fake spiderlings stick around for awhile, just to be spooky.
+ qdel(src)
+ else
+ if(!grow_as)
+ grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green)
+ var/mob/living/simple_animal/hostile/poison/terror_spider/S = new grow_as(T)
+ S.spider_myqueen = spider_myqueen
+ S.spider_mymother = spider_mymother
+ S.enemies = enemies
+ qdel(src)
+ if(movement_disabled)
+ return
if(travelling_in_vent)
if(isturf(loc))
travelling_in_vent = 0
@@ -90,6 +110,8 @@
frustration = 0
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
+ if(temp_vent.welded) // no point considering a vent we can't even use
+ continue
vents.Add(temp_vent)
if(!vents.len)
entry_vent = null
@@ -155,23 +177,7 @@
entry_vent = v
walk_to(src, entry_vent, 1)
break
- if(isturf(loc))
- amount_grown += rand(0,2)
- if(amount_grown >= 100)
- if(spider_awaymission && !is_away_level(z))
- stillborn = TRUE
- if(stillborn)
- if(amount_grown >= 300)
- // Fake spiderlings stick around for awhile, just to be spooky.
- qdel(src)
- else
- if(!grow_as)
- grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green)
- var/mob/living/simple_animal/hostile/poison/terror_spider/S = new grow_as(loc)
- S.spider_myqueen = spider_myqueen
- S.spider_mymother = spider_mymother
- S.enemies = enemies
- qdel(src)
+
// --------------------------------------------------------------------------------
@@ -244,3 +250,8 @@
if(spider_growinstantly)
S.amount_grown = 250
qdel(src)
+
+/obj/structure/spider/royaljelly
+ name = "royal jelly"
+ desc = "A pulsating mass of slime, jelly, blood, and or liquified human organs considered delicious and highly nutritious by terror spiders."
+ icon_state = "spiderjelly"
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
index 010acbc96f2..33ba1fe1637 100644
--- 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
@@ -83,6 +83,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
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
+ var/regen_points_per_jelly = 120 // gain a ton of regen points if you eat a jelly
// 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
@@ -184,6 +185,8 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
visible_message("[src] harmlessly nuzzles [target].")
T.CheckFaction()
CheckFaction()
+ else if(istype(target, /obj/structure/spider/royaljelly))
+ consume_jelly(target)
else if(istype(target, /obj/structure/spider)) // Prevents destroying coccoons (exploit), eggs (horrible misclick), etc
to_chat(src, "Destroying things created by fellow spiders would not help us.")
else if(istype(target, /obj/machinery/door/firedoor))
@@ -219,6 +222,18 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_specialattack(mob/living/carbon/human/L, poisonable)
L.attack_animal(src)
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/consume_jelly(obj/structure/spider/royaljelly/J)
+ if(regen_points_per_tick >= regen_points_per_hp)
+ to_chat(src, "Your spider type would not get any benefit from consuming royal jelly.")
+ return
+ if(regen_points > 200)
+ to_chat(src, "You aren't hungry for jelly right now.")
+ return
+ to_chat(src, "You consume the royal jelly! Regeneration speed increased!")
+ regen_points += regen_points_per_jelly
+ fed++
+ qdel(J)
+
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: PROC OVERRIDES ---------------------------
// --------------------------------------------------------------------------------
@@ -424,4 +439,32 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
var/pc_of_max_per_second = round(((hp_points_per_second / maxHealth) * 100), 0.1)
stat(null, "Regeneration: [ltext]: [num2text(pc_of_max_per_second)]% of health per second")
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoRemoteView()
+ if(!isturf(loc))
+ // This check prevents spiders using this ability while inside an atmos pipe, which will mess up their vision
+ to_chat(src, "You must be standing on a floor to do this.")
+ return
+ if(client && (client.eye != client.mob))
+ reset_perspective()
+ return
+ if(health != maxHealth)
+ to_chat(src, "You must be at full health to do this!")
+ return
+ var/list/targets = list()
+ targets += src // ensures that self is always at top of the list
+ for(var/thing in GLOB.ts_spiderlist)
+ var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing
+ if(T.stat == DEAD)
+ continue
+ if(T.spider_awaymission != spider_awaymission)
+ continue
+ targets |= T // we use |= instead of += to avoid adding src to the list twice
+ var/mob/living/L = input("Choose a terror to watch.", "Selection") in targets
+ if(istype(L))
+ reset_perspective(L)
+/mob/living/simple_animal/hostile/poison/terror_spider/adjustHealth(amount, updating_health = TRUE)
+ if(client && (client.eye != client.mob) && ismob(client.eye)) // the ismob check is required because client.eye can = atmos machines if a spider is in the vent
+ to_chat(src, "Cancelled remote view due to being under attack!")
+ reset_perspective()
+ . = ..()
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 60799216201..e915ba04139 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index e0ef6c5ba18..643bea3d835 100644
Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ