diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm
index daa2d634b9f..c69f53f2246 100644
--- a/code/_globalvars/lists/reagents.dm
+++ b/code/_globalvars/lists/reagents.dm
@@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(standard_chemicals, list("slimejelly","blood","water","lube","c
"cryoxadone","spaceacillin","carpotoxin","lsd","fluorosurfactant",
"fluorosurfactant","ethanol","ammonia","diethylamine","antihol","pancuronium",
"lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin",
- "enzyme","nothing","salglu_solution","antifreeze","neurotoxin"))
+ "enzyme","nothing","salglu_solution","antifreeze","neurotoxin", "jestosterone"))
// Rare chemicals
GLOBAL_LIST_INIT(rare_chemicals, list("minttoxin","syndicate_nanites", "xenomicrobes"))
// Standard medicines
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 9c42d7c30dc..41d4c2c8a97 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -823,7 +823,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 30
containertype = /obj/structure/closet/crate/secure
containername = "IV drip crate"
- access = access_cmo
+ access = access_medical
/datum/supply_packs/medical/surgery
name = "Surgery Crate"
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index dc8eef959d1..bbeb28316f2 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -921,7 +921,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
reference = "PB"
item = /obj/item/pizza_bomb
cost = 5
- surplus = 8
+ surplus = 80
/datum/uplink_item/explosives/grenadier
name = "Grenadier's belt"
@@ -1597,6 +1597,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/storage/box/syndicate
excludefrom = list(/datum/game_mode/nuclear)
cant_discount = TRUE // You fucking wish
+ var/crate_value = 50
+
+/datum/uplink_item/badass/surplus_crate/super
+ name = "Syndicate Super Surplus Crate"
+ desc = "A crate containing 125 telecrystals worth of random syndicate leftovers."
+ reference = "SYSS"
+ cost = 40
+ crate_value = 125
/datum/uplink_item/badass/surplus_crate/spawn_item(turf/loc, obj/item/uplink/U)
var/obj/structure/closet/crate/C = new(loc)
@@ -1604,16 +1612,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
var/list/buyable_items = list()
for(var/category in temp_uplink_list)
buyable_items += temp_uplink_list[category]
+ var/remaining_TC = crate_value
var/list/bought_items = list()
var/list/itemlog = list()
U.uses -= cost
- U.used_TC = 20
- var/remaining_TC = 50
+ U.used_TC = cost
var/datum/uplink_item/I
while(remaining_TC)
I = pick(buyable_items)
- if(!I.surplus)
+ if(!I.surplus || prob(100 - I.surplus))
continue
if(I.cost > remaining_TC)
continue
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index ac2b07ad243..067223c0285 100644
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -61,6 +61,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/outdoors = 0 //For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room)
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
+ var/nad_allowed = FALSE //is the station NAD allowed on this area?
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
@@ -168,31 +169,36 @@ var/list/ghostteleportlocs = list()
name = "\improper Emergency Shuttle"
music = "music/escape.ogg"
icon_state = "shuttle2"
+ nad_allowed = TRUE
/area/shuttle/pod_1
name = "\improper Escape Pod One"
music = "music/escape.ogg"
icon_state = "shuttle"
+ nad_allowed = TRUE
/area/shuttle/pod_2
name = "\improper Escape Pod Two"
music = "music/escape.ogg"
icon_state = "shuttle"
+ nad_allowed = TRUE
/area/shuttle/pod_3
name = "\improper Escape Pod Three"
music = "music/escape.ogg"
icon_state = "shuttle"
+ nad_allowed = TRUE
/area/shuttle/pod_4
name = "\improper Escape Pod Four"
music = "music/escape.ogg"
icon_state = "shuttle"
-
+ nad_allowed = TRUE
/area/shuttle/escape_pod1
name = "\improper Escape Pod One"
music = "music/escape.ogg"
+ nad_allowed = TRUE
/area/shuttle/escape_pod1/station
icon_state = "shuttle2"
@@ -206,6 +212,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/escape_pod2
name = "\improper Escape Pod Two"
music = "music/escape.ogg"
+ nad_allowed = TRUE
/area/shuttle/escape_pod2/station
icon_state = "shuttle2"
@@ -219,6 +226,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/escape_pod3
name = "\improper Escape Pod Three"
music = "music/escape.ogg"
+ nad_allowed = TRUE
/area/shuttle/escape_pod3/station
icon_state = "shuttle2"
@@ -232,6 +240,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/escape_pod5 //Pod 4 was lost to meteors
name = "\improper Escape Pod Five"
music = "music/escape.ogg"
+ nad_allowed = TRUE
/area/shuttle/escape_pod5/station
icon_state = "shuttle2"
@@ -304,6 +313,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/syndicate_elite
name = "\improper Syndicate Elite Shuttle"
icon_state = "shuttlered"
+ nad_allowed = TRUE
/area/shuttle/syndicate_elite/mothership
name = "\improper Syndicate Elite Shuttle"
@@ -316,6 +326,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/syndicate_sit
name = "\improper Syndicate SIT Shuttle"
icon_state = "shuttlered"
+ nad_allowed = TRUE
/area/shuttle/assault_pod
name = "Steel Rain"
@@ -451,6 +462,7 @@ var/list/ghostteleportlocs = list()
/area/shuttle/syndicate
name = "Syndicate Nuclear Team Shuttle"
icon_state = "shuttle"
+ nad_allowed = TRUE
/area/shuttle/trade
name = "Trade Shuttle"
@@ -491,6 +503,7 @@ var/list/ghostteleportlocs = list()
icon_state = "centcom"
requires_power = 0
dynamic_lighting = 0
+ nad_allowed = TRUE
/area/centcom/control
name = "\improper Centcom Control"
@@ -537,6 +550,7 @@ var/list/ghostteleportlocs = list()
name = "\improper Syndicate Forward Base"
icon_state = "syndie-ship"
requires_power = 0
+ nad_allowed = TRUE
/area/syndicate_mothership/control
name = "\improper Syndicate Control Room"
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 32d7919c97e..1ed5e812989 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -353,7 +353,7 @@ var/list/teleport_runes = list()
var/turf/T = get_turf(src)
for(var/mob/living/M in T.contents)
- if(!iscultist(M) && !ismindshielded(M) && ishuman(M))
+ if(!iscultist(M) && !ismindshielded(M) && !isgolem(M) && ishuman(M))
convertees.Add(M)
if(!convertees.len)
fail_invoke()
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 776652a3d6b..94190149848 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -402,19 +402,34 @@ var/bomb_set
icon_state = "nucleardisk"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 30, bio = 0, rad = 0)
+/obj/item/disk/nuclear/unrestricted
+ desc = "Seems to have been stripped of its safeties, you better not lose it."
+
/obj/item/disk/nuclear/New()
..()
processing_objects.Add(src)
GLOB.poi_list |= src
/obj/item/disk/nuclear/process()
- var/turf/disk_loc = get_turf(src)
- if(!is_secure_level(disk_loc.z))
+ if(!check_disk_loc())
var/holder = get(src, /mob)
if(holder)
to_chat(holder, "You can't help but feel that you just lost something back there...")
qdel(src)
+ //station disk is allowed on z1, escape shuttle/pods, CC, and syndicate shuttles/base, reset otherwise
+/obj/item/disk/nuclear/proc/check_disk_loc()
+ var/turf/T = get_turf(src)
+ var/area/A = get_area(src)
+ if(is_station_level(T.z))
+ return TRUE
+ if(A.nad_allowed)
+ return TRUE
+ return FALSE
+
+/obj/item/disk/nuclear/unrestricted/check_disk_loc()
+ return TRUE
+
/obj/item/disk/nuclear/Destroy(force)
var/turf/diskturf = get_turf(src)
diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm
index 57369dd337c..3cdbb9b7247 100644
--- a/code/game/jobs/job/supervisor.dm
+++ b/code/game/jobs/job/supervisor.dm
@@ -125,7 +125,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_weapons, access_ntrep)
+ access_clown, access_mime, access_RC_announce, access_keycard_auth, access_gateway, access_weapons, access_ntrep)
outfit = /datum/outfit/job/nanotrasenrep
/datum/outfit/job/nanotrasenrep
@@ -205,7 +205,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0)
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_magistrate)
+ access_clown, access_mime, access_RC_announce, access_keycard_auth, access_gateway, access_magistrate)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_lawyer, access_magistrate, access_heads)
outfit = /datum/outfit/job/judge
diff --git a/code/game/objects/items/weapons/lighters.dm b/code/game/objects/items/weapons/lighters.dm
index 127613991d8..0b348510b8e 100644
--- a/code/game/objects/items/weapons/lighters.dm
+++ b/code/game/objects/items/weapons/lighters.dm
@@ -9,7 +9,7 @@
item_state = "lighter-g"
var/icon_on = "lighter-g-on"
var/icon_off = "lighter-g"
- w_class = WEIGHT_CLASS_SMALL
+ w_class = WEIGHT_CLASS_TINY
throwforce = 4
flags = CONDUCT
slot_flags = SLOT_BELT
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index 0a481460344..e745f532af8 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -178,7 +178,7 @@ var/global/sent_strike_team = 0
equip_to_slot_or_del(new /obj/item/flashlight(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
if(is_leader)
- equip_to_slot_or_del(new /obj/item/disk/nuclear(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index 735d42ad71a..886315e465f 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -139,7 +139,7 @@ var/global/sent_syndicate_strike_team = 0
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
if(is_leader)
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_in_backpack)
- equip_to_slot_or_del(new /obj/item/disk/nuclear(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/disk/nuclear/unrestricted(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/card/emag(src), slot_r_store)
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 56da139b826..ef34c40b328 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -1476,6 +1476,13 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "ssscratches_backpack"
+/obj/item/storage/backpack/duffel/fluff/thebrew //Greey: Korala Ice
+ name = "The Brew"
+ desc = "Amber colored duffle bag resembling a long lost friend, a spirit long forgotten."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "greeyfluff"
+ item_state = "greeyfluff"
+
/obj/item/clothing/head/wizard/fake/fluff/dreamy //phantasmicdream : Dreamy Rockwall
name = "strange witch hat"
desc = "A shapeshifting witch hat. A strange aura comes from it..."
diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm
index 03f56ac701b..59fbbc01e55 100644
--- a/code/modules/events/sentience.dm
+++ b/code/modules/events/sentience.dm
@@ -33,7 +33,9 @@
SA.key = SG.key
SA.universal_speak = 1
SA.sentience_act()
- SA.maxHealth = max(SA.maxHealth, 200)
+ SA.maxHealth = max(SA.maxHealth + 200)
+ SA.melee_damage_lower = max(SA.melee_damage_lower + 15)
+ SA.melee_damage_upper = max(SA.melee_damage_upper + 15)
SA.health = SA.maxHealth
SA.del_on_death = FALSE
greet_sentient(SA)
diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm
index 413d27dcbc9..daceed1988e 100644
--- a/code/modules/events/spider_terror.dm
+++ b/code/modules/events/spider_terror.dm
@@ -36,9 +36,23 @@
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/mother
spawncount = 1
while(spawncount >= 1 && vents.len)
- var/obj/vent = pick(vents)
- var/obj/structure/spider/spiderling/terror_spiderling/S = new(vent.loc)
- S.grow_as = spider_type
- S.amount_grown = 90
+ var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents)
+
+ if(vent.welded)
+ vents -= vent
+ continue
+
+ // If the vent we picked has any living mob nearby, just remove it from the list, loop again, and pick something else.
+
+ var/turf/T = get_turf(vent)
+ var/hostiles_present = FALSE
+ for(var/mob/living/L in viewers(T))
+ if(L.stat != DEAD)
+ hostiles_present = TRUE
+ break
+
vents -= vent
- spawncount--
\ No newline at end of file
+ if(!hostiles_present)
+ new spider_type(vent.loc)
+ spawncount--
+
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index d9120c63ecd..2e4d3e8efd6 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -19,6 +19,10 @@
var/obj/item/radio/radio = null // For use with the radio MMI upgrade
var/datum/action/generic/configure_mmi_radio/radio_action = null
+ // Used for cases when mmi or one of it's children commits suicide.
+ // Needed to fix a rather insane bug when a posibrain/robotic brain commits suicide
+ var/dead_icon = "mmi_dead"
+
/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/organ/internal/brain/crystal))
to_chat(user, " This brain is too malformed to be able to use with the [src].")
diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm
index 777fce50423..c36a553aff4 100644
--- a/code/modules/mob/living/carbon/brain/death.dm
+++ b/code/modules/mob/living/carbon/brain/death.dm
@@ -4,8 +4,9 @@
if(!.)
return FALSE
if(!gibbed && container && istype(container, /obj/item/mmi))//If not gibbed but in a container.
+ var/obj/item/mmi/mmi = container
visible_message("[src]'s MMI flatlines!", "You hear something flatline.")
- container.icon_state = "mmi_dead"
+ mmi.icon_state = mmi.dead_icon
/mob/living/carbon/brain/gib()
// can we muster a parent call here?
diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm
index 932072691c0..c294a11c999 100644
--- a/code/modules/mob/living/carbon/brain/robotic_brain.dm
+++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm
@@ -21,6 +21,8 @@
var/mob/living/carbon/human/imprinted_master = null
var/ejected_flavor_text = "circuit"
+ dead_icon = "boris_blank"
+
/obj/item/mmi/robotic_brain/Destroy()
imprinted_master = null
return ..()
@@ -232,3 +234,4 @@
silenced = TRUE
requires_master = FALSE
ejected_flavor_text = "metal cube"
+ dead_icon = "posibrain"
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 b4e2728eabb..0c777002ae0 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
@@ -19,6 +19,7 @@
#define TS_DESC_PURPLE "Purple - Guard"
#define TS_DESC_BROWN "Brown - Breacher"
#define TS_DESC_PRINCE "Prince - WAR"
+#define TS_DESC_PRINCESS "Princess - HORDE"
#define TS_DESC_MOTHER "Mother - HORROR"
#define TS_DESC_QUEEN "Queen - LEADER"
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 b0756cddd7f..0cb0faa16cd 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
@@ -7,7 +7,7 @@
/datum/action/innate/terrorspider/web/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
- user.Web(0)
+ user.Web()
/datum/action/innate/terrorspider/wrap
name = "Wrap"
@@ -30,16 +30,6 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/green/user = owner
user.DoLayGreenEggs()
-// ---------- PRINCE ACTIONS
-
-/datum/action/innate/terrorspider/thickweb
- name = "Thick Web"
- icon_icon = 'icons/effects/effects.dmi'
- button_icon_state = "stickyweb2"
-
-/datum/action/innate/terrorspider/thickweb/Activate()
- var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
- user.Web(1)
// ---------- BOSS ACTIONS
@@ -52,6 +42,28 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/user = owner
user.DoVentSmash()
+// ---------- PRINCESS ACTIONS
+
+/datum/action/innate/terrorspider/evolvequeen
+ name = "Evolve Queen"
+ icon_icon = 'icons/mob/terrorspider.dmi'
+ button_icon_state = "terror_queen"
+
+/datum/action/innate/terrorspider/evolvequeen/Activate()
+ var/mob/living/simple_animal/hostile/poison/terror_spider/princess/user = owner
+ if(!istype(user))
+ to_chat(user, "ERROR: attempt to use evolve queen ability on a non-princess")
+ return
+ var/feedings_left = user.feedings_to_evolve - user.fed
+ if(feedings_left > 0)
+ to_chat(user, "You must wrap [feedings_left] more humanoid prey before you can do this!")
+ return
+ for(var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q in ts_spiderlist)
+ if(Q.spider_awaymission == user.spider_awaymission)
+ to_chat(user, "The presence of another Queen in the area is preventing you from maturing.")
+ return
+ user.evolve_to_queen()
+
// ---------- QUEEN ACTIONS
/datum/action/innate/terrorspider/queen/queennest
@@ -103,7 +115,9 @@
// ---------- WEB
-/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web(var/thick = 0)
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web()
+ if(!web_type)
+ return
var/turf/mylocation = loc
visible_message("[src] begins to secrete a sticky substance.")
if(do_after(src, delay_web, target = loc))
@@ -116,15 +130,8 @@
if(T)
to_chat(src, "There is already a web here.")
else
- var/obj/structure/spider/terrorweb/W = new /obj/structure/spider/terrorweb(loc)
+ var/obj/structure/spider/terrorweb/W = new web_type(loc)
W.creator_ckey = ckey
- if(thick)
- W.opacity = 1
- W.name = "thick terror web"
- W.health = W.health * 2
- if(web_infects)
- W.infectious = 1
- W.name = "sharp terror web"
/obj/structure/spider/terrorweb
name = "terror web"
@@ -135,7 +142,6 @@
health = 20 // two welders, or one laser shot (15 for the normal spider webs)
icon_state = "stickyweb1"
var/creator_ckey = null
- var/infectious = 0
/obj/structure/spider/terrorweb/New()
..()
@@ -164,11 +170,7 @@
DeCloakNearby()
if(iscarbon(mover))
var/mob/living/carbon/C = mover
- if(!IsTSInfected(C) && infectious)
- var/inject_target = pick("chest","head")
- if(C.can_inject(null, 0, inject_target, 0))
- to_chat(C, "[src] slices into you!")
- new /obj/item/organ/internal/body_egg/terror_eggs(C)
+ web_special_ability(C)
spawn(70)
if(C.loc == loc)
qdel(src)
@@ -186,6 +188,9 @@
return
..()
+/obj/structure/spider/terrorweb/proc/web_special_ability(mob/living/carbon/C)
+ return
+
// ---------- WRAP
/mob/living/simple_animal/hostile/poison/terror_spider/proc/FindWrapTarget()
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
index 2c30e61969a..bc568496236 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm
@@ -21,6 +21,7 @@
health = 120
melee_damage_lower = 5
melee_damage_upper = 10
+ web_type = /obj/structure/spider/terrorweb/black
stat_attack = 1 // ensures they will target people in crit, too!
spider_tier = TS_TIER_2
@@ -42,4 +43,17 @@
step_away(src, L)
LoseTarget()
step_away(src, L)
- visible_message("[src] jumps away from [L]!")
\ No newline at end of file
+ visible_message("[src] jumps away from [L]!")
+
+
+/obj/structure/spider/terrorweb/black
+ name = "sinister web"
+ desc = "This web has beads of a dark fluid on its strands."
+
+/obj/structure/spider/terrorweb/black/web_special_ability(mob/living/carbon/C)
+ if(istype(C))
+ if(!C.reagents.has_reagent("terror_black_toxin", 60))
+ var/inject_target = pick("chest","head")
+ if(C.can_inject(null, 0, inject_target, 0))
+ to_chat(C, "[src] slices into you!")
+ C.reagents.add_reagent("terror_black_toxin", 30)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/brown.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/brown.dm
index af5bd4495ee..389397da95c 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/brown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/brown.dm
@@ -26,6 +26,7 @@
ai_ventbreaker = 1
freq_ventcrawl_combat = 600 // Ventcrawls very frequently, breaking open vents as it goes.
freq_ventcrawl_idle = 1800
+ web_type = null
var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
/mob/living/simple_animal/hostile/poison/terror_spider/brown/New()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
index 15de66e7599..51028a69111 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
@@ -42,30 +42,32 @@
queenfakelings_action.button.name = "Empress Lings"
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/LayQueenEggs()
- var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE)
+ var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE)
var/numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50)
if(eggtype == null || numlings == null)
to_chat(src, "Cancelled.")
return
switch(eggtype)
if(TS_DESC_RED)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings)
if(TS_DESC_GRAY)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings)
if(TS_DESC_GREEN)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings)
if(TS_DESC_BLACK)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings)
if(TS_DESC_PURPLE)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple,numlings,0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings)
if(TS_DESC_WHITE)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white,numlings,0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, numlings)
if(TS_DESC_PRINCE)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, numlings)
+ if(TS_DESC_PRINCESS)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/princess, numlings)
if(TS_DESC_MOTHER)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, numlings)
if(TS_DESC_QUEEN)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen,numlings,1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen, numlings)
else
to_chat(src, "Unrecognized egg type.")
@@ -80,6 +82,7 @@
/mob/living/simple_animal/hostile/poison/terror_spider/white, \
/mob/living/simple_animal/hostile/poison/terror_spider/black)
S.spider_myqueen = spider_myqueen
+ S.spider_mymother = src
if(prob(sbpc))
S.stillborn = TRUE
if(spider_growinstantly)
@@ -93,7 +96,7 @@
for(var/obj/structure/spider/eggcluster/terror_eggcluster/T in ts_egg_list)
qdel(T)
for(var/obj/structure/spider/spiderling/terror_spiderling/T in ts_spiderling_list)
- T.stillborn = TRUE
+ qdel(T)
to_chat(src, "All Terror Spiders, except yourself, will die off shortly.")
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
index c24a7ef4369..2f124e94479 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm
@@ -25,6 +25,7 @@
wander = 0 // wandering defeats the purpose of stealth
idle_vision_range = 3 // very low idle vision range
delay_web = 20 // double speed
+ web_type = /obj/structure/spider/terrorweb/gray
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
@@ -136,3 +137,8 @@
if(get_dist(src,temp_vent) > 0 && get_dist(src,temp_vent) < 5)
step_to(src,temp_vent)
// if you're bumped off your vent, try to get back to it
+
+/obj/structure/spider/terrorweb/gray
+ alpha = 100
+ name = "transparent web"
+ desc = "This web is partly transparent, making it harder to see, and easier to get caught by."
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
index 64ef285ded8..793acd82136 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm
@@ -16,10 +16,11 @@
icon_state = "terror_green"
icon_living = "terror_green"
icon_dead = "terror_green_dead"
- maxHealth = 120
- health = 120
+ maxHealth = 150
+ health = 150
melee_damage_lower = 10
melee_damage_upper = 20
+ web_type = /obj/structure/spider/terrorweb/green
var/feedings_to_lay = 2
var/datum/action/innate/terrorspider/greeneggs/greeneggs_action
@@ -33,54 +34,46 @@
var/obj/structure/spider/eggcluster/E = locate() in get_turf(src)
if(E)
to_chat(src, "There is already a cluster of eggs here!")
- else if(fed < feedings_to_lay)
+ return
+ if(fed < feedings_to_lay)
to_chat(src, "You must wrap more humanoid prey before you can do this!")
+ return
+ var/list/eggtypes = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN)
+ var/num_brown = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/brown)
+ if(num_brown < 2)
+ eggtypes += TS_DESC_BROWN
+ var/num_black = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/black)
+ if(num_black < 2)
+ eggtypes += TS_DESC_BLACK
+ var/eggtype = pick(eggtypes)
+ if(client)
+ eggtype = input("What kind of eggs?") as null|anything in eggtypes
+ if(!(eggtype in eggtypes))
+ to_chat(src, "Unrecognized egg type.")
+ return 0
+ visible_message("[src] lays a cluster of eggs.")
+ if(eggtype == TS_DESC_RED)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 1)
+ else if(eggtype == TS_DESC_GRAY)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, 1)
+ else if(eggtype == TS_DESC_GREEN)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 1)
+ else if(eggtype == TS_DESC_BLACK)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, 1)
+ else if(eggtype == TS_DESC_BROWN)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 1)
else
- visible_message("[src] begins to lay a cluster of eggs.")
- if(prob(33))
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 1, 1)
- else if(prob(50))
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, 1, 1)
- else
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 1, 1)
- fed -= feedings_to_lay
+ to_chat(src, "Unrecognized egg type!")
+ fed += feedings_to_lay
+ fed -= feedings_to_lay
/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_special_action()
if(cocoon_target)
- if(get_dist(src, cocoon_target) <= 1)
- spider_steps_taken = 0
- DoWrap()
- else
- if(spider_steps_taken > spider_max_steps)
- spider_steps_taken = 0
- cocoon_target = null
- busy = 0
- stop_automated_movement = 0
- else
- spider_steps_taken++
- CreatePath(cocoon_target)
- step_to(src,cocoon_target)
- if(spider_debug)
- visible_message("[src] moves towards [cocoon_target] to cocoon it.")
+ handle_cocoon_target()
else if(fed >= feedings_to_lay)
DoLayGreenEggs()
else if(world.time > (last_cocoon_object + freq_cocoon_object))
- last_cocoon_object = world.time
- var/list/can_see = view(src, 10)
- for(var/mob/living/C in can_see)
- if(C.stat == DEAD && !isterrorspider(C) && !C.anchored)
- spider_steps_taken = 0
- cocoon_target = C
- return
- for(var/obj/O in can_see)
- if(O.anchored)
- continue
- if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
- if(!istype(O, /obj/item/paper))
- cocoon_target = O
- stop_automated_movement = 1
- spider_steps_taken = 0
- return
+ seek_cocoon_target()
/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
@@ -94,4 +87,14 @@
visible_message("[src] buries its fangs deep into the [inject_target] of [target]!")
else
visible_message("[src] bites [target], but cannot inject venom into [target.p_their()] [inject_target]!")
- L.attack_animal(src)
\ No newline at end of file
+ L.attack_animal(src)
+
+/obj/structure/spider/terrorweb/green
+ name = "slimy web"
+ desc = "This web is partly composed of strands of green slime."
+
+/obj/structure/spider/terrorweb/green/web_special_ability(mob/living/carbon/C)
+ if(istype(C))
+ if(C.eye_blurry < 60)
+ C.AdjustEyeBlurry(30)
+
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 7ef903a7b48..354f99db8af 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
@@ -13,9 +13,9 @@
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."
ai_target_method = TS_DAMAGE_SIMPLE
- icon_state = "terror_gray2"
- icon_living = "terror_gray2"
- icon_dead = "terror_gray2_dead"
+ icon_state = "terror_mother"
+ icon_living = "terror_mother"
+ icon_dead = "terror_mother_dead"
maxHealth = 50
health = 50
melee_damage_lower = 10
@@ -23,7 +23,10 @@
idle_ventcrawl_chance = 5
spider_tier = TS_TIER_3
spider_opens_doors = 2
- var/canspawn = 1
+ web_type = null
+ var/canspawn = TRUE
+ var/spawn_count = 30
+ var/spawn_pc_stillborn = 50
var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
/mob/living/simple_animal/hostile/poison/terror_spider/mother/New()
@@ -33,24 +36,20 @@
/mob/living/simple_animal/hostile/poison/terror_spider/mother/death(gibbed)
if(can_die())
- var/always_stillborn = FALSE
if(spider_awaymission && !is_away_level(z))
- always_stillborn = TRUE
+ canspawn = FALSE
if(canspawn)
- canspawn = 0
- for(var/i in 0 to 30)
+ 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))
- S.grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray)
- if(always_stillborn || prob(66))
+ if(prob(spawn_pc_stillborn))
S.stillborn = 1
- else if(prob(10))
- S.grow_as = pick(/mob/living/simple_animal/hostile/poison/terror_spider/black, /mob/living/simple_animal/hostile/poison/terror_spider/green)
+ 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
- S.immediate_ventcrawl = 1
visible_message("[src] breaks apart, the many spiders on its back scurrying everywhere!")
degenerate = 1
return ..()
/mob/living/simple_animal/hostile/poison/terror_spider/mother/Destroy()
- canspawn = 0
+ canspawn = FALSE
return ..()
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
index e0ac2a54927..d0ddc369517 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm
@@ -27,12 +27,8 @@
idle_ventcrawl_chance = 0
spider_tier = TS_TIER_3
spider_opens_doors = 2
- var/datum/action/innate/terrorspider/thickweb/thickweb_action
-
-/mob/living/simple_animal/hostile/poison/terror_spider/prince/New()
- ..()
- thickweb_action = new()
- thickweb_action.Grant(src)
+ web_type = /obj/structure/spider/terrorweb/purple
+ ai_spins_webs = FALSE
/mob/living/simple_animal/hostile/poison/terror_spider/prince/death(gibbed)
if(can_die() && !hasdied && spider_uo71)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm
new file mode 100644
index 00000000000..d53e5924bdd
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm
@@ -0,0 +1,68 @@
+
+// --------------------------------------------------------------------------------
+// ----------------- TERROR SPIDERS: T3 PRINCESS OF TERROR --------------------------
+// --------------------------------------------------------------------------------
+// -------------: ROLE: cutesy
+// -------------: AI: as green, but will evolve to queen when it can
+// -------------: SPECIAL: can evolve into a queen, if fed enough
+// -------------: TO FIGHT IT: kill it before it evolves
+// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
+
+/mob/living/simple_animal/hostile/poison/terror_spider/princess
+ name = "Princess of Terror spider"
+ desc = "An enormous spider. It looks strangely cute and fluffy."
+ spider_role_summary = "Future Queen"
+ ai_target_method = TS_DAMAGE_SIMPLE
+ icon_state = "terror_princess1"
+ icon_living = "terror_princess1"
+ icon_dead = "terror_princess_dead1"
+ maxHealth = 150
+ health = 150
+ regen_points_per_hp = 1 // always regens very fast
+ force_threshold = 18 // outright immune to anything of force under 18, same as queen
+ melee_damage_lower = 10
+ melee_damage_upper = 20
+ idle_ventcrawl_chance = 5
+ spider_tier = TS_TIER_3
+ spider_opens_doors = 2
+ web_type = /obj/structure/spider/terrorweb/queen
+ var/feedings_to_evolve = 3
+ var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
+ var/datum/action/innate/terrorspider/evolvequeen/evolvequeen_action
+
+/mob/living/simple_animal/hostile/poison/terror_spider/princess/New()
+ ..()
+ ventsmash_action = new()
+ ventsmash_action.Grant(src)
+ evolvequeen_action = new()
+ evolvequeen_action.Grant(src)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/princess/proc/evolve_to_queen()
+ change_mob_type(/mob/living/simple_animal/hostile/poison/terror_spider/queen, null, null, 1, 1)
+
+/mob/living/simple_animal/hostile/poison/terror_spider/princess/DoWrap()
+ . = ..()
+ if(fed == 0)
+ icon_state = "terror_princess1"
+ icon_living = "terror_princess1"
+ icon_dead = "terror_princess_dead1"
+ desc = "An enormous spider. It looks strangely cute and fluffy, with soft pink fur covering most of its body."
+ else if(fed == 1)
+ icon_state = "terror_princess2"
+ icon_living = "terror_princess2"
+ icon_dead = "terror_princess2_dead"
+ desc = "An enormous spider. It used to look strangely cute and fluffy, but now the effect is spoiled by parts of its fur, which have turned an ominous blood red in color."
+ else
+ icon_state = "terror_princess3"
+ icon_living = "terror_princess3"
+ icon_dead = "terror_princess3_dead"
+ desc = "An enormous spider. Its entire body has turned an ominous blood red color, with actual blood dripping from its jaws. It stares around, hungrily."
+
+/mob/living/simple_animal/hostile/poison/terror_spider/princess/spider_special_action()
+ if(cocoon_target)
+ handle_cocoon_target()
+ else if(fed >= feedings_to_evolve)
+ evolve_to_queen()
+ else if(world.time > (last_cocoon_object + freq_cocoon_object))
+ seek_cocoon_target()
+
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
index bd789d98db7..7f522b3382e 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm
@@ -28,15 +28,11 @@
ai_ventcrawls = 0
environment_smash = ENVIRONMENT_SMASH_RWALLS
idle_ventcrawl_chance = 0 // stick to the queen!
+ web_type = /obj/structure/spider/terrorweb/purple
+ ai_spins_webs = FALSE
var/dcheck_counter = 0
var/queen_visible = 1
var/cycles_noqueen = 0
- var/datum/action/innate/terrorspider/thickweb/thickweb_action
-
-/mob/living/simple_animal/hostile/poison/terror_spider/purple/New()
- ..()
- thickweb_action = new()
- thickweb_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/purple/death(gibbed)
if(can_die() && spider_myqueen)
@@ -45,7 +41,7 @@
if(get_dist(src,Q) > 20)
if(!degenerate && !Q.degenerate)
degenerate = 1
- Q.DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple,1,0)
+ Q.DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 1)
visible_message("[src] chitters in the direction of [Q]!")
return ..()
@@ -93,3 +89,9 @@
to_chat(src,"Your link to your Queen has been broken! Your life force starts to drain away!")
melee_damage_lower = 5
melee_damage_upper = 10
+
+/obj/structure/spider/terrorweb/purple
+ name = "thick web"
+ desc = "This web is so thick, most cannot see beyond it."
+ opacity = 1
+ health = 40
\ No newline at end of file
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 ce5120fab87..ed2ea164634 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
@@ -31,6 +31,7 @@
projectiletype = /obj/item/projectile/terrorqueenspit
spider_tier = TS_TIER_4
spider_opens_doors = 2
+ web_type = /obj/structure/spider/terrorweb/queen
var/spider_spawnfrequency = 1200 // 120 seconds
var/spider_spawnfrequency_stable = 1200 // 120 seconds. Spawnfrequency is set to this on ai spiders once nest setup is complete.
var/spider_lastspawn = 0
@@ -155,7 +156,7 @@
if(world.time > (lastnestsetup + nestfrequency))
lastnestsetup = world.time
spider_lastspawn = world.time
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2)
neststep = 3
if(3)
// Create spiders (random T1 types) until nest is full.
@@ -169,7 +170,7 @@
var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
spider_lastspawn = world.time
- DoLayTerrorEggs(pick(spider_types_standard), 2, 0)
+ DoLayTerrorEggs(pick(spider_types_standard), 2)
if(4)
// Nest should be full. If so, pulse attack command. Otherwise, start replenishing nest (stage 5).
if(world.time > (spider_lastspawn + spider_spawnfrequency))
@@ -192,13 +193,13 @@
var/num_white = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/white)
var/num_brown = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/brown)
if(num_purple < 4)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2)
else if(num_white < 2)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, 2, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, 2)
else if(num_brown < 2)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 2, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 2)
else
- DoLayTerrorEggs(pick(spider_types_standard), 2, 0)
+ DoLayTerrorEggs(pick(spider_types_standard), 2)
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestPrompt()
var/confirm = alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.","Nest?","Yes","No")
@@ -269,17 +270,17 @@
else
if(eggtype == TS_DESC_MOTHER)
canlay -= 12
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, 1, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, 1)
else if(eggtype == TS_DESC_PRINCE)
canlay -= 12
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, 1, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, 1)
return
else if(eggtype == TS_DESC_BROWN)
if(canlay < 4)
to_chat(src, "Insufficient strength. It takes as much effort to lay one of those as it does to lay 4 normal eggs.")
else
canlay -= 4
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 1, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 1)
return
var/numlings = 1
if(eggtype != TS_DESC_PURPLE)
@@ -295,15 +296,15 @@
canlay -= numlings
eggslaid += numlings
if(eggtype == TS_DESC_RED)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings, 1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings)
else if(eggtype == TS_DESC_GRAY)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings, 1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings)
else if(eggtype == TS_DESC_GREEN)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings, 1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings)
else if(eggtype == TS_DESC_BLACK)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings, 1)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings)
else if(eggtype == TS_DESC_PURPLE)
- DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings, 0)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings)
else
to_chat(src, "Unrecognized egg type.")
@@ -322,11 +323,12 @@
return
if(spider_can_fakelings)
spider_can_fakelings--
- var/numlings = 15
+ var/numlings = 25
for(var/i in 1 to numlings)
var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S.stillborn = 1
+ S.spider_mymother = src
if(!spider_can_fakelings)
queenfakelings_action.Remove(src)
else
@@ -347,3 +349,14 @@
L.Hallucinate(400)
if(!isterrorspider(L))
L.adjustToxLoss(bonus_tox)
+
+/obj/structure/spider/terrorweb/queen
+ name = "shimmering web"
+ desc = "This web seems to shimmer all different colors in the light."
+
+/obj/structure/spider/terrorweb/queen/web_special_ability(mob/living/carbon/C)
+ if(istype(C))
+ var/inject_target = pick("chest","head")
+ if(C.can_inject(null, 0, inject_target, 0))
+ C.Hallucinate(400)
+ C.adjustToxLoss(30)
\ 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
index 5f219f2b3b1..98556c63d34 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm
@@ -24,6 +24,7 @@
move_to_delay = 10 // at 20ticks/sec, this is 2 tile/sec movespeed
speed = 2 // movement_delay() gives 4.5, or 0.45s between steps, which = about 2.2 tiles/second. Player is slightly faster than AI, but cannot move on diagonals.
spider_opens_doors = 2
+ web_type = /obj/structure/spider/terrorweb/red
var/enrage = 0
var/melee_damage_lower_rage0 = 15
var/melee_damage_upper_rage0 = 20
@@ -57,4 +58,10 @@
visible_message("[src] retracts its fangs a little.")
melee_damage_lower = melee_damage_lower_rage1
melee_damage_upper = melee_damage_upper_rage1
- ..()
\ No newline at end of file
+ ..()
+
+
+/obj/structure/spider/terrorweb/red
+ health = 30
+ name = "reinforced web"
+ desc = "This web is reinforced with extra strands, for added strength."
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 2f92df3e562..999405df2d8 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
@@ -13,10 +13,14 @@
var/stillborn = FALSE
faction = list("terrorspiders")
var/spider_myqueen = null
- var/use_vents = 1
+ var/spider_mymother = null
+ var/goto_mother = FALSE
+ var/ventcrawl_chance = 30 // 30% every process(), assuming 33% wander does not trigger
+ var/immediate_ventcrawl = TRUE
var/list/enemies = list()
- var/immediate_ventcrawl = 0
var/spider_awaymission = FALSE
+ var/frustration = 0
+ var/debug_ai_choices = FALSE
/obj/structure/spider/spiderling/terror_spiderling/New()
..()
@@ -35,6 +39,48 @@
qdel(src)
. = ..()
+
+/obj/structure/spider/spiderling/terror_spiderling/die()
+ for(var/obj/structure/spider/spiderling/terror_spiderling/S in view(7, src))
+ S.immediate_ventcrawl = TRUE
+ . = ..()
+
+/obj/structure/spider/spiderling/terror_spiderling/proc/score_surroundings(atom/A = src)
+ var/safety_score = 0
+ var/turf/T = get_turf(A)
+ for(var/mob/living/L in viewers(T))
+ if(isterrorspider(L))
+ if(L.stat == DEAD)
+ safety_score--
+ else
+ safety_score++
+ if(spider_mymother && L == spider_mymother)
+ safety_score++
+ else if(L.stat != DEAD)
+ safety_score--
+ if(debug_ai_choices)
+ debug_visual(T, safety_score, A)
+ return safety_score
+
+/obj/structure/spider/spiderling/terror_spiderling/proc/debug_visual(turf/T, score, atom/A)
+ // This proc exists to help debug why spiderlings are making the ventcrawl AI choices they do.
+ // It won't be called unless you set the spiderling's debug_ai_choices to true.
+ if(debug_ai_choices && istype(T))
+ if(A == src)
+ if(score > 0)
+ new /obj/effect/temp_visual/heart(T) // heart symbol, I am safe here, protected by a friendly spider
+ else if (score == 0)
+ new /obj/effect/temp_visual/heal(T) // white "+" symbol, I am neutral here
+ else
+ new /obj/effect/temp_visual/at_shield(T) // octagon symbol, I am unsafe here, I need to flee
+ else
+ if(score > 0)
+ new /obj/effect/temp_visual/telekinesis(T) // blue sparks, this is a safe area, I want to go here
+ else if (score == 0)
+ new /obj/effect/temp_visual/revenant(T) // purple sparks, this is a neutral area, an acceptable choice
+ else
+ 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()
if(travelling_in_vent)
if(isturf(loc))
@@ -42,6 +88,7 @@
entry_vent = null
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
+ frustration = 0
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
vents.Add(temp_vent)
@@ -49,8 +96,22 @@
entry_vent = null
return
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
- if(prob(50))
- visible_message("[src] scrambles into the ventillation ducts!", "You hear something squeezing through the ventilation ducts.")
+ if(spider_mymother && (goto_mother || prob(10)))
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(5, spider_mymother))
+ if(!v.welded)
+ exit_vent = v
+ goto_mother = FALSE
+ if(!stillborn)
+ var/current_safety_score = score_surroundings(src)
+ var/new_safety_score = score_surroundings(exit_vent)
+ if(new_safety_score < current_safety_score)
+ // Try to find an alternative.
+ exit_vent = pick(vents)
+ new_safety_score = score_surroundings(exit_vent)
+ if(new_safety_score < current_safety_score)
+ // No alternative safe vent could be found. Abort.
+ entry_vent = null
+ return
var/original_location = loc
spawn(rand(20,60))
forceMove(exit_vent)
@@ -72,14 +133,24 @@
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
+ else
+ frustration++
+ walk_to(src, entry_vent, 1)
+ if(frustration > 2)
+ entry_vent = null
else if(prob(33))
var/list/nearby = oview(10, src)
if(nearby.len)
var/target_atom = pick(nearby)
if(!istype(get_turf(target_atom),/turf/space))
walk_to(src, target_atom)
- else if(immediate_ventcrawl || (prob(10) && use_vents))
- immediate_ventcrawl = 0
+ else if(immediate_ventcrawl || prob(ventcrawl_chance))
+ immediate_ventcrawl = FALSE
+ if(!stillborn && !goto_mother)
+ var/safety_score = score_surroundings(src)
+ if(safety_score > 0)
+ // This area seems safe (friendly spiders present). Do not leave this area.
+ return
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
@@ -91,29 +162,33 @@
if(spider_awaymission && !is_away_level(z))
stillborn = TRUE
if(stillborn)
- die()
+ if(amount_grown >= 300)
+ // Fake spiderlings stick around for awhile, just to be spooky.
+ die()
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.faction = faction
S.spider_myqueen = spider_myqueen
+ S.spider_mymother = spider_mymother
S.master_commander = master_commander
S.enemies = enemies
qdel(src)
+
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: EGGS (USED BY NURSE AND QUEEN TYPES) ---------
// --------------------------------------------------------------------------------
-/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoLayTerrorEggs(lay_type, lay_number, lay_crawl)
+/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoLayTerrorEggs(lay_type, lay_number)
stop_automated_movement = 1
var/obj/structure/spider/eggcluster/terror_eggcluster/C = new /obj/structure/spider/eggcluster/terror_eggcluster(get_turf(src))
C.spiderling_type = lay_type
C.spiderling_number = lay_number
- C.spiderling_ventcrawl = lay_crawl
C.faction = faction
C.spider_myqueen = spider_myqueen
+ C.spider_mymother = src
C.master_commander = master_commander
C.enemies = enemies
if(spider_growinstantly)
@@ -129,9 +204,9 @@
var/spider_growinstantly = 0
faction = list("terrorspiders")
var/spider_myqueen = null
+ var/spider_mymother = null
var/spiderling_type = null
var/spiderling_number = 1
- var/spiderling_ventcrawl = 1
var/list/enemies = list()
/obj/structure/spider/eggcluster/terror_eggcluster/New()
@@ -169,16 +244,11 @@
var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
if(spiderling_type)
S.grow_as = spiderling_type
- S.use_vents = spiderling_ventcrawl
S.faction = faction
S.spider_myqueen = spider_myqueen
+ S.spider_mymother = spider_mymother
S.master_commander = master_commander
S.enemies = enemies
if(spider_growinstantly)
S.amount_grown = 250
- var/rnum = 5 - spiderling_number
- for(var/i=0, i