diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index b3748ee25c..315d020dbe 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1562,3 +1562,4 @@
status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't.
else
layer = HIDING_LAYER
+
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 9a7ba9fb0f..99a86bc9c5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1015,7 +1015,7 @@ default behaviour is:
if(lying != lying_prev)
lying_prev = lying
update_transform()
-
+
return canmove
// Adds overlays for specific modifiers.
@@ -1201,3 +1201,7 @@ default behaviour is:
/mob/living/proc/make_hud_overlays()
return
+
+
+/mob/living/proc/has_vision()
+ return !(eye_blind || (disabilities & BLIND) || stat || blinded)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 0d88e0c96f..a142206cf6 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -418,3 +418,6 @@
ghostize(0)
qdel(src)
+
+/mob/living/silicon/has_vision()
+ return 0 //NOT REAL EYES
diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm
new file mode 100644
index 0000000000..cdcb92e23e
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/aliens/statue.dm
@@ -0,0 +1,315 @@
+// A mob which only moves when it isn't being watched by living beings.
+//SCP - 173 hype
+//Horrible shitcoding and stolen code adaptations below. You have been warned.
+
+/mob/living/simple_animal/hostile/statue
+ name = "statue" // matches the name of the statue with the flesh-to-stone spell
+ desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description
+ icon = 'icons/obj/statue.dmi'
+ icon_state = "human_male"
+ icon_living = "human_male"
+ icon_dead = "human_male"
+ intelligence_level = SA_HUMANOID
+ var/annoyance = 0 //stop fucking staring you creep
+ var/last_response = 0
+ faction = "statue"
+ mob_size = MOB_HUGE
+ response_help = "touches"
+ response_disarm = "pushes"
+ environment_smash = 2
+ can_be_antagged = 1
+ speed = -1
+ maxHealth = 50000
+ health = 50000
+// investigates = 1
+
+
+ harm_intent_damage = 35
+ melee_damage_lower = 30
+ melee_damage_upper = 45
+ attacktext = "clawed"
+ attack_sound = 'sound/hallucinations/growl1.ogg'
+
+ 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 = 9000
+ run_at_them = 0
+
+
+ move_to_delay = 0 // Very fast
+
+ animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue.
+
+ see_in_dark = 13
+ view_range = 35 //So it can run at the victim when out of the view
+// supernatural = 1
+/* aggro_vision_range = 12
+ idle_vision_range = 12
+*/
+ melee_miss_chance = 0
+
+
+ see_invisible = SEE_INVISIBLE_NOLIGHTING
+ sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
+ anchored = 1
+ status_flags = GODMODE // Cannot push also
+ var/last_hit = 0
+ var/cannot_be_seen = 1
+ var/mob/living/creator = null
+ mob_swap_flags = null
+
+// No movement while seen code.
+
+/mob/living/simple_animal/hostile/statue/New(loc, var/mob/living/creator)
+ ..()
+ last_response = world.time
+ // Give spells
+ add_spell(new/spell/aoe_turf/flicker_lights)
+ add_spell(new/spell/aoe_turf/blindness)
+ add_spell(new/spell/aoe_turf/shatter)
+
+
+ // Set creator
+ if(creator)
+ src.creator = creator
+
+/mob/living/simple_animal/hostile/statue/DestroySurroundings()
+ if(can_be_seen(get_turf(loc)))
+ if(client)
+ to_chat(src, "You cannot move, there are eyes on you!")
+ return 0
+ return ..()
+
+/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc)
+ if(can_be_seen(NewLoc))
+ if(client)
+ to_chat(src, "You cannot move, there are eyes on you!")
+ return 0
+ return ..()
+
+/mob/living/simple_animal/hostile/statue/Life()
+ ..()
+ handleAnnoyance()
+ if ((annoyance - 2) > 0)
+ annoyance -= 2
+ if(target_mob)
+ if((annoyance + 5) < 800)
+ annoyance += 5
+
+/mob/living/simple_animal/hostile/statue/handle_stance()
+ if(!..())
+ return
+ if(target_mob) // If we have a target and we're AI controlled
+ var/mob/watching = can_be_seen()
+ // If they're not our target
+ if(watching && watching != target_mob)
+ // This one is closer.
+ if(get_dist(watching, src) > get_dist(target_mob, src))
+ LoseTarget()
+ target_mob = watching
+
+
+/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance()
+ if(last_response + 3 SECONDS < world.time) //so it won't blind people 24/7
+ return
+ var/turf/T = get_turf(loc)
+ if (annoyance > 60)
+ AI_blind()
+ annoyance -= 25
+ if (prob(50))
+ if(T.get_lumcount() * 10 > 1.5)
+ AI_flash()
+ annoyance -= 35
+ last_response = world.time
+ return
+
+
+/mob/living/simple_animal/hostile/statue/proc/AI_blind()
+ for(var/mob/living/L in range(7, src))
+ if(L == src)
+ continue
+ if (prob(75))
+ if(istype(L , /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = L
+ if (H.species == "Diona" || H.species == "Promethean")// can't blink and organic
+ return
+ to_chat(L, "Your eyes feel very heavy.")
+ L.Blind(5)
+ return
+
+/mob/living/simple_animal/hostile/statue/proc/AI_flash()
+ if (prob(60))
+ visible_message("The statue slowly points at the light.")
+ for(var/obj/machinery/light/L in range(10, src))
+ L.flicker()
+ return
+
+
+/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash()
+ for(var/obj/structure/mirror/M in range(10, src))
+ if ((!M.shattered )||(!M.glass))
+ visible_message("The mirror shatters!")
+ M.shatter()
+ return
+
+
+
+/mob/living/simple_animal/hostile/statue/AttackTarget()
+ if(can_be_seen(get_turf(loc)))
+ if(client)
+ to_chat(src, "You cannot attack, there are eyes on you!")
+ return
+ else if(prob(80))
+ spawn(4)
+ ..()
+
+
+
+/mob/living/simple_animal/hostile/statue/face_atom()
+ if(!can_be_seen(get_turf(loc)))
+ ..()
+
+/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination)
+ if(!cannot_be_seen)
+ return null
+ // Check for darkness
+ var/turf/T = get_turf(loc)
+ if(T && destination && T.lighting_overlay)
+ if(T.get_lumcount() * 10 < 1 && destination.get_lumcount() * 10 < 1) // No one can see us in the darkness, right?
+ return null
+ if(T == destination)
+ destination = null
+
+ // We aren't in darkness, loop for viewers.
+ var/list/check_list = list(src)
+ if(destination)
+ check_list += destination
+
+ // This loop will, at most, loop twice.
+ for(var/atom/check in check_list)
+ for(var/mob/living/M in viewers(world.view + 1, check) - src)
+ if(!(M.sdisabilities & BLIND) || !(M.blinded))
+ if(M.has_vision() && !M.isSynthetic())
+ return M
+ for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
+ if(M.occupant && M.occupant.client)
+ if(M.occupant.has_vision() && !M.occupant.isSynthetic())
+ return M.occupant
+ for(var/obj/structure/mirror/M in view(7, check)) //Weeping angels hate mirrors. Probably because they're ugly af
+ if ((!M.shattered )||(!M.glass))
+ annoyance += 2
+ if ((annoyance > 200) && (ai_inactive == 0))
+ AI_mirrorshmash()
+ annoyance -= 200
+ return src //if it sees the mirror, it sees itself, right?
+ return null
+
+// Cannot talk
+
+/mob/living/simple_animal/hostile/statue/say()
+ return 0
+
+// Turn to dust when gibbed
+
+/mob/living/simple_animal/hostile/statue/gib()
+ dust()
+
+
+// Stop attacking clientless mobs
+
+/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs
+ if(isliving(the_target))
+ var/mob/living/L = the_target
+ if(!L.client && !L.ckey)
+ return 0
+ return ..()
+
+// Statue powers
+
+// Flicker lights
+/spell/aoe_turf/flicker_lights
+ name = "Flicker Lights"
+ desc = "You will trigger a large amount of lights around you to flicker."
+ spell_flags = 0
+ charge_max = 400
+ range = 14
+
+/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr)
+ for(var/turf/T in targets)
+ for(var/obj/machinery/light/L in T)
+ L.flicker()
+ return
+
+//Blind AOE
+/spell/aoe_turf/blindness
+ name = "Blindness"
+ desc = "Your prey will be momentarily blind for you to advance on them."
+
+ message = "You glare your eyes."
+ charge_max = 250
+ spell_flags = 0
+ range = 10
+
+/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr)
+ for(var/mob/living/L in living_mob_list)
+ if(L == user)
+ continue
+ var/turf/T = get_turf(L.loc)
+ if(T && T in targets)
+ L.Blind(7)
+ return
+
+
+/spell/aoe_turf/shatter
+ name = "Shatter mirrors!"
+ desc = "That handsome devil has to wait. You have people to make into corpses."
+
+ message = "You glare your eyes."
+ charge_max = 2000
+ silenced = 500
+ spell_flags = 0
+ range = 10
+
+
+
+
+/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr)
+ for(var/obj/structure/mirror/M in range(10, src))
+ if ((!M.shattered )||(!M.glass))
+ M.shatter()
+ return
+
+
+
+/mob/living/simple_animal/hostile/statue/verb/toggle_darkness()
+ set name = "Toggle Darkness"
+ set desc = "You ARE the darkness."
+ set category = "Abilities"
+ seedarkness = !seedarkness
+ plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness)
+ to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.")
+
+
+
+/mob/living/simple_animal/hostile/statue/restrained()
+ . = ..()
+ if(can_be_seen(loc))
+ return 1
+
+
+
+/mob/living/simple_animal/hostile/statue/ListTargets()
+ . = ..()
+
+ for(var/mob/living/V in mobs_in_xray_view(20, src))
+ . += V
+
+
+ return .
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index c8b78cfd65..9b0ca19ed5 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -33,11 +33,14 @@ var/global/photo_count = 0
var/icon/img //Big photo image
var/scribble //Scribble on the back.
var/icon/tiny
+ var/cursed = 0
var/photo_size = 3
/obj/item/weapon/photo/New()
id = photo_count++
+
+
/obj/item/weapon/photo/attack_self(mob/user as mob)
user.examinate(src)
@@ -233,6 +236,11 @@ var/global/photo_count = 0
mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
else
mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
+
+ for(var/mob/living/simple_animal/hostile/statue/S in the_turf)
+ if(S)
+ mob_detail += "You can see a [S] on the photo. Its stare makes you feel uneasy." //"That which holds the image of an angel, becomes itself an angel."
+
return mob_detail
/obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
@@ -274,7 +282,16 @@ var/global/photo_count = 0
y_c--
x_c = x_c - size
+
+
+
var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag)
+ if(findtext(mobs, "Its stare makes you feel uneasy"))
+ p.cursed = 1
+ visible_message("Something starts to slowly manifest from the picture!")
+ spawn(150)
+ new /mob/living/simple_animal/hostile/statue(usr.loc)
+
printpicture(user, p)
/obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag)
@@ -298,7 +315,6 @@ var/global/photo_count = 0
p.pixel_x = rand(-10, 10)
p.pixel_y = rand(-10, 10)
p.photo_size = size
-
return p
/obj/item/device/camera/proc/printpicture(mob/user, obj/item/weapon/photo/p)
@@ -318,6 +334,11 @@ var/global/photo_count = 0
p.pixel_y = pixel_y
p.photo_size = photo_size
p.scribble = scribble
+ p.cursed = cursed
+ if(p.cursed)
+ visible_message("Something starts to slowly manifest from the picture!")
+ spawn(150)
+ new /mob/living/simple_animal/hostile/statue(usr.loc)
if(copy_id)
p.id = id
diff --git a/polaris.dme b/polaris.dme
index 0bb899cea2..b3db30781b 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -1877,6 +1877,7 @@
#include "code\modules\mob\living\simple_animal\aliens\hivebot.dm"
#include "code\modules\mob\living\simple_animal\aliens\mimic.dm"
#include "code\modules\mob\living\simple_animal\aliens\shade.dm"
+#include "code\modules\mob\living\simple_animal\aliens\statue.dm"
#include "code\modules\mob\living\simple_animal\animals\bat.dm"
#include "code\modules\mob\living\simple_animal\animals\bear.dm"
#include "code\modules\mob\living\simple_animal\animals\carp.dm"
@@ -2428,6 +2429,7 @@
#include "code\ZAS\Zone.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
+#include "maps\northern_star\northern_star.dm"
#include "maps\southern_cross\southern_cross.dm"
#include "maps\submaps\_readme.dm"
#include "maps\submaps\space_submaps\space.dm"