Merge pull request #6097 from Kyep/terrorspiders-PR2

Terror Spiders - Part 2
This commit is contained in:
Fox McCloud
2017-02-13 06:27:32 -05:00
committed by GitHub
24 changed files with 1018 additions and 84 deletions
+7
View File
@@ -531,6 +531,13 @@
if(ticker.mode.greyshirts.len)
dat += check_role_table("Greyshirts", ticker.mode.greyshirts)
if(ts_spiderlist.len)
var/list/spider_minds = list()
for(var/mob/living/simple_animal/hostile/poison/terror_spider/S in ts_spiderlist)
if(S.ckey)
spider_minds += S.mind
dat += check_role_table("Terror Spiders", spider_minds)
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=400x500")
else
+2 -1
View File
@@ -191,7 +191,8 @@ 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, "Slaughter Demon", /datum/event/spawn_slaughter, 15, 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, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1)
)
+44
View File
@@ -0,0 +1,44 @@
/datum/event/spider_terror
announceWhen = 400
var/spawncount = 1
/datum/event/spider_terror/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
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/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in all_vent_pumps)
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)
switch(infestation_type)
if(1)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = pick(2,3)
if(2)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 1
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
while(spawncount >= 1 && vents.len)
var/obj/vent = pick(vents)
var/obj/effect/spider/spiderling/terror_spiderling/S = new(vent.loc)
S.name = "evil-looking spiderling"
S.grow_as = spider_type
S.amount_grown = 75
vents -= vent
spawncount--
@@ -4,8 +4,18 @@
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
#define TS_DESC_RED "Red - Assault"
#define TS_DESC_GRAY "Gray - Ambush"
#define TS_DESC_GREEN "Green - Nurse"
#define TS_DESC_WHITE "White - Infect"
#define TS_DESC_BLACK "Black - Poison"
#define TS_DESC_PURPLE "Purple - Guard"
#define TS_DESC_PRINCE "Prince - WAR"
#define TS_DESC_MOTHER "Mother - HORROR"
#define TS_DESC_QUEEN "Queen - LEADER"
#define TS_TIER_1 1
#define TS_TIER_2 2
#define TS_TIER_3 3
#define TS_TIER_4 4
#define TS_TIER_5 5
#define TS_TIER_5 5
@@ -1,4 +1,4 @@
// ---------- ACTIONS FOR ALL SPIDERS
/datum/action/innate/terrorspider/web
name = "Web"
@@ -19,17 +19,83 @@
user.FindWrapTarget()
user.DoWrap()
// ---------- GREEN ACTIONS
/datum/action/innate/terrorspider/greeneggs
name = "Lay Green Eggs"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "eggs"
/datum/action/innate/terrorspider/greeneggs/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/green/user = owner
user.DoLayGreenEggs()
// ---------- PRINCE ACTIONS
/datum/action/innate/terrorspider/princesmash
name = "Smash Welded Vent"
icon_icon = 'icons/atmos/vent_pump.dmi'
button_icon_state = "map_vent"
/datum/action/innate/terrorspider/princesmash/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/prince/user = owner
user.DoPrinceSmash()
// ---------- QUEEN ACTIONS
/datum/action/innate/terrorspider/queen/queennest
name = "Nest"
icon_icon = 'icons/mob/terrorspider.dmi'
button_icon_state = "terror_queen"
/datum/action/innate/terrorspider/queen/queennest/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
user.NestMode()
/datum/action/innate/terrorspider/queen/queensense
name = "Hive Sense"
icon_icon = 'icons/mob/actions.dmi'
button_icon_state = "mindswap"
/datum/action/innate/terrorspider/queen/queensense/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
user.DoHiveSense()
/datum/action/innate/terrorspider/queen/queeneggs
name = "Lay Queen Eggs"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "eggs"
/datum/action/innate/terrorspider/queen/queeneggs/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
user.LayQueenEggs()
/datum/action/innate/terrorspider/queen/queenfakelings
name = "Fake Spiderlings"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "spiderling"
/datum/action/innate/terrorspider/queen/queenfakelings/Activate()
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner
user.QueenFakeLings()
// ---------- WEB
/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))
var/obj/effect/spider/terrorweb/T = locate() in get_turf(src)
if(T)
to_chat(src, "<span class='danger'>There is already a web here.</span>")
if(loc != mylocation)
return
else if(istype(loc, /turf/space))
to_chat(src, "<span class='danger'>Webs cannot be spun in space.</span>")
else
new /obj/effect/spider/terrorweb(loc)
var/obj/effect/spider/terrorweb/T = locate() in get_turf(src)
if(T)
to_chat(src, "<span class='danger'>There is already a web here.</span>")
else
var/obj/effect/spider/terrorweb/W = new /obj/effect/spider/terrorweb(loc)
W.creator_ckey = ckey
/obj/effect/spider/terrorweb
name = "terror web"
@@ -39,23 +105,27 @@
density = 0 // prevents it blocking all movement
health = 20 // two welders, or one laser shot (15 for the normal spider webs)
icon_state = "stickyweb1"
var/creator_ckey = null
/obj/effect/spider/terrorweb/New()
..()
if(prob(50))
icon_state = "stickyweb2"
/obj/effect/spider/terrorweb/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_animal/hostile/poison/terror_spider))
return 1
if(istype(mover, /obj/item/projectile/terrorqueenspit))
return 1
if(isliving(mover))
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.
if(iscarbon(mover))
spawn(70)
qdel(src)
return 1
else
return 0
@@ -63,22 +133,25 @@
return prob(20)
return ..()
/obj/effect/spider/terrorweb/bullet_act(obj/item/projectile/Proj)
if(Proj.damage_type != BRUTE && Proj.damage_type != BURN)
visible_message("<span class='danger'>[src] is undamaged by [Proj]!</span>")
// Webs don't care about disablers, tasers, etc. Or toxin damage. They're organic, but not alive.
return
..()
// ---------- WRAP
/mob/living/simple_animal/hostile/poison/terror_spider/proc/FindWrapTarget()
if(!cocoon_target)
var/list/choices = list()
for(var/mob/living/L in oview(1,src))
if(Adjacent(L))
if(Adjacent(L) && !L.anchored)
if(L.stat == DEAD)
choices += L
for(var/obj/O in oview(1,src))
if(Adjacent(O) && !O.anchored)
if(!istype(O, /obj/effect/spider/terrorweb) && !istype(O, /obj/effect/spider/cocoon))
if(!istype(O, /obj/effect/spider/terrorweb) && !istype(O, /obj/effect/spider/cocoon) && !istype(O, /obj/effect/spider/spiderling/terror_spiderling))
choices += O
if(choices.len)
cocoon_target = input(src,"What do you wish to cocoon?") in null|choices
@@ -87,6 +160,9 @@
/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoWrap()
if(cocoon_target && busy != SPINNING_COCOON)
if(cocoon_target.anchored)
cocoon_target = null
return
busy = SPINNING_COCOON
visible_message("<span class='notice'>[src] begins to secrete a sticky substance around [cocoon_target].</span>")
stop_automated_movement = 1
@@ -125,3 +201,17 @@
busy = 0
stop_automated_movement = 0
/mob/living/simple_animal/hostile/poison/terror_spider/prince/proc/DoPrinceSmash()
for(var/obj/machinery/atmospherics/unary/vent_pump/P in view(1,src))
if(P.welded)
P.welded = 0
P.update_icon()
visible_message("<span class='danger'>[src] smashes the welded cover off [P]!</span>")
return
for(var/obj/machinery/atmospherics/unary/vent_scrubber/C in view(1,src))
if(C.welded)
C.welded = 0
C.update_icon()
visible_message("<span class='danger'>[src] smashes the welded cover off [C]!</span>")
return
to_chat(src, "<span class='danger'>There is no unwelded vent close enough to do this.</span>")
@@ -10,7 +10,7 @@
/mob/living/simple_animal/hostile/poison/terror_spider/black
name = "Black Terror spider"
desc = "An ominous-looking spider, black as the darkest night, and with merciless eyes and a blood-red hourglass pattern on its back."
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."
icon_state = "terror_widow"
@@ -24,14 +24,15 @@
stat_attack = 1 // ensures they will target people in crit, too!
spider_tier = TS_TIER_2
/mob/living/simple_animal/hostile/poison/terror_spider/black/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
return ..()
if(L.reagents.has_reagent("terror_black_toxin", 50))
if(L.reagents.has_reagent("terror_black_toxin", 100))
return ..()
var/inject_target = pick("chest", "head")
if(L.stunned || L.can_inject(null, 0, inject_target, 0))
L.reagents.add_reagent("terror_black_toxin", 15) // inject our special poison
L.reagents.add_reagent("terror_black_toxin", 30) // inject our special poison
visible_message("<span class='danger'>[src] buries its long 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>")
@@ -1,3 +1,4 @@
// Terror Spider, Black, Deadly Venom
/datum/reagent/terror_black_toxin
@@ -8,26 +9,38 @@
metabolization_rate = 0.1
/datum/reagent/terror_black_toxin/on_mob_life(mob/living/M)
if(volume < 15)
// bitten once, die slowly. Easy to survive a single bite - just go to medbay.
// total damage: 2/tick, human health 150 until crit, = 75 ticks, = 150 seconds = 2.5 minutes to get to medbay.
M.adjustToxLoss(2) // same damage/tick as tabun cycle 0 to 60
else if(volume < 30)
// bitten twice, die more quickly, muscle cramps make movement difficult. Call medics immediately.
// total damage: 4, human health 150 until crit, = 37.5 ticks, = 75s = 1m15s until death
M.adjustToxLoss(4)
M.Confused(3)
if(volume < 30)
// bitten once, die very slowly. Easy to survive a single bite - just go to medbay.
// total damage: 1/tick, human health 150 until crit, = 150 ticks, = 300 seconds = 5 minutes to get to medbay.
M.adjustToxLoss(1)
else if(volume < 60)
// bitten twice, die slowly. Get to medbay.
// total damage: 2/tick, human health 150 until crit, = 75 ticks, = 150 seconds = 2.5 minutes to get some medical treatment.
M.adjustToxLoss(2)
M.EyeBlurry(3)
else if(volume < 45)
// bitten thrice, die very quickly, severe muscle cramps make movement very difficult. Even calling for help probably won't save you.
// total damage: 8, human health 150 until crit, = 18.75 ticks, = 37s until death
M.adjustToxLoss(8) // a bit worse than coiine
else if(volume < 90)
// bitten thrice, die quickly, severe muscle cramps make movement very difficult. Even calling for help probably won't save you.
// total damage: 4, human health 150 until crit, = 37.5 ticks, = 75s = 1m15s until death
M.adjustToxLoss(4) // a bit worse than coiine
M.Confused(6)
M.EyeBlurry(6)
else
// bitten 4 or more times, whole body goes into shock/death
// total damage: 12, human health 150 until crit, = 12.5 ticks, = 25s until death
M.adjustToxLoss(12)
// total damage: 8, human health 150 until crit, = 18.75 ticks, = 37s until death
M.adjustToxLoss(8)
M.EyeBlurry(6)
M.Paralyse(5)
..()
// Terror Spider, Queen Toxin
/datum/reagent/terror_queen_toxin
name = "Terror Queen venom"
id = "terror_queen_toxin"
description = "A royally potent venom."
color = "#CF3600"
metabolization_rate = 2
/datum/reagent/terror_queen_toxin/on_mob_life(mob/living/M)
// make them hallucinate a lot, like a changeling sting
M.AdjustHallucinate(50, bound_upper = 400)
@@ -13,15 +13,15 @@
return
var/error_on_humanize = ""
var/humanize_prompt = "Take direct control of [src]?"
humanize_prompt += "Role: [spider_role_summary]"
humanize_prompt += " Role: [spider_role_summary]"
if(user.ckey in ts_ckey_blacklist)
error_on_humanize = "You are not able to control any terror spider this round."
else if(!ai_playercontrol_allowingeneral)
error_on_humanize = "Terror spiders cannot currently be player-controlled."
else if(spider_awaymission)
error_on_humanize = "Terror spiders that are part of an away mission cannot be controlled by ghosts."
else if(!ai_playercontrol_allowtype)
error_on_humanize = "This specific type of terror spider is not player-controllable."
else if(degenerate)
error_on_humanize = "Dying spiders are not player-controllable."
else if(stat == DEAD)
error_on_humanize = "Dead spiders are not player-controllable."
if(jobban_isbanned(user, "Syndicate") || jobban_isbanned(user, "alien"))
@@ -39,5 +39,4 @@
return
key = user.key
for(var/mob/dead/observer/G in player_list)
G.show_message("<i>A ghost has taken control of <b>[src]</b>. ([ghost_follow_link(src, ghost=G)]).</i>")
G.show_message("<i>A ghost has taken control of <b>[src]</b>. ([ghost_follow_link(src, ghost=G)]).</i>")
@@ -18,10 +18,8 @@
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
ventcrawler = 1
move_to_delay = 5 // normal speed
stat_attack = 1 // ensures they will target people in crit, too!
environment_smash = 1
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
@@ -0,0 +1,60 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T1 GREEN TERROR ------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: reproduction
// -------------: 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
/mob/living/simple_animal/hostile/poison/terror_spider/green
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"
icon_state = "terror_green"
icon_living = "terror_green"
icon_dead = "terror_green_dead"
maxHealth = 120
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
var/feedings_to_lay = 2
var/datum/action/innate/terrorspider/greeneggs/greeneggs_action
/mob/living/simple_animal/hostile/poison/terror_spider/green/New()
..()
greeneggs_action = new()
greeneggs_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/green/proc/DoLayGreenEggs()
var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
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>")
else
visible_message("<span class='notice'>[src] begins to lay a cluster of eggs.</span>")
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
/mob/living/simple_animal/hostile/poison/terror_spider/green/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
return
var/inject_target = pick("chest","head")
if(L.stunned || L.can_inject(null,0,inject_target,0))
if(L.eye_blurry < 60)
L.AdjustEyeBlurry(10)
// instead of having a venom that only lasts seconds, we just add the eyeblur directly.
visible_message("<span class='danger'>[src] buries its 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)
@@ -0,0 +1,40 @@
// All terror spider code that relates to queen ruling over a hive
/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoHiveSense()
var/hsline = ""
to_chat(src, "Your Brood: ")
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
if(T.spider_awaymission != spider_awaymission)
continue
hsline = "* [T] in [get_area(T)], "
if(T.stat == DEAD)
hsline += "DEAD"
else
hsline += "health [T.health] / [T.maxHealth], "
if(T.ckey)
hsline += " *Player Controlled* "
else
hsline += " AI "
to_chat(src,hsline)
/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)
if(T.stat != DEAD && !T.spider_placed && spider_awaymission == T.spider_awaymission)
numspiders += 1
return numspiders
/mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpidersType(specific_type)
var/numspiders = 0
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
if(T.stat != DEAD && !T.spider_placed && spider_awaymission == T.spider_awaymission)
if(T.type == specific_type)
numspiders += 1
for(var/obj/effect/spider/eggcluster/terror_eggcluster/E in ts_egg_list)
if(E.spiderling_type == specific_type && E.z == z)
numspiders += E.spiderling_number
for(var/obj/effect/spider/spiderling/terror_spiderling/L in ts_spiderling_list)
if(!L.stillborn && L.grow_as == specific_type && L.z == z)
numspiders += 1
return numspiders
@@ -0,0 +1,46 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T3 MOTHER OF TERROR --------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: living schmuck bait
// -------------: 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
/mob/living/simple_animal/hostile/poison/terror_spider/mother
name = "Mother of Terror spider"
desc = "An enormous spider. Hundreds of tiny spiderlings are crawling all over it. Their beady little eyes all stare at you. The horror!"
spider_role_summary = "Schmuck bait. Extremely weak in combat, but spawns many spiderlings when it dies."
icon_state = "terror_gray2"
icon_living = "terror_gray2"
icon_dead = "terror_gray2_dead"
maxHealth = 50
health = 50
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 5
spider_tier = TS_TIER_3
spider_opens_doors = 2
var/canspawn = 1
/mob/living/simple_animal/hostile/poison/terror_spider/mother/death(gibbed)
if(canspawn)
canspawn = 0
for(var/i in 0 to 30)
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)
if(prob(66))
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)
visible_message("<span class='userdanger'>[src] breaks apart, the many spiders on its back scurrying everywhere!</span>")
degenerate = 1
..()
/mob/living/simple_animal/hostile/poison/terror_spider/mother/Destroy()
canspawn = 0
return ..()
@@ -11,20 +11,34 @@
/mob/living/simple_animal/hostile/poison/terror_spider/prince
name = "Prince of Terror spider"
desc = "An enormous, terrifying spider. It looks like it is judging everything it sees. Its hide seems armored, and it bears the scars of many battles."
spider_role_summary = "Boss-level terror spider. Lightning bruiser. Capable of taking on a squad by itself."
spider_role_summary = "Miniboss terror spider. Lightning bruiser."
icon_state = "terror_allblack"
icon_living = "terror_allblack"
icon_dead = "terror_allblack_dead"
maxHealth = 400 // 20 laser shots.
health = 400
melee_damage_lower = 15
melee_damage_upper = 25
move_to_delay = 5
ventcrawler = 1
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
environment_smash = 3
loot = list(/obj/item/clothing/accessory/medal)
spider_tier = TS_TIER_3
spider_opens_doors = 2
var/datum/action/innate/terrorspider/princesmash/princesmash_action
/mob/living/simple_animal/hostile/poison/terror_spider/prince/New()
..()
princesmash_action = new()
princesmash_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/prince/spider_specialattack(mob/living/carbon/human/L)
if(prob(15))
@@ -0,0 +1,85 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T2 PURPLE TERROR -----------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: guarding queen nests
// -------------: 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
/mob/living/simple_animal/hostile/poison/terror_spider/purple
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."
icon_state = "terror_purple"
icon_living = "terror_purple"
icon_dead = "terror_purple_dead"
maxHealth = 200
health = 200
melee_damage_lower = 15
melee_damage_upper = 25
move_to_delay = 6
spider_tier = TS_TIER_2
spider_opens_doors = 2
ventcrawler = 0
environment_smash = 3
var/dcheck_counter = 0
var/queen_visible = 1
var/cycles_noqueen = 0
/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>")
L.Weaken(5)
L.Stun(5)
else
..()
/mob/living/simple_animal/hostile/poison/terror_spider/purple/Life()
. = ..()
if(.) // if mob is NOT dead
if(!degenerate && spider_myqueen)
if(dcheck_counter >= 10)
dcheck_counter = 0
purple_distance_check()
else
dcheck_counter++
/mob/living/simple_animal/hostile/poison/terror_spider/purple/proc/purple_distance_check()
if(spider_myqueen)
var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = spider_myqueen
if(Q)
if(Q.stat == DEAD)
spider_myqueen = null
degenerate = 1
to_chat(src,"<span class='userdanger'>Your Queen has died! Her power no longer sustains you!</span>")
return
queen_visible = 0
for(var/mob/living/M in view(src, vision_range))
if(M == Q)
queen_visible = 1
break
if(queen_visible)
cycles_noqueen = 0
if(spider_debug)
to_chat(src,"<span class='notice'>Queen visible.</span>")
else
cycles_noqueen++
if(spider_debug)
to_chat(src,"<span class='danger'>Queen NOT visible. Cycles: [cycles_noqueen].</span>")
if(cycles_noqueen == 3)
// one minute without queen sighted
to_chat(src,"<span class='notice'>You wonder where your Queen is.</span>")
else if(cycles_noqueen == 6)
// two minutes without queen sighted
to_chat(src,"<span class='danger'>Without your Queen in sight, you feel yourself getting weaker...</span>")
else if(cycles_noqueen >= 9)
// three minutes without queen sighted, kill them.
degenerate = 1
to_chat(src,"<span class='userdanger'>Your link to your Queen has been broken! Your life force starts to drain away!</span>")
melee_damage_lower = 5
melee_damage_upper = 10
@@ -0,0 +1,214 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T4 QUEEN OF TERROR ---------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: gamma-level threat to the whole station, like a blob
// -------------: 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
/mob/living/simple_animal/hostile/poison/terror_spider/queen
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."
icon_state = "terror_queen"
icon_living = "terror_queen"
icon_dead = "terror_queen_dead"
maxHealth = 200
health = 200
melee_damage_lower = 10
melee_damage_upper = 20
move_to_delay = 15 // yeah, this is very slow, but
ventcrawler = 1
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
var/nestfrequency = 150 // 15 seconds
var/lastnestsetup = 0
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/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere
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
var/datum/action/innate/terrorspider/queen/queenfakelings/queenfakelings_action
/mob/living/simple_animal/hostile/poison/terror_spider/queen/New()
..()
queennest_action = new()
queennest_action.Grant(src)
spider_myqueen = src
if(spider_awaymission)
spider_growinstantly = 1
spider_spawnfrequency = 150
/mob/living/simple_animal/hostile/poison/terror_spider/queen/Life()
. = ..()
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++
spider_lastspawn = world.time
if(canlay == 1)
to_chat(src, "<span class='notice'>You are able to lay eggs again.</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
to_chat(src, "<span class='notice'>You have [canlay] eggs available to lay.</span>")
/mob/living/simple_animal/hostile/poison/terror_spider/queen/death(gibbed)
if(!hasdied)
// 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)
P.visible_message("<span class='danger'>\The [src] writhes in pain!</span>")
to_chat(P,"<span class='userdanger'>\The [src] has died. Without her hivemind link, purple terrors like yourself cannot survive more than a few minutes!</span>")
P.degenerate = 1
..()
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestMode()
queeneggs_action = new()
queeneggs_action.Grant(src)
queenfakelings_action = new()
queenfakelings_action.Grant(src)
queensense_action = new()
queensense_action.Grant(src)
queennest_action.Remove(src)
hasnested = 1
ventcrawler = 0
environment_smash = 3
DoQueenScreech(8, 100, 8, 100)
MassFlicker()
to_chat(src, "<span class='notice'>You have matured to your egglaying stage. You can now smash through walls, and lay eggs, but can no longer ventcrawl.</span>")
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/MassFlicker()
var/list/target_lights = list()
for(var/mob/living/carbon/human/H in player_list)
if(H.z != z)
continue
if(H.stat == DEAD)
continue
for(var/obj/machinery/light/L in orange(7, H))
if(L.on && prob(25))
target_lights += L
for(var/obj/machinery/light/I in target_lights)
I.flicker()
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/LayQueenEggs()
if(!hasnested)
to_chat(src, "<span class='danger'>You must nest before doing this.</span>")
return
if(canlay < 1)
var/remainingtime = round(((spider_lastspawn + spider_spawnfrequency) - world.time) / 10, 1)
if(remainingtime > 0)
to_chat(src, "<span class='danger'>Too soon to attempt that again. Wait another [num2text(remainingtime)] seconds.</span>")
else
to_chat(src, "<span class='danger'>Too soon to attempt that again. Wait just a few more seconds...</span>")
return
var/list/eggtypes = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE)
if(canlay >= 12)
eggtypes |= TS_DESC_MOTHER
eggtypes |= TS_DESC_PRINCE
var num_purples = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/purple)
if(num_purples >= 2)
eggtypes -= TS_DESC_PURPLE
var num_blacks = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/black)
if(num_blacks >= 2)
eggtypes -= TS_DESC_BLACK
var/eggtype = input("What kind of eggs?") as null|anything in eggtypes
if(!(eggtype in eggtypes))
to_chat(src, "<span class='danger'>Unrecognized egg type.</span>")
return 0
if(eggtype == TS_DESC_MOTHER || eggtype == TS_DESC_PRINCE)
if(canlay < 12)
to_chat(src, "<span class='danger'>Insufficient strength. It takes as much effort to lay one of those as it does to lay 12 normal eggs.</span>")
else
if(eggtype == TS_DESC_MOTHER)
canlay -= 12
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, 1, 0)
else if(eggtype == TS_DESC_PRINCE)
canlay -= 12
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, 1, 0)
return
var/numlings = 1
if(eggtype != TS_DESC_PURPLE)
if(canlay >= 5)
numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5)
else if(canlay >= 3)
numlings = input("How many in the batch?") as null|anything in list(1, 2, 3)
else if(canlay == 2)
numlings = input("How many in the batch?") as null|anything in list(1, 2)
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
if(eggtype == TS_DESC_RED)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings, 1)
else if(eggtype == TS_DESC_GRAY)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings, 1)
else if(eggtype == TS_DESC_GREEN)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings, 1)
else if(eggtype == TS_DESC_BLACK)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings, 1)
else if(eggtype == TS_DESC_PURPLE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings, 0)
else
to_chat(src, "<span class='danger'>Unrecognized egg type.</span>")
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/DoQueenScreech(light_range, light_chance, camera_range, camera_chance)
visible_message("<span class='userdanger'>\The [src] emits a bone-chilling shriek!</span>")
for(var/obj/machinery/light/L in orange(light_range, src))
if(L.on && prob(light_chance))
L.broken()
for(var/obj/machinery/camera/C in orange(camera_range, src))
if(C.status && prob(camera_chance))
C.toggle_cam(src, 0)
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/QueenFakeLings()
if(spider_can_fakelings)
spider_can_fakelings--
var/numlings = 15
for(var/i in 1 to numlings)
var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/spider/spiderling/terror_spiderling(get_turf(src))
S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S.stillborn = 1
S.name = "Evil-Looking Spiderling"
S.desc = "It moves very quickly, hisses loudly for its size... and has disproportionately large fangs. Hopefully it does not grow up..."
if(!spider_can_fakelings)
queenfakelings_action.Remove(src)
else
to_chat(src, "<span class='danger'>You have run out of uses of this ability.</span>")
/obj/item/projectile/terrorqueenspit
name = "poisonous spit"
damage = 0
icon_state = "toxin"
damage_type = TOX
/obj/item/projectile/terrorqueenspit/on_hit(mob/living/carbon/target)
if(ismob(target))
var/mob/living/L = target
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))
L.adjustToxLoss(30)
@@ -57,4 +57,4 @@
visible_message("<span class='notice'>[src] retracts its fangs a little.</span>")
melee_damage_lower = melee_damage_lower_rage0
melee_damage_upper = melee_damage_upper_rage0
..()
..()
@@ -0,0 +1,172 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: SPIDERLINGS (USED BY GREEN, WHITE, QUEEN AND MOTHER TYPES)
// --------------------------------------------------------------------------------
/obj/effect/spider/spiderling/terror_spiderling
name = "spiderling"
desc = "A fast-moving tiny spider, prone to making aggressive hissing sounds. Hope it doesn't grow up."
icon_state = "spiderling"
anchored = 0
layer = 2.75
health = 3
var/stillborn = 0
faction = list("terrorspiders")
var/spider_myqueen = null
var/use_vents = 1
/obj/effect/spider/spiderling/terror_spiderling/New()
..()
ts_spiderling_list += src
/obj/effect/spider/spiderling/terror_spiderling/Destroy()
ts_spiderling_list -= src
return ..()
/obj/effect/spider/spiderling/terror_spiderling/Bump(atom/A)
if(istype(A, /obj/structure/table))
forceMove(A.loc)
else if(istype(A, /obj/machinery/recharge_station))
qdel(src)
else
..()
/obj/effect/spider/spiderling/terror_spiderling/process()
if(travelling_in_vent)
if(isturf(loc))
travelling_in_vent = 0
entry_vent = null
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
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)
if(prob(50))
visible_message("<B>[src] scrambles into the ventillation ducts!</B>", "<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
var/original_location = loc
spawn(rand(20,60))
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)
else if(prob(33))
var/list/nearby = oview(10, src)
if(nearby.len)
var/target_atom = pick(nearby)
walk_to(src, target_atom)
else if(prob(10) && use_vents)
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
walk_to(src, entry_vent, 1)
break
if(isturf(loc))
amount_grown += rand(0,2)
if(amount_grown >= 100)
if(stillborn)
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.master_commander = master_commander
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)
stop_automated_movement = 1
var/obj/effect/spider/eggcluster/terror_eggcluster/C = new /obj/effect/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.master_commander = master_commander
if(spider_growinstantly)
C.amount_grown = 250
C.spider_growinstantly = 1
spawn(10)
stop_automated_movement = 0
/obj/effect/spider/eggcluster/terror_eggcluster
name = "terror egg cluster"
desc = "A cluster of tiny spider eggs. They pulse with a strong inner life, and appear to have sharp thorns on the sides."
icon_state = "eggs"
var/spider_growinstantly = 0
faction = list("terrorspiders")
var/spider_myqueen = null
var/spiderling_type = null
var/spiderling_number = 1
var/spiderling_ventcrawl = 1
/obj/effect/spider/eggcluster/terror_eggcluster/New()
..()
ts_egg_list += src
spawn(50)
if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/red)
name = "red terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/gray)
name = "gray terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/green)
name = "green terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/black)
name = "black terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/purple)
name = "purple terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/white)
name = "white terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/mother)
name = "mother of terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/prince)
name = "prince of terror eggs"
else if(spiderling_type == /mob/living/simple_animal/hostile/poison/terror_spider/queen)
name = "queen of terror eggs"
/obj/effect/spider/eggcluster/terror_eggcluster/Destroy()
ts_egg_list -= src
return ..()
/obj/effect/spider/eggcluster/terror_eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = spiderling_number
for(var/i=0, i<num, i++)
var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/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.master_commander = master_commander
if(spider_growinstantly)
S.amount_grown = 250
var/rnum = 5 - spiderling_number
for(var/i=0, i<rnum, i++)
var/obj/effect/spider/spiderling/terror_spiderling/S = new /obj/effect/spider/spiderling/terror_spiderling(get_turf(src))
S.stillborn = 1
// every set of eggs always spawn 5 spiderlings, but most are decoys
qdel(src)
@@ -6,6 +6,8 @@ var/global/ts_count_alive_station = 0
var/global/ts_death_last = 0
var/global/ts_death_window = 9000 // 15 minutes
var/global/list/ts_spiderlist = list()
var/global/list/ts_egg_list = list()
var/global/list/ts_spiderling_list = list()
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: DEFAULTS ---------------------------------
@@ -62,6 +64,8 @@ var/global/list/ts_spiderlist = list()
// desired: 20hp/minute unmolested, 40hp/min on food boost, assuming one tick every 2 seconds
// 90/kill means bonus 30hp/kill regenerated over the next 1-2 minutes
var/degenerate = 0 // if 1, they slowly degen until they all die off. Used by high-level abilities only.
// Vision
idle_vision_range = 10
aggro_vision_range = 10
@@ -70,8 +74,7 @@ var/global/list/ts_spiderlist = list()
vision_type = new /datum/vision_override/nightvision/thermals/ling_augmented_eyesight
see_invisible = 5
// player control by ghosts
var/ai_playercontrol_allowingeneral = 1 // if 0, no spiders are player controllable. Default set in code, can be changed by queens.
// 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/spider_opens_doors = 1 // all spiders can open firedoors (they have no security). 1 = can open depowered doors. 2 = can open powered doors
@@ -81,47 +84,46 @@ var/global/list/ts_spiderlist = list()
var/spider_placed = 0
// AI variables designed for use in procs
var/atom/cocoon_target // for queen and nurse
var/atom/movable/cocoon_target // for queen and nurse
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent // nearby vent they are going to try to get to, and enter
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent // remote vent they intend to come out of
var/obj/machinery/atmospherics/unary/vent_pump/nest_vent // home vent, usually used by queens
var/fed = 0
var/travelling_in_vent = 0
var/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, 5 for empress.
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/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/killcount = 0
// Breathing, Pressure & Fire
// - No breathing / cannot be suffocated (spiders can hold their breath, look it up)
// - No pressure damage either - they have effectively exoskeletons
// - HOWEVER they can be burned to death!
// - Normal SPACE spiders should probably be immune to SPACE too, but meh, we try to leave the base spiders alone.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
heat_damage_per_tick = 5 //amount of damage applied if animal's body temperature is higher than maxbodytemp
// DEBUG OPTIONS & COMMANDS
var/spider_debug = 0
var/datum/action/innate/terrorspider/web/web_action
var/datum/action/innate/terrorspider/wrap/wrap_action
// Breathing - require some oxygen, and no toxins, but take little damage from this requirement not being met (they can hold their breath)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 1
// Temperature - can freeze in space and cook in plasma, but it takes extreme temperatures to do this.
minbodytemp = 100
maxbodytemp = 500
heat_damage_per_tick = 3
// DEBUG OPTIONS & COMMANDS
var/spider_growinstantly = 0 // DEBUG OPTION, DO NOT ENABLE THIS ON LIVE. IT IS USED TO TEST NEST GROWTH/SETUP AI.
var/spider_debug = 0
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: SHARED ATTACK CODE -----------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/AttackingTarget()
if(istype(target, /mob/living/simple_animal/hostile/poison/terror_spider))
if(isterrorspider(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>")
@@ -163,22 +165,21 @@ var/global/list/ts_spiderlist = list()
spider_specialattack(G,can_poison)
else
G.attack_animal(src)
else if(istype(target, /obj/structure/alien/resin))
var/obj/structure/alien/resin/E = target
do_attack_animation(E)
E.health -= rand(melee_damage_lower, melee_damage_upper)
E.healthcheck()
else
target.attack_animal(src)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_specialattack(mob/living/carbon/human/L, var/poisonable)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_specialattack(mob/living/carbon/human/L, poisonable)
L.attack_animal(src)
// --------------------------------------------------------------------------------
// --------------------- TERROR SPIDERS: PROC OVERRIDES ---------------------------
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/examine(mob/user)
..()
var/list/msgs = list()
@@ -195,18 +196,20 @@ var/global/list/ts_spiderlist = list()
msgs += "<span class='warning'>It has many injuries.</span>"
else if(health > (maxHealth*0.25))
msgs += "<span class='warning'>It is barely clinging on to life!</span>"
if(degenerate)
msgs += "<span class='warning'>It appears to be dying.</span>"
else if(health < maxHealth && regen_points > regen_points_per_kill)
msgs += "<span class='notice'>It appears to be regenerating quickly.</span>"
if(killcount >= 1)
msgs += "<span class='warning'>It has blood dribbling from its mouth.</span>"
to_chat(usr,msgs.Join("<BR>"))
/mob/living/simple_animal/hostile/poison/terror_spider/New()
..()
ts_spiderlist += src
add_language("Spider Hivemind")
add_language("Galactic Common")
if(spider_tier >= TS_TIER_2)
add_language("Galactic Common")
default_language = all_languages["Spider Hivemind"]
web_action = new()
@@ -215,6 +218,7 @@ var/global/list/ts_spiderlist = list()
wrap_action.Grant(src)
name += " ([rand(1, 1000)])"
real_name = name
msg_terrorspiders("[src] has grown in [get_area(src)].")
if(is_away_level(z))
spider_awaymission = 1
@@ -233,7 +237,7 @@ var/global/list/ts_spiderlist = list()
if(ckey)
var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state)
notify_ghosts("[src] has appeared in [get_area(src)]. (already player-controlled)", source = src, alert_overlay = alert_overlay)
else if(ai_playercontrol_allowingeneral && ai_playercontrol_allowtype)
else if(ai_playercontrol_allowtype)
var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state)
notify_ghosts("[src] has appeared in [get_area(src)].", enter_link = "<a href=?src=[UID()];activate=1>(Click to control)</a>", source = src, alert_overlay = alert_overlay, action = NOTIFY_ATTACK)
@@ -243,13 +247,15 @@ var/global/list/ts_spiderlist = list()
return ..()
/mob/living/simple_animal/hostile/poison/terror_spider/Life()
..()
if(stat == DEAD)
. = ..()
if(!.) // if mob is dead
if(prob(2))
// 2% chance every cycle to decompose
visible_message("<span class='notice'>\The dead body of the [src] decomposes!</span>")
gib()
else
if(degenerate > 0)
adjustToxLoss(rand(1,10))
if(regen_points < regen_points_max)
regen_points += regen_points_per_tick
if((bruteloss > 0) || (fireloss > 0))
@@ -263,9 +269,6 @@ var/global/list/ts_spiderlist = list()
if(prob(5))
CheckFaction()
/mob/living/simple_animal/hostile/poison/terror_spider/proc/handle_dying()
if(!hasdied)
hasdied = 1
@@ -282,7 +285,6 @@ var/global/list/ts_spiderlist = list()
handle_dying()
..()
/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_special_action()
return
@@ -0,0 +1,42 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T2 WHITE TERROR ------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: stealthy reproduction
// -------------: AI: injects a venom that makes you grow spiders in your body, then retreats
// -------------: SPECIAL: stuns you on first attack - vulnerable to groups while it does this
// -------------: TO FIGHT IT: blast it before it can get away
// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386
/mob/living/simple_animal/hostile/poison/terror_spider/white
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"
icon_state = "terror_white"
icon_living = "terror_white"
icon_dead = "terror_white_dead"
maxHealth = 100
health = 100
melee_damage_lower = 5
melee_damage_upper = 15
move_to_delay = 4
spider_tier = TS_TIER_2
loot = list(/obj/item/clothing/accessory/medal)
/mob/living/simple_animal/hostile/poison/terror_spider/white/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
return
var/inject_target = pick("chest","head")
L.attack_animal(src)
if(L.stunned || L.paralysis || L.can_inject(null,0,inject_target,0))
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)
/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))
return 1
return 0
+3
View File
@@ -617,3 +617,6 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
return FALSE
// Cast to 1/0
return !!(client.prefs.toggles & toggleflag)
#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
+82
View File
@@ -1,3 +1,6 @@
// Traitor-only space spider eggs
/obj/item/organ/internal/body_egg/spider_eggs
name = "spider eggs"
icon = 'icons/effects/effects.dmi'
@@ -34,3 +37,82 @@
M.reagents.del_reagent("spidereggs") //purge all remaining spider eggs reagent if caught, in time.
qdel(src) //We don't want people re-implanting these for near instant gibbings.
return null
// Terror Spiders - white spider infection
/obj/item/organ/internal/body_egg/terror_eggs
name = "terror eggs"
icon = 'icons/effects/effects.dmi'
icon_state = "eggs"
var/current_cycle = 0
var/awaymission_infection = 0
var/alternate_ending = 0
/obj/item/organ/internal/body_egg/terror_eggs/on_life()
current_cycle += 1
if(owner.health < -25)
to_chat(owner,"<span class='notice'>You feel a strange, blissful senstation.</span>")
owner.adjustBruteLoss(-5)
owner.adjustFireLoss(-5)
owner.adjustToxLoss(-5)
// the spider eggs secrete stimulants to keep their host alive until they hatch
switch(current_cycle)
if(1) // immediately
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
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
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
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
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
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(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.
// Actually, let's make it slightly worse... just to discourage people from bringing back infections.
alternate_ending = 1
to_chat(owner,"<span class='danger'>The shapes extend tendrils out of your wound... no... those are legs! SPIDER LEGS! You have spiderlings growing inside you! You scratch at the wound, but it just aggrivates them - they swarm out of the wound, biting you all over!</span>")
owner.visible_message("<span class='danger'>[owner] flails around on the floor as spiderlings erupt from their skin and swarm all over them! </span>")
owner.Stun(20)
owner.Weaken(20)
// yes, this is a long stun - that's intentional. Gotta give the spiderlings time to escape.
var/obj/effect/spider/spiderling/terror_spiderling/S1 = new(get_turf(owner))
S1.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S1.name = "red spiderling"
if(prob(50))
S1.stillborn = 1
var/obj/effect/spider/spiderling/terror_spiderling/S2 = new(get_turf(owner))
S2.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/gray
S2.name = "gray spiderling"
if(prob(50))
S2.stillborn = 1
var/obj/effect/spider/spiderling/terror_spiderling/S3 = new(get_turf(owner))
S3.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/green
S3.name = "green spiderling"
if(prob(50))
S3.stillborn = 1
if(alternate_ending)
S1.stillborn = 1
S2.stillborn = 1
S3.stillborn = 1
owner.gib()
else
owner.adjustToxLoss(rand(100,180)) // normal case, range: 100-180, average 140, almost crit (150).
if(190) // 6m 30s
to_chat(owner,"<span class='danger'>The spiderlings are gone. Your wound, though, looks worse than ever. Remnants of tiny spider eggs, and dead spiders, inside your flesh. Disgusting.</span>")
qdel(src)
/obj/item/organ/internal/body_egg/terror_eggs/remove(var/mob/living/carbon/M, var/special = 0)
..()
qdel(src) // prevent people re-implanting them into others
return null