mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-21 21:10:30 +01:00
cca0dfe7b6
Part one of our nefarious plans to destroy lag forever, and also accomplish some cool shit. This replaces our renderer system with plane masters, this will also be used to turn skyboxes into backdrops and thus totally remove skybox updating lag. Additionally, this will let us manipulate entire planes very easily to do all sorts of zany shit. All credit goes to the original coders, this is some seriously cool stuff. Also fixes some bizarre smoothing behaviour, reduces updateoverlays calls since now not every single structure in the game tries smoothing with nothing. <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/9b7cecd7-3c47-448b-9dd8-9b904640bf82" /> <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/647d75a2-1bff-45ca-ab92-0aea10631afd" /> --------- Co-authored-by: Matt Atlas <liermattia@gmail.com>
199 lines
5.3 KiB
Plaintext
199 lines
5.3 KiB
Plaintext
// CAMERA 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.
|
|
|
|
#define UPDATE_BUFFER 25 // 2.5 seconds
|
|
|
|
// 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
|
|
var/icon = 'icons/effects/cameravis.dmi'
|
|
var/icon_state = "black"
|
|
var/list/obfuscation_images = list()
|
|
var/static/icon/obfuscation_underlay
|
|
// There is an exploit were clients can memory-edit their local version of the static images, allowing them to see everything. This is a minor attempt to make that more difficult.
|
|
|
|
/datum/obfuscation/Destroy()
|
|
obfuscation_images.Cut()
|
|
. = ..()
|
|
|
|
/datum/obfuscation/proc/has_obfuscation(var/turf/T)
|
|
return !isnull(obfuscation_images[T])
|
|
|
|
/datum/obfuscation/proc/get_obfuscation(var/turf/T)
|
|
var/image/obfuscation = obfuscation_images[T]
|
|
if(!obfuscation)
|
|
obfuscation = image(icon, T, icon_state)
|
|
obfuscation.layer = OBFUSCATION_LAYER
|
|
obfuscation.plane = GAME_PLANE
|
|
if(!obfuscation_underlay)
|
|
// Creating a new icon of a fairly common icon state, adding some random color to prevent address searching, and hoping being static kills memory locality
|
|
var/turf/floor = /turf/simulated/floor/tiled
|
|
obfuscation_underlay = icon(initial(floor.icon), initial(floor.icon_state))
|
|
obfuscation_underlay.Blend(rgb(rand(0,255),rand(0,255),rand(0,255)))
|
|
obfuscation.underlays += obfuscation_underlay
|
|
obfuscation_images[T] = obfuscation
|
|
return obfuscation
|
|
|
|
/datum/chunk
|
|
var/datum/visualnet/visualnet
|
|
var/list/obscuredTurfs = list()
|
|
var/list/visibleTurfs = list()
|
|
var/list/obscured = list()
|
|
var/list/turfs = list()
|
|
var/list/seenby = list()
|
|
var/list/sources = list()
|
|
var/dirty = FALSE
|
|
var/updating = FALSE
|
|
var/x = 0
|
|
var/y = 0
|
|
var/z = 0
|
|
var/datum/obfuscation/obfuscation = new()
|
|
|
|
// Create a new camera chunk, since the chunks are made as they are needed.
|
|
|
|
/datum/chunk/New(var/datum/visualnet/visualnet, x, y, z)
|
|
..()
|
|
src.visualnet = visualnet
|
|
// 0xf = 15
|
|
x &= ~0xf
|
|
y &= ~0xf
|
|
|
|
src.x = x
|
|
src.y = y
|
|
src.z = z
|
|
|
|
var/turf/center = locate(x + 8, y + 8, z)
|
|
|
|
for(var/turf/t in RANGE_TURFS(10, center))
|
|
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
|
turfs[t] = t
|
|
|
|
add_sources(visualnet.sources)
|
|
acquire_visible_turfs(visibleTurfs)
|
|
|
|
// Removes turf that isn't in turfs.
|
|
visibleTurfs &= turfs
|
|
|
|
obscuredTurfs = turfs - visibleTurfs
|
|
|
|
for(var/turf in obscuredTurfs)
|
|
var/turf/t = turf
|
|
obscured += obfuscation.get_obfuscation(t)
|
|
|
|
|
|
/datum/chunk/Destroy()
|
|
visualnet = null
|
|
. = ..()
|
|
|
|
/datum/chunk/proc/add_sources(var/list/sources)
|
|
var/turf/center = locate(x + 8, y + 8, z)
|
|
for(var/entry in sources)
|
|
var/atom/A = entry
|
|
if(get_dist(get_turf(A), center) > 16)
|
|
continue
|
|
add_source(A)
|
|
|
|
// The visualnet checks if a source already exists or not, as appropriate, before calling add/remove_source on the chunk
|
|
/datum/chunk/proc/add_source(var/atom/source)
|
|
if(source in sources)
|
|
return FALSE
|
|
sources += source
|
|
visibility_changed()
|
|
return TRUE
|
|
|
|
/datum/chunk/proc/remove_source(var/atom/source)
|
|
if(sources.Remove(source))
|
|
visibility_changed()
|
|
return TRUE
|
|
return FALSE
|
|
|
|
// Visualnet adds and removes eyes.
|
|
|
|
/datum/chunk/proc/add_eye(mob/abstract/eye/freelook/eye)
|
|
seenby += eye
|
|
eye.visibleChunks += src
|
|
if(eye.owner && eye.owner.client)
|
|
eye.owner.client.images += obscured
|
|
|
|
/datum/chunk/proc/remove_eye(mob/abstract/eye/freelook/eye)
|
|
seenby -= eye
|
|
eye.visibleChunks -= src
|
|
if(eye.owner && eye.owner.client)
|
|
eye.owner.client.images -= obscured
|
|
|
|
// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
|
|
// instead be flagged to update the next time an AI Eye moves near it.
|
|
|
|
/datum/chunk/proc/visibility_changed(var/update_now = FALSE)
|
|
if(update_now)
|
|
update(TRUE)
|
|
return
|
|
|
|
if(updating)
|
|
return
|
|
|
|
if(seenby.len)
|
|
updating = TRUE
|
|
addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER)
|
|
else
|
|
dirty = TRUE
|
|
|
|
// The actual updating.
|
|
|
|
/datum/chunk/proc/update(var/forced = FALSE)
|
|
if(!updating && !forced)
|
|
return
|
|
|
|
var/list/newVisibleTurfs = new()
|
|
acquire_visible_turfs(newVisibleTurfs)
|
|
|
|
// Removes turf that isn't in turfs.
|
|
newVisibleTurfs &= turfs
|
|
|
|
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
|
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
|
|
|
visibleTurfs = newVisibleTurfs
|
|
obscuredTurfs = turfs - newVisibleTurfs
|
|
|
|
for(var/turf in visAdded)
|
|
var/turf/t = turf
|
|
if(obfuscation.has_obfuscation(t))
|
|
var/image/obfuscation_image = obfuscation.get_obfuscation(t)
|
|
obscured -= obfuscation_image
|
|
for(var/eye in seenby)
|
|
var/mob/abstract/eye/m = eye
|
|
if (m && m.owner && m.owner.client)
|
|
m.owner.client.images -= obfuscation_image
|
|
|
|
for(var/turf in visRemoved)
|
|
var/turf/t = turf
|
|
if(obscuredTurfs[t])
|
|
var/image/obfuscation_image = obfuscation.get_obfuscation(t)
|
|
obscured += obfuscation_image
|
|
|
|
for(var/eye in seenby)
|
|
var/mob/abstract/eye/m = eye
|
|
if (m && m.owner && m.owner.client)
|
|
m.owner.client.images += obfuscation_image
|
|
|
|
dirty = FALSE
|
|
updating = FALSE
|
|
|
|
/datum/chunk/proc/acquire_visible_turfs(var/list/visible)
|
|
return
|
|
|
|
/proc/seen_turfs_in_range(var/source, var/range)
|
|
. = list()
|
|
var/turf/pos = get_turf(source)
|
|
if(pos)
|
|
for(var/turf/T in get_hear(range, pos))
|
|
. += T
|
|
|
|
#undef UPDATE_BUFFER
|