mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 12:07:27 +01:00
Merge pull request #4780 from Crazylemon64/space_ruins
Crazypilot's Space Ruins Port
This commit is contained in:
@@ -32,6 +32,8 @@ Pipelines + Other Objects -> Pipe network
|
||||
var/global/datum/pipe_icon_manager/icon_manager
|
||||
|
||||
/obj/machinery/atmospherics/New()
|
||||
..()
|
||||
|
||||
if(!icon_manager)
|
||||
icon_manager = new()
|
||||
|
||||
@@ -42,8 +44,6 @@ Pipelines + Other Objects -> Pipe network
|
||||
if(!pipe_color_check(pipe_color))
|
||||
pipe_color = null
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/initialize()
|
||||
..()
|
||||
|
||||
|
||||
@@ -60,13 +60,13 @@
|
||||
icon_state = "map_vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/New()
|
||||
..()
|
||||
icon = null
|
||||
initial_loc = get_area(loc)
|
||||
area_uid = initial_loc.uid
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/high_volume
|
||||
name = "large air vent"
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
connect_types = list(1,3) //connects to regular and scrubber pipes
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/New()
|
||||
..()
|
||||
icon = null
|
||||
initial_loc = get_area(loc)
|
||||
area_uid = initial_loc.uid
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
|
||||
if(initial_loc && frequency == 1439)
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
layer = 2.4 //under wires with their 2.44
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/New()
|
||||
|
||||
..()
|
||||
|
||||
alpha = 255
|
||||
icon = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = EAST|SOUTH|WEST
|
||||
@@ -27,11 +32,6 @@
|
||||
if(WEST)
|
||||
initialize_directions = NORTH|EAST|SOUTH
|
||||
|
||||
..()
|
||||
|
||||
alpha = 255
|
||||
icon = null
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/initialize()
|
||||
..()
|
||||
for(var/D in cardinal)
|
||||
@@ -62,7 +62,6 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion()
|
||||
return list(node1, node2, node3)
|
||||
@@ -102,6 +101,7 @@
|
||||
if(istype(node3, /obj/machinery/atmospherics/pipe))
|
||||
qdel(parent)
|
||||
node3 = null
|
||||
check_nodes_exist()
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
@@ -121,40 +121,39 @@
|
||||
|
||||
alpha = 255
|
||||
|
||||
if(!node1 && !node2 && !node3)
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
for(var/obj/machinery/meter/meter in T)
|
||||
if(meter.target == src)
|
||||
new /obj/item/pipe_meter(T)
|
||||
qdel(meter)
|
||||
qdel(src)
|
||||
else
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
|
||||
underlays.Cut()
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
|
||||
underlays.Cut()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
|
||||
var/node1_direction = get_dir(src, node1)
|
||||
var/node2_direction = get_dir(src, node2)
|
||||
var/node3_direction = get_dir(src, node3)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
|
||||
var/node1_direction = get_dir(src, node1)
|
||||
var/node2_direction = get_dir(src, node2)
|
||||
var/node3_direction = get_dir(src, node3)
|
||||
|
||||
directions -= dir
|
||||
directions -= dir
|
||||
|
||||
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
|
||||
|
||||
for(var/D in directions)
|
||||
add_underlay(T,,D,icon_connect_type)
|
||||
for(var/D in directions)
|
||||
add_underlay(T,,D,icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/update_underlays()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
// A check to make sure both nodes exist - self-delete if they aren't present
|
||||
/obj/machinery/atmospherics/pipe/manifold/check_nodes_exist()
|
||||
if(!node1 && !node2 && !node3)
|
||||
Deconstruct()
|
||||
return 0 // 0: No nodes exist
|
||||
// 1: 1-3 nodes exist, we continue existing
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible
|
||||
icon_state = "map"
|
||||
level = 2
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
qdel(parent)
|
||||
node4 = null
|
||||
|
||||
check_nodes_exist()
|
||||
update_icon()
|
||||
|
||||
..()
|
||||
@@ -93,59 +94,45 @@
|
||||
return
|
||||
|
||||
alpha = 255
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
|
||||
underlays.Cut()
|
||||
|
||||
if(!node1 && !node2 && !node3 && !node4)
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
for(var/obj/machinery/meter/meter in T)
|
||||
if(meter.target == src)
|
||||
new /obj/item/pipe_meter(T)
|
||||
qdel(meter)
|
||||
qdel(src)
|
||||
else
|
||||
overlays.Cut()
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
|
||||
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
|
||||
var/node1_direction = get_dir(src, node1)
|
||||
var/node2_direction = get_dir(src, node2)
|
||||
var/node3_direction = get_dir(src, node3)
|
||||
var/node4_direction = get_dir(src, node4)
|
||||
|
||||
/*
|
||||
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
|
||||
directions -= dir
|
||||
|
||||
directions -= add_underlay(node1)
|
||||
directions -= add_underlay(node2)
|
||||
directions -= add_underlay(node3)
|
||||
directions -= add_underlay(node4)
|
||||
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node4,node4_direction,icon_connect_type)
|
||||
|
||||
for(var/D in directions)
|
||||
add_underlay(,D)
|
||||
*/
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) return
|
||||
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
|
||||
var/node1_direction = get_dir(src, node1)
|
||||
var/node2_direction = get_dir(src, node2)
|
||||
var/node3_direction = get_dir(src, node3)
|
||||
var/node4_direction = get_dir(src, node4)
|
||||
|
||||
directions -= dir
|
||||
|
||||
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
|
||||
directions -= add_underlay(T,node4,node4_direction,icon_connect_type)
|
||||
|
||||
for(var/D in directions)
|
||||
add_underlay(T,,D,icon_connect_type)
|
||||
for(var/D in directions)
|
||||
add_underlay(T,,D,icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/update_underlays()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
|
||||
// A check to make sure both nodes exist - self-delete if they aren't present
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/check_nodes_exist()
|
||||
if(!node1 && !node2 && !node3 && !node4)
|
||||
Deconstruct()
|
||||
return 0 // 0: No nodes exist
|
||||
// 1: 1-4 nodes exist, we continue existing
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/initialize()
|
||||
..()
|
||||
@@ -244,4 +231,4 @@
|
||||
color = PIPE_COLOR_GREEN
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
color = PIPE_COLOR_PURPLE
|
||||
|
||||
@@ -85,3 +85,7 @@
|
||||
return node.pipe_color
|
||||
else
|
||||
return pipe_color
|
||||
|
||||
// A check to make sure both nodes exist - self-delete if they aren't present
|
||||
/obj/machinery/atmospherics/pipe/proc/check_nodes_exist()
|
||||
return
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
connected_to = c
|
||||
node2 = target
|
||||
break
|
||||
|
||||
var/turf/T = loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
@@ -120,7 +121,9 @@
|
||||
if(istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
qdel(parent)
|
||||
node2 = null
|
||||
check_nodes_exist()
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/pipeline_expansion()
|
||||
return list(node1, node2)
|
||||
@@ -141,23 +144,22 @@
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
if(!node1 && !node2)
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
for(var/obj/machinery/meter/meter in T)
|
||||
if(meter.target == src)
|
||||
new /obj/item/pipe_meter(T)
|
||||
qdel(meter)
|
||||
qdel(src)
|
||||
else if(node1 && node2)
|
||||
if(node1 && node2)
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type)
|
||||
else
|
||||
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type)
|
||||
|
||||
// A check to make sure both nodes exist - self-delete if they aren't present
|
||||
/obj/machinery/atmospherics/pipe/simple/check_nodes_exist()
|
||||
if(!node1 && !node2)
|
||||
Deconstruct()
|
||||
return 0 // 0: No nodes exist
|
||||
// 1: 1-2 nodes exist, we continue existing
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/update_underlays()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
@@ -78,7 +78,7 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
|
||||
if(T.atmos_adjacent_turfs & counterdir)
|
||||
T.atmos_adjacent_turfs_amount -= 1
|
||||
T.atmos_adjacent_turfs &= ~counterdir
|
||||
|
||||
|
||||
//returns a list of adjacent turfs that can share air with this one.
|
||||
//alldir includes adjacent diagonal tiles that can share
|
||||
// air with both of the related adjacent cardinal tiles
|
||||
@@ -184,4 +184,4 @@ var/const/SPAWN_AIR = 256
|
||||
G.nitrogen += MOLES_N2STANDARD * amount
|
||||
|
||||
air.merge(G)
|
||||
air_master.add_to_active(src, 0)
|
||||
air_master.add_to_active(src, 0)
|
||||
|
||||
@@ -244,6 +244,14 @@
|
||||
#define REGION_COMMAND 7
|
||||
#define REGION_CENTCOMM 8
|
||||
|
||||
//used for maploader
|
||||
#define MAP_MINX 1
|
||||
#define MAP_MINY 2
|
||||
#define MAP_MINZ 3
|
||||
#define MAP_MAXX 4
|
||||
#define MAP_MAXY 5
|
||||
#define MAP_MAXZ 6
|
||||
|
||||
//Matricies
|
||||
#define MATRIX_DEFAULT list(1, 0, 0, 0,\
|
||||
0, 1, 0, 0,\
|
||||
|
||||
@@ -386,6 +386,16 @@
|
||||
//log_to_dd(" output: [out.len]")
|
||||
return reverselist(out)
|
||||
|
||||
//Copies a list, and all lists inside it recusively
|
||||
//Does not copy any other reference type
|
||||
/proc/deepCopyList(list/l)
|
||||
if(!islist(l))
|
||||
return l
|
||||
. = l.Copy()
|
||||
for(var/i = 1 to l.len)
|
||||
if(islist(.[i]))
|
||||
.[i] = .(.[i])
|
||||
|
||||
/proc/dd_sortedObjectList(var/list/L, var/cache=list())
|
||||
if(L.len < 2)
|
||||
return L
|
||||
|
||||
@@ -93,6 +93,12 @@
|
||||
to_chat(world, "<span class='danger'>[message]</span>")
|
||||
log_to_dd(message)
|
||||
|
||||
// A logging proc that only outputs after setup is done, to
|
||||
// help devs test initialization stuff that happens a lot
|
||||
/proc/log_after_setup(var/message)
|
||||
if(ticker && ticker.current_state > GAME_STATE_SETTING_UP)
|
||||
to_chat(world, "<span class='danger'>[message]</span>")
|
||||
log_to_dd(message)
|
||||
// Helper procs for building detailed log lines
|
||||
|
||||
/proc/datum_info_line(var/datum/d)
|
||||
|
||||
@@ -24,5 +24,4 @@ var/list/restricted_camera_networks = list( //Those networks can only be accesse
|
||||
"Hotel"
|
||||
)
|
||||
|
||||
var/list/map_templates = list()
|
||||
var/list/mineral_turfs = list()
|
||||
var/list/mineral_turfs = list()
|
||||
|
||||
@@ -54,3 +54,10 @@ var/list/carplist = list() //list of all carp-spawn landmarks
|
||||
|
||||
//away missions
|
||||
var/list/awaydestinations = list() //a list of landmarks that the warpgate can take you to
|
||||
|
||||
//List of preloaded templates
|
||||
var/list/datum/map_template/map_templates = list()
|
||||
|
||||
var/list/datum/map_template/ruins_templates = list()
|
||||
var/list/datum/map_template/space_ruins_templates = list()
|
||||
//var/list/datum/map_template/lava_ruins_templates = list()
|
||||
|
||||
@@ -146,4 +146,4 @@ var/global/datum/controller/process/air_system/air_master
|
||||
icemaster.icon = 'icons/turf/overlays.dmi'
|
||||
icemaster.icon_state = "snowfloor"
|
||||
icemaster.layer = TURF_LAYER+0.1
|
||||
icemaster.mouse_opacity = 0
|
||||
icemaster.mouse_opacity = 0
|
||||
|
||||
@@ -11,6 +11,7 @@ var/global/datum/controller/process/sun/sun
|
||||
name = "sun"
|
||||
schedule_interval = 600 // every 60 seconds
|
||||
sun = src
|
||||
log_startup_progress("Sun ticker starting up.")
|
||||
|
||||
angle = rand (0,360) // the station position to the sun is randomised at round start
|
||||
rate = rand(50,200)/100 // 50% - 200% of standard rotation
|
||||
|
||||
@@ -9,6 +9,7 @@ var/global/datum/controller/process/ticker/tickerProcess
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
|
||||
lastTickerTime = world.timeofday
|
||||
log_startup_progress("Time ticker starting up.")
|
||||
|
||||
if(!ticker)
|
||||
ticker = new
|
||||
|
||||
@@ -8,6 +8,7 @@ var/global/datum/controller/process/timer/timer_master
|
||||
name = "timer"
|
||||
schedule_interval = 5 //every 0.5 seconds
|
||||
timer_master = src
|
||||
log_startup_progress("Timer process starting up.")
|
||||
|
||||
/datum/controller/process/timer/statProcess()
|
||||
..()
|
||||
@@ -79,4 +80,4 @@ var/global/datum/controller/process/timer/timer_master
|
||||
if(event.id == id)
|
||||
qdel(event)
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/controller/process/vote/setup()
|
||||
name = "vote"
|
||||
schedule_interval = 10 // every second
|
||||
log_startup_progress("Voting ticker starting up.")
|
||||
|
||||
/datum/controller/process/vote/doWork()
|
||||
vote.process()
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
var/list/overflow_whitelist = list() //whitelist for overflow
|
||||
|
||||
var/disable_away_missions = 0 // disable away missions
|
||||
var/disable_space_ruins = 0 //disable space ruins
|
||||
|
||||
var/ooc_allowed = 1
|
||||
var/looc_allowed = 1
|
||||
@@ -547,6 +548,9 @@
|
||||
if("disable_away_missions")
|
||||
config.disable_away_missions = 1
|
||||
|
||||
if("disable_space_ruins")
|
||||
config.disable_space_ruins = 1
|
||||
|
||||
if("disable_lobby_music")
|
||||
config.disable_lobby_music = 1
|
||||
|
||||
|
||||
@@ -11,16 +11,16 @@ var/global/air_processing_killed = 0
|
||||
var/global/pipe_processing_killed = 0
|
||||
|
||||
/datum/controller
|
||||
var/processing = 0
|
||||
var/iteration = 0
|
||||
var/processing_interval = 0
|
||||
var/processing = 0
|
||||
var/iteration = 0
|
||||
var/processing_interval = 0
|
||||
|
||||
/datum/controller/proc/recover() // If we are replacing an existing controller (due to a crash) we attempt to preserve as much as we can.
|
||||
|
||||
datum/controller/game_controller
|
||||
var/list/shuttle_list // For debugging and VV
|
||||
/datum/controller/game_controller
|
||||
var/list/shuttle_list // For debugging and VV
|
||||
|
||||
datum/controller/game_controller/New()
|
||||
/datum/controller/game_controller/New()
|
||||
//There can be only one master_controller. Out with the old and in with the new.
|
||||
if(master_controller != src)
|
||||
if(istype(master_controller))
|
||||
@@ -38,12 +38,16 @@ datum/controller/game_controller/New()
|
||||
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
|
||||
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
|
||||
|
||||
datum/controller/game_controller/proc/setup()
|
||||
/datum/controller/game_controller/proc/setup()
|
||||
world.tick_lag = config.Ticklag
|
||||
|
||||
zlevels.initialize()
|
||||
|
||||
preloadTemplates()
|
||||
if(!config.disable_away_missions)
|
||||
createRandomZlevel()
|
||||
if(!config.disable_space_ruins)
|
||||
seedRuins(7, rand(0, 3), /area/space, space_ruins_templates)
|
||||
|
||||
setup_objects()
|
||||
setupgenetics()
|
||||
@@ -55,21 +59,21 @@ datum/controller/game_controller/proc/setup()
|
||||
|
||||
populate_spawn_points()
|
||||
|
||||
datum/controller/game_controller/proc/setup_objects()
|
||||
/datum/controller/game_controller/proc/setup_objects()
|
||||
var/watch = start_watch()
|
||||
var/count = 0
|
||||
var/overwatch = start_watch() // Overall.
|
||||
|
||||
log_startup_progress("Populating asset cache...")
|
||||
populate_asset_cache()
|
||||
log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.")
|
||||
log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.")
|
||||
|
||||
watch = start_watch()
|
||||
log_startup_progress("Initializing objects...")
|
||||
for(var/atom/movable/object in world)
|
||||
object.initialize()
|
||||
count++
|
||||
log_startup_progress(" Initialized [count] objects in [stop_watch(watch)]s.")
|
||||
log_startup_progress(" Initialized [count] objects in [stop_watch(watch)]s.")
|
||||
|
||||
watch = start_watch()
|
||||
count = 0
|
||||
@@ -83,7 +87,7 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
var/obj/machinery/atmospherics/unary/vent_scrubber/T = U
|
||||
T.broadcast_status()
|
||||
count++
|
||||
log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.")
|
||||
log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.")
|
||||
|
||||
watch = start_watch()
|
||||
count = 0
|
||||
@@ -91,6 +95,6 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
for(var/obj/machinery/atmospherics/machine in machines)
|
||||
machine.build_network()
|
||||
count++
|
||||
log_startup_progress(" Initialized [count] pipe networks in [stop_watch(watch)]s.")
|
||||
log_startup_progress(" Initialized [count] pipes in [stop_watch(watch)]s.")
|
||||
|
||||
log_startup_progress("Finished object initializations in [stop_watch(overwatch)]s.")
|
||||
|
||||
@@ -234,6 +234,7 @@
|
||||
|
||||
body += "<option value='?_src_=vars;mark_object=\ref[D]'>Mark Object</option>"
|
||||
body += "<option value='?_src_=vars;proc_call=\ref[D]'>Call Proc</option>"
|
||||
body += "<option value='?_src_=vars;jump_to=\ref[D]'>Jump to Object</option>"
|
||||
if(ismob(D))
|
||||
body += "<option value='?_src_=vars;mob_player_panel=\ref[D]'>Show player panel</option>"
|
||||
|
||||
@@ -394,11 +395,7 @@ body
|
||||
html += "<ul>"
|
||||
var/index = 1
|
||||
for(var/entry in L)
|
||||
if(istext(entry))
|
||||
html += debug_variable(entry, L[entry], level + 1)
|
||||
//html += debug_variable("[index]", L[index], level + 1)
|
||||
else
|
||||
html += debug_variable(index, L[index], level + 1)
|
||||
html += debug_variable(index, L[index], level + 1)
|
||||
index++
|
||||
html += "</ul>"
|
||||
|
||||
@@ -736,6 +733,17 @@ body
|
||||
if(T)
|
||||
callproc_datum(T)
|
||||
|
||||
else if(href_list["jump_to"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["jump_to"])
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
usr.client.jumptoturf(T)
|
||||
href_list["datumrefresh"] = href_list["jump_to"]
|
||||
|
||||
|
||||
else if(href_list["rotatedatum"])
|
||||
if(!check_rights(R_DEBUG|R_ADMIN)) return
|
||||
|
||||
@@ -1080,4 +1088,3 @@ body
|
||||
src.debug_variables(DAT)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
/datum/map_template/New(path = null, map = null, rename = null)
|
||||
if(path)
|
||||
mappath = path
|
||||
if(mappath)
|
||||
preload_size(mappath)
|
||||
if(map)
|
||||
mapfile = map
|
||||
@@ -16,52 +17,145 @@
|
||||
name = rename
|
||||
|
||||
/datum/map_template/proc/preload_size(path)
|
||||
var/quote = ascii2text(34)
|
||||
var/map_file = file2text(path)
|
||||
var/key_len = length(copytext(map_file,2,findtext(map_file,quote,2,0)))
|
||||
//assuming one map per file since more makes no sense for templates anyway
|
||||
var/mapstart = findtext(map_file,"\n(1,1,") //todo replace with something saner
|
||||
var/content = copytext(map_file,findtext(map_file,quote+"\n",mapstart,0)+2,findtext(map_file,"\n"+quote,mapstart,0)+1)
|
||||
var/line_len = length(copytext(content,1,findtext(content,"\n",2,0)))
|
||||
|
||||
width = line_len/key_len
|
||||
height = length(content)/(line_len+1)
|
||||
var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap = 0, measureOnly = 1)
|
||||
if(bounds)
|
||||
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
|
||||
height = bounds[MAP_MAXY]
|
||||
return bounds
|
||||
|
||||
/datum/map_template/proc/load(turf/T, centered = 0)
|
||||
var/turf/placement = T
|
||||
var/min_x = placement.x
|
||||
var/min_y = placement.y
|
||||
if(centered)
|
||||
T = locate(T.x - round(width / 2), T.y - round(height / 2), T.z)
|
||||
min_x -= round(width/2)
|
||||
min_y -= round(height/2)
|
||||
|
||||
var/max_x = min_x + width - 1
|
||||
var/max_y = min_y + height - 1
|
||||
|
||||
if(!T)
|
||||
return
|
||||
if(T.x+width > world.maxx)
|
||||
return
|
||||
if(T.y+height > world.maxy)
|
||||
return
|
||||
return 0
|
||||
|
||||
var/turf/bot_left = locate(max(1, min_x), max(1, min_y), placement.z)
|
||||
var/turf/top_right = locate(min(world.maxx, max_x), min(world.maxy, max_y), placement.z)
|
||||
|
||||
// 1 bigger, to update the turf smoothing
|
||||
var/turf/ST_bot_left = locate(max(1, min_x-1), max(1, min_y-1), placement.z)
|
||||
var/turf/ST_top_right = locate(min(world.maxx, max_x+1), min(world.maxy, max_y+1), placement.z)
|
||||
// This is to place a freeze on initialization until the map's done loading
|
||||
// otherwise atmos and stuff will start running mid-load
|
||||
// This system will metaphorically snap in half (not postpone init everywhere)
|
||||
// if given a multi-z template
|
||||
// it might need to be adapted for that when that time comes
|
||||
zlevels.add_dirt(placement.z)
|
||||
var/list/bounds = maploader.load_map(get_file(), min_x, min_y, placement.z, cropMap = 1)
|
||||
if(!bounds)
|
||||
return 0
|
||||
if(bot_left == null || top_right == null)
|
||||
log_debug("One of the late setup corners is bust")
|
||||
else
|
||||
log_debug("Late Setup from ([bot_left.x],[bot_left.y]) to ([top_right.x],[top_right.y])")
|
||||
|
||||
if(ST_bot_left == null || ST_top_right == null)
|
||||
log_debug("One of the smoothing corners is bust")
|
||||
else
|
||||
log_debug("Tile smoothing from ([ST_bot_left.x],[ST_bot_left.y]) to ([ST_top_right.x],[ST_top_right.y])")
|
||||
|
||||
maploader.load_map(get_file(), T.x-1, T.y-1, T.z)
|
||||
late_setup_level(
|
||||
block(T, locate(T.x + width - 1, T.y + height - 1, T.z)),
|
||||
block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + width, T.y + height, T.z)))
|
||||
block(bot_left, top_right),
|
||||
block(ST_bot_left, ST_top_right))
|
||||
zlevels.remove_dirt(placement.z)
|
||||
|
||||
log_game("[name] loaded at at [T.x],[T.y],[T.z]")
|
||||
log_game("[name] loaded at [min_x],[min_y],[placement.z]")
|
||||
return 1
|
||||
|
||||
/datum/map_template/proc/get_file()
|
||||
if(mapfile)
|
||||
return mapfile
|
||||
if(mappath)
|
||||
mapfile = file(mappath)
|
||||
return mapfile
|
||||
. = mapfile
|
||||
else if(mappath)
|
||||
. = file(mappath)
|
||||
|
||||
if(!.)
|
||||
log_to_dd(" The file of [src] appears to be empty/non-existent.")
|
||||
|
||||
/datum/map_template/proc/get_affected_turfs(turf/T, centered = 0)
|
||||
var/turf/placement = T
|
||||
var/min_x = placement.x
|
||||
var/min_y = placement.y
|
||||
if(centered)
|
||||
var/turf/corner = locate(placement.x - round(width/2), placement.y - round(height/2), placement.z)
|
||||
if(corner)
|
||||
placement = corner
|
||||
return block(placement, locate(placement.x+width-1, placement.y+height-1, placement.z))
|
||||
min_x -= round(width/2)
|
||||
min_y -= round(height/2)
|
||||
|
||||
var/max_x = min_x + width-1
|
||||
var/max_y = min_y + height-1
|
||||
placement = locate(max(min_x,1), max(min_y,1), placement.z)
|
||||
return block(placement, locate(min(max_x, world.maxx), min(max_y, world.maxy), placement.z))
|
||||
|
||||
/datum/map_template/proc/fits_in_map_bounds(turf/T, centered = 0)
|
||||
var/turf/placement = T
|
||||
var/min_x = placement.x
|
||||
var/min_y = placement.y
|
||||
if(centered)
|
||||
min_x -= round(width/2)
|
||||
min_y -= round(height/2)
|
||||
|
||||
var/max_x = min_x + width-1
|
||||
var/max_y = min_y + height-1
|
||||
if(min_x < 1 || min_y < 1 || max_x > world.maxx || max_y > world.maxy)
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
/proc/preloadTemplates(path = "_maps/map_files/templates/") //see master controller setup
|
||||
for(var/map in flist(path))
|
||||
if(cmptext(copytext(map, length(map) - 3), ".dmm"))
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
map_templates[T.name] = T
|
||||
map_templates[T.name] = T
|
||||
|
||||
if(!config.disable_space_ruins) // so we don't unnecessarily clutter start-up
|
||||
preloadRuinTemplates()
|
||||
//preloadShuttleTemplates()
|
||||
|
||||
/proc/preloadRuinTemplates()
|
||||
// Still supporting bans by filename
|
||||
var/list/banned
|
||||
if(fexists("config/spaceRuinBlacklist.txt"))
|
||||
banned = generateMapList("config/spaceRuinBlacklist.txt")
|
||||
else
|
||||
banned = generateMapList("config/example/spaceRuinBlacklist.txt")
|
||||
//banned += generateMapList("config/lavaRuinBlacklist.txt")
|
||||
|
||||
for(var/item in subtypesof(/datum/map_template/ruin))
|
||||
var/datum/map_template/ruin/ruin_type = item
|
||||
// screen out the abstract subtypes
|
||||
if(!initial(ruin_type.id))
|
||||
continue
|
||||
var/datum/map_template/ruin/R = new ruin_type()
|
||||
|
||||
if(banned.Find(R.mappath))
|
||||
continue
|
||||
|
||||
map_templates[R.name] = R
|
||||
ruins_templates[R.name] = R
|
||||
|
||||
/*
|
||||
if(istype(R, /datum/map_template/ruin/lavaland))
|
||||
lava_ruins_templates[R.name] = R
|
||||
*/
|
||||
if(istype(R, /datum/map_template/ruin/space))
|
||||
space_ruins_templates[R.name] = R
|
||||
|
||||
/*
|
||||
/proc/preloadShuttleTemplates()
|
||||
for(var/item in subtypesof(/datum/map_template/shuttle))
|
||||
var/datum/map_template/shuttle/shuttle_type = item
|
||||
if(!(initial(shuttle_type.suffix)))
|
||||
continue
|
||||
|
||||
var/datum/map_template/shuttle/S = new shuttle_type()
|
||||
|
||||
shuttle_templates[S.shuttle_id] = S
|
||||
map_templates[S.shuttle_id] = S
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/datum/map_template/ruin
|
||||
//name = "A Chest of Doubloons"
|
||||
name = null
|
||||
var/id = null // For blacklisting purposes, all ruins need an id
|
||||
var/description = "In the middle of a clearing in the rockface, there's a \
|
||||
chest filled with gold coins with Spanish engravings. How is there a \
|
||||
wooden container filled with 18th century coinage in the middle of a \
|
||||
lavawracked hellscape? It is clearly a mystery."
|
||||
|
||||
var/cost = null
|
||||
var/allow_duplicates = FALSE //A bit boring, don't you think? You can always explicitly allow it on a ruin definition
|
||||
|
||||
var/prefix = null
|
||||
var/suffix = null
|
||||
|
||||
/datum/map_template/ruin/New()
|
||||
if(!name && id)
|
||||
name = id
|
||||
|
||||
mappath = prefix + suffix
|
||||
..(path = mappath)
|
||||
@@ -0,0 +1,162 @@
|
||||
//The bigger ones lag like hell if there is more than one on a z-level, so cost 2 for them
|
||||
/datum/map_template/ruin/space
|
||||
prefix = "_maps/map_files/RandomRuins/SpaceRuins/"
|
||||
cost = 1
|
||||
|
||||
/datum/map_template/ruin/space/zoo
|
||||
id = "zoo"
|
||||
suffix = "abandonedzoo.dmm"
|
||||
name = "Biological Storage Facility"
|
||||
description = "In case society crumbles, we will be able to restore our \
|
||||
zoos to working order with the breeding stock kept in these 100% \
|
||||
secure and unbreachable storage facilities. At no point has anything \
|
||||
escaped. That's our story, and we're sticking to it."
|
||||
cost = 2
|
||||
|
||||
/datum/map_template/ruin/space/asteroid1
|
||||
id = "asteroid1"
|
||||
suffix = "asteroid1.dmm"
|
||||
name = "Asteroid 1"
|
||||
description = "I-spy with my little eye, something beginning with R."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid2
|
||||
id = "asteroid2"
|
||||
suffix = "asteroid2.dmm"
|
||||
name = "Asteroid 2"
|
||||
description = "Oh my god, a giant rock!"
|
||||
|
||||
/datum/map_template/ruin/space/asteroid3
|
||||
id = "asteroid3"
|
||||
suffix = "asteroid3.dmm"
|
||||
name = "Asteroid 3"
|
||||
description = "This asteroid floating in space has no official \
|
||||
designation, because the scientist that discovered it deemed it \
|
||||
'super dull'."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid4
|
||||
id = "asteroid4"
|
||||
suffix = "asteroid4.dmm"
|
||||
name = "Asteroid 4"
|
||||
description = "Nanotrasen Escape Pods have a 100%* success rate, and a \
|
||||
99%* customer satisfaction rate. *Please note that these statistics, \
|
||||
are taken from pods that have successfully docked with a recovery \
|
||||
vessel."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid5
|
||||
id = "asteroid5"
|
||||
suffix = "asteroid5.dmm"
|
||||
name = "Asteroid 5"
|
||||
description = "Oh my god, another giant rock!"
|
||||
|
||||
/datum/map_template/ruin/space/deep_storage
|
||||
id = "deep-storage"
|
||||
suffix = "deepstorage.dmm"
|
||||
name = "Survivalist Bunker"
|
||||
description = "Assume the best, prepare for the worst. Generally, you \
|
||||
should do so by digging a three man heavily fortified bunker into \
|
||||
a giant unused asteroid. Then make it self sufficient, mask any \
|
||||
evidence of construction, hook it covertly into the \
|
||||
telecommunications network and hope for the best."
|
||||
cost = 2
|
||||
|
||||
/datum/map_template/ruin/space/derelict1
|
||||
id = "derelict1"
|
||||
suffix = "derelict1.dmm"
|
||||
name = "Derelict 1"
|
||||
description = "Nothing to see here citizen, move along, certainly no \
|
||||
xeno outbreaks on this piece of station debris. That purple stuff? \
|
||||
It's uh... station nectar. It's a top secret research installation."
|
||||
|
||||
/datum/map_template/ruin/space/derelict2
|
||||
id = "derelict2"
|
||||
suffix = "derelict2.dmm"
|
||||
name = "Dinner for Two"
|
||||
description = "Oh this is the night\n\
|
||||
It's a beautiful night\n\
|
||||
And we call it bella notte"
|
||||
|
||||
/datum/map_template/ruin/space/derelict3
|
||||
id = "derelict3"
|
||||
suffix = "derelict3.dmm"
|
||||
name = "Derelict 3"
|
||||
description = "These hulks were once part of a larger structure, where \
|
||||
the three great \[REDACTED\] were forged."
|
||||
|
||||
/datum/map_template/ruin/space/derelict4
|
||||
id = "derelict4"
|
||||
suffix = "derelict4.dmm"
|
||||
name = "Derelict 4"
|
||||
description = "Centcom ferries have never crashed, will never crash, \
|
||||
there is no current investigation into a crashed ferry, and we \
|
||||
will not let Internal Affairs trample over high security information \
|
||||
in the name of this baseless witchhunt."
|
||||
|
||||
/datum/map_template/ruin/space/derelict5
|
||||
id = "derelict5"
|
||||
suffix = "derelict5.dmm"
|
||||
name = "Derelict 5"
|
||||
description = "The plan is, we put a whole bunch of crates full of \
|
||||
treasure in this disused warehouse, launch it into space, and then \
|
||||
ignore it. Forever."
|
||||
|
||||
/datum/map_template/ruin/space/empty_shell
|
||||
id = "empty-shell"
|
||||
suffix = "emptyshell.dmm"
|
||||
name = "Empty Shell"
|
||||
description = "Cosy, rural property availible for young professional \
|
||||
couple. Only twelve parsecs from the nearest hyperspace lane!"
|
||||
|
||||
/datum/map_template/ruin/space/gas_the_lizards
|
||||
id = "gas-the-lizards"
|
||||
suffix = "gasthelizards.dmm"
|
||||
name = "Disposal Facility 17"
|
||||
description = "Gas efficiency at 95.6%, fluid elimination at 96.2%. \
|
||||
Will require renewed supplies of 'carpet' before the end of the \
|
||||
quarter."
|
||||
|
||||
/datum/map_template/ruin/space/intact_empty_ship
|
||||
id = "intact-empty-ship"
|
||||
suffix = "intactemptyship.dmm"
|
||||
name = "Authorship"
|
||||
description = "Just somewhere quiet, where I can focus on my work with \
|
||||
no interruptions."
|
||||
|
||||
/datum/map_template/ruin/space/mech_transport
|
||||
id = "mech-transport"
|
||||
suffix = "mechtransport.dmm"
|
||||
name = "CF Corsair"
|
||||
description = "Well, when is it getting here? I have bills to pay; very \
|
||||
well-armed clients who want their shipments as soon as possible! I \
|
||||
don't care, just find it!"
|
||||
|
||||
/datum/map_template/ruin/space/onehalf
|
||||
id = "onehalf"
|
||||
suffix = "onehalf.dmm"
|
||||
name = "DK Excavator 453"
|
||||
description = "Based on the trace elements we've detected on the \
|
||||
gutted asteroids, we suspect that a mining ship using a restricted \
|
||||
engine is somewhere in the area. We'd like to request a patrol vessel \
|
||||
to investigate."
|
||||
cost = 2
|
||||
|
||||
/datum/map_template/ruin/space/spacebar
|
||||
id = "spacebar"
|
||||
suffix = "spacebar.dmm"
|
||||
name = "The Rampant Golem and Yellow Hound"
|
||||
description = "No questions asked. No shoes/foot protection, no service. \
|
||||
No tabs. No violence in the inside areas. That's it. Welcome to the \
|
||||
Rampant Golem and Yellow Hound. Can I take your order?"
|
||||
cost = 2
|
||||
|
||||
/datum/map_template/ruin/space/turreted_outpost
|
||||
id = "turreted-outpost"
|
||||
suffix = "turretedoutpost.dmm"
|
||||
name = "Unnamed Turreted Outpost"
|
||||
description = "We'd ask them to stop blaring that ruskiepop music, but \
|
||||
none of us are brave enough to go near those death turrets they have."
|
||||
|
||||
/datum/map_template/ruin/space/way_home
|
||||
id = "way-home"
|
||||
suffix = "way_home.dmm"
|
||||
name = "Salvation"
|
||||
description = "In the darkest times, we will find our way home."
|
||||
+10
-5
@@ -11,8 +11,16 @@
|
||||
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
|
||||
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
|
||||
|
||||
// This var is used with the maploader (modules/awaymissions/maploader/reader.dm)
|
||||
// if this is 1, when used in a map snippet, this will instantiate a unique
|
||||
// area from any other instances already present (meaning you can have
|
||||
// separate APCs, and so on)
|
||||
var/there_can_be_many = 0
|
||||
|
||||
|
||||
/area/New()
|
||||
|
||||
..()
|
||||
icon_state = ""
|
||||
layer = 10
|
||||
uid = ++global_uid
|
||||
@@ -28,14 +36,11 @@
|
||||
// lighting_state = 4
|
||||
//has_gravity = 0 // Space has gravity. Because.. because.
|
||||
|
||||
if(!requires_power)
|
||||
if(requires_power != 0)
|
||||
power_light = 0 //rastaf0
|
||||
power_equip = 0 //rastaf0
|
||||
power_environ = 0 //rastaf0
|
||||
|
||||
..()
|
||||
|
||||
// spawn(15)
|
||||
power_change() // all machines set to current power level, also updates lighting icon
|
||||
|
||||
/area/proc/get_cameras()
|
||||
@@ -384,4 +389,4 @@
|
||||
for(var/obj/machinery/door/airlock/temp_airlock in src)
|
||||
temp_airlock.prison_open()
|
||||
for(var/obj/machinery/door/window/temp_windoor in src)
|
||||
temp_windoor.open()
|
||||
temp_windoor.open()
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
/atom/movable/New()
|
||||
. = ..()
|
||||
areaMaster = get_area_master(src)
|
||||
if(auto_init && ticker && ticker.current_state == GAME_STATE_PLAYING)
|
||||
initialize()
|
||||
|
||||
// If you're wondering what goofery this is, this is for things that need the environment
|
||||
// around them set up - like `air_update_turf` and the like
|
||||
if((ticker && ticker.current_state == GAME_STATE_PLAYING))
|
||||
attempt_init()
|
||||
|
||||
/atom/movable/Destroy()
|
||||
for(var/atom/movable/AM in contents)
|
||||
@@ -36,6 +39,16 @@
|
||||
pulledby = null
|
||||
return ..()
|
||||
|
||||
// used to provide a good interface for the init delay system to step in
|
||||
// and we don't need to call `get_turf` until the game's started
|
||||
// at which point object creations are a fair toss more seldom
|
||||
/atom/movable/proc/attempt_init()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && zlevels.is_zlevel_dirty(T.z))
|
||||
zlevels.postpone_init(T.z, src)
|
||||
else if(auto_init)
|
||||
initialize()
|
||||
|
||||
/atom/movable/proc/initialize()
|
||||
return
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ var/round_start_time = 0
|
||||
if(candidate_source.match_tag != current_destination.match_tag)
|
||||
continue
|
||||
|
||||
if (candidate_source.match_width != current_destination.match_width || \
|
||||
if(candidate_source.match_width != current_destination.match_width || \
|
||||
candidate_source.match_height != current_destination.match_height)
|
||||
continue
|
||||
|
||||
@@ -479,4 +479,3 @@ var/round_start_time = 0
|
||||
event_manager.RoundEnd()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@
|
||||
air_alarm_repository.update_cache(src)
|
||||
|
||||
/obj/machinery/alarm/initialize()
|
||||
..()
|
||||
set_frequency(frequency)
|
||||
if(!master_is_operating())
|
||||
elect_master()
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/meter/initialize()
|
||||
..()
|
||||
if(!target)
|
||||
target = locate(/obj/machinery/atmospherics/pipe) in loc
|
||||
|
||||
@@ -153,4 +154,4 @@
|
||||
<ul>
|
||||
<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[initial(frequency)]">Reset</a>)</li>
|
||||
<li>[format_tag("ID Tag","id_tag")]</li>
|
||||
</ul>"}
|
||||
</ul>"}
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
//Perform the connection
|
||||
connected_port = new_port
|
||||
connected_port.connected_device = src
|
||||
// To avoid a chicken-egg thing where pipes need to
|
||||
// be initialized before the atmos cans are
|
||||
if(!connected_port.parent)
|
||||
connected_port.build_network()
|
||||
connected_port.parent.reconcile_air()
|
||||
|
||||
anchored = 1 //Prevent movement
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
src.scanner = findscanner()
|
||||
releasecloner()
|
||||
findcloner()
|
||||
if(!selected_pod)
|
||||
if(!selected_pod && pods.len)
|
||||
selected_pod = pods[1]
|
||||
|
||||
/obj/machinery/computer/cloning/proc/findscanner()
|
||||
@@ -450,4 +450,4 @@
|
||||
return (scanner && scanner.scan_level > 2)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/can_brainscan()
|
||||
return (scanner && scanner.scan_level > 3)
|
||||
return (scanner && scanner.scan_level > 3)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
efficiency = C
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/initialize()
|
||||
..()
|
||||
if(node) return
|
||||
for(var/cdir in cardinal)
|
||||
node = findConnecting(cdir)
|
||||
@@ -495,4 +496,4 @@
|
||||
return
|
||||
|
||||
/datum/data/function/proc/display()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -135,6 +135,7 @@ obj/machinery/door/airlock/proc/set_frequency(new_frequency)
|
||||
|
||||
|
||||
obj/machinery/door/airlock/initialize()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
@@ -294,4 +295,4 @@ obj/machinery/access_button/airlock_interior
|
||||
|
||||
obj/machinery/access_button/airlock_exterior
|
||||
frequency = 1379
|
||||
command = "cycle_exterior"
|
||||
command = "cycle_exterior"
|
||||
|
||||
@@ -45,11 +45,13 @@
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
|
||||
air_update_turf(1)
|
||||
update_freelook_sight()
|
||||
airlocks += src
|
||||
return
|
||||
|
||||
/obj/machinery/door/initialize()
|
||||
air_update_turf(1)
|
||||
..()
|
||||
|
||||
/obj/machinery/door/Destroy()
|
||||
density = 0
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/spacepoddoor/New()
|
||||
/obj/structure/spacepoddoor/initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
@@ -21,4 +21,4 @@
|
||||
/obj/structure/spacepoddoor/CanPass(atom/movable/A, turf/T)
|
||||
if(istype(A, /obj/spacepod))
|
||||
return ..()
|
||||
else return 0
|
||||
else return 0
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/dye_color = "#FFFFFF"
|
||||
|
||||
/obj/machinery/dye_generator/initialize()
|
||||
..()
|
||||
power_change()
|
||||
|
||||
/obj/machinery/dye_generator/power_change()
|
||||
@@ -127,4 +128,4 @@
|
||||
var/b_skin = hex2num(copytext(dye_color, 6, 8))
|
||||
if(H.change_skin_color(r_skin, g_skin, b_skin))
|
||||
H.update_dna()
|
||||
user.visible_message("<span class='notice'>[user] finishes dying [M]'s [what_to_dye]!</span>", "<span class='notice'>You finish dying [M]'s [what_to_dye]!</span>")
|
||||
user.visible_message("<span class='notice'>[user] finishes dying [M]'s [what_to_dye]!</span>", "<span class='notice'>You finish dying [M]'s [what_to_dye]!</span>")
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/embedded_controller/attack_ghost(mob/user as mob)
|
||||
src.ui_interact(user)
|
||||
|
||||
src.ui_interact(user)
|
||||
|
||||
/obj/machinery/embedded_controller/attack_ai(mob/user as mob)
|
||||
src.ui_interact(user)
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
unacidable = 1
|
||||
|
||||
/obj/machinery/embedded_controller/radio/initialize()
|
||||
..()
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/embedded_controller/radio/update_icon()
|
||||
@@ -77,4 +78,4 @@
|
||||
/obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter)
|
||||
radio_connection = radio_controller.add_object(src, frequency, radio_filter)
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
|
||||
/obj/machinery/kitchen_machine/proc/has_extra_item()
|
||||
for(var/obj/O in contents)
|
||||
if ( \
|
||||
if( \
|
||||
!istype(O,/obj/item/weapon/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/weapon/grown) \
|
||||
)
|
||||
@@ -400,4 +400,4 @@
|
||||
|
||||
if("dispose")
|
||||
dispose()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -47,7 +47,7 @@ Class Variables:
|
||||
Currently unused.
|
||||
|
||||
Class Procs:
|
||||
New() 'game/machinery/machine.dm'
|
||||
initialize() 'game/machinery/machine.dm'
|
||||
|
||||
Destroy() 'game/machinery/machine.dm'
|
||||
|
||||
@@ -117,9 +117,10 @@ Class Procs:
|
||||
var/use_log = list()
|
||||
var/list/settagwhitelist = list()//WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST.
|
||||
|
||||
/obj/machinery/New()
|
||||
/obj/machinery/initialize()
|
||||
addAtProcessing()
|
||||
return ..()
|
||||
. = ..()
|
||||
power_change()
|
||||
|
||||
/obj/machinery/proc/addAtProcessing()
|
||||
if(use_power)
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
/obj/machinery/shield/New()
|
||||
src.dir = pick(1,2,3,4)
|
||||
..()
|
||||
|
||||
/obj/machinery/shield/initialize()
|
||||
air_update_turf(1)
|
||||
..()
|
||||
|
||||
/obj/machinery/shield/Destroy()
|
||||
opacity = 0
|
||||
@@ -605,4 +608,4 @@
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return prob(10)
|
||||
else
|
||||
return !src.density
|
||||
return !src.density
|
||||
|
||||
@@ -145,6 +145,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
listening_level = position.z
|
||||
|
||||
/obj/machinery/telecomms/initialize()
|
||||
..()
|
||||
if(autolinkers.len)
|
||||
// Links nearby machines
|
||||
if(!long_range_link)
|
||||
@@ -584,10 +585,3 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
var/name = "data packet (#)"
|
||||
var/garbage_collector = 1 // if set to 0, will not be garbage collected
|
||||
var/input_type = "Speech File"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
return
|
||||
|
||||
/obj/machinery/computer/teleporter/initialize()
|
||||
..()
|
||||
link_power_station()
|
||||
update_icon()
|
||||
|
||||
@@ -294,6 +295,7 @@
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/teleport/hub/initialize()
|
||||
..()
|
||||
link_power_station()
|
||||
|
||||
/obj/machinery/teleport/hub/Destroy()
|
||||
@@ -472,6 +474,7 @@
|
||||
link_console_and_hub()
|
||||
|
||||
/obj/machinery/teleport/station/initialize()
|
||||
..()
|
||||
link_console_and_hub()
|
||||
|
||||
/obj/machinery/teleport/station/RefreshParts()
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/turretid/initialize()
|
||||
..()
|
||||
if(!control_area)
|
||||
control_area = get_area(src)
|
||||
else if(istext(control_area))
|
||||
|
||||
@@ -31,11 +31,13 @@
|
||||
var/resintype = null
|
||||
smooth = SMOOTH_TRUE
|
||||
|
||||
|
||||
/obj/structure/alien/resin/New(location)
|
||||
..()
|
||||
/obj/structure/alien/resin/initialize()
|
||||
air_update_turf(1)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/alien/resin/Destroy()
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/alien/resin/Move()
|
||||
var/turf/T = loc
|
||||
|
||||
@@ -1075,7 +1075,7 @@ steam.start() -- spawns the effect
|
||||
desc = "A lightweight foamed metal wall."
|
||||
var/metal = MFOAM_ALUMINUM
|
||||
|
||||
/obj/structure/foamedmetal/New()
|
||||
/obj/structure/foamedmetal/initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/obj/effect/landmark/New()
|
||||
|
||||
..()
|
||||
tag = text("landmark*[]", name)
|
||||
set_tag()
|
||||
invisibility = 101
|
||||
|
||||
switch(name) //some of these are probably obsolete
|
||||
@@ -105,18 +105,19 @@
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/obj/effect/landmark/proc/set_tag()
|
||||
tag = text("landmark*[]", name)
|
||||
|
||||
|
||||
/obj/effect/landmark/start
|
||||
name = "start"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/landmark/start/New()
|
||||
..()
|
||||
/obj/effect/landmark/start/set_tag()
|
||||
tag = "start*[name]"
|
||||
invisibility = 101
|
||||
|
||||
return 1
|
||||
|
||||
//Costume spawner landmarks
|
||||
|
||||
@@ -260,4 +261,4 @@
|
||||
/obj/effect/landmark/costume/sexymime/New()
|
||||
new /obj/item/clothing/mask/gas/sexymime(src.loc)
|
||||
new /obj/item/clothing/under/sexymime(src.loc)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -151,6 +151,15 @@
|
||||
"" = 90
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/crate_spawner // for ruins
|
||||
name = "lootcrate spawner"
|
||||
lootdoubles = 0
|
||||
|
||||
loot = list(
|
||||
/obj/structure/closet/crate/secure/loot = 20,
|
||||
"" = 80,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/trade_sol_rare
|
||||
name = "trader rare item spawner"
|
||||
lootdoubles = 0
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
var/useFull = 0
|
||||
var/useGrille = 1
|
||||
var/windowtospawn = /obj/structure/window/basic
|
||||
anchored = 1 // No sliding out while you prime
|
||||
|
||||
/obj/effect/spawner/window/New()
|
||||
/obj/effect/spawner/window/initialize()
|
||||
spawn(0)
|
||||
for(var/obj/structure/grille/G in get_turf(src)) qdel(G) //just in case mappers don't know what they are doing
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/obj/structure/grille/G in get_turf(src))
|
||||
// Complain noisily
|
||||
log_debug("Extra grille on turf: ([T.x],[T.y],[T.z])")
|
||||
qdel(G) //just in case mappers don't know what they are doing
|
||||
|
||||
if(!useFull)
|
||||
for(var/cdir in cardinal)
|
||||
@@ -30,7 +35,8 @@
|
||||
spawn(10)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/spawner/window/reinforced
|
||||
name = "reinforced window spawner"
|
||||
icon_state = "rwindow_spawner"
|
||||
windowtospawn = /obj/structure/window/reinforced
|
||||
windowtospawn = /obj/structure/window/reinforced
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
var/health = 50.0
|
||||
|
||||
/obj/structure/inflatable/New(location)
|
||||
/obj/structure/inflatable/initialize(location)
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
|
||||
@@ -16,152 +16,155 @@
|
||||
var/hardness = 1
|
||||
var/oreAmount = 7
|
||||
|
||||
New(location)
|
||||
..()
|
||||
icon_state = mineralType
|
||||
name = "[mineralType] door"
|
||||
air_update_turf(1)
|
||||
/obj/structure/mineral_door/New(location)
|
||||
..()
|
||||
icon_state = mineralType
|
||||
name = "[mineralType] door"
|
||||
|
||||
Destroy()
|
||||
density = 0
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
/obj/structure/mineral_door/initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
Move()
|
||||
var/turf/T = loc
|
||||
..()
|
||||
move_update_air(T)
|
||||
/obj/structure/mineral_door/Destroy()
|
||||
density = 0
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
Bumped(atom/user)
|
||||
..()
|
||||
if(!state)
|
||||
return TryToSwitchState(user)
|
||||
return
|
||||
/obj/structure/mineral_door/Move()
|
||||
var/turf/T = loc
|
||||
..()
|
||||
move_update_air(T)
|
||||
|
||||
attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
|
||||
if(isAI(user)) //so the AI can't open it
|
||||
return
|
||||
else if(isrobot(user)) //but cyborgs can
|
||||
if(get_dist(user,src) <= 1) //not remotely though
|
||||
return TryToSwitchState(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
/obj/structure/mineral_door/Bumped(atom/user)
|
||||
..()
|
||||
if(!state)
|
||||
return TryToSwitchState(user)
|
||||
return
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group) return 0
|
||||
if(istype(mover, /obj/effect/beam))
|
||||
return !opacity
|
||||
return !density
|
||||
/obj/structure/mineral_door/attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
|
||||
if(isAI(user)) //so the AI can't open it
|
||||
return
|
||||
else if(isrobot(user)) //but cyborgs can
|
||||
if(get_dist(user,src) <= 1) //not remotely though
|
||||
return TryToSwitchState(user)
|
||||
|
||||
CanAtmosPass()
|
||||
return !density
|
||||
/obj/structure/mineral_door/attack_hand(mob/user as mob)
|
||||
return TryToSwitchState(user)
|
||||
|
||||
proc/TryToSwitchState(atom/user)
|
||||
if(isSwitchingStates) return
|
||||
if(ismob(user))
|
||||
var/mob/M = user
|
||||
if(world.time - user.last_bumped <= 60) return //NOTE do we really need that?
|
||||
if(M.client)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!C.handcuffed)
|
||||
SwitchState()
|
||||
else
|
||||
/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group) return 0
|
||||
if(istype(mover, /obj/effect/beam))
|
||||
return !opacity
|
||||
return !density
|
||||
|
||||
/obj/structure/mineral_door/CanAtmosPass()
|
||||
return !density
|
||||
|
||||
/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
|
||||
if(isSwitchingStates) return
|
||||
if(ismob(user))
|
||||
var/mob/M = user
|
||||
if(world.time - user.last_bumped <= 60) return //NOTE do we really need that?
|
||||
if(M.client)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!C.handcuffed)
|
||||
SwitchState()
|
||||
else if(istype(user, /obj/mecha))
|
||||
SwitchState()
|
||||
else
|
||||
SwitchState()
|
||||
else if(istype(user, /obj/mecha))
|
||||
SwitchState()
|
||||
|
||||
proc/SwitchState()
|
||||
if(state)
|
||||
Close()
|
||||
else
|
||||
Open()
|
||||
|
||||
proc/Open()
|
||||
isSwitchingStates = 1
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
|
||||
flick("[mineralType]opening",src)
|
||||
sleep(10)
|
||||
density = 0
|
||||
opacity = 0
|
||||
state = 1
|
||||
update_icon()
|
||||
isSwitchingStates = 0
|
||||
air_update_turf(1)
|
||||
|
||||
proc/Close()
|
||||
isSwitchingStates = 1
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
|
||||
flick("[mineralType]closing",src)
|
||||
sleep(10)
|
||||
density = 1
|
||||
opacity = 1
|
||||
state = 0
|
||||
update_icon()
|
||||
isSwitchingStates = 0
|
||||
air_update_turf(1)
|
||||
/obj/structure/mineral_door/proc/SwitchState()
|
||||
if(state)
|
||||
Close()
|
||||
else
|
||||
Open()
|
||||
|
||||
/obj/structure/mineral_door/proc/Open()
|
||||
isSwitchingStates = 1
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
|
||||
flick("[mineralType]opening",src)
|
||||
sleep(10)
|
||||
density = 0
|
||||
opacity = 0
|
||||
state = 1
|
||||
update_icon()
|
||||
if(state)
|
||||
icon_state = "[mineralType]open"
|
||||
else
|
||||
icon_state = mineralType
|
||||
isSwitchingStates = 0
|
||||
air_update_turf(1)
|
||||
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W,/obj/item/weapon/pickaxe))
|
||||
var/obj/item/weapon/pickaxe/digTool = W
|
||||
to_chat(user, "You start digging the [name].")
|
||||
if(do_after(user,digTool.digspeed*hardness, target = src) && src)
|
||||
to_chat(user, "You finished digging.")
|
||||
Dismantle()
|
||||
else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc?
|
||||
hardness -= W.force/100
|
||||
to_chat(user, "You hit the [name] with your [W.name]!")
|
||||
CheckHardness()
|
||||
else
|
||||
attack_hand(user)
|
||||
return
|
||||
/obj/structure/mineral_door/proc/Close()
|
||||
isSwitchingStates = 1
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
|
||||
flick("[mineralType]closing",src)
|
||||
sleep(10)
|
||||
density = 1
|
||||
opacity = 1
|
||||
state = 0
|
||||
update_icon()
|
||||
isSwitchingStates = 0
|
||||
air_update_turf(1)
|
||||
|
||||
proc/CheckHardness()
|
||||
if(hardness <= 0)
|
||||
/obj/structure/mineral_door/update_icon()
|
||||
if(state)
|
||||
icon_state = "[mineralType]open"
|
||||
else
|
||||
icon_state = mineralType
|
||||
|
||||
/obj/structure/mineral_door/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W,/obj/item/weapon/pickaxe))
|
||||
var/obj/item/weapon/pickaxe/digTool = W
|
||||
to_chat(user, "You start digging the [name].")
|
||||
if(do_after(user,digTool.digspeed*hardness, target = src) && src)
|
||||
to_chat(user, "You finished digging.")
|
||||
Dismantle()
|
||||
else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc?
|
||||
hardness -= W.force/100
|
||||
to_chat(user, "You hit the [name] with your [W.name]!")
|
||||
CheckHardness()
|
||||
else
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/structure/mineral_door/proc/CheckHardness()
|
||||
if(hardness <= 0)
|
||||
Dismantle(1)
|
||||
|
||||
/obj/structure/mineral_door/proc/Dismantle(devastated = 0)
|
||||
if(!devastated)
|
||||
if(mineralType == "metal")
|
||||
var/ore = /obj/item/stack/sheet/metal
|
||||
for(var/i = 1, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
|
||||
for(var/i = 1, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
if(mineralType == "metal")
|
||||
var/ore = /obj/item/stack/sheet/metal
|
||||
for(var/i = 3, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
|
||||
for(var/i = 3, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/mineral_door/ex_act(severity = 1)
|
||||
switch(severity)
|
||||
if(1)
|
||||
Dismantle(1)
|
||||
|
||||
proc/Dismantle(devastated = 0)
|
||||
if(!devastated)
|
||||
if(mineralType == "metal")
|
||||
var/ore = /obj/item/stack/sheet/metal
|
||||
for(var/i = 1, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
|
||||
for(var/i = 1, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
if(mineralType == "metal")
|
||||
var/ore = /obj/item/stack/sheet/metal
|
||||
for(var/i = 3, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
else
|
||||
var/ore = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
|
||||
for(var/i = 3, i <= oreAmount, i++)
|
||||
new ore(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
ex_act(severity = 1)
|
||||
switch(severity)
|
||||
if(1)
|
||||
if(2)
|
||||
if(prob(20))
|
||||
Dismantle(1)
|
||||
if(2)
|
||||
if(prob(20))
|
||||
Dismantle(1)
|
||||
else
|
||||
hardness--
|
||||
CheckHardness()
|
||||
if(3)
|
||||
hardness -= 0.1
|
||||
else
|
||||
hardness--
|
||||
CheckHardness()
|
||||
return
|
||||
if(3)
|
||||
hardness -= 0.1
|
||||
CheckHardness()
|
||||
return
|
||||
|
||||
/obj/structure/mineral_door/iron
|
||||
mineralType = "metal"
|
||||
@@ -285,4 +288,4 @@
|
||||
|
||||
CheckHardness()
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -338,10 +338,13 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
ini_dir = dir
|
||||
if(!color && !istype(src,/obj/structure/window/plasmabasic) && !istype(src,/obj/structure/window/plasmareinforced))
|
||||
color = color_windows(src)
|
||||
air_update_turf(1)
|
||||
update_nearby_icons()
|
||||
return
|
||||
|
||||
/obj/structure/window/initialize()
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/window/Destroy()
|
||||
density = 0
|
||||
air_update_turf(1)
|
||||
@@ -402,10 +405,13 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
/obj/structure/window/plasmabasic/New(Loc,re=0)
|
||||
..()
|
||||
ini_dir = dir
|
||||
air_update_turf(1)
|
||||
update_nearby_icons()
|
||||
return
|
||||
|
||||
/obj/structure/window/plasmabasic/initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
/obj/structure/window/plasmabasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > T0C + 32000)
|
||||
hit(round(exposed_volume / 1000), 0)
|
||||
@@ -433,10 +439,13 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
/obj/structure/window/plasmareinforced/New(Loc,re=0)
|
||||
..()
|
||||
ini_dir = dir
|
||||
air_update_turf(1)
|
||||
update_nearby_icons()
|
||||
return
|
||||
|
||||
/obj/structure/window/plasmareinforced/initialize()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
/obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
@@ -516,4 +525,4 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
toggle_tint()
|
||||
|
||||
/obj/machinery/button/windowtint/update_icon()
|
||||
icon_state = "light[active]"
|
||||
icon_state = "light[active]"
|
||||
|
||||
@@ -129,16 +129,17 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
|
||||
/turf/simulated/floor/proc/make_plating()
|
||||
return ChangeTurf(/turf/simulated/floor/plating)
|
||||
|
||||
/turf/simulated/floor/ChangeTurf(turf/simulated/floor/T)
|
||||
/turf/simulated/floor/ChangeTurf(turf/simulated/floor/T, defer_change = FALSE, keep_icon = TRUE)
|
||||
if(!istype(src,/turf/simulated/floor)) return ..() //fucking turfs switch the fucking src of the fucking running procs
|
||||
if(!ispath(T,/turf/simulated/floor)) return ..()
|
||||
var/old_icon = icon_regular_floor
|
||||
var/old_plating = icon_plating
|
||||
var/old_dir = dir
|
||||
var/turf/simulated/floor/W = ..()
|
||||
W.icon_regular_floor = old_icon
|
||||
W.icon_plating = old_plating
|
||||
W.dir = old_dir
|
||||
if(keep_icon)
|
||||
W.icon_regular_floor = old_icon
|
||||
W.icon_plating = old_plating
|
||||
W.dir = old_dir
|
||||
W.update_icon()
|
||||
return W
|
||||
|
||||
|
||||
@@ -62,4 +62,4 @@
|
||||
/turf/simulated/shuttle/floor4/vox //Vox skipjack floors
|
||||
name = "skipjack floor"
|
||||
oxygen = 0
|
||||
nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD
|
||||
nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD
|
||||
|
||||
+21
-12
@@ -156,9 +156,11 @@
|
||||
qdel(L)
|
||||
|
||||
//Creates a new turf
|
||||
/turf/proc/ChangeTurf(var/path)
|
||||
if(!path) return
|
||||
if(path == type) return src
|
||||
/turf/proc/ChangeTurf(path, defer_change = FALSE, keep_icon = TRUE)
|
||||
if(!path)
|
||||
return
|
||||
if(!use_preloader && path == type) // Don't no-op if the map loader requires it to be reconstructed
|
||||
return src
|
||||
var/old_opacity = opacity
|
||||
var/old_dynamic_lighting = dynamic_lighting
|
||||
var/list/old_affecting_lights = affecting_lights
|
||||
@@ -167,12 +169,10 @@
|
||||
|
||||
if(air_master)
|
||||
air_master.remove_from_active(src)
|
||||
|
||||
var/turf/W = new path(src)
|
||||
if(!defer_change)
|
||||
W.AfterChange()
|
||||
|
||||
if(istype(W, /turf/simulated))
|
||||
W:Assimilate_Air()
|
||||
W.RemoveLattice()
|
||||
W.blueprint_data = old_blueprint_data
|
||||
|
||||
for(var/turf/space/S in range(W,1))
|
||||
@@ -189,13 +189,22 @@
|
||||
else
|
||||
lighting_clear_overlays()
|
||||
|
||||
W.levelupdate()
|
||||
W.CalculateAdjacentTurfs()
|
||||
return W
|
||||
|
||||
if(!can_have_cabling())
|
||||
// I'm including `ignore_air` because BYOND lacks positional-only arguments
|
||||
/turf/proc/AfterChange(ignore_air, keep_cabling = FALSE) //called after a turf has been replaced in ChangeTurf()
|
||||
levelupdate()
|
||||
CalculateAdjacentTurfs()
|
||||
|
||||
if(!keep_cabling && !can_have_cabling())
|
||||
for(var/obj/structure/cable/C in contents)
|
||||
qdel(C)
|
||||
return W
|
||||
|
||||
/turf/simulated/AfterChange(ignore_air, keep_cabling = FALSE)
|
||||
..()
|
||||
RemoveLattice()
|
||||
if(!ignore_air)
|
||||
Assimilate_Air()
|
||||
|
||||
//////Assimilate Air//////
|
||||
/turf/simulated/proc/Assimilate_Air()
|
||||
@@ -404,4 +413,4 @@
|
||||
|
||||
/turf/proc/add_blueprints_preround(atom/movable/AM)
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
add_blueprints(AM)
|
||||
add_blueprints(AM)
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
qdel(I)
|
||||
|
||||
/obj/effect/buildmode_line
|
||||
var/image/I
|
||||
var/image/I
|
||||
var/client/cl
|
||||
|
||||
/obj/effect/buildmode_line/New(var/client/c, var/atom/atom_a, var/atom/atom_b, var/linename)
|
||||
@@ -101,13 +101,13 @@
|
||||
I = image('icons/misc/mark.dmi', src, "line", 19.0)
|
||||
var/x_offset = ((atom_b.x * 32) + atom_b.pixel_x) - ((atom_a.x * 32) + atom_a.pixel_x)
|
||||
var/y_offset = ((atom_b.y * 32) + atom_b.pixel_y) - ((atom_a.y * 32) + atom_a.pixel_y)
|
||||
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Translate(0, 16)
|
||||
M.Scale(1, sqrt((x_offset * x_offset) + (y_offset * y_offset)) / 32)
|
||||
M.Turn(90 - Atan2(x_offset, y_offset)) // So... You pass coords in order x,y to this version of atan2. It should be called acsc2.
|
||||
M.Translate(atom_a.pixel_x, atom_a.pixel_y)
|
||||
|
||||
|
||||
transform = M
|
||||
cl = c
|
||||
cl.images += I
|
||||
@@ -242,6 +242,7 @@
|
||||
if(FILL_BUILDMODE)
|
||||
to_chat(user, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
|
||||
to_chat(user, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
|
||||
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
|
||||
to_chat(user, "<span class='notice'>***********************************************************</span>")
|
||||
if(LINK_BUILDMODE)
|
||||
@@ -509,16 +510,20 @@
|
||||
cornerB = select_tile(get_turf(object))
|
||||
if(left_click) //rectangular
|
||||
if(cornerA && cornerB)
|
||||
if(!objholder)
|
||||
to_chat(user, "<span class='warning'>Select object type first.</span>")
|
||||
if(alt_click)
|
||||
empty_region(block(get_turf(cornerA),get_turf(cornerB)))
|
||||
deselect_region()
|
||||
else
|
||||
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
|
||||
if(ispath(objholder,/turf))
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.dir = build_dir
|
||||
deselect_region()
|
||||
if(!objholder)
|
||||
to_chat(user, "<span class='warning'>Select object type first.</span>")
|
||||
else
|
||||
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
|
||||
if(ispath(objholder,/turf))
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.dir = build_dir
|
||||
deselect_region()
|
||||
return
|
||||
|
||||
//Something wrong - Reset
|
||||
@@ -567,13 +572,13 @@
|
||||
if(P.id_tag && P.id_tag != 1 && alert(holder, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
|
||||
goto(line_jump)
|
||||
P.id_tag = M.id
|
||||
|
||||
|
||||
line_jump // For the goto
|
||||
valid_links = 0
|
||||
for(var/obj/effect/buildmode_line/L in link_lines)
|
||||
qdel(L)
|
||||
link_lines -= L
|
||||
|
||||
|
||||
if(istype(link_obj, /obj/machinery/door_control))
|
||||
var/obj/machinery/door_control/M = link_obj
|
||||
for(var/obj/machinery/door/airlock/P in range(M.range,M))
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/client/proc/map_template_load()
|
||||
set category = "Debug"
|
||||
set name = "Map Template - Place"
|
||||
set name = "Map template - Place"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/datum/map_template/template
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in map_templates
|
||||
@@ -16,22 +15,27 @@
|
||||
if(!T)
|
||||
return
|
||||
|
||||
if(!template.fits_in_map_bounds(T, centered = TRUE))
|
||||
to_chat(usr, "Map is too large to fit in bounds. Map's dimensions: ([template.width], [template.height])")
|
||||
return
|
||||
|
||||
var/list/preview = list()
|
||||
for(var/S in template.get_affected_turfs(T,centered = TRUE))
|
||||
preview += image('icons/turf/overlays.dmi',S,"greenOverlay")
|
||||
usr.client.images += preview
|
||||
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
template.load(T, centered = TRUE)
|
||||
message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</A>")
|
||||
var/timer = start_watch()
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has started to place the map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a></span>")
|
||||
if(template.load(T, centered = TRUE))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a>. Took [stop_watch(timer)]s.</span>")
|
||||
else
|
||||
to_chat(usr, "Failed to place map")
|
||||
usr.client.images -= preview
|
||||
|
||||
/client/proc/map_template_upload()
|
||||
set category = "Debug"
|
||||
set name = "Map Template - Upload"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
|
||||
if(!map)
|
||||
return
|
||||
@@ -39,7 +43,12 @@
|
||||
to_chat(usr, "Bad map file: [map]")
|
||||
return
|
||||
|
||||
var/timer = start_watch()
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has begun uploading a map template ([map])</span>")
|
||||
var/datum/map_template/M = new(map=map, rename="[map]")
|
||||
M.preload_size(map)
|
||||
map_templates[M.name] = M
|
||||
message_admins("[key_name_admin(usr)] has uploaded a map template ([map])")
|
||||
if(M.preload_size(map))
|
||||
to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])")
|
||||
map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map]). Took [stop_watch(timer)]s.</span>")
|
||||
else
|
||||
to_chat(usr, "Map template '[map]' failed to load properly")
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/obj/effect/landmark/corpse
|
||||
name = "Unknown"
|
||||
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
|
||||
var/mob_species = null //Set to make a mob of another race, currently used only in ruins
|
||||
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
|
||||
var/corpsesuit = null
|
||||
var/corpseshoes = null
|
||||
@@ -37,6 +38,8 @@
|
||||
M.real_name = src.name
|
||||
M.death(1) //Kills the new mob
|
||||
M.timeofdeath = timeofdeath
|
||||
if(src.mob_species)
|
||||
M.set_species(src.mob_species)
|
||||
if(src.corpseuniform)
|
||||
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
|
||||
if(src.corpsesuit)
|
||||
@@ -285,3 +288,10 @@
|
||||
corpseid = 1
|
||||
corpseidjob = "Commander"
|
||||
corpseidaccess = "Captain"
|
||||
|
||||
/obj/effect/landmark/corpse/abductor //Connected to ruins, for some reason?
|
||||
name = "abductor"
|
||||
mobname = "???"
|
||||
mob_species = "abductor"
|
||||
corpseuniform = /obj/item/clothing/under/color/grey
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
|
||||
@@ -9,30 +9,43 @@
|
||||
var/template_name = null
|
||||
var/datum/map_template/template = null
|
||||
var/centered = 1
|
||||
var/loaded = 0
|
||||
|
||||
/obj/effect/landmark/map_loader/New(loc, tname)
|
||||
/obj/effect/landmark/map_loader/New(turf/loc, tname)
|
||||
..()
|
||||
|
||||
if(tname)
|
||||
template_name = tname
|
||||
if(template_name)
|
||||
template = map_templates[template_name]
|
||||
|
||||
/obj/effect/landmark/map_loader/initialize()
|
||||
..()
|
||||
if(template)
|
||||
load(template)
|
||||
|
||||
/obj/effect/landmark/map_loader/set_tag()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/map_loader/proc/load(datum/map_template/t)
|
||||
spawn(1)
|
||||
if(!t)
|
||||
return
|
||||
t.load(get_turf(src), centered = centered)
|
||||
t.loaded++
|
||||
qdel(src)
|
||||
if(!t)
|
||||
return
|
||||
if(loaded) // I wanna be super sure this loads only once
|
||||
return
|
||||
loaded = 1
|
||||
var/turf/pos = get_turf(src)
|
||||
// Hop to nullspace so we don't get re-initialized by the map we're loading
|
||||
loc = null
|
||||
t.load(pos, centered = centered)
|
||||
t.loaded++
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/map_loader/random
|
||||
var/template_list = ""
|
||||
|
||||
/obj/effect/landmark/map_loader/random/New()
|
||||
/obj/effect/landmark/map_loader/random/initialize()
|
||||
..()
|
||||
if(template_list)
|
||||
template_name = safepick(splittext(template_list, ";"))
|
||||
template = map_templates[template_name]
|
||||
load(template)
|
||||
load(template)
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
//SS13 Optimized Map loader
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//As of 3.6.2016
|
||||
//global datum that will preload variables on atoms instanciation
|
||||
var/global/use_preloader = FALSE
|
||||
var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite
|
||||
// These regexes are global - meaning that starting the maploader again mid-load will
|
||||
// reset progress - which means we need to track our index per-map, or we'll
|
||||
// eternally recurse
|
||||
// /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g
|
||||
var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g")
|
||||
// /^[\s\n]+"?|"?[\s\n]+$|^"|"$/g
|
||||
var/static/regex/trimQuotesRegex = new/regex({"^\[\\s\n]+"?|"?\[\\s\n]+$|^"|"$"}, "g")
|
||||
// /^[\s\n]+|[\s\n]+$/
|
||||
var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g")
|
||||
var/static/list/modelCache = list()
|
||||
|
||||
/**
|
||||
* Construct the model map and control the loading process
|
||||
@@ -16,87 +28,156 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
|
||||
* 2) Read the map line by line, parsing the result (using parse_grid)
|
||||
*
|
||||
* If `measureOnly` is set, then no atoms will be created, and all this will do
|
||||
* is return the bounds after parsing the file
|
||||
*
|
||||
* If you need to freeze init while you're working, you can use the spacial allocator's
|
||||
* "add_dirt" and "remove_dirt" which will put initializations on hold until you say
|
||||
* the word. This is important for loading large maps such as the cyberiad, where
|
||||
* atmos will attempt to start before it's ready, causing runtimes galore if init is
|
||||
* allowed to romp unchecked.
|
||||
*/
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset = 0 as num, y_offset = 0 as num, z_offset as num, do_sleep = 1 as num)
|
||||
if(!z_offset)//what z_level we are creating the map on
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num)
|
||||
var/tfile = dmm_file//the map file we're creating
|
||||
var/fname = "Lambda"
|
||||
if(isfile(tfile))
|
||||
fname = "[tfile]"
|
||||
tfile = file2text(tfile)
|
||||
|
||||
if(!x_offset)
|
||||
x_offset = 1
|
||||
if(!y_offset)
|
||||
y_offset = 1
|
||||
if(!z_offset)
|
||||
z_offset = world.maxz + 1
|
||||
|
||||
var/quote = ascii2text(34)
|
||||
var/tfile = file2text(dmm_file)//the map file we're creating
|
||||
var/tfile_len = length(tfile)
|
||||
var/lpos = 1 // the models definition index
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//first let's map model keys (e.g "aa") to their contents (e.g /turf/space{variables})
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
var/list/grid_models = list()
|
||||
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))//the length of the model key (e.g "aa" or "aba")
|
||||
var/key_len = 0
|
||||
|
||||
//proceed line by line
|
||||
for(lpos=1; lpos<tfile_len; lpos=findtext(tfile,"\n",lpos,0)+1)
|
||||
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
|
||||
if(copytext(tline,1,2) != quote)//we reached the map "layout"
|
||||
break
|
||||
var/model_key = copytext(tline,2,2+key_len)
|
||||
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
|
||||
grid_models[model_key] = model_contents
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//now let's fill the map with turf and objects using the constructed model map
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//position of the currently processed square
|
||||
var/zcrd=-1
|
||||
var/ycrd=y_offset
|
||||
var/xcrd=x_offset
|
||||
var/dmm_suite/loaded_map/LM = new
|
||||
// This try-catch is used as a budget "Finally" clause, as the dirt count
|
||||
// needs to be reset
|
||||
var/watch = start_watch()
|
||||
log_debug("[measureOnly ? "Measuring" : "Loading"] map: [fname]")
|
||||
try
|
||||
LM.index = 1
|
||||
while(dmmRegex.Find(tfile, LM.index))
|
||||
LM.index = dmmRegex.next
|
||||
|
||||
for(var/zpos=findtext(tfile,"\n(1,1,",lpos,0);zpos!=0;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)) //in case there's several maps to load
|
||||
// "aa" = (/type{vars=blah})
|
||||
if(dmmRegex.group[1]) // Model
|
||||
var/key = dmmRegex.group[1]
|
||||
if(grid_models[key]) // Duplicate model keys are ignored in DMMs
|
||||
continue
|
||||
if(key_len != length(key))
|
||||
if(!key_len)
|
||||
key_len = length(key)
|
||||
else
|
||||
throw EXCEPTION("Inconsistant key length in DMM")
|
||||
if(!measureOnly)
|
||||
grid_models[key] = dmmRegex.group[2]
|
||||
|
||||
zcrd++
|
||||
world.maxz = max(world.maxz, zcrd+z_offset)//create a new z_level if needed
|
||||
// (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
|
||||
else if(dmmRegex.group[3]) // Coords
|
||||
if(!key_len)
|
||||
throw EXCEPTION("Coords before model definition in DMM")
|
||||
|
||||
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1) //copy the whole map grid
|
||||
var/z_depth = length(zgrid)
|
||||
var/xcrdStart = text2num(dmmRegex.group[3]) + x_offset - 1
|
||||
//position of the currently processed square
|
||||
var/xcrd
|
||||
var/ycrd = text2num(dmmRegex.group[4]) + y_offset - 1
|
||||
var/zcrd = text2num(dmmRegex.group[5]) + z_offset - 1
|
||||
|
||||
//if exceeding the world max x or y, increase it
|
||||
var/x_depth = length(copytext(zgrid,1,findtext(zgrid,"\n",2,0)))
|
||||
var/x_tilecount = x_depth/key_len
|
||||
if(world.maxx<x_tilecount)
|
||||
world.maxx=x_tilecount
|
||||
if(!measureOnly)
|
||||
if(zcrd > world.maxz)
|
||||
if(cropMap)
|
||||
continue
|
||||
else
|
||||
zlevels.increase_max_zlevel_to(zcrd) //create a new z_level if needed
|
||||
|
||||
var/y_depth = z_depth / (x_depth+1)//x_depth + 1 because we're counting the '\n' characters in z_depth
|
||||
if(world.maxy<y_depth)
|
||||
world.maxy=y_depth
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrdStart)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd)
|
||||
|
||||
//then proceed it line by line, starting from top
|
||||
ycrd = y_depth
|
||||
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
|
||||
|
||||
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1)
|
||||
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0))
|
||||
var/leadingBlanks = 0
|
||||
while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "")
|
||||
if(leadingBlanks > 1)
|
||||
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
|
||||
|
||||
//fill the current square using the model map
|
||||
xcrd=0
|
||||
if(!gridLines.len) // Skip it if only blank lines exist.
|
||||
continue
|
||||
|
||||
for(var/mpos in 1 to x_depth step key_len)
|
||||
xcrd++
|
||||
var/model_key = copytext(grid_line,mpos,mpos+key_len)
|
||||
parse_grid(grid_models[model_key], xcrd + x_offset, ycrd + y_offset, zcrd + z_offset, do_sleep)
|
||||
if(gridLines.len && gridLines[gridLines.len] == "")
|
||||
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
|
||||
|
||||
//reached end of current map
|
||||
if(gpos+x_depth+1>z_depth)
|
||||
break
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd)
|
||||
ycrd += gridLines.len - 1 // Start at the top and work down
|
||||
|
||||
ycrd--
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
if(!cropMap && ycrd > world.maxy)
|
||||
if(!measureOnly)
|
||||
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd)
|
||||
else
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], min(ycrd, world.maxy))
|
||||
|
||||
//reached End Of File
|
||||
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len)
|
||||
break
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
var/maxx = xcrdStart
|
||||
if(measureOnly)
|
||||
for(var/line in gridLines)
|
||||
maxx = max(maxx, xcrdStart + length(line) / key_len - 1)
|
||||
else
|
||||
for(var/line in gridLines)
|
||||
if(ycrd <= world.maxy && ycrd >= 1)
|
||||
xcrd = xcrdStart
|
||||
for(var/tpos = 1 to length(line) - key_len + 1 step key_len)
|
||||
if(xcrd > world.maxx)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxx = xcrd
|
||||
|
||||
if(xcrd >= 1)
|
||||
var/model_key = copytext(line, tpos, tpos + key_len)
|
||||
if(!grid_models[model_key])
|
||||
throw EXCEPTION("Undefined model key in DMM: [model_key]. Map file: [fname].")
|
||||
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd, LM)
|
||||
// After this call, it is NOT safe to reference `dmmRegex` without another call to
|
||||
// "Find" - we might've hit a map loader here and changed its state
|
||||
CHECK_TICK
|
||||
|
||||
maxx = max(maxx, xcrd)
|
||||
++xcrd
|
||||
--ycrd
|
||||
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx)
|
||||
|
||||
CHECK_TICK
|
||||
catch(var/exception/e)
|
||||
_preloader.reset()
|
||||
throw e
|
||||
|
||||
_preloader.reset()
|
||||
log_debug("Loaded map in [stop_watch(watch)]s.")
|
||||
qdel(LM)
|
||||
if(bounds[MAP_MINX] == 1.#INF) // Shouldn't need to check every item
|
||||
log_debug("Min x: bounds[MAP_MINX]")
|
||||
log_debug("Min y: bounds[MAP_MINY]")
|
||||
log_debug("Min z: bounds[MAP_MINZ]")
|
||||
log_debug("Max x: bounds[MAP_MAXX]")
|
||||
log_debug("Max y: bounds[MAP_MAXY]")
|
||||
log_debug("Max z: bounds[MAP_MAXZ]")
|
||||
return null
|
||||
else
|
||||
if(!measureOnly)
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/T = t
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(1,keep_cabling = TRUE)
|
||||
return bounds
|
||||
|
||||
/**
|
||||
* Fill a given tile with its area/turf/objects/mobs
|
||||
@@ -115,48 +196,60 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* 4) Instanciates the atom with its variables
|
||||
*
|
||||
*/
|
||||
/dmm_suite/proc/parse_grid(model as text, xcrd as num, ycrd as num, zcrd as num, do_sleep = 1)
|
||||
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num, dmm_suite/loaded_map/LM)
|
||||
/*Method parse_grid()
|
||||
- Accepts a text string containing a comma separated list of type paths of the
|
||||
same construction as those contained in a .dmm file, and instantiates them.
|
||||
*/
|
||||
|
||||
var/list/members = list()//will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes = list()//will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/members //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/cached = modelCache[model]
|
||||
var/index
|
||||
|
||||
if(cached)
|
||||
members = cached[1]
|
||||
members_attributes = cached[2]
|
||||
else
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
members = list()
|
||||
members_attributes = list()
|
||||
index = 1
|
||||
|
||||
var/index=1
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos= find_next_delimiter_position(model,old_position,",","{","}")//find next delimiter (comma here) that's not within {...}
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...}
|
||||
|
||||
var/full_def = copytext(model,old_position,dpos)//full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))//path definition, e.g /obj/foo/bar
|
||||
members.Add(atom_def)
|
||||
old_position = dpos + 1
|
||||
var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/variables_start = findtext(full_def, "{")
|
||||
var/atom_def = text2path(trim_text(copytext(full_def, 1, variables_start))) //path definition, e.g /obj/foo/bar
|
||||
old_position = dpos + 1
|
||||
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
|
||||
continue
|
||||
members.Add(atom_def)
|
||||
|
||||
var/variables_start = findtext(full_def,"{")
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
while(dpos != 0)
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
|
||||
CHECK_TICK
|
||||
while(dpos != 0)
|
||||
|
||||
modelCache[model] = list(members, members_attributes)
|
||||
|
||||
|
||||
////////////////
|
||||
@@ -165,24 +258,25 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
|
||||
//in case of multiples turfs on one tile,
|
||||
//will contains the images of all underlying turfs, to simulate the DMM multiple tiles piling
|
||||
var/list/turfs_underlays = list()
|
||||
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
|
||||
var/turf/crds = locate(xcrd,ycrd,zcrd)
|
||||
if(members[index] != /area/template_noop)
|
||||
// We assume `members[index]` is an area path, as above, yes? I will operate
|
||||
// on that assumption.
|
||||
if(!ispath(members[index], /area))
|
||||
throw EXCEPTION("Oh no, I thought this was an area!")
|
||||
|
||||
var/atom/instance
|
||||
_preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation
|
||||
instance = LM.area_path_to_real_area(members[index])
|
||||
|
||||
instance = locate(members[index])
|
||||
var/turf/crds = locate(xcrd,ycrd,zcrd)
|
||||
if(crds)
|
||||
instance.contents.Add(crds)
|
||||
|
||||
if(use_preloader && instance)
|
||||
_preloader.load(instance)
|
||||
members.Remove(members[index])
|
||||
|
||||
//then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect
|
||||
|
||||
@@ -198,18 +292,20 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
if(T)
|
||||
//if others /turf are presents, simulates the underlays piling effect
|
||||
index = first_turf_index + 1
|
||||
while(index <= members.len)
|
||||
turfs_underlays.Insert(1,image(T.icon,null,T.icon_state,T.layer,T.dir))//add the current turf image to the underlays list
|
||||
var/turf/UT = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
add_underlying_turf(UT,T,turfs_underlays)//simulates the DMM piling effect
|
||||
T = UT
|
||||
while(index <= members.len - 1) // Last item is an /area
|
||||
var/underlay
|
||||
if(istype(T, /turf)) // I blame this on the stupid clown who coded the BYOND map editor
|
||||
underlay = T.appearance
|
||||
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
if(ispath(members[index],/turf))
|
||||
T.underlays += underlay
|
||||
|
||||
index++
|
||||
|
||||
//finally instance all remainings objects/mobs
|
||||
for(index in 1 to first_turf_index - 1)
|
||||
for(index in 1 to first_turf_index-1)
|
||||
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
CHECK_TICK
|
||||
|
||||
////////////////
|
||||
//Helpers procs
|
||||
@@ -222,7 +318,13 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(T)
|
||||
instance = new path (T)//first preloader pass
|
||||
if(ispath(path, /turf))
|
||||
T.ChangeTurf(path, 1, 0)
|
||||
instance = T
|
||||
else if(ispath(path, /area))
|
||||
|
||||
else
|
||||
instance = new path (T)//first preloader pass
|
||||
|
||||
if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New()
|
||||
_preloader.load(instance)
|
||||
@@ -232,16 +334,11 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//text trimming (both directions) helper proc
|
||||
//optionally removes quotes before and after the text (for variable name)
|
||||
/dmm_suite/proc/trim_text(what as text,trim_quotes=0)
|
||||
while(length(what) && (findtext(what," ",1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what," ",length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
if(trim_quotes)
|
||||
while(length(what) && (findtext(what,quote,1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what,quote,length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
return what
|
||||
return trimQuotesRegex.Replace(what, "")
|
||||
else
|
||||
return trimRegex.Replace(what, "")
|
||||
|
||||
|
||||
//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape
|
||||
//returns 0 if reached the last delimiter
|
||||
@@ -313,14 +410,6 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
return to_return
|
||||
|
||||
//simulates the DM multiple turfs on one tile underlaying
|
||||
/dmm_suite/proc/add_underlying_turf(turf/placed,turf/underturf, list/turfs_underlays)
|
||||
if(underturf.density)
|
||||
placed.density = 1
|
||||
if(underturf.opacity)
|
||||
placed.opacity = 1
|
||||
placed.underlays += turfs_underlays
|
||||
|
||||
//atom creation method that preloads variables at creation
|
||||
/atom/New()
|
||||
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -336,6 +425,7 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//Preloader datum
|
||||
//////////////////
|
||||
|
||||
// This ain't re-entrant, but we had this before the maploader update
|
||||
/dmm_suite/preloader
|
||||
parent_type = /datum
|
||||
var/list/attributes
|
||||
@@ -349,11 +439,41 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite/preloader/proc/load(atom/what)
|
||||
for(var/attribute in attributes)
|
||||
what.vars[attribute] = attributes[attribute]
|
||||
var/value = attributes[attribute]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
what.vars[attribute] = value
|
||||
use_preloader = FALSE
|
||||
|
||||
// If the map loader fails, make this safe
|
||||
/dmm_suite/preloader/proc/reset()
|
||||
use_preloader = FALSE
|
||||
attributes = list()
|
||||
target_path = null
|
||||
|
||||
// A datum for use within the context of loading a single map,
|
||||
// so that one can have separate "unpowered" areas for ruins or whatever,
|
||||
// yet have a single area type for use of mapping, instead of creating
|
||||
// a new area type for each new ruin
|
||||
/dmm_suite/loaded_map
|
||||
parent_type = /datum
|
||||
var/list/area_list = list()
|
||||
var/index = 1 // To store the state of the regex
|
||||
|
||||
/dmm_suite/loaded_map/proc/area_path_to_real_area(area/A)
|
||||
if(!ispath(A, /area))
|
||||
throw EXCEPTION("Wrong argument to `area_path_to_real_area`")
|
||||
|
||||
if(!(A in area_list))
|
||||
if(initial(A.there_can_be_many))
|
||||
area_list[A] = new A
|
||||
else
|
||||
area_list[A] = locate(A)
|
||||
|
||||
return area_list[A]
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
/turf/template_noop
|
||||
name = "Turf Passthrough"
|
||||
name = "Turf Passthrough"
|
||||
|
||||
@@ -326,7 +326,7 @@ swapmap
|
||||
x2+=x1-1
|
||||
y2+=y1-1
|
||||
z2+=z1-1
|
||||
world.maxz=max(z2,world.maxz) // stretch z if necessary
|
||||
zlevels.increase_max_zlevel_to(z2) // stretch z if necessary
|
||||
if(!ischunk)
|
||||
swapmaps_loaded[src]=null
|
||||
swapmaps_byname[id]=src
|
||||
@@ -373,7 +373,7 @@ swapmap
|
||||
mz=max(mz,M.z2)
|
||||
world.maxx=mx
|
||||
world.maxy=my
|
||||
world.maxz=mz
|
||||
zlevels.cut_levels_downto(mz)
|
||||
|
||||
// save and delete
|
||||
proc/Unload()
|
||||
|
||||
@@ -54,9 +54,8 @@
|
||||
name = "space hotel pamphlet"
|
||||
info = "<h3>Welcome to Deep Space Hotel 419!</h3>Thank you for choosing our hotel. Simply hand your credit or debit card to the concierge and get your room key! To check out, hand your credit card back.<small><h4>Conditions:</h4><ul><li>The hotel is not responsible for any losses due to time or space anomalies.<li>The hotel is not responsible for events that occur outside of the hotel station, including, but not limited to, events that occur inside of dimensional pockets.<li>The hotel is not responsible for overcharging your account.<li>The hotel is not responsible for missing persons.<li>The hotel is not responsible for mind-altering effects due to drugs, magic, demons, or space worms.</ul></small>"
|
||||
|
||||
/obj/effect/landmark/map_loader/hotel_room/New()
|
||||
/obj/effect/landmark/map_loader/hotel_room/initialize()
|
||||
..()
|
||||
|
||||
// load and randomly assign rooms
|
||||
var/global/list/south_room_templates = list()
|
||||
var/global/list/north_room_templates = list()
|
||||
@@ -65,26 +64,27 @@
|
||||
if(!loaded)
|
||||
loaded = 1
|
||||
for(var/map in flist(path))
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
if(copytext(map, 1, 3) == "n_")
|
||||
north_room_templates += T
|
||||
else if(copytext(map, 1, 3) == "s_")
|
||||
south_room_templates += T
|
||||
else
|
||||
// omnidirectional rooms are randomly assigned
|
||||
if(prob(50))
|
||||
if(cmptext(copytext(map, length(map) - 3), ".dmm"))
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
if(copytext(map, 1, 3) == "n_")
|
||||
north_room_templates += T
|
||||
else
|
||||
else if(copytext(map, 1, 3) == "s_")
|
||||
south_room_templates += T
|
||||
else
|
||||
// omnidirectional rooms are randomly assigned
|
||||
if(prob(50))
|
||||
north_room_templates += T
|
||||
else
|
||||
south_room_templates += T
|
||||
|
||||
var/datum/map_template/M = safepick(dir == NORTH ? north_room_templates : south_room_templates)
|
||||
if(M)
|
||||
template = M
|
||||
load(M)
|
||||
if(dir == NORTH)
|
||||
north_room_templates -= M
|
||||
else
|
||||
south_room_templates -= M
|
||||
load(M)
|
||||
|
||||
// The door to a hotel room, but also metadata for the room itself
|
||||
/obj/machinery/door/unpowered/hotel_door
|
||||
@@ -305,4 +305,4 @@
|
||||
S.retal_target = target
|
||||
S.retal = 1
|
||||
|
||||
#undef CHECKOUT_TIME
|
||||
#undef CHECKOUT_TIME
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away_mission_config.txt")
|
||||
|
||||
// Call this before you remove the last dirt on a z level - that way, all objects
|
||||
// will have proper atmos and other important enviro things
|
||||
/proc/late_setup_level(turfs, smoothTurfs)
|
||||
var/total_timer = start_watch()
|
||||
var/subtimer = start_watch()
|
||||
if(!smoothTurfs)
|
||||
smoothTurfs = turfs
|
||||
|
||||
log_debug("Setting up atmos")
|
||||
if(air_master)
|
||||
air_master.setup_allturfs(turfs)
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Initializing lighting")
|
||||
for(var/turf/T in turfs)
|
||||
if(T.dynamic_lighting)
|
||||
T.lighting_build_overlays()
|
||||
for(var/obj/structure/cable/PC in T)
|
||||
makepowernet_for(PC)
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Smoothing tiles")
|
||||
for(var/turf/T in smoothTurfs)
|
||||
if(T.smooth)
|
||||
smooth_icon(T)
|
||||
@@ -16,20 +29,95 @@
|
||||
var/atom/A = R
|
||||
if(A.smooth)
|
||||
smooth_icon(A)
|
||||
if(istype(T, /turf/simulated/mineral)) // For the listening post, among other maps
|
||||
var/turf/simulated/mineral/MT = T
|
||||
MT.add_edges()
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
log_debug("Late setup finished - took [stop_watch(total_timer)]s")
|
||||
|
||||
/proc/empty_rect(low_x,low_y, hi_x,hi_y, z)
|
||||
var/timer = start_watch()
|
||||
log_debug("Emptying region: ([low_x], [low_y]) to ([hi_x], [hi_y]) on z '[z]'")
|
||||
empty_region(block(locate(low_x, low_y, z), locate(hi_x, hi_y, z)))
|
||||
log_debug("Took [stop_watch(timer)]s")
|
||||
|
||||
/proc/empty_region(list/turfs)
|
||||
for(var/thing in turfs)
|
||||
var/turf/T = thing
|
||||
for(var/otherthing in T)
|
||||
qdel(otherthing)
|
||||
T.ChangeTurf(/turf/space)
|
||||
|
||||
/proc/createRandomZlevel()
|
||||
if(awaydestinations.len) //crude, but it saves another var!
|
||||
return
|
||||
|
||||
var/list/potentialRandomZlevels = list()
|
||||
log_startup_progress("Searching for away missions...")
|
||||
var/list/Lines
|
||||
if(fexists("config/away_mission_config.txt"))
|
||||
Lines = file2list("config/away_mission_config.txt")
|
||||
else
|
||||
Lines = file2list("config/example/away_mission_config.txt")
|
||||
if(potentialRandomZlevels && potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away mission...")
|
||||
|
||||
if(!Lines.len) return
|
||||
var/map = pick(potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
var/zlev = zlevels.add_new_zlevel()
|
||||
zlevels.add_dirt(zlev)
|
||||
maploader.load_map(file, z_offset = zlev)
|
||||
late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev)))
|
||||
zlevels.remove_dirt(zlev)
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
|
||||
//map_transition_config.Add(AWAY_MISSION_LIST)
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
|
||||
/proc/createALLZlevels()
|
||||
if(awaydestinations.len) //crude, but it saves another var!
|
||||
return
|
||||
|
||||
if(potentialRandomZlevels && potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away missions...")
|
||||
|
||||
for(var/map in potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
log_startup_progress("Loading away mission: [map]")
|
||||
var/zlev = zlevels.add_new_zlevel()
|
||||
zlevels.add_dirt(zlev)
|
||||
maploader.load_map(file, z_offset = zlev)
|
||||
late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev)))
|
||||
zlevels.remove_dirt(zlev)
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
|
||||
//map_transition_config.Add(AWAY_MISSION_LIST)
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
watch = start_watch()
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
|
||||
/proc/generateMapList(filename)
|
||||
var/list/potentialMaps = list()
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
if(!Lines.len)
|
||||
return
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
continue
|
||||
@@ -42,38 +130,87 @@
|
||||
|
||||
var/pos = findtext(t, " ")
|
||||
var/name = null
|
||||
// var/value = null
|
||||
|
||||
if(pos)
|
||||
name = lowertext(copytext(t, 1, pos))
|
||||
// value = copytext(t, pos + 1)
|
||||
|
||||
else
|
||||
name = lowertext(t)
|
||||
|
||||
if(!name)
|
||||
continue
|
||||
|
||||
potentialRandomZlevels.Add(t)
|
||||
potentialMaps.Add(t)
|
||||
|
||||
return potentialMaps
|
||||
|
||||
|
||||
if(potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away mission...")
|
||||
/proc/seedRuins(z_level = 1, budget = 0, whitelist = /area/space, list/potentialRuins = space_ruins_templates)
|
||||
var/overall_sanity = 100
|
||||
var/ruins = potentialRuins.Copy()
|
||||
var/initialbudget = budget
|
||||
var/watch = start_watch()
|
||||
|
||||
var/map = pick(potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
maploader.load_map(file, do_sleep = 0)
|
||||
late_setup_level(block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz)))
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
log_startup_progress("Loading ruins...")
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
while(budget > 0 && overall_sanity > 0)
|
||||
// Pick a ruin
|
||||
var/datum/map_template/ruin/ruin = ruins[pick(ruins)]
|
||||
// Can we afford it
|
||||
if(ruin.cost > budget)
|
||||
overall_sanity--
|
||||
continue
|
||||
// If so, try to place it
|
||||
var/sanity = 100
|
||||
// And if we can't fit it anywhere, give up, try again
|
||||
|
||||
while(sanity > 0)
|
||||
sanity--
|
||||
var/turf/T = locate(rand(25, world.maxx - 25), rand(25, world.maxy - 25), z_level)
|
||||
var/valid = 1
|
||||
|
||||
for(var/turf/check in ruin.get_affected_turfs(T,1))
|
||||
var/area/new_area = get_area(check)
|
||||
if(!(istype(new_area, whitelist)))
|
||||
valid = 0
|
||||
break
|
||||
|
||||
if(!valid)
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
log_to_dd(" Ruin \"[ruin.name]\" loaded in [stop_watch(watch)]s at ([T.x], [T.y], [T.z]).")
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T)
|
||||
R.Load(ruins,ruin)
|
||||
budget -= ruin.cost
|
||||
if(!ruin.allow_duplicates)
|
||||
ruins -= ruin.name
|
||||
break
|
||||
|
||||
to_chat(world, "<span class='danger'> Loaded ruins. Or not.</span>") //So the players don't know if we loaded ruins, but we do have a message
|
||||
|
||||
if(initialbudget == budget) //Kill me
|
||||
log_to_dd(" No ruins loaded.")
|
||||
|
||||
|
||||
/obj/effect/ruin_loader
|
||||
name = "random ruin"
|
||||
desc = "If you got lucky enough to see this..."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "syndballoon"
|
||||
invisibility = 0
|
||||
|
||||
/obj/effect/ruin_loader/proc/Load(list/potentialRuins = space_ruins_templates, datum/map_template/template = null)
|
||||
var/list/possible_ruins = list()
|
||||
for(var/A in potentialRuins)
|
||||
var/datum/map_template/T = potentialRuins[A]
|
||||
if(!T.loaded)
|
||||
possible_ruins += T
|
||||
if(!template && possible_ruins.len)
|
||||
template = safepick(possible_ruins)
|
||||
if(!template)
|
||||
return 0
|
||||
template.load(get_turf(src),centered = 1)
|
||||
template.loaded++
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
/obj/effect/levelref/New()
|
||||
..()
|
||||
levels += src
|
||||
|
||||
/obj/effect/levelref/initialize()
|
||||
..()
|
||||
for(var/obj/effect/levelref/O in levels)
|
||||
if(id == O.id && O != src)
|
||||
other = O
|
||||
@@ -104,7 +107,7 @@
|
||||
/turf/unsimulated/floor/upperlevel/New()
|
||||
..()
|
||||
var/obj/effect/levelref/R = locate() in get_area(src)
|
||||
if(R)
|
||||
if(R && R.other)
|
||||
init(R)
|
||||
|
||||
/turf/unsimulated/floor/upperlevel/Destroy()
|
||||
@@ -159,6 +162,8 @@
|
||||
..()
|
||||
portals += src
|
||||
|
||||
/obj/effect/view_portal/initialize()
|
||||
..()
|
||||
if(id)
|
||||
for(var/obj/effect/view_portal/O in portals)
|
||||
if(id == O.id && O != src && can_link(O))
|
||||
@@ -361,4 +366,4 @@
|
||||
screen_loc = "CENTER[ox >= 0 ? "+" : ""][ox],CENTER[oy >= 0 ? "+" : ""][oy]"
|
||||
|
||||
/obj/effect/view_portal_dummy/attack_ghost(mob/user)
|
||||
owner.attack_ghost(user)
|
||||
owner.attack_ghost(user)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
/obj/item/weapon/storage/bible)
|
||||
|
||||
/obj/structure/bookcase/initialize()
|
||||
..()
|
||||
for(var/obj/item/I in loc)
|
||||
if(is_type_in_list(I, valid_types))
|
||||
I.forceMove(src)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
color = "#000000"
|
||||
icon_state = "light1"
|
||||
auto_init = 0 // doesn't need special init
|
||||
|
||||
var/lum_r
|
||||
var/lum_g
|
||||
@@ -104,4 +105,4 @@
|
||||
if(istype(T))
|
||||
T.lighting_overlay = null
|
||||
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/on=0
|
||||
|
||||
/obj/machinery/media/receiver/boombox/initialize()
|
||||
..()
|
||||
if(on)
|
||||
update_on()
|
||||
update_icon()
|
||||
@@ -80,4 +81,4 @@
|
||||
if(on)
|
||||
icon_state="wallradio-p"
|
||||
else
|
||||
icon_state="wallradio"
|
||||
icon_state="wallradio"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/const/MAX_TEMP=70 // Celsius
|
||||
|
||||
/obj/machinery/media/transmitter/broadcast/initialize()
|
||||
..()
|
||||
testing("[type]/initialize() called!")
|
||||
if(autolink && autolink.len)
|
||||
for(var/obj/machinery/media/source in orange(20, src))
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
|
||||
|
||||
/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if (!yes || ( \
|
||||
if(!yes || ( \
|
||||
!istype(AM,/obj/machinery/door) && \
|
||||
!istype(AM,/obj/machinery/recharge_station) && \
|
||||
!istype(AM,/obj/machinery/disposal/deliveryChute) && \
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
var/alerted = 0
|
||||
var/ore_eaten = 1
|
||||
var/chase_time = 100
|
||||
var/will_burrow = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/New()
|
||||
..()
|
||||
@@ -170,7 +171,7 @@
|
||||
visible_message("<span class='notice'>The ore was swallowed whole!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time
|
||||
if(!alerted)
|
||||
if(!alerted && will_burrow)
|
||||
alerted = 1
|
||||
spawn(chase_time)
|
||||
if(alerted)
|
||||
|
||||
@@ -99,11 +99,22 @@
|
||||
var/global/list/status_overlays_lighting
|
||||
var/global/list/status_overlays_environ
|
||||
var/indestructible = 0 // If set, prevents aliens from destroying it
|
||||
var/keep_preset_name = 0
|
||||
|
||||
var/report_power_alarm = 1
|
||||
|
||||
var/shock_proof = 0 //if set to 1, this APC will not arc bolts of electricity if it's overloaded.
|
||||
|
||||
/obj/machinery/power/apc/worn_out
|
||||
name = "\improper Worn out APC"
|
||||
keep_preset_name = 1
|
||||
locked = 0
|
||||
environ = 0
|
||||
equipment = 0
|
||||
lighting = 0
|
||||
operating = 0
|
||||
|
||||
|
||||
/obj/machinery/power/apc/noalarm
|
||||
report_power_alarm = 0
|
||||
|
||||
@@ -192,15 +203,19 @@
|
||||
cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively)
|
||||
cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value)
|
||||
|
||||
var/area/A = src.loc.loc
|
||||
var/area/A = get_area(src)
|
||||
|
||||
|
||||
//if area isn't specified use current
|
||||
if(isarea(A) && src.areastring == null)
|
||||
src.area = A
|
||||
if(keep_preset_name)
|
||||
if(isarea(A))
|
||||
area = A
|
||||
// no-op, keep the name
|
||||
else if(isarea(A) && src.areastring == null)
|
||||
area = A
|
||||
name = "\improper [area.name] APC"
|
||||
else
|
||||
src.area = get_area_name(areastring)
|
||||
area = get_area_name(areastring)
|
||||
name = "\improper [area.name] APC"
|
||||
area.apc |= src
|
||||
update_icon()
|
||||
@@ -623,7 +638,7 @@
|
||||
else
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return src.attack_hand(user)
|
||||
if (!opened && wiresexposed && \
|
||||
if(!opened && wiresexposed && \
|
||||
(istype(W, /obj/item/device/multitool) || \
|
||||
istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/assembly/signaler)))
|
||||
return src.attack_hand(user)
|
||||
@@ -853,7 +868,7 @@
|
||||
if(istype(user, /mob/living/silicon))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
var/mob/living/silicon/robot/robot = user
|
||||
if ( \
|
||||
if( \
|
||||
src.aidisabled || \
|
||||
malfhack && istype(malfai) && \
|
||||
( \
|
||||
@@ -1382,4 +1397,4 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
|
||||
@@ -82,6 +82,7 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/initialize()
|
||||
..()
|
||||
setup_parts()
|
||||
middle.overlays += "activated"
|
||||
update_list()
|
||||
@@ -215,17 +216,17 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
/obj/machinery/gravity_generator/main/attack_hand(mob/user as mob)
|
||||
if(!..())
|
||||
return interact(user)
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/attack_ai(mob/user as mob)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/attack_ghost(mob/user as mob)
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/gravity_generator/main/interact(mob/user as mob)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
|
||||
var/dat = "Gravity Generator Breaker: "
|
||||
if(breaker)
|
||||
dat += "<span class='linkOn'>ON</span> <A href='?src=\ref[src];gentoggle=1'>OFF</A>"
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
var/redeem_immediately = 0 // redeem immediately for holding cell
|
||||
|
||||
/obj/machinery/treadmill_monitor/initialize()
|
||||
..()
|
||||
if(id)
|
||||
for(var/obj/machinery/power/treadmill/T in machines)
|
||||
if(T.id == id)
|
||||
@@ -222,4 +223,4 @@
|
||||
#undef FONT_SIZE
|
||||
#undef FONT_COLOR
|
||||
#undef FONT_STYLE
|
||||
#undef CHARS_PER_LINE
|
||||
#undef CHARS_PER_LINE
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
return
|
||||
else
|
||||
return 1
|
||||
if ( \
|
||||
if( \
|
||||
!isturf(src.loc) || \
|
||||
!(locate(/obj/structure/table) in src.loc) && \
|
||||
!(locate(/obj/machinery/optable) in src.loc) && \
|
||||
@@ -712,6 +712,18 @@
|
||||
reagents.add_reagent("toxin", 3)
|
||||
bitesize = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/lizardmeat
|
||||
name = "mutant lizard meat"
|
||||
desc = "Seems to be a slab of meat from some mutant lizard thing?"
|
||||
icon_state = "xenomeat"
|
||||
filling_color = "#43DE18"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("protein", 3)
|
||||
reagents.add_reagent("toxin", 3)
|
||||
bitesize = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/spiderleg
|
||||
name = "spider leg"
|
||||
desc = "A still twitching leg of a giant spider... you don't really want to eat this, do you?"
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//Parent types
|
||||
|
||||
/area/ruin/
|
||||
name = "\improper Unexplored Location"
|
||||
icon_state = "away"
|
||||
has_gravity = 1
|
||||
there_can_be_many = 1
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
always_unpowered = 0
|
||||
|
||||
/area/ruin/unpowered/no_grav
|
||||
has_gravity = 0
|
||||
|
||||
/area/ruin/powered
|
||||
requires_power = 0
|
||||
|
||||
|
||||
|
||||
|
||||
//Areas
|
||||
|
||||
/area/ruin/unpowered/no_grav/way_home
|
||||
name = "\improper Salvation"
|
||||
icon_state = "away"
|
||||
|
||||
/area/ruin/powered/snow_biodome
|
||||
|
||||
/area/ruin/powered/golem_ship
|
||||
name = "Free Golem Ship"
|
||||
|
||||
// Ruins of "onehalf" ship
|
||||
/area/ruin/onehalf/hallway
|
||||
name = "Hallway"
|
||||
icon_state = "hallC"
|
||||
|
||||
|
||||
/area/ruin/onehalf/drone_bay
|
||||
name = "Mining Drone Bay"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/ruin/onehalf/dorms_med
|
||||
name = "Crew Quarters"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/ruin/onehalf/bridge
|
||||
name = "Bridge"
|
||||
icon_state = "bridge"
|
||||
@@ -843,7 +843,7 @@
|
||||
name = "\improper Airtight plastic flaps"
|
||||
desc = "Heavy duty, airtight, plastic flaps."
|
||||
|
||||
/obj/structure/plasticflaps/mining/New()
|
||||
/obj/structure/plasticflaps/mining/initialize()
|
||||
air_update_turf(1)
|
||||
..()
|
||||
|
||||
@@ -857,4 +857,4 @@
|
||||
#undef ORDER_SCREEN_WIDTH
|
||||
#undef ORDER_SCREEN_HEIGHT
|
||||
#undef SUPPLY_SCREEN_WIDTH
|
||||
#undef SUPPLY_SCREEN_HEIGHT
|
||||
#undef SUPPLY_SCREEN_HEIGHT
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/datum/zlevel
|
||||
var/flags = 0
|
||||
var/dirt_count = 0
|
||||
var/zpos
|
||||
var/list/init_list = list()
|
||||
|
||||
/datum/zlevel/New(z)
|
||||
zpos = z
|
||||
|
||||
/datum/zlevel/proc/resume_init()
|
||||
if(dirt_count > 0)
|
||||
throw EXCEPTION("Init told to resume when z-level still dirty. Z level: '[zpos]'")
|
||||
log_debug("Releasing freeze on z-level '[zpos]'!")
|
||||
log_debug("Beginning initialization!")
|
||||
var/list/our_atoms = init_list // OURS NOW!!! (Keeping this list to ourselves will prevent hijack)
|
||||
init_list = list()
|
||||
var/list/late_maps = list()
|
||||
var/list/pipes = list()
|
||||
var/list/cables = list()
|
||||
var/watch = start_watch()
|
||||
for(var/schmoo in our_atoms)
|
||||
var/atom/movable/AM = schmoo
|
||||
if(AM) // to catch stuff like the nuke disk that no longer exists
|
||||
|
||||
// This can mess with our state - we leave these for last
|
||||
if(istype(AM, /obj/effect/landmark/map_loader))
|
||||
late_maps.Add(AM)
|
||||
continue
|
||||
AM.initialize()
|
||||
if(istype(AM, /obj/machinery/atmospherics))
|
||||
pipes.Add(AM)
|
||||
else if(istype(AM, /obj/structure/cable))
|
||||
cables.Add(AM)
|
||||
log_debug("Primary initialization finished in [stop_watch(watch)]s.")
|
||||
our_atoms.Cut()
|
||||
if(pipes.len)
|
||||
do_pipes(pipes)
|
||||
if(cables.len)
|
||||
do_cables(cables)
|
||||
if(late_maps.len)
|
||||
do_late_maps(late_maps)
|
||||
|
||||
/datum/zlevel/proc/do_pipes(list/pipes)
|
||||
var/watch = start_watch()
|
||||
log_debug("Building pipenets on z-level '[zpos]'!")
|
||||
for(var/schmoo in pipes)
|
||||
var/obj/machinery/atmospherics/machine = schmoo
|
||||
if(machine)
|
||||
machine.build_network()
|
||||
pipes.Cut()
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
|
||||
/datum/zlevel/proc/do_cables(list/cables)
|
||||
var/watch = start_watch()
|
||||
log_debug("Building powernets on z-level '[zpos]'!")
|
||||
for(var/schmoo in cables)
|
||||
var/obj/structure/cable/C = schmoo
|
||||
if(C)
|
||||
makepowernet_for(C)
|
||||
cables.Cut()
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
|
||||
/datum/zlevel/proc/do_late_maps(list/late_maps)
|
||||
var/watch = start_watch()
|
||||
log_debug("Loading map templates on z-level '[zpos]'!")
|
||||
zlevels.add_dirt(zpos) // Let's not repeatedly resume init for each template
|
||||
for(var/schmoo in late_maps)
|
||||
var/obj/effect/landmark/map_loader/ML = schmoo
|
||||
if(ML)
|
||||
ML.initialize()
|
||||
late_maps.Cut()
|
||||
zlevels.remove_dirt(zpos)
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
@@ -0,0 +1,89 @@
|
||||
var/global/datum/zlev_manager/zlevels = new
|
||||
|
||||
/datum/zlev_manager
|
||||
// A list of z-levels
|
||||
var/list/z_list = list()
|
||||
|
||||
|
||||
// Populate our z level list
|
||||
/datum/zlev_manager/proc/initialize()
|
||||
z_list.len = world.maxz
|
||||
for(var/i = 1, i <= world.maxz, i++)
|
||||
z_list[i] = new /datum/zlevel(i)
|
||||
|
||||
|
||||
|
||||
/datum/zlev_manager/proc/get_zlev(z)
|
||||
if(z < 1)
|
||||
throw EXCEPTION("Non-positive z level given!")
|
||||
else if(z > z_list.len)
|
||||
throw EXCEPTION("Untracked z level: '[z]'")
|
||||
else
|
||||
return z_list[z]
|
||||
|
||||
// For when you need the z-level to be at a certain point
|
||||
/datum/zlev_manager/proc/increase_max_zlevel_to(new_maxz)
|
||||
if(world.maxz>=new_maxz)
|
||||
return
|
||||
while(world.maxz<new_maxz)
|
||||
add_new_zlevel()
|
||||
|
||||
// Increments the max z-level by one
|
||||
// For convenience's sake returns the z-level added
|
||||
/datum/zlev_manager/proc/add_new_zlevel()
|
||||
world.maxz++
|
||||
var/our_z = world.maxz
|
||||
z_list.len++
|
||||
z_list[our_z] = new /datum/zlevel(our_z)
|
||||
return our_z
|
||||
|
||||
/datum/zlev_manager/proc/cut_levels_downto(new_maxz)
|
||||
if(world.maxz <= new_maxz)
|
||||
return
|
||||
while(world.maxz>new_maxz)
|
||||
kill_topmost_zlevel()
|
||||
|
||||
// Decrements the max z-level by one
|
||||
// not normally used, but hey the swapmap loader wanted it
|
||||
/datum/zlev_manager/proc/kill_topmost_zlevel()
|
||||
var/our_z = world.maxz
|
||||
qdel(z_list[our_z])
|
||||
z_list.len--
|
||||
world.maxz--
|
||||
|
||||
/*
|
||||
* "Dirt" management
|
||||
* "Dirt" is used to keep track of whether a z level should automatically have
|
||||
* stuff on it initialize or not - the map loaders, when set to defer init, place
|
||||
* a freeze on the z levels they touch so as to prevent atmos from exploding,
|
||||
* among other things
|
||||
*/
|
||||
|
||||
|
||||
// Returns whether the given z level has a freeze on initialization
|
||||
/datum/zlev_manager/proc/is_zlevel_dirty(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
return (our_z.dirt_count > 0)
|
||||
|
||||
|
||||
// Increases the dirt count on a z level
|
||||
/datum/zlev_manager/proc/add_dirt(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
if(our_z.dirt_count == 0)
|
||||
log_debug("Placing an init freeze on z-level '[our_z.zpos]'!")
|
||||
our_z.dirt_count++
|
||||
|
||||
|
||||
// Decreases the dirt count on a z level
|
||||
/datum/zlev_manager/proc/remove_dirt(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
our_z.dirt_count--
|
||||
if(our_z.dirt_count == 0)
|
||||
our_z.resume_init()
|
||||
if(our_z.dirt_count < 0)
|
||||
log_debug("WARNING: Imbalanced dirt removal")
|
||||
our_z.dirt_count = 0
|
||||
|
||||
/datum/zlev_manager/proc/postpone_init(z, thing)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
our_z.init_list.Add(thing)
|
||||
Reference in New Issue
Block a user