Merge pull request #6446 from Kyep/terrorspiders-PR3

Terror Spiders 3 - Awaymission & AI
This commit is contained in:
Fox McCloud
2017-02-25 17:04:30 -05:00
committed by GitHub
26 changed files with 2643 additions and 68 deletions
@@ -0,0 +1,256 @@
/area/awaymission/UO71
name = "UO71"
icon_state = "away"
report_alerts = 0
tele_proof = 1
/area/awaymission/UO71/plaza
name = "UO71 Plaza"
icon_state = "awaycontent1"
fire = 1
/area/awaymission/UO71/centralhall
name = "UO71 Central"
icon_state = "awaycontent2"
fire = 1
/area/awaymission/UO71/eng
name = "UO71 Engineering"
icon_state = "awaycontent3"
fire = 1
/area/awaymission/UO71/mining
name = "UO71 Mining"
icon_state = "awaycontent4"
fire = 1
/area/awaymission/UO71/science
name = "UO71 Science"
icon_state = "awaycontent5"
fire = 1
/area/awaymission/UO71/medical
name = "UO71 Medical"
icon_state = "awaycontent6"
fire = 1
/area/awaymission/UO71/gateway
name = "UO71 Gateway"
icon_state = "awaycontent7"
fire = 1
/area/awaymission/UO71/outside
name = "UO71 Outside"
icon_state = "awaycontent8"
/area/awaymission/UO71/bridge
name = "UO71 Bridge"
icon_state = "awaycontent21"
fire = 1
requires_power = 0
tele_proof = 1
/area/awaymission/UO71/queen
name = "UO71 Queen Lair"
icon_state = "awaycontent9"
fire = 1
requires_power = 0
tele_proof = 1
/area/awaymission/UO71/prince
name = "UO71 Prince Containment"
icon_state = "awaycontent10"
fire = 1
requires_power = 0
tele_proof = 1
/area/awaymission/UO71/mother
name = "UO71 Mother Containment"
icon_state = "awaycontent10"
fire = 1
requires_power = 0
tele_proof = 1
/area/awaymission/UO71/loot
name = "UO71 Loot Vault"
icon_state = "awaycontent11"
requires_power = 0
tele_proof = 1
/obj/item/weapon/paper/terrorspiders1
name = "paper - 'Sealed Facility'"
info = {"<b>SEALED FACILITY</b><br>
<br>
This facility is sealed shut by order of Commander Marquez. Do not enter.<br>
Terror spiders live here. We believe they are a weapon developed by the syndicate.<br>
Any surviving personnel are to evacuate immediately via the gateway.<br>
"}
/obj/item/weapon/paper/terrorspiders2
name = "paper - 'The Trio of Terror'"
info = {"<b>Status Report on the 'Terrors'</b><br>
<br>
All the spiders are deadly. We know this much already. Within an hour of their appearance, they have killed several staff.<br>
Three, however, bear particular mention, as they appear to be leading the spider hivemind.<br>
<br>
The Mother is held in containment 1. Advise leaving her alone.<br>
It is likely that the hundreds of tiny spiders swarming over her back would come to her defense if she was threatened.<br>
<br>
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.<br>
It is likely the appearance of the prince was related to our initial aggression against the Queen. These things can THINK.<br>
<br>
The Queen cannot be contained. She lives in the old bar, south of mining. She continues to breed dangerous spiders at an alarming rate.<br>
Many of her offspring are already roaming the compound, traveling through the vents. Contact with the team sent to subdue her has been lost.<br>
<br>
<br>
Based on the situation, Commander, I advise immediate evacuation through the gateway.<br>
-Research Director Simons<br>
"}
/obj/item/weapon/paper/terrorspiders3
name = "paper - 'Final Report'"
info = {"FROM: Field Agent 0738<br>
TO: Syndicate #873589<br>
SUBJECT: Mission Success<br>
<br>
I have seeded the Terror Queen egg in a dingy looking bar that bored engineers constructed near the mining tunnels.<br>
No doubt she will grow soon.<br>
<br>
I have also placed the Mother and Prince eggs nearby, injected with sedative. Hopefully the dimwitted NT scientists bring them back for study.<br>
With any luck, the Queen will sense them telepathically, think NT is holding her children hostage, and attack.<br>
<br>
I am going to extract out of the gateway before this all goes down.<br>
I don't imagine the staff have very long to live once the Queen declares war on this place.<br>
"}
/obj/item/weapon/paper/terrorspiders4
name = "paper - 'Prescription for Jones, David'"
info = {"PRESCRIPTION FOR: David Jones<br>
RANK: Miner<br>
FOR: Haloperidol<br>
REASON FOR TREATMENT: Hallucinations, Paranoia<br>
CAUSE: Hallucinations caused by encounter with toxic spit of spider in the caves. Paranoia caused by disappearing staff and suspicions of syndicate infiltration.<br>
TREATMENT PLAN: Take as needed. See Dr. Phloxi in one week if symptoms persist. <br>
"}
/obj/item/weapon/paper/terrorspiders5
name = "paper - 'A Study in Terror'"
info = {"<b>Findings Overview</b><br>
<br>
<p>Gray Spiders<br>Stealthy predators that ambush prey from vents. Otherwise weak.</p>
<p>Red Spiders<br>Can kill anyone in melee, but slow.</p>
<p>Green<br>Will lay eggs on dead bodies, breeding more spiders.</p>
<p>Black<br>Even a single bite is enough to kill a humanoid, given time.</p>
<p>White<br>Injects a parasitic agent. Deemed to pose too great an infection risk to study.</p>
<p>Purple<br>Only seen guarding the nest of the Queen to the south. Appear to be territorial, and very dangerous.</p>
<p>Prince<br>Held in containment 2. Appears to be a sort of super-warrior. Fast, strong, and thickly armored.</p>
<p>Mother<br>Carries hordes of spiderlings on its back. Held in containment 1. </p>
<p>Queen<br>Unable to contain. Present south of Cargo before contact was lost. Presumed ruler of the local hive.</p>
"}
/obj/item/weapon/paper/terrorspiders6
name = "paper - 'A Study in Venom'"
info = {"<b>Initial Report - Black Widow Venom</b><br>
<br>
Even a single bite kills within a few minutes. Immediate charcoal is necessary for the victim to survive.<br>
The fascinating thing is that multiple bites actually cause rapid symptom onset. The victim quickly loses the ability to walk.<br>
One test monkey went from perfect health to death in under 60 seconds - from 3 bites.<br>
I am so very glad I'm not responsible for keeping these things contained."}
/obj/item/weapon/paper/terrorspiders7
name = "paper - 'Security Orders'"
info = {"<b>Directives for Officer James</b><br>
<br>
1. Find a way to lift the bridge lockdown.<br>
2. Kill any spiders you encounter.<br>
3. Once on the bridge, open a path to the Queen in the south, and find a way to kill her, ending the infestation. <br>
Good luck, Officer.<br>
"}
/obj/item/weapon/paper/terrorspiders8
name = "paper - 'Last Words'"
info = {"<b>The Last Words of Nurse Barnes</b><br>
<br>
It is too much. First Phil, then those damn spiders bite Mary too. Heaven help us. <br>
I'll be evacuating as soon as I've grabbed my supplies. I had to pay for those myself. Stupid budget cuts. <br>
The new world they've found for us isn't that hospitable, but at least there are no deadly spid---<br>
(the writing trails off, as if the writer was interrupted)<br>
"}
/obj/item/weapon/gun/energy/laser/awaymission_aeg
name = "Wireless Energy Gun"
desc = "An energy gun that recharges wirelessly during away missions. Does not work on the main station."
force = 10
origin_tech = null
selfcharge = 1
var/inawaymission = 1
/obj/item/weapon/gun/energy/laser/awaymission_aeg/process()
var/turf/my_loc = get_turf(src)
if(is_away_level(my_loc.z))
if(inawaymission)
return ..()
if(ismob(loc))
to_chat(loc, "<span class='notice'>Your [src] activates, starting to draw power from a nearby wireless power source.</span>")
inawaymission = 1
else
if(inawaymission)
if(ismob(loc))
to_chat(loc, "<span class='danger'>Your [src] deactivates, as it is out of range from its power source.</span>")
power_supply.charge = 0
inawaymission = 0
update_icon()
/obj/item/weapon/reagent_containers/glass/beaker/terror_black_toxin
name = "beaker 'Black Terror Venom'"
/obj/item/weapon/reagent_containers/glass/beaker/terror_black_toxin/New()
..()
reagents.add_reagent("terror_black_toxin", 50)
update_icon()
/obj/machinery/computer/id_upgrader
name = "ID Upgrade Machine"
icon_state = "guest"
icon_screen = "pass"
var/list/access_to_give = list(access_away01)
var/beenused = 0
var/door_to_open = "UO71_Start"
/obj/machinery/computer/id_upgrader/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/D = I
if(!access_to_give.len)
to_chat(user, "<span class='notice'>This machine appears to be configured incorrectly.</span>")
return
var/did_upgrade = 0
var/list/id_access = D.GetAccess()
for(var/this_access in access_to_give)
if(!(this_access in id_access))
// don't have it - add it
D.access |= this_access
did_upgrade = 1
if(did_upgrade)
to_chat(user, "<span class='notice'>An access type was added to your ID card.</span>")
if(beenused)
return
spawn(1)
beenused = 1
var/unlocked_something = 0
for(var/obj/machinery/door/poddoor/P in airlocks)
if(P.density && P.id_tag == door_to_open && P.z == z)
P.open()
unlocked_something = 1
if(unlocked_something)
to_chat(user, "<span class='danger'>Activating the machine has unlocked a way forward!</span>")
else
to_chat(user, "<span class='notice'>Your ID card already has all the access this machine can give.</span>")
. = 1
+1 -1
View File
@@ -191,7 +191,7 @@ var/list/event_last_fired = list()
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, is_one_shot = 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, list(ASSIGNMENT_SECURITY = 20), is_one_shot = 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1)
)
+10 -9
View File
@@ -1,14 +1,14 @@
/datum/event/spider_terror
announceWhen = 400
announceWhen = 120
var/spawncount = 1
/datum/event/spider_terror/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
announceWhen = rand(announceWhen, announceWhen + 30)
spawncount = 1
/datum/event/spider_infestation/announce()
command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren.ogg')
/datum/event/spider_terror/announce()
command_announcement.Announce("Confirmed outbreak of level 3 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/effects/siren-spooky.ogg')
/datum/event/spider_terror/start()
@@ -17,23 +17,24 @@
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
if(temp_vent.parent.other_atmosmch.len > 50)
vents += temp_vent
var/spider_type
var/infestation_type = pick(1, 2, 3, 4)
var/infestation_type = pick(1, 2, 3, 4, 5)
switch(infestation_type)
if(1)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = pick(2,3)
spawncount = 3
if(2)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 1
spawncount = 2
if(3)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/prince
spawncount = 1
if(4)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
spawncount = 1
if(5)
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/effect/spider/spiderling/terror_spiderling/S = new(vent.loc)
@@ -4,6 +4,13 @@
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
#define TS_AI_AGGRESSIVE 0
#define TS_AI_DEFENSIVE 1
#define TS_DAMAGE_SIMPLE 0
#define TS_DAMAGE_POISON 1
#define TS_DAMAGE_BRUTE 2
#define TS_DESC_RED "Red - Assault"
#define TS_DESC_GRAY "Gray - Ambush"
#define TS_DESC_GREEN "Green - Nurse"
@@ -84,7 +84,7 @@
/mob/living/simple_animal/hostile/poison/terror_spider/proc/Web()
var/turf/mylocation = loc
visible_message("<span class='notice'>[src] begins to secrete a sticky substance.</span>")
if(do_after(src, 40, target = loc))
if(do_after(src, delay_web, target = loc))
if(loc != mylocation)
return
else if(istype(loc, /turf/space))
@@ -112,20 +112,30 @@
if(prob(50))
icon_state = "stickyweb2"
/obj/effect/spider/terrorweb/proc/DeCloakNearby()
for(var/mob/living/simple_animal/hostile/poison/terror_spider/gray/G in view(6,src))
if(!G.ckey && G.stat != DEAD)
G.GrayDeCloak()
G.Aggro()
/obj/effect/spider/terrorweb/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_animal/hostile/poison/terror_spider))
return 1
if(istype(mover, /obj/item/projectile/terrorqueenspit))
return 1
if(isliving(mover))
var/mob/living/M = mover
if(M.lying)
return 1
if(prob(80))
to_chat(mover, "<span class='danger'>You get stuck in [src] for a moment.</span>")
var/mob/living/M = mover
M.Stun(4) // 8 seconds.
M.Weaken(4) // 8 seconds.
DeCloakNearby()
if(iscarbon(mover))
spawn(70)
qdel(src)
if(mover.loc == loc)
qdel(src)
return 1
else
return 0
@@ -188,12 +198,15 @@
if(iscarbon(L))
regen_points += regen_points_per_kill
fed++
visible_message("<span class='danger'>[src] sticks a proboscis into [L] and sucks a viscous substance out.</span>")
to_chat(src, "<span class='notice'>You feel invigorated!</span>")
else
visible_message("<span class='danger'>[src] wraps [L] in a web.</span>")
large_cocoon = 1
last_cocoon_object = 0
L.loc = C
C.pixel_x = L.pixel_x
C.pixel_y = L.pixel_y
visible_message("<span class='danger'>[src] sticks a proboscis into [L] and sucks a viscous substance out.</span>")
break
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
@@ -12,6 +12,7 @@
name = "Black Terror spider"
desc = "An ominous-looking spider, black as the darkest night. It has merciless eyes, and a blood-red hourglass pattern on its back."
spider_role_summary = "Hit-and-run attacker with extremely venomous bite."
ai_target_method = TS_DAMAGE_POISON
icon_state = "terror_widow"
icon_living = "terror_widow"
@@ -37,3 +38,10 @@
else
visible_message("<span class='danger'>[src] bites [target], but cannot inject venom into their [inject_target]!</span>")
L.attack_animal(src)
if(!ckey && (!(target in enemies) || L.reagents.has_reagent("terror_black_toxin", 60)))
step_away(src,L)
step_away(src,L)
LoseTarget()
for(var/i in 0 to 3)
step_away(src, L)
visible_message("<span class='notice'>[src] warily eyes [L] from a distance.</span>")
@@ -0,0 +1,92 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T5 EMPRESS OF TERROR -------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: ruling over planets of uncountable spiders, like Xenomorph Empresses.
// -------------: AI: none - this is strictly adminspawn-only and intended for RP events, coder testing, and teaching people 'how to queen'
// -------------: SPECIAL: Lay Eggs ability that allows laying queen-level eggs.
// -------------: TO FIGHT IT: run away screaming?
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress
name = "Empress of Terror"
desc = "The unholy offspring of spiders, nightmares, and lovecraft fiction."
spider_role_summary = "Adminbus spider"
ai_target_method = TS_DAMAGE_SIMPLE
maxHealth = 1000
health = 1000
melee_damage_lower = 30
melee_damage_upper = 60
move_to_delay = 5
ventcrawler = 1
idle_ventcrawl_chance = 0
ai_playercontrol_allowtype = 0
ai_type = TS_AI_AGGRESSIVE
rapid = 1
canlay = 1000
spider_tier = TS_TIER_5
var/datum/action/innate/terrorspider/queen/empress/empresslings/empresslings_action
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)
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/handle_automated_action()
return
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/NestMode()
..()
queeneggs_action.button.name = "Empress Eggs"
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/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, "<span class='danger'>Cancelled.</span>")
return
switch(eggtype)
if(TS_DESC_RED)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red,numlings,1)
if(TS_DESC_GRAY)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray,numlings,1)
if(TS_DESC_GREEN)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green,numlings,1)
if(TS_DESC_BLACK)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black,numlings,1)
if(TS_DESC_PURPLE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple,numlings,0)
if(TS_DESC_WHITE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white,numlings,0)
if(TS_DESC_PRINCE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince,numlings,1)
if(TS_DESC_MOTHER)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother,numlings,1)
if(TS_DESC_QUEEN)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen,numlings,1)
else
to_chat(src, "<span class='danger'>Unrecognized egg type.</span>")
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/QueenFakeLings()
var/numlings = input("How many?") as null|anything in list(10, 20, 30, 40, 50)
var/sbpc = input("%chance to be stillborn?") as null|anything in list(0, 25, 50, 75, 100)
for(var/i=0, i<numlings, i++)
var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/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, \
/mob/living/simple_animal/hostile/poison/terror_spider/green, \
/mob/living/simple_animal/hostile/poison/terror_spider/white, \
/mob/living/simple_animal/hostile/poison/terror_spider/black)
S.spider_myqueen = spider_myqueen
if(prob(sbpc))
S.stillborn = 1
if(spider_growinstantly)
S.amount_grown = 250
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/proc/EraseBrood()
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
if(T.spider_tier < spider_tier)
T.degenerate = 1
to_chat(T, "<span class='userdanger'>Through the hivemind, the raw power of [src] floods into your body, burning it from the inside out!</span>")
for(var/obj/effect/spider/eggcluster/terror_eggcluster/T in ts_egg_list)
qdel(T)
for(var/obj/effect/spider/spiderling/terror_spiderling/T in ts_spiderling_list)
T.stillborn = 1
to_chat(src, "<span class='userdanger'>Brood will die off shortly.</span>")
@@ -2,24 +2,30 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T1 GRAY TERROR -------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: fast, weak terror spider
// -------------: SPECIAL: silences targets
// -------------: TO FIGHT IT: shoot it!
// -------------: ROLE: ambusher
// -------------: AI: hides in vents, emerges when prey is near to kill it, then hides again. Intended to scare normal crew.
// -------------: SPECIAL: invisible when on top of a vent, emerges when prey approaches or gets trapped in webs. Bite silences targets.
// -------------: TO FIGHT IT: shoot it through a window, or make it regret ambushing you
// -------------: 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."
desc = "An ominous-looking gray spider. It twitches occasionally, always seeming ready to pounce."
spider_role_summary = "Stealth spider that ambushes weak humans from vents."
ai_target_method = TS_DAMAGE_BRUTE
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
maxHealth = 120 // same health as hunter spider, aka, pretty weak.. but its almost invisible.
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 5 // normal speed
regen_points_per_hp = 2 // 50% higher regen speed
move_to_delay = 5 // slightly faster than normal
stat_attack = 1 // ensures they will target people in crit, too!
wander = 0 // wandering defeats the purpose of stealth
idle_vision_range = 3 // very low idle vision range
delay_web = 20 // double speed
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
@@ -35,4 +41,102 @@
visible_message("<span class='danger'>[src] buries grey fangs deep into the [inject_target] of [target]!</span>")
else
visible_message("<span class='danger'>[src] bites [target], but cannot inject venom into their [inject_target]!</span>")
L.attack_animal(src)
L.attack_animal(src)
/mob/living/simple_animal/hostile/poison/terror_spider/gray/adjustBruteLoss(damage)
..(damage)
if(invisibility > 0)
GrayDeCloak()
/mob/living/simple_animal/hostile/poison/terror_spider/gray/adjustFireLoss(damage)
..(damage)
if(invisibility > 0)
GrayDeCloak()
/mob/living/simple_animal/hostile/poison/terror_spider/gray/Aggro()
GrayDeCloak()
..()
/mob/living/simple_animal/hostile/poison/terror_spider/gray/AttackingTarget()
if(invisibility > 0)
GrayDeCloak()
else
..()
/mob/living/simple_animal/hostile/poison/terror_spider/proc/GrayCloak()
visible_message("<span class='notice'>[src] hides in the vent.</span>")
invisibility = SEE_INVISIBLE_LEVEL_ONE
icon_state = "terror_gray_cloaked"
icon_living = "terror_gray_cloaked"
if(!ckey)
vision_range = 3
idle_vision_range = 3
// Bugged, does not work yet. Also spams webs. Also doesn't look great. But... planned.
move_to_delay = 15 // while invisible, slow.
/mob/living/simple_animal/hostile/poison/terror_spider/proc/GrayDeCloak()
invisibility = 0
icon_state = "terror_gray"
icon_living = "terror_gray"
vision_range = 9
idle_vision_range = 9
move_to_delay = 5
prob_ai_hides_in_vents = 10
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_special_action()
if(prob(prob_ai_hides_in_vents))
var/obj/machinery/atmospherics/unary/vent_pump/e = locate() in get_turf(src)
if(e)
if(!e.welded || spider_awaymission)
if(invisibility != SEE_INVISIBLE_LEVEL_ONE) // aka: 35. ghosts have 15 with no darkness, 60 with darkness. Weird...
var/list/g_turfs_webbed = ListWebbedTurfs()
var/webcount = g_turfs_webbed.len
if(webcount >= 4)
// if there are already at least 4 webs around us, then we have a good web setup already. Cloak.
GrayCloak()
// I wonder if we should settle down here forever?
var/foundqueen = 0
for(var/mob/living/H in view(src, 10))
if(istype(H, /mob/living/simple_animal/hostile/poison/terror_spider/queen))
foundqueen = 1
break
if(!foundqueen)
var/list/g_turfs_visible = ListVisibleTurfs()
if(g_turfs_visible.len >= 12)
// So long as the room isn't tiny, and it has no queen in it, sure, settle there
// since we are settled now, disable most AI behaviors so we don't waste CPU.
ai_ventcrawls = 0
ai_spins_webs = 0
ai_break_lights = 0
prob_ai_hides_in_vents = 3
visible_message("<span class='notice'>[src] finishes setting up its trap in [get_area(src)].</span>")
else
var/list/g_turfs_valid = ListValidTurfs()
var/turfcount = g_turfs_valid.len
if(turfcount == 0)
// if there is literally nowhere else we could put a web, cloak.
GrayCloak()
else
// otherwise, pick one of the valid turfs with no web to create a web there.
new /obj/effect/spider/terrorweb(pick(g_turfs_valid))
visible_message("<span class='notice'>[src] spins a web.</span>")
else
if(invisibility == SEE_INVISIBLE_LEVEL_ONE)
// if our vent is welded, decloak
GrayDeCloak()
else
if(invisibility == SEE_INVISIBLE_LEVEL_ONE)
// if there is no vent under us, and we are cloaked, decloak
GrayDeCloak()
var/vdistance = 99
var/temp_vent = null
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
if(get_dist(src,v) < vdistance)
temp_vent = v
vdistance = get_dist(src,v)
if(temp_vent)
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
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T1 GREEN TERROR ------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: reproduction
// -------------: AI: after it kills you, it webs you and lays new terror eggs on your body
// -------------: SPECIAL: can also create webs, web normal objects, etc
// -------------: TO FIGHT IT: kill it however you like - just don't die to it!
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Green Terror spider"
desc = "An ominous-looking green spider. It has a small egg-sac attached to it, and dried blood stains on its carapace."
spider_role_summary = "Average melee spider that webs its victims and lays more spider eggs"
ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_green"
icon_living = "terror_green"
icon_dead = "terror_green_dead"
@@ -20,7 +21,6 @@
melee_damage_lower = 10
melee_damage_upper = 20
var/feedings_to_lay = 2
var/datum/action/innate/terrorspider/greeneggs/greeneggs_action
@@ -34,7 +34,7 @@
if(E)
to_chat(src, "<span class='notice'>There is already a cluster of eggs here!</span>")
else if(fed < feedings_to_lay)
to_chat(src, "<span class='warning'>You must wrap more prey before you can do this!</span>")
to_chat(src, "<span class='warning'>You must wrap more humanoid prey before you can do this!</span>")
else
visible_message("<span class='notice'>[src] begins to lay a cluster of eggs.</span>")
if(prob(33))
@@ -45,6 +45,43 @@
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 1, 1)
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("<span class='notice'>[src] moves towards [cocoon_target] to cocoon it.</span>")
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/weapon/paper))
cocoon_target = O
stop_automated_movement = 1
spider_steps_taken = 0
return
/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
@@ -18,6 +18,21 @@
hsline += " AI "
to_chat(src,hsline)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/SetHiveCommand(set_ai, set_ventcrawl)
var/numspiders = 0
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
if(spider_awaymission && !T.spider_awaymission)
continue
else if(!spider_awaymission && T.spider_awaymission)
continue
numspiders += 1
if(spider_tier >= T.spider_tier)
if(T.ai_type != set_ai)
T.ai_type = set_ai
if(T.idle_ventcrawl_chance != set_ventcrawl)
T.idle_ventcrawl_chance = set_ventcrawl
return numspiders
/mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpiders()
var/numspiders = 0
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
@@ -3,6 +3,7 @@
// ----------------- 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.
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
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."
ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_gray2"
icon_living = "terror_gray2"
icon_dead = "terror_gray2_dead"
@@ -20,10 +21,9 @@
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 5
idle_ventcrawl_chance = 5
spider_tier = TS_TIER_3
spider_opens_doors = 2
var/canspawn = 1
@@ -37,6 +37,7 @@
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.amount_grown = 50 // double speed growth
visible_message("<span class='userdanger'>[src] breaks apart, the many spiders on its back scurrying everywhere!</span>")
degenerate = 1
..()
@@ -12,26 +12,23 @@
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 = "Miniboss terror spider. Lightning bruiser."
ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_allblack"
icon_living = "terror_allblack"
icon_dead = "terror_allblack_dead"
maxHealth = 600 // 30 laser shots
health = 600
regen_points_per_hp = 6 // double the normal - IE halved regen speed
melee_damage_lower = 20
melee_damage_upper = 30
move_to_delay = 4 // faster than normal
ventcrawler = 0
ai_ventcrawls = 0
environment_smash = 3
loot = list(/obj/item/clothing/accessory/medal)
idle_ventcrawl_chance = 0
spider_tier = TS_TIER_3
spider_opens_doors = 2
var/datum/action/innate/terrorspider/princesmash/princesmash_action
@@ -40,6 +37,12 @@
princesmash_action = new()
princesmash_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/prince/death(gibbed)
if(!hasdied)
if(spider_uo71)
UnlockBlastDoors("UO71_SciStorage")
..()
/mob/living/simple_animal/hostile/poison/terror_spider/prince/spider_specialattack(mob/living/carbon/human/L)
if(prob(15))
visible_message("<span class='danger'>[src] rams into [L], knocking them to the floor!</span>")
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T2 PURPLE TERROR -----------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: guarding queen nests
// -------------: AI: dies if too far from queen
// -------------: SPECIAL: chance to stun on hit
// -------------: TO FIGHT IT: shoot it from range, bring friends!
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Purple Terror spider"
desc = "An ominous-looking purple spider. It looks about warily, as if waiting for something."
spider_role_summary = "Guards the nest of the Queen of Terror."
ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_purple"
icon_living = "terror_purple"
icon_dead = "terror_purple_dead"
@@ -20,17 +21,28 @@
melee_damage_lower = 15
melee_damage_upper = 25
move_to_delay = 6
spider_tier = TS_TIER_2
spider_opens_doors = 2
ventcrawler = 0
ai_ventcrawls = 0
environment_smash = 3
idle_ventcrawl_chance = 0 // stick to the queen!
var/dcheck_counter = 0
var/queen_visible = 1
var/cycles_noqueen = 0
/mob/living/simple_animal/hostile/poison/terror_spider/purple/death(gibbed)
if(spider_myqueen)
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = spider_myqueen
if(Q.stat != DEAD && !Q.ckey)
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)
visible_message("<span class='notice'>[src] chitters in the direction of [Q]!</span>")
. = ..()
/mob/living/simple_animal/hostile/poison/terror_spider/purple/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(cycles_noqueen < 6 && prob(10))
visible_message("<span class='danger'>[src] rams into [L], knocking them to the floor!</span>")
@@ -3,6 +3,7 @@
// ----------------- TERROR SPIDERS: T4 QUEEN OF TERROR ---------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: gamma-level threat to the whole station, like a blob
// -------------: AI: builds a nest, lays many eggs, attempts to take over the station
// -------------: SPECIAL: spins webs, breaks lights, breaks cameras, webs objects, lays eggs, commands other spiders...
// -------------: TO FIGHT IT: bring an army, and take no prisoners. Mechs and/or decloner guns are a very good idea.
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
@@ -11,7 +12,7 @@
name = "Queen of Terror spider"
desc = "An enormous, terrifying spider. Its egg sac is almost as big as its body, and teeming with spider eggs!"
spider_role_summary = "Commander of the spider forces. Lays eggs, directs the brood."
ai_target_method = TS_DAMAGE_SIMPLE
icon_state = "terror_queen"
icon_living = "terror_queen"
icon_dead = "terror_queen_dead"
@@ -29,22 +30,19 @@
var/neststep = 0
var/hasnested = 0
var/spider_max_per_nest = 20 // above this, queen stops spawning more, and declares war.
var/canlay = 0 // main counter for egg-laying ability! # = num uses, incremented at intervals
var/eggslaid = 0
var/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere
idle_ventcrawl_chance = 0
force_threshold = 18 // outright immune to anything of force under 18, this means welders can't hurt it, only guns can
ranged = 1
retreat_distance = 5
minimum_distance = 5
projectilesound = 'sound/weapons/pierce.ogg'
projectiletype = /obj/item/projectile/terrorqueenspit
spider_tier = TS_TIER_4
spider_opens_doors = 2
loot = list(/obj/item/clothing/accessory/medal)
var/datum/action/innate/terrorspider/queen/queennest/queennest_action
var/datum/action/innate/terrorspider/queen/queensense/queensense_action
var/datum/action/innate/terrorspider/queen/queeneggs/queeneggs_action
@@ -65,10 +63,15 @@
if(.) // if mob is NOT dead
if(ckey && canlay < 12 && hasnested) // max 12 eggs worth stored at any one time, realistically that's tons.
if(world.time > (spider_lastspawn + spider_spawnfrequency))
canlay++
if(eggslaid >= 20)
canlay += 3
else if(eggslaid >= 10)
canlay += 2
else
canlay++
spider_lastspawn = world.time
if(canlay == 1)
to_chat(src, "<span class='notice'>You are able to lay eggs again.</span>")
to_chat(src, "<span class='notice'>You have an egg available to lay.</span>")
else if(canlay == 12)
to_chat(src, "<span class='notice'>You have [canlay] eggs available to lay. You won't grow any more eggs until you lay some of your existing ones.</span>")
else
@@ -76,6 +79,9 @@
/mob/living/simple_animal/hostile/poison/terror_spider/queen/death(gibbed)
if(!hasdied)
SetHiveCommand(0, 15) // Hive becomes very aggressive.
if(spider_uo71)
UnlockBlastDoors("UO71_Caves")
// When a queen dies, so do her player-controlled purple-type guardians. Intended as a motivator for purples to ensure they guard her.
for(var/mob/living/simple_animal/hostile/poison/terror_spider/purple/P in ts_spiderlist)
if(ckey)
@@ -84,6 +90,131 @@
P.degenerate = 1
..()
/mob/living/simple_animal/hostile/poison/terror_spider/queen/Retaliate()
..()
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
T.enemies |= enemies
/mob/living/simple_animal/hostile/poison/terror_spider/queen/handle_automated_action()
..()
if(!stat && !ckey && AIStatus != AI_OFF && !target && !path_to_vent)
switch(neststep)
if(0)
// we have no nest :(
var/ok_to_nest = 1
var/area/new_area = get_area(loc)
if(new_area)
if(findtext(new_area.name, "hall"))
ok_to_nest = 0
// nesting in a hallway would be very stupid - crew would find and kill you almost instantly
var/numhostiles = 0
for(var/mob/living/H in oview(10, src))
if(!istype(H, /mob/living/simple_animal/hostile/poison/terror_spider))
if(H.stat != DEAD)
numhostiles += 1
// nesting RIGHT NEXT TO SOMEONE is even worse
if(numhostiles > 0)
ok_to_nest = 0
var/vdistance = 99
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(10, src))
if(!v.welded)
if(get_dist(src, v) < vdistance)
entry_vent = v
vdistance = get_dist(src, v)
if(!entry_vent)
ok_to_nest = 0
// don't nest somewhere with no vent - your brood won't be able to get out!
if(ok_to_nest && entry_vent)
nest_vent = entry_vent
neststep = 1
visible_message("<span class='danger'>\The [src] settles down, starting to build a nest.</span>")
else if(entry_vent)
if(!path_to_vent)
visible_message("<span class='danger'>\The [src] looks around warily - then seeks a better nesting ground.</span>")
path_to_vent = 1
else
visible_message("<span class='danger'>\The [src] looks around, searching for the vent that should be there, but isn't. A bluespace portal forms on her, and she is gone.</span>")
qdel(src)
new /obj/effect/portal(get_turf(loc))
if(1)
if(world.time > (lastnestsetup + nestfrequency))
lastnestsetup = world.time
neststep = 2
NestMode()
if(2)
if(world.time > (lastnestsetup + nestfrequency))
lastnestsetup = world.time
spider_lastspawn = world.time
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
neststep = 3
if(3)
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/effect/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
spider_lastspawn = world.time
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 0)
neststep = 4
if(4)
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/effect/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
if(!spider_awaymission)
QueenFakeLings()
spider_lastspawn = world.time
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 1)
neststep = 5
if(5)
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/effect/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
if(!spider_awaymission)
QueenFakeLings()
spider_lastspawn = world.time
if(prob(33))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, 2, 1)
else if(prob(50))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 1)
else
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
var/spidercount = CountSpiders()
if(spidercount >= spider_max_per_nest) // station overwhelmed!
neststep = 6
if(6)
if(world.time > (spider_lastspawn + spider_spawnfrequency))
spider_lastspawn = world.time
// go hostile, EXTERMINATE MODE.
SetHiveCommand(0, 15) // AI=0 (attack everyone), ventcrawl=15%/tick
var/numspiders = CountSpiders()
if(numspiders < spider_max_per_nest)
if(prob(33))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, 2, 1)
else if(prob(50))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 0)
else
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
else if(spider_awaymission)
neststep = 7
spider_spawnfrequency = spider_spawnfrequency_stable
// if we're an away mission queen... don't keep spawning spiders at high rates. Away team should have a chance.
if(7)
if(world.time > (spider_lastspawn + spider_spawnfrequency))
spider_lastspawn = world.time
var/numspiders = CountSpiders()
if(numspiders < spider_max_per_nest)
// someone is killing my children...
if(prob(25))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, 2, 1)
else if(prob(33))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, 2, 0)
else if(prob(50))
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, 2, 1)
else
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
neststep = 6
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestMode()
queeneggs_action = new()
queeneggs_action.Grant(src)
@@ -94,6 +225,7 @@
queennest_action.Remove(src)
hasnested = 1
ventcrawler = 0
ai_ventcrawls = 0
environment_smash = 3
DoQueenScreech(8, 100, 8, 100)
MassFlicker()
@@ -159,8 +291,8 @@
if(eggtype == null || numlings == null)
to_chat(src, "<span class='danger'>Cancelled.</span>")
return
//spider_lastspawn = world.time // don't think we actually need this, if queen is laying manually canlay controls her rate.
canlay -= numlings
eggslaid += numlings
if(eggtype == TS_DESC_RED)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings, 1)
else if(eggtype == TS_DESC_GRAY)
@@ -210,5 +342,5 @@
if(L.reagents)
if(L.can_inject(null, 0, "chest", 0))
L.reagents.add_reagent("terror_queen_toxin", 15)
if(!istype(L, /mob/living/simple_animal/hostile/poison/terror_spider))
if(!isterrorspider(L))
L.adjustToxLoss(30)
@@ -12,9 +12,8 @@
/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"
ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_red"
icon_living = "terror_red"
icon_dead = "terror_red_dead"
@@ -14,6 +14,7 @@
faction = list("terrorspiders")
var/spider_myqueen = null
var/use_vents = 1
var/list/enemies = list()
/obj/effect/spider/spiderling/terror_spiderling/New()
..()
@@ -91,6 +92,7 @@
S.faction = faction
S.spider_myqueen = spider_myqueen
S.master_commander = master_commander
S.enemies = enemies
qdel(src)
// --------------------------------------------------------------------------------
@@ -106,6 +108,7 @@
C.faction = faction
C.spider_myqueen = spider_myqueen
C.master_commander = master_commander
C.enemies = enemies
if(spider_growinstantly)
C.amount_grown = 250
C.spider_growinstantly = 1
@@ -122,6 +125,7 @@
var/spiderling_type = null
var/spiderling_number = 1
var/spiderling_ventcrawl = 1
var/list/enemies = list()
/obj/effect/spider/eggcluster/terror_eggcluster/New()
..()
@@ -162,6 +166,7 @@
S.faction = faction
S.spider_myqueen = spider_myqueen
S.master_commander = master_commander
S.enemies = enemies
if(spider_growinstantly)
S.amount_grown = 250
var/rnum = 5 - spiderling_number
@@ -0,0 +1,310 @@
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: TARGETING CODE -----------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/ListTargets()
var/list/targets1 = list()
var/list/targets2 = list()
var/list/targets3 = list()
for(var/mob/living/H in view(src, vision_range))
if(H.stat == DEAD)
continue
if(H.flags & GODMODE)
continue
if(H.stat == UNCONSCIOUS && !stat_attack)
continue
if(ai_type == TS_AI_DEFENSIVE && !(H in enemies))
continue
if(isterrorspider(H))
if(H in enemies)
targets3 += H
continue
if(iscarbon(H))
var/mob/living/carbon/C = H
if(IsInfected(C)) // only target the infected if they're attacking us. Even then, lowest priority.
if(C in enemies)
targets3 += C
continue
else if(C.reagents.has_reagent("terror_black_toxin",60))
// only target those dying of black spider venom if they are close, or our enemy
if(get_dist(src,C) <= 2 || (C in enemies))
targets2 += C
else
// Target prioritization by spider type. BRUTE spiders prioritize lower armor values, POISON spiders prioritize poisonable targets
if(ai_target_method == TS_DAMAGE_BRUTE)
var/theirarmor = C.getarmor(type = "melee")
// Example values: Civilian: 2, Engineer w/ Hardsuit: 10, Sec Officer with armor: 19, HoS: 48, Deathsquad: 80
if(theirarmor < 10)
targets1 += C
else if(C in enemies)
if(theirarmor < 30)
targets2 += C
else
targets3 += C
else
targets3 += C
else if(ai_target_method == TS_DAMAGE_POISON)
if(C.can_inject(null,0,"chest",0))
targets1 += C
else if(C in enemies)
targets2 += C
else
targets3 += C
else
// TS_DAMAGE_SIMPLE
if(C in enemies)
targets2 += C
else
targets3 += C
else
if(istype(H,/mob/living/simple_animal))
var/mob/living/simple_animal/S = H
if(S.force_threshold > melee_damage_upper)
continue
if(H in enemies)
targets2 += H
else
targets3 += H
if(health < maxHealth)
// if we're hurt, and ONLY if we're hurt, do the additional check for mechs/space pods. Save processing time.
for(var/obj/mecha/M in view(src, vision_range))
if(get_dist(M, src) <= 2)
targets2 += M
else
targets3 += M
for(var/obj/spacepod/S in view(src, vision_range))
targets3 += S
if(targets1.len)
return targets1
if(targets2.len)
return targets2
return targets3
/mob/living/simple_animal/hostile/poison/terror_spider/LoseTarget()
if(target && isliving(target))
var/mob/living/T = target
if(T.stat > 0)
killcount++
regen_points += regen_points_per_kill
attackstep = 0
attackcycles = 0
..()
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: AI BEHAVIOR CODE -------------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/handle_automated_action()
if (stat || ckey)
return ..()
if(AIStatus != AI_OFF && !target)
var/my_ventcrawl_freq = freq_ventcrawl_idle
if(ts_count_dead > 0)
if(world.time < (ts_death_last + ts_death_window))
my_ventcrawl_freq = freq_ventcrawl_combat
// First, check for general actions that any spider could take.
if(path_to_vent)
if(entry_vent)
if(spider_steps_taken > spider_max_steps)
path_to_vent = 0
stop_automated_movement = 0
spider_steps_taken = 0
path_to_vent = 0
entry_vent = null
else if(get_dist(src, entry_vent) <= 1)
path_to_vent = 0
stop_automated_movement = 1
spider_steps_taken = 0
spawn(50)
stop_automated_movement = 0
TSVentCrawlRandom(entry_vent)
else
spider_steps_taken++
CreatePath(entry_vent)
step_to(src,entry_vent)
if(spider_debug > 0)
visible_message("<span class='notice'>[src] moves towards the vent [entry_vent].</span>")
else
path_to_vent = 0
else if(ai_break_lights && world.time > (last_break_light + freq_break_light))
last_break_light = world.time
for(var/obj/machinery/light/L in range(1, src))
if(!L.status)
step_to(src,L)
L.on = 1
L.broken()
L.do_attack_animation(src)
visible_message("<span class='danger'>[src] smashes the [L.name].</span>")
break
else if(ai_spins_webs && world.time > (last_spins_webs + freq_spins_webs))
last_spins_webs = world.time
var/obj/effect/spider/terrorweb/T = locate() in get_turf(src)
if(!T)
new /obj/effect/spider/terrorweb(get_turf(src))
visible_message("<span class='notice'>[src] puts up some spider webs.</span>")
else if(ai_ventcrawls && world.time > (last_ventcrawl_time + my_ventcrawl_freq))
if(prob(idle_ventcrawl_chance))
last_ventcrawl_time = world.time
var/vdistance = 99
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(10, src))
if(!v.welded)
if(get_dist(src,v) < vdistance)
entry_vent = v
vdistance = get_dist(src,v)
if(entry_vent)
path_to_vent = 1
else
// If none of the general actions apply, check for class-specific actions.
spider_special_action()
else if(AIStatus != AI_OFF && target)
CreatePath(target)
..()
/mob/living/simple_animal/hostile/poison/terror_spider/adjustBruteLoss(damage)
..(damage)
Retaliate()
/mob/living/simple_animal/hostile/poison/terror_spider/adjustFireLoss(damage)
..(damage)
Retaliate()
/mob/living/simple_animal/hostile/poison/terror_spider/proc/Retaliate()
var/list/around = oview(src, 7)
var/list/ts_nearby = list()
for(var/atom/movable/A in around)
if(A in enemies)
continue
if(isterrorspider(A))
ts_nearby += A
continue
if(isliving(A))
var/mob/living/M = A
if(!("terrorspiders" in M.faction))
enemies |= M
visible_message("<span class='danger'>[src] glares at [M]!</span>")
else if(istype(A, /obj/mecha))
var/obj/mecha/M = A
if(M.occupant)
enemies |= M
enemies |= M.occupant
else if(istype(A, /obj/spacepod))
var/obj/spacepod/M = A
if(M.pilot)
enemies |= M
enemies |= M.pilot
for(var/mob/living/simple_animal/hostile/poison/terror_spider/H in ts_nearby)
var/retaliate_faction_check = 0
for(var/F in faction)
if(F in H.faction)
retaliate_faction_check = 1
break
if(retaliate_faction_check && !attack_same && !H.attack_same)
H.enemies |= enemies
return 0
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: PATHING CODE -----------------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/proc/CreatePath(mygoal)
var/m2 = get_turf(src)
if(m2 == mylocation)
chasecycles++
ClearObstacle(get_turf(mygoal))
if(chasecycles >= 2)
chasecycles = 0
if(spider_opens_doors)
var/tgt_dir = get_dir(src,mygoal)
for(var/obj/machinery/door/airlock/A in view(1, src))
if(A.density)
try_open_airlock(A)
for(var/obj/machinery/door/firedoor/F in view(1, src))
if(tgt_dir == get_dir(src,F) && F.density && !F.welded)
visible_message("<span class='danger'>[src] pries open the firedoor!</span>")
F.open()
else
mylocation = m2
chasecycles = 0
/mob/living/simple_animal/hostile/poison/terror_spider/proc/ClearObstacle(turf/target_turf)
var/list/valid_obstacles = list(/obj/structure/window, /obj/structure/closet, /obj/structure/table, /obj/structure/grille, /obj/structure/rack, /obj/machinery/door/window)
for(var/dir in cardinal) // North, South, East, West
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
if(is_type_in_list(obstacle, valid_obstacles))
obstacle.attack_animal(src)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/TSVentCrawlRandom(/var/entry_vent)
if(entry_vent)
if(get_dist(src, entry_vent) <= 2)
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
vents.Add(temp_vent)
if(!vents.len)
entry_vent = null
return
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
visible_message("<B>[src] scrambles into the ventillation ducts!</B>", "<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
spawn(rand(20,60))
var/original_location = loc
forceMove(exit_vent)
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
forceMove(original_location)
entry_vent = null
return
if(prob(50))
audible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
forceMove(original_location)
entry_vent = null
return
forceMove(exit_vent.loc)
entry_vent = null
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: ENVIRONMENT CODE -------------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListValidTurfs()
var/list/potentials = list()
for(var/turf/simulated/T in oview(3,get_turf(src)))
if(T.density == 0 && get_dist(get_turf(src),T) == 3)
var/obj/effect/spider/terrorweb/W = locate() in T
if(!W)
var/obj/structure/grille/G = locate() in T
if(!G)
var/obj/structure/window/O = locate() in T
if(!O)
potentials += T
return potentials
/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListWebbedTurfs()
var/list/webbed = list()
for(var/turf/simulated/T in oview(3,get_turf(src)))
if(T.density == 0 && get_dist(get_turf(src),T) == 3)
var/obj/effect/spider/terrorweb/W = locate() in T
if(W)
webbed += T
return webbed
/mob/living/simple_animal/hostile/poison/terror_spider/proc/ListVisibleTurfs()
var/list/vturfs = list()
for(var/turf/simulated/T in oview(7,get_turf(src)))
if(T.density == 0)
vturfs += T
return vturfs
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: MISC AI CODE -----------------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/proc/UnlockBlastDoors(target_id_tag)
for(var/obj/machinery/door/poddoor/P in airlocks)
if(P.density && P.id_tag == target_id_tag && P.z == z && !P.operating)
P.open()
@@ -1,4 +1,3 @@
var/global/list/ts_ckey_blacklist = list()
var/global/ts_count_dead = 0
var/global/ts_count_alive_awaymission = 0
@@ -43,6 +42,15 @@ var/global/list/ts_spiderling_list = list()
// Ventcrawling
ventcrawler = 1 // allows player ventcrawling
var/ai_ventcrawls = 1
var/idle_ventcrawl_chance = 3 // default 3% chance to ventcrawl when not in combat to a random exit vent
var/freq_ventcrawl_combat = 1800 // 3 minutes
var/freq_ventcrawl_idle = 9000 // 15 minutes
var/last_ventcrawl_time = -9000 // Last time the spider crawled. Used to prevent excessive crawling. Setting to freq*-1 ensures they can crawl once on spawn.
// AI movement tracking
var/spider_steps_taken = 0 // leave at 0, its a counter for ai steps taken.
var/spider_max_steps = 15 // after we take X turns trying to do something, give up!
// Speech
speak_chance = 0 // quiet but deadly
@@ -71,15 +79,35 @@ var/global/list/ts_spiderling_list = list()
aggro_vision_range = 10
see_in_dark = 10
nightvision = 1
vision_type = new /datum/vision_override/nightvision/thermals/ling_augmented_eyesight
see_invisible = 5
sight = SEE_MOBS
// AI aggression settings
var/ai_type = TS_AI_AGGRESSIVE // 0 = aggressive to everyone, 1 = defends self only
var/ai_target_method = TS_DAMAGE_SIMPLE
// AI player control by ghosts
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/ai_break_lights = 1 // AI lightbreaking behavior
var/freq_break_light = 600
var/last_break_light = 0 // leave this, changed by procs.
var/ai_spins_webs = 1 // AI web-spinning behavior
var/freq_spins_webs = 600
var/last_spins_webs = 0 // leave this, changed by procs.
var/delay_web = 40 // delay between starting to spin web, and finishing
var/freq_cocoon_object = 1200 // two minutes between each attempt
var/last_cocoon_object = 0 // leave this, changed by procs.
var/prob_ai_hides_in_vents = 15 // probabily of a gray spider hiding in a vent
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_uo71 = 0 // if 1, spider is in the UO71 away mission
var/spider_unlock_id_tag = "" // if defined, unlock awaymission blast doors with this tag on death
var/spider_role_summary = "UNDEFINED"
var/spider_placed = 0
@@ -90,16 +118,18 @@ var/global/list/ts_spiderling_list = list()
var/obj/machinery/atmospherics/unary/vent_pump/nest_vent // home vent, usually used by queens
var/fed = 0
var/travelling_in_vent = 0
var/list/enemies = list()
var/path_to_vent = 0
var/killcount = 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
var/hasdied = 0
var/list/spider_special_drops = list()
var/attackstep = 0
var/attackcycles = 0
var/spider_myqueen = null
var/mylocation = null
var/chasecycles = 0
var/last_cocoon_object = 0 // leave this, changed by procs.
var/datum/action/innate/terrorspider/web/web_action
var/datum/action/innate/terrorspider/wrap/wrap_action
@@ -124,13 +154,15 @@ var/global/list/ts_spiderling_list = list()
/mob/living/simple_animal/hostile/poison/terror_spider/AttackingTarget()
if(isterrorspider(target))
if(target in enemies)
enemies -= target
var/mob/living/simple_animal/hostile/poison/terror_spider/T = target
if(T.spider_tier > spider_tier)
visible_message("<span class='notice'>[src] bows in respect for the terrifying presence of [target].</span>")
visible_message("<span class='notice'>[src] cowers before [target].</span>")
else if(T.spider_tier == spider_tier)
visible_message("<span class='notice'>[src] nuzzles [target].</span>")
else if(T.spider_tier < spider_tier && spider_tier >= 4)
visible_message("<span class='notice'>[src] gives [target] a stern look.</span>")
target.attack_animal(src)
else
visible_message("<span class='notice'>[src] harmlessly nuzzles [target].</span>")
T.CheckFaction()
@@ -223,6 +255,15 @@ var/global/list/ts_spiderling_list = list()
if(is_away_level(z))
spider_awaymission = 1
ts_count_alive_awaymission++
if(spider_tier >= 3)
ai_ventcrawls = 0 // means that pre-spawned bosses on away maps won't ventcrawl. Necessary to keep prince/mother in one place.
if(istype(get_area(src), /area/awaymission/UO71)) // if we are playing the away mission with our special spiders...
spider_uo71 = 1
if(world.time < 600)
// these are static spiders, specifically for the UO71 away mission, make them stay in place
ai_ventcrawls = 0
spider_placed = 1
wander = 0
else
ts_count_alive_station++
// after 30 seconds, assuming nobody took control of it yet, offer it to ghosts.
@@ -1,4 +1,3 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T2 WHITE TERROR ------------------------------
// --------------------------------------------------------------------------------
@@ -12,12 +11,12 @@
name = "White Terror spider"
desc = "An ominous-looking white spider, its ghostly eyes and vicious-looking fangs are the stuff of nightmares."
spider_role_summary = "Rare, bite-and-run spider that infects hosts with spiderlings"
ai_target_method = TS_DAMAGE_POISON
icon_state = "terror_white"
icon_living = "terror_white"
icon_dead = "terror_white_dead"
maxHealth = 100
health = 100
maxHealth = 200
health = 200
melee_damage_lower = 5
melee_damage_upper = 15
move_to_delay = 4
@@ -25,6 +24,18 @@
loot = list(/obj/item/clothing/accessory/medal)
/mob/living/simple_animal/hostile/poison/terror_spider/white/LoseTarget()
stop_automated_movement = 0
attackstep = 0
attackcycles = 0
..()
/mob/living/simple_animal/hostile/poison/terror_spider/white/death(gibbed)
if(!hasdied)
if(spider_uo71)
UnlockBlastDoors("UO71_Bridge")
..()
/mob/living/simple_animal/hostile/poison/terror_spider/white/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
@@ -35,6 +46,13 @@
if(!IsInfected(L))
visible_message("<span class='danger'>[src] buries its long fangs deep into the [inject_target] of [L]!</span>")
new /obj/item/organ/internal/body_egg/terror_eggs(L)
if(!ckey)
LoseTarget()
walk_away(src,L,2,1)
else if(prob(25))
visible_message("<span class='danger'>[src] pounces on [L]!</span>")
L.Weaken(5)
L.Stun(5)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/IsInfected(mob/living/carbon/C) // Terror AI requires this
if(C.get_int_organ(/obj/item/organ/internal/body_egg))
+6 -6
View File
@@ -63,19 +63,19 @@
to_chat(owner,"<span class='danger'>Your spider bite wound hurts horribly! </span>")
if(istype(get_area(owner), /area/awaycontent) || istype(get_area(owner), /area/awaymission))
awaymission_infection = 1
if(15) // 30 seconds... enough time for the nerve agent to kick in, the pain to be blocked, and healing to begin
if(15) // 30s... enough time for the nerve agent to kick in, the pain to be blocked, and healing to begin
to_chat(owner,"<span class='notice'>The pain has faded, and stopped bleeding, though the skin around it has turned black.</span>")
owner.adjustBruteLoss(-10)
if(60) // 2 minutes... the point where the venom uses and accellerates the healing process, to feed the eggs
if(30) // 1m... the point where the venom uses and accellerates the healing process, to feed the eggs
to_chat(owner,"<span class='notice'>Your bite wound has completely sealed up, though the skin is still black. You feel significantly better.</span>")
owner.adjustBruteLoss(-20)
if(120) // 4 minutes... where the eggs are developing, and the wound is turning into a hatching site, but invisibly
if(90) // 3m... where the eggs are developing, and the wound is turning into a hatching site, but invisibly
to_chat(owner,"<span class='notice'>The black flesh around your old spider bite wound has started to peel off.</span>")
if(150) // 5 minutes... where the victim realizes something is wrong - this is not a normal wound
if(100) // 3m20s... where the victim realizes something is wrong - this is not a normal wound
to_chat(owner,"<span class='danger'>The black flesh around your spider bite wound has cracked, and started to split open!</span>")
if(165) // 5m 30s
if(110) // 3m40s...
to_chat(owner,"<span class='danger'>The black flesh splits open completely, revealing a cluster of small black oval shapes inside you, shapes that seem to be moving!</span>")
if(180) // 6m
if(120) // 4m...
if(awaymission_infection && is_away_level(owner.z))
// we started in the awaymission, we ended on the station.
// To prevent someone bringing an infection back, we're going to trigger an alternate, equally-bad result here.