/tg/ vis openspace

This commit is contained in:
Aronai Sieyes
2021-06-30 15:39:07 -04:00
parent d7d7c22846
commit b4387f251d
48 changed files with 440 additions and 640 deletions

View File

@@ -49,11 +49,10 @@ What is the naming convention for planes or layers?
#define PLANE_LOOKINGGLASS -78 // For the Looking Glass holodecks
#define PLANE_LOOKINGGLASS_IMG -77 // For the Looking Glass holodecks
// OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive
#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 27) //VOREStation Edit
#define OPENSPACE_PLANE_START -73
#define OPENSPACE_PLANE_END -48 //VOREStation Edit
#define OVER_OPENSPACE_PLANE -47 //VOREStation Edit
#define OPENSPACE_PLANE -51 // Has to be lower than turfs
#define OPENSPACE_LAYER 600 // Above every other layer
#define OPENSPACE_BACKDROP_PLANE -50 // Black square has to be above openspace turfs
// Turf Planes
#define PLATING_PLANE -44 // Plating
@@ -70,8 +69,11 @@ What is the naming convention for planes or layers?
#define WATER_LAYER 3.0 // Layer for water overlays.
#define ABOVE_TURF_LAYER 3.1 // Snow and wallmounted/floormounted equipment
#define DECAL_PLANE -44 // Permanent decals
#define DECAL_LAYER 10
#define DIRTY_PLANE -43 // Nonpermanent decals
#define DIRTY_LAYER 11
#define BLOOD_PLANE -42 // Blood is really dirty, but we can do special stuff if we separate it
#define BLOOD_DECAL_LAYER 12
// Obj planes
#define OBJ_PLANE -35

View File

@@ -218,7 +218,9 @@
#define COMSIG_TURF_CHANGE "turf_change"
///from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity"
///from base of turf/New(): (turf/source, direction)
///from base of turf/multiz_turf_del(): (turf/source, direction)
#define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del"
///from base of turf/multiz_turf_new: (turf/source, direction)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new"
// /atom/movable signals

View File

@@ -379,38 +379,39 @@
#define VIS_LIGHTING 2
#define VIS_O_LIGHT 3
#define VIS_EMISSIVE 4
#define VIS_OPENSPACE 5
#define VIS_GHOSTS 5
#define VIS_AI_EYE 6
#define VIS_GHOSTS 6
#define VIS_AI_EYE 7
#define VIS_CH_STATUS 7
#define VIS_CH_HEALTH 8
#define VIS_CH_LIFE 9
#define VIS_CH_ID 10
#define VIS_CH_WANTED 11
#define VIS_CH_IMPLOYAL 12
#define VIS_CH_IMPTRACK 13
#define VIS_CH_IMPCHEM 14
#define VIS_CH_SPECIAL 15
#define VIS_CH_STATUS_OOC 16
#define VIS_CH_STATUS 8
#define VIS_CH_HEALTH 9
#define VIS_CH_LIFE 10
#define VIS_CH_ID 11
#define VIS_CH_WANTED 12
#define VIS_CH_IMPLOYAL 13
#define VIS_CH_IMPTRACK 14
#define VIS_CH_IMPCHEM 15
#define VIS_CH_SPECIAL 16
#define VIS_CH_STATUS_OOC 17
#define VIS_ADMIN1 17
#define VIS_ADMIN2 18
#define VIS_ADMIN3 19
#define VIS_ADMIN1 18
#define VIS_ADMIN2 19
#define VIS_ADMIN3 20
#define VIS_MESONS 20
#define VIS_MESONS 21
#define VIS_TURFS 21
#define VIS_OBJS 22
#define VIS_MOBS 23
#define VIS_TURFS 22
#define VIS_OBJS 23
#define VIS_MOBS 24
#define VIS_BUILDMODE 24
#define VIS_BUILDMODE 25
#define VIS_CLOAKED 25
#define VIS_CLOAKED 26
#define VIS_STATUS 26
#define VIS_STATUS 27
#define VIS_COUNT 26 //Must be highest number from above.
#define VIS_COUNT 27 //Must be highest number from above.
//Some mob icon layering defines
#define BODY_LAYER -100

View File

@@ -1,13 +1,13 @@
#undef VIS_COUNT
#define VIS_CH_STATUS_R 27
#define VIS_CH_HEALTH_VR 28
#define VIS_CH_BACKUP 29
#define VIS_CH_VANTAG 30
#define VIS_CH_STATUS_R 28
#define VIS_CH_HEALTH_VR 29
#define VIS_CH_BACKUP 30
#define VIS_CH_VANTAG 31
#define VIS_AUGMENTED 31
#define VIS_AUGMENTED 32
#define VIS_COUNT 31
#define VIS_COUNT 32
//Protean organs
#define O_ORCH "orchestrator"

View File

@@ -78,7 +78,6 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_HOLOMAPS -5
#define INIT_ORDER_NIGHTSHIFT -6
#define INIT_ORDER_OVERLAY -7
#define INIT_ORDER_OPENSPACE -10
#define INIT_ORDER_XENOARCH -20
#define INIT_ORDER_CIRCUIT -21
#define INIT_ORDER_AI -22

View File

@@ -273,9 +273,24 @@
var/list/hear = dview(range,T,INVISIBILITY_MAXIMUM)
var/list/hearturfs = list()
// Openspace visibility handling
// Below turfs we can see
for(var/turf/simulated/open/O in hear)
var/turf/U = GetBelow(O)
while(istype(U))
hearturfs |= U
U = GetBelow(U)
// Above us
var/above_range = range
var/turf/Ab = GetAbove(T)
while(isopenspace(Ab) && --above_range > 0)
hear |= dview(above_range,Ab,INVISIBILITY_MAXIMUM)
Ab = GetAbove(Ab)
for(var/thing in hear)
if(istype(thing, /obj)) //Can't use isobj() because /atom/movable returns true in that, and so lighting overlays would be included
if(istype(thing, /obj)) //Can't use isobj() because /atom/movable returns true in that
objs += thing
hearturfs |= get_turf(thing)
if(ismob(thing))

View File

@@ -156,10 +156,6 @@
if(z_level_change) // Same goes for mobs.
M.onTransitZ(T.z, X.z)
if(istype(M, /mob/living))
var/mob/living/LM = M
LM.check_shadow() // Need to check their Z-shadow, which is normally done in forceMove().
if(shuttlework)
var/turf/simulated/shuttle/SS = T
SS.landed_holder.leave_turf(turftoleave)

View File

@@ -852,10 +852,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
if(z_level_change) // Same goes for mobs.
M.onTransitZ(T.z, X.z)
if(istype(M, /mob/living))
var/mob/living/LM = M
LM.check_shadow() // Need to check their Z-shadow, which is normally done in forceMove().
if(shuttlework)
var/turf/simulated/shuttle/SS = T
SS.landed_holder.leave_turf()

View File

@@ -1,107 +0,0 @@
//
// Controller handling icon updates of open space turfs
//
GLOBAL_VAR_INIT(open_space_initialised, FALSE)
SUBSYSTEM_DEF(open_space)
name = "Open Space"
wait = 2 // 5 times per second.
init_order = INIT_ORDER_OPENSPACE
var/list/turfs_to_process = list() // List of turfs queued for update.
var/list/turfs_to_process_old = null // List of turfs currently being updated.
var/counter = 1 // Can't use .len because we need to iterate in order
var/static/image/over_OS_darkness // Image overlayed over the bottom turf with stuff in it.
/datum/controller/subsystem/open_space/Initialize(timeofday)
over_OS_darkness = image('icons/turf/open_space.dmi', "black_open")
over_OS_darkness.plane = OVER_OPENSPACE_PLANE
over_OS_darkness.layer = MOB_LAYER
initialize_open_space()
// Pre-process open space turfs once before the round starts.
fire(FALSE, TRUE)
return ..()
/datum/controller/subsystem/open_space/Recover()
flags |= SS_NO_INIT // Make extra sure we don't initialize twice.
. = ..()
/datum/controller/subsystem/open_space/fire(resumed = 0, init_tick_checks = FALSE)
// We use a different list so any additions to the update lists during a delay from MC_TICK_CHECK
// don't cause things to be cut from the list without being updated.
//If we're not resuming, this must mean it's a new iteration so we have to grab the turfs
if (!resumed)
src.counter = 1
src.turfs_to_process_old = turfs_to_process
turfs_to_process = list()
//cache for sanic speed (lists are references anyways)
var/list/turfs_to_process_old = src.turfs_to_process_old
var/counter = src.counter
while(counter <= turfs_to_process_old.len)
var/turf/T = turfs_to_process_old[counter]
counter += 1
if(!QDELETED(T))
update_turf(T)
if (init_tick_checks)
CHECK_TICK // Used during initialization processing
else if (MC_TICK_CHECK)
src.counter = counter // Save for when we're resumed
return // Used during normal MC processing.
/datum/controller/subsystem/open_space/proc/update_turf(var/turf/T)
for(var/atom/movable/A in T)
A.fall()
T.update_icon()
/datum/controller/subsystem/open_space/proc/add_turf(var/turf/T, var/recursive = 0)
ASSERT(isturf(T))
// Check for multiple additions
// Pointless to process the same turf twice. But we need to push it to the end of the list
// because any turfs below it need to process first.
turfs_to_process -= T
turfs_to_process += T
if(recursive > 0)
var/turf/above = GetAbove(T)
if(above && isopenspace(above))
add_turf(above, recursive)
// Queue the initial updates of open space turfs when the game starts. This will lag!
/datum/controller/subsystem/open_space/proc/initialize_open_space()
// Do initial setup from bottom to top.
for(var/zlevel = 1 to world.maxz)
for(var/turf/simulated/open/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
add_turf(T)
CHECK_TICK
GLOB.open_space_initialised = TRUE
/datum/controller/subsystem/open_space/stat_entry(msg_prefix)
return ..("T [turfs_to_process.len]")
/obj/update_icon()
. = ..()
if(GLOB.open_space_initialised && !invisibility && isturf(loc))
var/turf/T = GetAbove(src)
if(isopenspace(T))
// log_debug("[T] ([T.x],[T.y],[T.z]) queued for update for [src].update_icon()")
SSopen_space.add_turf(T, 1)
// Ouch... this is painful. But is there any other way?
/* - No for now
/obj/New()
. = ..()
if(open_space_initialised && !invisibility)
var/turf/T = GetAbove(src)
if(isopenspace(T))
// log_debug("[T] ([T.x],[T.y],[T.z]) queued for update for [src]New()")
OS_controller.add_turf(T, 1)
*/
// We probably should hook Destroy() If we can think of something more efficient, lets hear it.
/obj/Destroy()
if(GLOB.open_space_initialised && !invisibility && isturf(loc))
var/turf/T = GetAbove(src)
if(isopenspace(T))
SSopen_space.add_turf(T, 1)
. = ..() // Important that this be at the bottom, or we will have been moved to nullspace.

View File

@@ -0,0 +1,82 @@
/datum/element/turf_z_transparency
var/show_bottom_level = FALSE
///This proc sets up the signals to handle updating viscontents when turfs above/below update. Handle plane and layer here too so that they don't cover other obs/turfs in Dream Maker
/datum/element/turf_z_transparency/Attach(datum/target, show_bottom_level = TRUE)
. = ..()
if(!isturf(target))
return ELEMENT_INCOMPATIBLE
var/turf/our_turf = target
src.show_bottom_level = show_bottom_level
our_turf.plane = OPENSPACE_PLANE
our_turf.layer = OPENSPACE_LAYER
RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, .proc/on_multiz_turf_del)
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_turf_new)
update_multiz(our_turf, TRUE, TRUE)
/datum/element/turf_z_transparency/Detach(datum/source)
. = ..()
var/turf/our_turf = source
our_turf.vis_contents.len = 0
///Updates the viscontents or underlays below this tile.
/datum/element/turf_z_transparency/proc/update_multiz(turf/our_turf, prune_on_fail = FALSE, init = FALSE)
var/turf/below_turf = GetBelow(our_turf)
if(!below_turf)
our_turf.vis_contents.len = 0
if(!show_bottom_level(our_turf) && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
our_turf.ChangeTurf(/turf/simulated/floor/plating)
return FALSE
if(init)
below_turf?.update_icon() // So the 'ceiling-less' overlay gets added.
our_turf.vis_contents += below_turf
if(is_blocked_turf(our_turf)) //Show girders below closed turfs
var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01)
girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += girder_underlay
var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02)
plating_underlay = RESET_ALPHA | RESET_COLOR
our_turf.underlays += plating_underlay
return TRUE
/datum/element/turf_z_transparency/proc/on_multiz_turf_del(turf/our_turf, turf/below_turf, dir)
SIGNAL_HANDLER
if(dir != DOWN)
return
update_multiz(our_turf)
/datum/element/turf_z_transparency/proc/on_multiz_turf_new(turf/our_turf, turf/below_turf, dir)
SIGNAL_HANDLER
if(dir != DOWN)
return
update_multiz(our_turf)
///Called when there is no real turf below this turf
/datum/element/turf_z_transparency/proc/show_bottom_level(turf/our_turf)
if(!show_bottom_level)
return FALSE
var/turf/path = get_base_turf(our_turf.z) || /turf/space
if(!ispath(path))
path = text2path(path)
if(!ispath(path))
warning("Z-level [our_turf.z] has invalid baseturf '[get_base_turf(our_turf.z)]'")
path = /turf/space
var/do_plane = ispath(path, /turf/space) ? SPACE_PLANE : null
var/do_state = ispath(path, /turf/space) ? "white" : initial(path.icon_state)
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), do_state, layer = TURF_LAYER-0.02, plane = do_plane)
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += underlay_appearance
return TRUE

View File

@@ -63,10 +63,6 @@
moveToNullspace()
vis_contents.Cut()
for(var/atom/movable/A as anything in vis_locs)
A.vis_contents -= src
if(pulledby)
pulledby.stop_pulling()

View File

@@ -30,6 +30,7 @@
icon = 'icons/obj/monitors_vr.dmi' //VOREStation Edit - Other icons
icon_state = "alarm0"
layer = ABOVE_WINDOW_LAYER
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
anchored = 1
use_power = USE_POWER_IDLE
idle_power_usage = 80

View File

@@ -82,6 +82,7 @@
desc = "Used to print temporary passes for people. Handy!"
icon_state = "guest"
layer = ABOVE_WINDOW_LAYER
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
icon_keyboard = null
icon_screen = "pass"
density = 0

View File

@@ -8,6 +8,7 @@ FIRE ALARM
icon_state = "fire"
layer = ABOVE_WINDOW_LAYER
blocks_emissive = FALSE
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/detecting = 1.0
var/working = 1.0
var/time = 10.0

View File

@@ -8,6 +8,7 @@ GLOBAL_LIST_EMPTY(holoposters)
use_power = 1
idle_power_usage = 80
power_channel = ENVIRON
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/icon_forced = FALSE
var/examine_addon = "It appears to be powered off."
var/mytimer

View File

@@ -12,6 +12,7 @@
idle_power_usage = 10
power_channel = LIGHT
blocks_emissive = FALSE
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/on = 1
var/area/area = null
var/otherarea = null

View File

@@ -3,6 +3,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "fuel"
plane = DIRTY_PLANE
layer = DIRTY_LAYER
anchored = 1
var/amount = 1
generic_filth = TRUE

View File

@@ -11,6 +11,7 @@ var/global/list/image/splatter_cache=list()
density = 0
anchored = 1
plane = BLOOD_PLANE
layer = BLOOD_DECAL_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")

View File

@@ -7,6 +7,7 @@ generic_filth = TRUE means when the decal is saved, it will be switched out for
/obj/effect/decal/cleanable
plane = DIRTY_PLANE
layer = DIRTY_LAYER
var/persistent = FALSE
var/generic_filth = FALSE
var/age = 0

View File

@@ -3,6 +3,7 @@
desc = "A rune drawn in crayon."
icon = 'icons/obj/rune.dmi'
plane = DIRTY_PLANE
layer = DIRTY_LAYER
anchored = 1
/obj/effect/decal/cleanable/crayon/New(location,main = "#FFFFFF",shade = "#000000",var/type = "rune")

View File

@@ -15,32 +15,20 @@
w_class = ITEMSIZE_NORMAL
show_messages = 1
/// List of objects which this item can store (if set, it can't store anything else)
var/list/can_hold
/// List of objects which this item can't store (in effect only if can_hold isn't set)
var/list/cant_hold
/// List of mobs which are currently seeing the contents of this item's storage
var/list/is_seeing
var/list/can_hold = new/list() //List of objects which this item can store (if set, it can't store anything else)
var/list/cant_hold = new/list() //List of objects which this item can't store (in effect only if can_hold isn't set)
var/list/is_seeing = new/list() //List of mobs which are currently seeing the contents of this item's storage
var/max_w_class = ITEMSIZE_SMALL //Max size of objects that this object can store (in effect only if can_hold isn't set)
var/max_storage_space = ITEMSIZE_COST_SMALL * 4 //The sum of the storage costs of all the items in this storage item.
var/storage_slots = null //The number of storage slots in this container. If null, it uses the volume-based storage instead.
/// Boxes screen object for fixed-size storage (belts, etc)
var/obj/screen/storage/boxes = null
/// List of 'click catchers' for boxes for fixed-size storage
var/list/box_catchers = null
/// For dynamic storage, the leftmost pixel column for the whole storage display. Most of the interesting effects are hung on this in vis_contents.
var/obj/screen/storage/storage_start = null
/// For dynamic storage, the majority of the width of the whole storage display. Decorative, but sized to the width appropriate to represent how much storage there is.
var/obj/screen/storage/storage_start = null //storage UI
var/obj/screen/storage/storage_continue = null
/// For dynamic storage, the rightmost pixel column for the whole storage display. Decorative.
var/obj/screen/storage/storage_end = null
/// The "X" button at the far right of the storage
var/obj/screen/storage/stored_start = null
var/obj/screen/storage/stored_continue = null
var/obj/screen/storage/stored_end = null
var/obj/screen/close/closer = null
var/use_to_pickup //Set this to make it possible to use this item in an inverse way, so you can have the item in your hand and click items on the floor to pick them up.
var/display_contents_with_number //Set this to make the storage item group contents of the same type and display them as a number.
var/allow_quick_empty //Set this variable to allow the object to have the 'empty' verb, which dumps all the contents on the floor.
@@ -50,67 +38,15 @@
var/list/starts_with //Things to spawn on the box on spawn
var/empty //Mapper override to spawn an empty version of a container that usually has stuff
/obj/item/weapon/storage/Initialize()
. = ..()
if(allow_quick_empty)
verbs += /obj/item/weapon/storage/verb/quick_empty
else
verbs -= /obj/item/weapon/storage/verb/quick_empty
if(allow_quick_gather)
verbs += /obj/item/weapon/storage/verb/toggle_gathering_mode
else
verbs -= /obj/item/weapon/storage/verb/toggle_gathering_mode
if(storage_slots)
src.boxes = new /obj/screen/storage( )
src.boxes.name = "storage"
src.boxes.master = src
src.boxes.icon_state = "block"
src.boxes.screen_loc = "7,7 to 10,8"
else
src.storage_start = new /obj/screen/storage( )
src.storage_start.name = "storage"
src.storage_start.master = src
src.storage_start.icon_state = "storage_start"
src.storage_start.screen_loc = "7,7 to 10,8"
src.storage_continue = new /obj/screen/storage( )
src.storage_continue.name = "storage"
src.storage_continue.master = src
src.storage_continue.icon_state = "storage_continue"
src.storage_continue.screen_loc = "7,7 to 10,8"
src.storage_end = new /obj/screen/storage( )
src.storage_end.name = "storage"
src.storage_end.master = src
src.storage_end.icon_state = "storage_end"
src.storage_end.screen_loc = "7,7 to 10,8"
src.closer = new /obj/screen/close( )
src.closer.master = src
src.closer.icon_state = "storage_close"
src.closer.hud_layerise()
orient2hud()
if(LAZYLEN(starts_with) && !empty)
for(var/newtype in starts_with)
var/count = starts_with[newtype] || 1 //Could have left it blank.
while(count)
count--
new newtype(src)
starts_with = null //Reduce list count.
calibrate_size()
/obj/item/weapon/storage/Destroy()
close_all()
clear_slot_catchers()
QDEL_NULL(boxes)
QDEL_NULL(storage_start)
QDEL_NULL(storage_continue)
QDEL_NULL(storage_end)
QDEL_NULL(stored_start)
QDEL_NULL(stored_continue)
QDEL_NULL(stored_end)
QDEL_NULL(closer)
if(ismob(loc))
@@ -177,58 +113,44 @@
return
if(user.s_active)
user.s_active.hide_from(user)
var/client/C = user.client
if(!C)
return
if(storage_slots)
C.screen += src.boxes
create_slot_catchers()
C.screen += src.box_catchers
user.client.screen -= src.boxes
user.client.screen -= src.storage_start
user.client.screen -= src.storage_continue
user.client.screen -= src.storage_end
user.client.screen -= src.closer
user.client.screen -= src.contents
user.client.screen += src.closer
user.client.screen += src.contents
if(storage_slots)
user.client.screen += src.boxes
else
C.screen += src.storage_start
C.screen += src.storage_continue
C.screen += src.storage_end
C.screen += src.closer
C.screen += src.contents
user.client.screen += src.storage_start
user.client.screen += src.storage_continue
user.client.screen += src.storage_end
user.s_active = src
LAZYDISTINCTADD(is_seeing,user)
is_seeing |= user
return
/obj/item/weapon/storage/proc/hide_from(mob/user as mob)
var/client/C = user.client
LAZYREMOVE(is_seeing,user)
if(!C)
if(!LAZYLEN(is_seeing))
clear_slot_catchers()
if(!user.client)
return
if(storage_slots)
C.screen -= src.boxes
C.screen -= src.box_catchers
else
C.screen -= src.storage_start
C.screen -= src.storage_continue
C.screen -= src.storage_end
C.screen -= src.closer
C.screen -= src.contents
user.client.screen -= src.boxes
user.client.screen -= src.storage_start
user.client.screen -= src.storage_continue
user.client.screen -= src.storage_end
user.client.screen -= src.closer
user.client.screen -= src.contents
if(user.s_active == src)
user.s_active = null
if(!LAZYLEN(is_seeing))
clear_slot_catchers()
is_seeing -= user
/obj/item/weapon/storage/proc/open(mob/user as mob)
if (use_sound)
playsound(src, src.use_sound, 50, 0, -5)
orient2hud(user)
if(user.s_active)
if (user.s_active)
user.s_active.close(user)
show_to(user)
@@ -248,25 +170,9 @@
if(M.s_active == src && M.client)
cansee |= M
else
LAZYREMOVE(is_seeing,M)
is_seeing -= M
return cansee
/obj/item/weapon/storage/proc/create_slot_catchers()
clear_slot_catchers()
var/list/new_catchers = list()
for(var/obj/item/I in contents)
var/atom/movable/storage_slot/SS = new(null, I)
SS.screen_loc = I.screen_loc
SS.mouse_opacity = MOUSE_OPACITY_OPAQUE
new_catchers += SS
box_catchers = new_catchers
/obj/item/weapon/storage/proc/clear_slot_catchers()
if(box_catchers)
for(var/mob/M in is_seeing)
M.client?.screen -= box_catchers
QDEL_LIST_NULL(box_catchers)
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
/obj/item/weapon/storage/proc/orient_objs(tx, ty, mx, my)
@@ -294,9 +200,6 @@
ND.sample_object.screen_loc = "[cx]:16,[cy]:16"
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
ND.sample_object.hud_layerise()
var/atom/movable/storage_slot/SS = new(null, ND.sample_object)
SS.screen_loc = ND.sample_object.screen_loc
SS.mouse_opacity = MOUSE_OPACITY_OPAQUE
cx++
if (cx > (4+cols))
cx = 4
@@ -306,9 +209,6 @@
O.screen_loc = "[cx]:16,[cy]:16"
O.maptext = ""
O.hud_layerise()
var/atom/movable/storage_slot/SS = new(null, O)
SS.screen_loc = O.screen_loc
SS.mouse_opacity = MOUSE_OPACITY_OPAQUE
cx++
if (cx > (4+cols))
cx = 4
@@ -317,20 +217,6 @@
return
/obj/item/weapon/storage/proc/space_orient_objs(var/list/obj/item/display_contents)
SHOULD_NOT_SLEEP(TRUE)
/// A prototype for drawing the leftmost border behind each item in storage
var/static/mutable_appearance/stored_start
/// A prototype for drawing the wide backing space behind each item in storage
var/static/mutable_appearance/stored_continue
/// A prototype for drawing the rightmost border behind each item in storage
var/static/mutable_appearance/stored_end
if(!stored_start)
// Because these are static and manipulated all the time by different storages, you'd better make 100000% sure this proc never sleeps
stored_start = mutable_appearance(icon = 'icons/mob/screen1.dmi', icon_state = "stored_start", layer = 0.1, plane = PLANE_PLAYER_HUD_ITEMS)
stored_continue = mutable_appearance(icon = 'icons/mob/screen1.dmi', icon_state = "stored_continue", layer = 0.1, plane = PLANE_PLAYER_HUD_ITEMS)
stored_end = mutable_appearance(icon = 'icons/mob/screen1.dmi', icon_state = "stored_end", layer = 0.1, plane = PLANE_PLAYER_HUD_ITEMS)
var/baseline_max_storage_space = INVENTORY_STANDARD_SPACE / 2 //should be equal to default backpack capacity // This is a lie.
// Above var is misleading, what it does upon changing is makes smaller inventory sizes have smaller space on the UI.
@@ -340,7 +226,7 @@
var/stored_cap_width = 4 //length of sprite for start and end of the box representing the stored item
var/storage_width = min( round( 224 * max_storage_space/baseline_max_storage_space ,1) ,274) //length of sprite for the box representing total storage space
QDEL_LIST_NULL(storage_start.vis_contents)
storage_start.cut_overlays()
var/matrix/M = matrix()
M.Scale((storage_width-storage_cap_width*2+3)/32,1)
@@ -354,7 +240,6 @@
var/endpoint = 1
for(var/obj/item/O in contents)
var/atom/movable/storage_slot/SS = new(null, O)
startpoint = endpoint + 1
endpoint += storage_width * O.get_storage_cost()/max_storage_space
@@ -365,19 +250,21 @@
M_continue.Scale((endpoint-startpoint-stored_cap_width*2)/32,1)
M_continue.Translate(startpoint+stored_cap_width+(endpoint-startpoint-stored_cap_width*2)/2 - 16,0)
M_end.Translate(endpoint-stored_cap_width,0)
stored_start.transform = M_start
stored_continue.transform = M_continue
stored_end.transform = M_end
SS.add_overlay(list(stored_start, stored_continue, stored_end))
src.stored_start.transform = M_start
src.stored_continue.transform = M_continue
src.stored_end.transform = M_end
storage_start.add_overlay(stored_start)
storage_start.add_overlay(stored_continue)
storage_start.add_overlay(stored_end)
O.screen_loc = "4:[round((startpoint+endpoint)/2)+2],2:16"
O.maptext = ""
O.hud_layerise()
storage_start.vis_contents += SS
src.closer.screen_loc = "4:[storage_width+19],2:16"
return
/datum/numbered_display
var/obj/item/sample_object
var/number
@@ -434,14 +321,14 @@
to_chat(usr, "<span class='notice'>[src] is full, make some space.</span>")
return 0 //Storage item is full
if(LAZYLEN(can_hold) && !is_type_in_list(W, can_hold))
if(can_hold.len && !is_type_in_list(W, can_hold))
if(!stop_messages)
if (istype(W, /obj/item/weapon/hand_labeler))
return 0
to_chat(usr, "<span class='notice'>[src] cannot hold [W].</span>")
return 0
if(LAZYLEN(cant_hold) && is_type_in_list(W, cant_hold))
if(cant_hold.len && is_type_in_list(W, cant_hold))
if(!stop_messages)
to_chat(usr, "<span class='notice'>[src] cannot hold [W].</span>")
return 0
@@ -510,8 +397,10 @@
var/obj/item/weapon/storage/fancy/F = src
F.update_icon(1)
for(var/mob/M in is_seeing)
M?.client.screen -= W
for(var/mob/M in range(1, src.loc))
if (M.s_active == src)
if (M.client)
M.client.screen -= W
if(new_location)
if(ismob(loc))
@@ -524,10 +413,10 @@
else
W.forceMove(get_turf(src))
for(var/mob/M in is_seeing)
if(M.s_active == src)
orient2hud(M)
show_to(M)
if(usr)
src.orient2hud(usr)
if(usr.s_active)
usr.s_active.show_to(usr)
if(W.maptext)
W.maptext = ""
W.on_exit_storage(src)
@@ -647,6 +536,68 @@
for(var/obj/item/I in contents)
remove_from_storage(I, T)
/obj/item/weapon/storage/Initialize()
. = ..()
if(allow_quick_empty)
verbs += /obj/item/weapon/storage/verb/quick_empty
else
verbs -= /obj/item/weapon/storage/verb/quick_empty
if(allow_quick_gather)
verbs += /obj/item/weapon/storage/verb/toggle_gathering_mode
else
verbs -= /obj/item/weapon/storage/verb/toggle_gathering_mode
src.boxes = new /obj/screen/storage( )
src.boxes.name = "storage"
src.boxes.master = src
src.boxes.icon_state = "block"
src.boxes.screen_loc = "7,7 to 10,8"
src.storage_start = new /obj/screen/storage( )
src.storage_start.name = "storage"
src.storage_start.master = src
src.storage_start.icon_state = "storage_start"
src.storage_start.screen_loc = "7,7 to 10,8"
src.storage_continue = new /obj/screen/storage( )
src.storage_continue.name = "storage"
src.storage_continue.master = src
src.storage_continue.icon_state = "storage_continue"
src.storage_continue.screen_loc = "7,7 to 10,8"
src.storage_end = new /obj/screen/storage( )
src.storage_end.name = "storage"
src.storage_end.master = src
src.storage_end.icon_state = "storage_end"
src.storage_end.screen_loc = "7,7 to 10,8"
src.stored_start = new /obj //we just need these to hold the icon
src.stored_start.icon_state = "stored_start"
src.stored_continue = new /obj
src.stored_continue.icon_state = "stored_continue"
src.stored_end = new /obj
src.stored_end.icon_state = "stored_end"
src.closer = new /obj/screen/close( )
src.closer.master = src
src.closer.icon_state = "storage_close"
src.closer.hud_layerise()
orient2hud()
if(LAZYLEN(starts_with) && !empty)
for(var/newtype in starts_with)
var/count = starts_with[newtype] || 1 //Could have left it blank.
while(count)
count--
new newtype(src)
starts_with = null //Reduce list count.
calibrate_size()
/obj/item/weapon/storage/proc/calibrate_size()
var/total_storage_space = 0
for(var/obj/item/I in contents)
@@ -723,8 +674,7 @@
/obj/item/weapon/storage/proc/make_exact_fit()
storage_slots = contents.len
LAZYCLEARLIST(can_hold)
can_hold = list()
can_hold.Cut()
max_w_class = 0
max_storage_space = 0
for(var/obj/item/I in src)
@@ -797,32 +747,3 @@
for (var/obj/O in contents)
remove_from_storage(O, T)
O.tumble(2)
/// Hangar for storage backdrops, so that we can redirect clicks from them to our item for QOL
/atom/movable/storage_slot
name = "stored - "
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
plane = PLANE_PLAYER_HUD_ITEMS
layer = 0.1
alpha = 200
var/weakref/held_item
/atom/movable/storage_slot/New(newloc, obj/item/held_item)
ASSERT(held_item)
name += held_item.name
src.held_item = weakref(held_item)
/atom/movable/storage_slot/Destroy()
held_item = null
/// Has to be this way. The fact that the overlays will be constantly mutated by other storage means we can't wait.
/atom/movable/storage_slot/add_overlay(list/somethings)
ASSERT(islist(somethings))
overlays = somethings
/atom/movable/storage_slot/Click()
var/obj/item/I = held_item?.resolve()
if(I)
usr.ClickOn(I)
return 1

View File

@@ -1,6 +1,7 @@
/obj
layer = OBJ_LAYER
plane = OBJ_PLANE
vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of obj in openspace.
//Used to store information about the contents of the object.
var/list/matter
var/w_class // Size of the object.

View File

@@ -4,7 +4,7 @@
icon = 'icons/turf/catwalks.dmi'
icon_state = "catwalk"
plane = DECAL_PLANE
layer = ABOVE_UTILITY
layer = DECAL_LAYER
density = 0
anchored = 1.0
var/hatch_open = FALSE
@@ -140,7 +140,7 @@
anchored = 1.0
var/activated = FALSE
plane = DECAL_PLANE
layer = ABOVE_UTILITY
layer = DECAL_LAYER
var/tile = /obj/item/stack/tile/floor
var/platecolor = "#858a8f"

View File

@@ -5,7 +5,7 @@
anchored = TRUE // Usually, plants don't move. Usually.
plane = DECAL_PLANE
layer = BELOW_MOB_LAYER
layer = DECAL_LAYER
var/randomize_size = FALSE
var/max_x_scale = 1.25

View File

@@ -7,7 +7,7 @@ var/list/floor_decals = list()
name = "floor decal"
icon = 'icons/turf/flooring/decals_vr.dmi' // VOREStation Edit
plane = DECAL_PLANE
layer = MAPPER_DECAL_LAYER
layer = DECAL_LAYER
var/supplied_dir
/obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour)

View File

@@ -2,6 +2,7 @@
icon = 'icons/turf/floors.dmi'
layer = TURF_LAYER
plane = TURF_PLANE
vis_flags = VIS_INHERIT_ID | VIS_INHERIT_PLANE// Important for interaction with and visualization of openspace.
level = 1
var/holy = 0
@@ -49,6 +50,13 @@
if(movement_cost && pathweight == 1) // This updates pathweight automatically.
pathweight = movement_cost
var/turf/Ab = GetAbove(src)
if(Ab)
Ab.multiz_turf_new(src, DOWN)
var/turf/Be = GetBelow(src)
if(Be)
Be.multiz_turf_new(src, UP)
/turf/Destroy()
. = QDEL_HINT_IWILLGC
cleanbot_reserved_turfs -= src

View File

@@ -42,7 +42,12 @@
var/old_outdoors = outdoors
var/old_dangerous_objects = dangerous_objects
//to_world("Replacing [src.type] with [N]")
var/turf/Ab = GetAbove(src)
if(Ab)
Ab.multiz_turf_del(src, DOWN)
var/turf/Be = GetBelow(src)
if(Be)
Be.multiz_turf_del(src, UP)
if(connections) connections.erase_all()
@@ -53,6 +58,8 @@
var/turf/simulated/S = src
if(S.zone) S.zone.rebuild()
cut_overlays(TRUE)
if(ispath(N, /turf/simulated/floor))
var/turf/simulated/W = new N( locate(src.x, src.y, src.z) )
if(old_fire)

View File

@@ -13,6 +13,7 @@
idle_power_usage = 10
active_power_usage = 500
circuit = /obj/item/weapon/circuitboard/station_map
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
// TODO - Port use_auto_lights from /vg - for now declare here
var/use_auto_lights = 1

View File

@@ -11,6 +11,7 @@
plane = PLANE_EMISSIVE
layer = FLOAT_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
vis_flags = VIS_HIDE
//Why?
//render_targets copy the transform of the target as well, but vis_contents also applies the transform
//to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform.

View File

@@ -2,6 +2,7 @@
name = "observer"
desc = "This shouldn't appear"
density = 0
vis_flags = NONE
/mob/observer/dead
name = "ghost"

View File

@@ -50,7 +50,7 @@ var/list/slot_equipment_priority = list( \
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
if(!W)
return 0
if(!W.mob_can_equip(src, slot, disable_warning))
if(!W.mob_can_equip(src, slot))
if(del_on_fail)
qdel(W)
@@ -93,7 +93,7 @@ var/list/slot_equipment_priority = list( \
return 0
/mob/proc/equip_to_storage(obj/item/newitem, user_initiated = FALSE)
/mob/proc/equip_to_storage(obj/item/newitem)
return 0
/* Hands */

View File

@@ -16,40 +16,13 @@ This saves us from having to call add_fingerprint() any time something is put in
if(!I)
to_chat(H, "<span class='notice'>You are not holding anything to equip.</span>")
return
var/moved = FALSE
// Try an equipment slot
if(H.equip_to_appropriate_slot(I))
moved = TRUE
// No? Try a storage item.
else if(H.equip_to_storage(I, TRUE))
moved = TRUE
// No?! Well, give up.
if(!moved)
to_chat(H, "<span class='warning'>You are unable to equip that.</span>")
// Update hand icons
else
if(hand)
update_inv_l_hand(0)
else
update_inv_r_hand(0)
/mob/living/carbon/human/equip_to_storage(obj/item/newitem, user_initiated = FALSE)
// Try put it in their belt first
if(istype(src.belt,/obj/item/weapon/storage))
var/obj/item/weapon/storage/wornbelt = src.belt
if(wornbelt.can_be_inserted(newitem, 1))
if(user_initiated)
wornbelt.handle_item_insertion(newitem)
else
newitem.forceMove(wornbelt)
return wornbelt
return ..()
else
to_chat(H, "<font color='red'>You are unable to equip that.</font>")
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
for (var/slot in slots)

View File

@@ -39,6 +39,7 @@
/obj/effect/weaversilk/floor
var/possible_icon_states = list("floorweb1", "floorweb2", "floorweb3", "floorweb4", "floorweb5", "floorweb6", "floorweb7", "floorweb8")
plane = DIRTY_PLANE
layer = DIRTY_LAYER
/obj/effect/weaversilk/floor/Initialize()
..()

View File

@@ -6,25 +6,19 @@
var/obj/item/weapon/tank/internal = null//Human/Monkey
var/obj/item/clothing/mask/wear_mask = null//Carbon
/mob/living/equip_to_storage(obj/item/newitem, user_initiated = FALSE)
/mob/living/equip_to_storage(obj/item/newitem)
// Try put it in their backpack
if(istype(src.back,/obj/item/weapon/storage))
var/obj/item/weapon/storage/backpack = src.back
if(backpack.can_be_inserted(newitem, 1))
if(user_initiated)
backpack.handle_item_insertion(newitem)
else
newitem.forceMove(src.back)
return src.back
newitem.forceMove(src.back)
return 1
// Try to place it in any item that can store stuff, on the mob.
for(var/obj/item/weapon/storage/S in src.contents)
if (S.can_be_inserted(newitem, 1))
if(user_initiated)
S.handle_item_insertion(newitem)
else
newitem.forceMove(S)
return S
newitem.forceMove(S)
return 1
return 0
//Returns the thing in our active hand

View File

@@ -342,20 +342,6 @@ var/list/channel_to_radio_key = new
speech_bubble.alpha = CLAMP(sb_alpha, 0, 255)
images_to_clients[speech_bubble] = list()
// Attempt Multi-Z Talking
var/mob/above = src.shadow
while(!QDELETED(above))
var/turf/ST = get_turf(above)
if(ST)
var/list/results = get_mobs_and_objs_in_view_fast(ST, world.view)
var/image/z_speech_bubble = generate_speech_bubble(above, "h[speech_bubble_test]")
images_to_clients[z_speech_bubble] = list()
for(var/item in results["mobs"])
if(item != above && !(item in listening))
listening[item] = z_speech_bubble
listening_obj |= results["objs"]
above = above.shadow
//Main 'say' and 'whisper' message delivery
for(var/mob/M in listening)
spawn(0) //Using spawns to queue all the messages for AFTER this proc is done, and stop runtimes

View File

@@ -84,9 +84,6 @@
else
exclude_mobs = list(src)
src.show_message(self_message, 1, blind_message, 2)
// Transfer messages about what we are doing to upstairs
if(shadow)
shadow.visible_message(message, self_message, blind_message, exclude_mobs, range)
if(isnull(runemessage))
runemessage = -1
. = ..(message, blind_message, exclude_mobs, range, runemessage) // Really not ideal that atom/visible_message has different arg numbering :(

View File

@@ -4,6 +4,8 @@
plane = MOB_PLANE
animate_movement = 2
blocks_emissive = EMISSIVE_BLOCK_GENERIC
///when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace.
vis_flags = VIS_INHERIT_PLANE
var/datum/mind/mind
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak

View File

@@ -18,6 +18,7 @@
plane_masters[VIS_LIGHTING] = new /obj/screen/plane_master/lighting //Lighting system (but different!)
plane_masters[VIS_O_LIGHT] = new /obj/screen/plane_master/o_light_visual //Object lighting (using masks)
plane_masters[VIS_EMISSIVE] = new /obj/screen/plane_master/emissive //Emissive overlays
plane_masters[VIS_OPENSPACE] = new /obj/screen/plane_master/openspace //Openspace drop shadows mostly
plane_masters[VIS_GHOSTS] = new /obj/screen/plane_master/ghosts //Ghosts!
plane_masters[VIS_AI_EYE] = new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
@@ -223,6 +224,20 @@
. = ..()
add_filter("em_block_masking", 1, color_matrix_filter(GLOB.em_mask_matrix))
/////////////////
//Openspace gets some magic filters for layers
/obj/screen/plane_master/openspace
plane = OPENSPACE_BACKDROP_PLANE
blend_mode = BLEND_MULTIPLY
alpha = 255
/obj/screen/plane_master/openspace/Initialize()
. = ..()
//add_filter("multiz_lighting_mask", 1, alpha_mask_filter(render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE)) // Makes fake planet lights not work right
add_filter("first_stage_openspace", 2, drop_shadow_filter(color = "#04080FAA", size = -10))
add_filter("second_stage_openspace", 3, drop_shadow_filter(color = "#04080FAA", size = -15))
//add_filter("third_stage_openspace", 4, drop_shadow_filter(color = "#04080FAA", size = -20)) // TOO dark
/////////////////
//Ghosts has a special alpha level
/obj/screen/plane_master/ghosts

View File

@@ -33,9 +33,6 @@
cut_overlay(typing_indicator, TRUE)
typing = FALSE
if(shadow) //Multi-Z above-me shadows
shadow.set_typing_indicator(state)
return state
/mob/verb/say_wrapper()

View File

@@ -5,12 +5,3 @@
var/height = 1 ///< The number of Z-Levels in the map.
var/turf/edge_type ///< What the map edge should be formed with. (null = world.turf)
// FOR THE LOVE OF GOD USE THESE. DO NOT FUCKING SPAGHETTIFY THIS.
// Use the Has*() functions if you ONLY need to check.
// If you need to do something, use Get*().
/HasAbove(var/z)
/HasBelow(var/z)
// These give either the turf or null.
/GetAbove(var/atom/atom)
/GetBelow(var/atom/atom)

View File

@@ -1,3 +1,4 @@
/// Multiz support override for CanZPass
/turf/proc/CanZPass(atom/A, direction)
if(z == A.z) //moving FROM this turf
return direction == UP //can't go below
@@ -7,84 +8,81 @@
if(direction == DOWN) //on a turf above, trying to enter
return !density && isopenspace(GetAbove(src)) // VOREStation Edit
/// Multiz support override for CanZPass
/turf/simulated/open/CanZPass(atom, direction)
return 1
/// Multiz support override for CanZPass
/turf/space/CanZPass(atom, direction)
return 1
/// WARNING WARNING
/// Turfs DO NOT lose their signals when they get replaced, REMEMBER THIS
/// It's possible because turfs are fucked, and if you have one in a list and it's replaced with another one, the list ref points to the new turf
/// We do it because moving signals over was needlessly expensive, and bloated a very commonly used bit of code
/turf/proc/multiz_turf_del(turf/T, dir)
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_DEL, T, dir)
/turf/proc/multiz_turf_new(turf/T, dir)
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_NEW, T, dir)
//
// Open Space - "empty" turf that lets stuff fall thru it to the layer below
//
GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdrop, new)
/atom/movable/openspace_backdrop
name = "openspace_backdrop"
anchored = TRUE
icon = 'icons/turf/floors.dmi'
icon_state = "grey"
plane = OPENSPACE_BACKDROP_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
vis_flags = VIS_INHERIT_ID
/turf/simulated/open
name = "open space"
icon = 'icons/turf/space.dmi'
icon_state = ""
desc = "\..."
icon = 'icons/turf/floors.dmi'
icon_state = "invisible"
desc = "Watch your step!"
density = 0
plane = OPENSPACE_PLANE_START
plane = OPENSPACE_PLANE
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
dynamic_lighting = 0 // Someday lets do proper lighting z-transfer. Until then we are leaving this off so it looks nicer.
can_build_into_floor = TRUE
var/turf/below
/turf/simulated/open/vacuum
oxygen = 0
nitrogen = 0
temperature = TCMB
/turf/simulated/open/post_change()
..()
update()
/turf/simulated/open/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
var/turf/T = GetBelow(src)
if(T)
GLOB.turf_entered_event.unregister(T, src, .proc/BelowOpenUpdated)
GLOB.turf_exited_event.unregister(T, src, .proc/BelowOpenUpdated)
. = ..()
/turf/simulated/open/Initialize()
. = ..()
ASSERT(HasBelow(z))
update()
var/turf/T = GetBelow(src)
if(T)
GLOB.turf_entered_event.register(T, src, .proc/BelowOpenUpdated)
GLOB.turf_exited_event.register(T, src, .proc/BelowOpenUpdated)
add_overlay(GLOB.openspace_backdrop_one_for_all, TRUE) //Special grey square for projecting backdrop darkness filter on it.
return INITIALIZE_HINT_LATELOAD
/turf/simulated/open/LateInitialize()
. = ..()
AddElement(/datum/element/turf_z_transparency, FALSE)
update_icon()
/turf/simulated/open/Entered(var/atom/movable/mover, var/atom/oldloc)
..()
mover.fall()
/turf/simulated/open/proc/BelowOpenUpdated(turf/T, atom/movable/AM, old_loc)
if(isobj(AM) && GLOB.open_space_initialised && !AM.invisibility)
SSopen_space.add_turf(src, 1)
/turf/simulated/open/proc/update()
for(var/atom/movable/A in src)
A.fall()
// Called when thrown object lands on this turf.
/turf/simulated/open/hitby(var/atom/movable/AM, var/speed)
. = ..()
AM.fall()
/turf/simulated/open/proc/update()
plane = OPENSPACE_PLANE + src.z
below = GetBelow(src)
turf_changed_event.register(below, src, /atom/proc/update_icon)
levelupdate()
below.update_icon() // So the 'ceiling-less' overlay gets added.
for(var/atom/movable/A in src)
A.fall()
if(GLOB.open_space_initialised)
SSopen_space.add_turf(src, TRUE)
// override to make sure nothing is hidden
/turf/simulated/open/levelupdate()
for(var/obj/O in src)
O.hide(0)
/turf/simulated/open/examine(mob/user, distance, infix, suffix)
. = ..()
if(Adjacent(user))
@@ -93,50 +91,9 @@
depth += 1
. += "It is about [depth] levels deep."
/**
* Update icon and overlays of open space to be that of the turf below, plus any visible objects on that turf.
*/
/turf/simulated/open/update_icon()
cut_overlays() // Edit - Overlays are being crashy when modified.
update_icon_edge()// Add - Get grass into open spaces and whatnot.
if(below)
// Skybox lives on its own plane, if we don't set it to see that, then open space tiles over true space tiles see white nothingness below
if(is_space())
plane = SPACE_PLANE
else
plane = OPENSPACE_PLANE + src.z
var/below_is_open = isopenspace(below)
if(below_is_open)
underlays = below.underlays
else
var/image/bottom_turf = image(icon = below.icon, icon_state = below.icon_state, dir=below.dir, layer=below.layer)
bottom_turf.plane = src.plane
bottom_turf.color = below.color
underlays = list(bottom_turf)
copy_overlays(below)
// get objects (not mobs, they are handled by /obj/zshadow)
var/list/o_img = list()
for(var/obj/O in below)
if(O.invisibility) continue // Ignore objects that have any form of invisibility
if(O.loc != below) continue // Ignore multi-turf objects not directly below
var/image/temp2 = image(O, dir = O.dir, layer = O.layer)
if(temp2.icon == null)
temp2.icon_state = null
temp2.plane = src.plane
temp2.color = O.color
temp2.overlays = get_overlays(O, TRUE)
// TODO Is pixelx/y needed?
o_img += temp2
add_overlay(o_img)
if(!below_is_open)
add_overlay(SSopen_space.over_OS_darkness)
return 0
return PROCESS_KILL
cut_overlays()
update_icon_edge()
// Straight copy from space.
/turf/simulated/open/attackby(obj/item/C as obj, mob/user as mob)
@@ -189,3 +146,84 @@
if(!O.CanFallThru(L, GetBelow(src)))
return TRUE // Can't fall through this, like lattice or catwalk.
return ..()
/turf/simulated/floor/glass
name = "glass floor"
desc = "Dont jump on it, or do, I'm not your mom."
icon = 'icons/turf/flooring/glass.dmi'
icon_state = "glass-0"
base_icon_state = "glass"
/*
baseturfs = /turf/simulated/openspace
intact = FALSE //this means wires go on top
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = list(SMOOTH_GROUP_TURF_OPEN, SMOOTH_GROUP_FLOOR_TRANSPARENT_GLASS)
canSmoothWith = list(SMOOTH_GROUP_FLOOR_TRANSPARENT_GLASS)
footstep = FOOTSTEP_PLATING
barefootstep = FOOTSTEP_HARD_BAREFOOT
clawfootstep = FOOTSTEP_HARD_CLAW
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
*/
// /turf/simulated/floor/glass/setup_broken_states()
// return list("glass-damaged1", "glass-damaged2", "glass-damaged3")
/turf/simulated/floor/glass/Initialize()
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
..()
return INITIALIZE_HINT_LATELOAD
/turf/simulated/floor/glass/LateInitialize()
. = ..()
AddElement(/datum/element/turf_z_transparency, TRUE)
blend_icons()
// TG's icon blending method because I don't want to redo all the icon states AAA
//Redefinitions of the diagonal directions so they can be stored in one var without conflicts
/turf/simulated/floor/glass/proc/blend_icons()
var/new_junction = NONE
for(var/direction in cardinal) //Cardinal case first.
var/turf/T = get_step(src, direction)
if(istype(T, type))
new_junction |= direction
if(!(new_junction & (NORTH|SOUTH)) || !(new_junction & (EAST|WEST)))
icon_state = "[base_icon_state]-[new_junction]"
return
if(new_junction & NORTH)
if(new_junction & WEST)
var/turf/T = get_step(src, NORTHWEST)
if(istype(T, type))
new_junction |= (1<<7)
if(new_junction & EAST)
var/turf/T = get_step(src, NORTHEAST)
if(istype(T, type))
new_junction |= (1<<4)
if(new_junction & SOUTH)
if(new_junction & WEST)
var/turf/T = get_step(src, SOUTHWEST)
if(istype(T, type))
new_junction |= (1<<6)
if(new_junction & EAST)
var/turf/T = get_step(src, SOUTHEAST)
if(istype(T, type))
new_junction |= (1<<5)
icon_state = "[base_icon_state]-[new_junction]"
/turf/simulated/floor/glass/reinforced
name = "reinforced glass floor"
desc = "Do jump on it, it can take it."
icon = 'icons/turf/flooring/reinf_glass.dmi'
icon_state = "reinf_glass-0"
base_icon_state = "reinf_glass"
// /turf/simulated/floor/glass/reinforced/setup_broken_states()
// return list("reinf_glass-damaged1", "reinf_glass-damaged2", "reinf_glass-damaged3")

View File

@@ -1,126 +0,0 @@
/mob // TODO: rewrite as obj.
var/mob/zshadow/shadow
/mob/zshadow
plane = OVER_OPENSPACE_PLANE
name = "shadow"
desc = "Z-level shadow"
status_flags = GODMODE
anchored = 1
unacidable = 1
density = 0
opacity = 0 // Don't trigger lighting recalcs gah! TODO - consider multi-z lighting.
//auto_init = FALSE // We do not need to be initialize()d
var/mob/owner = null // What we are a shadow of.
/mob/zshadow/can_fall()
return FALSE
/mob/zshadow/New(var/mob/L)
if(!istype(L))
qdel(src)
return
owner = L
sync_icon(L)
/mob/zshadow/Destroy()
owner.shadow = null
owner = null
..() //But we don't return because the hint is wrong
return QDEL_HINT_QUEUE
/mob/Destroy()
QDEL_NULL(shadow)
. = ..()
/mob/zshadow/examine(mob/user, distance, infix, suffix)
if(!owner)
// The only time we should have a null owner is if we are in nullspace. Help figure out why we were examined.
crash_with("[src] ([type]) @ [log_info_line()] was examined by [user] @ [global.log_info_line(user)]")
return list()
return owner.examine(user, distance, infix, suffix)
// Relay some stuff they hear
/mob/zshadow/hear_say(var/list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(speaker && speaker.z != src.z)
return // Only relay speech on our acutal z, otherwise we might relay sounds that were themselves relayed up!
if(isliving(owner))
verb += " from above"
return owner.hear_say(message_pieces, verb, italics, speaker, speech_sound, sound_vol)
/mob/zshadow/proc/sync_icon(var/mob/M)
name = M.name
icon = M.icon
icon_state = M.icon_state
//color = M.color
color = "#848484"
overlays = M.overlays
transform = M.transform
dir = M.dir
invisibility = M.invisibility
if(shadow)
shadow.sync_icon(src)
/mob/living/Moved()
. = ..()
check_shadow()
/mob/living/forceMove()
. = ..()
check_shadow()
/mob/living/on_mob_jump()
// We're about to be admin-jumped.
// Unfortuantely loc isn't set until after this proc is called. So we must spawn() so check_shadow executes with the new loc.
. = ..()
if(shadow)
spawn(0)
check_shadow()
/mob/living/proc/check_shadow()
var/mob/M = src
if(isturf(M.loc))
var/turf/simulated/open/OS = GetAbove(src)
while(OS && istype(OS))
if(!M.shadow)
M.shadow = new /mob/zshadow(M)
M.shadow.forceMove(OS)
M = M.shadow
OS = GetAbove(M)
// The topmost level does not need a shadow!
if(M.shadow)
qdel(M.shadow)
M.shadow = null
//
// Handle cases where the owner mob might have changed its icon or overlays.
//
/mob/living/update_icons()
. = ..()
if(shadow)
shadow.sync_icon(src)
// WARNING - the true carbon/human/update_icons does not call ..(), therefore we must sideways override this.
// But be careful, we don't want to screw with that proc. So lets be cautious about what we do here.
/mob/living/carbon/human/update_icons()
. = ..()
if(shadow)
shadow.sync_icon(src)
/mob/set_dir(new_dir)
. = ..()
if(shadow)
shadow.set_dir(new_dir)
/mob/zshadow/set_typing_indicator(var/state)
if(!typing_indicator)
init_typing_indicator("typing")
if(state && !typing)
add_overlay(typing_indicator)
typing = 1
else if(!state && typing)
cut_overlay(typing_indicator)
typing = 0
if(shadow)
shadow.set_typing_indicator(state)

View File

@@ -4,6 +4,7 @@
icon = 'icons/effects/writing.dmi'
desc = "It looks like someone has scratched something here."
plane = DIRTY_PLANE
layer = DIRTY_LAYER
gender = PLURAL
blend_mode = BLEND_MULTIPLY
color = "#000000"

View File

@@ -86,6 +86,7 @@ GLOBAL_LIST_EMPTY(apcs)
clicksound = "switch"
req_access = list(access_engine_equip)
blocks_emissive = FALSE
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/area/area
var/areastring = null
var/obj/item/weapon/cell/cell

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -274,7 +274,6 @@
#include "code\controllers\subsystems\media_tracks.dm"
#include "code\controllers\subsystems\mobs.dm"
#include "code\controllers\subsystems\nightshift.dm"
#include "code\controllers\subsystems\open_space.dm"
#include "code\controllers\subsystems\orbits.dm"
#include "code\controllers\subsystems\overlays.dm"
#include "code\controllers\subsystems\persist_vr.dm"
@@ -356,6 +355,7 @@
#include "code\datums\components\crafting\tool_quality.dm"
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\light_blocking.dm"
#include "code\datums\elements\turf_transparency.dm"
#include "code\datums\game_masters\_common.dm"
#include "code\datums\helper_datums\construction_datum.dm"
#include "code\datums\helper_datums\events.dm"
@@ -3197,7 +3197,6 @@
#include "code\modules\multiz\pipes.dm"
#include "code\modules\multiz\stairs.dm"
#include "code\modules\multiz\turf.dm"
#include "code\modules\multiz\zshadow.dm"
#include "code\modules\news\news_init.dm"
#include "code\modules\news\newspaper.dm"
#include "code\modules\news\newspaper_layout.dm"