Merge branch 'master' into upstream-merge-27801
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
@@ -51,7 +51,7 @@
|
||||
user.remote_control = null
|
||||
user = null
|
||||
QDEL_NULL(eye)
|
||||
|
||||
|
||||
if(hologram)
|
||||
hologram.HC = null
|
||||
hologram = null
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
@@ -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.")
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
+825
-823
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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///////////
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user