Merge pull request #8678 from Kyep/ts_tunneler

Terror Spider Update, Brown Terrors
This commit is contained in:
Fox McCloud
2018-04-08 01:38:34 -04:00
committed by GitHub
16 changed files with 171 additions and 123 deletions
+2 -3
View File
@@ -22,7 +22,7 @@
switch(infestation_type)
if(1)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = 4
spawncount = 5
if(2)
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
spawncount = 2
@@ -38,8 +38,7 @@
while(spawncount >= 1 && vents.len)
var/obj/vent = pick(vents)
var/obj/structure/spider/spiderling/terror_spiderling/S = new(vent.loc)
S.name = "evil-looking spiderling"
S.grow_as = spider_type
S.amount_grown = 75
S.amount_grown = 90
vents -= vent
spawncount--
@@ -17,6 +17,7 @@
#define TS_DESC_WHITE "White - Infect"
#define TS_DESC_BLACK "Black - Poison"
#define TS_DESC_PURPLE "Purple - Guard"
#define TS_DESC_BROWN "Brown - Breacher"
#define TS_DESC_PRINCE "Prince - WAR"
#define TS_DESC_MOTHER "Mother - HORROR"
#define TS_DESC_QUEEN "Queen - LEADER"
@@ -121,6 +121,7 @@
if(thick)
W.opacity = 1
W.name = "thick terror web"
W.health = W.health * 2
if(web_infects)
W.infectious = 1
W.name = "sharp terror web"
@@ -251,17 +252,32 @@
stop_automated_movement = 0
/mob/living/simple_animal/hostile/poison/terror_spider/proc/DoVentSmash()
var/valid_target = FALSE
for(var/obj/machinery/atmospherics/unary/vent_pump/P in range(1, get_turf(src)))
if(P.welded)
valid_target = TRUE
for(var/obj/machinery/atmospherics/unary/vent_scrubber/C in range(1, get_turf(src)))
if(C.welded)
valid_target = TRUE
if(!valid_target)
to_chat(src, "<span class='warning'>No welded vent or scrubber nearby!</span>")
return
playsound(get_turf(src), 'sound/machines/airlock_alien_prying.ogg', 50, 0)
if(do_after(src, 40, target = loc))
for(var/obj/machinery/atmospherics/unary/vent_pump/P in view(1, src))
for(var/obj/machinery/atmospherics/unary/vent_pump/P in range(1, get_turf(src)))
if(P.welded)
P.welded = 0
P.update_icon()
P.update_pipe_image()
forceMove(P.loc)
P.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))
for(var/obj/machinery/atmospherics/unary/vent_scrubber/C in range(1, get_turf(src)))
if(C.welded)
C.welded = 0
C.update_icon()
C.update_pipe_image()
forceMove(C.loc)
C.visible_message("<span class='danger'>[src] smashes the welded cover off [C]!</span>")
return
to_chat(src, "<span class='danger'>There is no welded vent or scrubber close enough to do this.</span>")
@@ -39,9 +39,8 @@
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)
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>")
step_away(src, L)
visible_message("<span class='notice'>[src] jumps away from [L]!</span>")
@@ -0,0 +1,34 @@
// --------------------------------------------------------------------------------
// ----------------- TERROR SPIDERS: T2 BROWN TERROR ------------------------------
// --------------------------------------------------------------------------------
// -------------: ROLE: breaking vents
// -------------: AI: ventcrawls a lot, breaks open vents
// -------------: SPECIAL: ventsmash
// -------------: TO FIGHT IT: blast it before it can get away!
// -------------: SPRITES FROM: IK3I
/mob/living/simple_animal/hostile/poison/terror_spider/brown
name = "Brown Terror spider"
desc = "An ominous-looking spider, colored brown like the dirt it crawled out of. Its forearms have sharp digging claws."
spider_role_summary = "Vent-breaking spider that breaches into new areas."
ai_target_method = TS_DAMAGE_BRUTE
icon_state = "terror_brown"
icon_living = "terror_brown"
icon_dead = "terror_brown_dead"
maxHealth = 120 // Low
health = 120
melee_damage_lower = 20
melee_damage_upper = 30
move_to_delay = 20 // Slow.
spider_opens_doors = 2 // Breach specialist.
environment_smash = ENVIRONMENT_SMASH_RWALLS // Breaks anything.
spider_tier = TS_TIER_2
ai_ventbreaker = 1
freq_ventcrawl_combat = 600 // Ventcrawls very frequently, breaking open vents as it goes.
freq_ventcrawl_idle = 1800
var/datum/action/innate/terrorspider/ventsmash/ventsmash_action
/mob/living/simple_animal/hostile/poison/terror_spider/brown/New()
..()
ventsmash_action = new()
ventsmash_action.Grant(src)
@@ -29,19 +29,16 @@
/mob/living/simple_animal/hostile/poison/terror_spider/gray/spider_specialattack(mob/living/carbon/human/L, poisonable)
if(!poisonable)
..()
return
if(L.silent >= 10)
L.attack_animal(src)
var/obj/structure/spider/terrorweb/W = locate() in get_turf(L)
if(W)
melee_damage_lower = initial(melee_damage_lower) * 2
melee_damage_upper = initial(melee_damage_upper) * 2
visible_message("<span class='danger'>[src] savagely mauls [target] while they are stuck in the web!</span>")
else
var/inject_target = pick("chest","head")
if(L.stunned || L.can_inject(null,0,inject_target,0))
L.Silence(20) // instead of having a venom that only lasts seconds, we just add the silence directly.
visible_message("<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)
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
visible_message("<span class='danger'>[src] bites [target]!</span>")
L.attack_animal(src)
/mob/living/simple_animal/hostile/poison/terror_spider/gray/adjustBruteLoss(damage)
..(damage)
@@ -25,7 +25,6 @@
ventcrawler = 0
ai_ventcrawls = 0
environment_smash = ENVIRONMENT_SMASH_RWALLS
loot = list(/obj/item/clothing/accessory/medal)
idle_ventcrawl_chance = 0
spider_tier = TS_TIER_3
spider_opens_doors = 2
@@ -20,7 +20,7 @@
health = 200
melee_damage_lower = 15
melee_damage_upper = 25
move_to_delay = 6
move_to_delay = 4
spider_tier = TS_TIER_2
spider_opens_doors = 2
ventcrawler = 0
@@ -30,7 +30,12 @@
var/dcheck_counter = 0
var/queen_visible = 1
var/cycles_noqueen = 0
var/datum/action/innate/terrorspider/thickweb/thickweb_action
/mob/living/simple_animal/hostile/poison/terror_spider/purple/New()
..()
thickweb_action = new()
thickweb_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/purple/death(gibbed)
if(spider_myqueen)
@@ -43,14 +48,6 @@
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>")
L.Weaken(5)
L.Stun(5)
else
..()
/mob/living/simple_animal/hostile/poison/terror_spider/purple/Life()
. = ..()
if(.) // if mob is NOT dead
@@ -6,7 +6,7 @@
// -------------: 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
// -------------: SPRITES FROM: IK3I
/mob/living/simple_animal/hostile/poison/terror_spider/queen
name = "Queen of Terror spider"
@@ -23,17 +23,6 @@
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 = 25 // above this, AI queens become stable
var/canlay = 4 // 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
@@ -43,7 +32,18 @@
projectiletype = /obj/item/projectile/terrorqueenspit
spider_tier = TS_TIER_4
spider_opens_doors = 2
loot = list(/obj/item/clothing/accessory/medal)
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 = 300 // 30 seconds
var/lastnestsetup = 0
var/neststep = 0
var/hasnested = 0
var/spider_max_per_nest = 25 // above this, AI queens become stable
var/canlay = 4 // 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
var/list/spider_types_standard = list(/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/black)
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
@@ -98,12 +98,18 @@
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/proc/ai_nest_is_full()
var/numspiders = CountSpiders()
if(numspiders >= spider_max_per_nest)
return TRUE
return FALSE
/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 :(
// No nest. If current location is eligible for nesting, advance to step 1.
var/ok_to_nest = 1
var/area/new_area = get_area(loc)
if(new_area)
@@ -140,81 +146,60 @@
qdel(src)
new /obj/effect/portal(get_turf(loc))
if(1)
// No nest, and we should create one. Start NestMode(), then advance to step 2.
if(world.time > (lastnestsetup + nestfrequency))
lastnestsetup = world.time
neststep = 2
NestMode()
if(2)
// Create initial pair of purple nest guards.
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)
// Create spiders (random T1 types) until nest is full.
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/structure/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)
if(ai_nest_is_full())
if(spider_awaymission)
spider_spawnfrequency = spider_spawnfrequency_stable
neststep = 4
else
var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
spider_lastspawn = world.time
DoLayTerrorEggs(pick(spider_types_standard), 2, 0)
if(4)
// Nest should be full. If so, pulse attack command. Otherwise, start replenishing nest (stage 5).
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/structure/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/red, 2, 1)
if(ai_nest_is_full())
SetHiveCommand(0, 15) // AI=0 (attack everyone), ventcrawl=15%/tick
else
neststep = 5
if(5)
// If already replenished, go idle (stage 4). Otherwise, replenish nest.
if(world.time > (spider_lastspawn + spider_spawnfrequency))
if(prob(20))
var/obj/structure/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)
if(ai_nest_is_full())
neststep = 4
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
var/obj/structure/spider/eggcluster/terror_eggcluster/N = locate() in get_turf(src)
if(!N)
spider_lastspawn = world.time
var/num_purple = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/purple)
var/num_white = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/white)
var/num_brown = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/brown)
if(num_purple < 4)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2, 0)
else if(num_white < 2)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, 2, 0)
else if(num_brown < 2)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 2, 0)
else
DoLayTerrorEggs(pick(spider_types_standard), 2, 0)
/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestPrompt()
var/confirm = alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.","Nest?","Yes","No")
@@ -264,13 +249,15 @@
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 >= 4)
eggtypes |= TS_DESC_BROWN
if(canlay >= 12)
eggtypes |= TS_DESC_MOTHER
eggtypes |= TS_DESC_PRINCE
var num_purples = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/purple)
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)
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
@@ -288,6 +275,13 @@
canlay -= 12
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, 1, 0)
return
else if(eggtype == TS_DESC_BROWN)
if(canlay < 4)
to_chat(src, "<span class='danger'>Insufficient strength. It takes as much effort to lay one of those as it does to lay 4 normal eggs.</span>")
else
canlay -= 4
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 1, 0)
return
var/numlings = 1
if(eggtype != TS_DESC_PURPLE)
if(canlay >= 5)
@@ -333,9 +327,7 @@
for(var/i in 1 to numlings)
var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src))
S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red
S.stillborn = TRUE
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..."
S.stillborn = 1
if(!spider_can_fakelings)
queenfakelings_action.Remove(src)
else
@@ -148,7 +148,7 @@
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(!v.welded || ai_ventbreaker)
if(get_dist(src,v) < vdistance)
entry_vent = v
vdistance = get_dist(src,v)
@@ -217,7 +217,8 @@
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)
spawn(0)
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>")
@@ -234,9 +235,13 @@
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)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/TSVentCrawlRandom()
if(entry_vent)
if(get_dist(src, entry_vent) <= 2)
if(ai_ventbreaker && entry_vent.welded)
entry_vent.welded = 0
entry_vent.update_icon()
entry_vent.visible_message("<span class='danger'>[src] smashes the welded cover off [entry_vent]!</span>")
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
vents.Add(temp_vent)
@@ -250,17 +255,23 @@
forceMove(exit_vent)
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
if(!exit_vent || (exit_vent.welded && !ai_ventbreaker))
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)
if(!exit_vent || (exit_vent.welded && !ai_ventbreaker))
forceMove(original_location)
entry_vent = null
return
if(ai_ventbreaker && exit_vent.welded)
exit_vent.welded = 0
exit_vent.update_icon()
exit_vent.update_pipe_image()
exit_vent.visible_message("<span class='danger'>[src] smashes the welded cover off [exit_vent]!</span>")
playsound(exit_vent.loc, 'sound/machines/airlock_alien_prying.ogg', 50, 0)
forceMove(exit_vent.loc)
entry_vent = null
var/area/new_area = get_area(loc)
@@ -49,6 +49,7 @@ var/global/list/ts_spiderling_list = list()
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.
var/ai_ventbreaker = 0
// AI movement tracking
var/spider_steps_taken = 0 // leave at 0, its a counter for ai steps taken.
@@ -271,6 +272,8 @@ var/global/list/ts_spiderling_list = list()
// after 30 seconds, assuming nobody took control of it yet, offer it to ghosts.
addtimer(src, "CheckFaction", 150)
addtimer(src, "announcetoghosts", 300)
var/datum/atom_hud/U = huds[DATA_HUD_MEDICAL_ADVANCED]
U.add_hud_to(src)
/mob/living/simple_animal/hostile/poison/terror_spider/proc/announcetoghosts()
if(spider_awaymission)
@@ -21,7 +21,6 @@
melee_damage_upper = 15
move_to_delay = 4
spider_tier = TS_TIER_2
loot = list(/obj/item/clothing/accessory/medal)
web_infects = 1