Fixes conflict with explosives PR

This commit is contained in:
Kyep
2016-07-16 02:59:19 -07:00
240 changed files with 6053 additions and 1556 deletions
+2 -2
View File
@@ -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)
+30 -31
View File
@@ -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
+29 -42
View File
@@ -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
+4
View File
@@ -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
+12 -10
View File
@@ -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()
+2 -2
View File
@@ -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)
+19 -11
View File
@@ -16,6 +16,13 @@
#define DIAG_MECH_HUD "11"// Mech health bar
#define STATUS_HUD_OOC "12"// STATUS_HUD without virus db check for someone being ill.
#define DIAG_BOT_HUD "13"// Bot HUDS
#define PLANT_NUTRIENT_HUD "15"// Plant nutrient level
#define PLANT_WATER_HUD "16"// Plant water level
#define PLANT_STATUS_HUD "17"// Plant harvest/dead
#define PLANT_HEALTH_HUD "18"// Plant health
#define PLANT_TOXIN_HUD "19"// Toxin level
#define PLANT_PEST_HUD "20"// Pest level
#define PLANT_WEED_HUD "21"// Weed level
//for antag huds. these are used at the /mob level
#define SPECIALROLE_HUD "13"
@@ -28,16 +35,17 @@
#define DATA_HUD_MEDICAL_BASIC 3
#define DATA_HUD_MEDICAL_ADVANCED 4
#define DATA_HUD_DIAGNOSTIC 5
#define DATA_HUD_HYDROPONIC 6
//NATIONS
#define GAME_HUD_NATIONS 6
#define GAME_HUD_NATIONS 7
//antag HUD defines
#define ANTAG_HUD_CULT 7
#define ANTAG_HUD_REV 8
#define ANTAG_HUD_OPS 9
#define ANTAG_HUD_WIZ 10
#define ANTAG_HUD_SHADOW 11
#define ANTAG_HUD_TRAITOR 12
#define ANTAG_HUD_NINJA 13 //For Daves Rework
#define ANTAG_HUD_CHANGELING 14
#define ANTAG_HUD_VAMPIRE 15
#define ANTAG_HUD_ABDUCTOR 16 //For Fox
#define ANTAG_HUD_CULT 8
#define ANTAG_HUD_REV 9
#define ANTAG_HUD_OPS 10
#define ANTAG_HUD_WIZ 11
#define ANTAG_HUD_SHADOW 12
#define ANTAG_HUD_TRAITOR 13
#define ANTAG_HUD_NINJA 14 //For Daves Rework
#define ANTAG_HUD_CHANGELING 15
#define ANTAG_HUD_VAMPIRE 16
#define ANTAG_HUD_ABDUCTOR 17 //For Fox
+8
View File
@@ -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,\
+6 -2
View File
@@ -815,9 +815,13 @@ The _flatIcons list is a cache for generated icon files.
/proc/getHologramIcon(icon/A, safety=1)//If safety is on, a new icon is not created.
var/icon/flat_icon = safety ? A : new(A)//Has to be a new icon to not constantly change the same icon.
var/icon/alpha_mask
flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish.
flat_icon.ChangeOpacity(0.5)//Make it half transparent.
var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanline")//Scanline effect.
if(A.Height() == 64)
alpha_mask = new('icons/mob/ancient_machine.dmi', "scanline2")//Scaline for tall icons.
else
alpha_mask = new('icons/effects/effects.dmi', "scanline")//Scanline effect.
flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect.
return flat_icon
@@ -879,4 +883,4 @@ proc/sort_atoms_by_layer(var/list/atoms)
if(J) //Only set the icon if it succeeded, the icon without the pixel is 1000x better than a black square.
icon = J
return J
return 0
return 0
+10
View File
@@ -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
+6
View File
@@ -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)
+1 -1
View File
@@ -42,6 +42,6 @@ var/list/TAGGERLOCATIONS = list("Disposals",
"Atmospherics", "HoS Office", "Security", "Medbay",
"CMO Office", "Chemistry", "Research", "RD Office",
"Robotics", "HoP Office", "Library", "Chapel", "Captain's Office",
"Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics")
"Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics","Brig Physician")
var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")
+1 -2
View File
@@ -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()
+7
View File
@@ -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()
@@ -327,9 +327,7 @@
/datum/controller/process/proc/catchException(var/exception/e, var/thrower)
if(istype(e)) // Real runtimes go to the real error handler
// There are two newlines here, because handling desc sucks
e.desc = " Caught by process: [name]\n\n" + e.desc
world.Error(e, e_src = thrower)
log_runtime(e, thrower, "Caught by process: [name]")
return
var/etext = "[e]"
var/eid = "[e]" // Exception ID, for tracking repeated exceptions
+1 -1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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()
+6 -3
View File
@@ -18,9 +18,8 @@
var/log_adminwarn = 0 // log warnings admins get about bomb construction and such
var/log_pda = 0 // log pda messages
var/log_world_output = 0 // log world.log << messages
var/log_runtimes = 0 // Logs all runtimes.
var/log_runtimes = 0 // logs world.log to a file
var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits
var/log_runtime = 0 // logs world.log to a file
var/sql_enabled = 0 // for sql switching
var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
var/allow_vote_restart = 0 // allow votes to restart
@@ -168,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
@@ -288,7 +288,7 @@
config.log_hrefs = 1
if("log_runtime")
config.log_runtime = 1
config.log_runtimes = 1
if("mentors")
config.mods_are_mentors = 1
@@ -548,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
+16 -12
View File
@@ -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.")
+2 -2
View File
@@ -156,7 +156,7 @@
blacklist = null
whitelist = list(/obj/item/weapon/tank,/obj/item/weapon/reagent_containers,
/obj/item/stack/medical,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/gun/syringe,
/obj/item/weapon/c4,/obj/item/weapon/grenade,/obj/item/ammo_box,
/obj/item/weapon/grenade/plastic/c4,/obj/item/weapon/grenade,/obj/item/ammo_box,
/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/flamethrower, /obj/item/weapon/lighter,
/obj/item/weapon/match,/obj/item/weapon/weldingtool)
@@ -258,7 +258,7 @@
whitelist = list(/obj/item/weapon/banhammer,/obj/item/weapon/sord,/obj/item/weapon/claymore,/obj/item/weapon/holo/esword,
/obj/item/weapon/flamethrower,/obj/item/weapon/grenade,/obj/item/weapon/gun,/obj/item/weapon/hatchet,/obj/item/weapon/katana,
/obj/item/weapon/kitchen/knife,/obj/item/weapon/melee,/obj/item/weapon/nullrod,/obj/item/weapon/pickaxe,/obj/item/weapon/twohanded,
/obj/item/weapon/c4,/obj/item/weapon/scalpel,/obj/item/weapon/shield,/obj/item/weapon/grown/nettle/death)
/obj/item/weapon/grenade/plastic/c4,/obj/item/weapon/scalpel,/obj/item/weapon/shield,/obj/item/weapon/grown/nettle/death)
/datum/cargoprofile/tools
name = "Devices & Tools"
+13 -6
View File
@@ -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
+123 -29
View File
@@ -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
*/
+3 -2
View File
@@ -6,7 +6,8 @@ var/datum/atom_hud/huds = list( \
DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), \
DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), \
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), \
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(),
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), \
DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(), \
GAME_HUD_NATIONS = new/datum/atom_hud/antag(), \
ANTAG_HUD_CULT = new/datum/atom_hud/antag(), \
ANTAG_HUD_REV = new/datum/atom_hud/antag(), \
@@ -17,7 +18,7 @@ var/datum/atom_hud/huds = list( \
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden()\
)
/datum/atom_hud
+21
View File
@@ -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)
+162
View File
@@ -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."
+8
View File
@@ -1083,6 +1083,14 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 10
containername = "beekeeper suits"
//Bottler
/datum/supply_packs/organic/bottler
name = "Brewing Buddy Bottler Unit"
contains = list(/obj/machinery/bottler,
/obj/item/weapon/wrench)
cost = 35
containername = "bottler crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Materials ///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+10 -2
View File
@@ -953,11 +953,19 @@ var/list/uplink_items = list()
/datum/uplink_item/device_tools/plastic_explosives
name = "Composition C-4"
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaller to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds."
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect an assembly to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds."
reference = "C4"
item = /obj/item/weapon/c4
item = /obj/item/weapon/grenade/plastic/c4
cost = 1
/datum/uplink_item/device_tools/breaching_charge
name = "Composition X-4"
desc = "X-4 is a shaped charge designed to be safe to the user while causing maximum damage to the occupants of the room beach breached. It has a modifiable timer with a minimum setting of 10 seconds."
reference = "X4"
item = /obj/item/weapon/grenade/plastic/x4
cost = 2
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/powersink
name = "Power Sink"
desc = "When screwed to wiring attached to an electric grid, then activated, this large device places excessive load on the grid, causing a stationwide blackout. The sink cannot be carried because of its excessive size. Ordering this sends you a small beacon that will teleport the power sink to your location on activation."
-13
View File
@@ -17,19 +17,6 @@ var/const/WIRE_EXPLODE = 1
if(!mended)
explode()
/datum/wires/explosive/plastic
holder_type = /obj/item/weapon/c4
/datum/wires/explosive/plastic/CanUse(var/mob/living/L)
var/obj/item/weapon/c4/P = holder
if(P.open_panel)
return 1
return 0
/datum/wires/explosive/plastic/explode()
var/obj/item/weapon/c4/P = holder
P.explode(get_turf(P))
/datum/wires/explosive/gibtonite
holder_type = /obj/item/weapon/twohanded/required/gibtonite
+26 -14
View File
@@ -1577,11 +1577,11 @@ var/list/ghostteleportlocs = list()
/area/security/main
name = "\improper Security Office"
icon_state = "security"
icon_state = "securityoffice"
/area/security/lobby
name = "\improper Security Lobby"
icon_state = "security"
icon_state = "securitylobby"
/area/security/brig
name = "\improper Brig"
@@ -1597,7 +1597,7 @@ var/list/ghostteleportlocs = list()
/area/security/permabrig
name = "\improper Prison Wing"
icon_state = "sec_prison"
icon_state = "sec_prison_perma"
/area/security/prison
name = "\improper Prison Wing"
@@ -1617,11 +1617,11 @@ var/list/ghostteleportlocs = list()
/area/security/prison/cell_block/A
name = "\improper Prison Cell Block A"
icon_state = "brig"
icon_state = "brigcella"
/area/security/prison/cell_block/B
name = "\improper Prison Cell Block B"
icon_state = "brig"
icon_state = "brigcellb"
/area/security/prison/cell_block/C
name = "\improper Prison Cell Block C"
@@ -1629,15 +1629,27 @@ var/list/ghostteleportlocs = list()
/area/security/execution
name = "\improper Execution"
icon_state = "security"
icon_state = "execution"
/area/security/processing
name = "\improper Prisoner Processing"
icon_state = "security"
icon_state = "prisonerprocessing"
/area/security/interrogation
name = "\improper Interrogation"
icon_state = "security"
icon_state = "interrogation"
/area/security/seceqstorage
name = "\improper Security Equipment Storage"
icon_state = "securityequipmentstorage"
/area/security/interrogationhallway
name = "\improper Interrogation Hallway"
icon_state = "interrogationhall"
/area/security/courtroomdandp
name = "\improper Courtroom Defense and Prosecution"
icon_state = "seccourt"
/area/security/interrogationobs
name = "\improper Interrogation Observation"
@@ -1645,11 +1657,11 @@ var/list/ghostteleportlocs = list()
/area/security/evidence
name = "\improper Evidence Room"
icon_state = "security"
icon_state = "evidence"
/area/security/prisonlockers
name = "\improper Prisoner Lockers"
icon_state = "sec_prison"
icon_state = "sec_prison_lockers"
/area/security/medbay
name = "\improper Security Medbay"
@@ -1665,11 +1677,11 @@ var/list/ghostteleportlocs = list()
/area/security/armoury
name = "\improper Armory"
icon_state = "Warden"
icon_state = "armory"
/area/security/securearmoury
name = "\improper Secure Armory"
icon_state = "Warden"
icon_state = "secarmory"
/area/security/armoury/gamma
name = "\improper Gamma Armory"
@@ -1678,7 +1690,7 @@ var/list/ghostteleportlocs = list()
/area/security/securehallway
name = "\improper Security Secure Hallway"
icon_state = "security"
icon_state = "securehall"
/area/security/hos
name = "\improper Head of Security's Office"
@@ -1686,7 +1698,7 @@ var/list/ghostteleportlocs = list()
area/security/podbay
name = "\improper Security Podbay"
icon_state = "security"
icon_state = "securitypodbay"
/area/security/detectives_office
name = "\improper Detective's Office"
+10 -5
View File
@@ -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()
+2 -2
View File
@@ -70,7 +70,7 @@ var/global/max_secret_rooms = 6
walltypes = list(/turf/simulated/wall/cult=3,/turf/simulated/mineral/random/high_chance=1)
floortypes = list(/turf/simulated/floor/engine/cult)
treasureitems = list(/obj/item/device/soulstone=1, /obj/item/clothing/suit/space/cult=1, /obj/item/weapon/bedsheet/cult=2,
/obj/item/clothing/suit/cultrobes=2, /mob/living/simple_animal/hostile/creature=3)
/obj/item/clothing/suit/hooded/cultrobes=2, /mob/living/simple_animal/hostile/creature=3)
fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2,
/obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/woodentable=2,/obj/item/weapon/ectoplasm=3,
/obj/item/clothing/head/helmet/space/cult=1, /obj/item/clothing/shoes/cult=1)
@@ -209,4 +209,4 @@ var/global/max_secret_rooms = 6
emptyturfs -= T
//log_to_dd("The [theme] themed [T.loc] has been created!")
return 1
return 1
+15 -2
View File
@@ -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
+81
View File
@@ -46,6 +46,9 @@
/datum/atom_hud/data/diagnostic
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD)
/datum/atom_hud/data/hydroponic
hud_icons = list (PLANT_NUTRIENT_HUD, PLANT_WATER_HUD, PLANT_STATUS_HUD, PLANT_HEALTH_HUD, PLANT_TOXIN_HUD, PLANT_PEST_HUD, PLANT_WEED_HUD)
/* MED/SEC/DIAG HUD HOOKS */
/*
@@ -314,3 +317,81 @@
holder.icon_state = "hudmove"
else
holder.icon_state = ""
/*~~~~~~~~~~~~~~
PLANT HUD
~~~~~~~~~~~~~~~*/
/proc/RoundPlantBar(value)
switch(value * 100)
if(1 to 10)
return "10"
if(10 to 20)
return "20"
if(20 to 30)
return "30"
if(30 to 40)
return "40"
if(40 to 50)
return "50"
if(50 to 60)
return "60"
if(60 to 70)
return "70"
if(70 to 80)
return "80"
if(80 to 90)
return "90"
if(90 to INFINITY)
return "max"
else
return "zero"
return "zero"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_nutrient()
var/image/holder = hud_list[PLANT_NUTRIENT_HUD]
holder.icon_state = "hudnutrient[RoundPlantBar(nutrilevel/maxnutri)]"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_water()
var/image/holder = hud_list[PLANT_WATER_HUD]
holder.icon_state = "hudwater[RoundPlantBar(waterlevel/maxwater)]"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_status()
var/image/holder = hud_list[PLANT_STATUS_HUD]
if(!seed)
holder.icon_state = ""
return
if(harvest)
holder.icon_state = "hudharvest"
return
if(dead)
holder.icon_state = "huddead"
return
holder.icon_state = ""
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_health()
var/image/holder = hud_list[PLANT_HEALTH_HUD]
if(!seed)
holder.icon_state = ""
return
holder.icon_state = "hudplanthealth[RoundPlantBar(health/seed.get_trait(TRAIT_ENDURANCE))]"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_toxin()
var/image/holder = hud_list[PLANT_TOXIN_HUD]
if(toxins < 1) // You don't want to see these icons if the value is small
holder.icon_state = ""
return
holder.icon_state = "hudtoxin[RoundPlantBar(toxins/10)]"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_pest()
var/image/holder = hud_list[PLANT_PEST_HUD]
if(pestlevel < 1) // You don't want to see these icons if the value is small
holder.icon_state = ""
return
holder.icon_state = "hudpest[RoundPlantBar(pestlevel/10)]"
/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_weed()
var/image/holder = hud_list[PLANT_WEED_HUD]
if(weedlevel < 1) // You don't want to see these icons if the value is small
holder.icon_state = ""
return
holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]"
+6 -4
View File
@@ -43,20 +43,22 @@
icon_state = "cult_hoodalt"
item_state = "cult_hoodalt"
/obj/item/clothing/suit/cultrobes/alt
/obj/item/clothing/suit/hooded/cultrobes/alt
icon_state = "cultrobesalt"
item_state = "cultrobesalt"
hoodtype = /obj/item/clothing/head/culthood/alt
/obj/item/clothing/suit/cultrobes
/obj/item/clothing/suit/hooded/cultrobes
name = "cult robes"
desc = "A set of armored robes worn by the followers of Nar-Sie"
icon_state = "cultrobes"
item_state = "cultrobes"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
hoodtype = /obj/item/clothing/head/culthood
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade)
armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
flags_inv = HIDEJUMPSUIT
/obj/item/clothing/head/magus
name = "magus helm"
icon_state = "magus"
@@ -90,4 +92,4 @@
desc = "A bulky suit of armour, bristling with spikes. It looks space proof."
w_class = 3
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank)
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
+1 -2
View File
@@ -1032,8 +1032,7 @@ var/list/sacrificed = list()
usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \
"\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.")
user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head)
user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit)
user.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit)
user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes)
user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back)
//the above update their overlay icons cache but do not call update_icons()
+1 -2
View File
@@ -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
+2 -3
View File
@@ -493,8 +493,7 @@ var/global/list/multiverse = list()
M.equip_to_slot_or_del(sword, slot_r_hand)
if("cultist")
M.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(sword, slot_r_hand)
@@ -873,4 +872,4 @@ var/global/list/multiverse = list()
pump_delay = 60
heal_brute = 25
heal_burn = 25
heal_oxy = 25
heal_oxy = 25
+1
View File
@@ -225,6 +225,7 @@
air_alarm_repository.update_cache(src)
/obj/machinery/alarm/initialize()
..()
set_frequency(frequency)
if(!master_is_operating())
elect_master()
+2 -1
View File
@@ -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
+2 -2
View File
@@ -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)
+2 -1
View File
@@ -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
+1 -1
View File
@@ -997,7 +997,7 @@ About the new airlock wires panel:
if(istype(C, /obj/item/device/detective_scanner) || istype(C, /obj/item/taperoll))
return
if(istype(C, /obj/item/weapon/c4))
if(istype(C, /obj/item/weapon/grenade/plastic/c4))
to_chat(user, "The hatch is coated with a product that prevents the shaped charge from sticking!")
return
+2 -1
View File
@@ -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"
+3 -1
View File
@@ -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
+2 -2
View File
@@ -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
+2 -1
View File
@@ -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
+4 -3
View File
@@ -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)
+4 -1
View File
@@ -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"
+3
View 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()
+1 -1
View File
@@ -244,7 +244,7 @@
badcount++
for(var/obj/item/weapon/kitchen/knife/K in src.loc)
badcount++
for(var/obj/item/weapon/c4/KK in src.loc)
for(var/obj/item/weapon/grenade/plastic/c4/KK in src.loc)
badcount++
for(var/obj/item/weapon/melee/ML in src.loc)
badcount++
+1
View File
@@ -45,6 +45,7 @@
return ..()
/obj/machinery/turretid/initialize()
..()
if(!control_area)
control_area = get_area(src)
else if(istext(control_area))
+6 -4
View File
@@ -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
+1 -1
View File
@@ -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)
+7 -6
View File
@@ -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
+44 -42
View File
@@ -8,84 +8,86 @@
desc = "This is rubbish."
/obj/item/trash/raisins
name = "4no raisins"
icon_state= "4no_raisins"
name = "4no raisins"
icon_state= "4no_raisins"
/obj/item/trash/candy
name = "Candy"
icon_state= "candy"
name = "Candy"
icon_state= "candy"
/obj/item/trash/cheesie
name = "Cheesie honkers"
icon_state = "cheesie_honkers"
name = "Cheesie honkers"
icon_state = "cheesie_honkers"
/obj/item/trash/chips
name = "Chips"
icon_state = "chips"
name = "Chips"
icon_state = "chips"
/obj/item/trash/popcorn
name = "Popcorn"
icon_state = "popcorn"
name = "Popcorn"
icon_state = "popcorn"
/obj/item/trash/sosjerky
name = "Scaredy's Private Reserve Beef Jerky"
icon_state = "sosjerky"
name = "Scaredy's Private Reserve Beef Jerky"
icon_state = "sosjerky"
/obj/item/trash/syndi_cakes
name = "Syndi cakes"
icon_state = "syndi_cakes"
name = "Syndi cakes"
icon_state = "syndi_cakes"
/obj/item/trash/waffles
name = "Waffles"
icon_state = "waffles"
name = "Waffles"
icon_state = "waffles"
/obj/item/trash/plate
name = "Plate"
icon_state = "plate"
name = "Plate"
icon_state = "plate"
/obj/item/trash/snack_bowl
name = "Snack bowl"
icon_state = "snack_bowl"
name = "Snack bowl"
icon_state = "snack_bowl"
/obj/item/trash/pistachios
name = "Pistachios pack"
icon_state = "pistachios_pack"
name = "Pistachios pack"
icon_state = "pistachios_pack"
/obj/item/trash/semki
name = "Semki pack"
icon_state = "semki_pack"
name = "Semki pack"
icon_state = "semki_pack"
/obj/item/trash/tray
name = "Tray"
icon_state = "tray"
name = "Tray"
icon_state = "tray"
/obj/item/trash/candle
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
/obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration"
icon_state = "liquidfood"
name = "\improper \"LiquidFood\" ration"
icon_state = "liquidfood"
/obj/item/trash/can
name = "crushed can"
icon_state = "cola"
name = "crushed can"
icon_state = "cola"
var/is_glass = 0
var/is_plastic = 0
/obj/item/trash/gum
name = "chewed gum"
desc = "NOT free candy."
icon_state = "gum"
name = "chewed gum"
desc = "NOT free candy."
icon_state = "gum"
/obj/item/trash/tastybread
name = "bread tube"
icon_state = "tastybread"
name = "bread tube"
icon_state = "tastybread"
/obj/item/trash/tapetrash
name = "old duct tape"
icon_state = "tape"
desc = "Not sticky anymore."
throw_range = 1
name = "old duct tape"
icon_state = "tape"
desc = "Not sticky anymore."
throw_range = 1
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
return
+195 -86
View File
@@ -1,31 +1,96 @@
/obj/item/weapon/c4
name = "plastic explosives"
/obj/item/weapon/grenade/plastic
name = "plastic explosive"
desc = "Used to put holes in specific areas without too much extra hole."
gender = PLURAL
icon = 'icons/obj/assemblies.dmi'
icon_state = "plastic-explosive0"
item_state = "plasticx"
item_state = "plastic-explosive"
flags = NOBLUDGEON
w_class = 2
det_time = 10
display_timer = 0
origin_tech = "syndicate=2"
var/datum/wires/explosive/plastic/wires = null
var/timer = 10
var/atom/target = null
var/open_panel = 0
var/image_overlay = null
var/obj/item/device/assembly_holder/nadeassembly = null
var/assemblyattacher
/obj/item/weapon/c4/New()
wires = new(src)
/obj/item/weapon/grenade/plastic/New()
image_overlay = image('icons/obj/grenade.dmi', "[item_state]2")
..()
/obj/item/weapon/c4/Destroy()
qdel(wires)
wires = null
/obj/item/weapon/grenade/plastic/Destroy()
qdel(nadeassembly)
nadeassembly = null
target = null
return ..()
..()
/obj/item/weapon/c4/suicide_act(var/mob/user)
. = (BRUTELOSS)
to_chat(viewers(user), "<span class='suicide'>[user] activates the C4 and holds it above his head! It looks like \he's going out with a bang!</span>")
/obj/item/weapon/grenade/plastic/attackby(obj/item/I, mob/user, params)
if(!nadeassembly && istype(I, /obj/item/device/assembly_holder))
var/obj/item/device/assembly_holder/A = I
if(!user.unEquip(I))
return ..()
nadeassembly = A
A.master = src
A.loc = src
assemblyattacher = user.ckey
to_chat(user, "<span class='notice'>You add [A] to the [name].</span>")
playsound(src, 'sound/weapons/tap.ogg', 20, 1)
update_icon()
return
if(nadeassembly && istype(I, /obj/item/weapon/wirecutters))
playsound(src, 'sound/items/Wirecutter.ogg', 20, 1)
nadeassembly.loc = get_turf(src)
nadeassembly.master = null
nadeassembly = null
update_icon()
return
..()
//assembly stuff
/obj/item/weapon/grenade/plastic/receive_signal()
prime()
/obj/item/weapon/grenade/plastic/Crossed(atom/movable/AM)
if(nadeassembly)
nadeassembly.Crossed(AM)
/obj/item/weapon/grenade/plastic/on_found(mob/finder)
if(nadeassembly)
nadeassembly.on_found(finder)
/obj/item/weapon/grenade/plastic/attack_self(mob/user)
if(nadeassembly)
nadeassembly.attack_self(user)
return
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
if(user.get_active_hand() == src)
newtime = Clamp(newtime, 10, 60000)
det_time = newtime
to_chat(user, "Timer set for [det_time] seconds.")
/obj/item/weapon/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag)
if (!flag)
return
if (istype(AM, /mob/living/carbon))
return
to_chat(user, "<span class='notice'>You start planting the [src]. The timer is set to [det_time]...</span>")
if(do_after(user, 50, target = AM))
if(!user.unEquip(src))
return
src.target = AM
loc = null
message_admins("[key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse",0,1)
log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse")
target.overlays += image_overlay
if(!nadeassembly)
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
addtimer(src, "prime", det_time*10)
/obj/item/weapon/grenade/plastic/suicide_act(mob/user)
message_admins("[key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) suicided with [src.name] at ([user.x],[user.y],[user.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",0,1)
message_admins("[key_name(user)] suicided with [name] at ([user.x],[user.y],[user.z])")
user.visible_message("<span class='suicide'>[user] activates the [name] and holds it above \his head! It looks like \he's going out with a bang!</span>")
var/message_say = "FOR NO RAISIN!"
if(user.mind)
if(user.mind.special_role)
@@ -44,81 +109,125 @@
message_say = "FOR THE REVOLOUTION!"
else if(role == "death commando" || role == ROLE_ERT)
message_say = "FOR NANOTRASEN!"
user.say(message_say)
target = user
message_admins("[key_name_admin(user)] suicided with [src.name] at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
message_admins("[key_name(user)] suicided with [src.name] at ([x],[y],[z])")
explode(get_turf(user))
return .
sleep(10)
prime()
user.gib()
/obj/item/weapon/c4/attackby(var/obj/item/I, var/mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
open_panel = !open_panel
to_chat(user, "<span class='notice'>You [open_panel ? "open" : "close"] the wire panel.</span>")
else if(istype(I, /obj/item/weapon/wirecutters) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler ))
wires.Interact(user)
/obj/item/weapon/grenade/plastic/update_icon()
if(nadeassembly)
icon_state = "[item_state]1"
else
..()
icon_state = "[item_state]0"
/obj/item/weapon/c4/attack_self(mob/user as mob)
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num|null
if(newtime == null)
return
if(newtime < 10)
newtime = 10
if(newtime > 60000)
newtime = 60000
timer = newtime
to_chat(user, "Timer set for [timer] seconds.")
//////////////////////////
///// The Explosives /////
//////////////////////////
/obj/item/weapon/grenade/plastic/c4
name = "C4"
desc = "Used to put holes in specific areas without too much extra hole. A saboteurs favourite."
/obj/item/weapon/c4/afterattack(atom/target as obj|turf, mob/user as mob, flag)
if(!flag)
return
if(ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage) || istype(target, /obj/item/clothing/accessory/storage) || istype(target, /obj/item/clothing/under))
return
to_chat(user, "Planting explosives...")
if(do_after(user, 50, target = target) && in_range(user, target))
user.drop_item()
src.target = target
loc = null
if(ismob(target))
add_logs(target, user, "planted [name] on")
user.visible_message("\red [user.name] finished planting an explosive on [target.name]!")
message_admins("[key_name_admin(user)] planted [src.name] on [key_name_admin(target)] with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse")
else
message_admins("[key_name_admin(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2")
to_chat(user, "Bomb has been planted. Timer counting down from [timer].")
spawn(timer*10)
explode(get_turf(target))
/obj/item/weapon/c4/proc/explode(var/location)
if(!target)
target = get_atom_on_turf(src)
if(!target)
target = src
if(location)
explosion(location, -1, -1, 4, 4)
/obj/item/weapon/grenade/plastic/c4/prime()
var/turf/location
if(target)
if(istype(target, /turf/simulated/wall))
var/turf/simulated/wall/W = target
W.dismantle_wall(1)
else
target.ex_act(1)
if(isobj(target))
if(target)
qdel(target)
if(!qdeleted(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
location.ex_act(2, target)
explosion(location,0,0,3)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/weapon/c4/attack(mob/M as mob, mob/user as mob, def_zone)
return
// X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of.
// C4 is intended to be used for infiltration, and destroying tech. X4 is intended to be used for heavy breaching and tight spaces.
// Intended to replace C4 for nukeops, and to be a randomdrop in surplus/random traitor purchases.
/obj/item/weapon/grenade/plastic/x4
name = "X4"
desc = "A specialized shaped high explosive breaching charge. Designed to be safer for the user, and less so, for the wall."
var/aim_dir = NORTH
icon_state = "plasticx40"
item_state = "plasticx4"
/obj/item/weapon/grenade/plastic/x4/prime()
var/turf/location
if(target)
if(!qdeleted(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
explosion(T,0,2,0)
location.ex_act(2, target)
else
explosion(location, 0, 2, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/weapon/grenade/plastic/x4/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
// Shaped charge
// Same blasting power as C4, but with the same idea as the X4 -- Everyone on one side of the wall is safe.
/obj/item/weapon/grenade/plastic/c4_shaped
name = "C4 (shaped)"
desc = "A brick of C4 shaped to allow more precise breaching."
var/aim_dir = NORTH
/obj/item/weapon/grenade/plastic/c4_shaped/prime()
var/turf/location
if(target)
if(!qdeleted(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
location.ex_act(2, target)
else
explosion(location, 0, 0, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/weapon/grenade/plastic/c4_shaped/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
/obj/item/weapon/grenade/plastic/c4_shaped/flash
name = "C4 (flash)"
desc = "A C4 charge with an altered chemical composition, designed to blind and deafen the occupants of a room before breaching."
/obj/item/weapon/grenade/plastic/c4_shaped/flash/prime()
if(target && target.density)
T = get_step(get_turf(target), aim_dir)
else if(target)
T = get_turf(target)
else
T = get_turf(src)
var/obj/item/weapon/grenade/flashbang/CB = new/obj/item/weapon/grenade/flashbang(T)
CB.prime()
..()
@@ -20,10 +20,19 @@
if(!user.IsAdvancedToolUser())
return
if(!istype(C))
return
if(CLUMSY in user.mutations && prob(50))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user,user)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!(H.get_organ("l_hand") || H.get_organ("r_hand")))
to_chat(user, "<span class='warning'>How do you suggest handcuffing someone with no hands?</span>")
return
if(!C.handcuffed)
C.visible_message("<span class='danger'>[user] is trying to put [src.name] on [C]!</span>", \
"<span class='userdanger'>[user] is trying to put [src.name] on [C]!</span>")
@@ -117,6 +126,11 @@
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user)
if(isrobot(user))
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!(H.get_organ("l_hand") || H.get_organ("r_hand")))
to_chat(user, "<span class='warning'>How do you suggest handcuffing someone with no hands?</span>")
return
if(!C.handcuffed)
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[user] is trying to put zipties on [C]!</span>", \
@@ -192,7 +192,6 @@
/obj/item/weapon/storage/fancy/cigarettes/update_icon()
icon_state = "[initial(icon_state)][contents.len]"
desc = "There are [contents.len] cig\s left!"
return
/obj/item/weapon/storage/fancy/cigarettes/proc/lace_cigarette(var/obj/item/clothing/mask/cigarette/C as obj)
@@ -386,4 +385,4 @@
new /obj/item/weapon/egg_scoop(src)
new /obj/item/weapon/fish_net(src)
new /obj/item/weapon/tank_brush(src)
new /obj/item/weapon/fishfood(src)
new /obj/item/weapon/fishfood(src)
@@ -37,7 +37,7 @@
new /obj/item/weapon/gun/projectile/revolver(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/weapon/card/emag(src)
new /obj/item/weapon/c4(src)
new /obj/item/weapon/grenade/plastic/c4(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit_jacket/really_black(src)
@@ -13,10 +13,8 @@
..()
new /obj/item/clothing/under/rank/chaplain(src)
new /obj/item/clothing/shoes/black(src)
new /obj/item/clothing/suit/nun(src)
new /obj/item/clothing/head/nun_hood(src)
new /obj/item/clothing/suit/chaplain_hoodie(src)
new /obj/item/clothing/head/chaplain_hood(src)
new /obj/item/clothing/suit/hooded/nun(src)
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/clothing/suit/holidaypriest(src)
new /obj/item/clothing/under/wedding/bride_white(src)
new /obj/item/weapon/storage/backpack/cultpack (src)
@@ -28,4 +26,4 @@
new /obj/item/clothing/gloves/ring/silver(src)
new /obj/item/clothing/gloves/ring/silver(src)
new /obj/item/clothing/gloves/ring/gold(src)
new /obj/item/clothing/gloves/ring/gold(src)
new /obj/item/clothing/gloves/ring/gold(src)
@@ -15,6 +15,7 @@
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
new /obj/item/weapon/storage/backpack/duffel/engineering(src)
new /obj/item/clothing/head/beret/ce(src)
new /obj/item/areaeditor/blueprints(src)
new /obj/item/weapon/storage/box/permits(src)
new /obj/item/clothing/under/rank/chief_engineer(src)
@@ -141,4 +142,4 @@
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
new /obj/item/weapon/watertank/atmos(src)
new /obj/item/clothing/suit/fire/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
+1 -1
View File
@@ -25,7 +25,7 @@
var/health = 50.0
/obj/structure/inflatable/New(location)
/obj/structure/inflatable/initialize(location)
..()
air_update_turf(1)
+133 -130
View File
@@ -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)
..()
..()
+13 -4
View File
@@ -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]"
+22 -20
View File
@@ -75,24 +75,24 @@ var/ert_request_answered = 0
/mob/dead/observer/proc/JoinResponseTeam()
if(!send_emergency_team)
to_chat(usr, "No emergency response team is currently being sent.")
to_chat(src, "No emergency response team is currently being sent.")
return 0
if(jobban_isbanned(usr, ROLE_ERT))
to_chat(usr, "<span class='warning'>You are jobbanned from the emergency reponse team!</span>")
if(jobban_isbanned(src, ROLE_ERT))
to_chat(src, "<span class='warning'>You are jobbanned from the emergency reponse team!</span>")
return 0
var/player_age_check = check_client_age(usr.client, responseteam_age)
var/player_age_check = check_client_age(src.client, responseteam_age)
if(player_age_check && config.use_age_restriction_for_antags)
to_chat(usr, "<span class='warning'>This role is not yet available to you. You need to wait another [player_age_check] days.</span>")
to_chat(src, "<span class='warning'>This role is not yet available to you. You need to wait another [player_age_check] days.</span>")
return 0
if(src.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
to_chat(usr, "\blue <B>Upon using the antagHUD you forfeited the ability to join the round.</B>")
to_chat(src, "\blue <B>Upon using the antagHUD you forfeited the ability to join the round.</B>")
return 0
if(response_team_members.len > 6)
to_chat(usr, "The emergency response team is already full!")
to_chat(src, "The emergency response team is already full!")
return 0
for(var/obj/effect/landmark/L in landmarks_list)
@@ -100,12 +100,13 @@ var/ert_request_answered = 0
L.name = null
if(!src.client)
return
var/client/C = src.client
var/mob/living/carbon/human/new_commando = C.create_response_team(L.loc)
qdel(L)
new_commando.mind.key = usr.key
new_commando.key = usr.key
new_commando.update_icons()
spawn(-1)
var/client/C = src.client
var/mob/living/carbon/human/new_commando = C.create_response_team(L.loc)
qdel(L)
new_commando.mind.key = src.key
new_commando.key = src.key
new_commando.update_icons()
return 1
/proc/trigger_armed_response_team(var/datum/response_team/response_team_type)
@@ -132,7 +133,14 @@ var/ert_request_answered = 0
var/obj/item/organ/external/head/head_organ = M.get_organ("head")
response_team_members |= M
var/new_gender = alert(usr, "Please select your gender.", "Character Generation", "Male", "Female")
var/new_gender = alert(src, "Please select your gender.", "ERT Character Generation", "Male", "Female")
var/class = 0
while(!class)
class = input(src, "Which loadout would you like to choose?") in active_team.get_slot_list()
if(!active_team.check_slot_available(class)) // Because the prompt does not update automatically when a slot gets filled.
class = 0
if(new_gender)
if(new_gender == "Male")
M.change_gender(MALE)
@@ -182,12 +190,6 @@ var/ert_request_answered = 0
ticker.minds += M.mind //Adds them to regular mind list.
M.loc = spawn_location
var/class = 0
while(!class)
class = input("Which loadout would you like to choose?") in active_team.get_slot_list()
if(!active_team.check_slot_available(class)) // Because the prompt does not update automatically when a slot gets filled.
class = 0
active_team.equip_officer(class, M)
return M
+5 -4
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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)
+19 -14
View File
@@ -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 -1
View File
@@ -847,7 +847,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
sec_briefcase.contents += new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba
sec_briefcase.contents += new /obj/item/ammo_box/a357
sec_briefcase.contents += new /obj/item/weapon/c4
sec_briefcase.contents += new /obj/item/weapon/grenade/plastic/c4
// briefcase must be unlocked by setting the code.
M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
var/obj/item/weapon/implant/dust/DUST = new /obj/item/weapon/implant/dust(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")
+1 -1
View File
@@ -144,7 +144,7 @@ var/global/sent_strike_team = 0
equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
if(!leader_selected)
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack)
@@ -148,10 +148,10 @@ var/global/sent_syndicate_strike_team = 0
equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m45(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
if(!syndicate_leader_selected)
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
+10
View File
@@ -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
+22 -9
View File
@@ -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)
+245 -125
View File
@@ -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
+166 -29
View File
@@ -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
+7 -2
View File
@@ -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)
+15
View File
@@ -260,3 +260,18 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
send_asset_list(client, uncommon)
send_asset_list(client, common)
/datum/asset/chem_master
var/assets = list()
var/verify = FALSE
/datum/asset/chem_master/register()
for(var/i = 1 to 20)
assets["pill[i].png"] = icon('icons/obj/chemical.dmi', "pill[i]")
for(var/i = 1 to 20)
assets["bottle[i].png"] = icon('icons/obj/chemical.dmi', "bottle[i]")
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
/datum/asset/chem_master/send(client)
send_asset_list(client,assets,verify)
@@ -61,4 +61,35 @@
/datum/gear/accessory/scarf/stripedblue
display_name = "scarf, striped blue"
path = /obj/item/clothing/accessory/stripedbluescarf
path = /obj/item/clothing/accessory/stripedbluescarf
/datum/gear/accessory/holobadge
display_name = "holobadge, pin"
path = /obj/item/clothing/accessory/holobadge
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/accessory/holobadge_n
display_name = "holobadge, cord"
path = /obj/item/clothing/accessory/holobadge/cord
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/accessory/tieblue
display_name = "tie, blue"
path = /obj/item/clothing/accessory/blue
/datum/gear/accessory/tiered
display_name = "tie, red"
path = /obj/item/clothing/accessory/red
/datum/gear/accessory/tieblack
display_name = "tie, black"
path = /obj/item/clothing/accessory/black
/datum/gear/accessory/tiehorrible
display_name = "tie, vomit green"
path = /obj/item/clothing/accessory/horrible
/datum/gear/accessory/stethoscope
display_name = "stethoscope"
path = /obj/item/clothing/accessory/stethoscope
allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Paramedic", "Brig Physician")
@@ -1,3 +1,40 @@
/datum/gear/dice
display_name = "d20"
path = /obj/item/weapon/dice/d20
display_name = "a d20"
path = /obj/item/weapon/dice/d20
/datum/gear/uplift
display_name = "a pack of Uplifts"
path = /obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift
/datum/gear/robust
display_name = "a pack of Robusts"
path = /obj/item/weapon/storage/fancy/cigarettes/cigpack_robust
/datum/gear/carp
display_name = "a pack of Carps"
path = /obj/item/weapon/storage/fancy/cigarettes/cigpack_carp
/datum/gear/midori
display_name = "a pack of Midoris"
path = /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori
/datum/gear/lighter
display_name = "a cheap lighter"
path = /obj/item/weapon/lighter
/datum/gear/rock
display_name = "a pet rock"
path = /obj/item/toy/pet_rock
/datum/gear/sechud
display_name = "a classic security HUD"
path = /obj/item/clothing/glasses/hud/security
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/matches
display_name = "a box of matches"
path = /obj/item/weapon/storage/box/matches
/datum/gear/cards
display_name = "a deck of cards"
path = /obj/item/toy/cards/deck
@@ -0,0 +1,114 @@
/datum/gear/hat
subtype_path = /datum/gear/hat
slot = slot_head
sort_category = "Headwear"
/datum/gear/hat/hhat_yellow
display_name = "hardhat, yellow"
path = /obj/item/clothing/head/hardhat
allowed_roles = list("Chief Engineer", "Engineer", "Mechanic", "Life Support Specialist")
/datum/gear/hat/hhat_orange
display_name = "hardhat, orange"
path = /obj/item/clothing/head/hardhat/orange
allowed_roles = list("Chief Engineer", "Engineer", "Mechanic", "Life Support Specialist")
/datum/gear/hat/hhat_blue
display_name = "hardhat, blue"
path = /obj/item/clothing/head/hardhat/dblue
allowed_roles = list("Chief Engineer", "Engineer", "Mechanic", "Life Support Specialist")
/datum/gear/hat/that
display_name = "top hat"
path = /obj/item/clothing/head/that
/datum/gear/hat/flatcap
display_name = "flat cap"
path = /obj/item/clothing/head/flatcap
/datum/gear/hat/fez
display_name = "fez"
path = /obj/item/clothing/head/fez
/datum/gear/hat/bfedora
display_name = "fedora, black"
path = /obj/item/clothing/head/fedora
/datum/gear/hat/wfedora
display_name = "fedora, white"
path = /obj/item/clothing/head/fedora/whitefedora
/datum/gear/hat/brfedora
display_name = "fedora, brown"
path = /obj/item/clothing/head/fedora/brownfedora
/datum/gear/hat/beretsec
display_name = "security beret"
path = /obj/item/clothing/head/beret/sec
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/hat/capcsec
display_name = "security corporate cap"
path = /obj/item/clothing/head/soft/sec/corp
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/hat/capsec
display_name = "security cap"
path = /obj/item/clothing/head/soft/sec
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/hat/capred
display_name = "cap, red"
path = /obj/item/clothing/head/soft/red
/datum/gear/hat/capblue
display_name = "cap, blue"
path = /obj/item/clothing/head/soft/blue
/datum/gear/hat/capgreen
display_name = "cap, green"
path = /obj/item/clothing/head/soft/green
/datum/gear/hat/capblack
display_name = "cap, black"
path = /obj/item/clothing/head/soft/black
/datum/gear/hat/cappurple
display_name = "cap, purple"
path = /obj/item/clothing/head/soft/purple
/datum/gear/hat/capwhite
display_name = "cap, white"
path = /obj/item/clothing/head/soft/mime
/datum/gear/hat/caporange
display_name = "cap, orange"
path = /obj/item/clothing/head/soft/orange
/datum/gear/hat/capgrey
display_name = "cap, grey"
path = /obj/item/clothing/head/soft/grey
/datum/gear/hat/capyellow
display_name = "cap, yellow"
path = /obj/item/clothing/head/soft/yellow
/datum/gear/hat/cowboyhat
display_name = "cowboy hat"
path = /obj/item/clothing/head/cowboyhat
/datum/gear/hat/beret/purple
display_name = "beret, purple"
path = /obj/item/clothing/head/beret/purple_normal
/datum/gear/hat/beret/black
display_name = "beret, black"
path = /obj/item/clothing/head/beret/black
/datum/gear/hat/beret/blue
display_name = "beret, blue"
path = /obj/item/clothing/head/beret/blue
/datum/gear/hat/beret/red
display_name = "beret, red"
path = /obj/item/clothing/head/beret
@@ -0,0 +1,146 @@
/datum/gear/suit
subtype_path = /datum/gear/suit
slot = slot_wear_suit
sort_category = "External Wear"
//WINTER COATS
/datum/gear/suit/coat
subtype_path = /datum/gear/suit/coat
cost = 2
/datum/gear/suit/coat/grey
display_name = "winter coat"
path = /obj/item/clothing/suit/hooded/wintercoat
/datum/gear/suit/coat/job
subtype_path = /datum/gear/suit/coat
subtype_cost_overlap = FALSE
/datum/gear/suit/coat/job/sec
display_name = "winter coat, security"
path = /obj/item/clothing/suit/hooded/wintercoat/security
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Security Pod Pilot")
/datum/gear/suit/coat/job/captain
display_name = "winter coat, captain"
path = /obj/item/clothing/suit/hooded/wintercoat/captain
allowed_roles = list("Captain")
/datum/gear/suit/coat/job/med
display_name = "winter coat, medical"
path = /obj/item/clothing/suit/hooded/wintercoat/medical
allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician")
/datum/gear/suit/coat/job/sci
display_name = "winter coat, science"
path = /obj/item/clothing/suit/hooded/wintercoat/science
allowed_roles = list("Scientist", "Research Director")
/datum/gear/suit/coat/job/engi
display_name = "winter coat, engineering"
path = /obj/item/clothing/suit/hooded/wintercoat/engineering
allowed_roles = list("Chief Engineer", "Engineer", "Mechanic")
/datum/gear/suit/coat/job/atmos
display_name = "winter coat, atmospherics"
path = /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
allowed_roles = list("Chief Engineer", "Life Support Specialist")
/datum/gear/suit/coat/job/hydro
display_name = "winter coat, hydroponics"
path = /obj/item/clothing/suit/hooded/wintercoat/hydro
allowed_roles = list("Botanist")
/datum/gear/suit/coat/job/cargo
display_name = "winter coat, cargo"
path = /obj/item/clothing/suit/hooded/wintercoat/cargo
allowed_roles = list("Quartermaster", "Cargo Technician")
/datum/gear/suit/coat/job/miner
display_name = "winter coat, miner"
path = /obj/item/clothing/suit/hooded/wintercoat/miner
allowed_roles = list("Miner")
//LABCOATS
/datum/gear/suit/labcoat_emt
display_name = "labcoat, paramedic"
path = /obj/item/clothing/suit/storage/labcoat/emt
allowed_roles = list("Chief Medical Officer", "Paramedic")
//JACKETS
/datum/gear/suit/leather_jacket
display_name = "leather jacket"
path = /obj/item/clothing/suit/jacket/leather
/datum/gear/suit/br_tcoat
display_name = "trenchcoat, brown"
path = /obj/item/clothing/suit/browntrenchcoat
/datum/gear/suit/bl_tcoat
display_name = "trenchcoat, black"
path = /obj/item/clothing/suit/blacktrenchcoat
/datum/gear/suit/bomber_jacket
display_name = "bomber jacket"
path = /obj/item/clothing/suit/jacket
/datum/gear/suit/ol_miljacket
display_name = "military jacket, olive"
path = /obj/item/clothing/suit/jacket/miljacket
/datum/gear/suit/nv_miljacket
display_name = "military jacket, navy"
path = /obj/item/clothing/suit/jacket/miljacket/navy
/datum/gear/suit/ds_miljacket
display_name = "military jacket, desert"
path = /obj/item/clothing/suit/jacket/miljacket/desert
/datum/gear/suit/wh_miljacket
display_name = "military jacket, white"
path = /obj/item/clothing/suit/jacket/miljacket/white
/datum/gear/suit/secjacket
display_name = "security jacket"
path = /obj/item/clothing/suit/armor/secjacket
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Security Pod Pilot")
/datum/gear/suit/poncho
display_name = "poncho, classic"
path = /obj/item/clothing/suit/poncho
/datum/gear/suit/grponcho
display_name = "poncho, green"
path = /obj/item/clothing/suit/poncho/green
/datum/gear/suit/rdponcho
display_name = "poncho, red"
path = /obj/item/clothing/suit/poncho/red
/datum/gear/suit/tphoodie
display_name = "hoodie, Tharsis Polytech"
path = /obj/item/clothing/suit/hooded/hoodie/tp
/datum/gear/suit/nthoodie
display_name = "hoodie, Nanotrasen"
path = /obj/item/clothing/suit/hooded/hoodie/nt
/datum/gear/suit/lamhoodie
display_name = "hoodie, Lunar Academy of Medicine"
path = /obj/item/clothing/suit/hooded/hoodie/lam
/datum/gear/suit/cuthoodie
display_name = "hoodie, Canaan University of Technology"
path = /obj/item/clothing/suit/hooded/hoodie/cut
/datum/gear/suit/mithoodie
display_name = "hoodie, Martian Institute of Technology"
path = /obj/item/clothing/suit/hooded/hoodie/mit
/datum/gear/suit/bluehoodie
display_name = "hoodie, blue"
path = /obj/item/clothing/suit/hooded/hoodie/blue
/datum/gear/suit/blackhoodie
display_name = "hoodie, black"
path = /obj/item/clothing/suit/hooded/hoodie
@@ -24,7 +24,7 @@
path = /obj/item/clothing/under/blackskirt
/datum/gear/uniform/skirt/job
cost = 3
cost = 2
subtype_path = /datum/gear/uniform/skirt/job
subtype_cost_overlap = FALSE
@@ -96,4 +96,96 @@
/datum/gear/uniform/skirt/job/head_of_security
display_name = "skirt, hos"
path = /obj/item/clothing/under/rank/head_of_security/skirt
allowed_roles = list("Head of Security")
allowed_roles = list("Head of Security")
/datum/gear/uniform/sec
subtype_path = /datum/gear/uniform/sec
cost = 2
/datum/gear/uniform/sec/formal
display_name = "security uniform, formal"
path = /obj/item/clothing/under/rank/security/formal
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Security Pod Pilot")
datum/gear/uniform/secorporate
display_name = "security uniform, corporate "
path = /obj/item/clothing/under/rank/security/corp
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/uniform/sec/dispatch
display_name = "security uniform, dispatch"
path = /obj/item/clothing/under/rank/dispatch
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
/datum/gear/uniform/sec/casual
display_name = "security uniform, casual"
path = /obj/item/clothing/under/rank/security2
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Detective", "Security Pod Pilot")
/datum/gear/uniform/shorts/red
display_name = "shorts, red"
path = /obj/item/clothing/under/shorts/red
/datum/gear/uniform/shorts/green
display_name = "shorts, green"
path = /obj/item/clothing/under/shorts/green
/datum/gear/uniform/shorts/blue
display_name = "shorts, blue"
path = /obj/item/clothing/under/shorts/blue
/datum/gear/uniform/shorts/black
display_name = "shorts, black"
path = /obj/item/clothing/under/shorts/black
/datum/gear/uniform/shorts/grey
display_name = "shorts, grey"
path = /obj/item/clothing/under/shorts/grey
/datum/gear/uniform/pants/jeans
display_name = "jeans, classic"
path = /obj/item/clothing/under/pants/classicjeans
/datum/gear/uniform/pants/mjeans
display_name = "jeans, mustang"
path = /obj/item/clothing/under/pants/mustangjeans
/datum/gear/uniform/pants/bljeans
display_name = "jeans, black"
path = /obj/item/clothing/under/pants/blackjeans
/datum/gear/uniform/pants/yfjeans
display_name = "jeans, Young Folks"
path = /obj/item/clothing/under/pants/youngfolksjeans
/datum/gear/uniform/pants/whitepants
display_name = "pants, white"
path = /obj/item/clothing/under/pants/white
/datum/gear/uniform/pants/redpants
display_name = "pants, red"
path = /obj/item/clothing/under/pants/red
/datum/gear/uniform/pants/blackpants
display_name = "pants, black"
path = /obj/item/clothing/under/pants/black
/datum/gear/uniform/pants/tanpants
display_name = "pants, tan"
path = /obj/item/clothing/under/pants/tan
/datum/gear/uniform/pants/bluepants
display_name = "pants, blue"
path = /obj/item/clothing/under/pants/blue
/datum/gear/uniform/pants/trackpants
display_name = "trackpants"
path = /obj/item/clothing/under/pants/track
/datum/gear/uniform/pants/khakipants
display_name = "pants, khaki"
path = /obj/item/clothing/under/pants/khaki
/datum/gear/uniform/pants/caopants
display_name = "pants, camo"
path = /obj/item/clothing/under/pants/camo
@@ -1844,10 +1844,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
character.name = character.real_name
character.flavor_text = flavor_text
if(character.ckey && !jobban_isbanned(character, "Records"))
character.med_record = med_record
character.sec_record = sec_record
character.gen_record = gen_record
character.med_record = med_record
character.sec_record = sec_record
character.gen_record = gen_record
character.change_gender(gender)
character.age = age
+16 -1
View File
@@ -114,4 +114,19 @@
prescription_upgradable = 1
/obj/item/clothing/glasses/hud/security/sunglasses/prescription
prescription = 1
prescription = 1
/obj/item/clothing/glasses/hud/hydroponic
name = "Hydroponic HUD"
desc = "A heads-up display capable of analyzing the health and status of plants growing in hydro trays and soil."
icon_state = "hydroponichud"
HUDType = DATA_HUD_HYDROPONIC
/obj/item/clothing/glasses/hud/hydroponic/night
name = "Night Vision Hydroponic HUD"
desc = "A hydroponic HUD fitted with a light amplifier."
icon_state = "hydroponichudnight"
item_state = "glasses"
darkness_view = 8
see_darkness = 0
prescription_upgradable = 0
+6 -1
View File
@@ -116,6 +116,11 @@
desc = "A beret for those who have shown immaculate proficienty in piping. Or plumbing."
icon_state = "beret_atmospherics"
/obj/item/clothing/head/beret/ce
name = "chief engineer beret"
desc = "A white beret with the engineering insignia emblazoned on it. Its owner knows what they're doing. Probably."
icon_state = "beret_ce"
//Medical
/obj/item/clothing/head/surgery
name = "surgical cap"
@@ -137,4 +142,4 @@
/obj/item/clothing/head/surgery/black
desc = "A cap coroners wear during autopsies. Keeps their hair from falling into the cadavers. It is as dark than the coroner's humor."
icon_state = "surgcap_black"
icon_state = "surgcap_black"

Some files were not shown because too many files have changed in this diff Show More