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 a78d9147e2..092b5e677a 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 6453f4bba4..60a0ec8858 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -79,7 +79,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 5781543089..179f7251d9 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -286,9 +286,24 @@ var/mobs_radio_range_fired = 1 //CHOMPEdit 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 e6487eecd3..abe3ce7994 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..03ec06c05b --- /dev/null +++ b/code/datums/elements/turf_transparency.dm @@ -0,0 +1,84 @@ +/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, override = TRUE) + RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_turf_new, override = TRUE) + + 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 + UnregisterSignal(our_turf, COMSIG_TURF_MULTIZ_DEL) + UnregisterSignal(our_turf, COMSIG_TURF_MULTIZ_NEW) + +///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 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 983e0ea56e..1814440955 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,712 +1,712 @@ -/atom/movable - layer = OBJ_LAYER - appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER - glide_size = 8 - var/last_move = null //The direction the atom last moved - var/anchored = 0 - // var/elevation = 2 - not used anywhere - var/moving_diagonally - var/move_speed = 10 - var/l_move_time = 1 - var/throwing = 0 - var/thrower - var/turf/throw_source = null - var/throw_speed = 2 - var/throw_range = 7 - var/moved_recently = 0 - var/mob/pulledby = null - var/item_state = null // Used to specify the item state for the on-mob overlays. - var/icon_scale_x = 1 // Used to scale icons up or down horizonally in update_transform(). - var/icon_scale_y = 1 // Used to scale icons up or down vertically in update_transform(). - var/icon_rotation = 0 // Used to rotate icons in update_transform() - var/icon_expected_height = 32 - var/icon_expected_width = 32 - var/old_x = 0 - var/old_y = 0 - var/datum/riding/riding_datum = null - var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P) - var/movement_type = NONE - - var/cloaked = FALSE //If we're cloaked or not - var/image/cloaked_selfimage //The image we use for our client to let them see where we are - -/atom/movable/Initialize(mapload) - . = ..() - switch(blocks_emissive) - if(EMISSIVE_BLOCK_GENERIC) - var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = PLANE_EMISSIVE, alpha = src.alpha) - gen_emissive_blocker.color = GLOB.em_block_color - gen_emissive_blocker.dir = dir - gen_emissive_blocker.appearance_flags |= appearance_flags - add_overlay(list(gen_emissive_blocker), TRUE) - if(EMISSIVE_BLOCK_UNIQUE) - render_target = ref(src) - em_block = new(src, render_target) - add_overlay(list(em_block), TRUE) - if(opacity) - AddElement(/datum/element/light_blocking) - switch(light_system) - if(STATIC_LIGHT) - update_light() - if(MOVABLE_LIGHT) - AddComponent(/datum/component/overlay_lighting, starts_on = light_on) - if(MOVABLE_LIGHT_DIRECTIONAL) - AddComponent(/datum/component/overlay_lighting, is_directional = TRUE, starts_on = light_on) - -/atom/movable/Destroy() - . = ..() - for(var/atom/movable/AM in contents) - qdel(AM) - - if(opacity) - RemoveElement(/datum/element/light_blocking) - - moveToNullspace() - - vis_contents.Cut() - for(var/atom/movable/A as anything in vis_locs) - A.vis_contents -= src - - if(pulledby) - pulledby.stop_pulling() - - if(orbiting) - stop_orbit() - QDEL_NULL(riding_datum) //VOREStation Add - -/atom/movable/vv_edit_var(var_name, var_value) - if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly. - return FALSE - return ..() - -//////////////////////////////////////// -/atom/movable/Move(atom/newloc, direct = 0, movetime) - // Didn't pass enough info - if(!loc || !newloc) - return FALSE - - // Store this early before we might move, it's used several places - var/atom/oldloc = loc - - // If we're not moving to the same spot (why? does that even happen?) - if(loc != newloc) - if(!direct) - direct = get_dir(oldloc, newloc) - if (IS_CARDINAL(direct)) //Cardinal move - // Track our failure if any in this value - . = TRUE - - // Face the direction of movement - set_dir(direct) - - // Check to make sure we can leave - if(!loc.Exit(src, newloc)) - . = FALSE - - // Check to make sure we can enter, if we haven't already failed - if(. && !newloc.Enter(src, src.loc)) - . = FALSE - - // Check to make sure if we're multi-tile we can move, if we haven't already failed - if(. && !check_multi_tile_move_density_dir(direct, locs)) - . = FALSE - - // Definitely moving if you enter this, no failures so far - if(. && locs.len <= 1) // We're not a multi-tile object. - var/area/oldarea = get_area(oldloc) - var/area/newarea = get_area(newloc) - var/old_z = get_z(oldloc) - var/dest_z = get_z(newloc) - - // Do The Move - glide_for(movetime) - loc = newloc - . = TRUE - - // So objects can be informed of z-level changes - if (old_z != dest_z) - onTransitZ(old_z, dest_z) - - // We don't call parent so we are calling this for byond - oldloc.Exited(src, newloc) - if(oldarea != newarea) - oldarea.Exited(src, newloc) - - // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself - for(var/i in oldloc) - var/atom/movable/thing = i - // We don't call parent so we are calling this for byond - thing.Uncrossed(src) - - // We don't call parent so we are calling this for byond - newloc.Entered(src, oldloc) - if(oldarea != newarea) - newarea.Entered(src, oldloc) - - // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself - for(var/i in loc) - var/atom/movable/thing = i - // We don't call parent so we are calling this for byond - thing.Crossed(src, oldloc) - - // We're a multi-tile object (multiple locs) - else if(. && newloc) - . = doMove(newloc) - - //Diagonal move, split it into cardinal moves - else - moving_diagonally = FIRST_DIAG_STEP - var/first_step_dir - // The `&& moving_diagonally` checks are so that a forceMove taking - // place due to a Crossed, Bumped, etc. call will interrupt - // the second half of the diagonal movement, or the second attempt - // at a first half if step() fails because we hit something. - glide_for(movetime) - if (direct & NORTH) - if (direct & EAST) - if (step(src, NORTH) && moving_diagonally) - first_step_dir = NORTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, EAST) - else if (moving_diagonally && step(src, EAST)) - first_step_dir = EAST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, NORTH) - else if (direct & WEST) - if (step(src, NORTH) && moving_diagonally) - first_step_dir = NORTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, WEST) - else if (moving_diagonally && step(src, WEST)) - first_step_dir = WEST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, NORTH) - else if (direct & SOUTH) - if (direct & EAST) - if (step(src, SOUTH) && moving_diagonally) - first_step_dir = SOUTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, EAST) - else if (moving_diagonally && step(src, EAST)) - first_step_dir = EAST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, SOUTH) - else if (direct & WEST) - if (step(src, SOUTH) && moving_diagonally) - first_step_dir = SOUTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, WEST) - else if (moving_diagonally && step(src, WEST)) - first_step_dir = WEST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, SOUTH) - // If we failed, turn to face the direction of the first step at least - if(!. && moving_diagonally == SECOND_DIAG_STEP) - set_dir(first_step_dir) - // Done, regardless! - moving_diagonally = 0 - // We return because step above will call Move() and we don't want to do shenanigans back in here again - return - - else if(!loc || (loc == oldloc)) - last_move = 0 - return - - // If we moved, call Moved() on ourselves - if(.) - Moved(oldloc, direct, FALSE, movetime) - - // Update timers/cooldown stuff - move_speed = world.time - l_move_time - l_move_time = world.time - last_move = direct // The direction you last moved - // set_dir(direct) //Don't think this is necessary - -//Called after a successful Move(). By this point, we've already moved -/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE, movetime) - SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, old_loc, direction, forced, movetime) - // Handle any buckled mobs on this movable - if(has_buckled_mobs()) - handle_buckled_mob_movement(old_loc, direction, movetime) - if(riding_datum) - riding_datum.handle_vehicle_layer() - riding_datum.handle_vehicle_offsets() - for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update. - light.source_atom.update_light() - return TRUE - -/atom/movable/set_dir(newdir) - . = ..(newdir) - if(riding_datum) - riding_datum.handle_vehicle_offsets() - -/atom/movable/relaymove(mob/user, direction) - . = ..() - if(riding_datum) - riding_datum.handle_ride(user, direction) - -// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. -// You probably want CanPass() -/atom/movable/Cross(atom/movable/AM) - return CanPass(AM, loc) - -/atom/movable/CanPass(atom/movable/mover, turf/target) - . = ..() - if(locs && locs.len >= 2) // If something is standing on top of us, let them pass. - if(mover.loc in locs) - . = TRUE - return . - -//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! -/atom/movable/Crossed(atom/movable/AM, oldloc) - return - -/atom/movable/Uncross(atom/movable/AM, atom/newloc) - . = ..() - if(isturf(newloc) && !CheckExit(AM, newloc)) - return FALSE - -/atom/movable/Bump(atom/A) - if(!A) - CRASH("Bump was called with no argument.") - . = ..() - if(throwing) - throw_impact(A) - throwing = 0 - if(QDELETED(A)) - return - A.Bumped(src) - A.last_bumped = world.time - -/atom/movable/proc/forceMove(atom/destination, direction, movetime) - . = FALSE - if(destination) - . = doMove(destination, direction, movetime) - else - CRASH("No valid destination passed into forceMove") - -/atom/movable/proc/moveToNullspace() - return doMove(null) - -/atom/movable/proc/doMove(atom/destination, direction, movetime) - var/atom/oldloc = loc - var/area/old_area = get_area(oldloc) - var/same_loc = oldloc == destination - - if(destination) - var/area/destarea = get_area(destination) - - // Do The Move - glide_for(movetime) - last_move = isnull(direction) ? 0 : direction - loc = destination - - // Unset this in case it was set in some other proc. We're no longer moving diagonally for sure. - moving_diagonally = 0 - - // We are moving to a different loc - if(!same_loc) - // Not moving out of nullspace - if(oldloc) - oldloc.Exited(src, destination) - // If it's not the same area, Exited() it - if(old_area && old_area != destarea) - old_area.Exited(src, destination) - - // Uncross everything where we left - for(var/i in oldloc) - var/atom/movable/AM = i - if(AM == src) - continue - AM.Uncrossed(src) - if(loc != destination) // Uncrossed() triggered a separate movement - return - - // Information about turf and z-levels for source and dest collected - var/turf/oldturf = get_turf(oldloc) - var/turf/destturf = get_turf(destination) - var/old_z = (oldturf ? oldturf.z : null) - var/dest_z = (destturf ? destturf.z : null) - - // So objects can be informed of z-level changes - if (old_z != dest_z) - onTransitZ(old_z, dest_z) - - // Destination atom Entered - destination.Entered(src, oldloc) - - // Entered() the new area if it's not the same area - if(destarea && old_area != destarea) - destarea.Entered(src, oldloc) - - // We ignore ourselves because if we're multi-tile we might be in both old and new locs - for(var/i in destination) - var/atom/movable/AM = i - if(AM == src) - continue - AM.Crossed(src, oldloc) - if(loc != destination) // Crossed triggered a separate movement - return - - // Call our thingy to inform everyone we moved - Moved(oldloc, NONE, TRUE) - - // Break pulling if we are too far to pull now. - if(pulledby && (pulledby.z != src.z || get_dist(pulledby, src) > 1)) - pulledby.stop_pulling() - - // We moved - return TRUE - - //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) - else if(oldloc) - loc = null - - // Uncross everything where we left (no multitile safety like above because we are definitely not still there) - for(var/i in oldloc) - var/atom/movable/AM = i - AM.Uncrossed(src) - - // Exited() our loc and area - oldloc.Exited(src, null) - if(old_area) - old_area.Exited(src, null) - - // We moved - return TRUE - -/atom/movable/proc/onTransitZ(old_z,new_z) - GLOB.z_moved_event.raise_event(src, old_z, new_z) - for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. - var/atom/movable/AM = item - AM.onTransitZ(old_z,new_z) - -/atom/movable/proc/glide_for(movetime) - if(movetime) - glide_size = WORLD_ICON_SIZE/max(DS2TICKS(movetime), 1) - spawn(movetime) - glide_size = initial(glide_size) - else - glide_size = initial(glide_size) - -///////////////////////////////////////////////////////////////// - -//called when src is thrown into hit_atom -/atom/movable/proc/throw_impact(atom/hit_atom, var/speed) - if(istype(hit_atom,/mob/living)) - var/mob/living/M = hit_atom - if(M.buckled == src) - return // Don't hit the thing we're buckled to. - M.hitby(src,speed) - - else if(isobj(hit_atom)) - var/obj/O = hit_atom - if(!O.anchored) - step(O, src.last_move) - O.hitby(src,speed) - - else if(isturf(hit_atom)) - src.throwing = 0 - var/turf/T = hit_atom - T.hitby(src,speed) - -//decided whether a movable atom being thrown can pass through the turf it is in. -/atom/movable/proc/hit_check(var/speed) - if(src.throwing) - for(var/atom/A in get_turf(src)) - if(A == src) continue - if(istype(A,/mob/living)) - if(A:lying) continue - src.throw_impact(A,speed) - if(isobj(A)) - if(!A.density || A.throwpass) - continue - // Special handling of windows, which are dense but block only from some directions - if(istype(A, /obj/structure/window)) - var/obj/structure/window/W = A - if (!W.is_fulltile() && !(turn(src.last_move, 180) & A.dir)) - continue - // Same thing for (closed) windoors, which have the same problem - else if(istype(A, /obj/machinery/door/window) && !(turn(src.last_move, 180) & A.dir)) - continue - src.throw_impact(A,speed) - -/atom/movable/proc/throw_at(atom/target, range, speed, thrower) - if(!target || !src) - return 0 - if(target.z != src.z) - return 0 - //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target - src.throwing = 1 - src.thrower = thrower - src.throw_source = get_turf(src) //store the origin turf - src.pixel_z = 0 - if(usr) - if(HULK in usr.mutations) - src.throwing = 2 // really strong throw! - - var/dist_travelled = 0 - var/dist_since_sleep = 0 - var/area/a = get_area(src.loc) - - var/dist_x = abs(target.x - src.x) - var/dist_y = abs(target.y - src.y) - - var/dx - if (target.x > src.x) - dx = EAST - else - dx = WEST - - var/dy - if (target.y > src.y) - dy = NORTH - else - dy = SOUTH - - var/error - var/major_dir - var/major_dist - var/minor_dir - var/minor_dist - if(dist_x > dist_y) - error = dist_x/2 - dist_y - major_dir = dx - major_dist = dist_x - minor_dir = dy - minor_dist = dist_y - else - error = dist_y/2 - dist_x - major_dir = dy - major_dist = dist_y - minor_dir = dx - minor_dist = dist_x - - range = min(dist_x + dist_y, range) - - while(src && target && src.throwing && istype(src.loc, /turf) \ - && ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \ - || (a && a.has_gravity == 0) \ - || istype(src.loc, /turf/space))) - // only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up - var/atom/step - if(error >= 0) - step = get_step(src, major_dir) - error -= minor_dist - else - step = get_step(src, minor_dir) - error += major_dist - if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge - break - src.Move(step) - hit_check(speed) - dist_travelled++ - dist_since_sleep++ - if(dist_since_sleep >= speed) - dist_since_sleep = 0 - sleep(1) - a = get_area(src.loc) - // and yet it moves - if(src.does_spin) - src.SpinAnimation(speed = 4, loops = 1) - - //done throwing, either because it hit something or it finished moving - if(isobj(src)) src.throw_impact(get_turf(src),speed) - src.throwing = 0 - src.thrower = null - src.throw_source = null - fall() - - -//Overlays -/atom/movable/overlay - var/atom/master = null - anchored = 1 - -/atom/movable/overlay/New() - for(var/x in src.verbs) - src.verbs -= x - ..() - -/atom/movable/overlay/attackby(a, b) - if (src.master) - return src.master.attackby(a, b) - return - -/atom/movable/overlay/attack_hand(a, b, c) - if (src.master) - return src.master.attack_hand(a, b, c) - return - -/atom/movable/proc/touch_map_edge() - if(z in using_map.sealed_levels) - return - - if(using_map.use_overmap) - overmap_spacetravel(get_turf(src), src) - return - - var/move_to_z = src.get_transit_zlevel() - if(move_to_z) - var/new_z = move_to_z - var/new_x - var/new_y - - if(x <= TRANSITIONEDGE) - new_x = world.maxx - TRANSITIONEDGE - 2 - new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) - - else if (x >= (world.maxx - TRANSITIONEDGE + 1)) - new_x = TRANSITIONEDGE + 1 - new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) - - else if (y <= TRANSITIONEDGE) - new_y = world.maxy - TRANSITIONEDGE -2 - new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) - - else if (y >= (world.maxy - TRANSITIONEDGE + 1)) - new_y = TRANSITIONEDGE + 1 - new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) - - if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear - var/datum/game_mode/nuclear/G = ticker.mode - G.check_nuke_disks() - - var/turf/T = locate(new_x, new_y, new_z) - if(istype(T)) - forceMove(T) - -//by default, transition randomly to another zlevel -/atom/movable/proc/get_transit_zlevel() - var/list/candidates = using_map.accessible_z_levels.Copy() - candidates.Remove("[src.z]") - - if(!candidates.len) - return null - return text2num(pickweight(candidates)) - -// Returns the current scaling of the sprite. -// Note this DOES NOT measure the height or width of the icon, but returns what number is being multiplied with to scale the icons, if any. -/atom/movable/proc/get_icon_scale_x() - return icon_scale_x - -/atom/movable/proc/get_icon_scale_y() - return icon_scale_y - -/atom/movable/proc/update_transform() - var/matrix/M = matrix() - M.Scale(icon_scale_x, icon_scale_y) - M.Turn(icon_rotation) - src.transform = M - -// Use this to set the object's scale. -/atom/movable/proc/adjust_scale(new_scale_x, new_scale_y) - if(isnull(new_scale_y)) - new_scale_y = new_scale_x - if(new_scale_x != 0) - icon_scale_x = new_scale_x - if(new_scale_y != 0) - icon_scale_y = new_scale_y - update_transform() - -/atom/movable/proc/adjust_rotation(new_rotation) - icon_rotation = new_rotation - update_transform() - -// Called when touching a lava tile. -/atom/movable/proc/lava_act() - fire_act(null, 10000, 1000) - - -// Procs to cloak/uncloak -/atom/movable/proc/cloak() - if(cloaked) - return FALSE - cloaked = TRUE - . = TRUE // We did work - - var/static/animation_time = 1 SECOND - cloaked_selfimage = get_cloaked_selfimage() - - //Wheeee - cloak_animation(animation_time) - - //Needs to be last so people can actually see the effect before we become invisible - if(cloaked) // Ensure we are still cloaked after the animation delay - plane = CLOAKED_PLANE - -/atom/movable/proc/uncloak() - if(!cloaked) - return FALSE - cloaked = FALSE - . = TRUE // We did work - - var/static/animation_time = 1 SECOND - QDEL_NULL(cloaked_selfimage) - - //Needs to be first so people can actually see the effect, so become uninvisible first - plane = initial(plane) - - //Oooooo - uncloak_animation(animation_time) - - -// Animations for cloaking/uncloaking -/atom/movable/proc/cloak_animation(var/length = 1 SECOND) - //Save these - var/initial_alpha = alpha - - //Animate alpha fade - animate(src, alpha = 0, time = length) - - //Animate a cloaking effect - var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. - filters += filter(type="wave", x = 0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS) - animate(filters[our_filter], offset = 1, size = 8, time = length, flags = ANIMATION_PARALLEL) - - //Wait for animations to finish - sleep(length+5) - - //Remove those - filters -= filter(type="wave", x = 0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS) - - //Back to original alpha - alpha = initial_alpha - -/atom/movable/proc/uncloak_animation(var/length = 1 SECOND) - //Save these - var/initial_alpha = alpha - - //Put us back to normal, but no alpha - alpha = 0 - - //Animate alpha fade up - animate(src, alpha = initial_alpha, time = length) - - //Animate a cloaking effect - var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. - filters += filter(type="wave", x=0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS) - animate(filters[our_filter], offset = 0, size = 0, time = length, flags = ANIMATION_PARALLEL) - - //Wait for animations to finish - sleep(length+5) - - //Remove those - filters -= filter(type="wave", x=0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS) - - -// So cloaked things can see themselves, if necessary -/atom/movable/proc/get_cloaked_selfimage() - var/icon/selficon = icon(icon, icon_state) - selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White - var/image/selfimage = image(selficon) - selfimage.color = "#0000FF" - selfimage.alpha = 100 - selfimage.layer = initial(layer) - selfimage.plane = initial(plane) - selfimage.loc = src - - return selfimage - -/atom/movable/proc/get_cell() - return +/atom/movable + layer = OBJ_LAYER + appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER + glide_size = 8 + var/last_move = null //The direction the atom last moved + var/anchored = 0 + // var/elevation = 2 - not used anywhere + var/moving_diagonally + var/move_speed = 10 + var/l_move_time = 1 + var/throwing = 0 + var/thrower + var/turf/throw_source = null + var/throw_speed = 2 + var/throw_range = 7 + var/moved_recently = 0 + var/mob/pulledby = null + var/item_state = null // Used to specify the item state for the on-mob overlays. + var/icon_scale_x = 1 // Used to scale icons up or down horizonally in update_transform(). + var/icon_scale_y = 1 // Used to scale icons up or down vertically in update_transform(). + var/icon_rotation = 0 // Used to rotate icons in update_transform() + var/icon_expected_height = 32 + var/icon_expected_width = 32 + var/old_x = 0 + var/old_y = 0 + var/datum/riding/riding_datum = null + var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P) + var/movement_type = NONE + + var/cloaked = FALSE //If we're cloaked or not + var/image/cloaked_selfimage //The image we use for our client to let them see where we are + +/atom/movable/Initialize(mapload) + . = ..() + switch(blocks_emissive) + if(EMISSIVE_BLOCK_GENERIC) + var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = PLANE_EMISSIVE, alpha = src.alpha) + gen_emissive_blocker.color = GLOB.em_block_color + gen_emissive_blocker.dir = dir + gen_emissive_blocker.appearance_flags |= appearance_flags + add_overlay(list(gen_emissive_blocker), TRUE) + if(EMISSIVE_BLOCK_UNIQUE) + render_target = ref(src) + em_block = new(src, render_target) + add_overlay(list(em_block), TRUE) + if(opacity) + AddElement(/datum/element/light_blocking) + switch(light_system) + if(STATIC_LIGHT) + update_light() + if(MOVABLE_LIGHT) + AddComponent(/datum/component/overlay_lighting, starts_on = light_on) + if(MOVABLE_LIGHT_DIRECTIONAL) + AddComponent(/datum/component/overlay_lighting, is_directional = TRUE, starts_on = light_on) + +/atom/movable/Destroy() + . = ..() + for(var/atom/movable/AM in contents) + qdel(AM) + + if(opacity) + RemoveElement(/datum/element/light_blocking) + + moveToNullspace() + + vis_contents.Cut() + for(var/atom/movable/A as anything in vis_locs) + A.vis_contents -= src + + if(pulledby) + pulledby.stop_pulling() + + if(orbiting) + stop_orbit() + QDEL_NULL(riding_datum) //VOREStation Add + +/atom/movable/vv_edit_var(var_name, var_value) + if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly. + return FALSE + return ..() + +//////////////////////////////////////// +/atom/movable/Move(atom/newloc, direct = 0, movetime) + // Didn't pass enough info + if(!loc || !newloc) + return FALSE + + // Store this early before we might move, it's used several places + var/atom/oldloc = loc + + // If we're not moving to the same spot (why? does that even happen?) + if(loc != newloc) + if(!direct) + direct = get_dir(oldloc, newloc) + if (IS_CARDINAL(direct)) //Cardinal move + // Track our failure if any in this value + . = TRUE + + // Face the direction of movement + set_dir(direct) + + // Check to make sure we can leave + if(!loc.Exit(src, newloc)) + . = FALSE + + // Check to make sure we can enter, if we haven't already failed + if(. && !newloc.Enter(src, src.loc)) + . = FALSE + + // Check to make sure if we're multi-tile we can move, if we haven't already failed + if(. && !check_multi_tile_move_density_dir(direct, locs)) + . = FALSE + + // Definitely moving if you enter this, no failures so far + if(. && locs.len <= 1) // We're not a multi-tile object. + var/area/oldarea = get_area(oldloc) + var/area/newarea = get_area(newloc) + var/old_z = get_z(oldloc) + var/dest_z = get_z(newloc) + + // Do The Move + glide_for(movetime) + loc = newloc + . = TRUE + + // So objects can be informed of z-level changes + if (old_z != dest_z) + onTransitZ(old_z, dest_z) + + // We don't call parent so we are calling this for byond + oldloc.Exited(src, newloc) + if(oldarea != newarea) + oldarea.Exited(src, newloc) + + // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself + for(var/i in oldloc) + var/atom/movable/thing = i + // We don't call parent so we are calling this for byond + thing.Uncrossed(src) + + // We don't call parent so we are calling this for byond + newloc.Entered(src, oldloc) + if(oldarea != newarea) + newarea.Entered(src, oldloc) + + // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself + for(var/i in loc) + var/atom/movable/thing = i + // We don't call parent so we are calling this for byond + thing.Crossed(src, oldloc) + + // We're a multi-tile object (multiple locs) + else if(. && newloc) + . = doMove(newloc) + + //Diagonal move, split it into cardinal moves + else + moving_diagonally = FIRST_DIAG_STEP + var/first_step_dir + // The `&& moving_diagonally` checks are so that a forceMove taking + // place due to a Crossed, Bumped, etc. call will interrupt + // the second half of the diagonal movement, or the second attempt + // at a first half if step() fails because we hit something. + glide_for(movetime) + if (direct & NORTH) + if (direct & EAST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & WEST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & SOUTH) + if (direct & EAST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + else if (direct & WEST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + // If we failed, turn to face the direction of the first step at least + if(!. && moving_diagonally == SECOND_DIAG_STEP) + set_dir(first_step_dir) + // Done, regardless! + moving_diagonally = 0 + // We return because step above will call Move() and we don't want to do shenanigans back in here again + return + + else if(!loc || (loc == oldloc)) + last_move = 0 + return + + // If we moved, call Moved() on ourselves + if(.) + Moved(oldloc, direct, FALSE, movetime) + + // Update timers/cooldown stuff + move_speed = world.time - l_move_time + l_move_time = world.time + last_move = direct // The direction you last moved + // set_dir(direct) //Don't think this is necessary + +//Called after a successful Move(). By this point, we've already moved +/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE, movetime) + SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, old_loc, direction, forced, movetime) + // Handle any buckled mobs on this movable + if(has_buckled_mobs()) + handle_buckled_mob_movement(old_loc, direction, movetime) + if(riding_datum) + riding_datum.handle_vehicle_layer() + riding_datum.handle_vehicle_offsets() + for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update. + light.source_atom.update_light() + return TRUE + +/atom/movable/set_dir(newdir) + . = ..(newdir) + if(riding_datum) + riding_datum.handle_vehicle_offsets() + +/atom/movable/relaymove(mob/user, direction) + . = ..() + if(riding_datum) + riding_datum.handle_ride(user, direction) + +// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. +// You probably want CanPass() +/atom/movable/Cross(atom/movable/AM) + return CanPass(AM, loc) + +/atom/movable/CanPass(atom/movable/mover, turf/target) + . = ..() + if(locs && locs.len >= 2) // If something is standing on top of us, let them pass. + if(mover.loc in locs) + . = TRUE + return . + +//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! +/atom/movable/Crossed(atom/movable/AM, oldloc) + return + +/atom/movable/Uncross(atom/movable/AM, atom/newloc) + . = ..() + if(isturf(newloc) && !CheckExit(AM, newloc)) + return FALSE + +/atom/movable/Bump(atom/A) + if(!A) + CRASH("Bump was called with no argument.") + . = ..() + if(throwing) + throw_impact(A) + throwing = 0 + if(QDELETED(A)) + return + A.Bumped(src) + A.last_bumped = world.time + +/atom/movable/proc/forceMove(atom/destination, direction, movetime) + . = FALSE + if(destination) + . = doMove(destination, direction, movetime) + else + CRASH("No valid destination passed into forceMove") + +/atom/movable/proc/moveToNullspace() + return doMove(null) + +/atom/movable/proc/doMove(atom/destination, direction, movetime) + var/atom/oldloc = loc + var/area/old_area = get_area(oldloc) + var/same_loc = oldloc == destination + + if(destination) + var/area/destarea = get_area(destination) + + // Do The Move + glide_for(movetime) + last_move = isnull(direction) ? 0 : direction + loc = destination + + // Unset this in case it was set in some other proc. We're no longer moving diagonally for sure. + moving_diagonally = 0 + + // We are moving to a different loc + if(!same_loc) + // Not moving out of nullspace + if(oldloc) + oldloc.Exited(src, destination) + // If it's not the same area, Exited() it + if(old_area && old_area != destarea) + old_area.Exited(src, destination) + + // Uncross everything where we left + for(var/i in oldloc) + var/atom/movable/AM = i + if(AM == src) + continue + AM.Uncrossed(src) + if(loc != destination) // Uncrossed() triggered a separate movement + return + + // Information about turf and z-levels for source and dest collected + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + + // So objects can be informed of z-level changes + if (old_z != dest_z) + onTransitZ(old_z, dest_z) + + // Destination atom Entered + destination.Entered(src, oldloc) + + // Entered() the new area if it's not the same area + if(destarea && old_area != destarea) + destarea.Entered(src, oldloc) + + // We ignore ourselves because if we're multi-tile we might be in both old and new locs + for(var/i in destination) + var/atom/movable/AM = i + if(AM == src) + continue + AM.Crossed(src, oldloc) + if(loc != destination) // Crossed triggered a separate movement + return + + // Call our thingy to inform everyone we moved + Moved(oldloc, NONE, TRUE) + + // Break pulling if we are too far to pull now. + if(pulledby && (pulledby.z != src.z || get_dist(pulledby, src) > 1)) + pulledby.stop_pulling() + + // We moved + return TRUE + + //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) + else if(oldloc) + loc = null + + // Uncross everything where we left (no multitile safety like above because we are definitely not still there) + for(var/i in oldloc) + var/atom/movable/AM = i + AM.Uncrossed(src) + + // Exited() our loc and area + oldloc.Exited(src, null) + if(old_area) + old_area.Exited(src, null) + + // We moved + return TRUE + +/atom/movable/proc/onTransitZ(old_z,new_z) + GLOB.z_moved_event.raise_event(src, old_z, new_z) + for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) + +/atom/movable/proc/glide_for(movetime) + if(movetime) + glide_size = WORLD_ICON_SIZE/max(DS2TICKS(movetime), 1) + spawn(movetime) + glide_size = initial(glide_size) + else + glide_size = initial(glide_size) + +///////////////////////////////////////////////////////////////// + +//called when src is thrown into hit_atom +/atom/movable/proc/throw_impact(atom/hit_atom, var/speed) + if(istype(hit_atom,/mob/living)) + var/mob/living/M = hit_atom + if(M.buckled == src) + return // Don't hit the thing we're buckled to. + M.hitby(src,speed) + + else if(isobj(hit_atom)) + var/obj/O = hit_atom + if(!O.anchored) + step(O, src.last_move) + O.hitby(src,speed) + + else if(isturf(hit_atom)) + src.throwing = 0 + var/turf/T = hit_atom + T.hitby(src,speed) + +//decided whether a movable atom being thrown can pass through the turf it is in. +/atom/movable/proc/hit_check(var/speed) + if(src.throwing) + for(var/atom/A in get_turf(src)) + if(A == src) continue + if(istype(A,/mob/living)) + if(A:lying) continue + src.throw_impact(A,speed) + if(isobj(A)) + if(!A.density || A.throwpass) + continue + // Special handling of windows, which are dense but block only from some directions + if(istype(A, /obj/structure/window)) + var/obj/structure/window/W = A + if (!W.is_fulltile() && !(turn(src.last_move, 180) & A.dir)) + continue + // Same thing for (closed) windoors, which have the same problem + else if(istype(A, /obj/machinery/door/window) && !(turn(src.last_move, 180) & A.dir)) + continue + src.throw_impact(A,speed) + +/atom/movable/proc/throw_at(atom/target, range, speed, thrower) + if(!target || !src) + return 0 + if(target.z != src.z) + return 0 + //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target + src.throwing = 1 + src.thrower = thrower + src.throw_source = get_turf(src) //store the origin turf + src.pixel_z = 0 + if(usr) + if(HULK in usr.mutations) + src.throwing = 2 // really strong throw! + + var/dist_travelled = 0 + var/dist_since_sleep = 0 + var/area/a = get_area(src.loc) + + var/dist_x = abs(target.x - src.x) + var/dist_y = abs(target.y - src.y) + + var/dx + if (target.x > src.x) + dx = EAST + else + dx = WEST + + var/dy + if (target.y > src.y) + dy = NORTH + else + dy = SOUTH + + var/error + var/major_dir + var/major_dist + var/minor_dir + var/minor_dist + if(dist_x > dist_y) + error = dist_x/2 - dist_y + major_dir = dx + major_dist = dist_x + minor_dir = dy + minor_dist = dist_y + else + error = dist_y/2 - dist_x + major_dir = dy + major_dist = dist_y + minor_dir = dx + minor_dist = dist_x + + range = min(dist_x + dist_y, range) + + while(src && target && src.throwing && istype(src.loc, /turf) \ + && ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \ + || (a && a.has_gravity == 0) \ + || istype(src.loc, /turf/space))) + // only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up + var/atom/step + if(error >= 0) + step = get_step(src, major_dir) + error -= minor_dist + else + step = get_step(src, minor_dir) + error += major_dist + if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge + break + src.Move(step) + hit_check(speed) + dist_travelled++ + dist_since_sleep++ + if(dist_since_sleep >= speed) + dist_since_sleep = 0 + sleep(1) + a = get_area(src.loc) + // and yet it moves + if(src.does_spin) + src.SpinAnimation(speed = 4, loops = 1) + + //done throwing, either because it hit something or it finished moving + if(isobj(src)) src.throw_impact(get_turf(src),speed) + src.throwing = 0 + src.thrower = null + src.throw_source = null + fall() + + +//Overlays +/atom/movable/overlay + var/atom/master = null + anchored = 1 + +/atom/movable/overlay/New() + for(var/x in src.verbs) + src.verbs -= x + ..() + +/atom/movable/overlay/attackby(a, b) + if (src.master) + return src.master.attackby(a, b) + return + +/atom/movable/overlay/attack_hand(a, b, c) + if (src.master) + return src.master.attack_hand(a, b, c) + return + +/atom/movable/proc/touch_map_edge() + if(z in using_map.sealed_levels) + return + + if(using_map.use_overmap) + overmap_spacetravel(get_turf(src), src) + return + + var/move_to_z = src.get_transit_zlevel() + if(move_to_z) + var/new_z = move_to_z + var/new_x + var/new_y + + if(x <= TRANSITIONEDGE) + new_x = world.maxx - TRANSITIONEDGE - 2 + new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) + + else if (x >= (world.maxx - TRANSITIONEDGE + 1)) + new_x = TRANSITIONEDGE + 1 + new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) + + else if (y <= TRANSITIONEDGE) + new_y = world.maxy - TRANSITIONEDGE -2 + new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) + + else if (y >= (world.maxy - TRANSITIONEDGE + 1)) + new_y = TRANSITIONEDGE + 1 + new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) + + if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear + var/datum/game_mode/nuclear/G = ticker.mode + G.check_nuke_disks() + + var/turf/T = locate(new_x, new_y, new_z) + if(istype(T)) + forceMove(T) + +//by default, transition randomly to another zlevel +/atom/movable/proc/get_transit_zlevel() + var/list/candidates = using_map.accessible_z_levels.Copy() + candidates.Remove("[src.z]") + + if(!candidates.len) + return null + return text2num(pickweight(candidates)) + +// Returns the current scaling of the sprite. +// Note this DOES NOT measure the height or width of the icon, but returns what number is being multiplied with to scale the icons, if any. +/atom/movable/proc/get_icon_scale_x() + return icon_scale_x + +/atom/movable/proc/get_icon_scale_y() + return icon_scale_y + +/atom/movable/proc/update_transform() + var/matrix/M = matrix() + M.Scale(icon_scale_x, icon_scale_y) + M.Turn(icon_rotation) + src.transform = M + +// Use this to set the object's scale. +/atom/movable/proc/adjust_scale(new_scale_x, new_scale_y) + if(isnull(new_scale_y)) + new_scale_y = new_scale_x + if(new_scale_x != 0) + icon_scale_x = new_scale_x + if(new_scale_y != 0) + icon_scale_y = new_scale_y + update_transform() + +/atom/movable/proc/adjust_rotation(new_rotation) + icon_rotation = new_rotation + update_transform() + +// Called when touching a lava tile. +/atom/movable/proc/lava_act() + fire_act(null, 10000, 1000) + + +// Procs to cloak/uncloak +/atom/movable/proc/cloak() + if(cloaked) + return FALSE + cloaked = TRUE + . = TRUE // We did work + + var/static/animation_time = 1 SECOND + cloaked_selfimage = get_cloaked_selfimage() + + //Wheeee + cloak_animation(animation_time) + + //Needs to be last so people can actually see the effect before we become invisible + if(cloaked) // Ensure we are still cloaked after the animation delay + plane = CLOAKED_PLANE + +/atom/movable/proc/uncloak() + if(!cloaked) + return FALSE + cloaked = FALSE + . = TRUE // We did work + + var/static/animation_time = 1 SECOND + QDEL_NULL(cloaked_selfimage) + + //Needs to be first so people can actually see the effect, so become uninvisible first + plane = initial(plane) + + //Oooooo + uncloak_animation(animation_time) + + +// Animations for cloaking/uncloaking +/atom/movable/proc/cloak_animation(var/length = 1 SECOND) + //Save these + var/initial_alpha = alpha + + //Animate alpha fade + animate(src, alpha = 0, time = length) + + //Animate a cloaking effect + var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. + filters += filter(type="wave", x = 0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS) + animate(filters[our_filter], offset = 1, size = 8, time = length, flags = ANIMATION_PARALLEL) + + //Wait for animations to finish + sleep(length+5) + + //Remove those + filters -= filter(type="wave", x = 0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS) + + //Back to original alpha + alpha = initial_alpha + +/atom/movable/proc/uncloak_animation(var/length = 1 SECOND) + //Save these + var/initial_alpha = alpha + + //Put us back to normal, but no alpha + alpha = 0 + + //Animate alpha fade up + animate(src, alpha = initial_alpha, time = length) + + //Animate a cloaking effect + var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. + filters += filter(type="wave", x=0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS) + animate(filters[our_filter], offset = 0, size = 0, time = length, flags = ANIMATION_PARALLEL) + + //Wait for animations to finish + sleep(length+5) + + //Remove those + filters -= filter(type="wave", x=0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS) + + +// So cloaked things can see themselves, if necessary +/atom/movable/proc/get_cloaked_selfimage() + var/icon/selficon = icon(icon, icon_state) + selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White + var/image/selfimage = image(selficon) + selfimage.color = "#0000FF" + selfimage.alpha = 100 + selfimage.layer = initial(layer) + selfimage.plane = initial(plane) + selfimage.loc = src + + return selfimage + +/atom/movable/proc/get_cell() + return diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index 54ae1f942c..4891db7091 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' //CHOMPEdit: Continues using new air alarm sprite, contrary to YW 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 283d86aeff..9d991ca556 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..ec43bb22df 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -826,3 +826,4 @@ 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 31c8168a1c..2de2dc2991 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 5644ea0283..82f8b58efe 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 @@ -50,6 +51,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 e6185c0a89..c6552b6557 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/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 a48ac9cd05..7dd3f52c5d 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/say.dm b/code/modules/mob/living/say.dm index 2abe2cc145..fc7d08677b 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -347,20 +347,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 ef56b6b020..ca7d3b2635 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 eb26ea848e..0d16617feb 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/maps/offmap_vr/om_ships/itglight.dmm b/maps/offmap_vr/om_ships/itglight.dmm index 1bb19ea182..6c8a11d2aa 100644 --- a/maps/offmap_vr/om_ships/itglight.dmm +++ b/maps/offmap_vr/om_ships/itglight.dmm @@ -27,6 +27,13 @@ pixel_x = -26 }, /mob/living/simple_mob/vore/woof/cass, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "ac" = ( @@ -3355,6 +3362,19 @@ /obj/machinery/smartfridge/chemistry, /turf/simulated/floor/tiled/eris/white/cargo, /area/itglight/medbay) +"wc" = ( +/obj/structure/bed/chair/comfy/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/brown_platform, +/area/itglight/common) "wg" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -3545,10 +3565,7 @@ /obj/structure/bed/chair/comfy/brown{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 8 - }, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "wX" = ( /obj/structure/cable/pink{ @@ -3855,7 +3872,7 @@ icon_state = "frame"; pixel_y = 62 }, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "yN" = ( /obj/machinery/seed_extractor, @@ -4973,18 +4990,6 @@ }, /turf/simulated/floor, /area/itglight/starboarddocking) -"EN" = ( -/obj/structure/cable/pink{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) "EP" = ( /obj/structure/cable/pink{ d1 = 4; @@ -5736,6 +5741,17 @@ /area/itglight/shuttlebay) "IN" = ( /obj/structure/coatrack, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "IQ" = ( @@ -5796,6 +5812,13 @@ /turf/simulated/floor/tiled/steel_ridged, /area/itglight/starboardengi) "Ji" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Jk" = ( @@ -5812,14 +5835,16 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/itglight/starboarddocking) "Jm" = ( -/obj/structure/cable/pink{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/structure/cable/pink{ + d1 = 2; + d2 = 8; + icon_state = "2-8" }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) @@ -6203,13 +6228,18 @@ /turf/simulated/floor/tiled/dark, /area/itglight/passengersleeping) "LZ" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/structure/cable/pink{ d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 8; + icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Mg" = ( @@ -6217,6 +6247,17 @@ /obj/machinery/computer/ship/navigation/telescreen{ pixel_y = 30 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Mh" = ( @@ -6243,6 +6284,17 @@ /obj/structure/bed/chair/comfy/brown{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/structure/cable/pink{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Mm" = ( @@ -6316,27 +6368,19 @@ /obj/machinery/light{ dir = 8 }, -/turf/simulated/floor/tiled/eris/steel/brown_platform, -/area/itglight/common) -"ME" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable/pink{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "MF" = ( /obj/structure/table/wooden_reinforced, /obj/item/device/paicard, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "MG" = ( /obj/structure/cable{ @@ -6372,30 +6416,17 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/monotile, /area/itglight/lockers) -"MU" = ( +"MY" = ( +/obj/structure/bed/chair/sofa/brown/right{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable/pink{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, -/obj/structure/cable/pink{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/structure/cable/pink{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) -"MY" = ( -/obj/structure/bed/chair/sofa/brown/right{ - dir = 4 - }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Na" = ( @@ -6447,11 +6478,8 @@ /area/itglight/starboardcargo) "Nn" = ( /obj/structure/table/wooden_reinforced, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 - }, /obj/random/coin, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "No" = ( /obj/effect/floor_decal/industrial/warning{ @@ -6473,18 +6501,6 @@ }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/shuttlebay) -"Ns" = ( -/obj/structure/cable/pink{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) "Nv" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -6634,6 +6650,17 @@ /obj/structure/bed/chair/sofa/brown/corner{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/structure/cable/pink{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Om" = ( @@ -6658,12 +6685,34 @@ /area/itglight/kitchen) "Or" = ( /obj/structure/bed/chair/sofa/brown, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Ot" = ( /obj/structure/bed/chair/comfy/brown{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Ov" = ( @@ -6679,16 +6728,21 @@ /turf/simulated/floor/tiled/dark, /area/itglight/passengersleeping) "Ow" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 8 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 }, /obj/structure/cable/pink{ - d1 = 4; + d1 = 1; d2 = 8; - icon_state = "4-8" + icon_state = "1-8" + }, +/obj/structure/cable/pink{ + d1 = 2; + d2 = 8; + icon_state = "2-8" }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) @@ -6910,6 +6964,13 @@ /obj/structure/handrail{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Qh" = ( @@ -6934,16 +6995,6 @@ /obj/machinery/atmospherics/pipe/tank/phoron/full, /turf/simulated/floor, /area/itglight/portengi) -"Qp" = ( -/obj/structure/cable/pink{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) "Qq" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -7010,7 +7061,7 @@ /area/itglight/medbay) "QI" = ( /obj/structure/table/wooden_reinforced, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "QN" = ( /obj/structure/handrail{ @@ -7021,6 +7072,7 @@ d2 = 2; icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "QO" = ( @@ -7086,7 +7138,7 @@ /area/itglight/medbay) "Rb" = ( /obj/structure/flora/pottedplant/orientaltree, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "Rd" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -7124,9 +7176,6 @@ /area/itglight/portengi) "Rp" = ( /obj/structure/table/wooden_reinforced, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, /obj/structure/cable/pink{ d1 = 1; d2 = 2; @@ -7135,6 +7184,9 @@ /obj/machinery/light{ dir = 4 }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Rq" = ( @@ -7227,42 +7279,23 @@ }, /turf/simulated/floor/tiled/eris/white/cargo, /area/itglight/medbay) -"Sh" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 8 - }, -/obj/structure/cable/pink{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) "Sw" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 8 - }, -/obj/structure/cable/pink{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/pink{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/structure/cable/pink{ d1 = 2; d2 = 4; icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Sz" = ( @@ -7569,9 +7602,6 @@ "Uw" = ( /turf/simulated/wall/shull, /area/itglight/medbay) -"UF" = ( -/turf/simulated/floor/carpet/sblucarpet, -/area/itglight/common) "UH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -7649,10 +7679,7 @@ /turf/simulated/floor/tiled/eris/white/cargo, /area/itglight/medbay) "UZ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/carpet/sblucarpet, +/turf/simulated/floor/glass/reinforced, /area/itglight/common) "Vd" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -7709,6 +7736,35 @@ }, /turf/simulated/floor, /area/itglight/starboardengi) +<<<<<<< HEAD +||||||| parent of b9e47f102b... Merge pull request #10764 from VOREStation/Arokha/multiviz +"Vz" = ( +/obj/machinery/newscaster{ + pixel_x = -12; + pixel_y = -26 + }, +/turf/simulated/floor/tiled/eris/steel/brown_platform, +/area/itglight/common) +======= +"Vz" = ( +/obj/machinery/newscaster{ + pixel_x = -12; + pixel_y = -26 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/eris/steel/brown_platform, +/area/itglight/common) +>>>>>>> b9e47f102b... Merge pull request #10764 from VOREStation/Arokha/multiviz "VB" = ( /obj/machinery/light{ dir = 1 @@ -7883,6 +7939,17 @@ /area/itglight/portsolars) "WE" = ( /obj/structure/flora/pottedplant/minitree, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/structure/cable/pink{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "WG" = ( @@ -8446,6 +8513,17 @@ /area/itglight/shuttlebay) "Zs" = ( /obj/structure/bed/chair/sofa/brown/left, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/pink{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/common) "Zw" = ( @@ -18148,9 +18226,9 @@ Xu Or yK QI -Sh -UF -UF +UZ +UZ +UZ IN Xu ZG @@ -18290,10 +18368,22 @@ Xu Zs QI Nn +<<<<<<< HEAD Sh UF UF Ji +||||||| parent of b9e47f102b... Merge pull request #10764 from VOREStation/Arokha/multiviz +Sh +UF +UF +Vz +======= +UZ +UZ +UZ +Vz +>>>>>>> b9e47f102b... Merge pull request #10764 from VOREStation/Arokha/multiviz Xu Ud YT @@ -18430,11 +18520,11 @@ LG bk wL LZ -ME -Ns -MU -Qp -EN +UZ +UZ +UZ +UZ +UZ Jm SO Oe @@ -18573,9 +18663,9 @@ Ng Xu Ot wW -UF -Sh -UF +UZ +UZ +UZ UZ Jt Xu @@ -18716,8 +18806,8 @@ Xu Mg MF Rb -Sh -UF +UZ +UZ UZ SH Xu @@ -18856,7 +18946,7 @@ kR Ek Xu Ml -Ml +wc Ji Sw QN diff --git a/vorestation.dme b/vorestation.dme index 5708583578..1ca7f1ebeb 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -289,7 +289,6 @@ #include "code\controllers\subsystems\mobs.dm" #include "code\controllers\subsystems\nanoui.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" @@ -373,6 +372,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" @@ -3417,7 +3417,6 @@ #include "code\modules\multiz\stairs.dm" #include "code\modules\multiz\turf.dm" #include "code\modules\multiz\turf_yw.dm" -#include "code\modules\multiz\zshadow.dm" #include "code\modules\nano\nanoexternal.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanomapgen.dm"