Merge branch 'master' of https://github.com/tgstation/tgstation into gero_gero

# Conflicts:
#	icons/effects/96x96.dmi
This commit is contained in:
Ergovisavi
2017-07-01 16:20:05 -07:00
33 changed files with 1951 additions and 948 deletions
+1 -12
View File
@@ -15,18 +15,7 @@
unit_name = "solar panel control board"
export_types = list(/obj/item/weapon/circuitboard/computer/solar_control)
/datum/export/swarmer
cost = 2000
unit_name = "deactivated alien deconstruction drone"
export_types = list(/obj/item/device/unactivated_swarmer)
/datum/export/swarmer/applies_to(obj/O, contr = 0, emag = 0)
if(!..())
return FALSE
var/obj/item/device/unactivated_swarmer/S = O
if(!S.crit_fail)
return FALSE
return TRUE
export_types = list(/obj/item/device/deactivated_swarmer)
+206 -131
View File
@@ -15,6 +15,9 @@
The base of program_type will always be ignored; only subtypes will be loaded.
*/
#define HOLODECK_CD 25
#define HOLODECK_DMG_CD 500
/obj/machinery/computer/holodeck
name = "holodeck control console"
desc = "A computer used to control a nearby holodeck."
@@ -26,109 +29,106 @@
var/area/holodeck/last_program
var/area/offline_program = /area/holodeck/rec_center/offline
var/list/program_cache = list()
var/list/emag_programs = list()
var/list/program_cache
var/list/emag_programs
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
// set this if you want it to start with some particular program.
var/init_program = null
// or this to get anything
var/random_program = 0
var/active = 0
var/damaged = 0
var/active = FALSE
var/damaged = FALSE
var/list/spawned = list()
var/list/effects = list()
var/last_change = 0
var/current_cd = 0
/obj/machinery/computer/holodeck/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/holodeck/LateInitialize()
if(ispath(holodeck_type,/area))
var/list/possible = get_areas(holodeck_type,subtypes = FALSE)
linked = pop(possible)
if(ispath(offline_program,/area))
var/list/possible = get_areas(offline_program,subtypes = FALSE)
offline_program = pop(possible)
// the following is necessary for power reasons
if(!linked || !offline_program)
log_world("No matching holodeck area found")
qdel(src)
return
var/area/AS = get_area(src)
if(istype(AS,/area/holodeck))
log_world("### MAPPING ERROR")
log_world("Holodeck computer cannot be in a holodeck.")
log_world("This would cause circular power dependency.")
qdel(src) // todo handle constructed computers
return //l-lewd...
else
linked.linked = src // todo detect multiple/constructed computers
if(ispath(holodeck_type, /area))
linked = locate(holodeck_type) in GLOB.sortedAreas
if(ispath(offline_program,/area))
offline_program = locate(offline_program) in GLOB.sortedAreas
// the following is necessary for power reasons
if(!linked || !offline_program)
log_world("No matching holodeck area found")
qdel(src)
return
var/area/AS = get_area(src)
if(istype(AS, /area/holodeck))
log_world("### MAPPING ERROR")
log_world("Holodeck computer cannot be in a holodeck.")
log_world("This would cause circular power dependency.")
qdel(src)
return
else
linked.linked = src
program_cache = list()
emag_programs = list()
for(var/typekey in subtypesof(program_type))
var/area/holodeck/A = locate(typekey)
if(!A || A == offline_program)
continue
if(A.contents.len == 0)
continue // not loaded
if(A.restricted)
emag_programs += A
else
program_cache += A
if(typekey == init_program)
load_program(A,force=1)
if(random_program && program_cache.len && init_program == null)
load_program(pick(program_cache),force=1)
else if(!program)
load_program(offline_program)
generate_program_list()
load_program(offline_program, FALSE, FALSE)
/obj/machinery/computer/holodeck/Destroy()
emergency_shutdown()
if(linked)
linked.linked = null
return ..()
/obj/machinery/computer/holodeck/power_change()
..()
. = ..()
toggle_power(!stat)
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = 0)
if(active == toggleOn) return
/obj/machinery/computer/holodeck/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "holodeck", name, 400, 500, master_ui, state)
ui.open()
if(toggleOn)
if(last_program && last_program != offline_program)
load_program(last_program, delay = 1)
active = 1
else
last_program = program
load_program(offline_program,force=1)
active = 0
/obj/machinery/computer/holodeck/ui_data(mob/user)
var/list/data = list()
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
last_program = program
load_program(offline_program,1)
active = 0
data["default_programs"] = program_cache
if(emagged)
data["emagged"] = TRUE
data["emag_programs"] = emag_programs
data["program"] = program
data["can_toggle_safety"] = issilicon(user) || IsAdminGhost(user)
return data
/obj/machinery/computer/holodeck/ui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("load_program")
var/program_to_load = text2path(params["type"])
if(!ispath(program_to_load))
return FALSE
var/area/A = locate(program_to_load) in GLOB.sortedAreas
if(A)
load_program(A)
if("safety")
emagged = !emagged
if(emagged && program && emag_programs[program.name])
emergency_shutdown()
nerf(emagged)
/obj/machinery/computer/holodeck/process()
if(damaged)
if(prob(10))
for(var/turf/T in linked)
if(prob(5))
var/datum/effect_system/spark_spread/s = new
s.set_up(2, 1, T)
s.start()
return
if(damaged && prob(10))
for(var/turf/T in linked)
if(prob(5))
do_sparks(2, 1, T)
return
if(!..() || !active)
return
if(!floorcheck())
emergency_shutdown()
damaged = 1
damaged = TRUE
for(var/mob/M in urange(10,src))
M.show_message("The holodeck overloads!")
@@ -144,67 +144,24 @@
for(var/item in spawned)
if(!(get_turf(item) in linked))
derez(item, 0)
for(var/obj/effect/holodeck_effect/HE in effects)
for(var/e in effects)
var/obj/effect/holodeck_effect/HE = e
HE.tick()
active_power_usage = 50 + spawned.len * 3 + effects.len * 5
/obj/machinery/computer/holodeck/proc/floorcheck()
for(var/turf/T in linked)
if(!T.intact || isspaceturf(T))
return 0
return 1
/obj/machinery/computer/holodeck/Topic(href, list/href_list)
if(..())
/obj/machinery/computer/holodeck/emag_act(mob/user)
if(emagged)
return
usr.set_machine(src)
add_fingerprint(usr)
if(href_list["loadarea"])
var/areapath = text2path(href_list["loadarea"])
if(!ispath(areapath, /area/holodeck))
return
var/area/holodeck/area = locate(areapath)
if(!istype(area))
return
if(area == offline_program || (area in program_cache) || (emagged && (area in emag_programs)))
load_program(area)
else if("safety" in href_list)
var/safe = text2num(href_list["safety"])
if(!issilicon(usr))
return
emagged = !safe
if(!program)
return
if(safe && (program in emag_programs))
emergency_shutdown()
nerf(safe)
updateUsrDialog()
/obj/machinery/computer/holodeck/proc/nerf(active)
for(var/obj/item/I in spawned)
I.damtype = (active? STAMINA : initial(I.damtype) )
for(var/obj/effect/holodeck_effect/HE in effects)
HE.safety(active)
/obj/machinery/computer/holodeck/emag_act(mob/user as mob)
if(!emagged)
if(!emag_programs.len)
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
return
playsound(loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
log_game("[key_name(user)] emagged the Holodeck Control Console")
updateUsrDialog()
nerf(!emagged)
/obj/machinery/computer/holodeck/Destroy()
if(linked)
emergency_shutdown()
linked.linked = null
return ..()
if(!LAZYLEN(emag_programs))
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
return
playsound(src, 'sound/effects/sparks4.ogg', 75, 1)
emagged = TRUE
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
log_game("[key_name(user)] emagged the Holodeck Control Console")
nerf(!emagged)
/obj/machinery/computer/holodeck/emp_act(severity)
emergency_shutdown()
@@ -216,4 +173,122 @@
/obj/machinery/computer/holodeck/blob_act(obj/structure/blob/B)
emergency_shutdown()
return ..()
return ..()
/obj/machinery/computer/holodeck/proc/generate_program_list()
for(var/typekey in subtypesof(program_type))
var/area/holodeck/A = locate(typekey) in GLOB.sortedAreas
if(!A || A == offline_program || !A.contents.len)
continue
var/list/info_this = list()
info_this["name"] = A.name
info_this["type"] = A.type
if(A.restricted)
LAZYADD(emag_programs, list(info_this))
else
LAZYADD(program_cache, list(info_this))
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
if(active == toggleOn)
return
if(toggleOn)
if(last_program && last_program != offline_program)
addtimer(CALLBACK(src, .proc/load_program, last_program, TRUE), 25)
active = TRUE
else
last_program = program
load_program(offline_program, TRUE)
active = FALSE
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
last_program = program
load_program(offline_program, TRUE)
active = FALSE
/obj/machinery/computer/holodeck/proc/floorcheck()
for(var/turf/T in linked)
if(!T.intact || isspaceturf(T))
return FALSE
return TRUE
/obj/machinery/computer/holodeck/proc/nerf(active)
for(var/obj/item/I in spawned)
I.damtype = active ? STAMINA : initial(I.damtype)
for(var/e in effects)
var/obj/effect/holodeck_effect/HE = e
HE.safety(active)
/obj/machinery/computer/holodeck/proc/load_program(area/A, force = FALSE, add_delay = TRUE)
if(!is_operational())
A = offline_program
force = TRUE
if(program == A)
return
if(current_cd > world.time && !force)
say("ERROR. Recalibrating projection apparatus.")
return
if(add_delay)
current_cd = world.time + HOLODECK_CD
if(damaged)
current_cd += HOLODECK_DMG_CD
active = (A != offline_program)
use_power = active + IDLE_POWER_USE
for(var/e in effects)
var/obj/effect/holodeck_effect/HE = e
HE.deactivate(src)
for(var/item in spawned)
derez(item, force)
program = A
// note nerfing does not yet work on guns, should
// should also remove/limit/filter reagents?
// this is an exercise left to others I'm afraid. -Sayu
spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged)
for(var/obj/machinery/M in spawned)
M.flags |= NODECONSTRUCT
for(var/obj/structure/S in spawned)
S.flags |= NODECONSTRUCT
effects = list()
addtimer(CALLBACK(src, .proc/finish_spawn), 30)
/obj/machinery/computer/holodeck/proc/finish_spawn()
var/list/added = list()
for(var/obj/effect/holodeck_effect/HE in spawned)
effects += HE
spawned -= HE
var/atom/x = HE.activate(src)
if(istype(x) || islist(x))
spawned += x // holocarp are not forever
added += x
for(var/obj/machinery/M in added)
M.flags |= NODECONSTRUCT
for(var/obj/structure/S in added)
S.flags |= NODECONSTRUCT
/obj/machinery/computer/holodeck/proc/derez(obj/O, silent = TRUE, forced = FALSE)
// Emagging a machine creates an anomaly in the derez systems.
if(O && emagged && !stat && !forced)
if((ismob(O) || ismob(O.loc)) && prob(50))
addtimer(CALLBACK(src, .proc/derez, O, silent), 50) // may last a disturbingly long time
return
spawned -= O
if(!O)
return
var/turf/T = get_turf(O)
for(var/atom/movable/AM in O) // these should be derezed if they were generated
AM.forceMove(T)
if(ismob(AM))
silent = FALSE // otherwise make sure they are dropped
if(!silent)
visible_message("[O] fades away!")
qdel(O)
#undef HOLODECK_CD
#undef HOLODECK_DMG_CD
-111
View File
@@ -1,111 +0,0 @@
/obj/machinery/computer/holodeck/attack_hand(var/mob/user as mob)
user.set_machine(src)
var/dat = "<h3>Current Loaded Programs</h3>"
dat += "<a href='?src=\ref[src];loadarea=[offline_program.type]'>Power Off</a><br>"
for(var/area/A in program_cache)
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
if(emagged && emag_programs.len)
dat += "<span class='warning'>SUPERVISOR ACCESS - SAFETY PROTOCOLS DISABLED - CAUTION: EMITTER ANOMALY</span><br>"
for(var/area/A in emag_programs)
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
var/datum/browser/popup = new(user, "computer", name, 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/holodeck/attack_ai(var/mob/user as mob)
var/dat = "<h3>Current Loaded Programs</h3>"
dat += "<a href='?src=\ref[src];loadarea=[offline_program.type]'>Power Off</a><br>"
for(var/area/A in program_cache)
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
if(emag_programs.len)
dat += "<br>"
if(emagged)
dat += "Safety protocol: <span class='bad'>Offline</span> <a href='?\ref[src];safety=1'>Engage</a><br>"
for(var/area/A in emag_programs)
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
else
dat += "Safety protocol: <span class='good'>Online</span> <a href='?\ref[src];safety=0'>Disengage</a><br>"
var/datum/browser/popup = new(user, "computer", name, 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/holodeck/proc/load_program(var/area/A, var/force = 0, var/delay = 0)
if(stat)
A = offline_program
force = 1
delay = 0
if(program == A)
return
if(world.time < (last_change + 25 + (damaged?500:0)) && !force)
if(delay)
sleep(25)
else
if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve
return
if(get_dist(usr,src) <= 3)
to_chat(usr, "<span class='warning'>ERROR. Recalibrating projection apparatus.</span>")
return
last_change = world.time
active = (A != offline_program)
use_power = active ? ACTIVE_POWER_USE : IDLE_POWER_USE
for(var/obj/effect/holodeck_effect/HE in effects)
HE.deactivate(src)
for(var/item in spawned)
derez(item, forced=force)
program = A
// note nerfing does not yet work on guns, should
// should also remove/limit/filter reagents?
// this is an exercise left to others I'm afraid. -Sayu
spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged)
for(var/obj/machinery/M in spawned)
M.flags |= NODECONSTRUCT
for(var/obj/structure/S in spawned)
S.flags |= NODECONSTRUCT
effects = list()
spawn(30)
var/list/added = list()
for(var/obj/effect/holodeck_effect/HE in spawned)
effects += HE
spawned -= HE
var/atom/x = HE.activate(src)
if(istype(x) || islist(x))
spawned += x // holocarp are not forever
added += x
for(var/obj/machinery/M in added)
M.flags |= NODECONSTRUCT
for(var/obj/structure/S in added)
S.flags |= NODECONSTRUCT
/obj/machinery/computer/holodeck/proc/derez(var/obj/obj, var/silent = 1, var/forced = 0)
// Emagging a machine creates an anomaly in the derez systems.
if(obj && src.emagged && !src.stat && !forced)
if((ismob(obj) || ismob(obj.loc)) && prob(50))
spawn(50) .(obj,silent) // may last a disturbingly long time
return
spawned.Remove(obj)
if(!obj)
return
var/turf/T = get_turf(obj)
for(var/atom/movable/AM in obj.contents) // these should be derezed if they were generated
AM.loc = T
if(ismob(AM))
silent = FALSE // otherwise make sure they are dropped
if(!silent)
visible_message("The [obj.name] fades away!")
qdel(obj)
+14 -2
View File
@@ -106,6 +106,7 @@
desc = "For grilling, broiling, charring, smoking, heating, roasting, toasting, simmering, searing, melting, and occasionally burning things."
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "bonfire"
light_color = LIGHT_COLOR_FIRE
density = FALSE
anchored = TRUE
buckle_lying = 0
@@ -113,6 +114,16 @@
var/grill = FALSE
var/fire_stack_strength = 5
/obj/structure/bonfire/dense
density = TRUE
/obj/structure/bonfire/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
return TRUE
if(mover.throwing)
return TRUE
return ..()
/obj/structure/bonfire/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill)
var/obj/item/stack/rods/R = W
@@ -130,8 +141,7 @@
R.use(1)
grill = TRUE
to_chat(user, "<span class='italics'>You add a grill to \the [src].")
var/mutable_appearance/grill_overlay = mutable_appearance('icons/obj/hydroponics/equipment.dmi', "bonfire_grill")
overlays += grill_overlay
add_overlay("bonfire_grill")
else
return ..()
if(W.is_hot())
@@ -160,6 +170,8 @@
var/obj/item/weapon/grown/log/L = new /obj/item/weapon/grown/log(src.loc)
L.pixel_x += rand(1,4)
L.pixel_y += rand(1,4)
if(can_buckle || grill)
new /obj/item/stack/rods(loc, 1)
qdel(src)
return
..()
+1 -1
View File
@@ -66,7 +66,7 @@
else if(eye_blurry) //blurry eyes heal slowly
adjust_blurriness(-1)
if (getBrainLoss() >= 60 && stat != DEAD)
if (getBrainLoss() >= 60 && stat == CONSCIOUS)
if(prob(3))
if(prob(25))
emote("drool")
@@ -97,7 +97,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
desc = "Transmited over the signal is a strange message repeated in every language you know of, and some you don't too..." //the message is "nom nom nom"
invisibility = 100
//SWARMER AI
//AI versions of the swarmer mini-antag
//This is an Abstract Base, it re-enables AI, but does not give the swarmer any goals/targets
@@ -107,7 +106,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
weather_immunities = list("ash") //wouldn't be fun otherwise
AIStatus = AI_ON
/mob/living/simple_animal/hostile/swarmer/ai/Initialize()
. = ..()
ToggleLight() //so you can see them eating you out of house and home/shooting you/stunlocking you for eternity
@@ -262,16 +260,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
check_friendly_fire = TRUE //you're supposed to protect the resource swarmers, you poop
retreat_distance = 3
minimum_distance = 3
login_text_dump = {"
<b>You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate.</b>
<b>Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful.</b>
<b>Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.</b>
<b>Objectives:</b>
1. Defend Resource Swarmers while they consume resources and replicate until there are no more resources left.
2. Ensure that this location is fit for invasion at a later date; do not perform actions that would render it dangerous or inhospitable.
3. Biological resources should not be harmed if possible, violent force can be applied should they fail to keep away.
"}
/mob/living/simple_animal/hostile/swarmer/ai/ranged_combat/Aggro()
..()
@@ -285,16 +273,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
health = 60
maxHealth = 60
ranged = FALSE
login_text_dump = {"
<b>You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate.</b>
<b>Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful.</b>
<b>Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.</b>
<b>Objectives:</b>
1. Defend Resource Swarmers while they consume resources and replicate until there are no more resources left.
2. Ensure that this location is fit for invasion at a later date; do not perform actions that would render it dangerous or inhospitable.
3. Biological resources should not be harmed if possible, violent force can be applied should they fail to keep away.
"}
/mob/living/simple_animal/hostile/swarmer/ai/melee_combat/Aggro()
..()
@@ -30,10 +30,9 @@
spawned_mobs = null
return ..()
/mob/living/simple_animal/hostile/spawner/Life()
..()
if(!stat)
spawn_mob()
/mob/living/simple_animal/hostile/spawner/handle_automated_action()
. = ..()
spawn_mob()
/mob/living/simple_animal/hostile/spawner/proc/spawn_mob()
if(spawned_mobs.len >= max_mobs)
+1 -1
View File
@@ -22,7 +22,7 @@
/obj/item/weapon/gun/ballistic/update_icon()
..()
if(current_skin)
icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
icon_state = "[unique_reskin[current_skin]][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
else
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]"
+2 -2
View File
@@ -5,7 +5,7 @@
icon_state = "deliverycloset"
density = 1
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
var/giftwrapped = 0
var/giftwrapped = FALSE
var/sortTag = 0
/obj/structure/bigDelivery/attack_hand(mob/user)
@@ -44,7 +44,7 @@
var/obj/item/stack/wrapping_paper/WP = W
if(WP.use(3))
user.visible_message("[user] wraps the package in festive paper!")
giftwrapped = 1
giftwrapped = TRUE
icon_state = "gift[icon_state]"
else
to_chat(user, "<span class='warning'>You need more paper!</span>")
@@ -1,49 +1,39 @@
#define ASH_WALKER_SPAWN_THRESHOLD 2
//The ash walker den consumes corpses or unconscious mobs to create ash walker eggs. For more info on those, check ghost_role_spawners.dm
/mob/living/simple_animal/hostile/spawner/ash_walker
name = "ash walker nest"
desc = "A nest built around a necropolis tendril. The eggs seem to grow unnaturally fast..."
icon = 'icons/mob/nest.dmi'
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker
name = "necropolis tendril nest"
desc = "A vile tendril of corruption. It's surrounded by a nest of rapidly growing eggs..."
icon_state = "ash_walker_nest"
icon_living = "ash_walker_nest"
icon_dead = "ash_walker_nest"
faction = list("ashwalker")
health = 200
maxHealth = 200
loot = list(/obj/effect/gibspawner, /obj/item/device/assembly/signaler/anomaly)
del_on_death = 1
var/meat_counter
var/obj/effect/light_emitter/tendril/emitted_light
/mob/living/simple_animal/hostile/spawner/ash_walker/Initialize()
. = ..()
emitted_light = new(loc)
loot = list(/obj/effect/collapse)
var/meat_counter = 6
/mob/living/simple_animal/hostile/spawner/ash_walker/Destroy()
QDEL_NULL(emitted_light)
. = ..()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death()
new /obj/item/device/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs)))
return ..()
/mob/living/simple_animal/hostile/spawner/ash_walker/Life()
..()
if(!stat)
consume()
spawn_mob()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/handle_automated_action()
consume()
return ..()
/mob/living/simple_animal/hostile/spawner/ash_walker/proc/consume()
for(var/mob/living/H in view(src,1)) //Only for corpse right next to/on same tile
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/proc/consume()
for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile
if(H.stat)
visible_message("<span class='warning'>Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.</span>")
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1)
if(ismegafauna(H))
meat_counter += 20
else
meat_counter ++
for(var/obj/item/W in H)
H.dropItemToGround(W)
meat_counter++
H.gib()
adjustHealth(-maxHealth * 0.05)//restores 5% hp of tendril
/mob/living/simple_animal/hostile/spawner/ash_walker/spawn_mob()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/spawn_mob()
if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD)
new /obj/effect/mob_spawn/human/ash_walker(get_step(src.loc, SOUTH))
new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)))
visible_message("<span class='danger'>One of the eggs swells to an unnatural size and tumbles free. It's ready to hatch!</span>")
meat_counter -= ASH_WALKER_SPAWN_THRESHOLD
@@ -4,6 +4,7 @@
desc = "A massive stone gateway."
icon = 'icons/effects/96x96.dmi'
icon_state = "gate_full"
flags = ON_BORDER
appearance_flags = 0
layer = TABLE_LAYER
anchored = TRUE
@@ -24,6 +25,7 @@
/obj/structure/necropolis_gate/Initialize()
. = ..()
setDir(SOUTH)
var/turf/sight_blocker_turf = get_turf(src)
if(sight_blocker_distance)
for(var/i in 1 to sight_blocker_distance)
@@ -32,6 +34,7 @@
sight_blocker_turf = get_step(sight_blocker_turf, NORTH)
if(sight_blocker_turf)
sight_blocker = new (sight_blocker_turf) //we need to block sight in a different spot than most things do
sight_blocker.pixel_y = initial(sight_blocker.pixel_y) - (32 * sight_blocker_distance)
icon_state = "gate_bottom"
top_overlay = mutable_appearance('icons/effects/96x96.dmi', "gate_top")
top_overlay.layer = EDGED_TURF_LAYER
@@ -53,9 +56,22 @@
/obj/structure/necropolis_gate/singularity_pull()
return 0
/obj/structure/necropolis_gate/CanPass(atom/movable/mover, turf/target, height=0)
if(get_dir(loc, target) == dir)
return !density
return 1
/obj/structure/necropolis_gate/CheckExit(atom/movable/O, target)
if(get_dir(O.loc, target) == dir)
return !density
return 1
/obj/structure/opacity_blocker
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
icon = 'icons/effects/96x96.dmi'
icon_state = "gate_blocker"
layer = EDGED_TURF_LAYER
pixel_x = -32
pixel_y = -32
mouse_opacity = 0
opacity = TRUE
@@ -94,6 +110,7 @@
break
sight_blocker_turf = get_step(sight_blocker_turf, NORTH)
if(sight_blocker_turf)
sight_blocker.pixel_y = initial(sight_blocker.pixel_y) - (32 * sight_blocker_distance)
sight_blocker.forceMove(sight_blocker_turf)
sleep(2.5)
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 30, TRUE, frequency = 15000)