diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 639724eca2..6221409788 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -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 diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index 9ca46ce7e8..3561178d6b 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -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 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index b70001cbd6..19ff35c86b 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -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 diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index 116358e577..be17f09c39 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -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" diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 9ad2af0504..2c9e6ee6a6 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -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 diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index c7631479f8..2f172d198e 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -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)) diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index 5a0a519743..ffef724172 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -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) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index ee5899fbe8..5540fe8e08 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -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() diff --git a/code/controllers/subsystems/open_space.dm b/code/controllers/subsystems/open_space.dm deleted file mode 100644 index 4e96dbfda4..0000000000 --- a/code/controllers/subsystems/open_space.dm +++ /dev/null @@ -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. diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm new file mode 100644 index 0000000000..df2446cd46 --- /dev/null +++ b/code/datums/elements/turf_transparency.dm @@ -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 \ No newline at end of file diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 983e0ea56e..728859eee7 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -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() diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index 9e700f9904..8f223ed549 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -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 diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 30182cbd8b..e23aa459be 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -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 diff --git a/code/game/machinery/fire_alarm.dm b/code/game/machinery/fire_alarm.dm index a1a22b80c8..6c5e6400d4 100644 --- a/code/game/machinery/fire_alarm.dm +++ b/code/game/machinery/fire_alarm.dm @@ -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 diff --git a/code/game/machinery/holoposter.dm b/code/game/machinery/holoposter.dm index d52e10b57a..7a71d9fc64 100644 --- a/code/game/machinery/holoposter.dm +++ b/code/game/machinery/holoposter.dm @@ -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 diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 89bd996dea..44a80c4445 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -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 diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index bd6e1e97f6..deb8ec8a0c 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -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 diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index c9ae326bf2..7692dd334e 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -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") diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0df27515c7..ed411a67ab 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -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 diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 559157af29..8f92ea0089 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -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") diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index c0414036b5..9f3f4335c8 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -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 = "[(ND.number > 1)? "[ND.number]" : ""]" 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, "[src] is full, make some space.") 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, "[src] cannot hold [W].") 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, "[src] cannot hold [W].") 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 diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 2432e79008..9f16a6b9c9 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -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. diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index c8c312334f..58674def1a 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -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" diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm index e73e2a1758..ccb3106886 100644 --- a/code/game/objects/structures/flora/flora.dm +++ b/code/game/objects/structures/flora/flora.dm @@ -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 diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index 578fb80f54..1fd1d6e6ed 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -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) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 8b3bee6f9e..bd7df8d280 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -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 diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index efbea4ffb3..e826867ab7 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -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) diff --git a/code/modules/holomap/station_holomap.dm b/code/modules/holomap/station_holomap.dm index 9d56943856..2430267981 100644 --- a/code/modules/holomap/station_holomap.dm +++ b/code/modules/holomap/station_holomap.dm @@ -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 diff --git a/code/modules/lighting/emissive_blocker.dm b/code/modules/lighting/emissive_blocker.dm index 690b9b5216..b65c714d1f 100644 --- a/code/modules/lighting/emissive_blocker.dm +++ b/code/modules/lighting/emissive_blocker.dm @@ -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. diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 74b3e6dc0e..06c538b041 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -2,6 +2,7 @@ name = "observer" desc = "This shouldn't appear" density = 0 + vis_flags = NONE /mob/observer/dead name = "ghost" diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 13bc02dda4..35df5ef8a1 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -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 */ diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 7aa1dee24f..d756271286 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -16,40 +16,13 @@ This saves us from having to call add_fingerprint() any time something is put in if(!I) to_chat(H, "You are not holding anything to equip.") 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, "You are unable to equip that.") - - // 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, "You are unable to equip that.") /mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1) for (var/slot in slots) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/weaver_objs.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/weaver_objs.dm index 72d53be19b..b3ddc26ed3 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/weaver_objs.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/weaver_objs.dm @@ -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() ..() diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index c2ea298683..8d4a66def3 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -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 diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 6db59df65b..139397aa29 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -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 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d8040cdc0b..9b623bec93 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -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 :( diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index a0ca4cd492..b2c1ca4ede 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -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 diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index cfd4a91729..49d90a5a95 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -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 diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index c3c5a1450d..e9715834c8 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -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() diff --git a/code/modules/multiz/_stubs.dm b/code/modules/multiz/_stubs.dm index a9d1d456b1..2b8fe09e0d 100644 --- a/code/modules/multiz/_stubs.dm +++ b/code/modules/multiz/_stubs.dm @@ -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) \ No newline at end of file diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index 15c000cdc5..ab2bcf6e3d 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -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") diff --git a/code/modules/multiz/zshadow.dm b/code/modules/multiz/zshadow.dm deleted file mode 100644 index 3b6efa34d0..0000000000 --- a/code/modules/multiz/zshadow.dm +++ /dev/null @@ -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) diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm index e0b7fa05ee..2259186c71 100644 --- a/code/modules/persistence/graffiti.dm +++ b/code/modules/persistence/graffiti.dm @@ -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" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 4f7ac688d7..c9ecf3d8fb 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -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 diff --git a/icons/turf/flooring/glass.dmi b/icons/turf/flooring/glass.dmi new file mode 100644 index 0000000000..e28bb13e23 Binary files /dev/null and b/icons/turf/flooring/glass.dmi differ diff --git a/icons/turf/flooring/reinf_glass.dmi b/icons/turf/flooring/reinf_glass.dmi new file mode 100644 index 0000000000..97614f510f Binary files /dev/null and b/icons/turf/flooring/reinf_glass.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index f95702fa27..978eb5d9c7 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/vorestation.dme b/vorestation.dme index a9ca7045cd..d80feb7101 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -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"