Merge pull request #505 from ArchieBeepBoop/zlevel
Ports Citadel Multi-Z Level fixes
@@ -0,0 +1 @@
|
||||
#define FORCE_MAP "_maps/multiz_debug.json"
|
||||
@@ -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}]
|
||||
}
|
||||
@@ -145,7 +145,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 ) )
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
@@ -251,6 +253,13 @@
|
||||
out_var += cached_gases[total_moles_id];\
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
|
||||
#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
|
||||
#else
|
||||
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
|
||||
#endif
|
||||
|
||||
//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance.
|
||||
#define GAS_GARBAGE_COLLECT(GASGASGAS)\
|
||||
var/list/CACHE_GAS = GASGASGAS;\
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
/////////////////
|
||||
|
||||
|
||||
|
||||
// /area signals
|
||||
|
||||
// /turf signals
|
||||
|
||||
@@ -19,6 +19,16 @@
|
||||
//Turfs
|
||||
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
|
||||
|
||||
GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
|
||||
/turf/open/space,
|
||||
/turf/open/chasm,
|
||||
/turf/open/lava,
|
||||
/turf/open/water,
|
||||
/turf/open/openspace
|
||||
)))
|
||||
|
||||
#define isgroundlessturf(A) (is_type_in_typecache(A, GLOB.turfs_without_ground))
|
||||
|
||||
#define isopenturf(A) (istype(A, /turf/open))
|
||||
|
||||
#define isindestructiblefloor(A) (istype(A, /turf/open/indestructible))
|
||||
|
||||
@@ -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
|
||||
@@ -85,25 +86,28 @@
|
||||
#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 CAMERA_STATIC_PLANE 18
|
||||
#define CAMERA_STATIC_LAYER 18
|
||||
#define BYOND_LIGHTING_PLANE 18
|
||||
#define BYOND_LIGHTING_LAYER 18
|
||||
|
||||
#define CAMERA_STATIC_PLANE 19
|
||||
#define CAMERA_STATIC_LAYER 19
|
||||
//HUD layer defines
|
||||
|
||||
#define FULLSCREEN_PLANE 19
|
||||
#define FLASH_LAYER 19
|
||||
#define FULLSCREEN_LAYER 19.1
|
||||
#define UI_DAMAGE_LAYER 19.2
|
||||
#define BLIND_LAYER 19.3
|
||||
#define CRIT_LAYER 19.4
|
||||
#define CURSE_LAYER 19.5
|
||||
#define FULLSCREEN_PLANE 20
|
||||
#define FLASH_LAYER 20
|
||||
#define FULLSCREEN_LAYER 20.1
|
||||
#define UI_DAMAGE_LAYER 20.2
|
||||
#define BLIND_LAYER 20.3
|
||||
#define CRIT_LAYER 20.4
|
||||
#define CURSE_LAYER 20.5
|
||||
|
||||
#define HUD_PLANE 20
|
||||
#define HUD_LAYER 20
|
||||
#define ABOVE_HUD_PLANE 21
|
||||
#define ABOVE_HUD_LAYER 21
|
||||
#define HUD_PLANE 21
|
||||
#define HUD_LAYER 21
|
||||
#define ABOVE_HUD_PLANE 22
|
||||
#define ABOVE_HUD_LAYER 22
|
||||
|
||||
#define SPLASHSCREEN_LAYER 22
|
||||
#define SPLASHSCREEN_PLANE 22
|
||||
#define SPLASHSCREEN_LAYER 23
|
||||
#define SPLASHSCREEN_PLANE 23
|
||||
|
||||
@@ -38,6 +38,7 @@ require only minor tweaks.
|
||||
#define ZTRAIT_SPACE_RUINS "Space Ruins"
|
||||
#define ZTRAIT_LAVA_RUINS "Lava Ruins"
|
||||
#define ZTRAIT_LAVA_UNDERGROUND "Lava Underground"
|
||||
#define ZTRAIT_ISOLATED_RUINS "Isolated Ruins" //Placing ruins on z levels with this trait will use turf reservation instead of usual placement.
|
||||
// prevents certain turfs from being stripped by a singularity
|
||||
#define ZTRAIT_PLANET "Planet"
|
||||
|
||||
@@ -102,6 +103,10 @@ require only minor tweaks.
|
||||
#define PLACEMENT_TRIES 100 //How many times we try to fit the ruin somewhere until giving up (really should just swap to some packing algo)
|
||||
|
||||
#define PLACE_DEFAULT "random"
|
||||
#define PLACE_SAME_Z "same"
|
||||
#define PLACE_SPACE_RUIN "space"
|
||||
#define PLACE_LAVA_RUIN "lavaland"
|
||||
#define PLACE_SAME_Z "same" //On same z level as original ruin
|
||||
#define PLACE_SPACE_RUIN "space" //On space ruin z level(s)
|
||||
#define PLACE_LAVA_RUIN "lavaland" //On lavaland ruin z levels(s)
|
||||
#define PLACE_BELOW "below" //On z levl below - centered on same tile
|
||||
#define PLACE_ISOLATED "isolated" //On isolated ruin z level
|
||||
//Map type stuff.
|
||||
#define MAP_TYPE_STATION "station"
|
||||
|
||||
@@ -497,5 +497,10 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define VOMIT_TOXIC 1
|
||||
#define VOMIT_PURPLE 2
|
||||
|
||||
// possible bitflag return values of intercept_zImpact(atom/movable/AM, levels = 1) calls
|
||||
#define FALL_INTERCEPTED (1<<0) //Stops the movable from falling further and crashing on the ground
|
||||
#define FALL_NO_MESSAGE (1<<1) //Used to suppress the "[A] falls through [old_turf]" messages where it'd make little sense at all, like going downstairs.
|
||||
#define FALL_STOP_INTERCEPTING (1<<2) //Used in situations where halting the whole "intercept" loop would be better, like supermatter dusting (and thus deleting) the atom.
|
||||
|
||||
//Misc text define. Does 4 spaces. Used as a makeshift tabulator.
|
||||
#define FOURSPACES " "
|
||||
@@ -10,6 +10,8 @@
|
||||
#define UNIQUE_RENAME (1<<6) // can you customize the description/name of the thing?
|
||||
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
|
||||
#define FROZEN (1<<8)
|
||||
#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
|
||||
#define BLOCK_Z_FALL (1<<10)
|
||||
|
||||
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
|
||||
|
||||
@@ -46,4 +48,4 @@
|
||||
#define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed
|
||||
#define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change.
|
||||
#define ORGAN_VITAL (1<<4) //Currently only the brain
|
||||
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
|
||||
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something
|
||||
|
||||
#define TIMER_ID_NULL -1
|
||||
|
||||
//For servers that can't do with any additional lag, set this to none in flightpacks.dm in subsystem/processing.
|
||||
#define FLIGHTSUIT_PROCESSING_NONE 0
|
||||
#define FLIGHTSUIT_PROCESSING_FULL 1
|
||||
@@ -115,6 +114,7 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_ATMOS_ADJACENCY 300
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
#define CHANGETURF_FORCEOP 4
|
||||
#define CHANGETURF_SKIP 8 // A flag for PlaceOnTop to just instance the new turf instead of calling ChangeTurf. Used for uninitialized turfs NOTHING ELSE
|
||||
#define CHANGETURF_INHERIT_AIR 16 // Inherit air from previous turf. Implies CHANGETURF_IGNORE_AIR
|
||||
#define CHANGETURF_RECALC_ADJACENT 32 //Immediately recalc adjacent atmos turfs instead of queuing.
|
||||
@@ -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
|
||||
|
||||
@@ -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", size = -10)
|
||||
filters += filter(type = "drop_shadow", color = "#04080FAA", size = -15)
|
||||
filters += filter(type = "drop_shadow", color = "#04080FAA", 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, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA")
|
||||
filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset)
|
||||
|
||||
/obj/screen/plane_master/proc/clear_filters()
|
||||
filters = list()
|
||||
|
||||
/obj/screen/plane_master/floor
|
||||
name = "floor plane master"
|
||||
plane = FLOOR_PLANE
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
SUBSYSTEM_DEF(adjacent_air)
|
||||
name = "Atmos Adjacency"
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 10
|
||||
priority = FIRE_PRIORITY_ATMOS_ADJACENCY
|
||||
var/list/queue = list()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/stat_entry()
|
||||
#ifdef TESTING
|
||||
..("P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]")
|
||||
#else
|
||||
..("P:[length(queue)]")
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/Initialize()
|
||||
while(length(queue))
|
||||
fire(mc_check = FALSE)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE)
|
||||
|
||||
var/list/queue = src.queue
|
||||
|
||||
while (length(queue))
|
||||
var/turf/currT = queue[1]
|
||||
queue.Cut(1,2)
|
||||
|
||||
currT.ImmediateCalculateAdjacentTurfs()
|
||||
|
||||
if(mc_check)
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
else
|
||||
CHECK_TICK
|
||||
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/ruins_templates = list()
|
||||
var/list/space_ruins_templates = list()
|
||||
var/list/lava_ruins_templates = list()
|
||||
var/datum/space_level/isolated_ruins_z //Created on demand during ruin loading.
|
||||
|
||||
var/list/shuttle_templates = list()
|
||||
var/list/shelter_templates = list()
|
||||
@@ -25,6 +26,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/datum/turf_reservations //list of turf reservations
|
||||
var/list/used_turfs = list() //list of turf = datum/turf_reservation
|
||||
|
||||
var/list/reservation_ready = list()
|
||||
var/clearing_reserved_turfs = FALSE
|
||||
|
||||
// Z-manager stuff
|
||||
@@ -93,7 +95,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
// Set up Z-level transitions.
|
||||
setup_map_transitions()
|
||||
generate_station_area_list()
|
||||
initialize_reserved_level()
|
||||
initialize_reserved_level(transit.z_value)
|
||||
return ..()
|
||||
|
||||
/* Nuke threats, for making the blue tiles on the station go RED
|
||||
@@ -441,7 +443,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
GLOB.the_gateway.wait = world.time
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override, border_type_override)
|
||||
UNTIL(initialized && !clearing_reserved_turfs)
|
||||
UNTIL((!z || reservation_ready["[z]"]) && !clearing_reserved_turfs)
|
||||
var/datum/turf_reservation/reserve = new type
|
||||
if(turf_type_override)
|
||||
reserve.turf_type = turf_type_override
|
||||
@@ -453,8 +455,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
return reserve
|
||||
//If we didn't return at this point, theres a good chance we ran out of room on the exisiting reserved z levels, so lets try a new one
|
||||
num_of_res_levels += 1
|
||||
var/newReserved = add_new_zlevel("Transit/Reserved [num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
|
||||
if(reserve.Reserve(width, height, newReserved))
|
||||
var/datum/space_level/newReserved = add_new_zlevel("Transit/Reserved [num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
|
||||
initialize_reserved_level(newReserved.z_value)
|
||||
if(reserve.Reserve(width, height, newReserved.z_value))
|
||||
return reserve
|
||||
else
|
||||
if(!level_trait(z, ZTRAIT_RESERVED))
|
||||
@@ -466,19 +469,22 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
QDEL_NULL(reserve)
|
||||
|
||||
//This is not for wiping reserved levels, use wipe_reservations() for that.
|
||||
/datum/controller/subsystem/mapping/proc/initialize_reserved_level()
|
||||
/datum/controller/subsystem/mapping/proc/initialize_reserved_level(z)
|
||||
UNTIL(!clearing_reserved_turfs) //regardless, lets add a check just in case.
|
||||
clearing_reserved_turfs = TRUE //This operation will likely clear any existing reservations, so lets make sure nothing tries to make one while we're doing it.
|
||||
for(var/i in levels_by_trait(ZTRAIT_RESERVED))
|
||||
var/turf/A = get_turf(locate(SHUTTLE_TRANSIT_BORDER,SHUTTLE_TRANSIT_BORDER,i))
|
||||
var/turf/B = get_turf(locate(world.maxx - SHUTTLE_TRANSIT_BORDER,world.maxy - SHUTTLE_TRANSIT_BORDER,i))
|
||||
var/block = block(A, B)
|
||||
for(var/t in block)
|
||||
// No need to empty() these, because it's world init and they're
|
||||
// already /turf/open/space/basic.
|
||||
var/turf/T = t
|
||||
T.flags_1 |= UNUSED_RESERVATION_TURF_1
|
||||
unused_turfs["[i]"] = block
|
||||
if(!level_trait(z,ZTRAIT_RESERVED))
|
||||
clearing_reserved_turfs = FALSE
|
||||
CRASH("Invalid z level prepared for reservations.")
|
||||
var/turf/A = get_turf(locate(SHUTTLE_TRANSIT_BORDER,SHUTTLE_TRANSIT_BORDER,z))
|
||||
var/turf/B = get_turf(locate(world.maxx - SHUTTLE_TRANSIT_BORDER,world.maxy - SHUTTLE_TRANSIT_BORDER,z))
|
||||
var/block = block(A, B)
|
||||
for(var/t in block)
|
||||
// No need to empty() these, because it's world init and they're
|
||||
// already /turf/open/space/basic.
|
||||
var/turf/T = t
|
||||
T.flags_1 |= UNUSED_RESERVATION_TURF_1
|
||||
unused_turfs["[z]"] = block
|
||||
reservation_ready["[z]"] = TRUE
|
||||
clearing_reserved_turfs = FALSE
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/reserve_turfs(list/turfs)
|
||||
@@ -512,3 +518,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
for(var/B in areas)
|
||||
var/area/A = B
|
||||
A.reg_in_areas_in_z()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/get_isolated_ruin_z()
|
||||
if(!isolated_ruins_z)
|
||||
isolated_ruins_z = add_new_zlevel("Isolated Ruins/Reserved", list(ZTRAIT_RESERVED = TRUE, ZTRAIT_ISOLATED_RUINS = TRUE))
|
||||
initialize_reserved_level(isolated_ruins_z.z_value)
|
||||
return isolated_ruins_z.z_value
|
||||
|
||||
@@ -146,6 +146,11 @@ SUBSYSTEM_DEF(throwing)
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
if(!thrownthing.zfalling) // I don't think you can zfall while thrown but hey, just in case.
|
||||
var/turf/T = get_turf(thrownthing)
|
||||
if(T && thrownthing.has_gravity(T))
|
||||
T.zFall(thrownthing)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
|
||||
@@ -187,6 +187,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
|
||||
@@ -738,4 +742,7 @@ Proc for attack log creation, because really why not
|
||||
if(filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
|
||||
|
||||
@@ -35,6 +35,50 @@
|
||||
var/throwforce = 0
|
||||
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")
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/proc/NeverShouldHaveComeHere(turf/T)
|
||||
return isspaceturf(T) || isclosedturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T)
|
||||
return isclosedturf(T) || isgroundlessturf(T)
|
||||
|
||||
/obj/effect/decal/ex_act(severity, target)
|
||||
qdel(src)
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
/obj/effect/abstract/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/abstract/has_gravity(turf/T)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/dummy/singularity_pull()
|
||||
return
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
number_of_rods = 2
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
|
||||
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
|
||||
to_chat(user, "<span class='notice'>The supporting rods look like they could be <b>cut</b>.</span>")
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
#define STAIR_TERMINATOR_AUTOMATIC 0
|
||||
#define STAIR_TERMINATOR_NO 1
|
||||
#define STAIR_TERMINATOR_YES 2
|
||||
|
||||
// dir determines the direction of travel to go upwards (due to lack of sprites, currently only 1 and 2 make sense)
|
||||
// stairs require /turf/open/openspace as the tile above them to work
|
||||
// multiple stair objects can be chained together; the Z level transition will happen on the final stair object in the chain
|
||||
|
||||
/obj/structure/stairs
|
||||
name = "stairs"
|
||||
icon = 'icons/obj/stairs.dmi'
|
||||
icon_state = "stairs"
|
||||
anchored = TRUE
|
||||
|
||||
var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/openspace
|
||||
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
|
||||
var/turf/listeningTo
|
||||
|
||||
/obj/structure/stairs/Initialize(mapload)
|
||||
if(force_open_above)
|
||||
force_open_above()
|
||||
build_signal_listener()
|
||||
update_surrounding()
|
||||
return ..()
|
||||
|
||||
/obj/structure/stairs/Destroy()
|
||||
listeningTo = null
|
||||
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(!isobserver(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.
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
var/pulling = L.pulling
|
||||
if(pulling)
|
||||
L.pulling.forceMove(target)
|
||||
L.forceMove(target)
|
||||
L.start_pulling(pulling)
|
||||
else
|
||||
AM.forceMove(target)
|
||||
|
||||
/obj/structure/stairs/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(var_name != NAMEOF(src, force_open_above))
|
||||
return
|
||||
if(!var_value)
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW)
|
||||
listeningTo = null
|
||||
else
|
||||
build_signal_listener()
|
||||
force_open_above()
|
||||
|
||||
/obj/structure/stairs/proc/build_signal_listener()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW)
|
||||
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
|
||||
RegisterSignal(T, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_new)
|
||||
listeningTo = T
|
||||
|
||||
/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)
|
||||
. = ..()
|
||||
if(isTerminator())
|
||||
. |= FALL_INTERCEPTED | FALL_NO_MESSAGE
|
||||
|
||||
/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
|
||||
@@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
if(turf_type)
|
||||
var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags)
|
||||
SSair.remove_from_active(newT)
|
||||
newT.CalculateAdjacentTurfs()
|
||||
CALCULATE_ADJACENT_TURFS(newT)
|
||||
SSair.add_to_active(newT,1)
|
||||
|
||||
/turf/proc/copyTurf(turf/T)
|
||||
@@ -140,6 +140,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
newTurf.air = stashed_air
|
||||
SSair.add_to_active(newTurf)
|
||||
else
|
||||
if(ispath(path,/turf/closed))
|
||||
flags |= CHANGETURF_RECALC_ADJACENT
|
||||
return ..()
|
||||
|
||||
// Take off the top layer turf and replace it with the next baseturf down
|
||||
@@ -263,7 +265,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
//If you modify this function, ensure it works correctly with lateloaded map templates.
|
||||
/turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf()
|
||||
levelupdate()
|
||||
CalculateAdjacentTurfs()
|
||||
if(flags & CHANGETURF_RECALC_ADJACENT)
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
else
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
|
||||
//update firedoor adjacency
|
||||
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
|
||||
|
||||
@@ -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/MouseDrop_T(atom/dropping, mob/user)
|
||||
. = ..()
|
||||
if(dropping == user && isliving(user))
|
||||
@@ -184,43 +200,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
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
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()
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/turf/open/openspace
|
||||
name = "open space"
|
||||
desc = "Watch your step!"
|
||||
icon_state = "grey"
|
||||
baseturfs = /turf/open/openspace
|
||||
CanAtmosPassVertical = ATMOS_PASS_YES
|
||||
//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() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
|
||||
. = ..()
|
||||
plane = FLOOR_OPENSPACE_PLANE
|
||||
layer = OPENSPACE_LAYER
|
||||
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)
|
||||
if(A.anchored)
|
||||
return FALSE
|
||||
for(var/obj/O in contents)
|
||||
if(O.obj_flags & BLOCK_Z_FALL)
|
||||
return FALSE
|
||||
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>")
|
||||
|
||||
/turf/open/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
if(!CanBuildHere())
|
||||
return FALSE
|
||||
|
||||
switch(the_rcd.mode)
|
||||
if(RCD_FLOORWALL)
|
||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||
if(L)
|
||||
return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1)
|
||||
else
|
||||
return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3)
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_FLOORWALL)
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -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
|
||||
@@ -65,12 +65,21 @@
|
||||
add_overlay(/obj/effect/fullbright)
|
||||
|
||||
if(requires_activation)
|
||||
CalculateAdjacentTurfs()
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
SSair.add_to_active(src)
|
||||
|
||||
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
|
||||
|
||||
@@ -79,13 +88,19 @@
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/turf/proc/Initalize_Atmos(times_fired)
|
||||
CalculateAdjacentTurfs()
|
||||
CALCULATE_ADJACENT_TURFS(src)
|
||||
|
||||
/turf/Destroy(force)
|
||||
. = QDEL_HINT_IWILLGC
|
||||
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
|
||||
@@ -108,6 +123,60 @@
|
||||
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, turf/prev_turf)
|
||||
var/flags = NONE
|
||||
var/mov_name = A.name
|
||||
for(var/i in contents)
|
||||
var/atom/thing = i
|
||||
flags |= thing.intercept_zImpact(A, levels)
|
||||
if(flags & FALL_STOP_INTERCEPTING)
|
||||
break
|
||||
if(prev_turf && !(flags & FALL_NO_MESSAGE))
|
||||
prev_turf.visible_message("<span class='danger'>[mov_name] falls through [prev_turf]!</span>")
|
||||
if(flags & FALL_INTERCEPTED)
|
||||
return
|
||||
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.zfalling = TRUE
|
||||
A.forceMove(target)
|
||||
A.zfalling = FALSE
|
||||
target.zImpact(A, levels, src)
|
||||
return TRUE
|
||||
|
||||
/turf/proc/handleRCL(obj/item/twohanded/rcl/C, mob/user)
|
||||
if(C.loaded)
|
||||
for(var/obj/structure/cable/LC in src)
|
||||
@@ -199,6 +268,9 @@
|
||||
if(O.obj_flags & FROZEN)
|
||||
O.make_unfrozen()
|
||||
|
||||
if(!AM.zfalling)
|
||||
zFall(AM)
|
||||
|
||||
/turf/proc/is_plasteel_floor()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -395,7 +395,9 @@
|
||||
if(!istype(user) || on_cooldown)
|
||||
return
|
||||
var/turf/T = get_turf(user)
|
||||
if(!T)
|
||||
var/area/A = get_area(user)
|
||||
if(!T || !A || A.noteleport)
|
||||
to_chat(user, "<span class='warning'>You play \the [src], yet no sound comes out of it... Looks like it won't work here.</span>")
|
||||
return
|
||||
on_cooldown = TRUE
|
||||
last_user = user
|
||||
|
||||
@@ -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,47 @@
|
||||
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
|
||||
if(blocks_air || T.blocks_air)
|
||||
R = 1
|
||||
/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 = TRUE
|
||||
if (T == src)
|
||||
return !R
|
||||
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)
|
||||
/turf/proc/ImmediateCalculateAdjacentTurfs()
|
||||
var/canpass = CANATMOSPASS(src, src)
|
||||
var/canvpass = CANVERTICALATMOSPASS(src, src)
|
||||
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))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
|
||||
LAZYINITLIST(atmos_adjacent_turfs)
|
||||
LAZYINITLIST(T.atmos_adjacent_turfs)
|
||||
atmos_adjacent_turfs[T] = TRUE
|
||||
@@ -72,11 +79,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
|
||||
@@ -98,7 +107,7 @@
|
||||
|
||||
/turf/air_update_turf(command = 0)
|
||||
if(command)
|
||||
CalculateAdjacentTurfs()
|
||||
ImmediateCalculateAdjacentTurfs()
|
||||
SSair.add_to_active(src,command)
|
||||
|
||||
/atom/movable/proc/move_update_air(turf/T)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
obj/machinery/atmospherics/pipe/simple/multiz ///This is an atmospherics pipe which can relay air up a deck (Z+1). It currently only supports being on pipe layer 1
|
||||
name = "multi deck pipe adapter"
|
||||
desc = "An adapter which allows pipes to connect to other pipenets on different decks."
|
||||
icon_state = "multiz_pipe"
|
||||
icon = 'icons/obj/atmos.dmi'
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/multiz/update_icon()
|
||||
. = ..()
|
||||
cut_overlays() //This adds the overlay showing it's a multiz pipe. This should go above turfs and such
|
||||
var/image/multiz_overlay_node = new(src) //If we have a firing state, light em up!
|
||||
multiz_overlay_node.icon = 'icons/obj/atmos.dmi'
|
||||
multiz_overlay_node.icon_state = "multiz_pipe"
|
||||
multiz_overlay_node.layer = HIGH_OBJ_LAYER
|
||||
add_overlay(multiz_overlay_node)
|
||||
|
||||
///Attempts to locate a multiz pipe that's above us, if it finds one it merges us into its pipenet
|
||||
/obj/machinery/atmospherics/pipe/simple/multiz/pipeline_expansion()
|
||||
icon = 'icons/obj/atmos.dmi' //Just to refresh.
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/machinery/atmospherics/pipe/simple/multiz/above = locate(/obj/machinery/atmospherics/pipe/simple/multiz) in(SSmapping.get_turf_above(T))
|
||||
var/obj/machinery/atmospherics/pipe/simple/multiz/below = locate(/obj/machinery/atmospherics/pipe/simple/multiz) in(SSmapping.get_turf_below(T))
|
||||
if(below)
|
||||
below.pipeline_expansion() //If we've got one below us, force it to add us on facebook
|
||||
if(above)
|
||||
nodes += above
|
||||
above.nodes += src //Two way travel :)
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
@@ -122,7 +122,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list(
|
||||
|
||||
if(toupdate.len)
|
||||
for(var/turf/T1 in toupdate)
|
||||
T1.CalculateAdjacentTurfs()
|
||||
CALCULATE_ADJACENT_TURFS(T1)
|
||||
SSair.add_to_active(T1,1)
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas)
|
||||
var/sanity = PLACEMENT_TRIES
|
||||
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas,turf/forced_turf)
|
||||
var/sanity = forced_turf ? 1 : PLACEMENT_TRIES
|
||||
if(SSmapping.level_trait(z,ZTRAIT_ISOLATED_RUINS))
|
||||
return place_on_isolated_level(z)
|
||||
while(sanity > 0)
|
||||
sanity--
|
||||
var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(width / 2)
|
||||
var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(height / 2)
|
||||
var/turf/central_turf = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
|
||||
var/turf/central_turf = forced_turf ? forced_turf : locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
|
||||
var/valid = TRUE
|
||||
|
||||
for(var/turf/check in get_affected_turfs(central_turf,1))
|
||||
@@ -24,7 +26,7 @@
|
||||
qdel(monster)
|
||||
for(var/obj/structure/flora/ash/plant in T)
|
||||
qdel(plant)
|
||||
|
||||
|
||||
load(central_turf,centered = TRUE)
|
||||
loaded++
|
||||
|
||||
@@ -32,9 +34,20 @@
|
||||
T.flags_1 |= NO_RUINS_1
|
||||
|
||||
new /obj/effect/landmark/ruin(central_turf, src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return central_turf
|
||||
|
||||
/datum/map_template/ruin/proc/place_on_isolated_level(z)
|
||||
var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(width, height, z) //Make the new level creation work with different traits.
|
||||
if(!reservation)
|
||||
return
|
||||
var/turf/placement = locate(reservation.bottom_left_coords[1],reservation.bottom_left_coords[2],reservation.bottom_left_coords[3])
|
||||
load(placement)
|
||||
loaded++
|
||||
for(var/turf/T in get_affected_turfs(placement))
|
||||
T.flags_1 |= NO_RUINS_1
|
||||
var/turf/center = locate(placement.x + round(width/2),placement.y + round(height/2),placement.z)
|
||||
new /obj/effect/landmark/ruin(center, src)
|
||||
return center
|
||||
|
||||
/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
|
||||
if(!z_levels || !z_levels.len)
|
||||
@@ -49,9 +62,8 @@
|
||||
|
||||
var/list/ruins = potentialRuins.Copy()
|
||||
|
||||
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default)
|
||||
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default) or if the assoc value is a turf to the specified turf.
|
||||
var/list/ruins_availible = list() //we can try these in the current pass
|
||||
var/forced_z //If set we won't pick z level and use this one instead.
|
||||
|
||||
//Set up the starting ruin list
|
||||
for(var/key in ruins)
|
||||
@@ -67,34 +79,55 @@
|
||||
while(budget > 0 && (ruins_availible.len || forced_ruins.len))
|
||||
var/datum/map_template/ruin/current_pick
|
||||
var/forced = FALSE
|
||||
var/forced_z //If set we won't pick z level and use this one instead.
|
||||
var/forced_turf //If set we place the ruin centered on the given turf
|
||||
if(forced_ruins.len) //We have something we need to load right now, so just pick it
|
||||
for(var/ruin in forced_ruins)
|
||||
current_pick = ruin
|
||||
if(forced_ruins[ruin] > 0) //Load into designated z
|
||||
if(isturf(forced_ruins[ruin]))
|
||||
var/turf/T = forced_ruins[ruin]
|
||||
forced_z = T.z //In case of chained ruins
|
||||
forced_turf = T
|
||||
else if(forced_ruins[ruin] > 0) //Load into designated z
|
||||
forced_z = forced_ruins[ruin]
|
||||
forced = TRUE
|
||||
break
|
||||
else //Otherwise just pick random one
|
||||
current_pick = pickweight(ruins_availible)
|
||||
|
||||
var/placement_tries = PLACEMENT_TRIES
|
||||
var/placement_tries = forced_turf ? 1 : PLACEMENT_TRIES //Only try once if we target specific turf
|
||||
var/failed_to_place = TRUE
|
||||
var/z_placed = 0
|
||||
while(placement_tries > 0)
|
||||
placement_tries--
|
||||
z_placed = pick(z_levels)
|
||||
if(!current_pick.try_to_place(forced_z ? forced_z : z_placed,whitelist))
|
||||
continue
|
||||
else
|
||||
failed_to_place = FALSE
|
||||
break
|
||||
var/target_z = 0
|
||||
var/turf/placed_turf //Where the ruin ended up if we succeeded
|
||||
outer:
|
||||
while(placement_tries > 0)
|
||||
placement_tries--
|
||||
target_z = pick(z_levels)
|
||||
if(forced_z)
|
||||
target_z = forced_z
|
||||
if(current_pick.always_spawn_with) //If the ruin has part below, make sure that z exists.
|
||||
for(var/v in current_pick.always_spawn_with)
|
||||
if(current_pick.always_spawn_with[v] == PLACE_BELOW)
|
||||
var/turf/T = locate(1,1,target_z)
|
||||
if(!SSmapping.get_turf_below(T))
|
||||
if(forced_z)
|
||||
continue outer
|
||||
else
|
||||
break outer
|
||||
|
||||
placed_turf = current_pick.try_to_place(target_z,whitelist,forced_turf)
|
||||
if(!placed_turf)
|
||||
continue
|
||||
else
|
||||
failed_to_place = FALSE
|
||||
break
|
||||
|
||||
//That's done remove from priority even if it failed
|
||||
if(forced)
|
||||
//TODO : handle forced ruins with multiple variants
|
||||
forced_ruins -= current_pick
|
||||
forced = FALSE
|
||||
|
||||
|
||||
if(failed_to_place)
|
||||
for(var/datum/map_template/ruin/R in ruins_availible)
|
||||
if(R.id == current_pick.id)
|
||||
@@ -118,18 +151,21 @@
|
||||
if(istype(linked,v))
|
||||
switch(current_pick.always_spawn_with[v])
|
||||
if(PLACE_SAME_Z)
|
||||
forced_ruins[linked] = forced_z ? forced_z : z_placed //I guess you might want a chain somehow
|
||||
forced_ruins[linked] = target_z //I guess you might want a chain somehow
|
||||
if(PLACE_LAVA_RUIN)
|
||||
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_LAVA_RUINS))
|
||||
if(PLACE_SPACE_RUIN)
|
||||
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_SPACE_RUINS))
|
||||
if(PLACE_DEFAULT)
|
||||
forced_ruins[linked] = -1
|
||||
forced_z = 0
|
||||
if(PLACE_BELOW)
|
||||
forced_ruins[linked] = SSmapping.get_turf_below(placed_turf)
|
||||
if(PLACE_ISOLATED)
|
||||
forced_ruins[linked] = SSmapping.get_isolated_ruin_z()
|
||||
|
||||
//Update the availible list
|
||||
for(var/datum/map_template/ruin/R in ruins_availible)
|
||||
if(R.cost > budget)
|
||||
ruins_availible -= R
|
||||
|
||||
|
||||
log_world("Ruin loader finished with [budget] left to spend.")
|
||||
|
||||
@@ -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
|
||||
@@ -17,6 +17,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/can_reenter_round = TRUE
|
||||
var/datum/hud/living/carbon/hud = null // hud
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/mob/dead/observer/canZMove(direction, turf/target)
|
||||
return TRUE
|
||||
@@ -48,6 +48,15 @@
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi')
|
||||
return holder
|
||||
|
||||
/mob/living/onZImpact(turf/T, levels)
|
||||
if(!isgroundlessturf(T))
|
||||
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
|
||||
|
||||
@@ -117,3 +117,5 @@
|
||||
//List of active diseases
|
||||
var/list/diseases = list() // list of all diseases in a mob
|
||||
var/list/disease_resistances = list()
|
||||
|
||||
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
|
||||
|
||||
@@ -30,3 +30,14 @@
|
||||
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/proc/update_pull_movespeed()
|
||||
if(pulling && isliving(pulling))
|
||||
var/mob/living/L = pulling
|
||||
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
|
||||
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
|
||||
return
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
|
||||
|
||||
/mob/living/canZMove(dir, turf/target)
|
||||
return can_zTravel(target, dir) && (movement_type & FLYING)
|
||||
|
||||
@@ -372,3 +372,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
|
||||
|
||||
@@ -117,7 +117,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
use_power = IDLE_POWER_USE
|
||||
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
|
||||
var/on = TRUE
|
||||
var/breaker = 1
|
||||
var/breaker = TRUE
|
||||
var/list/parts = list()
|
||||
var/obj/middle = null
|
||||
var/charging_state = POWER_IDLE
|
||||
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
M.set_broken()
|
||||
middle.cut_overlays()
|
||||
charge_count = 0
|
||||
breaker = 0
|
||||
breaker = FALSE
|
||||
set_power()
|
||||
set_state(0)
|
||||
investigate_log("has broken down.", INVESTIGATE_GRAVITY)
|
||||
@@ -176,7 +176,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
for(var/obj/machinery/gravity_generator/M in parts)
|
||||
if(M.stat & BROKEN)
|
||||
M.set_fix()
|
||||
broken_state = 0
|
||||
broken_state = FALSE
|
||||
update_icon()
|
||||
set_power()
|
||||
|
||||
@@ -273,11 +273,11 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
|
||||
// Set the charging state based on power/breaker.
|
||||
/obj/machinery/gravity_generator/main/proc/set_power()
|
||||
var/new_state = 0
|
||||
var/new_state = FALSE
|
||||
if(stat & (NOPOWER|BROKEN) || !breaker)
|
||||
new_state = 0
|
||||
new_state = FALSE
|
||||
else if(breaker)
|
||||
new_state = 1
|
||||
new_state = TRUE
|
||||
|
||||
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
|
||||
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", INVESTIGATE_GRAVITY)
|
||||
@@ -292,13 +292,13 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
var/alert = FALSE
|
||||
if(SSticker.IsRoundInProgress())
|
||||
if(on) // If we turned on and the game is live.
|
||||
if(gravity_in_level() == 0)
|
||||
alert = 1
|
||||
if(gravity_in_level() == FALSE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought online and is now producing gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought online [ADMIN_VERBOSEJMP(src)]")
|
||||
else
|
||||
if(gravity_in_level() == 1)
|
||||
alert = 1
|
||||
if(gravity_in_level() == TRUE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought offline and there is now no gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought offline with no backup generator. [ADMIN_VERBOSEJMP(src)]")
|
||||
|
||||
@@ -361,7 +361,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
var/sound/alert_sound = sound('sound/effects/alert.ogg')
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/M = i
|
||||
if(M.z != z)
|
||||
if(M.z != z && !(SSmapping.level_trait(z, ZTRAITS_STATION) && SSmapping.level_trait(M.z, ZTRAITS_STATION)))
|
||||
continue
|
||||
M.update_gravity(M.mob_has_gravity())
|
||||
if(M.client)
|
||||
@@ -371,20 +371,28 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
/obj/machinery/gravity_generator/main/proc/gravity_in_level()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return 0
|
||||
return FALSE
|
||||
if(GLOB.gravity_generators["[T.z]"])
|
||||
return length(GLOB.gravity_generators["[T.z]"])
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/update_list()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if(T)
|
||||
if(!GLOB.gravity_generators["[T.z]"])
|
||||
GLOB.gravity_generators["[T.z]"] = list()
|
||||
if(on)
|
||||
GLOB.gravity_generators["[T.z]"] |= src
|
||||
var/list/z_list = list()
|
||||
// Multi-Z, station gravity generator generates gravity on all ZTRAIT_STATION z-levels.
|
||||
if(SSmapping.level_trait(T.z, ZTRAIT_STATION))
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
z_list += z
|
||||
else
|
||||
GLOB.gravity_generators["[T.z]"] -= src
|
||||
z_list += T.z
|
||||
for(var/z in z_list)
|
||||
if(!GLOB.gravity_generators["[z]"])
|
||||
GLOB.gravity_generators["[z]"] = list()
|
||||
if(on)
|
||||
GLOB.gravity_generators["[z]"] |= src
|
||||
else
|
||||
GLOB.gravity_generators["[z]"] -= src
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/change_setting(value)
|
||||
if(value != setting)
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/obj/machinery/power/deck_relay //This bridges powernets
|
||||
name = "Multi-deck power adapter"
|
||||
desc = "A huge bundle of double insulated cabling which seems to run up into the ceiling."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "cablerelay-off"
|
||||
var/obj/machinery/power/deck_relay/below ///The relay that's below us (for bridging powernets)
|
||||
var/obj/machinery/power/deck_relay/above ///The relay that's above us (for bridging powernets)
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
|
||||
/obj/machinery/power/deck_relay/attackby(obj/item/I,mob/user)
|
||||
if(default_unfasten_wrench(user, I))
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/deck_relay/process()
|
||||
if(!anchored)
|
||||
icon_state = "cablerelay-off"
|
||||
if(above) //Lose connections
|
||||
above.below = null
|
||||
if(below)
|
||||
below.above = null
|
||||
return
|
||||
refresh() //Sometimes the powernets get lost, so we need to keep checking.
|
||||
if(powernet && (powernet.avail <= 0)) // is it powered?
|
||||
icon_state = "cablerelay-off"
|
||||
else
|
||||
icon_state = "cablerelay-on"
|
||||
if(!below || QDELETED(below) || !above || QDELETED(above))
|
||||
icon_state = "cablerelay-off"
|
||||
find_relays()
|
||||
|
||||
///Allows you to scan the relay with a multitool to see stats.
|
||||
/obj/machinery/power/deck_relay/multitool_act(mob/user, obj/item/I)
|
||||
if(powernet && (powernet.avail > 0)) // is it powered?
|
||||
to_chat(user, "<span class='danger'>Total power: [DisplayPower(powernet.avail)]\nLoad: [DisplayPower(powernet.load)]\nExcess power: [DisplayPower(surplus())]</span>")
|
||||
if(!powernet || below.powernet != powernet)
|
||||
icon_state = "cablerelay-off"
|
||||
to_chat(user, "<span class='danger'>Powernet connection lost. Attempting to re-establish. Ensure the relays below this one are connected too.</span>")
|
||||
find_relays()
|
||||
addtimer(CALLBACK(src, .proc/refresh), 20) //Wait a bit so we can find the one below, then get powering
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/deck_relay/Initialize()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, .proc/find_relays), 30)
|
||||
addtimer(CALLBACK(src, .proc/refresh), 50) //Wait a bit so we can find the one below, then get powering
|
||||
|
||||
///Handles re-acquiring + merging powernets found by find_relays()
|
||||
/obj/machinery/power/deck_relay/proc/refresh()
|
||||
if(above)
|
||||
above.merge(src)
|
||||
if(below)
|
||||
below.merge(src)
|
||||
|
||||
/obj/machinery/power/deck_relay/proc/merge(var/obj/machinery/power/deck_relay/DR)
|
||||
if(!DR)
|
||||
return
|
||||
var/turf/merge_from = get_turf(DR)
|
||||
var/turf/merge_to = get_turf(src)
|
||||
var/obj/structure/cable/C = merge_from.get_cable_node()
|
||||
var/obj/structure/cable/XR = merge_to.get_cable_node()
|
||||
if(C && XR)
|
||||
merge_powernets(XR.powernet,C.powernet)//Bridge the powernets.
|
||||
|
||||
///Locates relays that are above and below this object
|
||||
/obj/machinery/power/deck_relay/proc/find_relays()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || !istype(T))
|
||||
return FALSE
|
||||
below = null //in case we're re-establishing
|
||||
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
|
||||
if(C && C.powernet)
|
||||
C.powernet.add_machine(src) //Nice we're in.
|
||||
powernet = C.powernet
|
||||
below = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_below(T))
|
||||
above = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_above(T))
|
||||
if(below || above)
|
||||
icon_state = "cablerelay-on"
|
||||
return TRUE
|
||||
@@ -313,7 +313,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
playsound(T, 'sound/effects/supermatter.ogg', 50, 1)
|
||||
T.visible_message("<span class='danger'>[T] smacks into [src] and rapidly flashes to ash.</span>",\
|
||||
"<span class='italics'>You hear a loud crack as you are washed with a wave of heat.</span>")
|
||||
T.CalculateAdjacentTurfs()
|
||||
CALCULATE_ADJACENT_TURFS(T)
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/process_atmos()
|
||||
var/turf/T = loc
|
||||
@@ -650,6 +650,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
|
||||
Consume(AM)
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/intercept_zImpact(atom/movable/AM, levels)
|
||||
. = ..()
|
||||
Bumped(AM)
|
||||
. |= FALL_STOP_INTERCEPTING | FALL_INTERCEPTED
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/proc/Consume(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/user = AM
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/reagent/consumable/cooking_oil/reaction_turf(turf/open/T, reac_volume)
|
||||
if(!istype(T))
|
||||
if(!istype(T) || isgroundlessturf(T))
|
||||
return
|
||||
if(reac_volume >= 5)
|
||||
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#define MULTIZ_PIPE_UP 1 ///Defines for determining which way a multiz disposal element should travel
|
||||
#define MULTIZ_PIPE_DOWN 2 ///Defines for determining which way a multiz disposal element should travel
|
||||
|
||||
|
||||
/obj/structure/disposalpipe/trunk/multiz
|
||||
name = "Disposal trunk that goes up"
|
||||
icon_state = "pipe-up"
|
||||
var/multiz_dir = MULTIZ_PIPE_UP ///Set the multiz direction of your trunk. 1 = up, 2 = down
|
||||
|
||||
/obj/structure/disposalpipe/trunk/multiz/down
|
||||
name = "Disposal trunk that goes down"
|
||||
icon_state = "pipe-down"
|
||||
multiz_dir = MULTIZ_PIPE_DOWN
|
||||
|
||||
/obj/structure/disposalpipe/trunk/multiz/transfer(obj/structure/disposalholder/H)
|
||||
if(H.dir == DOWN) //Since we're a trunk, you can still place a chute / bin over us. If theyve entered from there, treat this as a normal trunk
|
||||
return ..()
|
||||
// otherwise, go to the linked object
|
||||
if(multiz_dir) //Are we a trunk that goes up? Or down?
|
||||
var/turf/T = null
|
||||
if(multiz_dir == MULTIZ_PIPE_UP)
|
||||
T = SSmapping.get_turf_above(get_turf(src)) //Get the turf above us
|
||||
if(multiz_dir == MULTIZ_PIPE_DOWN)
|
||||
T = SSmapping.get_turf_below(get_turf(src))
|
||||
if(!T)
|
||||
expel(H)
|
||||
return //Nothing located.
|
||||
var/obj/structure/disposalpipe/trunk/multiz/pipe = locate(/obj/structure/disposalpipe/trunk/multiz) in T
|
||||
if(pipe)
|
||||
var/obj/structure/disposalholder/destination = new(pipe) //For future reference, the disposal holder is the thing that carries mobs
|
||||
destination.init(pipe) //This instantiates it
|
||||
destination.merge(H) //This takes the contents of H (Our disposal holder that's travelling into us) and puts them into the destination holder
|
||||
destination.active = TRUE //Active allows it to process and move
|
||||
destination.setDir(DOWN) //This tells the trunk above us NOT to loop it back down to us, or else you get an infinite loop
|
||||
destination.move()
|
||||
return null //Which removes the disposalholder
|
||||
else
|
||||
var/obj/structure/disposaloutlet/O = linked
|
||||
if(istype(O))
|
||||
O.expel(H) // expel at outlet
|
||||
else
|
||||
var/obj/machinery/disposal/D = linked
|
||||
D.expel(H) // expel at disposal
|
||||
|
||||
// Returning null without expelling holder makes the holder expell itself
|
||||
return null
|
||||
|
||||
#undef MULTIZ_PIPE_UP
|
||||
#undef MULTIZ_PIPE_DOWN
|
||||
@@ -33,6 +33,9 @@
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/obj/docking_port/has_gravity(turf/T)
|
||||
return FALSE
|
||||
|
||||
/obj/docking_port/take_damage()
|
||||
return
|
||||
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
after_cast(targets)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
|
||||
var/A = null
|
||||
|
||||
var/area/U = get_area(usr)
|
||||
if(U.noteleport && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
|
||||
to_chat(usr, "<span class='warning'>Unseen forces prevent you from casting this spell in this area</span>")
|
||||
return
|
||||
var/A
|
||||
if(!randomise_selection)
|
||||
A = input("Area to teleport to", "Teleport", A) as null|anything in GLOB.teleportlocs
|
||||
else
|
||||
@@ -53,12 +56,13 @@
|
||||
if(target && target.buckled)
|
||||
target.buckled.unbuckle_mob(target, force=1)
|
||||
|
||||
var/forcecheck = istype(get_area(target), /area/wizard_station)
|
||||
var/list/tempL = L
|
||||
var/attempt = null
|
||||
var/success = 0
|
||||
while(tempL.len)
|
||||
attempt = pick(tempL)
|
||||
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC)
|
||||
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
if(get_turf(target) == attempt)
|
||||
success = 1
|
||||
break
|
||||
@@ -66,7 +70,7 @@
|
||||
tempL.Remove(attempt)
|
||||
|
||||
if(!success)
|
||||
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC)
|
||||
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
|
||||
playsound(get_turf(user), sound2, 50,1)
|
||||
|
||||
return
|
||||
|
||||
@@ -35,4 +35,7 @@ map deltastation
|
||||
endmap
|
||||
|
||||
map runtimestation
|
||||
endmap
|
||||
|
||||
map multiz_debug
|
||||
endmap
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
@@ -226,6 +226,7 @@
|
||||
#include "code\controllers\configuration\entries\game_options.dm"
|
||||
#include "code\controllers\configuration\entries\general.dm"
|
||||
#include "code\controllers\subsystem\acid.dm"
|
||||
#include "code\controllers\subsystem\adjacent_air.dm"
|
||||
#include "code\controllers\subsystem\air.dm"
|
||||
#include "code\controllers\subsystem\air_turfs.dm"
|
||||
#include "code\controllers\subsystem\assets.dm"
|
||||
@@ -1035,6 +1036,7 @@
|
||||
#include "code\game\objects\structures\safe.dm"
|
||||
#include "code\game\objects\structures\showcase.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"
|
||||
@@ -1089,6 +1091,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"
|
||||
@@ -1368,6 +1371,7 @@
|
||||
#include "code\modules\assembly\signaler.dm"
|
||||
#include "code\modules\assembly\timer.dm"
|
||||
#include "code\modules\assembly\voice.dm"
|
||||
#include "code\modules\atmospherics\multiz.dm"
|
||||
#include "code\modules\atmospherics\environmental\LINDA_fire.dm"
|
||||
#include "code\modules\atmospherics\environmental\LINDA_system.dm"
|
||||
#include "code\modules\atmospherics\environmental\LINDA_turf_tile.dm"
|
||||
@@ -1882,6 +1886,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"
|
||||
@@ -1966,6 +1971,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"
|
||||
@@ -2355,6 +2361,7 @@
|
||||
#include "code\modules\power\gravitygenerator.dm"
|
||||
#include "code\modules\power\lighting.dm"
|
||||
#include "code\modules\power\monitor.dm"
|
||||
#include "code\modules\power\multiz.dm"
|
||||
#include "code\modules\power\port_gen.dm"
|
||||
#include "code\modules\power\power.dm"
|
||||
#include "code\modules\power\powernet.dm"
|
||||
@@ -2563,6 +2570,7 @@
|
||||
#include "code\modules\recycling\disposal\construction.dm"
|
||||
#include "code\modules\recycling\disposal\eject.dm"
|
||||
#include "code\modules\recycling\disposal\holder.dm"
|
||||
#include "code\modules\recycling\disposal\multiz.dm"
|
||||
#include "code\modules\recycling\disposal\outlet.dm"
|
||||
#include "code\modules\recycling\disposal\pipe.dm"
|
||||
#include "code\modules\recycling\disposal\pipe_sorting.dm"
|
||||
|
||||