diff --git a/baystation12.dme b/baystation12.dme
index fbf18f8a94b..a9282a6a5dd 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -37,6 +37,7 @@
#include "code\_onclick\click.dm"
#include "code\_onclick\cyborg.dm"
#include "code\_onclick\drag_drop.dm"
+#include "code\_onclick\eye.dm"
#include "code\_onclick\item_attack.dm"
#include "code\_onclick\observer.dm"
#include "code\_onclick\other_mobs.dm"
@@ -1049,13 +1050,24 @@
#include "code\modules\mob\typing_indicator.dm"
#include "code\modules\mob\update_icons.dm"
#include "code\modules\mob\dead\death.dm"
+#include "code\modules\mob\dead\observer\login.dm"
#include "code\modules\mob\dead\observer\logout.dm"
#include "code\modules\mob\dead\observer\observer.dm"
#include "code\modules\mob\dead\observer\say.dm"
#include "code\modules\mob\freelook\chunk.dm"
#include "code\modules\mob\freelook\eye.dm"
+#include "code\modules\mob\freelook\life.dm"
+#include "code\modules\mob\freelook\read_me.dm"
#include "code\modules\mob\freelook\update_triggers.dm"
#include "code\modules\mob\freelook\visualnet.dm"
+#include "code\modules\mob\freelook\ai\cameranet.dm"
+#include "code\modules\mob\freelook\ai\chunk.dm"
+#include "code\modules\mob\freelook\ai\eye.dm"
+#include "code\modules\mob\freelook\ai\update_triggers.dm"
+#include "code\modules\mob\freelook\mask\chunk.dm"
+#include "code\modules\mob\freelook\mask\cultnet.dm"
+#include "code\modules\mob\freelook\mask\eye.dm"
+#include "code\modules\mob\freelook\mask\update_triggers.dm"
#include "code\modules\mob\language\generic.dm"
#include "code\modules\mob\language\language.dm"
#include "code\modules\mob\language\outsider.dm"
@@ -1176,11 +1188,6 @@
#include "code\modules\mob\living\silicon\ai\logout.dm"
#include "code\modules\mob\living\silicon\ai\say.dm"
#include "code\modules\mob\living\silicon\ai\subsystems.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\chunk.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\eye.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\read_me.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm"
#include "code\modules\mob\living\silicon\decoy\death.dm"
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
#include "code\modules\mob\living\silicon\decoy\life.dm"
@@ -1252,6 +1259,9 @@
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
+#include "code\modules\mob\living\simple_animal\narsie\login.dm"
+#include "code\modules\mob\living\simple_animal\narsie\logout.dm"
+#include "code\modules\mob\living\simple_animal\narsie\narsie.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
#include "code\modules\mob\new_player\new_player.dm"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 01b9509ae86..50c08172e1d 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -49,6 +49,11 @@ var/global/list/undershirt_t = list("White Tank top" = "u1", "Black Tank top" =
//Backpacks
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg)
+
+// Visual nets
+var/list/datum/visualnet/visual_nets = list()
+var/datum/visualnet/camera/cameranet = new()
+var/datum/visualnet/cult/cultnet = new()
//////////////////////////
/////Initial Building/////
//////////////////////////
diff --git a/code/_onclick/eye.dm b/code/_onclick/eye.dm
new file mode 100644
index 00000000000..1c3282f23bb
--- /dev/null
+++ b/code/_onclick/eye.dm
@@ -0,0 +1,7 @@
+/mob/living/simple_animal/shade/narsie/DblClickOn(var/atom/A, params)
+ if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
+ build_click(src, client.buildmode, params, A)
+ return
+
+ sanity_check_eye()
+ eyeobj.setLoc(A)
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index e9c5429dd2a..9c656b05110 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -33,7 +33,7 @@ var/list/global_huds = list(
screen.screen_loc = "1,1"
screen.icon = 'icons/obj/hud_full.dmi'
screen.icon_state = icon_state
- screen.layer = 17
+ screen.layer = SCREEN_LAYER
screen.mouse_opacity = 0
return screen
@@ -259,11 +259,11 @@ datum/hud/New(mob/owner)
if(!hud_used)
usr << "\red This mob type does not use a HUD."
return
-
+
if(!ishuman(src))
usr << "\red Inventory hiding is currently only supported for human mobs, sorry."
return
-
+
if(!client) return
if(client.view != world.view)
return
@@ -325,7 +325,7 @@ datum/hud/New(mob/owner)
return
if(client.view != world.view)
return
-
+
if(hud_used.hud_shown)
hud_used.hud_shown = 0
if(src.hud_used.adding)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 6a17d03a072..a1c0acf0081 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -8,4 +8,4 @@
required_enemies = 3
uplink_welcome = "Nar-Sie Uplink Console:"
end_on_antag_death = 1
- antag_tag = MODE_CULTIST
\ No newline at end of file
+ antag_tag = MODE_CULTIST
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index f677140cc3e..b57172dbff9 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -1,7 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
-#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
-
#define DOOR_REPAIR_AMOUNT 50 //amount of health regained per stack amount used
/obj/machinery/door
diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/freelook/ai/cameranet.dm
similarity index 93%
rename from code/modules/mob/living/silicon/ai/freelook/cameranet.dm
rename to code/modules/mob/freelook/ai/cameranet.dm
index d2d042c778a..2fb3c4b5ced 100644
--- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
+++ b/code/modules/mob/freelook/ai/cameranet.dm
@@ -2,8 +2,6 @@
//
// The datum containing all the chunks.
-var/datum/visualnet/camera/cameranet = new()
-
/datum/visualnet/camera
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
var/list/cameras = list()
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/freelook/ai/chunk.dm
similarity index 100%
rename from code/modules/mob/living/silicon/ai/freelook/chunk.dm
rename to code/modules/mob/freelook/ai/chunk.dm
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/freelook/ai/eye.dm
similarity index 100%
rename from code/modules/mob/living/silicon/ai/freelook/eye.dm
rename to code/modules/mob/freelook/ai/eye.dm
diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/freelook/ai/update_triggers.dm
similarity index 100%
rename from code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
rename to code/modules/mob/freelook/ai/update_triggers.dm
diff --git a/code/modules/mob/freelook/chunk.dm b/code/modules/mob/freelook/chunk.dm
index 8c6c7d043aa..9b6b562df33 100644
--- a/code/modules/mob/freelook/chunk.dm
+++ b/code/modules/mob/freelook/chunk.dm
@@ -101,7 +101,7 @@
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obfuscations[obfuscation.type])
- t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
+ t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
obscured += t.obfuscations[obfuscation.type]
for(var/eye in seenby)
@@ -140,7 +140,7 @@
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obfuscations[obfuscation.type])
- t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
+ t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
obscured += t.obfuscations[obfuscation.type]
#undef UPDATE_BUFFER
diff --git a/code/modules/mob/freelook/eye.dm b/code/modules/mob/freelook/eye.dm
index 70ae8cb7002..318ed4da6e8 100644
--- a/code/modules/mob/freelook/eye.dm
+++ b/code/modules/mob/freelook/eye.dm
@@ -12,6 +12,7 @@
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
+ var/owner_follows_eye = 0
see_in_dark = 7
status_flags = GODMODE
@@ -40,7 +41,9 @@ mob/eye/Del()
..()
// Movement code. Returns 0 to stop air movement from moving it.
-/mob/eye/Move()
+/mob/eye/Move(n, direct)
+ if(owner == src)
+ EyeMove(n, direct)
return 0
/mob/eye/examinate()
@@ -60,15 +63,35 @@ mob/eye/Del()
/mob/eye/proc/setLoc(var/T)
if(owner)
T = get_turf(T)
- loc = T
+ if(T != loc)
+ loc = T
- if(owner.client)
- owner.client.eye = src
+ if(owner.client)
+ owner.client.eye = src
- visualnet.visibility(src)
- return 1
+ if(owner_follows_eye)
+ visualnet.updateVisibility(owner, 0)
+ owner.loc = loc
+ visualnet.updateVisibility(owner, 0)
+
+ visualnet.visibility(src)
+ return 1
return 0
+/mob/eye/proc/getLoc()
+ if(owner)
+ if(!isturf(owner.loc) || !owner.client)
+ return
+ return loc
+/mob
+ var/mob/eye/eyeobj
+
+/mob/proc/EyeMove(n, direct)
+ if(!eyeobj)
+ return
+
+ return eyeobj.EyeMove(n, direct)
+
/mob/eye/EyeMove(n, direct)
var/initial = initial(sprint)
var/max_sprint = 50
@@ -86,18 +109,3 @@ mob/eye/Del()
sprint = min(sprint + 0.5, max_sprint)
else
sprint = initial
-
-/mob/eye/proc/getLoc()
- if(owner)
- if(!isturf(owner.loc) || !owner.client)
- return
- return loc
-
-/mob
- var/mob/eye/eyeobj
-
-/mob/proc/EyeMove(n, direct)
- if(!eyeobj)
- return
-
- return eyeobj.EyeMove(n, direct)
diff --git a/code/modules/mob/freelook/life.dm b/code/modules/mob/freelook/life.dm
new file mode 100644
index 00000000000..1d1248e872e
--- /dev/null
+++ b/code/modules/mob/freelook/life.dm
@@ -0,0 +1,7 @@
+/mob/eye/Life()
+ ..()
+ // If we lost our client, reset the list of visible chunks so they update properly on return
+ if(owner == src && !client)
+ visibleChunks.Cut()
+ /*else if(owner && !owner.client)
+ visibleChunks.Cut()*/
diff --git a/code/modules/mob/freelook/mask/chunk.dm b/code/modules/mob/freelook/mask/chunk.dm
new file mode 100644
index 00000000000..b0973951cc2
--- /dev/null
+++ b/code/modules/mob/freelook/mask/chunk.dm
@@ -0,0 +1,39 @@
+// CULT CHUNK
+//
+// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
+// Allows the Eye to stream these chunks and know what it can and cannot see.
+
+/datum/obfuscation/cult
+ icon_state = "white"
+
+/datum/chunk/cult
+ obfuscation = new /datum/obfuscation/cult()
+
+/datum/chunk/cult/acquireVisibleTurfs(var/list/visible)
+ for(var/mob/living/L in living_mob_list)
+ for(var/turf/t in L.seen_turfs())
+ visible[t] = t
+
+/mob/living/proc/seen_turfs()
+ return seen_turfs_in_range(src, 3)
+
+/mob/living/carbon/human/seen_turfs()
+ /*if(src.isSynthetic())
+ return list()*/
+
+ if(mind in cult.current_antagonists)
+ return seen_turfs_in_range(src, client ? client.view : 7)
+ return ..()
+
+/mob/living/silicon/seen_turfs()
+ return list()
+
+/mob/living/simple_animal/seen_turfs()
+ return seen_turfs_in_range(src, 1)
+
+/mob/living/simple_animal/shade/narsie/seen_turfs()
+ return view(2, src)
+
+/proc/seen_turfs_in_range(var/source, var/range)
+ var/turf/pos = get_turf(source)
+ return hear(range, pos)
diff --git a/code/modules/mob/freelook/mask/cultnet.dm b/code/modules/mob/freelook/mask/cultnet.dm
new file mode 100644
index 00000000000..4e4e01b8472
--- /dev/null
+++ b/code/modules/mob/freelook/mask/cultnet.dm
@@ -0,0 +1,15 @@
+// CULT NET
+//
+// The datum containing all the chunks.
+
+/datum/visualnet/cult
+ chunk_type = /datum/chunk/cult
+
+/datum/visualnet/cult/proc/provides_vision(var/mob/living/L)
+ return L.provides_cult_vision()
+
+/mob/living/proc/provides_cult_vision()
+ return 1
+
+/mob/living/silicon/provides_cult_vision()
+ return 0
diff --git a/code/modules/mob/freelook/mask/eye.dm b/code/modules/mob/freelook/mask/eye.dm
new file mode 100644
index 00000000000..9b211e3bce5
--- /dev/null
+++ b/code/modules/mob/freelook/mask/eye.dm
@@ -0,0 +1,36 @@
+// MASK EYE
+//
+// A mob that a cultists controls to look around the station with.
+// It streams chunks as it moves around, which will show it what the cultist can and cannot see.
+
+/mob/eye/maskEye
+ name = "Eye of Nar-Sie"
+ acceleration = 0
+ owner_follows_eye = 1
+
+/mob/eye/maskEye/New()
+ ..()
+ visualnet = cultnet
+
+/mob/living/simple_animal/shade/narsie/New()
+ ..()
+ sanity_check_eye()
+
+/mob/living/simple_animal/shade/narsie/Del()
+ del(eyeobj)
+ ..()
+
+/mob/living/simple_animal/shade/narsie/verb/center_on_self()
+ set category = "Mask of Nar-Sie"
+ set name = "Center on Self"
+
+ sanity_check_eye()
+ for(var/datum/chunk/c in eyeobj.visibleChunks)
+ c.remove(eyeobj)
+ eyeobj.setLoc(src)
+
+/mob/living/simple_animal/shade/narsie/proc/sanity_check_eye()
+ if(!eyeobj)
+ eyeobj = new /mob/eye/maskEye()
+ eyeobj.owner = src
+ eyeobj.setLoc(src)
diff --git a/code/modules/mob/freelook/mask/update_triggers.dm b/code/modules/mob/freelook/mask/update_triggers.dm
new file mode 100644
index 00000000000..a02aa864a67
--- /dev/null
+++ b/code/modules/mob/freelook/mask/update_triggers.dm
@@ -0,0 +1,50 @@
+//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
+
+#define CULT_UPDATE_BUFFER 30
+
+/mob/living/var/updating_cult_vision = 0
+
+/mob/living/Move()
+ var/oldLoc = src.loc
+ . = ..()
+ if(.)
+ if(cultnet.provides_vision(src))
+ if(!updating_cult_vision)
+ updating_cult_vision = 1
+ spawn(CULT_UPDATE_BUFFER)
+ if(oldLoc != src.loc)
+ cultnet.updateVisibility(oldLoc, 0)
+ cultnet.updateVisibility(loc, 0)
+ updating_cult_vision = 0
+
+#undef CULT_UPDATE_BUFFER
+
+/mob/living/New()
+ ..()
+ cultnet.updateVisibility(src, 0)
+
+/mob/living/Del()
+ cultnet.updateVisibility(src, 0)
+ ..()
+
+/mob/living/rejuvenate()
+ var/was_dead = stat == DEAD
+ ..()
+ if(was_dead && stat != DEAD)
+ // Arise!
+ cultnet.updateVisibility(src, 0)
+
+/mob/living/death()
+ if(..())
+ // If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
+ cultnet.updateVisibility(src)
+
+/datum/antagonist/add_antagonist(var/datum/mind/player)
+ ..()
+ if(src == cult)
+ cultnet.updateVisibility(player.current, 0)
+
+/datum/antagonist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
+ ..()
+ if(src == cult)
+ cultnet.updateVisibility(player.current, 0)
diff --git a/code/modules/mob/living/silicon/ai/freelook/read_me.dm b/code/modules/mob/freelook/read_me.dm
similarity index 100%
rename from code/modules/mob/living/silicon/ai/freelook/read_me.dm
rename to code/modules/mob/freelook/read_me.dm
diff --git a/code/modules/mob/freelook/visualnet.dm b/code/modules/mob/freelook/visualnet.dm
index dedc23ab2dd..161aeb92b82 100644
--- a/code/modules/mob/freelook/visualnet.dm
+++ b/code/modules/mob/freelook/visualnet.dm
@@ -2,8 +2,6 @@
//
// The datum containing all the chunks.
-var/global/list/visual_nets = new()
-
/datum/visualnet
// The chunks of the map, mapping the areas that an object can see.
var/list/chunks = list()
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 14b069a6a19..b1cc2067f4c 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -46,4 +46,4 @@
if(istype(L))
if(prob(12))
L.Weaken(3)
- L.visible_message("\the [src] knocks down \the [L]!")
\ No newline at end of file
+ L.visible_message("\the [src] knocks down \the [L]!")
diff --git a/code/modules/mob/living/simple_animal/narsie/login.dm b/code/modules/mob/living/simple_animal/narsie/login.dm
new file mode 100644
index 00000000000..ac6e9b014fb
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/narsie/login.dm
@@ -0,0 +1,3 @@
+/mob/living/simple_animal/shade/narsie/Login()
+ ..()
+ src.center_on_self()
diff --git a/code/modules/mob/living/simple_animal/narsie/logout.dm b/code/modules/mob/living/simple_animal/narsie/logout.dm
new file mode 100644
index 00000000000..07dcf7812d0
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/narsie/logout.dm
@@ -0,0 +1,3 @@
+/mob/living/simple_animal/shade/narsie/Logout()
+ ..()
+ src.center_on_self()
diff --git a/code/modules/mob/living/simple_animal/narsie/narsie.dm b/code/modules/mob/living/simple_animal/narsie/narsie.dm
new file mode 100644
index 00000000000..2337bc35f3c
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/narsie/narsie.dm
@@ -0,0 +1,108 @@
+/mob/living/simple_animal/shade/narsie
+ maxHealth = 9001
+ health = 9001
+ status_flags = GODMODE
+ layer = OBFUSCATION_LAYER + 0.1
+ invisibility = INVISIBILITY_OBSERVER
+ see_invisible = SEE_INVISIBLE_CULT
+
+ var/influence_max = 0
+ var/influence_target = 0
+ var/influence_current = 0
+ var/last_influence_change = 0
+
+/mob/living/simple_animal/shade/narsie/New()
+ ..()
+ src.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
+ last_influence_change = world.time
+
+ make_floating(1)
+
+/mob/living/simple_animal/shade/narsie/stop_floating()
+
+/mob/living/simple_animal/shade/narsie/say(var/message)
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/emote(var/act, var/type, var/desc)
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/visible_emote(var/act_desc)
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/audible_emote(var/act_desc)
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/attack_hand()
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/UnarmedAttack()
+ if(HasSufficientInfluenceFeedback())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/hear_say()
+ if(HasSufficientInfluence())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/hear_radio()
+ if(HasSufficientInfluence())
+ ..()
+
+/mob/living/simple_animal/shade/narsie/proc/HasSufficientInfluenceFeedback()
+ . = HasSufficientInfluence()
+ if(!.)
+ src << "You do not yet have the influence to interact directly with the mortal realm."
+
+/mob/living/simple_animal/shade/narsie/proc/HasSufficientInfluence()
+ return invisibility <= SEE_INVISIBLE_LIVING
+
+/mob/living/simple_animal/shade/narsie/verb/TargetInfluence()
+ set category = "Mask of Nar-Sie"
+ set name = "Set Target Influence"
+
+ var/influence = input("Set the target influence level", "Set influence", influence_target) as num|null
+ if(isnum(influence))
+ influence_target = influence
+
+/mob/living/simple_animal/shade/narsie/verb/MaxInfluence()
+ set category = "Mask of Nar-Sie"
+ set name = "Set Max Influence"
+
+ var/influence = input("Set the max influence level", "Set influence", influence_max) as num|null
+ if(isnum(influence))
+ influence_max = influence
+
+/mob/living/simple_animal/shade/narsie/Life()
+ ..()
+ ProcessHUD()
+ ProcessInfluence()
+
+/mob/living/simple_animal/shade/narsie/OnDeathInLife()
+
+/mob/living/simple_animal/shade/narsie/proc/ProcessHUD()
+ if(client)
+ client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.thermal, global_hud.meson, global_hud.science)
+
+ client.screen |= global_hud.science
+
+/mob/living/simple_animal/shade/narsie/proc/ProcessInfluence()
+ var/ticks_since_last = world.time - last_influence_change
+ last_influence_change = world.time
+
+ if(influence_target > influence_max)
+ influence_target = influence_max
+
+ if(influence_current < influence_target)
+ influence_current += round(ticks_since_last/10,1)
+
+ if(influence_current > influence_target)
+ influence_current = influence_target
+
+/mob/living/simple_animal/shade/narsie/Stat()
+ if(statpanel("Mask of Nar-Sie"))
+ stat(null, "Influence: [influence_current]/[influence_max]")
+ ..()
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index c200ef6f703..ea3496ecf7c 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -31,15 +31,7 @@
Life()
..()
- if(stat == 2)
- new /obj/item/weapon/ectoplasm (src.loc)
- for(var/mob/M in viewers(src, null))
- if((M.client && !( M.blinded )))
- M.show_message("\red [src] lets out a contented sigh as their form unwinds. ")
- ghostize()
- del src
- return
-
+ OnDeathInLife()
attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/device/soulstone))
@@ -59,3 +51,13 @@
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
return
+
+/mob/living/simple_animal/shade/proc/OnDeathInLife()
+ if(stat == 2)
+ new /obj/item/weapon/ectoplasm (src.loc)
+ for(var/mob/M in viewers(src, null))
+ if((M.client && !( M.blinded )))
+ M.show_message("\red [src] lets out a contented sigh as their form unwinds. ")
+ ghostize()
+ del src
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 425295cd2d9..aded7eb0c09 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -343,7 +343,7 @@
var/obj/machinery/bot/B = target_mob
if(B.health > 0)
return (0)
- return (1)
+ return 1
//Call when target overlay should be added/removed
/mob/living/simple_animal/update_targeted()
diff --git a/code/setup.dm b/code/setup.dm
index efad87a5dd8..815430b2b57 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -836,3 +836,9 @@ var/list/be_special_flags = list(
//Area flags, possibly more to come
#define RAD_SHIELDED 1 //shielded from radiation, clearly
+
+// Custom layer definitions, supplementing the default TURF_LAYER, MOB_LAYER, etc.
+#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
+#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
+#define OBFUSCATION_LAYER 14 //Where images covering the view for eyes are put
+#define SCREEN_LAYER 17 //Mob HUD/effects layer
diff --git a/icons/effects/cameravis.dmi b/icons/effects/cameravis.dmi
index 3ecc9eb80ac..2b819836fc3 100644
Binary files a/icons/effects/cameravis.dmi and b/icons/effects/cameravis.dmi differ