[READY]MultiZ stuff - tile atmos, movement backend, falling backend, etc etc - Electric boogaloo (#40428)

Basic multiZ mob movement procs (Observers can always move)
Open space, showing what things are below it, and everything that entails. No complex support for dynamic generation just yet.
Decide how openspace should look :/

    Atoms falling through open space (NO MOB SUPPORT/DAMAGE/ANYTHING YET.)

//CANCELLED FOR ANOTHER PR - [ ] Being able to see upwards? Downwards is going to be handled by open space.

MultiZ tile atmospherics - EDIT: Working demo! https://puu.sh/B7mUs/3f6274740f.mp4
Bugtest the heck out of this trainwreck.
This commit is contained in:
kevinz000
2018-12-11 01:09:59 -08:00
committed by yogstation13-bot
parent 36f9fa9b90
commit d1411a8eee
29 changed files with 10633 additions and 64 deletions

File diff suppressed because it is too large Load Diff

1
_maps/multiz_debug.dm Normal file
View File

@@ -0,0 +1 @@
#define FORCE_MAP "_maps/multiz_debug.json"

6
_maps/multiz_debug.json Normal file
View File

@@ -0,0 +1,6 @@
{
"map_name": "MultiZ Debug",
"map_path": "map_files/debug",
"map_file": "multiz.dmm",
"traits": [{"Up": 1}, {"Up": 1, "Down": -1}, {"Down": -1}]
}

View File

@@ -147,7 +147,9 @@
#define ATMOS_PASS_NO 0
#define ATMOS_PASS_PROC -1 //ask CanAtmosPass()
#define ATMOS_PASS_DENSITY -2 //just check density
#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) )
#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) )
//OPEN TURF ATMOS
#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn

View File

@@ -103,6 +103,8 @@
// /turf signals
#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
// /atom/movable signals
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)

View File

@@ -9,6 +9,7 @@
#define FLOOR_PLANE -2
#define GAME_PLANE -1
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define SPACE_LAYER 1.8
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
#define MID_TURF_LAYER 2.02
@@ -82,11 +83,15 @@
#define ABOVE_LIGHTING_PLANE 16
#define ABOVE_LIGHTING_LAYER 16
#define BYOND_LIGHTING_PLANE 17
#define BYOND_LIGHTING_LAYER 17
#define FLOOR_OPENSPACE_PLANE 17
#define OPENSPACE_LAYER 17
#define BYOND_LIGHTING_PLANE 18
#define BYOND_LIGHTING_LAYER 18
#define CAMERA_STATIC_PLANE 19
#define CAMERA_STATIC_LAYER 19
#define CAMERA_STATIC_PLANE 18
#define CAMERA_STATIC_LAYER 18
//HUD layer defines
#define FULLSCREEN_PLANE 19

View File

@@ -1,6 +1,16 @@
GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(cardinals_multiz, list(NORTH, SOUTH, EAST, WEST, UP, DOWN))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(corners_multiz, list(UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(diagonals_multiz, list(
NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST,
UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST,
DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(alldirs_multiz, list(
NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST,
UP, UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST,
DOWN, DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created
GLOBAL_LIST_EMPTY(start_landmarks_list) //list of all spawn points created

View File

@@ -16,6 +16,28 @@
//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong.
/obj/screen/plane_master/proc/backdrop(mob/mymob)
/obj/screen/plane_master/openspace
name = "open space plane master"
plane = FLOOR_OPENSPACE_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_MULTIPLY
alpha = 255
/obj/screen/plane_master/openspace/backdrop(mob/mymob)
filters = list()
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -10)
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -15)
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -20)
/obj/screen/plane_master/proc/outline(_size, _color)
filters += filter(type = "outline", size = _size, color = _color)
/obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA")
filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border)
/obj/screen/plane_master/proc/clear_filters()
filters = list()
/obj/screen/plane_master/floor
name = "floor plane master"
plane = FLOOR_PLANE

View File

@@ -186,6 +186,10 @@
else
M.forceMove(src)
//common name
/atom/proc/update_multiz(prune_on_fail = FALSE)
return FALSE
/atom/proc/assume_air(datum/gas_mixture/giver)
qdel(giver)
return null
@@ -728,3 +732,6 @@ Proc for attack log creation, because really why not
/atom/movable/proc/get_filter(name)
if(filter_data && filter_data[name])
return filters[filter_data.Find(name)]
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
return FALSE

View File

@@ -36,6 +36,51 @@
var/datum/component/orbiter/orbiting
var/can_be_z_moved = TRUE
var/zfalling = FALSE
/atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction)
if(!direction)
direction = DOWN
if(!source)
source = get_turf(src)
if(!source)
return FALSE
if(!target)
target = get_step_multiz(source, direction)
if(!target)
return FALSE
return !(movement_type & FLYING) && has_gravity(source) && !throwing
/atom/movable/proc/onZImpact(turf/T, levels)
var/atom/highest = T
for(var/i in T.contents)
var/atom/A = i
if(!A.density)
continue
if(isobj(A) || ismob(A))
if(A.layer > highest.layer)
highest = A
INVOKE_ASYNC(src, .proc/SpinAnimation, 5, 2)
throw_impact(highest)
return TRUE
//For physical constraints to travelling up/down.
/atom/movable/proc/can_zTravel(turf/destination, direction)
var/turf/T = get_turf(src)
if(!T)
return FALSE
if(!direction)
if(!destination)
return FALSE
direction = get_dir(T, destination)
if(direction != UP && direction != DOWN)
return FALSE
if(!destination)
destination = get_step_multiz(src, direction)
if(!destination)
return FALSE
return T.zPassOut(src, direction, destination) && destination.zPassIn(src, direction, T)
/atom/movable/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("step_x", "step_y", "step_size")
var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height")

View File

@@ -58,6 +58,9 @@
/obj/effect/abstract/singularity_act()
return
/obj/effect/abstract/has_gravity(turf/T)
return FALSE
/obj/effect/dummy/singularity_pull()
return

View File

@@ -0,0 +1,111 @@
#define STAIR_TERMINATOR_AUTOMATIC 0
#define STAIR_TERMINATOR_NO 1
#define STAIR_TERMINATOR_YES 2
/obj/structure/stairs
name = "stairs"
icon = 'icons/obj/stairs.dmi'
icon_state = "stairs"
anchored = TRUE
//dir = direction of travel to go upwards
var/force_open_above = FALSE
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
var/datum/component/redirect/multiz_signal_listener
/obj/structure/stairs/Initialize(mapload)
if(force_open_above)
force_open_above()
build_signal_listener()
update_surrounding()
return ..()
/obj/structure/stairs/Destroy()
QDEL_NULL(multiz_signal_listener)
return ..()
/obj/structure/stairs/Move() //Look this should never happen but...
. = ..()
if(force_open_above)
build_signal_listener()
update_surrounding()
/obj/structure/stairs/proc/update_surrounding()
update_icon()
for(var/i in GLOB.cardinals)
var/turf/T = get_step(get_turf(src), i)
var/obj/structure/stairs/S = locate() in T
if(S)
S.update_icon()
/obj/structure/stairs/Uncross(atom/movable/AM, turf/newloc)
if(!newloc || !AM)
return ..()
if(isliving(AM) && isTerminator() && (get_dir(src, newloc) == dir))
stair_ascend(AM)
return FALSE
return ..()
/obj/structure/stairs/Cross(atom/movable/AM)
if(isTerminator() && (get_dir(src, AM) == dir))
return FALSE
return ..()
/obj/structure/stairs/update_icon()
if(isTerminator())
icon_state = "stairs_t"
else
icon_state = "stairs"
/obj/structure/stairs/proc/stair_ascend(atom/movable/AM)
var/turf/checking = get_step_multiz(get_turf(src), UP)
if(!istype(checking))
return
if(!checking.zPassIn(AM, UP, get_turf(src)))
return
var/turf/target = get_step_multiz(get_turf(src), (dir|UP))
if(istype(target) && !target.can_zFall(AM, null, get_step_multiz(target, DOWN))) //Don't throw them into a tile that will just dump them back down.
AM.forceMove(target)
/obj/structure/stairs/vv_edit_var(var_name, var_value)
. = ..()
if(.)
if(var_name == NAMEOF(src, force_open_above))
if(!var_value)
QDEL_NULL(multiz_signal_listener)
else
build_signal_listener()
force_open_above()
/obj/structure/stairs/proc/build_signal_listener()
QDEL_NULL(multiz_signal_listener)
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
multiz_signal_listener = T.AddComponent(/datum/component/redirect, list(COMSIG_TURF_MULTIZ_NEW = CALLBACK(src, .proc/on_multiz_new)))
/obj/structure/stairs/proc/force_open_above()
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
if(T && !istype(T))
T.ChangeTurf(/turf/open/openspace)
/obj/structure/stairs/proc/on_multiz_new(turf/source, dir)
if(dir == UP)
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
if(T && !istype(T))
T.ChangeTurf(/turf/open/openspace)
/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1)
return isTerminator()
/obj/structure/stairs/proc/isTerminator() //If this is the last stair in a chain and should move mobs up
if(terminator_mode != STAIR_TERMINATOR_AUTOMATIC)
return (terminator_mode == STAIR_TERMINATOR_YES)
var/turf/T = get_turf(src)
if(!T)
return FALSE
var/turf/them = get_step(T, dir)
if(!them)
return FALSE
for(var/obj/structure/stairs/S in them)
if(S.dir == dir)
return FALSE
return TRUE

View File

@@ -16,6 +16,22 @@
if(wet)
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
//direction is direction of travel of A
/turf/open/zPassIn(atom/movable/A, direction, turf/source)
return (direction == DOWN)
//direction is direction of travel of A
/turf/open/zPassOut(atom/movable/A, direction, turf/destination)
return (direction == UP)
//direction is direction of travel of air
/turf/open/zAirIn(direction, turf/source)
return (direction == DOWN)
//direction is direction of travel of air
/turf/open/zAirOut(direction, turf/source)
return (direction == UP)
/turf/open/indestructible
name = "floor"
icon = 'icons/turf/floors.dmi'
@@ -157,43 +173,14 @@
update_visuals()
current_cycle = times_fired
//cache some vars
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals)
var/turf/open/enemy_tile = get_step(src, direction)
if(!istype(enemy_tile))
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile
continue
CalculateAdjacentTurfs()
for(var/i in atmos_adjacent_turfs)
var/turf/open/enemy_tile = i
var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
//only check this turf, if it didn't check us when it was initalized
if(enemy_tile.current_cycle < times_fired)
if(CANATMOSPASS(src, enemy_tile))
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(enemy_tile.atmos_adjacent_turfs)
atmos_adjacent_turfs[enemy_tile] = TRUE
enemy_tile.atmos_adjacent_turfs[src] = TRUE
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile
if (enemy_tile.atmos_adjacent_turfs)
enemy_tile.atmos_adjacent_turfs -= src
UNSETEMPTY(enemy_tile.atmos_adjacent_turfs)
continue
else
if (!atmos_adjacent_turfs || !atmos_adjacent_turfs[enemy_tile])
continue
if(!excited && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]")
excited = TRUE
SSair.active_turfs |= src
UNSETEMPTY(atmos_adjacent_turfs)
if (atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()

View File

@@ -0,0 +1,108 @@
/turf/open/openspace
name = "open space"
desc = "Watch your step!"
icon_state = "grey"
baseturfs = /turf/open/openspace
CanAtmosPassVertical = ATMOS_PASS_YES
plane = FLOOR_OPENSPACE_PLANE
layer = OPENSPACE_LAYER
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/can_cover_up = TRUE
var/can_build_on = TRUE
/turf/open/openspace/debug/update_multiz()
..()
return TRUE
/turf/open/openspace/Initialize()
. = ..()
return INITIALIZE_HINT_LATELOAD
/turf/open/openspace/LateInitialize()
update_multiz(TRUE, TRUE)
/turf/open/openspace/Destroy()
vis_contents.len = 0
return ..()
/turf/open/openspace/update_multiz(prune_on_fail = FALSE, init = FALSE)
. = ..()
var/turf/T = below()
if(!T)
vis_contents.len = 0
if(prune_on_fail)
ChangeTurf(/turf/open/floor/plating)
return FALSE
if(init)
vis_contents += T
return TRUE
/turf/open/openspace/multiz_turf_del(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
/turf/open/openspace/multiz_turf_new(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
/turf/open/openspace/zAirIn()
return TRUE
/turf/open/openspace/zAirOut()
return TRUE
/turf/open/openspace/zPassIn(atom/movable/A, direction, turf/source)
return TRUE
/turf/open/openspace/zPassOut(atom/movable/A, direction, turf/destination)
return TRUE
/turf/open/openspace/proc/CanCoverUp()
return can_cover_up
/turf/open/openspace/proc/CanBuildHere()
return can_build_on
/turf/open/openspace/attackby(obj/item/C, mob/user, params)
..()
if(!CanBuildHere())
return
if(istype(C, /obj/item/stack/rods))
var/obj/item/stack/rods/R = C
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
var/obj/structure/lattice/catwalk/W = locate(/obj/structure/lattice/catwalk, src)
if(W)
to_chat(user, "<span class='warning'>There is already a catwalk here!</span>")
return
if(L)
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
new/obj/structure/lattice/catwalk(src)
else
to_chat(user, "<span class='warning'>You need two rods to build a catwalk!</span>")
return
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
ReplaceWithLattice()
else
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
return
if(istype(C, /obj/item/stack/tile/plasteel))
if(!CanCoverUp())
return
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/plasteel/S = C
if(S.use(1))
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "<span class='notice'>You build a floor.</span>")
PlaceOnTop(/turf/open/floor/plating)
else
to_chat(user, "<span class='warning'>You need one floor tile to build a floor!</span>")
else
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")

View File

@@ -19,7 +19,6 @@
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
bullet_bounce_sound = null
/turf/open/space/basic/New() //Do not convert to Initialize
//This is used to optimize the map loader
return

View File

@@ -39,7 +39,7 @@
return FALSE
. = ..()
/turf/Initialize()
/turf/Initialize(mapload)
if(flags_1 & INITIALIZED_1)
stack_trace("Warning: [src]([type]) initialized multiple times!")
flags_1 |= INITIALIZED_1
@@ -68,6 +68,15 @@
if (light_power && light_range)
update_light()
var/turf/T = SSmapping.get_turf_above(src)
if(T)
T.multiz_turf_new(src, DOWN)
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN)
T = SSmapping.get_turf_below(src)
if(T)
T.multiz_turf_new(src, UP)
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP)
if (opacity)
has_opaque_atom = TRUE
@@ -83,6 +92,12 @@
if(!changing_turf)
stack_trace("Incorrect turf deletion")
changing_turf = FALSE
var/turf/T = SSmapping.get_turf_above(src)
if(T)
T.multiz_turf_del(src, DOWN)
T = SSmapping.get_turf_below(src)
if(T)
T.multiz_turf_del(src, UP)
if(force)
..()
//this will completely wipe turf state
@@ -105,6 +120,54 @@
return
user.Move_Pulled(src)
/turf/proc/multiz_turf_del(turf/T, dir)
/turf/proc/multiz_turf_new(turf/T, dir)
//zPassIn doesn't necessarily pass an atom!
//direction is direction of travel of air
/turf/proc/zPassIn(atom/movable/A, direction, turf/source)
return FALSE
//direction is direction of travel of air
/turf/proc/zPassOut(atom/movable/A, direction, turf/destination)
return FALSE
//direction is direction of travel of air
/turf/proc/zAirIn(direction, turf/source)
return FALSE
//direction is direction of travel of air
/turf/proc/zAirOut(direction, turf/source)
return FALSE
/turf/proc/zImpact(atom/movable/A, levels = 1)
for(var/i in contents)
var/atom/thing = i
if(thing.intercept_zImpact(A, levels))
return FALSE
if(zFall(A, ++levels))
return FALSE
A.visible_message("<span class='danger'>[A] crashes into [src]!</span>")
A.onZImpact(src, levels)
return TRUE
/turf/proc/can_zFall(atom/movable/A, levels = 1, turf/target)
return zPassOut(A, DOWN, target) && target.zPassIn(A, DOWN, src)
/turf/proc/zFall(atom/movable/A, levels = 1, force = FALSE)
var/turf/target = get_step_multiz(src, DOWN)
if(!target || (!isobj(A) && !ismob(A)))
return FALSE
if(!force && (!can_zFall(A, levels, target) || !A.can_zFall(src, levels, target, DOWN)))
return FALSE
A.visible_message("<span class='danger'>[A] falls through [src]!</span>")
A.zfalling = TRUE
A.forceMove(target)
A.zfalling = FALSE
target.zImpact(A, levels)
return TRUE
/turf/proc/handleRCL(obj/item/twohanded/rcl/C, mob/user)
if(C.loaded)
for(var/obj/structure/cable/LC in src)
@@ -193,6 +256,8 @@
var/obj/O = AM
if(O.obj_flags & FROZEN)
O.make_unfrozen()
if(!AM.zfalling)
zFall(AM)
/turf/proc/is_plasteel_floor()
return FALSE

View File

@@ -1,4 +1,6 @@
/atom/var/CanAtmosPass = ATMOS_PASS_YES
/atom/var/CanAtmosPassVertical = ATMOS_PASS_YES
/atom/proc/CanAtmosPass(turf/T)
switch (CanAtmosPass)
if (ATMOS_PASS_PROC)
@@ -8,42 +10,45 @@
else
return CanAtmosPass
/turf/closed/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPassVertical = ATMOS_PASS_NO
/turf/open/CanAtmosPass = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T)
var/R
/turf/open/CanAtmosPassVertical = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = dir_inverse_multiz(dir)
var/R = FALSE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE
if(blocks_air || T.blocks_air)
R = 1
R = TRUE
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!CANATMOSPASS(O, other))
R = 1
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
R = TRUE
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
var/D = get_dir(src, T)
atmos_supeconductivity |= D
D = get_dir(T, src)
T.atmos_supeconductivity |= D
return 0 //no need to keep going, we got all we asked
atmos_supeconductivity |= dir
T.atmos_supeconductivity |= opp
return FALSE //no need to keep going, we got all we asked
atmos_supeconductivity &= ~get_dir(src, T)
T.atmos_supeconductivity &= ~get_dir(T, src)
atmos_supeconductivity &= ~dir
T.atmos_supeconductivity &= ~opp
return !R
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
return 0
return FALSE
/turf/proc/CalculateAdjacentTurfs()
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
if(!T)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
if(!isopenturf(T))
continue
if( !(blocks_air || T.blocks_air) && CANATMOSPASS(T, src) )
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (CANVERTICALATMOSPASS(T, src)) : (CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE
@@ -72,11 +77,13 @@
var/turf/curloc = src
for (var/direction in GLOB.diagonals)
for (var/direction in GLOB.diagonals_multiz)
var/matchingDirections = 0
var/turf/S = get_step(curloc, direction)
var/turf/S = get_step_multiz(curloc, direction)
if(!S)
continue
for (var/checkDirection in GLOB.cardinals)
for (var/checkDirection in GLOB.cardinals_multiz)
var/turf/checkTurf = get_step(S, checkDirection)
if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf])
continue

View File

@@ -42,8 +42,7 @@
/turf/open/Destroy()
if(active_hotspot)
qdel(active_hotspot)
active_hotspot = null
QDEL_NULL(active_hotspot)
// Adds the adjacent turfs to the current atmos processing
for(var/T in atmos_adjacent_turfs)
SSair.add_to_active(T)

View File

@@ -0,0 +1,47 @@
/proc/get_step_multiz(ref, dir)
if(dir & UP)
dir &= ~UP
return get_step(SSmapping.get_turf_above(get_turf(ref)), dir)
if(dir & DOWN)
dir &= ~DOWN
return get_step(SSmapping.get_turf_below(get_turf(ref)), dir)
return get_step(ref, dir)
/proc/get_dir_multiz(turf/us, turf/them)
us = get_turf(us)
them = get_turf(them)
if(!us || !them)
return NONE
if(us.z == them.z)
return get_dir(us, them)
else
var/turf/T = us.above()
var/dir = NONE
if(T && (T.z == them.z))
dir = UP
else
T = us.below()
if(T && (T.z == them.z))
dir = DOWN
else
return get_dir(us, them)
return (dir | get_dir(us, them))
/turf/proc/above()
return get_step_multiz(src, UP)
/turf/proc/below()
return get_step_multiz(src, DOWN)
/proc/dir_inverse_multiz(dir)
var/holder = dir & (UP|DOWN)
if((holder == NONE) || (holder == (UP|DOWN)))
return turn(dir, 180)
dir &= ~(UP|DOWN)
dir = turn(dir, 180)
if(holder == UP)
holder = DOWN
else
holder = UP
dir |= holder
return dir

View File

@@ -15,6 +15,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
see_in_dark = 100
invisibility = INVISIBILITY_OBSERVER
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0

View File

@@ -0,0 +1,2 @@
/mob/dead/observer/canZMove(direction, turf/target)
return TRUE

View File

@@ -40,6 +40,15 @@
QDEL_LIST(diseases)
return ..()
/mob/living/onZImpact(turf/T, levels)
ZImpactDamage(T, levels)
return ..()
/mob/living/proc/ZImpactDamage(turf/T, levels)
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
adjustBruteLoss((levels * 5) ** 1.5)
Knockdown(levels * 50)
/mob/living/proc/OpenCraftingMenu()
return

View File

@@ -25,3 +25,9 @@
add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = T.slowdown)
else
remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD)
/mob/living/can_zFall(turf/T, levels)
return !(movement_type & FLYING)
/mob/living/canZMove(dir, turf/target)
return can_zTravel(target, dir) && (movement_type & FLYING)

View File

@@ -373,3 +373,35 @@
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
selector.update_icon(src)
/mob/verb/up()
set name = "Move Upwards"
set category = "IC"
if(zMove(UP, TRUE))
to_chat(src, "<span class='notice'>You move upwards.</span>")
/mob/verb/down()
set name = "Move Down"
set category = "IC"
if(zMove(DOWN, TRUE))
to_chat(src, "<span class='notice'>You move down.</span>")
/mob/proc/zMove(dir, feedback = FALSE)
if(dir != UP && dir != DOWN)
return FALSE
var/turf/target = get_step_multiz(src, dir)
if(!target)
if(feedback)
to_chat(src, "<span class='warning'>There's nothing in that direction!</span>")
return FALSE
if(!canZMove(dir, target))
if(feedback)
to_chat(src, "<span class='warning'>You couldn't move there!</span>")
return FALSE
forceMove(target)
return TRUE
/mob/proc/canZMove(direction, turf/target)
return FALSE

View File

@@ -33,6 +33,9 @@
else
return QDEL_HINT_LETMELIVE
/obj/docking_port/has_gravity(turf/T)
return FALSE
/obj/docking_port/take_damage()
return

View File

@@ -42,3 +42,6 @@ endmap
map runtimestation
endmap
map multiz_debug
endmap

BIN
icons/obj/stairs.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 304 KiB

View File

@@ -14,6 +14,7 @@
// BEGIN_INCLUDE
#include "_maps\_basemap.dm"
#include "_maps\multiz_debug.dm"
#include "code\_compile_options.dm"
#include "code\world.dm"
#include "code\__DEFINES\_globals.dm"
@@ -995,6 +996,7 @@
#include "code\game\objects\structures\showcase.dm"
#include "code\game\objects\structures\spawner.dm"
#include "code\game\objects\structures\spirit_board.dm"
#include "code\game\objects\structures\stairs.dm"
#include "code\game\objects\structures\statues.dm"
#include "code\game\objects\structures\table_frames.dm"
#include "code\game\objects\structures\tables_racks.dm"
@@ -1050,6 +1052,7 @@
#include "code\game\turfs\closed.dm"
#include "code\game\turfs\open.dm"
#include "code\game\turfs\turf.dm"
#include "code\game\turfs\openspace\openspace.dm"
#include "code\game\turfs\simulated\chasm.dm"
#include "code\game\turfs\simulated\dirtystation.dm"
#include "code\game\turfs\simulated\floor.dm"
@@ -1782,6 +1785,7 @@
#include "code\modules\mapping\reader.dm"
#include "code\modules\mapping\ruins.dm"
#include "code\modules\mapping\verify.dm"
#include "code\modules\mapping\space_management\multiz_helpers.dm"
#include "code\modules\mapping\space_management\space_level.dm"
#include "code\modules\mapping\space_management\space_reservation.dm"
#include "code\modules\mapping\space_management\space_transition.dm"
@@ -1848,6 +1852,7 @@
#include "code\modules\mob\dead\observer\logout.dm"
#include "code\modules\mob\dead\observer\notificationprefs.dm"
#include "code\modules\mob\dead\observer\observer.dm"
#include "code\modules\mob\dead\observer\observer_movement.dm"
#include "code\modules\mob\dead\observer\say.dm"
#include "code\modules\mob\living\blood.dm"
#include "code\modules\mob\living\bloodcrawl.dm"