mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-01-29 10:21:52 +00:00
/tg/ vis openspace
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
82
code/datums/elements/turf_transparency.dm
Normal file
82
code/datums/elements/turf_transparency.dm
Normal 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
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "observer"
|
||||
desc = "This shouldn't appear"
|
||||
density = 0
|
||||
vis_flags = NONE
|
||||
|
||||
/mob/observer/dead
|
||||
name = "ghost"
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 :(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
BIN
icons/turf/flooring/glass.dmi
Normal file
BIN
icons/turf/flooring/glass.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
icons/turf/flooring/reinf_glass.dmi
Normal file
BIN
icons/turf/flooring/reinf_glass.dmi
Normal file
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 |
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user