Files
Polaris/code/game/objects/effects/spiders.dm
Leshana 6a0cc39419 Fixes objects using walk_to() not being able to be garbage collected.
* Okay evidently walk_to(A, B) doesn't stop when A reaches B, but keeps running in the background forever until it is manually canceled!  Therefore in order to be garbage collected, we must cancel walking on any object that might have initiated it.
* Fixes this on chemsmoke and spiders.
* The same story applies to walk_towards; fixed for dust, meteors and immovablerod, and also to walk_away; fixed for flashbangs.
* Also fixed chemsmoke actually getting qdeled at the right time.
2017-06-16 13:40:15 -04:00

264 lines
7.4 KiB
Plaintext

//generic procs copied from obj/effect/alien
/obj/effect/spider
name = "web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
anchored = 1
density = 0
var/health = 15
//similar to weeds, but only barfed out by nurses manually
/obj/effect/spider/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(3.0)
if (prob(5))
qdel(src)
return
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(W.attack_verb.len)
visible_message("<span class='warning'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
else
visible_message("<span class='warning'>\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user))
damage = 15
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
health -= damage
healthcheck()
/obj/effect/spider/bullet_act(var/obj/item/projectile/Proj)
..()
health -= Proj.get_structure_damage()
healthcheck()
/obj/effect/spider/proc/healthcheck()
if(health <= 0)
qdel(src)
/obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
/obj/effect/spider/stickyweb
icon_state = "stickyweb1"
New()
if(prob(50))
icon_state = "stickyweb2"
/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
if(istype(mover, /mob/living/simple_animal/hostile/giant_spider))
return 1
else if(istype(mover, /mob/living))
if(prob(50))
mover << "<span class='warning'>You get stuck in \the [src] for a moment.</span>"
return 0
else if(istype(mover, /obj/item/projectile))
return prob(30)
return 1
/obj/effect/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
var/amount_grown = 0
var/spiders_min = 6
var/spiders_max = 24
New()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
processing_objects |= src
/obj/effect/spider/eggcluster/New(var/location, var/atom/parent)
get_light_and_color(parent)
..()
/obj/effect/spider/eggcluster/Destroy()
processing_objects -= src
if(istype(loc, /obj/item/organ/external))
var/obj/item/organ/external/O = loc
O.implants -= src
return ..()
/obj/effect/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = rand(spiders_min, spiders_max)
var/obj/item/organ/external/O = null
if(istype(loc, /obj/item/organ/external))
O = loc
for(var/i=0, i<num, i++)
var/spiderling = new /obj/effect/spider/spiderling(src.loc, src)
if(O)
O.implants += spiderling
qdel(src)
/obj/effect/spider/eggcluster/small
spiders_min = 1
spiders_max = 3
/obj/effect/spider/spiderling
name = "spiderling"
desc = "It never stays still for long."
icon_state = "spiderling"
anchored = 0
layer = 2.7
health = 3
var/last_itch = 0
var/amount_grown = -1
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
var/travelling_in_vent = 0
/obj/effect/spider/spiderling/New(var/location, var/atom/parent)
pixel_x = rand(6,-6)
pixel_y = rand(6,-6)
processing_objects |= src
//50% chance to grow up
if(prob(50))
amount_grown = 1
get_light_and_color(parent)
..()
/obj/effect/spider/spiderling/Destroy()
processing_objects -= src
walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
/obj/effect/spider/spiderling/Bump(atom/user)
if(istype(user, /obj/structure/table))
src.loc = user.loc
else
..()
/obj/effect/spider/spiderling/proc/die()
visible_message("<span class='alert'>[src] dies!</span>")
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
qdel(src)
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
die()
/obj/effect/spider/spiderling/process()
if(travelling_in_vent)
if(istype(src.loc, /turf))
travelling_in_vent = 0
entry_vent = null
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
if(entry_vent.network && entry_vent.network.normal_members.len)
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.network.normal_members)
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))
src.visible_message("<B>[src] scrambles into the ventillation ducts!</B>")*/
spawn(rand(20,60))
loc = exit_vent
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
if(prob(50))
src.visible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>",2)
sleep(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
loc = exit_vent.loc
entry_vent = null
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
else
entry_vent = null
//=================
if(isturf(loc))
if(prob(25))
var/list/nearby = trange(5, src) - loc
if(nearby.len)
var/target_atom = pick(nearby)
walk_to(src, target_atom, 5)
if(prob(25))
src.visible_message("<span class='notice'>\The [src] skitters[pick(" away"," around","")].</span>")
else if(prob(5))
//vent crawl!
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
walk_to(src, entry_vent, 5)
break
if(amount_grown >= 100)
var/spawn_type = pick(typesof(/mob/living/simple_animal/hostile/giant_spider))
new spawn_type(src.loc, src)
qdel(src)
else if(isorgan(loc))
if(!amount_grown) amount_grown = 1
var/obj/item/organ/external/O = loc
if(!O.owner || O.owner.stat == DEAD || amount_grown > 80)
O.implants -= src
src.loc = O.owner ? O.owner.loc : O.loc
src.visible_message("<span class='warning'>\A [src] makes its way out of [O.owner ? "[O.owner]'s [O.name]" : "\the [O]"]!</span>")
if(O.owner)
O.owner.apply_damage(1, BRUTE, O.organ_tag)
else if(prob(1))
O.owner.apply_damage(1, TOX, O.organ_tag)
if(world.time > last_itch + 30 SECONDS)
last_itch = world.time
O.owner << "<span class='notice'>Your [O.name] itches...</span>"
else if(prob(1))
src.visible_message("<span class='notice'>\The [src] skitters.</span>")
if(amount_grown)
amount_grown += rand(0,2)
/obj/effect/decal/cleanable/spiderling_remains
name = "spiderling remains"
desc = "Green squishy mess."
icon = 'icons/effects/effects.dmi'
icon_state = "greenshatter"
/obj/effect/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
icon_state = "cocoon1"
health = 60
New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
/obj/effect/spider/cocoon/Destroy()
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
for(var/atom/movable/A in contents)
A.loc = src.loc
return ..()