Merge branch 'master' into upstream-merge-27801

This commit is contained in:
kevinz000
2017-06-03 06:38:57 -07:00
committed by GitHub
228 changed files with 402605 additions and 227955 deletions
+2
View File
@@ -51,8 +51,10 @@
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175)
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248)
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
+13
View File
@@ -4,6 +4,19 @@
// #define EAST 4
// #define WEST 8
//These get to go at the top, because they're special
//You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects)
/* eg:
/mob/living/carbon/human/death()
world << THIS_PROC_TYPE_STR //You can only output the string versions
Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a string with () (eg: the _WITH_ARGS defines) to make it look nicer)
*/
#define THIS_PROC_TYPE .....
#define THIS_PROC_TYPE_STR "[THIS_PROC_TYPE]" //Because you can only obtain a string of THIS_PROC_TYPE using "[]", and it's nice to just +/+= strings
#define THIS_PROC_TYPE_STR_WITH_ARGS "[THIS_PROC_TYPE]([args.Join(",")])"
#define THIS_PROC_TYPE_WEIRD ...... //This one is WEIRD, in some cases (When used in certain defines? (eg: ASSERT)) THIS_PROC_TYPE will fail to work, but THIS_PROC_TYPE_WEIRD will work instead
#define THIS_PROC_TYPE_WEIRD_STR "[THIS_PROC_TYPE_WEIRD]" //Included for completeness
#define THIS_PROC_TYPE_WEIRD_STR_WITH_ARGS "[THIS_PROC_TYPE_WEIRD]([args.Join(",")])" //Ditto
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
+1
View File
@@ -42,6 +42,7 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
#define INIT_ORDER_DBCORE 17
#define INIT_ORDER_SERVER_MAINT 16
#define INIT_ORDER_JOBS 15
#define INIT_ORDER_EVENTS 14
+2 -2
View File
@@ -3,8 +3,8 @@
#define WIRE_AI "AI Connection"
#define WIRE_ALARM "Alarm"
#define WIRE_AVOIDANCE "Avoidance"
#define WIRE_BACKUP1 "Auxillary Power 1"
#define WIRE_BACKUP2 "Auxillary Power 2"
#define WIRE_BACKUP1 "Auxiliary Power 1"
#define WIRE_BACKUP2 "Auxiliary Power 2"
#define WIRE_BEACON "Beacon"
#define WIRE_BOLTS "Bolts"
#define WIRE_BOOM "Boom"
+8 -7
View File
@@ -1079,18 +1079,17 @@ B --><-- A
return L
//similar function to RANGE_TURFS(), but will search spiralling outwards from the center (like the above, but only turfs)
/proc/spiral_range_turfs(dist=0, center=usr, orange=0)
/proc/spiral_range_turfs(dist=0, center=usr, orange=0, list/outlist = list(), tick_checked)
outlist.Cut()
if(!dist)
if(!orange)
return list(center)
else
return list()
outlist += center
return outlist
var/turf/t_center = get_turf(center)
if(!t_center)
return list()
return outlist
var/list/L = list()
var/list/L = outlist
var/turf/T
var/y
var/x
@@ -1128,6 +1127,8 @@ B --><-- A
if(T)
L += T
c_dist++
if(tick_checked)
CHECK_TICK
return L
+9 -9
View File
@@ -22,12 +22,12 @@ GLOBAL_VAR_INIT(tinted_weldhelh, TRUE)
// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit.
GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch
GLOBAL_VAR_INIT(Debug2, FALSE)
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3)
GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7)
GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14)
GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14)
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3)
GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7)
GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14)
GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14)
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
+2
View File
@@ -31,4 +31,6 @@ GLOBAL_PROTECT(OOClog)
GLOBAL_LIST_EMPTY(adminlog)
GLOBAL_PROTECT(adminlog)
GLOBAL_LIST_EMPTY(individual_log_list) // Logs each mob individual logs, a global so it doesn't get lost on cloning/changing mobs
GLOBAL_LIST_EMPTY(active_turfs_startlist)
+4
View File
@@ -208,6 +208,8 @@
var/generate_minimaps = 0
var/grey_assistants = 0
var/id_console_jobslot_delay = 30
var/lavaland_budget = 60
var/space_budget = 16
@@ -409,6 +411,8 @@
usewhitelist = TRUE
if("allow_metadata")
allow_Metadata = 1
if("id_console_jobslot_delay")
id_console_jobslot_delay = text2num(value)
if("inactivity_period")
inactivity_period = text2num(value) * 10 //documented as seconds in config.txt
if("afk_period")
-2
View File
@@ -82,8 +82,6 @@ SUBSYSTEM_DEF(blackbox)
add_details("radio_usage","PDA-[pda_msg_amt]")
add_details("radio_usage","RC-[rc_msg_amt]")
set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
if (!SSdbcore.Connect())
return
+17 -12
View File
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(dbcore)
name = "Database"
flags = SS_NO_INIT|SS_NO_FIRE
init_order = INIT_ORDER_DBCORE
var/const/FAILED_DB_CONNECTION_CUTOFF = 5
var/const/Default_Cursor = 0
@@ -30,6 +30,11 @@ SUBSYSTEM_DEF(dbcore)
_db_con = SSdbcore._db_con
/datum/controller/subsystem/dbcore/Shutdown()
//This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
if(SSdbcore.Connect())
var/sql_station_name = sanitizeSQL(station_name())
var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (end_datetime, game_mode_result, end_state, station_name) VALUES (Now(), '[SSticker.mode_result]', '[SSticker.end_state]', '[sql_station_name]') WHERE id = [GLOB.round_id]")
query_round_end.Execute()
if(IsConnected())
Disconnect()
@@ -48,7 +53,7 @@ SUBSYSTEM_DEF(dbcore)
if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
return FALSE
if(!config.sql_enabled)
return FALSE
@@ -171,16 +176,16 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
var/_db_query
/datum/DBQuery/New(sql_query, datum/controller/subsystem/dbcore/connection_handler, cursor_handler)
if(sql_query)
if(sql_query)
sql = sql_query
if(connection_handler)
if(connection_handler)
db_connection = connection_handler
if(cursor_handler)
if(cursor_handler)
default_cursor = cursor_handler
item = list()
_db_query = _dm_db_new_query()
/datum/DBQuery/proc/Connect(datum/controller/subsystem/dbcore/connection_handler)
/datum/DBQuery/proc/Connect(datum/controller/subsystem/dbcore/connection_handler)
db_connection = connection_handler
/datum/DBQuery/proc/warn_execute()
@@ -194,16 +199,16 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
if(!. && log_error)
log_sql("[ErrorMsg()] | Query used: [sql]")
/datum/DBQuery/proc/NextRow()
/datum/DBQuery/proc/NextRow()
return _dm_db_next_row(_db_query,item,conversions)
/datum/DBQuery/proc/RowsAffected()
return _dm_db_rows_affected(_db_query)
/datum/DBQuery/proc/RowCount()
/datum/DBQuery/proc/RowCount()
return _dm_db_row_count(_db_query)
/datum/DBQuery/proc/ErrorMsg()
/datum/DBQuery/proc/ErrorMsg()
return _dm_db_error_msg(_db_query)
/datum/DBQuery/proc/Columns()
@@ -232,11 +237,11 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
return db_connection.Quote(str)
/datum/DBQuery/proc/SetConversion(column,conversion)
if(istext(column))
if(istext(column))
column = columns.Find(column)
if(!conversions)
if(!conversions)
conversions = list(column)
else if(conversions.len < column)
else if(conversions.len < column)
conversions.len = column
conversions[column] = conversion
+1 -1
View File
@@ -105,7 +105,7 @@ SUBSYSTEM_DEF(events)
//These are needed because /area/engine has to be removed from the list, but we still want these areas to get fucked up.
var/list/danger_areas = list(
/area/engine/break_room,
/area/engine/chiefs_office)
/area/crew_quarters/heads/chief)
//Need to locate() as it's just a list of paths.
return locate(pick((GLOB.the_station_areas - safe_areas) + danger_areas))
+510
View File
@@ -0,0 +1,510 @@
SUBSYSTEM_DEF(explosion)
priority = 99
wait = 1
flags = SS_TICKER|SS_NO_INIT
var/list/explosions
var/rebuild_tick_split_count = FALSE
var/tick_portions_required = 0
var/list/logs
var/list/zlevels_that_ignore_bombcap
var/list/doppler_arrays
//legacy caps, set by config
var/devastation_cap = 3
var/heavy_cap = 7
var/light_cap = 14
var/flash_cap = 14
var/flame_cap = 14
var/dyn_ex_scale = 0.5
var/id_counter = 0
/datum/controller/subsystem/explosion/PreInit()
doppler_arrays = list()
logs = list()
explosions = list()
zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]")
/datum/controller/subsystem/explosion/Shutdown()
QDEL_LIST(explosions)
QDEL_LIST(logs)
zlevels_that_ignore_bombcap.Cut()
/datum/controller/subsystem/explosion/Recover()
explosions = SSexplosion.explosions
logs = SSexplosion.logs
id_counter = SSexplosion.id_counter
rebuild_tick_split_count = TRUE
zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap
doppler_arrays = SSexplosion.doppler_arrays
devastation_cap = SSexplosion.devastation_cap
heavy_cap = SSexplosion.heavy_cap
light_cap = SSexplosion.light_cap
flash_cap = SSexplosion.flash_cap
flame_cap = SSexplosion.flame_cap
dyn_ex_scale = SSexplosion.dyn_ex_scale
/datum/controller/subsystem/explosion/fire()
var/list/cached_explosions = explosions
var/num_explosions = cached_explosions.len
if(!num_explosions)
return
//figure exactly how many tick splits are required
var/num_splits
if(rebuild_tick_split_count)
var/reactionary = config.reactionary_explosions
num_splits = num_explosions
for(var/I in cached_explosions)
var/datum/explosion/E = I
if(!E.turfs_processed)
++num_splits
if(reactionary && !E.densities_processed)
++num_splits
tick_portions_required = num_splits
else
num_splits = tick_portions_required
MC_SPLIT_TICK_INIT(num_splits)
for(var/I in cached_explosions)
var/datum/explosion/E = I
var/etp = E.turfs_processed
if(!etp)
if(GatherTurfs(E))
--tick_portions_required
etp = TRUE
MC_SPLIT_TICK
var/edp = E.densities_processed
if(!edp)
if(DensityCalculate(E, etp))
--tick_portions_required
edp = TRUE
MC_SPLIT_TICK
if(ProcessExplosion(E, edp)) //splits the tick
--tick_portions_required
explosions -= E
logs += E
NotifyDopplers(E)
MC_SPLIT_TICK
/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E)
for(var/array in doppler_arrays)
var/obj/machinery/doppler_array/A = array
A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range)
/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
epicenter = get_turf(epicenter)
if(!epicenter)
return
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
if(heavy_impact_range > 1)
var/datum/effect_system/explosion/Eff
if(smoke)
Eff = new /datum/effect_system/explosion/smoke
else
Eff = new
Eff.set_up(epicenter)
Eff.start()
//flash mobs
if(flash_range)
for(var/mob/living/L in viewers(flash_range, epicenter))
L.flash_act()
if(!silent)
ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent)
//add to SS
if(E.extent)
tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0)
explosions += E
else
logs += E //Already done processing
/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE)
if(!power)
return
var/range = round((2 * power) ** dyn_ex_scale)
Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke)
// Using default dyn_ex scale:
// 100 explosion power is a (5, 10, 20) explosion.
// 75 explosion power is a (4, 8, 17) explosion.
// 50 explosion power is a (3, 7, 14) explosion.
// 25 explosion power is a (2, 5, 10) explosion.
// 10 explosion power is a (1, 3, 6) explosion.
// 5 explosion power is a (0, 1, 3) explosion.
// 1 explosion power is a (0, 0, 1) explosion.
/datum/explosion
var/explosion_id
var/turf/epicenter
var/started_at
var/finished_at
var/tick_started
var/tick_finished
var/turfs_processed = FALSE
var/densities_processed = FALSE
var/orig_dev_range
var/orig_heavy_range
var/orig_light_range
var/orig_flash_range
var/orig_flame_range
var/devastation
var/heavy
var/light
var/extent
var/flash
var/flame
var/gather_dist = 0
var/list/gathered_turfs
var/list/calculated_turfs
var/list/unsafe_turfs
/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
explosion_id = id
epicenter = epi
densities_processed = !config.reactionary_explosions
orig_dev_range = devastation_range
orig_heavy_range = heavy_impact_range
orig_light_range = light_impact_range
orig_flash_range = flash_range
orig_flame_range = flame_range
if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap))
//Clamp all values
devastation_range = min(SSexplosion.devastation_cap, devastation_range)
heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range)
light_impact_range = min(SSexplosion.light_cap, light_impact_range)
flash_range = min(SSexplosion.flash_cap, flash_range)
flame_range = min(SSexplosion.flame_cap, flame_range)
//store this
devastation = devastation_range
heavy = heavy_impact_range
light = light_impact_range
extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
flash = flash_range
flame = flame_range
started_at = REALTIMEOFDAY
tick_started = world.time
gathered_turfs = list()
calculated_turfs = list()
unsafe_turfs = list()
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
// Stereo users will also hear the direction of the explosion!
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
// 3/7/14 will calculate to 80 + 35
/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent)
var/far_dist = 0
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
var/z0 = epicenter.z
var/frequency = get_rand_frequency()
var/ex_sound = get_sfx("explosion")
for(var/mob/M in GLOB.player_list)
// Double check for client
var/turf/M_turf = get_turf(M)
if(M_turf && M_turf.z == z0)
var/dist = get_dist(M_turf, epicenter)
// If inside the blast radius + world.view - 2
if(dist <= round(extent + world.view - 2, 1))
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
/datum/explosion/Destroy()
SSexplosion.explosions -= src
SSexplosion.logs -= src
LAZYCLEARLIST(gathered_turfs)
LAZYCLEARLIST(calculated_turfs)
LAZYCLEARLIST(unsafe_turfs)
return ..()
/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E)
var/turf/epicenter = E.epicenter
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
var/c_dist = E.gather_dist
var/dist = E.extent
var/list/L = E.gathered_turfs
if(!c_dist)
L += epicenter
++c_dist
while( c_dist <= dist )
var/y = y0 + c_dist
var/x = x0 - c_dist + 1
for(x in x to x0 + c_dist)
var/turf/T = locate(x, y, z0)
if(T)
L += T
y = y0 + c_dist - 1
x = x0 + c_dist
for(y in y0 - c_dist to y)
var/turf/T = locate(x, y, z0)
if(T)
L += T
y = y0 - c_dist
x = x0 + c_dist - 1
for(x in x0 - c_dist to x)
var/turf/T = locate(x, y, z0)
if(T)
L += T
y = y0 - c_dist + 1
x = x0 - c_dist
for(y in y to y0 + c_dist)
var/turf/T = locate(x, y, z0)
if(T)
L += T
++c_dist
if(MC_TICK_CHECK)
break
if(c_dist > dist)
E.turfs_processed = TRUE
return TRUE
else
E.gather_dist = c_dist
return FALSE
/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs)
var/list/L = E.calculated_turfs
var/cut_to = 1
for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area
var/turf/T = I
++cut_to
var/current_exp_block = T.density ? T.explosion_block : 0
for(var/obj/machinery/door/D in T)
if(D.density)
current_exp_block += D.explosion_block
for(var/obj/structure/window/W in T)
if(W.reinf && W.fulltile)
current_exp_block += W.explosion_block
for(var/obj/structure/blob/B in T)
current_exp_block += B.explosion_block
L[T] = current_exp_block
if(MC_TICK_CHECK)
E.gathered_turfs.Cut(1, cut_to)
return FALSE
E.gathered_turfs.Cut()
return done_gathering_turfs
/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs)
//cache shit for speed
var/id = E.explosion_id
var/list/cached_unsafe = E.unsafe_turfs
var/list/cached_exp_block = E.calculated_turfs
var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs
var/devastation_range = E.devastation
var/heavy_impact_range = E.heavy
var/light_impact_range = E.light
var/flame_range = E.flame
var/throw_range_max = E.extent
var/turf/epi = E.epicenter
var/x0 = epi.x
var/y0 = epi.y
var/cut_to = 1
for(var/TI in affected_turfs)
var/turf/T = TI
++cut_to
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
var/dist = init_dist
if(cached_exp_block)
var/turf/Trajectory = T
while(Trajectory != epi)
Trajectory = get_step_towards(Trajectory, epi)
dist += cached_exp_block[Trajectory]
var/flame_dist = dist < flame_range
var/throw_dist = dist
if(dist < devastation_range)
dist = 1
else if(dist < heavy_impact_range)
dist = 2
else if(dist < light_impact_range)
dist = 3
else
dist = 0
//------- EX_ACT AND TURF FIRES -------
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
new /obj/effect/hotspot(T) //Mostly for ambience!
if(dist > 0)
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
T.explosion_id = id
T.ex_act(dist)
cached_unsafe += T
//--- THROW ITEMS AROUND ---
var/throw_dir = get_dir(epi, T)
for(var/obj/item/I in T)
if(!I.anchored)
var/throw_range = rand(throw_dist, throw_range_max)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything)
I.throw_at(throw_at, throw_range, 4)
if(MC_TICK_CHECK)
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
if(cached_unsafe.len > circumference) //only do this every revolution
for(var/Unexplode in cached_unsafe)
var/turf/UnexplodeT = Unexplode
UnexplodeT.explosion_level = 0
cached_unsafe.Cut()
done_calculating_turfs = FALSE
break
affected_turfs.Cut(1, cut_to)
if(!done_calculating_turfs)
return FALSE
//unfuck the shit
for(var/Unexplode in cached_unsafe)
var/turf/UnexplodeT = Unexplode
UnexplodeT.explosion_level = 0
cached_unsafe.Cut()
E.finished_at = REALTIMEOFDAY
E.tick_finished = world.time
return TRUE
/client/proc/check_bomb_impacts()
set name = "Check Bomb Impact"
set category = "Debug"
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
var/turf/epicenter = get_turf(mob)
if(!epicenter)
return
var/x0 = epicenter.x
var/y0 = epicenter.y
var/dev = 0
var/heavy = 0
var/light = 0
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
var/choice = input("Bomb Size?") in choices
switch(choice)
if(null)
return 0
if("Small Bomb")
dev = 1
heavy = 2
light = 3
if("Medium Bomb")
dev = 2
heavy = 3
light = 4
if("Big Bomb")
dev = 3
heavy = 5
light = 7
if("Custom Bomb")
dev = input("Devestation range (Tiles):") as num
heavy = input("Heavy impact range (Tiles):") as num
light = input("Light impact range (Tiles):") as num
else
return
var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE)
while(!SSexplosion.GatherTurfs(E))
stoplag()
var/list/turfs
if(newmode)
while(!SSexplosion.DensityCalculate(E, TRUE))
stoplag()
turfs = E.calculated_turfs.Copy()
else
turfs = E.gathered_turfs.Copy()
qdel(E)
for(var/I in turfs)
var/turf/T = I
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T]
if(dist < dev)
T.color = "red"
T.maptext = "Dev"
else if (dist < heavy)
T.color = "yellow"
T.maptext = "Heavy"
else if (dist < light)
T.color = "blue"
T.maptext = "Light"
CHECK_TICK
sleep(100)
for(var/I in turfs)
var/turf/T = I
T.color = null
T.maptext = null
+3 -3
View File
@@ -37,11 +37,11 @@ SUBSYSTEM_DEF(machines)
var/seconds = wait * 0.1
while(currentrun.len)
var/datum/thing = currentrun[currentrun.len]
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
if(thing && thing.process(seconds) != PROCESS_KILL)
if(thing:use_power)
thing:auto_use_power() //add back the power state
if(thing.use_power)
thing.auto_use_power() //add back the power state
else
processing -= thing
if (thing)
+3 -1
View File
@@ -119,7 +119,9 @@ SUBSYSTEM_DEF(mapping)
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
SSblackbox.add_details("map_name", config.map_name)
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
query_round_map_name.Execute()
if(config.minetype != "lavaland")
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
+1
View File
@@ -25,6 +25,7 @@ SUBSYSTEM_DEF(shuttle)
var/area/emergencyLastCallLoc
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
var/emergencyNoEscape
var/emergencyNoRecall = FALSE
var/list/hostileEnvironments = list()
//supply shuttle stuff
+13 -8
View File
@@ -60,6 +60,8 @@ SUBSYSTEM_DEF(ticker)
var/round_start_time = 0
var/list/round_start_events
var/mode_result = "undefined"
var/end_state = "undefined"
var/modevoted = FALSE //Have we sent a vote for the gamemode?
@@ -639,9 +641,9 @@ SUBSYSTEM_DEF(ticker)
sleep(50)
if(mode.station_was_nuked)
Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
Reboot("Station destroyed by Nuclear Device.", "nuke")
else
Reboot("Round ended.", "end_proper", "proper completion")
Reboot("Round ended.", "proper completion")
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
var/m
@@ -842,7 +844,7 @@ SUBSYSTEM_DEF(ticker)
C.Export("##action=load_rsc", round_end_sound)
round_end_sound_sent = TRUE
/datum/controller/subsystem/ticker/proc/Reboot(reason, feedback_c, feedback_r, delay)
/datum/controller/subsystem/ticker/proc/Reboot(reason, end_string, delay)
set waitfor = FALSE
if(usr && !check_rights(R_SERVER, TRUE))
return
@@ -850,21 +852,24 @@ SUBSYSTEM_DEF(ticker)
if(!delay)
delay = config.round_end_countdown * 10
if(delay_end)
var/skip_delay = check_rights()
if(delay_end && !skip_delay)
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
return
to_chat(world, "<span class='boldannounce'>Rebooting World in [delay/10] [(delay >= 10 && delay < 20) ? "second" : "seconds"]. [reason]</span>")
var/start_wait = world.time
UNTIL(round_end_sound_sent && (world.time - start_wait) > (delay * 2)) //don't wait forever
UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever
sleep(delay - (world.time - start_wait))
if(delay_end)
if(delay_end && !skip_delay)
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
return
SSblackbox.set_details("[feedback_c]","[feedback_r]")
if(end_string)
end_state = end_string
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
@@ -882,4 +887,4 @@ SUBSYSTEM_DEF(ticker)
'sound/roundend/disappointed.ogg'\
)
world << sound(round_end_sound)
world << sound(round_end_sound)
+1 -1
View File
@@ -137,7 +137,7 @@ SUBSYSTEM_DEF(vote)
active_admins = 1
break
if(!active_admins)
SSticker.Reboot("Restart vote successful.", "end_error", "restart vote")
SSticker.Reboot("Restart vote successful.", "restart vote")
else
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
@@ -1,10 +1,48 @@
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1)
set waitfor = 0
src = null //so we don't abort once src is deleted
#define EXPLOSION_THROW_SPEED 4
GLOBAL_LIST_EMPTY(explosions)
//Against my better judgement, I will return the explosion datum
//If I see any GC errors for it I will find you
//and I will gib you
/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
return new /datum/explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
//This datum creates 3 async tasks
//1 GatherSpiralTurfsProc runs spiral_range_turfs(tick_checked = TRUE) to populate the affected_turfs list
//2 CaculateExplosionBlock adds the blockings to the cached_exp_block list
//3 The main thread explodes the prepared turfs
/datum/explosion
var/explosion_id
var/started_at
var/running = TRUE
var/stopped = 0 //This is the number of threads stopped !DOESN'T COUNT THREAD 2!
var/static/id_counter = 0
#define EX_PREPROCESS_EXIT_CHECK \
if(!running) {\
stopped = 2;\
qdel(src);\
return;\
}
#define EX_PREPROCESS_CHECK_TICK \
if(TICK_CHECK) {\
stoplag();\
EX_PREPROCESS_EXIT_CHECK\
}
/datum/explosion/New(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
set waitfor = FALSE
var/id = ++id_counter
explosion_id = id
epicenter = get_turf(epicenter)
if(!epicenter)
return
GLOB.explosions += src
if(isnull(flame_range))
flame_range = light_impact_range
if(isnull(flash_range))
@@ -30,14 +68,13 @@
//I would make this not ex_act the thing that triggered the explosion,
//but everything that explodes gives us their loc or a get_turf()
//and somethings expect us to ex_act them so they can qdel()
sleep(1) //tldr, let the calling proc call qdel(src) before we explode
stoplag() //tldr, let the calling proc call qdel(src) before we explode
var/static/explosionid = 1
var/id = explosionid++
var/start = world.timeofday
EX_PREPROCESS_EXIT_CHECK
started_at = REALTIMEOFDAY
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
var/list/cached_exp_block = list()
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
@@ -53,23 +90,27 @@
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
if(!silent)
var/frequency = get_rand_frequency()
var/ex_sound = get_sfx("explosion")
for(var/mob/M in GLOB.player_list)
// Double check for client
if(M && M.client)
var/turf/M_turf = get_turf(M)
if(M_turf && M_turf.z == epicenter.z)
var/dist = get_dist(M_turf, epicenter)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
var/turf/M_turf = get_turf(M)
if(M_turf && M_turf.z == z0)
var/dist = get_dist(M_turf, epicenter)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
EX_PREPROCESS_CHECK_TICK
//postpone processing for a bit
var/postponeCycles = max(round(devastation_range/8),1)
@@ -77,66 +118,52 @@
SSmachines.postpone(postponeCycles)
if(heavy_impact_range > 1)
var/datum/effect_system/explosion/E
if(smoke)
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
E.set_up(epicenter)
E.start()
E = new /datum/effect_system/explosion/smoke
else
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
E.set_up(epicenter)
E.start()
E = new
E.set_up(epicenter)
E.start()
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
if(config.reactionary_explosions)
for(var/turf/T in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
cached_exp_block[T] = 0
if(T.density && T.explosion_block)
cached_exp_block[T] += T.explosion_block
for(var/obj/machinery/door/D in T)
if(D.density && D.explosion_block)
cached_exp_block[T] += D.explosion_block
for(var/obj/structure/window/W in T)
if(W.reinf && W.fulltile)
cached_exp_block[T] += W.explosion_block
for(var/obj/structure/blob/B in T)
cached_exp_block[T] += B.explosion_block
CHECK_TICK
EX_PREPROCESS_CHECK_TICK
//flash mobs
if(flash_range)
for(var/mob/living/L in viewers(flash_range, epicenter))
L.flash_act()
CHECK_TICK
EX_PREPROCESS_CHECK_TICK
var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep
for(var/turf/T in affected_turfs)
var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter)
if (!T)
continue
var/reactionary = config.reactionary_explosions
var/list/cached_exp_block
if(reactionary)
cached_exp_block = CaculateExplosionBlock(affected_turfs)
//lists are guaranteed to contain at least 1 turf at this point
var/iteration = 0
var/affTurfLen = affected_turfs.len
var/expBlockLen = cached_exp_block.len
for(var/TI in affected_turfs)
var/turf/T = TI
++iteration
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
var/dist = init_dist
if(config.reactionary_explosions)
if(reactionary)
var/turf/Trajectory = T
while(Trajectory != epicenter)
Trajectory = get_step_towards(Trajectory, epicenter)
dist += cached_exp_block[Trajectory]
var/flame_dist = 0
var/flame_dist = dist < flame_range
var/throw_dist = dist
if(dist < flame_range)
flame_dist = 1
if(dist < devastation_range)
dist = 1
else if(dist < heavy_impact_range)
@@ -148,27 +175,61 @@
//------- EX_ACT AND TURF FIRES -------
if(T)
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
new /obj/effect/hotspot(T) //Mostly for ambience!
if(dist > 0)
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
T.explosion_id = id
T.ex_act(dist)
exploded_this_tick += T
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
new /obj/effect/hotspot(T) //Mostly for ambience!
if(dist > 0)
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
T.explosion_id = id
T.ex_act(dist)
exploded_this_tick += T
//--- THROW ITEMS AROUND ---
var/throw_dir = get_dir(epicenter,T)
for(var/obj/item/I in T)
if(I && !I.anchored)
if(!I.anchored)
var/throw_range = rand(throw_dist, max_range)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
I.throw_at(throw_at, throw_range, I.throw_speed)
I.throw_speed = EXPLOSION_THROW_SPEED //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
I.throw_at(throw_at, throw_range, EXPLOSION_THROW_SPEED)
if(TICK_CHECK)
//wait for the lists to repop
var/break_condition
if(reactionary)
//If we've caught up to the density checker thread and there are no more turfs to process
break_condition = iteration == expBlockLen && iteration < affTurfLen
else
//If we've caught up to the turf gathering thread and it's still running
break_condition = iteration == affTurfLen && !stopped
if(break_condition || TICK_CHECK)
stoplag()
if(!running)
break
//update the trackers
affTurfLen = affected_turfs.len
expBlockLen = cached_exp_block.len
if(break_condition)
if(reactionary)
//until there are more block checked turfs than what we are currently at
//or the explosion has stopped
UNTIL(iteration < affTurfLen || !running)
else
//until there are more gathered turfs than what we are currently at
//or there are no more turfs to gather/the explosion has stopped
UNTIL(iteration < expBlockLen || stopped)
if(!running)
break
//update the trackers
affTurfLen = affected_turfs.len
expBlockLen = cached_exp_block.len
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
if(exploded_this_tick.len > circumference) //only do this every revolution
for(var/Unexplode in exploded_this_tick)
@@ -182,24 +243,67 @@
UnexplodeT.explosion_level = 0
exploded_this_tick.Cut()
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
var/took = (REALTIMEOFDAY - started_at) / 10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
if(GLOB.Debug2)
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
//Machines which report explosions.
for(var/array in GLOB.doppler_arrays)
var/obj/machinery/doppler_array/A = array
A.sense_explosion(epicenter,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range)
if(running) //if we aren't in a hurry
//Machines which report explosions.
for(var/array in GLOB.doppler_arrays)
var/obj/machinery/doppler_array/A = array
A.sense_explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, took,orig_dev_range, orig_heavy_range, orig_light_range)
return 1
++stopped
qdel(src)
#undef EX_PREPROCESS_EXIT_CHECK
#undef EX_PREPROCESS_CHECK_TICK
//asyncly populate the affected_turfs list
/datum/explosion/proc/GatherSpiralTurfs(range, turf/epicenter)
set waitfor = FALSE
. = list()
spiral_range_turfs(range, epicenter, outlist = ., tick_checked = TRUE)
++stopped
/proc/secondaryexplosion(turf/epicenter, range)
for(var/turf/tile in spiral_range_turfs(range, epicenter))
tile.ex_act(2)
/datum/explosion/proc/CaculateExplosionBlock(list/affected_turfs)
set waitfor = FALSE
. = list()
var/processed = 0
while(!stopped && running)
var/I
for(I in (processed + 1) to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area
var/turf/T = affected_turfs[I]
var/current_exp_block = T.density ? T.explosion_block : 0
for(var/obj/machinery/door/D in T)
if(D.density)
current_exp_block += D.explosion_block
for(var/obj/structure/window/W in T)
if(W.reinf && W.fulltile)
current_exp_block += W.explosion_block
for(var/obj/structure/blob/B in T)
current_exp_block += B.explosion_block
.[T] = current_exp_block
if(TICK_CHECK)
break
processed = I
stoplag()
/datum/explosion/Destroy()
running = FALSE
if(stopped < 2) //wait for main thread and spiral_range thread
return QDEL_HINT_IWILLGC
GLOB.explosions -= src
return ..()
/client/proc/check_bomb_impacts()
set name = "Check Bomb Impact"
+1 -1
View File
@@ -51,7 +51,7 @@
user.remote_control = null
user = null
QDEL_NULL(eye)
if(hologram)
hologram.HC = null
hologram = null
+1
View File
@@ -68,6 +68,7 @@
/datum/mind/New(var/key)
src.key = key
soulOwner = src
martial_art = default_martial_art
/datum/mind/Destroy()
SSticker.minds -= src
+11 -6
View File
@@ -20,7 +20,8 @@
var/r_hand = null
var/l_hand = null
var/internals_slot = null //ID of slot containing a gas tank
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
var/list/implants = null
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
//to be overriden for customization depending on client prefs,species etc
@@ -71,11 +72,11 @@
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
if(backpack_contents)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
@@ -88,6 +89,10 @@
if(internals_slot)
H.internal = H.get_item_by_slot(internals_slot)
H.update_action_buttons_icon()
if(implants)
for(var/implant_type in implants)
var/obj/item/weapon/implant/I = new implant_type(H)
I.implant(H, null, silent=TRUE)
H.update_body()
return 1
+1 -1
View File
@@ -134,7 +134,7 @@
area_type = /area
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
/area/ai_monitored/turret_protected/ai, /area/storage/emergency, /area/storage/emergency2, /area/shuttle)
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle)
target_z = ZLEVEL_STATION
immunity_type = "rad"
+6 -3
View File
@@ -50,9 +50,9 @@
R.show_laws()
if(WIRE_LOCKDOWN)
R.SetLockdown(!R.lockcharge) // Toggle
if(WIRE_RESET_MODULE)
if(R.has_module())
R.ResetModule()
if(WIRE_RESET_MODULE)
if(R.has_module())
R.visible_message("[R]'s module servos twitch.", "Your module display flickers.")
/datum/wires/robot/on_cut(wire, mend)
var/mob/living/silicon/robot/R = holder
@@ -74,3 +74,6 @@
R.visible_message("[R]'s camera lense focuses loudly.", "Your camera lense focuses loudly.")
if(WIRE_LOCKDOWN) // Simple lockdown.
R.SetLockdown(!mend)
if(WIRE_RESET_MODULE)
if(R.has_module() && !mend)
R.ResetModule()
File diff suppressed because it is too large Load Diff
+4
View File
@@ -37,6 +37,7 @@
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = 0
has_gravity = 1
flags = NONE
/area/tdome/arena
name = "Thunderdome Arena"
@@ -75,6 +76,7 @@
requires_power = 0
has_gravity = 1
noteleport = 1
flags = NONE
//Abductors
/area/abductor_ship
@@ -83,6 +85,7 @@
requires_power = 0
noteleport = 1
has_gravity = 1
flags = NONE
//Syndicates
/area/syndicate_mothership
@@ -92,6 +95,7 @@
has_gravity = 1
noteleport = 1
blob_allowed = 0 //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
flags = NONE
/area/syndicate_mothership/control
name = "Syndicate Control Room"
+3 -3
View File
@@ -57,13 +57,13 @@
name = "Mining Station Communications"
/area/mine/cafeteria
name = "Mining station Cafeteria"
name = "Mining Station Cafeteria"
/area/mine/hydroponics
name = "Mining station Hydroponics"
name = "Mining Station Hydroponics"
/area/mine/sleeper
name = "Mining station Emergency Sleeper"
name = "Mining Station Emergency Sleeper"
/area/mine/north_outpost
name = "North Mining Outpost"
+14 -3
View File
@@ -115,15 +115,26 @@
/area/prison/solitary
name = "Solitary Confinement"
icon_state = "brig"
/area/prison/execution_room
name = "Prisoner Education Chamber"
icon_state = "armory"
/area/prison/cell_block/A
/area/prison/execution_room
name = "Prisoner Education Chamber"
icon_state = "armory"
/area/prison/cell_block/a
// /area/prison/cell_block/A
name = "Prison Cell Block A"
icon_state = "brig"
/area/prison/cell_block/B
/area/prison/cell_block/b
// /area/prison/cell_block/B
name = "Prison Cell Block B"
icon_state = "brig"
/area/prison/cell_block/C
/area/prison/cell_block/c
// /area/prison/cell_block/C
name = "Prison Cell Block C"
icon_state = "brig"
+35 -7
View File
@@ -21,20 +21,48 @@
//Areas
/area/ruin/powered/beach
icon_state = "dk_yellow"
/area/ruin/powered/clownplanet
icon_state = "dk_yellow"
/area/ruin/powered/animal_hospital
icon_state = "dk_yellow"
/area/ruin/powered/snow_biodome
icon_state = "dk_yellow"
/area/ruin/powered/gluttony
icon_state = "dk_yellow"
/area/ruin/powered/golem_ship
name = "Free Golem Ship"
icon_state = "dk_yellow"
/area/ruin/powered/greed
icon_state = "dk_yellow"
/area/ruin/unpowered/hierophant
name = "Hierophant's Arena"
icon_state = "dk_yellow"
/area/ruin/powered/pride
icon_state = "dk_yellow"
/area/ruin/powered/seedvault
icon_state = "dk_yellow"
/area/ruin/powered/syndicate_lava_base
name = "Secret Base"
icon_state = "dk_yellow"
/area/ruin/unpowered/no_grav/way_home
name = "\improper Salvation"
icon_state = "away"
/area/ruin/powered/snow_biodome
/area/ruin/powered/golem_ship
name = "Free Golem Ship"
/area/ruin/powered/syndicate_lava_base
name = "Secret Base"
// Ruins of "onehalf" ship
+36 -36
View File
@@ -28,8 +28,8 @@
var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
var/datum/proximity_monitor/proximity_monitor
var/datum/proximity_monitor/proximity_monitor
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
@@ -39,21 +39,21 @@
var/do_initialize = SSatoms.initialized
if(do_initialize > INITIALIZATION_INSSATOMS)
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
if(SSatoms.InitAtom(src, args))
//we were deleted
return
var/list/created = SSatoms.created_atoms
if(created)
created += src
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
if(SSatoms.InitAtom(src, args))
//we were deleted
return
var/list/created = SSatoms.created_atoms
if(created)
created += src
//Called after New if the map is being loaded. mapload = TRUE
//Called from base of New if the map is being loaded. mapload = FALSE
//This base must be called or derivatives must set initialized to TRUE
//must not sleep
//This base must be called or derivatives must set initialized to TRUE
//must not sleep
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
//Note: the following functions don't call the base for optimization and must copypasta:
// /turf/Initialize
@@ -76,23 +76,23 @@
if (opacity && isturf(loc))
var/turf/T = loc
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
return INITIALIZE_HINT_NORMAL
return INITIALIZE_HINT_NORMAL
//called if Initialize returns INITIALIZE_HINT_LATELOAD
//This version shouldn't be called
/atom/proc/LateInitialize()
var/static/list/warned_types = list()
if(!warned_types[type])
WARNING("Old style LateInitialize behaviour detected in [type]!")
warned_types[type] = TRUE
Initialize(FALSE)
//called if Initialize returns INITIALIZE_HINT_LATELOAD
//This version shouldn't be called
/atom/proc/LateInitialize()
var/static/list/warned_types = list()
if(!warned_types[type])
WARNING("Old style LateInitialize behaviour detected in [type]!")
warned_types[type] = TRUE
Initialize(FALSE)
/atom/Destroy()
if(alternate_appearances)
for(var/K in alternate_appearances)
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
AA.remove_from_hud(src)
for(var/K in alternate_appearances)
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
AA.remove_from_hud(src)
if(reagents)
qdel(reagents)
@@ -100,13 +100,13 @@
LAZYCLEARLIST(priority_overlays)
//SSoverlays.processing -= src //we COULD do this, but it's better to just let it fall out of the processing queue
QDEL_NULL(light)
QDEL_NULL(light)
return ..()
/atom/proc/handle_ricochet(obj/item/projectile/P)
return
/atom/proc/handle_ricochet(obj/item/projectile/P)
return
/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
return (!density || !height)
@@ -277,7 +277,7 @@
return
/atom/proc/ex_act(severity, target)
set waitfor = FALSE
set waitfor = FALSE
contents_explosion(severity, target)
/atom/proc/blob_act(obj/structure/blob/B)
@@ -509,10 +509,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
/atom/proc/mech_melee_attack(obj/mecha/M)
return
//If a mob logouts/logins in side of an object you can use this proc
/atom/proc/on_log(login)
if(loc)
loc.on_log(login)
//If a mob logouts/logins in side of an object you can use this proc
/atom/proc/on_log(login)
if(loc)
loc.on_log(login)
/*
+9
View File
@@ -0,0 +1,9 @@
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
@@ -274,6 +274,7 @@
return
/atom/proc/ex_act(severity, target)
+ set waitfor = FALSE
contents_explosion(severity, target)
/atom/proc/blob_act(obj/structure/blob/B)
+3 -3
View File
@@ -20,7 +20,7 @@
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
..()
if(blobwincount <= GLOB.blobs_legit.len)
SSblackbox.set_details("round_end_result","win - blob took over")
SSticker.mode_result = "win - blob took over"
to_chat(world, "<FONT size = 3><B>The blob has taken over the station!</B></FONT>")
to_chat(world, "<B>The entire station was eaten by the Blob!</B>")
log_game("Blob mode completed with a blob victory.")
@@ -28,7 +28,7 @@
SSticker.news_report = BLOB_WIN
else if(station_was_nuked)
SSblackbox.set_details("round_end_result","halfwin - nuke")
SSticker.mode_result = "halfwin - nuke"
to_chat(world, "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>")
to_chat(world, "<B>Directive 7-12 has been successfully carried out, preventing the Blob from spreading.</B>")
log_game("Blob mode completed with a tie (station destroyed).")
@@ -36,7 +36,7 @@
SSticker.news_report = BLOB_NUKE
else if(!GLOB.blob_cores.len)
SSblackbox.set_details("round_end_result","loss - blob eliminated")
SSticker.mode_result = "loss - blob eliminated"
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
to_chat(world, "<B>The alien organism has been eradicated from the station!</B>")
log_game("Blob mode completed with a crew victory.")
+3 -3
View File
@@ -191,7 +191,7 @@ Credit where due:
var/datum/game_mode/clockwork_cult/C = SSticker.mode
if(C.check_clockwork_victory())
text += "<span class='large_brass'><b>Ratvar's servants have succeeded in fulfilling His goals!</b></span>"
SSblackbox.set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
SSticker.mode_result = "win - servants completed their objective (summon ratvar)"
else
var/half_victory = FALSE
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in GLOB.all_clockwork_objects
@@ -200,10 +200,10 @@ Credit where due:
if(half_victory)
text += "<span class='large_brass'><b>The crew escaped before Ratvar could rise, but the gateway \
was successfully constructed!</b></span>"
SSblackbox.set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
SSticker.mode_result = "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)"
else
text += "<span class='userdanger'>Ratvar's servants have failed!</span>"
SSblackbox.set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
SSticker.mode_result = "loss - servants failed their objective (summon ratvar)"
text += "<br><b>The servants' objective was:</b> <br>[CLOCKCULT_OBJECTIVE]"
text += "<br>Ratvar's servants had <b>[GLOB.clockwork_caches]</b> Tinkerer's Caches."
text += "<br><b>Construction Value(CV)</b> was: <b>[GLOB.clockwork_construction_value]</b>"
+4 -13
View File
@@ -208,12 +208,10 @@
/datum/game_mode/cult/declare_completion()
if(!check_cult_victory())
SSblackbox.set_details("round_end_result","win - cult win")
SSblackbox.set_val("round_end_result",acolytes_survived)
SSticker.mode_result = "win - cult win"
to_chat(world, "<span class='greentext'>The cult has succeeded! Nar-sie has snuffed out another torch in the void!</span>")
else
SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
SSblackbox.set_val("round_end_result",acolytes_survived)
SSticker.mode_result = "loss - staff stopped the cult"
to_chat(world, "<span class='redtext'>The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!</span>")
var/text = ""
@@ -257,22 +255,15 @@
/datum/game_mode/proc/datum_cult_completion()
var/text = ""
var/acolytes_survived = 0
for(var/datum/mind/cult_mind in cult)
if (cult_mind.current && cult_mind.current.stat != DEAD)
if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
acolytes_survived++
var/cult_fail = 0
cult_fail += eldergod
if(!GLOB.sac_complete)
cult_fail++
if(!cult_fail)
SSblackbox.set_details("round_end_result","win - cult win")
SSblackbox.set_val("round_end_result",acolytes_survived)
SSticker.mode_result = "win - cult win"
to_chat(world, "<span class='greentext'>The cult has succeeded! Nar-sie has snuffed out another torch in the void!</span>")
else
SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
SSblackbox.set_val("round_end_result",acolytes_survived)
SSticker.mode_result = "loss - staff stopped the cult"
to_chat(world, "<span class='redtext'>The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!</span>")
if(cult_objectives.len)
text += "<br><b>The cultists' objectives were:</b>"
+4 -1
View File
@@ -225,7 +225,10 @@ This file contains the arcane tome files.
"<span class='cult'>You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.</span>")
if(user.blood_volume)
user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick("l_arm", "r_arm"))
if(!do_after(user, initial(rune_to_scribe.scribe_delay), target = get_turf(user)))
var/scribe_mod = initial(rune_to_scribe.scribe_delay)
if(istype(get_turf(user), /turf/open/floor/engine/cult))
scribe_mod *= 0.5
if(!do_after(user, scribe_mod, target = get_turf(user)))
for(var/V in shields)
var/obj/structure/emergency_shield/sanguine/S = V
if(S && !QDELETED(S))
@@ -46,7 +46,10 @@
if(damage_interrupt && isliving(owner))
var/mob/living/L = owner
health = list("health" = L.health)
if(do_after(owner, scribe_time, target = owner, extra_checks = CALLBACK(owner, /mob.proc/break_do_after_checks, health, action_interrupt)))
var/scribe_mod = scribe_time
if(istype(get_turf(owner), /turf/open/floor/engine/cult))
scribe_mod *= 0.5
if(do_after(owner, scribe_mod, target = owner, extra_checks = CALLBACK(owner, /mob.proc/break_do_after_checks, health, action_interrupt)))
var/obj/effect/rune/new_rune = new rune_type(owner.loc)
new_rune.keyword = chosen_keyword
else
+11 -5
View File
@@ -80,11 +80,17 @@
report = config.intercept
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
SSblackbox.set_details("round_start","[time2text(world.realtime)]")
if(SSticker && SSticker.mode)
SSblackbox.set_details("game_mode","[SSticker.mode]")
if(GLOB.revdata.commit)
SSblackbox.set_details("revision","[GLOB.revdata.commit]")
if(SSdbcore.Connect())
var/sql
if(SSticker && SSticker.mode)
sql += "game_mode = '[SSticker.mode]'"
if(sql)
sql += ", "
if(GLOB.revdata.commit)
sql += "commit_hash = '[GLOB.revdata.commit]'"
if(sql)
var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
query_round_game_mode.Execute()
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
+22 -7
View File
@@ -33,13 +33,14 @@
/obj/machinery/dominator/tesla_act()
qdel(src)
/obj/machinery/dominator/New()
..()
/obj/machinery/dominator/Initialize()
. = ..()
set_light(2)
GLOB.poi_list |= src
spark_system = new
spark_system.set_up(5, TRUE, src)
countdown = new(src)
update_icon()
/obj/machinery/dominator/examine(mob/user)
..()
@@ -103,8 +104,23 @@
spark_system.start()
else if(!(stat & BROKEN))
spark_system.start()
cut_overlays()
update_icon()
/obj/machinery/dominator/update_icon()
cut_overlays()
if(!(stat & BROKEN))
icon_state = "dominator-active"
if(operating)
var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
if(gang)
dominator_overlay.color = gang.color_hex
add_overlay(dominator_overlay)
else
icon_state = "dominator"
if(obj_integrity/max_integrity < 0.66)
add_overlay("damage")
else
icon_state = "dominator-broken"
/obj/machinery/dominator/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
@@ -142,10 +158,9 @@
gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1)
set_light(0)
icon_state = "dominator-broken"
cut_overlays()
operating = 0
stat |= BROKEN
update_icon()
STOP_PROCESSING(SSmachines, src)
/obj/machinery/dominator/Destroy()
@@ -196,9 +211,9 @@
priority_announce("Network breach detected in [locname]. The [gang.name] Gang is attempting to seize control of the station!","Network Alert")
gang.domination()
SSshuttle.registerHostileEnvironment(src)
src.name = "[gang.name] Gang [src.name]"
name = "[gang.name] Gang [name]"
operating = 1
icon_state = "dominator-[gang.color]"
update_icon()
countdown.color = gang.color_hex
countdown.start()
+16 -2
View File
@@ -261,6 +261,20 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
gang_bosses += G.bosses
return gang_bosses
/datum/game_mode/proc/shuttle_check()
if(SSshuttle.emergencyNoRecall)
return
var/alive = 0
for(var/mob/living/L in GLOB.player_list)
if(L.stat != DEAD)
alive++
if((alive < (GLOB.joined_player_list.len * 0.4)) && ((SSshuttle.emergency.timeLeft(1) > (SSshuttle.emergencyCallTime * 0.4))))
SSshuttle.emergencyNoRecall = TRUE
SSshuttle.emergency.request(null, set_coefficient = 0.4)
priority_announce("Catastrophic casualties detected: crisis shuttle protocols activated - jamming recall signals across all frequencies.")
/proc/determine_domination_time(var/datum/gang/G)
return max(180,480 - (round((G.territory.len/GLOB.start_state.num_territories)*100, 1) * 9))
@@ -274,12 +288,12 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
return
if(!winner)
to_chat(world, "<span class='redtext'>The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]</span><br>")
SSblackbox.set_details("round_end_result","loss - gangs failed takeover")
SSticker.mode_result = "loss - gangs failed takeover"
SSticker.news_report = GANG_LOSS
else
to_chat(world, "<span class='redtext'>The [winner.name] Gang successfully performed a hostile takeover of the station!</span><br>")
SSblackbox.set_details("round_end_result","win - gang domination complete")
SSticker.mode_result = "win - gang domination complete"
SSticker.news_report = GANG_TAKEOVER
+3 -1
View File
@@ -202,7 +202,9 @@
return
var/added_names = ""
var/lost_names = ""
SSticker.mode.shuttle_check() // See if its time to start wrapping things up
//Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report
var/list/reclaimed_territories = territory_new & territory_lost
territory |= reclaimed_territories
+3
View File
@@ -167,6 +167,9 @@
if(!can_use(user))
return 0
if(SSshuttle.emergencyNoRecall)
return 0
if(recalling)
to_chat(usr, "<span class='warning'>Error: Recall already in progress.</span>")
return 0
+1 -3
View File
@@ -50,8 +50,6 @@
else
to_chat(world, "<span class='boldnotice'>Nobody survived the meteor storm!</span>")
SSblackbox.set_details("round_end_result","end - evacuation")
SSblackbox.set_val("round_end_result",survivors)
SSticker.mode_result = "end - evacuation"
..()
return 1
+4 -4
View File
@@ -31,15 +31,15 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinal)
pickedstart = spaceDebrisStartLoc(startSide, 1)
pickedgoal = spaceDebrisFinishLoc(startSide, 1)
pickedstart = spaceDebrisStartLoc(startSide, ZLEVEL_STATION)
pickedgoal = spaceDebrisFinishLoc(startSide, ZLEVEL_STATION)
max_i--
if(max_i<=0)
return
var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
M.z_original = 1
M.z_original = ZLEVEL_STATION
spawn(0)
walk_towards(M, M.dest, 1)
@@ -96,7 +96,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
pass_flags = PASSTABLE
var/heavy = 0
var/meteorsound = 'sound/effects/meteorimpact.ogg'
var/z_original = 1
var/z_original = ZLEVEL_STATION
var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME
@@ -181,6 +181,7 @@
to_chat(H, "<span class='warning'>You feel intensely watched.</span>")
sleep(5)
to_chat(H, "<span class='warning'><b>Your mind snaps!</b></span>")
to_chat(H, "<big><span class='warning'><b>You can't remember how you got here...</b></span></big>")
var/objtype = pick(subtypesof(/datum/objective/abductee/))
var/datum/objective/abductee/O = new objtype()
SSticker.mode.abductees += H.mind
@@ -107,10 +107,8 @@
/datum/game_mode/monkey/declare_completion()
if(check_monkey_victory())
SSblackbox.set_details("round_end_result","win - monkey win")
SSblackbox.set_val("round_end_result",escaped_monkeys)
SSticker.mode_result = "win - monkey win"
to_chat(world, "<span class='userdanger'>The monkeys have overthrown their captors! Eeek eeeek!!</span>")
else
SSblackbox.set_details("round_end_result","loss - staff stopped the monkeys")
SSblackbox.set_val("round_end_result",escaped_monkeys)
SSticker.mode_result = "loss - staff stopped the monkeys"
to_chat(world, "<span class='userdanger'>The staff managed to contain the monkey infestation!</span>")
+10 -10
View File
@@ -201,70 +201,70 @@
if(nuke_off_station == NUKE_SYNDICATE_BASE)
SSblackbox.set_details("round_end_result","loss - syndicate nuked - disk secured")
SSticker.mode_result = "loss - syndicate nuked - disk secured"
to_chat(world, "<FONT size = 3><B>Humiliating Syndicate Defeat</B></FONT>")
to_chat(world, "<B>The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed!</B> Next time, don't lose the nuke!")
SSticker.news_report = NUKE_SYNDICATE_BASE
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
SSblackbox.set_details("round_end_result","win - syndicate nuke")
SSticker.mode_result = "win - syndicate nuke"
to_chat(world, "<FONT size = 3><B>Syndicate Major Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives have destroyed [station_name()]!</B>")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
SSblackbox.set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
to_chat(world, "<FONT size = 3><B>Total Annihilation</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
SSblackbox.set_details("round_end_result","halfwin - blew wrong station")
SSticker.mode_result = "halfwin - blew wrong station"
to_chat(world, "<FONT size = 3><B>Crew Minor Victory</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
SSblackbox.set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time"
to_chat(world, "<FONT size = 3><B>[syndicate_name()] operatives have earned Darwin Award!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
SSblackbox.set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead"
to_chat(world, "<FONT size = 3><B>Crew Major Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disk and killed the [syndicate_name()] Operatives</B>")
SSticker.news_report = OPERATIVES_KILLED
else if (disk_rescued)
SSblackbox.set_details("round_end_result","loss - evacuation - disk secured")
SSticker.mode_result = "loss - evacuation - disk secured"
to_chat(world, "<FONT size = 3><B>Crew Major Victory</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!</B>")
SSticker.news_report = OPERATIVES_KILLED
else if (!disk_rescued && are_operatives_dead())
SSblackbox.set_details("round_end_result","halfwin - evacuation - disk not secured")
SSticker.mode_result = "halfwin - evacuation - disk not secured"
to_chat(world, "<FONT size = 3><B>Neutral Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!</B>")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && crew_evacuated)
SSblackbox.set_details("round_end_result","halfwin - detonation averted")
SSticker.mode_result = "halfwin - detonation averted"
to_chat(world, "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()].</B> Next time, don't lose the disk!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && !crew_evacuated)
SSblackbox.set_details("round_end_result","halfwin - interrupted")
SSticker.mode_result = "halfwin - interrupted"
to_chat(world, "<FONT size = 3><B>Neutral Victory</B></FONT>")
to_chat(world, "<B>Round was mysteriously interrupted!</B>")
+1 -1
View File
@@ -459,7 +459,7 @@
var/datum/game_mode/nuclear/NM = SSticker.mode
NM.nukes_left --
if(!SSticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
SSticker.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
SSticker.Reboot("Station destroyed by Nuclear Device.", "nuke - unhandled ending")
/*
+2 -2
View File
@@ -345,13 +345,13 @@
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
SSblackbox.set_details("round_end_result","win - heads killed")
SSticker.mode_result = "win - heads killed"
to_chat(world, "<span class='redtext'>The heads of staff were killed or exiled! The revolutionaries win!</span>")
SSticker.news_report = REVS_WIN
else if(finished == 2)
SSblackbox.set_details("round_end_result","loss - rev heads killed")
SSticker.mode_result = "loss - rev heads killed"
to_chat(world, "<span class='redtext'>The heads of staff managed to stop the revolution!</span>")
SSticker.news_report = REVS_LOSE
+1 -1
View File
@@ -133,7 +133,7 @@
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
SSblackbox.set_details("round_end_result","loss - wizard killed")
SSticker.mode_result = "loss - wizard killed"
to_chat(world, "<FONT size=3><B>The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT>")
..(1)
+1 -1
View File
@@ -180,7 +180,7 @@
/datum/game_mode/wizard/declare_completion()
if(finished)
SSblackbox.set_details("round_end_result","loss - wizard killed")
SSticker.mode_result = "loss - wizard killed"
to_chat(world, "<span class='userdanger'>The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</span>")
SSticker.news_report = WIZARD_KILLED
+19 -20
View File
@@ -5,7 +5,7 @@
start_active = 1
/obj/machinery/camera/emp_proof/Initialize()
..()
. = ..()
upgradeEmpProof()
// X-RAY
@@ -15,7 +15,7 @@
icon_state = "xraycam" // Thanks to Krutchen for the icons.
/obj/machinery/camera/xray/Initialize()
..()
. = ..()
upgradeXRay()
// MOTION
@@ -32,7 +32,7 @@
start_active = 1
/obj/machinery/camera/all/Initialize()
..()
. = ..()
upgradeEmpProof()
upgradeXRay()
upgradeMotion()
@@ -43,23 +43,22 @@
var/number = 0 //camera number in area
//This camera type automatically sets it's name to whatever the area that it's in is called.
/obj/machinery/camera/autoname/Initialize(mapload)
if(mapload)
..()
return TRUE
else
if(!initialized)
..()
number = 1
var/area/A = get_area(src)
if(A)
for(var/obj/machinery/camera/autoname/C in GLOB.machines)
if(C == src) continue
var/area/CA = get_area(C)
if(CA.type == A.type)
if(C.number)
number = max(number, C.number+1)
c_tag = "[A.name] #[number]"
/obj/machinery/camera/autoname/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/camera/autoname/LateInitialize()
. = ..()
number = 1
var/area/A = get_area(src)
if(A)
for(var/obj/machinery/camera/autoname/C in GLOB.machines)
if(C == src) continue
var/area/CA = get_area(C)
if(CA.type == A.type)
if(C.number)
number = max(number, C.number+1)
c_tag = "[A.name] #[number]"
// CHECKS
+9 -5
View File
@@ -1056,17 +1056,21 @@
/obj/effect/mob_spawn/human/corpse/orionsecurity
name = "Spaceport Security"
id_job = "Officer"
id_access_list = list(GLOB.access_syndicate)
outfit = /datum/outfit/orionsecurity
/datum/outfit/orionsecurity
name = "Orion Spaceport Security"
uniform = /obj/item/clothing/under/syndicate
suit = /obj/item/clothing/suit/armor/vest
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
radio = /obj/item/device/radio/headset
ears = /obj/item/device/radio/headset
mask = /obj/item/clothing/mask/gas
helmet = /obj/item/clothing/head/helmet/swat
head = /obj/item/clothing/head/helmet/swat
back = /obj/item/weapon/storage/backpack
has_id = 1
id_job = "Officer"
id_access_list = list(GLOB.access_syndicate)
id = /obj/item/weapon/card/id
/obj/item/weapon/orion_ship
name = "model settler ship"
+7 -2
View File
@@ -24,7 +24,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
//Cooldown for closing positions in seconds
//if set to -1: No cooldown... probably a bad idea
//if set to 0: Not able to close "original" positions. You can only close positions that you have opened before
var/change_position_cooldown = 60
var/change_position_cooldown = 30
//Jobs you cannot open new positions for
var/list/blacklisted = list(
"AI",
@@ -46,6 +46,11 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/card/Initialize()
. = ..()
change_position_cooldown = config.id_console_jobslot_delay
/obj/machinery/computer/card/attackby(obj/O, mob/user, params)//TODO:SANITY
if(istype(O, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/idcard = O
@@ -532,7 +537,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
SSjob.prioritized_jobs += j
prioritycount++
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if ("print")
+13 -10
View File
@@ -98,20 +98,14 @@
/obj/machinery/door/airlock/Initialize()
. = ..()
wires = new /datum/wires/airlock(src)
if (cyclelinkeddir)
cyclelinkairlock()
if(frequency)
set_frequency(frequency)
update_icon()
wires = new /datum/wires/airlock(src)
if(src.closeOtherId != null)
spawn (5)
for (var/obj/machinery/door/airlock/A in GLOB.airlocks)
if(A.closeOtherId == src.closeOtherId && A != src)
src.closeOther = A
break
if(closeOtherId != null)
addtimer(CALLBACK(.proc/update_other_id), 5)
if(glass)
airlock_material = "glass"
if(security_level > AIRLOCK_SECURITY_METAL)
@@ -127,6 +121,15 @@
diag_hud.add_to_hud(src)
diag_hud_set_electrified()
update_icon()
/obj/machinery/door/airlock/proc/update_other_id()
for(var/obj/machinery/door/airlock/A in GLOB.airlocks)
if(A.closeOtherId == closeOtherId && A != src)
closeOther = A
break
/obj/machinery/door/airlock/proc/cyclelinkairlock()
if (cyclelinkedairlock)
cyclelinkedairlock.cyclelinkedairlock = null
+4 -4
View File
@@ -1,5 +1,5 @@
GLOBAL_LIST_EMPTY(doppler_arrays)
GLOBAL_LIST_EMPTY(doppler_arrays)
/obj/machinery/doppler_array
name = "tachyon-doppler array"
desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array.\n<span class='notice'>Alt-click to rotate it clockwise.</span>"
@@ -13,10 +13,10 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
/obj/machinery/doppler_array/New()
..()
GLOB.doppler_arrays += src
GLOB.doppler_arrays += src
/obj/machinery/doppler_array/Destroy()
GLOB.doppler_arrays -= src
GLOB.doppler_arrays -= src
return ..()
/obj/machinery/doppler_array/process()
+12 -2
View File
@@ -51,7 +51,7 @@ Possible to do for anyone motivated enough:
var/static/list/holopads = list()
/obj/machinery/holopad/Initialize()
..()
. = ..()
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/holopad(null)
B.apply_default_parts(src)
holopads += src
@@ -73,7 +73,7 @@ Possible to do for anyone motivated enough:
if (powered())
stat &= ~NOPOWER
else
stat |= ~NOPOWER
stat |= NOPOWER
if(outgoing_call)
outgoing_call.ConnectionFailure(src)
@@ -118,6 +118,10 @@ Possible to do for anyone motivated enough:
return ..()
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
if(isAI(user))
hangup_all_calls()
return
if(!CheckCallClose())
interact(user)
@@ -163,6 +167,12 @@ Possible to do for anyone motivated enough:
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
//Stop ringing the AI!!
/obj/machinery/holopad/proc/hangup_all_calls()
for(var/I in holo_calls)
var/datum/holocall/HC = I
HC.Disconnect(src)
/obj/machinery/holopad/Topic(href, href_list)
if(..() || isAI(usr))
return
@@ -87,7 +87,9 @@
if(has_cover)
cover = new /obj/machinery/porta_turret_cover(loc)
cover.parent_turret = src
underlays += image('icons/obj/turrets.dmi',icon_state = "basedark")
var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark")
base.layer = NOT_HIGH_OBJ_LAYER
underlays += base
if(!has_cover)
INVOKE_ASYNC(src, .proc/popUp)
@@ -1100,4 +1102,4 @@
if(target == user || target == get_turf(src))
return
target_turf = get_turf(target)
fire_helper(target_turf)
fire_helper(user)
+12 -17
View File
@@ -86,23 +86,24 @@
req_access = list(GLOB.access_engine)
max_integrity = 100
obj_integrity = 100
var/active = 0
var/list/deployed_shields = list()
var/active = FALSE
var/list/deployed_shields
var/locked = 0
var/shield_range = 4
/obj/machinery/shieldgen/Destroy()
for(var/obj/structure/emergency_shield/ES in deployed_shields)
qdel(ES)
/obj/machinery/shieldgen/Initialize(mapload)
. = ..()
deployed_shields = list()
if(mapload && active && anchored)
shields_up()
/obj/machinery/shieldgen/Destroy()
QDEL_LIST(deployed_shields)
return ..()
/obj/machinery/shieldgen/proc/shields_up()
if(active)
return 0 //If it's already turned on, how did this get called?
active = 1
active = TRUE
update_icon()
for(var/turf/target_tile in range(shield_range, src))
@@ -111,15 +112,9 @@
deployed_shields += new /obj/structure/emergency_shield(target_tile)
/obj/machinery/shieldgen/proc/shields_down()
if(!active)
return 0 //If it's already off, how did this get called?
active = 0
active = FALSE
update_icon()
for(var/obj/structure/emergency_shield/ES in deployed_shields)
qdel(ES)
deployed_shields.Cut()
QDEL_LIST(deployed_shields)
/obj/machinery/shieldgen/process()
if((stat & BROKEN) && active)
+1 -1
View File
@@ -154,7 +154,7 @@
M.forceMove(loc)
if(prob(30))
explosion(get_turf(loc), 0, 0, 1, 3)
explosion(get_turf(loc), 0, 0, 1, 3)
if(wreckage)
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
+4 -4
View File
@@ -12,8 +12,8 @@
var/poster_type
var/obj/structure/sign/poster/poster_structure
/obj/item/weapon/poster/New(loc, obj/structure/sign/poster/new_poster_structure)
..()
/obj/item/weapon/poster/Initialize(mapload, obj/structure/sign/poster/new_poster_structure)
. = ..()
poster_structure = new_poster_structure
if(!new_poster_structure && poster_type)
poster_structure = new poster_type(src)
@@ -58,8 +58,8 @@
var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here."
var/poster_item_icon_state = "rolled_poster"
/obj/structure/sign/poster/New()
..()
/obj/structure/sign/poster/Initialize()
. = ..()
if(random_basetype)
randomise(random_basetype)
if(!ruined)
+1 -1
View File
@@ -39,7 +39,7 @@
var/range_flash = 3
/obj/effect/mine/explosive/mineEffect(mob/victim)
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
/obj/effect/mine/stun
+5 -6
View File
@@ -1,19 +1,18 @@
/obj/item/weapon/poster/wanted
icon_state = "rolled_poster"
/obj/item/weapon/poster/wanted/New(turf/loc, icon/person_icon, wanted_name, description)
var/obj/structure/sign/poster/wanted/wanted_poster = new(person_icon, wanted_name, description)
..(loc, wanted_poster)
/obj/item/weapon/poster/wanted/Initialize(mapload, icon/person_icon, wanted_name, description)
. = ..(mapload, new /obj/structure/sign/poster/wanted(src, person_icon, wanted_name, description))
name = "wanted poster ([wanted_name])"
desc = "A wanted poster for [wanted_name]."
/obj/structure/sign/poster/wanted
var/wanted_name
/obj/structure/sign/poster/wanted/New(var/icon/person_icon, var/person_name, var/description)
/obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description)
. = ..()
if(!person_icon)
qdel(src)
return
return INITIALIZE_HINT_QDEL
name = "wanted poster ([person_name])"
wanted_name = person_name
desc = description
+2 -2
View File
@@ -897,9 +897,9 @@ GLOBAL_LIST_EMPTY(PDAs)
if(T)
T.hotspot_expose(700,125)
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
explosion(T, -1, 1, 3, 4)
explosion(T, -1, 1, 3, 4)
else
explosion(T, -1, -1, 2, 3)
explosion(T, -1, -1, 2, 3)
qdel(src)
return
+8 -9
View File
@@ -10,15 +10,14 @@
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
/obj/item/device/paicard/Initialize()
..()
SSpai.pai_card_list += src
add_overlay("pai-off")
return ..()
/obj/item/device/paicard/Destroy()
//Will stop people throwing friend pAIs into the singularity so they can respawn
SSpai.pai_card_list -= src
if(!isnull(pai))
pai.death(0)
QDEL_NULL(pai)
return ..()
/obj/item/device/paicard/attack_self(mob/user)
@@ -26,9 +25,9 @@
return
user.set_machine(src)
var/dat = "<TT><B>Personal AI Device</B><BR>"
if(pai && (!pai.master_dna || !pai.master))
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
if(pai)
if(!pai.master_dna || !pai.master)
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
dat += "Installed Personality: [pai.name]<br>"
dat += "Prime directive: <br>[pai.laws.zeroth]<br>"
for(var/slaws in pai.laws.supplied)
@@ -86,7 +85,7 @@
to_chat(pai, "<span class='danger'>Byte by byte you lose your sense of self.</span>")
to_chat(pai, "<span class='userdanger'>Your mental faculties leave you.</span>")
to_chat(pai, "<span class='rose'>oblivion... </span>")
pai.death(0)
removePersonality()
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(pai.radio)
@@ -119,9 +118,9 @@
audible_message("\The [src] plays a cheerful startup noise!")
/obj/item/device/paicard/proc/removePersonality()
src.pai = null
src.cut_overlays()
src.add_overlay("pai-off")
QDEL_NULL(pai)
cut_overlays()
add_overlay("pai-off")
/obj/item/device/paicard/proc/setEmotion(emotion)
if(pai)
+1 -1
View File
@@ -141,5 +141,5 @@
if(power_drained >= max_power)
STOP_PROCESSING(SSobj, src)
explosion(src.loc, 4,8,16,32)
explosion(src.loc, 4,8,16,32)
qdel(src)
@@ -22,6 +22,11 @@ Mineral Sheets
/obj/item/stack/sheet/mineral
icon = 'icons/obj/mining.dmi'
/obj/item/stack/sheet/mineral/Initialize(mapload)
pixel_x = rand(-4, 4)
pixel_y = rand(-4, 4)
. = ..()
/*
* Sandstone
*/
@@ -31,9 +36,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
/* new/datum/stack_recipe("sandstone wall", ???), \
new/datum/stack_recipe("sandstone floor", ???),\ */
new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1) \
))
/obj/item/stack/sheet/mineral/sandstone
@@ -49,9 +52,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
/obj/item/stack/sheet/mineral/sandstone/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.sandstone_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/obj/item/stack/sheet/mineral/sandstone/thirty
amount = 30
@@ -74,9 +75,24 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
/obj/item/stack/sheet/mineral/sandbags/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.sandbag_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/obj/item/weapon/emptysandbag
name = "empty sandbag"
desc = "A bag to be filled with sand."
icon = 'icons/obj/items.dmi'
icon_state = "sandbag"
w_class = WEIGHT_CLASS_TINY
/obj/item/weapon/emptysandbag/attackby(obj/item/W, mob/user, params)
if(istype(W,/obj/item/weapon/ore/glass))
to_chat(user, "<span class='notice'>You fill the sandbag.</span>")
var/obj/item/stack/sheet/mineral/sandbags/I = new /obj/item/stack/sheet/mineral/sandbags
qdel(src)
user.put_in_hands(I)
qdel(W)
else
return ..()
/*
* Diamond
@@ -99,9 +115,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
/obj/item/stack/sheet/mineral/diamond/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.diamond_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
* Uranium
@@ -123,9 +137,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
/obj/item/stack/sheet/mineral/uranium/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.uranium_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
* Plasma
@@ -149,9 +161,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
/obj/item/stack/sheet/mineral/plasma/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plasma_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/obj/item/stack/sheet/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
@@ -190,9 +200,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
/obj/item/stack/sheet/mineral/gold/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.gold_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
* Silver
@@ -217,9 +225,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
/obj/item/stack/sheet/mineral/silver/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.silver_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
* Clown
@@ -239,9 +245,7 @@ GLOBAL_LIST_INIT(clown_recipes, list ( \
/obj/item/stack/sheet/mineral/bananium/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.clown_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
* Titanium
@@ -265,9 +269,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
/obj/item/stack/sheet/mineral/titanium/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.titanium_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
@@ -292,9 +294,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
/obj/item/stack/sheet/mineral/plastitanium/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plastitanium_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/*
@@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
/obj/item/stack/sheet/mineral/snow/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.snow_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
. = ..()
/****************************** Others ****************************/
@@ -347,7 +345,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.adamantine_recipes
..()
. = ..()
/*
* Mythril
@@ -384,4 +382,4 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
/obj/item/stack/sheet/mineral/abductor/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.abductor_recipes
..()
. = ..()
+66 -72
View File
@@ -14,14 +14,16 @@
origin_tech = "combat=1;plasmatech=2;engineering=2"
resistance_flags = FIRE_PROOF
var/status = 0
var/throw_amount = 100
var/lit = 0 //on or off
var/operating = 0//cooldown
var/obj/item/weapon/weldingtool/weldtool = null
var/obj/item/device/assembly/igniter/igniter = null
var/obj/item/weapon/tank/internals/plasma/ptank = null
var/warned_admins = 0 //for the message_admins() when lit
//variables for prebuilt flamethrowers
var/create_full = FALSE
var/create_with_tank = FALSE
var/igniter_type = /obj/item/device/assembly/igniter
/obj/item/weapon/flamethrower/Destroy()
if(weldtool)
@@ -32,9 +34,8 @@
qdel(ptank)
return ..()
/obj/item/weapon/flamethrower/process()
if(!lit)
if(!lit || !igniter)
STOP_PROCESSING(SSobj, src)
return null
var/turf/location = loc
@@ -43,8 +44,7 @@
if(M.is_holding(src))
location = M.loc
if(isturf(location)) //start a fire if possible
location.hotspot_expose(700, 2)
return
igniter.flamethrower_process(location)
/obj/item/weapon/flamethrower/update_icon()
@@ -58,6 +58,9 @@
item_state = "flamethrower_1"
else
item_state = "flamethrower_0"
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
return
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, flag)
@@ -82,13 +85,13 @@
if(istype(W, /obj/item/weapon/wrench) && !status)//Taking this apart
var/turf/T = get_turf(src)
if(weldtool)
weldtool.loc = T
weldtool.forceMove(T)
weldtool = null
if(igniter)
igniter.loc = T
igniter.forceMove(T)
igniter = null
if(ptank)
ptank.loc = T
ptank.forceMove(T)
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
@@ -114,7 +117,10 @@
else if(istype(W,/obj/item/weapon/tank/internals/plasma))
if(ptank)
to_chat(user, "<span class='notice'>There is already a plasma tank loaded in [src]!</span>")
if(user.transferItemToLoc(W,src))
ptank.forceMove(get_turf(src))
ptank = W
to_chat(user, "<span class='notice'>You swap the plasma tank in [src]!</span>")
return
if(!user.transferItemToLoc(W, src))
return
@@ -129,53 +135,26 @@
/obj/item/weapon/flamethrower/attack_self(mob/user)
if(user.stat || user.restrained() || user.lying)
return
user.set_machine(src)
toggle_igniter(user)
/obj/item/weapon/flamethrower/proc/toggle_igniter(mob/user)
if(!ptank)
to_chat(user, "<span class='notice'>Attach a plasma tank first!</span>")
return
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove plasmatank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
user << browse(dat, "window=flamethrower;size=600x300")
onclose(user, "flamethrower")
return
/obj/item/weapon/flamethrower/Topic(href,href_list[])
if(href_list["close"])
usr.unset_machine()
usr << browse(null, "window=flamethrower")
if(!status)
to_chat(user, "<span class='notice'>Secure the igniter first!</span>")
return
if(usr.stat || usr.restrained() || usr.lying)
return
usr.set_machine(src)
if(href_list["light"])
if(!ptank)
return
if(!status)
return
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
if(!warned_admins)
message_admins("[ADMIN_LOOKUPFLW(usr)] has lit a flamethrower.")
warned_admins = 1
if(href_list["amount"])
throw_amount = throw_amount + text2num(href_list["amount"])
throw_amount = max(50, min(5000, throw_amount))
if(href_list["remove"])
if(!ptank)
return
usr.put_in_hands(ptank)
ptank = null
lit = 0
usr.unset_machine()
usr << browse(null, "window=flamethrower")
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
to_chat(user, "<span class='notice'>You ignite [src]!</span>")
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
if(!warned_admins)
message_admins("[ADMIN_LOOKUPFLW(user)] has lit a flamethrower.")
warned_admins = 1
else
STOP_PROCESSING(SSobj,src)
update_icon()
return
/obj/item/weapon/flamethrower/CheckParts(list/parts_list)
..()
@@ -195,19 +174,22 @@
for(var/turf/T in turflist)
if(T == previousturf)
continue //so we don't burn the tile we be standin on
if(!T.atmos_adjacent_turfs || !T.atmos_adjacent_turfs[previousturf])
var/list/turfs_sharing_with_prev = previousturf.GetAtmosAdjacentTurfs(alldir=1)
if(!(T in turfs_sharing_with_prev))
break
ignite_turf(T)
if(igniter)
igniter.ignite_turf(src,T)
else
default_ignite(T)
sleep(1)
previousturf = T
operating = 0
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
return
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target, release_amount = 0.05)
/obj/item/weapon/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
@@ -218,30 +200,42 @@
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
//location.hotspot_expose(1000,500,1)
SSair.add_to_active(target, 0)
return
/obj/item/weapon/flamethrower/full/New(var/loc)
..()
if(!weldtool)
weldtool = new /obj/item/weapon/weldingtool(src)
weldtool.status = 0
if(!igniter)
igniter = new /obj/item/device/assembly/igniter(src)
igniter.secured = 0
status = 1
update_icon()
/obj/item/weapon/flamethrower/Initialize(mapload)
. = ..()
if(create_full)
if(!weldtool)
weldtool = new /obj/item/weapon/weldingtool(src)
weldtool.status = 0
if(!igniter)
igniter = new igniter_type(src)
igniter.secured = 0
status = 1
if(create_with_tank)
ptank = new /obj/item/weapon/tank/internals/plasma/full(src)
update_icon()
/obj/item/weapon/flamethrower/full/tank/New(var/loc)
..()
ptank = new /obj/item/weapon/tank/internals/plasma/full(src)
update_icon()
/obj/item/weapon/flamethrower/full/tank
create_full = TRUE
/obj/item/weapon/flamethrower/full/tank
create_with_tank = TRUE
/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!</span>")
var/target_turf = get_turf(owner)
ignite_turf(target_turf, 100)
igniter.ignite_turf(src,target_turf, release_amount = 100)
qdel(ptank)
return 1 //It hit the flamethrower, not them
/obj/item/device/assembly/igniter/proc/flamethrower_process(turf/open/location)
location.hotspot_expose(700,2)
/obj/item/device/assembly/igniter/cold/flamethrower_process(turf/open/location)
return
/obj/item/device/assembly/igniter/proc/ignite_turf(obj/item/weapon/flamethrower/F,turf/open/location,release_amount = 0.05)
F.default_ignite(location,release_amount)
@@ -59,7 +59,7 @@
/obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up
update_mob()
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
qdel(src)
/obj/item/weapon/grenade/iedcasing/examine(mob/user)
@@ -9,7 +9,7 @@
/obj/item/weapon/grenade/syndieminibomb/prime()
update_mob()
explosion(src.loc,1,2,4,flame_range = 2)
explosion(src.loc,1,2,4,flame_range = 2)
qdel(src)
/obj/item/weapon/grenade/syndieminibomb/concussion
@@ -20,7 +20,7 @@
/obj/item/weapon/grenade/syndieminibomb/concussion/prime()
update_mob()
explosion(src.loc,0,2,3,flame_range = 3)
explosion(src.loc,0,2,3,flame_range = 3)
qdel(src)
/obj/item/weapon/grenade/syndieminibomb/concussion/frag
@@ -83,7 +83,7 @@
/obj/item/weapon/storage/backpack/holding/singularity_act(current_size)
var/dist = max((current_size - 2),1)
explosion(src.loc,(dist),(dist*2),(dist*4))
explosion(src.loc,(dist),(dist*2),(dist*4))
return
@@ -203,7 +203,7 @@
/obj/item/organ/hivelord_core,
/obj/item/device/wormhole_jaunter,
/obj/item/weapon/storage/bag/plants,
/obj/item/stack/marker_beacon
)
@@ -249,8 +249,8 @@
/obj/item/weapon/storage/belt/military
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "explorer1"
item_state = "explorer1"
icon_state = "militarywebbing"
item_state = "militarywebbing"
max_w_class = WEIGHT_CLASS_SMALL
/obj/item/weapon/storage/belt/military/abductor
@@ -405,10 +405,9 @@
if(iscyborg(user))
return //Robots can't interact with storage items.
if(contents.len >= storage_slots) //don't use items on the backpack if they don't fit
return 1
if(!can_be_inserted(W, 0 , user))
if(contents.len >= storage_slots) //don't use items on the backpack if they don't fit
return 1
return 0
handle_item_insertion(W, 0 , user)
@@ -140,7 +140,7 @@
item_state = "plasmaman_tank_belt"
slot_flags = SLOT_BELT
force = 5
volume = 3
volume = 6
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/weapon/tank/internals/plasmaman/belt/full/New()
@@ -64,6 +64,7 @@
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/clothing/head/soft/purple(src)
new /obj/item/weapon/paint/paint_remover(src)
new /obj/item/weapon/melee/flyswatter(src)
new /obj/item/device/flashlight(src)
for(var/i in 1 to 3)
new /obj/item/weapon/caution(src)
@@ -38,7 +38,7 @@
log_game("[key_name(user)] has detonated [src.name].")
for(var/atom/movable/AM in src)
qdel(AM)
explosion(get_turf(src), 0, 1, 5, 5)
explosion(get_turf(src), 0, 1, 5, 5)
qdel(src)
/obj/structure/closet/crate/secure/weapon
@@ -29,6 +29,7 @@
return ..()
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
/obj/effect/mob_spawn/human/ash_walker
name = "ash walker egg"
desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within."
@@ -36,8 +37,7 @@
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
icon_state = "large_egg"
mob_species = /datum/species/lizard/ashwalker
helmet = /obj/item/clothing/head/helmet/gladiator
uniform = /obj/item/clothing/under/gladiator/ash_walker
outfit = /datum/outfit/ashwalker
roundstart = FALSE
death = FALSE
anchored = 0
@@ -58,12 +58,18 @@
H.underwear = "Nude"
H.update_body()
/obj/effect/mob_spawn/human/ash_walker/New()
..()
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload)
. = ..()
var/area/A = get_area(src)
if(A)
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
/datum/outfit/ashwalker
name ="Ashwalker"
head = /obj/item/clothing/head/helmet/gladiator
uniform = /obj/item/clothing/under/gladiator/ash_walker
//Timeless prisons: Spawns in Wish Granter prisons in lavaland. Ghosts become age-old users of the Wish Granter and are advised to seek repentance for their past.
/obj/effect/mob_spawn/human/exile
name = "timeless prison"
@@ -188,38 +194,38 @@
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
/obj/effect/mob_spawn/human/hermit/New()
/obj/effect/mob_spawn/human/hermit/Initialize(mapload)
. = ..()
var/arrpee = rand(1,4)
switch(arrpee)
if(1)
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
life and sent you to this hell are forever branded into your memory.</b>"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/sneakers/black
back = /obj/item/weapon/storage/backpack
outfit.uniform = /obj/item/clothing/under/assistantformal
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/weapon/storage/backpack
if(2)
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
uniform = /obj/item/clothing/under/rank/prisoner
shoes = /obj/item/clothing/shoes/sneakers/orange
back = /obj/item/weapon/storage/backpack
outfit.uniform = /obj/item/clothing/under/rank/prisoner
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
outfit.back = /obj/item/weapon/storage/backpack
if(3)
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
uniform = /obj/item/clothing/under/rank/medical
suit = /obj/item/clothing/suit/toggle/labcoat
back = /obj/item/weapon/storage/backpack/medic
shoes = /obj/item/clothing/shoes/sneakers/black
outfit.uniform = /obj/item/clothing/under/rank/medical
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
outfit.back = /obj/item/weapon/storage/backpack/medic
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
if(4)
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
uniform = /obj/item/clothing/under/color/grey/glorf
shoes = /obj/item/clothing/shoes/sneakers/black
back = /obj/item/weapon/storage/backpack
..()
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/weapon/storage/backpack
/obj/effect/mob_spawn/human/hermit/Destroy()
new/obj/structure/fluff/empty_cryostasis_sleeper(get_turf(src))
@@ -241,10 +247,7 @@
mob_name = "an escaped prisoner"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper_s"
uniform = /obj/item/clothing/under/rank/prisoner
mask = /obj/item/clothing/mask/breath
shoes = /obj/item/clothing/shoes/sneakers/orange
pocket1 = /obj/item/weapon/tank/internals/emergency_oxygen
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
death = FALSE
flavour_text = "<font size=3><b>G</b></font><b>ood. It seems as though your ship crashed. You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
@@ -254,12 +257,20 @@
L.real_name = "NTP #LL-0[rand(111,999)]" //Nanotrasen Prisoner #Lavaland-(numbers)
L.name = L.real_name
/obj/effect/mob_spawn/human/prisoner_transport/New()
/obj/effect/mob_spawn/human/prisoner_transport/Initialize(mapload)
. = ..()
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
"worship of a forbidden deity", "interspecies relations", "mutiny")
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
..()
/datum/outfit/lavalandprisoner
name = "Lavaland Prisoner"
uniform = /obj/item/clothing/under/rank/prisoner
mask = /obj/item/clothing/mask/breath
shoes = /obj/item/clothing/shoes/sneakers/orange
r_pocket = /obj/item/weapon/tank/internals/emergency_oxygen
/obj/effect/mob_spawn/human/prisoner_transport/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
@@ -272,31 +283,39 @@
mob_name = "hotel staff member"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper_s"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
pocket1 = /obj/item/device/radio/off
back = /obj/item/weapon/storage/backpack
objectives = "Cater to visiting guests with your fellow staff. Do not leave your assigned hotel and always remember: The customer is always right!"
implants = list(/obj/item/weapon/implant/mindshield)
death = FALSE
roundstart = FALSE
random = TRUE
outfit = /datum/outfit/hotelstaff
flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
dereliction of duty!"
/datum/outfit/hotelstaff
name = "Hotel Staff"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/device/radio/off
back = /obj/item/weapon/storage/backpack
implants = list(/obj/item/weapon/implant/mindshield)
/obj/effect/mob_spawn/human/hotel_staff/security
name = "hotel security sleeper"
mob_name = "hotel security memeber"
uniform = /obj/item/clothing/under/rank/security/blueshirt
shoes = /obj/item/clothing/shoes/jackboots
suit = /obj/item/clothing/suit/armor/vest/blueshirt
helmet = /obj/item/clothing/head/helmet/blueshirt
back = /obj/item/weapon/storage/backpack/security
belt = /obj/item/weapon/storage/belt/security/full
outfit = /datum/outfit/hotelstaff/security
flavour_text = "You are a peacekeeper assigned to this hotel to protect the intrests of the company while keeping the peace between \
guests and the staff.Do <font size=6><b>NOT</b></font> leave the hotel, as that is grounds for contract termination."
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
/datum/outfit/hotelstaff/security
name = "Hotel Secuirty"
uniform = /obj/item/clothing/under/rank/security/blueshirt
shoes = /obj/item/clothing/shoes/jackboots
suit = /obj/item/clothing/suit/armor/vest/blueshirt
head = /obj/item/clothing/head/helmet/blueshirt
back = /obj/item/weapon/storage/backpack/security
belt = /obj/item/weapon/storage/belt/security/full
/obj/effect/mob_spawn/human/hotel_staff/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
..()
@@ -307,22 +326,17 @@
mob_name = "Demonic friend"
icon = 'icons/obj/cardboard_cutout.dmi'
icon_state = "cutout_basic"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
pocket1 = /obj/item/device/radio/off
back = /obj/item/weapon/storage/backpack
implants = list(/obj/item/weapon/implant/mindshield) //No revolutionaries, he's MY friend.
outfit = /datum/outfit/demonic_friend
death = FALSE
roundstart = FALSE
random = TRUE
has_id = TRUE
id_job = "SuperFriend"
id_access = "assistant"
var/obj/effect/proc_holder/spell/targeted/summon_friend/spell
var/datum/mind/owner
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
..()
. = ..()
owner = owner_mind
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for their short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
var/area/A = get_area(src)
@@ -349,3 +363,11 @@
to_chat(L, "<span class='userdanger'>Your owner is already dead! You will soon perish.</span>")
addtimer(CALLBACK(L, /mob.proc/dust, 150)) //Give em a few seconds as a mercy.
/datum/outfit/demonic_friend
name = "Demonic Friend"
uniform = /obj/item/clothing/under/assistantformal
shoes = /obj/item/clothing/shoes/laceup
r_pocket = /obj/item/device/radio/off
back = /obj/item/weapon/storage/backpack
implants = list(/obj/item/weapon/implant/mindshield) //No revolutionaries, he's MY friend.
id = /obj/item/weapon/card/id
+7 -7
View File
@@ -25,14 +25,14 @@
//The code below here isn't exactly optimal, but because of the individual decals that each area uses it's still applicable.
//high dirt - 1/3
if(istype(A, /area/toxins/test_area) || istype(A, /area/mine/production) || istype(A, /area/mine/living_quarters) || istype(A, /area/mine/north_outpost) || istype(A, /area/mine/west_outpost) || istype(A, /area/wreck) || istype(A, /area/derelict) || istype(A, /area/djstation))
if(istype(A, /area/science/test_area) || istype(A, /area/mine/production) || istype(A, /area/mine/living_quarters) || istype(A, /area/mine/north_outpost) || istype(A, /area/mine/west_outpost) || istype(A, /area/wreck) || istype(A, /area/derelict) || istype(A, /area/djstation))
new /obj/effect/decal/cleanable/dirt(src) //vanilla, but it works
return
if(prob(80)) //mid dirt - 1/15
return
if(istype(A, /area/engine) || istype(A,/area/assembly) || istype(A,/area/maintenance) || istype(A,/area/construction))
if(istype(A, /area/engine) || istype(A, /area/crew_quarters/heads/chief) || istype(A,/area/assembly) || istype(A, /area/science/robotics) || istype(A,/area/maintenance) || istype(A,/area/construction))
//Blood, sweat, and oil. Oh, and dirt.
if(prob(3))
new /obj/effect/decal/cleanable/blood/old(src)
@@ -46,7 +46,7 @@
new /obj/effect/decal/cleanable/dirt(src)
return
if(istype(A, /area/crew_quarters/toilet) || istype(A, /area/crew_quarters/locker/locker_toilet))
if(istype(A, /area/crew_quarters/toilet))
if(prob(40))
if(prob(90))
new /obj/effect/decal/cleanable/vomit/old(src)
@@ -62,7 +62,7 @@
if(prob(75)) //low dirt - 1/60
return
if(istype(A, /area/ai_monitored/turret_protected) || istype(A, /area/security)) //chance of incident
if(istype(A, /area/ai_monitored/turret_protected) || istype(A, /area/prison) || istype(A, /area/security) || istype(A, /area/crew_quarters/heads/hos)) //chance of incident
if(prob(20))
if(prob(5))
new /obj/effect/decal/cleanable/blood/gibs/old(src)
@@ -71,7 +71,7 @@
return
if(istype(A, /area/crew_quarters/kitchen)) //Kitchen messes
if(istype(A, /area/crew_quarters/kitchen) || istype(A, /area/crew_quarters/cafeteria)) //Kitchen messes
if(prob(60))
if(prob(50))
new /obj/effect/decal/cleanable/egg_smudge(src)
@@ -79,7 +79,7 @@
new /obj/effect/decal/cleanable/flour(src)
return
if(istype(A, /area/medical)) //Kept clean, but chance of blood
if(istype(A, /area/medical) || istype(A, /area/crew_quarters/heads/cmo)) //Kept clean, but chance of blood
if(prob(66))
if(prob(5))
new /obj/effect/decal/cleanable/blood/gibs/old(src)
@@ -92,7 +92,7 @@
new /obj/effect/decal/cleanable/vomit/old(src)
return
if(istype(A, /area/toxins))
if(istype(A, /area/science) || istype(A, /area/crew_quarters/heads/hor))
if(prob(20))
new /obj/effect/decal/cleanable/greenglow(src) //this cleans itself up but it might startle you when you see it.
return
@@ -322,6 +322,7 @@
slowdown = 2
environment_type = "snow"
sand_type = /obj/item/stack/sheet/mineral/snow
flags = NONE
/turf/open/floor/plating/asteroid/snow/airless
initial_gas_mix = "TEMP=2.7"
File diff suppressed because it is too large Load Diff
+14 -1
View File
@@ -52,7 +52,20 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!procname)
return
if(targetselected && !hascall(target,procname))
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
var/testname = procname
if(targetselected)
//Find one of the 3 possible ways they could have written /proc/PROCNAME
if(findtext(procname, "/proc/"))
testname = replacetext(procname, "/proc/", "")
else if(findtext(procname, "/proc"))
testname = replacetext(procname, "/proc", "")
else if(findtext(procname, "proc/"))
testname = replacetext(procname, "proc/", "")
//Clear out any parenthesis if they're a dummy
testname = replacetext(testname, "()", "")
if(targetselected && !hascall(target,testname))
to_chat(usr, "<font color='red'>Error: callproc(): type [target.type] has no proc named [procname].</font>")
return
else
@@ -16,7 +16,7 @@
for(var/log_type in M.logging)
var/list/reversed = M.logging[log_type]
reversed = reverseRange(reversed.Copy())
dat += "<center>[log_type]</center><br>"
dat += "<center><b>[log_type]</b></center><br>"
for(var/entry in reversed)
dat += "<font size=2px>[entry]: [reversed[entry]]</font><br>"
dat += "<hr>"
@@ -26,6 +26,6 @@
if(reversed)
reversed = reverseRange(reversed.Copy())
for(var/entry in reversed)
dat += "<font size=2px>[entry]: [reversed[entry]]</font><hr>"
dat += "<font size=2px>[entry]: [reversed[entry]]</font><br>"
usr << browse(dat, "window=invidual_logging;size=600x480")
@@ -1,6 +1,6 @@
#define PUMP_OUT "out"
#define PUMP_IN "in"
#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 30)
#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 10)
#define PUMP_MIN_PRESSURE (ONE_ATMOSPHERE / 10)
#define PUMP_DEFAULT_PRESSURE (ONE_ATMOSPHERE)
@@ -53,7 +53,7 @@
for(var/turf/T in get_area_turfs(thearea.type))
L+=T
var/loc = pick(L)
explosion(loc,explosiondev,explosionmed,explosionlight)
explosion(loc,explosiondev,explosionmed,explosionlight)
reload = 0
/*/mob/proc/openfire()
+124 -148
View File
@@ -38,7 +38,7 @@
create(ckey = user.ckey)
/obj/effect/mob_spawn/Initialize(mapload)
..()
. = ..()
if(instant || (roundstart && (mapload || (SSticker && SSticker.current_state > GAME_STATE_SETTING_UP))))
create()
else
@@ -90,29 +90,39 @@
mob_type = /mob/living/carbon/human
//Human specific stuff.
var/mob_species = null //Set to make them a mutant race such as lizard or skeleton. Uses the datum typepath instead of the ID.
var/outfit_type = null //Will start with this if exists then apply specific slots. Job outfits are generated with IDs and disabled PDAs.
var/uniform = null //Set this to an object path to have the slot filled with said object on the corpse.
var/r_hand = null
var/l_hand = null
var/suit = null
var/shoes = null
var/gloves = null
var/radio = null
var/glasses = null
var/mask = null
var/neck = null
var/helmet = null
var/belt = null
var/pocket1 = null
var/pocket2 = null
var/back = null
var/has_id = FALSE //Set to TRUE if you want them to have an ID
var/datum/outfit/outfit = /datum/outfit //If this is a path, it will be instanced in Initialize()
var/disable_pda = TRUE
//All of these only affect the ID that the outfit has placed in the ID slot
var/id_job = null //Such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/id_access = null //This is for access. See access.dm for which jobs give what access. Use "Captain" if you want it to be all access.
var/id_access_list = null //Allows you to manually add access to an ID card.
var/id_icon = null //For setting it to be a gold, silver, centcom etc ID
var/husk = null
var/list/implants = list()
//these vars are for lazy mappers to override parts of the outfit
//these cannot be null by default, or mappers cannot set them to null if they want nothing in that slot
var/uniform = -1
var/r_hand = -1
var/l_hand = -1
var/suit = -1
var/shoes = -1
var/gloves = -1
var/ears = -1
var/glasses = -1
var/mask = -1
var/head = -1
var/belt = -1
var/r_pocket = -1
var/l_pocket = -1
var/back = -1
var/id = -1
/obj/effect/mob_spawn/human/Initialize()
. = ..()
if(ispath(outfit))
outfit = new outfit()
if(!outfit)
outfit = new /datum/outfit
/obj/effect/mob_spawn/human/equip(mob/living/carbon/human/H)
if(mob_species)
@@ -120,48 +130,20 @@
if(husk)
H.Drain()
if(outfit_type)
H.equipOutfit(outfit_type)
// We don't want corpse PDAs to show up in the messenger list.
var/obj/item/device/pda/PDA = locate(/obj/item/device/pda) in H
if(PDA)
PDA.toff = TRUE
if(uniform)
H.equip_to_slot_or_del(new uniform(H), slot_w_uniform)
if(suit)
H.equip_to_slot_or_del(new suit(H), slot_wear_suit)
if(shoes)
H.equip_to_slot_or_del(new shoes(H), slot_shoes)
if(gloves)
H.equip_to_slot_or_del(new gloves(H), slot_gloves)
if(radio)
H.equip_to_slot_or_del(new radio(H), slot_ears)
if(glasses)
H.equip_to_slot_or_del(new glasses(H), slot_glasses)
if(mask)
H.equip_to_slot_or_del(new mask(H), slot_wear_mask)
if(neck)
H.equip_to_slot_or_del(new neck(H), slot_neck)
if(helmet)
H.equip_to_slot_or_del(new helmet(H), slot_head)
if(belt)
H.equip_to_slot_or_del(new belt(H), slot_belt)
if(pocket1)
H.equip_to_slot_or_del(new pocket1(H), slot_r_store)
if(pocket2)
H.equip_to_slot_or_del(new pocket2(H), slot_l_store)
if(back)
H.equip_to_slot_or_del(new back(H), slot_back)
if(l_hand)
H.put_in_hands_or_del(new l_hand(H))
if(r_hand)
H.put_in_hands_or_del(new r_hand(H))
if(has_id)
var/obj/item/weapon/card/id/W = new(H)
if(id_icon)
W.icon_state = id_icon
if(outfit)
var/static/list/slots = list("uniform", "r_hand", "l_hand", "suit", "shoes", "gloves", "ears", "glasses", "mask", "head", "belt", "r_pocket", "l_pocket", "back", "id")
for(var/slot in slots)
var/T = vars[slot]
if(!isnum(T))
outfit.vars[slot] = T
H.equipOutfit(outfit)
if(disable_pda)
// We don't want corpse PDAs to show up in the messenger list.
var/obj/item/device/pda/PDA = locate(/obj/item/device/pda) in H
if(PDA)
PDA.toff = TRUE
var/obj/item/weapon/card/id/W = H.wear_id
if(W)
if(id_access)
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
@@ -176,15 +158,6 @@
W.assignment = id_job
W.registered_name = H.real_name
W.update_label()
H.equip_to_slot_or_del(W, slot_wear_id)
for(var/I in implants)
var/obj/item/weapon/implant/X = new I
X.implant(H)
if(!H.head && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
HS.ToggleHelmet()
//Instant version - use when spawning corpses during runtime
/obj/effect/mob_spawn/human/corpse
@@ -248,52 +221,22 @@
// I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example.
/obj/effect/mob_spawn/human/syndicatesoldier
name = "Syndicate Operative"
uniform = /obj/item/clothing/under/syndicate
suit = /obj/item/clothing/suit/armor/vest
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
radio = /obj/item/device/radio/headset
mask = /obj/item/clothing/mask/gas
helmet = /obj/item/clothing/head/helmet/swat
back = /obj/item/weapon/storage/backpack
has_id = 1
id_job = "Operative"
id_access_list = list(GLOB.access_syndicate)
/obj/effect/mob_spawn/human/syndicatecommando
name = "Syndicate Commando"
uniform = /obj/item/clothing/under/syndicate
suit = /obj/item/clothing/suit/space/hardsuit/syndi
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
radio = /obj/item/device/radio/headset
mask = /obj/item/clothing/mask/gas/syndicate
back = /obj/item/weapon/tank/jetpack/oxygen
pocket1 = /obj/item/weapon/tank/internals/emergency_oxygen
has_id = 1
id_job = "Operative"
id_access_list = list(GLOB.access_syndicate)
///////////Civilians//////////////////////
/obj/effect/mob_spawn/human/cook
name = "Cook"
outfit_type = /datum/outfit/job/cook
outfit = /datum/outfit/job/cook
/obj/effect/mob_spawn/human/doctor
name = "Doctor"
outfit_type = /datum/outfit/job/doctor
outfit = /datum/outfit/job/doctor
/obj/effect/mob_spawn/human/doctor/alive
death = FALSE
roundstart = FALSE
random = TRUE
radio = null
back = null
name = "sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper"
@@ -309,49 +252,40 @@
/obj/effect/mob_spawn/human/engineer
name = "Engineer"
outfit_type = /datum/outfit/job/engineer
gloves = /obj/item/clothing/gloves/color/yellow
outfit = /datum/outfit/job/engineer/gloved
/obj/effect/mob_spawn/human/engineer/rig
outfit_type = /datum/outfit/job/engineer/rig
outfit = /datum/outfit/job/engineer/gloved/rig
/obj/effect/mob_spawn/human/clown
name = "Clown"
outfit_type = /datum/outfit/job/clown
outfit = /datum/outfit/job/clown
/obj/effect/mob_spawn/human/scientist
name = "Scientist"
outfit_type = /datum/outfit/job/scientist
outfit = /datum/outfit/job/scientist
/obj/effect/mob_spawn/human/miner
name = "Shaft Miner"
outfit_type = /datum/outfit/job/miner/asteroid
outfit = /datum/outfit/job/miner/asteroid
/obj/effect/mob_spawn/human/miner/rig
outfit_type = /datum/outfit/job/miner/equipped/asteroid
outfit = /datum/outfit/job/miner/equipped/asteroid
/obj/effect/mob_spawn/human/miner/explorer
outfit_type = /datum/outfit/job/miner/equipped
outfit = /datum/outfit/job/miner/equipped
/obj/effect/mob_spawn/human/plasmaman
mob_species = /datum/species/plasmaman
helmet = /obj/item/clothing/head/helmet/space/plasmaman
uniform = /obj/item/clothing/under/plasmaman
back = /obj/item/weapon/tank/internals/plasmaman/full
mask = /obj/item/clothing/mask/breath
outfit = /datum/outfit/plasmaman
/obj/effect/mob_spawn/human/bartender
name = "Space Bartender"
uniform = /obj/item/clothing/under/rank/bartender
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
has_id = 1
id_job = "Bartender"
id_access_list = list(GLOB.access_bar)
outfit = /datum/outfit/spacebartender
/obj/effect/mob_spawn/human/bartender/alive
death = FALSE
@@ -362,10 +296,18 @@
icon_state = "sleeper"
flavour_text = "You are a space bartender!"
/datum/outfit/spacebartender
name = "Space Bartender"
uniform = /obj/item/clothing/under/rank/bartender
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
id = /obj/item/weapon/card/id
/obj/effect/mob_spawn/human/beach
glasses = /obj/item/clothing/glasses/sunglasses
uniform = /obj/item/clothing/under/shorts/red
pocket1 = /obj/item/weapon/storage/wallet/random
outfit = /datum/outfit/beachbum
/obj/effect/mob_spawn/human/beach/alive
death = FALSE
@@ -377,50 +319,74 @@
icon_state = "sleeper"
flavour_text = "You are a beach bum!"
/obj/effect/mob_spawn/human/beach/equip(mob/living/carbon/human/H)
/datum/outfit/beachbum
name = "Beach Bum"
glasses = /obj/item/clothing/glasses/sunglasses
uniform = /obj/item/clothing/under/shorts/red
r_pocket = /obj/item/weapon/storage/wallet/random
/datum/outfit/beachbum/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(visualsOnly)
return
H.dna.add_mutation(STONER)
/////////////////Officers+Nanotrasen Security//////////////////////
/obj/effect/mob_spawn/human/bridgeofficer
name = "Bridge Officer"
radio = /obj/item/device/radio/headset/heads/hop
id_job = "Bridge Officer"
id_access_list = list(GLOB.access_cent_captain)
outfit = /datum/outfit/nanotrasenbridgeofficercorpse
/datum/outfit/nanotrasenbridgeofficercorpse
name = "Bridge Officer Corpse"
ears = /obj/item/device/radio/headset/heads/hop
uniform = /obj/item/clothing/under/rank/centcom_officer
suit = /obj/item/clothing/suit/armor/bulletproof
shoes = /obj/item/clothing/shoes/sneakers/black
glasses = /obj/item/clothing/glasses/sunglasses
has_id = 1
id_job = "Bridge Officer"
id_access_list = list(GLOB.access_cent_captain)
id = /obj/item/weapon/card/id
/obj/effect/mob_spawn/human/commander
name = "Commander"
uniform = /obj/item/clothing/under/rank/centcom_commander
suit = /obj/item/clothing/suit/armor/bulletproof
radio = /obj/item/device/radio/headset/heads/captain
glasses = /obj/item/clothing/glasses/eyepatch
mask = /obj/item/clothing/mask/cigarette/cigar/cohiba
helmet = /obj/item/clothing/head/centhat
gloves = /obj/item/clothing/gloves/combat
shoes = /obj/item/clothing/shoes/combat/swat
pocket1 = /obj/item/weapon/lighter
has_id = 1
id_job = "Commander"
id_access_list = list(GLOB.access_cent_captain)
outfit = /datum/outfit/nanotrasencommandercorpse
/datum/outfit/nanotrasencommandercorpse
name = "Nanotrasen Private Security Commander"
uniform = /obj/item/clothing/under/rank/centcom_commander
suit = /obj/item/clothing/suit/armor/bulletproof
ears = /obj/item/device/radio/headset/heads/captain
glasses = /obj/item/clothing/glasses/eyepatch
mask = /obj/item/clothing/mask/cigarette/cigar/cohiba
head = /obj/item/clothing/head/centhat
gloves = /obj/item/clothing/gloves/combat
shoes = /obj/item/clothing/shoes/combat/swat
r_pocket = /obj/item/weapon/lighter
id = /obj/item/weapon/card/id
/obj/effect/mob_spawn/human/nanotrasensoldier
name = "Nanotrasen Private Security Officer"
id_job = "Private Security Force"
id_access_list = list(GLOB.access_cent_specops)
outfit = /datum/outfit/nanotrasensoldiercorpse
/datum/outfit/nanotrasensoldiercorpse
name = "NT Private Security Officer Corpse"
uniform = /obj/item/clothing/under/rank/security
suit = /obj/item/clothing/suit/armor/vest
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
mask = /obj/item/clothing/mask/gas/sechailer/swat
helmet = /obj/item/clothing/head/helmet/swat/nanotrasen
head = /obj/item/clothing/head/helmet/swat/nanotrasen
back = /obj/item/weapon/storage/backpack/security
has_id = 1
id_job = "Private Security Force"
id_access_list = list(GLOB.access_cent_specops)
id = /obj/item/weapon/card/id
/obj/effect/mob_spawn/human/commander/alive
death = FALSE
@@ -431,6 +397,7 @@
icon_state = "sleeper"
flavour_text = "You are a Nanotrasen Commander!"
/////////////////Spooky Undead//////////////////////
/obj/effect/mob_spawn/human/skeleton
@@ -463,9 +430,14 @@
name = "abductor"
mob_name = "alien"
mob_species = /datum/species/abductor
outfit = /datum/outfit/abductorcorpse
/datum/outfit/abductorcorpse
name = "Abductor Corpse"
uniform = /obj/item/clothing/under/color/grey
shoes = /obj/item/clothing/shoes/combat
//For ghost bar.
/obj/effect/mob_spawn/human/alive/space_bar_patron
name = "Bar cryogenics"
@@ -473,11 +445,7 @@
random = TRUE
permanent = TRUE
uses = -1
uniform = /obj/item/clothing/under/rank/bartender
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
outfit = /datum/outfit/spacebartender
/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user)
var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No")
@@ -485,3 +453,11 @@
return
user.visible_message("<span class='notice'>[user.name] climbs back into cryosleep...</span>")
qdel(user)
/datum/outfit/cryobartender
name = "Cryogenic Bartender"
uniform = /obj/item/clothing/under/rank/bartender
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
@@ -186,12 +186,11 @@
/obj/effect/mob_spawn/human/syndicatesoldier/coldres
name = "Syndicate Snow Operative"
uniform = /obj/item/clothing/under/syndicate/coldres
shoes = /obj/item/clothing/shoes/combat/coldres
radio = /obj/item/device/radio/headset/syndicate/alt
pocket1 = /obj/item/weapon/gun/ballistic/automatic/pistol
pocket2 = /obj/item/weapon/card/id/syndicate
has_id = 0
outfit = /datum/outfit/snowsyndie/corpse
/datum/outfit/snowsyndie/corpse
name = "Syndicate Snow Operative Corpse"
implants = null
/obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive
name = "sleeper"
@@ -200,11 +199,20 @@
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
implants = list(/obj/item/weapon/implant/exile)
faction = "syndicate"
outfit = /datum/outfit/snowsyndie
flavour_text = {"You are a syndicate operative recently awoken from cyrostatis in an underground outpost. Monitor Nanotrasen communications and record infomation. All intruders should be
disposed of swirfly to assure no gathered infomation is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself."}
/datum/outfit/snowsyndie
name = "Syndicate Snow Operative"
uniform = /obj/item/clothing/under/syndicate/coldres
shoes = /obj/item/clothing/shoes/combat/coldres
ears = /obj/item/device/radio/headset/syndicate/alt
r_pocket = /obj/item/weapon/gun/ballistic/automatic/pistol
l_pocket = /obj/item/weapon/card/id/syndicate
implants = list(/obj/item/weapon/implant/exile)
/obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive/female
mob_gender = FEMALE
@@ -107,7 +107,7 @@
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
explosion(M, 1, 0, 0, 0)
explosion(M, 1, 0, 0, 0)
qdel(src)
/////For the Wishgranter///////////
+2 -2
View File
@@ -46,7 +46,7 @@
// Plasma. The oil of 26 century. The reason why you are here.
/datum/export/material/plasma
cost = 500
cost = 300
material_id = MAT_PLASMA
message = "cm3 of plasma"
@@ -76,7 +76,7 @@
// Plastitanium.
/datum/export/material/plastitanium
cost = 750
cost = 550
material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium, so ((250 x 250) + (250 x 500)) / 250
message = "cm3 of plastitanium"
+4 -3
View File
@@ -39,8 +39,9 @@
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
var/static/list/meson_mining_failure_excuses = list("seismic activity", "excessive lava", "ambient radiation", "electromagnetic storms", "bluespace disruption", \
"gravity", "dust", "dense rock", "ash", "badly understood science", "radiant heat")
var/static/list/meson_mining_failure_excuses = list("badly understood science", "damaged meson generators", "electromagnetic storms", "bluespace disruption", "ancient structures", \
"ambient radiation", "seismic activity", "extreme weather", "strange signals", "excessive lava", "giant monsters", "a loose wire", "lens warping", "radiant heat", "volcanic ash", \
"budget cuts","alien life","dense rock", "gravity", "dust")
var/picked_excuse
var/mesons_on = TRUE
@@ -65,7 +66,7 @@
if(iscarbon(user)) //only carbons can wear glasses
var/mob/living/carbon/C = user
if(!mesons_on)
if(mesons_on)
to_chat(C, "<span class='notice'>Your Meson Scanners have reactivated.</span>")
else if(picked_excuse)
to_chat(C, "<span class='warning'>Due to [picked_excuse], your Meson Scanners will not be able to display terrain layouts in this area.</span>")
+1 -1
View File
@@ -57,7 +57,7 @@
M.speak = rampant_speeches.Copy()
M.speak_chance = 7
else
explosion(upriser.loc, -1, 1, 2, 4, 0)
explosion(upriser.loc, -1, 1, 2, 4, 0)
qdel(upriser)
kill()
+2 -2
View File
@@ -21,8 +21,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/datum/round_event/immovable_rod/start()
var/startside = pick(GLOB.cardinal)
var/turf/startT = spaceDebrisStartLoc(startside, 1)
var/turf/endT = spaceDebrisFinishLoc(startside, 1)
var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION)
var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION)
new /obj/effect/immovablerod(startT, endT)
/obj/effect/immovablerod
+2 -3
View File
@@ -8,13 +8,12 @@
announceWhen = 50
endWhen = 20
var/list/area/areasToOpen = list()
var/list/potential_areas = list(/area/atmos,
/area/bridge,
var/list/potential_areas = list(/area/bridge,
/area/engine,
/area/medical,
/area/security,
/area/quartermaster,
/area/toxins)
/area/science)
var/severity = 1
+1 -1
View File
@@ -32,7 +32,7 @@
var/obj/machinery/telecomms/processor/P = T
if(prob(10))
// Damage the surrounding area to indicate that it popped
explosion(get_turf(P), 0, 0, 2)
explosion(get_turf(P), 0, 0, 2)
// Only a level 1 explosion actually damages the machine
// at all
P.ex_act(1)
+4 -2
View File
@@ -89,7 +89,8 @@ Shaft Miner
backpack_contents = list(
/obj/item/weapon/storage/bag/ore=1,\
/obj/item/weapon/kitchen/knife/combat/survival=1,\
/obj/item/weapon/mining_voucher=1)
/obj/item/weapon/mining_voucher=1,\
/obj/item/stack/marker_beacon/ten=1)
backpack = /obj/item/weapon/storage/backpack/explorer
satchel = /obj/item/weapon/storage/backpack/satchel/explorer
@@ -113,7 +114,8 @@ Shaft Miner
/obj/item/weapon/kitchen/knife/combat/survival=1,
/obj/item/weapon/mining_voucher=1,
/obj/item/device/t_scanner/adv_mining_scanner/lesser=1,
/obj/item/weapon/gun/energy/kinetic_accelerator=1)
/obj/item/weapon/gun/energy/kinetic_accelerator=1,\
/obj/item/stack/marker_beacon/ten=1)
/datum/outfit/job/miner/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
+5 -2
View File
@@ -98,13 +98,16 @@ Station Engineer
pda_slot = slot_l_store
backpack_contents = list(/obj/item/device/modular_computer/tablet/preset/advanced=1)
/datum/outfit/job/engineer/rig
/datum/outfit/job/engineer/gloved
name = "Station Engineer (Gloves)"
gloves = /obj/item/clothing/gloves/color/yellow
/datum/outfit/job/engineer/gloved/rig
name = "Station Engineer (Hardsuit)"
mask = /obj/item/clothing/mask/breath
suit = /obj/item/clothing/suit/space/hardsuit/engine
suit_store = /obj/item/weapon/tank/internals/oxygen
gloves = /obj/item/clothing/gloves/color/yellow
head = null
internals_slot = slot_s_store
+185 -190
View File
@@ -1,190 +1,185 @@
/datum/job
//The name of the job
var/title = "NOPE"
//Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
//Determines who can demote this position
var/department_head = list()
//Tells the given channels that the given mob is the new department head. See communications.dm for valid channels.
var/list/head_announce = null
//Bitflags for the job
var/flag = 0
var/department_flag = 0
//Players will be allowed to spawn in as jobs that are set to "Station"
var/faction = "None"
//How many players can be this job
var/total_positions = 0
//How many players can spawn in as this job
var/spawn_positions = 0
//How many players have this job
var/current_positions = 0
//Supervisors, who this person answers to directly
var/supervisors = ""
//Sellection screen color
var/selection_color = "#ffffff"
//If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect.
var/req_admin_notify
//If you have the use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
var/minimal_player_age = 0
var/outfit = null
//Only override this proc
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M)
//do actions on H but send messages to M as the key may not have been transferred_yet
/datum/job/proc/announce(mob/living/carbon/human/H)
if(head_announce)
announce_head(H, head_announce)
//Don't override this unless the job transforms into a non-human (Silicons do this for example)
/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE)
if(!H)
return 0
//Equip the rest of the gear
H.dna.species.before_equip_job(src, H, visualsOnly)
if(outfit)
H.equipOutfit(outfit, visualsOnly)
H.dna.species.after_equip_job(src, H, visualsOnly)
if(!visualsOnly && announce)
announce(H)
if(config.enforce_human_authority && (title in GLOB.command_positions))
H.dna.features["tail_human"] = "None"
H.dna.features["ears"] = "None"
H.regenerate_icons()
/datum/job/proc/get_access()
if(!config) //Needed for robots.
return src.minimal_access.Copy()
. = list()
if(config.jobs_have_minimal_access)
. = src.minimal_access.Copy()
else
. = src.access.Copy()
if(config.jobs_have_maint_access & EVERYONE_HAS_MAINT_ACCESS) //Config has global maint access set
. |= list(GLOB.access_maint_tunnels)
/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
if(H && GLOB.announcement_systems.len)
//timer because these should come after the captain announcement
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
/datum/job/proc/player_old_enough(client/C)
if(available_in_days(C) == 0)
return 1 //Available in 0 days = available right now = player is old enough to play.
return 0
/datum/job/proc/available_in_days(client/C)
if(!C)
return 0
if(!config.use_age_restriction_for_jobs)
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
if(!isnum(minimal_player_age))
return 0
return max(0, minimal_player_age - C.player_age)
/datum/job/proc/config_check()
return 1
/datum/job/proc/map_check()
return TRUE
/datum/outfit/job
name = "Standard Gear"
var/jobtype = null
uniform = /obj/item/clothing/under/color/grey
id = /obj/item/weapon/card/id
ears = /obj/item/device/radio/headset
belt = /obj/item/device/pda
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
var/list/implants = null
var/backpack = /obj/item/weapon/storage/backpack
var/satchel = /obj/item/weapon/storage/backpack/satchel
var/dufflebag = /obj/item/weapon/storage/backpack/dufflebag
var/box = /obj/item/weapon/storage/box/survival
var/pda_slot = slot_belt
/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
switch(H.backbag)
if(GBACKPACK)
back = /obj/item/weapon/storage/backpack //Grey backpack
if(GSATCHEL)
back = /obj/item/weapon/storage/backpack/satchel //Grey satchel
if(GDUFFLEBAG)
back = /obj/item/weapon/storage/backpack/dufflebag //Grey Dufflebag
if(LSATCHEL)
back = /obj/item/weapon/storage/backpack/satchel/leather //Leather Satchel
if(DSATCHEL)
back = satchel //Department satchel
if(DDUFFLEBAG)
back = dufflebag //Department dufflebag
else
back = backpack //Department backpack
if(box)
backpack_contents.Insert(1, box) // Box always takes a first slot in backpack
backpack_contents[box] = 1
/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(visualsOnly)
return
var/datum/job/J = SSjob.GetJobType(jobtype)
if(!J)
J = SSjob.GetJob(H.job)
var/obj/item/weapon/card/id/C = H.wear_id
if(istype(C))
C.access = J.get_access()
C.registered_name = H.real_name
C.assignment = J.title
C.update_label()
H.sec_hud_set_ID()
var/obj/item/device/pda/PDA = H.get_item_by_slot(pda_slot)
if(istype(PDA))
PDA.owner = H.real_name
PDA.ownjob = J.title
PDA.update_label()
if(implants)
for(var/implant_type in implants)
var/obj/item/weapon/implant/I = new implant_type(H)
I.implant(H, null, silent=TRUE)
/datum/job
//The name of the job
var/title = "NOPE"
//Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
//Determines who can demote this position
var/department_head = list()
//Tells the given channels that the given mob is the new department head. See communications.dm for valid channels.
var/list/head_announce = null
//Bitflags for the job
var/flag = 0
var/department_flag = 0
//Players will be allowed to spawn in as jobs that are set to "Station"
var/faction = "None"
//How many players can be this job
var/total_positions = 0
//How many players can spawn in as this job
var/spawn_positions = 0
//How many players have this job
var/current_positions = 0
//Supervisors, who this person answers to directly
var/supervisors = ""
//Sellection screen color
var/selection_color = "#ffffff"
//If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect.
var/req_admin_notify
//If you have the use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
var/minimal_player_age = 0
var/outfit = null
//Only override this proc
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M)
//do actions on H but send messages to M as the key may not have been transferred_yet
/datum/job/proc/announce(mob/living/carbon/human/H)
if(head_announce)
announce_head(H, head_announce)
//Don't override this unless the job transforms into a non-human (Silicons do this for example)
/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE)
if(!H)
return 0
//Equip the rest of the gear
H.dna.species.before_equip_job(src, H, visualsOnly)
if(outfit)
H.equipOutfit(outfit, visualsOnly)
H.dna.species.after_equip_job(src, H, visualsOnly)
if(!visualsOnly && announce)
announce(H)
if(config.enforce_human_authority && (title in GLOB.command_positions))
H.dna.features["tail_human"] = "None"
H.dna.features["ears"] = "None"
H.regenerate_icons()
/datum/job/proc/get_access()
if(!config) //Needed for robots.
return src.minimal_access.Copy()
. = list()
if(config.jobs_have_minimal_access)
. = src.minimal_access.Copy()
else
. = src.access.Copy()
if(config.jobs_have_maint_access & EVERYONE_HAS_MAINT_ACCESS) //Config has global maint access set
. |= list(GLOB.access_maint_tunnels)
/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
if(H && GLOB.announcement_systems.len)
//timer because these should come after the captain announcement
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
/datum/job/proc/player_old_enough(client/C)
if(available_in_days(C) == 0)
return 1 //Available in 0 days = available right now = player is old enough to play.
return 0
/datum/job/proc/available_in_days(client/C)
if(!C)
return 0
if(!config.use_age_restriction_for_jobs)
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
if(!isnum(minimal_player_age))
return 0
return max(0, minimal_player_age - C.player_age)
/datum/job/proc/config_check()
return 1
/datum/job/proc/map_check()
return TRUE
/datum/outfit/job
name = "Standard Gear"
var/jobtype = null
uniform = /obj/item/clothing/under/color/grey
id = /obj/item/weapon/card/id
ears = /obj/item/device/radio/headset
belt = /obj/item/device/pda
back = /obj/item/weapon/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
var/backpack = /obj/item/weapon/storage/backpack
var/satchel = /obj/item/weapon/storage/backpack/satchel
var/dufflebag = /obj/item/weapon/storage/backpack/dufflebag
var/box = /obj/item/weapon/storage/box/survival
var/pda_slot = slot_belt
/datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
switch(H.backbag)
if(GBACKPACK)
back = /obj/item/weapon/storage/backpack //Grey backpack
if(GSATCHEL)
back = /obj/item/weapon/storage/backpack/satchel //Grey satchel
if(GDUFFLEBAG)
back = /obj/item/weapon/storage/backpack/dufflebag //Grey Dufflebag
if(LSATCHEL)
back = /obj/item/weapon/storage/backpack/satchel/leather //Leather Satchel
if(DSATCHEL)
back = satchel //Department satchel
if(DDUFFLEBAG)
back = dufflebag //Department dufflebag
else
back = backpack //Department backpack
if(box)
if(!backpack_contents)
backpack_contents = list()
backpack_contents.Insert(1, box) // Box always takes a first slot in backpack
backpack_contents[box] = 1
/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
if(visualsOnly)
return
var/datum/job/J = SSjob.GetJobType(jobtype)
if(!J)
J = SSjob.GetJob(H.job)
var/obj/item/weapon/card/id/C = H.wear_id
if(istype(C))
C.access = J.get_access()
C.registered_name = H.real_name
C.assignment = J.title
C.update_label()
H.sec_hud_set_ID()
var/obj/item/device/pda/PDA = H.get_item_by_slot(pda_slot)
if(istype(PDA))
PDA.owner = H.real_name
PDA.ownjob = J.title
PDA.update_label()
@@ -0,0 +1,142 @@
/*****************Marker Beacons**************************/
GLOBAL_LIST_INIT(marker_beacon_colors, list(
"Random" = FALSE,//not a true color, will pick a random color
"Burgundy" = LIGHT_COLOR_FLARE,
"Bronze" = LIGHT_COLOR_ORANGE,
"Yellow" = LIGHT_COLOR_YELLOW,
"Lime" = LIGHT_COLOR_SLIME_LAMP,
"Olive" = LIGHT_COLOR_GREEN,
"Jade" = LIGHT_COLOR_BLUEGREEN,
"Teal" = LIGHT_COLOR_LIGHT_CYAN,
"Cerulean" = LIGHT_COLOR_BLUE,
"Indigo" = LIGHT_COLOR_DARK_BLUE,
"Purple" = LIGHT_COLOR_PURPLE,
"Violet" = LIGHT_COLOR_LAVENDER,
"Fuchsia" = LIGHT_COLOR_PINK))
/obj/item/stack/marker_beacon
name = "marker beacon"
singular_name = "marker beacon"
desc = "Prism-brand path illumination devices. Used by miners to mark paths and warn of danger."
icon = 'icons/obj/lighting.dmi'
icon_state = "marker"
merge_type = /obj/item/stack/marker_beacon
max_amount = 100
var/picked_color = "random"
/obj/item/stack/marker_beacon/ten //miners start with 10 of these
amount = 10
/obj/item/stack/marker_beacon/thirty //and they're bought in stacks of 1, 10, or 30
amount = 30
/obj/item/stack/marker_beacon/Initialize(mapload)
. = ..()
update_icon()
/obj/item/stack/marker_beacon/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Use in-hand to place a [singular_name].</span>")
to_chat(user, "<span class='notice'>Alt-click to select a color. Current color is [picked_color].</span>")
/obj/item/stack/marker_beacon/update_icon()
icon_state = "[initial(icon_state)][lowertext(picked_color)]"
/obj/item/stack/marker_beacon/attack_self(mob/user)
if(!isturf(user.loc))
to_chat(user, "<span class='warning'>You need more space to place a [singular_name] here.</span>")
return
if(locate(/obj/structure/marker_beacon) in user.loc)
to_chat(user, "<span class='warning'>There is already a [singular_name] here.</span>")
return
if(use(1))
to_chat(user, "<span class='notice'>You activate and anchor [amount ? "a":"the"] [singular_name] in place.</span>")
playsound(user, 'sound/machines/click.ogg', 50, 1)
var/obj/structure/marker_beacon/M = new(user.loc, picked_color)
transfer_fingerprints_to(M)
/obj/item/stack/marker_beacon/AltClick(mob/user)
if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors
if(user.incapacitated() || !in_range(src, user))
return
if(input_color)
picked_color = input_color
update_icon()
/obj/structure/marker_beacon
name = "marker beacon"
desc = "A Prism-brand path illumination device. It is anchored in place and glowing steadily."
icon = 'icons/obj/lighting.dmi'
icon_state = "marker"
layer = BELOW_OPEN_DOOR_LAYER
armor = list(melee = 50, bullet = 75, laser = 75, energy = 75, bomb = 25, bio = 100, rad = 100, fire = 25, acid = 0)
obj_integrity = 50
max_integrity = 50
anchored = TRUE
light_range = 2
light_power = 3
var/remove_speed = 15
var/picked_color
/obj/structure/marker_beacon/Initialize(mapload, set_color)
. = ..()
picked_color = set_color
update_icon()
/obj/structure/marker_beacon/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
var/obj/item/stack/marker_beacon/M = new(loc)
M.picked_color = picked_color
M.update_icon()
qdel(src)
/obj/structure/marker_beacon/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to select a color. Current color is [picked_color].</span>")
/obj/structure/marker_beacon/update_icon()
while(!picked_color || !GLOB.marker_beacon_colors[picked_color])
picked_color = pick(GLOB.marker_beacon_colors)
icon_state = "[initial(icon_state)][lowertext(picked_color)]-on"
set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color])
/obj/structure/marker_beacon/attack_hand(mob/living/user)
to_chat(user, "<span class='notice'>You start picking [src] up...</span>")
if(do_after(user, remove_speed, target = src))
var/obj/item/stack/marker_beacon/M = new(loc)
M.picked_color = picked_color
M.update_icon()
transfer_fingerprints_to(M)
if(user.put_in_hands(M, TRUE)) //delete the beacon if it fails
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
qdel(src) //otherwise delete us
/obj/structure/marker_beacon/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/stack/marker_beacon))
var/obj/item/stack/marker_beacon/M = I
to_chat(user, "<span class='notice'>You start picking [src] up...</span>")
if(do_after(user, remove_speed, target = src) && M.amount + 1 <= M.max_amount)
M.add(1)
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
qdel(src)
else
return ..()
/obj/structure/marker_beacon/AltClick(mob/user)
..()
if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
var/input_color = input(user, "Choose a color.", "Beacon Color") as null|anything in GLOB.marker_beacon_colors
if(user.incapacitated() || !in_range(src, user))
return
if(input_color)
picked_color = input_color
update_icon()
@@ -0,0 +1,111 @@
/*****************Pickaxes & Drills & Shovels****************/
/obj/item/weapon/pickaxe
name = "pickaxe"
icon = 'icons/obj/mining.dmi'
icon_state = "pickaxe"
flags = CONDUCT
slot_flags = SLOT_BELT | SLOT_BACK
force = 15
throwforce = 10
item_state = "pickaxe"
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_METAL=2000) //one sheet, but where can you make them?
var/digspeed = 40
var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg')
origin_tech = "materials=2;engineering=3"
attack_verb = list("hit", "pierced", "sliced", "attacked")
/obj/item/weapon/pickaxe/mini
name = "compact pickaxe"
desc = "A smaller, compact version of the standard pickaxe."
icon_state = "minipick"
force = 10
throwforce = 7
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=1000)
/obj/item/weapon/pickaxe/proc/playDigSound()
playsound(src, pick(digsound),50,1)
/obj/item/weapon/pickaxe/silver
name = "silver-plated pickaxe"
icon_state = "spickaxe"
item_state = "spickaxe"
digspeed = 20 //mines faster than a normal pickaxe, bought from mining vendor
origin_tech = "materials=3;engineering=4"
desc = "A silver-plated pickaxe that mines slightly faster than standard-issue."
force = 17
/obj/item/weapon/pickaxe/diamond
name = "diamond-tipped pickaxe"
icon_state = "dpickaxe"
item_state = "dpickaxe"
digspeed = 14
origin_tech = "materials=5;engineering=4"
desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt."
force = 19
/obj/item/weapon/pickaxe/drill
name = "mining drill"
icon_state = "handdrill"
item_state = "jackhammer"
slot_flags = SLOT_BELT
digspeed = 25 //available from roundstart, faster than a pickaxe.
digsound = list('sound/weapons/drill.ogg')
hitsound = 'sound/weapons/drill.ogg'
origin_tech = "materials=2;powerstorage=2;engineering=3"
desc = "An electric mining drill for the especially scrawny."
/obj/item/weapon/pickaxe/drill/cyborg
name = "cyborg mining drill"
desc = "An integrated electric mining drill."
flags = NODROP
/obj/item/weapon/pickaxe/drill/diamonddrill
name = "diamond-tipped mining drill"
icon_state = "diamonddrill"
digspeed = 7
origin_tech = "materials=6;powerstorage=4;engineering=4"
desc = "Yours is the drill that will pierce the heavens!"
/obj/item/weapon/pickaxe/drill/cyborg/diamond //This is the BORG version!
name = "diamond-tipped cyborg mining drill" //To inherit the NODROP flag, and easier to change borg specific drill mechanics.
icon_state = "diamonddrill"
digspeed = 7
/obj/item/weapon/pickaxe/drill/jackhammer
name = "sonic jackhammer"
icon_state = "jackhammer"
item_state = "jackhammer"
digspeed = 5 //the epitome of powertools. extremely fast mining, laughs at puny walls
origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4"
digsound = list('sound/weapons/sonic_jackhammer.ogg')
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls."
/obj/item/weapon/shovel
name = "shovel"
desc = "A large tool for digging and moving dirt."
icon = 'icons/obj/mining.dmi'
icon_state = "shovel"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 8
var/digspeed = 20
throwforce = 4
item_state = "shovel"
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=50)
origin_tech = "materials=2;engineering=2"
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
sharpness = IS_SHARP
/obj/item/weapon/shovel/spade
name = "spade"
desc = "A small tool for digging and moving dirt."
icon_state = "spade"
item_state = "spade"
force = 5
throwforce = 7
w_class = WEIGHT_CLASS_SMALL
@@ -0,0 +1,333 @@
/*****************************Survival Pod********************************/
/area/survivalpod
name = "\improper Emergency Shelter"
icon_state = "away"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
has_gravity = TRUE
//Survival Capsule
/obj/item/weapon/survivalcapsule
name = "bluespace shelter capsule"
desc = "An emergency shelter stored within a pocket of bluespace."
icon_state = "capsule"
icon = 'icons/obj/mining.dmi'
w_class = WEIGHT_CLASS_TINY
origin_tech = "engineering=3;bluespace=3"
var/template_id = "shelter_alpha"
var/datum/map_template/shelter/template
var/used = FALSE
/obj/item/weapon/survivalcapsule/proc/get_template()
if(template)
return
template = SSmapping.shelter_templates[template_id]
if(!template)
throw EXCEPTION("Shelter template ([template_id]) not found!")
qdel(src)
/obj/item/weapon/survivalcapsule/Destroy()
template = null // without this, capsules would be one use. per round.
. = ..()
/obj/item/weapon/survivalcapsule/examine(mob/user)
. = ..()
get_template()
to_chat(user, "This capsule has the [template.name] stored.")
to_chat(user, template.description)
/obj/item/weapon/survivalcapsule/attack_self()
//Can't grab when capsule is New() because templates aren't loaded then
get_template()
if(!used)
loc.visible_message("<span class='warning'>\The [src] begins to shake. Stand back!</span>")
used = TRUE
sleep(50)
var/turf/deploy_location = get_turf(src)
var/status = template.check_deploy(deploy_location)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
src.loc.visible_message("<span class='warning'>\The [src] will not function in this area.</span>")
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
var/width = template.width
var/height = template.height
src.loc.visible_message("<span class='warning'>\The [src] doesn't have room to deploy! You need to clear a [width]x[height] area!</span>")
if(status != SHELTER_DEPLOY_ALLOWED)
used = FALSE
return
playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1)
var/turf/T = deploy_location
if(T.z != ZLEVEL_MINING && T.z != ZLEVEL_LAVALAND)//only report capsules away from the mining/lavaland level
message_admins("[ADMIN_LOOKUPFLW(usr)] activated a bluespace capsule away from the mining level! [ADMIN_JMP(T)]")
log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [get_area(T)][COORD(T)]")
template.load(deploy_location, centered = TRUE)
new /obj/effect/particle_effect/smoke(get_turf(src))
qdel(src)
/obj/item/weapon/survivalcapsule/luxury
name = "luxury bluespace shelter capsule"
desc = "An exorbitantly expensive luxury suite stored within a pocket of bluespace."
origin_tech = "engineering=3;bluespace=4"
template_id = "shelter_beta"
//Pod objects
//Window
/obj/structure/window/shuttle/survival_pod
name = "pod window"
icon = 'icons/obj/smooth_structures/pod_window.dmi'
icon_state = "smooth"
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod)
/obj/structure/window/reinforced/survival_pod
name = "pod window"
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "pwindow"
//Door
/obj/machinery/door/airlock/survival_pod
name = "airlock"
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_pod
opacity = FALSE
glass = TRUE
var/expected_dir = SOUTH //we visually turn when shuttle rotated, but need to not turn for any other reason
/obj/machinery/door/airlock/survival_pod/setDir(direction)
direction = expected_dir
..()
/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/machinery/door/airlock/survival_pod/vertical
dir = EAST
expected_dir = EAST
/obj/structure/door_assembly/door_assembly_pod
name = "pod airlock assembly"
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
airlock_type = /obj/machinery/door/airlock/survival_pod
anchored = TRUE
state = 1
mineral = "glass"
material = "glass"
var/expected_dir = SOUTH
/obj/structure/door_assembly/door_assembly_pod/setDir(direction)
direction = expected_dir
..()
/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/structure/door_assembly/door_assembly_pod/vertical
dir = EAST
expected_dir = EAST
//Windoor
/obj/machinery/door/window/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "windoor"
base_state = "windoor"
//Table
/obj/structure/table/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "table"
smooth = SMOOTH_FALSE
//Sleeper
/obj/machinery/sleeper/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper"
/obj/machinery/sleeper/survival_pod/update_icon()
if(state_open)
cut_overlays()
else
add_overlay("sleeper_cover")
//Computer
/obj/item/device/gps/computer
name = "pod computer"
icon_state = "pod_computer"
icon = 'icons/obj/lavaland/pod_computer.dmi'
anchored = TRUE
density = TRUE
pixel_y = -32
/obj/item/device/gps/computer/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench) && !(flags&NODECONSTRUCT))
playsound(src.loc, W.usesound, 50, 1)
user.visible_message("<span class='warning'>[user] disassembles the gps.</span>", \
"<span class='notice'>You start to disassemble the gps...</span>", "You hear clanking and banging noises.")
if(do_after(user, 20*W.toolspeed, target = src))
new /obj/item/device/gps(loc)
qdel(src)
return
return ..()
/obj/item/device/gps/computer/attack_hand(mob/user)
attack_self(user)
//Bed
/obj/structure/bed/pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "bed"
//Survival Storage Unit
/obj/machinery/smartfridge/survival_pod
name = "survival pod storage"
desc = "A heated storage unit."
icon_state = "donkvendor"
icon = 'icons/obj/lavaland/donkvendor.dmi'
icon_on = "donkvendor"
icon_off = "donkvendor"
light_range = 5
light_power = 1.2
light_color = "#DDFFD3"
max_n_of_items = 10
pixel_y = -4
flags = NODECONSTRUCT
/obj/machinery/smartfridge/survival_pod/empty
name = "dusty survival pod storage"
desc = "A heated storage unit. This one's seen better days."
/obj/machinery/smartfridge/survival_pod/empty/Initialize(mapload)
..(mapload, TRUE)
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
if(istype(O, /obj/item))
return 1
return 0
/obj/machinery/smartfridge/survival_pod/Initialize(mapload, empty)
. = ..()
if(empty)
return
for(var/i in 1 to 5)
var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/warm/W = new(src)
load(W)
if(prob(50))
var/obj/item/weapon/storage/pill_bottle/dice/D = new(src)
load(D)
else
var/obj/item/device/instrument/guitar/G = new(src)
load(G)
//Fans
/obj/structure/fans
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "fans"
name = "environmental regulation system"
desc = "A large machine releasing a constant gust of air."
anchored = TRUE
density = TRUE
var/arbitraryatmosblockingvar = TRUE
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 5
CanAtmosPass = ATMOS_PASS_NO
/obj/structure/fans/deconstruct()
if(!(flags & NODECONSTRUCT))
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
qdel(src)
/obj/structure/fans/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench) && !(flags&NODECONSTRUCT))
playsound(src.loc, W.usesound, 50, 1)
user.visible_message("<span class='warning'>[user] disassembles the fan.</span>", \
"<span class='notice'>You start to disassemble the fan...</span>", "You hear clanking and banging noises.")
if(do_after(user, 20*W.toolspeed, target = src))
deconstruct()
return ..()
/obj/structure/fans/tiny
name = "tiny fan"
desc = "A tiny fan, releasing a thin gust of air."
layer = ABOVE_NORMAL_TURF_LAYER
density = FALSE
icon_state = "fan_tiny"
buildstackamount = 2
/obj/structure/fans/Initialize(mapload)
. = ..()
air_update_turf(1)
/obj/structure/fans/Destroy()
var/turf/T = loc
. = ..()
T.air_update_turf(1)
//Inivisible, indestructible fans
/obj/structure/fans/tiny/invisible
name = "air flow blocker"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
invisibility = INVISIBILITY_ABSTRACT
//Signs
/obj/structure/sign/mining
name = "nanotrasen mining corps sign"
desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims."
icon = 'icons/turf/walls/survival_pod_walls.dmi'
icon_state = "ntpod"
/obj/structure/sign/mining/survival
name = "shelter sign"
desc = "A high visibility sign designating a safe shelter."
icon = 'icons/turf/walls/survival_pod_walls.dmi'
icon_state = "survival"
//Fluff
/obj/structure/tubes
icon_state = "tubes"
icon = 'icons/obj/lavaland/survival_pod.dmi'
name = "tubes"
anchored = TRUE
layer = BELOW_MOB_LAYER
density = FALSE
/obj/item/fakeartefact
name = "expensive forgery"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
var/possible = list(/obj/item/ship_in_a_bottle,
/obj/item/weapon/gun/energy/pulse,
/obj/item/weapon/sleeping_carp_scroll,
/obj/item/weapon/melee/supermatter_sword,
/obj/item/weapon/shield/changeling,
/obj/item/weapon/lava_staff,
/obj/item/weapon/katana/energy,
/obj/item/weapon/hierophant_club,
/obj/item/weapon/his_grace,
/obj/item/weapon/gun/ballistic/minigun,
/obj/item/weapon/gun/ballistic/automatic/l6_saw,
/obj/item/weapon/gun/magic/staff/chaos,
/obj/item/weapon/gun/magic/staff/spellblade,
/obj/item/weapon/gun/magic/wand/death,
/obj/item/weapon/gun/magic/wand/fireball,
/obj/item/stack/telecrystal/twenty,
/obj/item/nuke_core,
/obj/item/phylactery,
/obj/item/riding_offhand,
/obj/item/weapon/banhammer)
/obj/item/fakeartefact/Initialize()
. = ..()
var/obj/item/I = pick(possible)
name = initial(I.name)
icon = initial(I.icon)
desc = initial(I.desc)
icon_state = initial(I.icon_state)
item_state = initial(I.item_state)
@@ -11,7 +11,7 @@
desc = "It's watching you suspiciously."
/obj/structure/closet/crate/necropolis/tendril/PopulateContents()
var/loot = rand(1,26)
var/loot = rand(1,27)
switch(loot)
if(1)
new /obj/item/device/shared_storage/red(src)
@@ -28,9 +28,7 @@
if(7)
new /obj/item/weapon/pickaxe/diamond(src)
if(8)
new /obj/item/clothing/head/culthood(src)
new /obj/item/clothing/suit/cultrobes(src)
new /obj/item/weapon/bedsheet/cult(src)
new /obj/item/borg/upgrade/modkit/resonator_blasts(src)
if(9)
new /obj/item/organ/brain/alien(src)
if(10)
@@ -40,7 +38,7 @@
if(12)
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src)
if(13)
new /obj/item/weapon/sord(src)
new /obj/item/borg/upgrade/modkit/cooldown/repeater(src)
if(14)
new /obj/item/weapon/nullrod/scythe/talking(src)
if(15)
@@ -68,6 +66,9 @@
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
if(26)
new /obj/item/book_of_babel(src)
if(27)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/weapon/bedsheet/cult(src)
+4
View File
@@ -9,6 +9,9 @@
anchored = 1
var/obj/item/weapon/card/id/inserted_id
var/list/prize_list = list( //if you add something to this, please, for the love of god, use tabs and not spaces.
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10),
new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100),
new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300),
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 100),
new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/premium,100),
new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/cigarette/cigar/havana, 150),
@@ -182,6 +185,7 @@
if("Extraction and Rescue Kit")
new /obj/item/weapon/extraction_pack(loc)
new /obj/item/fulton_core(loc)
new /obj/item/stack/marker_beacon/thirty(loc)
if("Crusher Kit")
new /obj/item/weapon/twohanded/required/mining_hammer(loc)
new /obj/item/weapon/storage/belt/mining/alt(loc)
-423
View File
@@ -72,432 +72,9 @@
return
..()
/*********************Pickaxe & Drills**************************/
/obj/item/weapon/pickaxe
name = "pickaxe"
icon = 'icons/obj/mining.dmi'
icon_state = "pickaxe"
flags = CONDUCT
slot_flags = SLOT_BELT | SLOT_BACK
force = 15
throwforce = 10
item_state = "pickaxe"
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_METAL=2000) //one sheet, but where can you make them?
var/digspeed = 40
var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg')
origin_tech = "materials=2;engineering=3"
attack_verb = list("hit", "pierced", "sliced", "attacked")
/obj/item/weapon/pickaxe/mini
name = "compact pickaxe"
desc = "A smaller, compact version of the standard pickaxe."
icon_state = "minipick"
force = 10
throwforce = 7
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=1000)
/obj/item/weapon/pickaxe/proc/playDigSound()
playsound(src, pick(digsound),50,1)
/obj/item/weapon/pickaxe/silver
name = "silver-plated pickaxe"
icon_state = "spickaxe"
item_state = "spickaxe"
digspeed = 20 //mines faster than a normal pickaxe, bought from mining vendor
origin_tech = "materials=3;engineering=4"
desc = "A silver-plated pickaxe that mines slightly faster than standard-issue."
force = 17
/obj/item/weapon/pickaxe/diamond
name = "diamond-tipped pickaxe"
icon_state = "dpickaxe"
item_state = "dpickaxe"
digspeed = 14
origin_tech = "materials=5;engineering=4"
desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt."
force = 19
/obj/item/weapon/pickaxe/drill
name = "mining drill"
icon_state = "handdrill"
item_state = "jackhammer"
slot_flags = SLOT_BELT
digspeed = 25 //available from roundstart, faster than a pickaxe.
digsound = list('sound/weapons/drill.ogg')
hitsound = 'sound/weapons/drill.ogg'
origin_tech = "materials=2;powerstorage=2;engineering=3"
desc = "An electric mining drill for the especially scrawny."
/obj/item/weapon/pickaxe/drill/cyborg
name = "cyborg mining drill"
desc = "An integrated electric mining drill."
flags = NODROP
/obj/item/weapon/pickaxe/drill/diamonddrill
name = "diamond-tipped mining drill"
icon_state = "diamonddrill"
digspeed = 7
origin_tech = "materials=6;powerstorage=4;engineering=4"
desc = "Yours is the drill that will pierce the heavens!"
/obj/item/weapon/pickaxe/drill/cyborg/diamond //This is the BORG version!
name = "diamond-tipped cyborg mining drill" //To inherit the NODROP flag, and easier to change borg specific drill mechanics.
icon_state = "diamonddrill"
digspeed = 7
/obj/item/weapon/pickaxe/drill/jackhammer
name = "sonic jackhammer"
icon_state = "jackhammer"
item_state = "jackhammer"
digspeed = 5 //the epitome of powertools. extremely fast mining, laughs at puny walls
origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4"
digsound = list('sound/weapons/sonic_jackhammer.ogg')
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls."
/*****************************Shovel********************************/
/obj/item/weapon/shovel
name = "shovel"
desc = "A large tool for digging and moving dirt."
icon = 'icons/obj/mining.dmi'
icon_state = "shovel"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 8
var/digspeed = 20
throwforce = 4
item_state = "shovel"
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=50)
origin_tech = "materials=2;engineering=2"
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
sharpness = IS_SHARP
/obj/item/weapon/shovel/spade
name = "spade"
desc = "A small tool for digging and moving dirt."
icon_state = "spade"
item_state = "spade"
force = 5
throwforce = 7
w_class = WEIGHT_CLASS_SMALL
/obj/item/weapon/emptysandbag
name = "empty sandbag"
desc = "A bag to be filled with sand."
icon = 'icons/obj/items.dmi'
icon_state = "sandbag"
w_class = WEIGHT_CLASS_TINY
/obj/item/weapon/emptysandbag/attackby(obj/item/W, mob/user, params)
if(istype(W,/obj/item/weapon/ore/glass))
to_chat(user, "<span class='notice'>You fill the sandbag.</span>")
var/obj/item/stack/sheet/mineral/sandbags/I = new /obj/item/stack/sheet/mineral/sandbags
qdel(src)
user.put_in_hands(I)
qdel(W)
else
return ..()
/**********************Mining car (Crate like thing, not the rail car)**************************/
/obj/structure/closet/crate/miningcar
desc = "A mining car. This one doesn't work on rails, but has to be dragged."
name = "Mining car (not for rails)"
icon_state = "miningcar"
/*****************************Survival Pod********************************/
/area/survivalpod
name = "\improper Emergency Shelter"
icon_state = "away"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = 0
has_gravity = 1
/obj/item/weapon/survivalcapsule
name = "bluespace shelter capsule"
desc = "An emergency shelter stored within a pocket of bluespace."
icon_state = "capsule"
icon = 'icons/obj/mining.dmi'
w_class = WEIGHT_CLASS_TINY
origin_tech = "engineering=3;bluespace=3"
var/template_id = "shelter_alpha"
var/datum/map_template/shelter/template
var/used = FALSE
/obj/item/weapon/survivalcapsule/proc/get_template()
if(template)
return
template = SSmapping.shelter_templates[template_id]
if(!template)
throw EXCEPTION("Shelter template ([template_id]) not found!")
qdel(src)
/obj/item/weapon/survivalcapsule/Destroy()
template = null // without this, capsules would be one use. per round.
. = ..()
/obj/item/weapon/survivalcapsule/examine(mob/user)
. = ..()
get_template()
to_chat(user, "This capsule has the [template.name] stored.")
to_chat(user, template.description)
/obj/item/weapon/survivalcapsule/attack_self()
// Can't grab when capsule is New() because templates aren't loaded then
get_template()
if(used == FALSE)
src.loc.visible_message("<span class='warning'>\The [src] begins \
to shake. Stand back!</span>")
used = TRUE
sleep(50)
var/turf/deploy_location = get_turf(src)
var/status = template.check_deploy(deploy_location)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
src.loc.visible_message("<span class='warning'>\The [src] \
will not function in this area.</span>")
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS)
var/width = template.width
var/height = template.height
src.loc.visible_message("<span class='warning'>\The [src] \
doesn't have room to deploy! You need to clear a \
[width]x[height] area!</span>")
if(status != SHELTER_DEPLOY_ALLOWED)
used = FALSE
return
playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1)
var/turf/T = deploy_location
if(T.z != ZLEVEL_MINING && T.z != ZLEVEL_LAVALAND)//only report capsules away from the mining/lavaland level
message_admins("[ADMIN_LOOKUPFLW(usr)] activated a bluespace capsule away from the mining level! [ADMIN_JMP(T)]")
log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [get_area(T)][COORD(T)]")
template.load(deploy_location, centered = TRUE)
new /obj/effect/particle_effect/smoke(get_turf(src))
qdel(src)
//Pod turfs and objects
//Window
/obj/structure/window/shuttle/survival_pod
name = "pod window"
icon = 'icons/obj/smooth_structures/pod_window.dmi'
icon_state = "smooth"
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/closed/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod)
//Door
/obj/machinery/door/airlock/survival_pod
name = "airlock"
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_pod
opacity = 0
glass = 1
var/expected_dir = SOUTH //we visually turn when shuttle rotated, but need to not turn for any other reason
/obj/machinery/door/airlock/survival_pod/setDir(direction)
direction = expected_dir
..()
/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/machinery/door/airlock/survival_pod/vertical
dir = EAST
expected_dir = EAST
/obj/structure/door_assembly/door_assembly_pod
name = "pod airlock assembly"
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
airlock_type = /obj/machinery/door/airlock/survival_pod
anchored = 1
state = 1
mineral = "glass"
material = "glass"
var/expected_dir = SOUTH
/obj/structure/door_assembly/door_assembly_pod/setDir(direction)
direction = expected_dir
..()
/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/structure/door_assembly/door_assembly_pod/vertical
dir = EAST
expected_dir = EAST
//Table
/obj/structure/table/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "table"
smooth = SMOOTH_FALSE
//Sleeper
/obj/machinery/sleeper/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper"
/obj/machinery/sleeper/survival_pod/update_icon()
if(state_open)
cut_overlays()
else
add_overlay("sleeper_cover")
//Computer
/obj/item/device/gps/computer
name = "pod computer"
icon_state = "pod_computer"
icon = 'icons/obj/lavaland/pod_computer.dmi'
anchored = 1
density = 1
pixel_y = -32
/obj/item/device/gps/computer/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench) && !(flags&NODECONSTRUCT))
playsound(src.loc, W.usesound, 50, 1)
user.visible_message("<span class='warning'>[user] disassembles the gps.</span>", \
"<span class='notice'>You start to disassemble the gps...</span>", "You hear clanking and banging noises.")
if(do_after(user, 20*W.toolspeed, target = src))
new /obj/item/device/gps(src.loc)
qdel(src)
return ..()
/obj/item/device/gps/computer/attack_hand(mob/user)
attack_self(user)
//Bed
/obj/structure/bed/pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "bed"
//Survival Storage Unit
/obj/machinery/smartfridge/survival_pod
name = "survival pod storage"
desc = "A heated storage unit."
icon_state = "donkvendor"
icon = 'icons/obj/lavaland/donkvendor.dmi'
icon_on = "donkvendor"
icon_off = "donkvendor"
light_range = 5
light_power = 1.2
light_color = "#DDFFD3"
max_n_of_items = 10
pixel_y = -4
flags = NODECONSTRUCT
/obj/machinery/smartfridge/survival_pod/empty
name = "dusty survival pod storage"
desc = "A heated storage unit. This one's seen better days."
/obj/machinery/smartfridge/survival_pod/empty/Initialize(mapload)
..(mapload, TRUE)
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
if(istype(O, /obj/item))
return 1
return 0
/obj/machinery/smartfridge/survival_pod/Initialize(mapload, empty)
..()
if(empty)
return
for(var/i in 1 to 5)
var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/warm/W = new(src)
load(W)
if(prob(50))
var/obj/item/weapon/storage/pill_bottle/dice/D = new(src)
load(D)
else
var/obj/item/device/instrument/guitar/G = new(src)
load(G)
//Fans
/obj/structure/fans
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "fans"
name = "environmental regulation system"
desc = "A large machine releasing a constant gust of air."
anchored = 1
density = 1
var/arbitraryatmosblockingvar = TRUE
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 5
CanAtmosPass = ATMOS_PASS_NO
/obj/structure/fans/deconstruct()
if(!(flags & NODECONSTRUCT))
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
qdel(src)
/obj/structure/fans/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench) && !(flags&NODECONSTRUCT))
playsound(src.loc, W.usesound, 50, 1)
user.visible_message("<span class='warning'>[user] disassembles the fan.</span>", \
"<span class='notice'>You start to disassemble the fan...</span>", "You hear clanking and banging noises.")
if(do_after(user, 20*W.toolspeed, target = src))
deconstruct()
return ..()
/obj/structure/fans/tiny
name = "tiny fan"
desc = "A tiny fan, releasing a thin gust of air."
layer = ABOVE_NORMAL_TURF_LAYER
density = 0
icon_state = "fan_tiny"
buildstackamount = 2
/obj/structure/fans/New(loc)
..()
air_update_turf(1)
/obj/structure/fans/Destroy()
var/turf/T = loc
. = ..()
T.air_update_turf(1)
//Inivisible, indestructible fans
/obj/structure/fans/tiny/invisible
name = "air flow blocker"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
invisibility = INVISIBILITY_ABSTRACT
//Signs
/obj/structure/sign/mining
name = "nanotrasen mining corps sign"
desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims."
icon = 'icons/turf/walls/survival_pod_walls.dmi'
icon_state = "ntpod"
/obj/structure/sign/mining/survival
name = "shelter sign"
desc = "A high visibility sign designating a safe shelter."
icon = 'icons/turf/walls/survival_pod_walls.dmi'
icon_state = "survival"
//Fluff
/obj/structure/tubes
icon_state = "tubes"
icon = 'icons/obj/lavaland/survival_pod.dmi'
name = "tubes"
anchored = 1
layer = BELOW_MOB_LAYER
density = 0

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