mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-21 12:05:28 +01:00
Cult visual network.
Implementation of a cult visual network, similar to the original camera network. Includes the "eye" itself and the initial construction of a mob that can control one.
This commit is contained in:
-2
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()*/
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
@@ -46,4 +46,4 @@
|
||||
if(istype(L))
|
||||
if(prob(12))
|
||||
L.Weaken(3)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
/mob/living/simple_animal/shade/narsie/Login()
|
||||
..()
|
||||
src.center_on_self()
|
||||
@@ -0,0 +1,3 @@
|
||||
/mob/living/simple_animal/shade/narsie/Logout()
|
||||
..()
|
||||
src.center_on_self()
|
||||
@@ -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]")
|
||||
..()
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user