Merge branch 'master' into upstream-merge-27773
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#define WACKY "Wacky"
|
||||
#define MUT_MUTE "Mute"
|
||||
#define SMILE "Smile"
|
||||
#define STONER "Stoner"
|
||||
#define UNINTELLIGABLE "Unintelligable"
|
||||
#define SWEDISH "Swedish"
|
||||
#define CHAV "Chav"
|
||||
|
||||
@@ -95,11 +95,13 @@
|
||||
|
||||
//tablecrafting defines
|
||||
#define CAT_NONE ""
|
||||
#define CAT_WEAPON "Weaponry"
|
||||
#define CAT_WEAPONRY "Weaponry"
|
||||
#define CAT_WEAPON "Weapons"
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_ROBOT "Robots"
|
||||
#define CAT_MISC "Misc"
|
||||
#define CAT_PRIMAL "Tribal"
|
||||
#define CAT_FOOD "Foods"
|
||||
#define CAT_BREAD "Breads"
|
||||
#define CAT_BURGER "Burgers"
|
||||
#define CAT_CAKE "Cakes"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -34,8 +34,8 @@ Last space-z level = empty
|
||||
#define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) && ..() }
|
||||
|
||||
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
|
||||
#define ZLEVEL_STATION 1
|
||||
#define ZLEVEL_CENTCOM 2
|
||||
#define ZLEVEL_CENTCOM 1
|
||||
#define ZLEVEL_STATION 2
|
||||
#define ZLEVEL_MINING 5
|
||||
#define ZLEVEL_LAVALAND 5
|
||||
#define ZLEVEL_EMPTY_SPACE 11
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
27
code/__DEFINES/server_tools.dm
Normal file
27
code/__DEFINES/server_tools.dm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define REBOOT_MODE_NORMAL 0
|
||||
#define REBOOT_MODE_HARD 1
|
||||
#define REBOOT_MODE_SHUTDOWN 2
|
||||
|
||||
#define IRC_STATUS_THROTTLE 50
|
||||
|
||||
//keep these in sync with TGS3
|
||||
#define SERVICE_WORLD_PARAM "server_service"
|
||||
#define SERVICE_PR_TEST_JSON "..\\..\\prtestjob.json"
|
||||
|
||||
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
|
||||
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
|
||||
#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce"
|
||||
#define SERVICE_CMD_IRC_STATUS "irc_status"
|
||||
#define SERVICE_CMD_ADMIN_MSG "adminmsg"
|
||||
#define SERVICE_CMD_NAME_CHECK "namecheck"
|
||||
#define SERVICE_CMD_ADMIN_WHO "adminwho"
|
||||
|
||||
//#define SERVICE_CMD_PARAM_KEY //defined in __compile_options.dm
|
||||
#define SERVICE_CMD_PARAM_COMMAND "command"
|
||||
#define SERVICE_CMD_PARAM_MESSAGE "message"
|
||||
#define SERVICE_CMD_PARAM_TARGET "target"
|
||||
#define SERVICE_CMD_PARAM_SENDER "sender"
|
||||
|
||||
#define SERVICE_REQUEST_KILL_PROCESS "killme"
|
||||
#define SERVICE_REQUEST_IRC_BROADCAST "irc"
|
||||
#define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc"
|
||||
@@ -30,7 +30,6 @@
|
||||
// DEBUFFS //
|
||||
/////////////
|
||||
|
||||
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
|
||||
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
|
||||
|
||||
#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
|
||||
@@ -41,3 +40,12 @@
|
||||
|
||||
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
|
||||
|
||||
|
||||
/////////////
|
||||
// NEUTRAL //
|
||||
/////////////
|
||||
|
||||
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
|
||||
|
||||
#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -131,9 +131,12 @@
|
||||
return
|
||||
|
||||
//Removes any null entries from the list
|
||||
//Returns TRUE if the list had nulls, FALSE otherwise
|
||||
/proc/listclearnulls(list/L)
|
||||
var/list/N = new(L.len)
|
||||
var/start_len = L.len
|
||||
var/list/N = new(start_len)
|
||||
L -= N
|
||||
return L.len < start_len
|
||||
|
||||
/*
|
||||
* Returns list containing all the entries from first list that are not present in second.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
for(var/file in args)
|
||||
src << browse_rsc(file)
|
||||
|
||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
|
||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html"))
|
||||
var/path = root
|
||||
|
||||
for(var/i=0, i<max_iterations, i++)
|
||||
@@ -22,9 +22,13 @@
|
||||
|
||||
if(copytext(path,-1,0) != "/") //didn't choose a directory, no need to iterate again
|
||||
break
|
||||
|
||||
var/extension = copytext(path,-4,0)
|
||||
if( !fexists(path) || !(extension in valid_extensions) )
|
||||
var/extensions
|
||||
for(var/i in valid_extensions)
|
||||
if(extensions)
|
||||
extensions += "|"
|
||||
extensions += "[i]"
|
||||
var/regex/valid_ext = new("\\.([extensions])$", "i")
|
||||
if( !fexists(path) || !(valid_ext.Find(path)) )
|
||||
to_chat(src, "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>")
|
||||
return
|
||||
|
||||
|
||||
@@ -507,7 +507,8 @@
|
||||
return
|
||||
|
||||
//First we spawn a dude.
|
||||
var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
|
||||
var/mob/living/carbon/human/new_character = new//The mob being spawned.
|
||||
SSjob.SendToLateJoin(new_character)
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
new_character.dna.update_dna_identity()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1343,7 +1344,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
//kevinz000 if you touch this I will hunt you down
|
||||
GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE)
|
||||
GLOBAL_PROTECT(valid_HTTPSGet)
|
||||
/proc/HTTPSGet(url)
|
||||
/proc/HTTPSGet(url) //tgs2 support
|
||||
if(findtext(url, "\""))
|
||||
GLOB.valid_HTTPSGet = FALSE
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
//MINOR TWEAKS/MISC
|
||||
#define AGE_MIN 17 //youngest a character can be
|
||||
#define AGE_MAX 85 //oldest a character can be
|
||||
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
|
||||
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
|
||||
#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up
|
||||
#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets
|
||||
#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
|
||||
@@ -62,14 +62,12 @@
|
||||
#endif
|
||||
|
||||
//Update this whenever you need to take advantage of more recent byond features
|
||||
#define MIN_COMPILER_VERSION 511
|
||||
#define MIN_COMPILER_VERSION 511
|
||||
#if DM_VERSION < MIN_COMPILER_VERSION
|
||||
//Don't forget to update this part
|
||||
#error Your version of BYOND is too out-of-date to compile this project. Go to byond.com/download and update.
|
||||
#error You need version 511 or higher
|
||||
#error You need version 511 or higher
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SERVERTOOLS
|
||||
#define SERVERTOOLS 0
|
||||
#endif
|
||||
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events
|
||||
|
||||
GLOBAL_LIST_EMPTY(wizardstart)
|
||||
GLOBAL_LIST_EMPTY(newplayer_start)
|
||||
GLOBAL_LIST_EMPTY(latejoin)
|
||||
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
|
||||
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here
|
||||
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
|
||||
|
||||
@@ -32,4 +32,6 @@ GLOBAL_LIST_EMPTY(ladders)
|
||||
GLOBAL_LIST_EMPTY(trophy_cases)
|
||||
|
||||
GLOBAL_LIST_EMPTY(wire_color_directory)
|
||||
GLOBAL_LIST_EMPTY(wire_name_directory)
|
||||
GLOBAL_LIST_EMPTY(wire_name_directory)
|
||||
|
||||
GLOBAL_LIST_EMPTY(ai_status_displays)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -261,6 +263,8 @@
|
||||
|
||||
var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart.
|
||||
|
||||
var/irc_announce_new_game = FALSE
|
||||
|
||||
/datum/configuration/New()
|
||||
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
|
||||
for(var/T in gamemode_cache)
|
||||
@@ -409,6 +413,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")
|
||||
@@ -423,7 +429,7 @@
|
||||
popup_admin_pm = 1
|
||||
if("allow_holidays")
|
||||
allow_holidays = 1
|
||||
if("useircbot")
|
||||
if("useircbot") //tgs2 support
|
||||
useircbot = 1
|
||||
if("ticklag")
|
||||
var/ticklag = text2num(value)
|
||||
@@ -536,6 +542,8 @@
|
||||
error_silence_time = text2num(value)
|
||||
if("error_msg_delay")
|
||||
error_msg_delay = text2num(value)
|
||||
if("irc_announce_new_game")
|
||||
irc_announce_new_game = TRUE
|
||||
else
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
@@ -827,6 +835,8 @@
|
||||
if ("endmap")
|
||||
maplist[currentmap.map_name] = currentmap
|
||||
currentmap = null
|
||||
if ("disabled")
|
||||
currentmap = null
|
||||
else
|
||||
GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
|
||||
|
||||
|
||||
@@ -177,7 +177,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
to_chat(world, "<span class='boldannounce'>[msg]</span>")
|
||||
log_world(msg)
|
||||
|
||||
SetRunLevel(1)
|
||||
if (!current_runlevel)
|
||||
SetRunLevel(1)
|
||||
|
||||
// Sort subsystems by display setting for easy access.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_display)
|
||||
|
||||
@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
|
||||
query_record_playercount.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
@@ -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
|
||||
|
||||
@@ -178,7 +176,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
|
||||
query_report_death.Execute()
|
||||
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
510
code/controllers/subsystem/explosion.dm
Normal file
510
code/controllers/subsystem/explosion.dm
Normal file
@@ -0,0 +1,510 @@
|
||||
SUBSYSTEM_DEF(explosion)
|
||||
priority = 99
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/explosions
|
||||
|
||||
var/rebuild_tick_split_count = FALSE
|
||||
var/tick_portions_required = 0
|
||||
|
||||
var/list/logs
|
||||
|
||||
var/list/zlevels_that_ignore_bombcap
|
||||
var/list/doppler_arrays
|
||||
|
||||
//legacy caps, set by config
|
||||
var/devastation_cap = 3
|
||||
var/heavy_cap = 7
|
||||
var/light_cap = 14
|
||||
var/flash_cap = 14
|
||||
var/flame_cap = 14
|
||||
var/dyn_ex_scale = 0.5
|
||||
|
||||
var/id_counter = 0
|
||||
|
||||
/datum/controller/subsystem/explosion/PreInit()
|
||||
doppler_arrays = list()
|
||||
logs = list()
|
||||
explosions = list()
|
||||
zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]")
|
||||
|
||||
/datum/controller/subsystem/explosion/Shutdown()
|
||||
QDEL_LIST(explosions)
|
||||
QDEL_LIST(logs)
|
||||
zlevels_that_ignore_bombcap.Cut()
|
||||
|
||||
/datum/controller/subsystem/explosion/Recover()
|
||||
explosions = SSexplosion.explosions
|
||||
logs = SSexplosion.logs
|
||||
id_counter = SSexplosion.id_counter
|
||||
rebuild_tick_split_count = TRUE
|
||||
zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap
|
||||
doppler_arrays = SSexplosion.doppler_arrays
|
||||
|
||||
devastation_cap = SSexplosion.devastation_cap
|
||||
heavy_cap = SSexplosion.heavy_cap
|
||||
light_cap = SSexplosion.light_cap
|
||||
flash_cap = SSexplosion.flash_cap
|
||||
flame_cap = SSexplosion.flame_cap
|
||||
dyn_ex_scale = SSexplosion.dyn_ex_scale
|
||||
|
||||
/datum/controller/subsystem/explosion/fire()
|
||||
var/list/cached_explosions = explosions
|
||||
var/num_explosions = cached_explosions.len
|
||||
if(!num_explosions)
|
||||
return
|
||||
|
||||
//figure exactly how many tick splits are required
|
||||
var/num_splits
|
||||
if(rebuild_tick_split_count)
|
||||
var/reactionary = config.reactionary_explosions
|
||||
num_splits = num_explosions
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
if(!E.turfs_processed)
|
||||
++num_splits
|
||||
if(reactionary && !E.densities_processed)
|
||||
++num_splits
|
||||
tick_portions_required = num_splits
|
||||
else
|
||||
num_splits = tick_portions_required
|
||||
|
||||
MC_SPLIT_TICK_INIT(num_splits)
|
||||
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
|
||||
var/etp = E.turfs_processed
|
||||
if(!etp)
|
||||
if(GatherTurfs(E))
|
||||
--tick_portions_required
|
||||
etp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
var/edp = E.densities_processed
|
||||
if(!edp)
|
||||
if(DensityCalculate(E, etp))
|
||||
--tick_portions_required
|
||||
edp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
if(ProcessExplosion(E, edp)) //splits the tick
|
||||
--tick_portions_required
|
||||
explosions -= E
|
||||
logs += E
|
||||
NotifyDopplers(E)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E)
|
||||
for(var/array in doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range)
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
|
||||
|
||||
var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/Eff
|
||||
if(smoke)
|
||||
Eff = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
Eff = new
|
||||
Eff.set_up(epicenter)
|
||||
Eff.start()
|
||||
|
||||
//flash mobs
|
||||
if(flash_range)
|
||||
for(var/mob/living/L in viewers(flash_range, epicenter))
|
||||
L.flash_act()
|
||||
|
||||
if(!silent)
|
||||
ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent)
|
||||
|
||||
//add to SS
|
||||
if(E.extent)
|
||||
tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0)
|
||||
explosions += E
|
||||
else
|
||||
logs += E //Already done processing
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE)
|
||||
if(!power)
|
||||
return
|
||||
var/range = round((2 * power) ** dyn_ex_scale)
|
||||
Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke)
|
||||
|
||||
// Using default dyn_ex scale:
|
||||
// 100 explosion power is a (5, 10, 20) explosion.
|
||||
// 75 explosion power is a (4, 8, 17) explosion.
|
||||
// 50 explosion power is a (3, 7, 14) explosion.
|
||||
// 25 explosion power is a (2, 5, 10) explosion.
|
||||
// 10 explosion power is a (1, 3, 6) explosion.
|
||||
// 5 explosion power is a (0, 1, 3) explosion.
|
||||
// 1 explosion power is a (0, 0, 1) explosion.
|
||||
|
||||
/datum/explosion
|
||||
var/explosion_id
|
||||
var/turf/epicenter
|
||||
|
||||
var/started_at
|
||||
var/finished_at
|
||||
var/tick_started
|
||||
var/tick_finished
|
||||
|
||||
var/turfs_processed = FALSE
|
||||
var/densities_processed = FALSE
|
||||
|
||||
var/orig_dev_range
|
||||
var/orig_heavy_range
|
||||
var/orig_light_range
|
||||
var/orig_flash_range
|
||||
var/orig_flame_range
|
||||
|
||||
var/devastation
|
||||
var/heavy
|
||||
var/light
|
||||
var/extent
|
||||
|
||||
var/flash
|
||||
var/flame
|
||||
|
||||
var/gather_dist = 0
|
||||
|
||||
var/list/gathered_turfs
|
||||
var/list/calculated_turfs
|
||||
|
||||
var/list/unsafe_turfs
|
||||
|
||||
/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
explosion_id = id
|
||||
epicenter = epi
|
||||
|
||||
densities_processed = !config.reactionary_explosions
|
||||
|
||||
orig_dev_range = devastation_range
|
||||
orig_heavy_range = heavy_impact_range
|
||||
orig_light_range = light_impact_range
|
||||
orig_flash_range = flash_range
|
||||
orig_flame_range = flame_range
|
||||
|
||||
if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap))
|
||||
//Clamp all values
|
||||
devastation_range = min(SSexplosion.devastation_cap, devastation_range)
|
||||
heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range)
|
||||
light_impact_range = min(SSexplosion.light_cap, light_impact_range)
|
||||
flash_range = min(SSexplosion.flash_cap, flash_range)
|
||||
flame_range = min(SSexplosion.flame_cap, flame_range)
|
||||
|
||||
//store this
|
||||
devastation = devastation_range
|
||||
heavy = heavy_impact_range
|
||||
light = light_impact_range
|
||||
|
||||
extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
|
||||
flash = flash_range
|
||||
flame = flame_range
|
||||
|
||||
started_at = REALTIMEOFDAY
|
||||
tick_started = world.time
|
||||
|
||||
gathered_turfs = list()
|
||||
calculated_turfs = list()
|
||||
unsafe_turfs = list()
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
|
||||
// 3/7/14 will calculate to 80 + 35
|
||||
/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent)
|
||||
var/far_dist = 0
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(extent + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
|
||||
/datum/explosion/Destroy()
|
||||
SSexplosion.explosions -= src
|
||||
SSexplosion.logs -= src
|
||||
LAZYCLEARLIST(gathered_turfs)
|
||||
LAZYCLEARLIST(calculated_turfs)
|
||||
LAZYCLEARLIST(unsafe_turfs)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E)
|
||||
var/turf/epicenter = E.epicenter
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/c_dist = E.gather_dist
|
||||
var/dist = E.extent
|
||||
|
||||
var/list/L = E.gathered_turfs
|
||||
|
||||
if(!c_dist)
|
||||
L += epicenter
|
||||
++c_dist
|
||||
|
||||
while( c_dist <= dist )
|
||||
var/y = y0 + c_dist
|
||||
var/x = x0 - c_dist + 1
|
||||
for(x in x to x0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 + c_dist - 1
|
||||
x = x0 + c_dist
|
||||
for(y in y0 - c_dist to y)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist
|
||||
x = x0 + c_dist - 1
|
||||
for(x in x0 - c_dist to x)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist + 1
|
||||
x = x0 - c_dist
|
||||
for(y in y to y0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
++c_dist
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
if(c_dist > dist)
|
||||
E.turfs_processed = TRUE
|
||||
return TRUE
|
||||
else
|
||||
E.gather_dist = c_dist
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs)
|
||||
var/list/L = E.calculated_turfs
|
||||
var/cut_to = 1
|
||||
for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = I
|
||||
++cut_to
|
||||
|
||||
var/current_exp_block = T.density ? T.explosion_block : 0
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density)
|
||||
current_exp_block += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
current_exp_block += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
current_exp_block += B.explosion_block
|
||||
|
||||
L[T] = current_exp_block
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
E.gathered_turfs.Cut(1, cut_to)
|
||||
return FALSE
|
||||
|
||||
E.gathered_turfs.Cut()
|
||||
return done_gathering_turfs
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs)
|
||||
//cache shit for speed
|
||||
var/id = E.explosion_id
|
||||
|
||||
var/list/cached_unsafe = E.unsafe_turfs
|
||||
var/list/cached_exp_block = E.calculated_turfs
|
||||
var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs
|
||||
|
||||
var/devastation_range = E.devastation
|
||||
var/heavy_impact_range = E.heavy
|
||||
var/light_impact_range = E.light
|
||||
|
||||
var/flame_range = E.flame
|
||||
var/throw_range_max = E.extent
|
||||
|
||||
var/turf/epi = E.epicenter
|
||||
|
||||
var/x0 = epi.x
|
||||
var/y0 = epi.y
|
||||
|
||||
var/cut_to = 1
|
||||
for(var/TI in affected_turfs)
|
||||
var/turf/T = TI
|
||||
++cut_to
|
||||
|
||||
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
|
||||
var/dist = init_dist
|
||||
|
||||
if(cached_exp_block)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epi)
|
||||
Trajectory = get_step_towards(Trajectory, epi)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = dist < flame_range
|
||||
var/throw_dist = dist
|
||||
|
||||
if(dist < devastation_range)
|
||||
dist = 1
|
||||
else if(dist < heavy_impact_range)
|
||||
dist = 2
|
||||
else if(dist < light_impact_range)
|
||||
dist = 3
|
||||
else
|
||||
dist = 0
|
||||
|
||||
//------- EX_ACT AND TURF FIRES -------
|
||||
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
cached_unsafe += T
|
||||
|
||||
//--- THROW ITEMS AROUND ---
|
||||
|
||||
var/throw_dir = get_dir(epi, T)
|
||||
for(var/obj/item/I in T)
|
||||
if(!I.anchored)
|
||||
var/throw_range = rand(throw_dist, throw_range_max)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, 4)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
|
||||
if(cached_unsafe.len > circumference) //only do this every revolution
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
done_calculating_turfs = FALSE
|
||||
break
|
||||
|
||||
affected_turfs.Cut(1, cut_to)
|
||||
|
||||
if(!done_calculating_turfs)
|
||||
return FALSE
|
||||
|
||||
//unfuck the shit
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
|
||||
E.finished_at = REALTIMEOFDAY
|
||||
E.tick_finished = world.time
|
||||
|
||||
return TRUE
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
|
||||
var/dev = 0
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = input("Bomb Size?") in choices
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
if("Small Bomb")
|
||||
dev = 1
|
||||
heavy = 2
|
||||
light = 3
|
||||
if("Medium Bomb")
|
||||
dev = 2
|
||||
heavy = 3
|
||||
light = 4
|
||||
if("Big Bomb")
|
||||
dev = 3
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devestation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
else
|
||||
return
|
||||
|
||||
var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE)
|
||||
|
||||
while(!SSexplosion.GatherTurfs(E))
|
||||
stoplag()
|
||||
var/list/turfs
|
||||
if(newmode)
|
||||
while(!SSexplosion.DensityCalculate(E, TRUE))
|
||||
stoplag()
|
||||
turfs = E.calculated_turfs.Copy()
|
||||
else
|
||||
turfs = E.gathered_turfs.Copy()
|
||||
|
||||
qdel(E)
|
||||
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T]
|
||||
|
||||
if(dist < dev)
|
||||
T.color = "red"
|
||||
T.maptext = "Dev"
|
||||
else if (dist < heavy)
|
||||
T.color = "yellow"
|
||||
T.maptext = "Heavy"
|
||||
else if (dist < light)
|
||||
T.color = "blue"
|
||||
T.maptext = "Light"
|
||||
CHECK_TICK
|
||||
|
||||
sleep(100)
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
T.color = null
|
||||
T.maptext = null
|
||||
@@ -11,6 +11,7 @@ SUBSYSTEM_DEF(job)
|
||||
var/initial_players_to_assign = 0 //used for checking against population caps
|
||||
|
||||
var/list/prioritized_jobs = list()
|
||||
var/list/latejoin_trackers = list() //Don't read this list, use GetLateJoinTurfs() instead
|
||||
|
||||
/datum/controller/subsystem/job/Initialize(timeofday)
|
||||
if(!occupations.len)
|
||||
@@ -378,23 +379,11 @@ SUBSYSTEM_DEF(job)
|
||||
continue
|
||||
S = sloc
|
||||
break
|
||||
if(S)
|
||||
SendToAtom(H, S, buckle = FALSE)
|
||||
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
|
||||
log_world("Couldn't find a round start spawn point for [rank]")
|
||||
S = get_turf(pick(GLOB.latejoin))
|
||||
if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to.
|
||||
log_world("Couldn't find a round start latejoin spawn point.")
|
||||
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
S = T
|
||||
continue
|
||||
if(istype(S, /obj/effect/landmark) && isturf(S.loc))
|
||||
H.loc = S.loc
|
||||
SendToLateJoin(H)
|
||||
|
||||
if(H.mind)
|
||||
H.mind.assigned_role = rank
|
||||
@@ -516,3 +505,45 @@ SUBSYSTEM_DEF(job)
|
||||
newjob.total_positions = J.total_positions
|
||||
newjob.spawn_positions = J.spawn_positions
|
||||
newjob.current_positions = J.current_positions
|
||||
|
||||
/datum/controller/subsystem/job/proc/SendToAtom(mob/M, atom/A, buckle)
|
||||
if(buckle && isliving(M) && istype(A, /obj/structure/chair))
|
||||
var/obj/structure/chair/C = A
|
||||
if(C.buckle_mob(M, FALSE, FALSE))
|
||||
return
|
||||
M.forceMove(get_turf(A))
|
||||
|
||||
/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE)
|
||||
if(latejoin_trackers.len)
|
||||
SendToAtom(M, pick(latejoin_trackers), buckle)
|
||||
else
|
||||
//bad mojo
|
||||
var/area/shuttle/arrival/A = locate() in GLOB.sortedAreas
|
||||
if(A)
|
||||
//first check if we can find a chair
|
||||
var/obj/structure/chair/C = locate() in A
|
||||
if(C)
|
||||
SendToAtom(M, C, buckle)
|
||||
return
|
||||
else //last hurrah
|
||||
var/list/avail = list()
|
||||
for(var/turf/T in A)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
avail += T
|
||||
if(avail.len)
|
||||
SendToAtom(M, pick(avail), FALSE)
|
||||
return
|
||||
|
||||
//pick an open spot on arrivals and dump em
|
||||
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
|
||||
if(arrivals_turfs.len)
|
||||
for(var/turf/T in arrivals_turfs)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
SendToAtom(M, T, FALSE)
|
||||
return
|
||||
//last chance, pick ANY spot on arrivals and dump em
|
||||
SendToAtom(M, arrivals_turfs[1], FALSE)
|
||||
else
|
||||
var/msg = "Unable to send mob [M] to late join!"
|
||||
message_admins(msg)
|
||||
CRASH(msg)
|
||||
|
||||
@@ -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
|
||||
@@ -222,7 +223,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
/datum/controller/subsystem/shuttle/proc/centcom_recall(old_timer, admiral_message)
|
||||
if(emergency.mode != SHUTTLE_CALL || emergency.timer != old_timer)
|
||||
return
|
||||
emergency.cancel(/area/centcom)
|
||||
emergency.cancel()
|
||||
|
||||
if(!admiral_message)
|
||||
admiral_message = pick(GLOB.admiral_messages)
|
||||
|
||||
@@ -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
|
||||
@@ -744,6 +746,15 @@ SUBSYSTEM_DEF(ticker)
|
||||
cinematic = SSticker.cinematic
|
||||
maprotatechecked = SSticker.maprotatechecked
|
||||
|
||||
switch (current_state)
|
||||
if(GAME_STATE_SETTING_UP)
|
||||
Master.SetRunLevel(RUNLEVEL_SETUP)
|
||||
if(GAME_STATE_PLAYING)
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
if(GAME_STATE_FINISHED)
|
||||
Master.SetRunLevel(RUNLEVEL_POSTGAME)
|
||||
|
||||
|
||||
modevoted = SSticker.modevoted
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_news_report()
|
||||
@@ -833,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
|
||||
@@ -841,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>")
|
||||
|
||||
@@ -873,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.")
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/list/symptoms = list() // The symptoms of the disease.
|
||||
var/id = ""
|
||||
var/processing = 0
|
||||
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
var/static/list/advance_cures = list(
|
||||
"sodiumchloride", "sugar", "orangejuice",
|
||||
@@ -399,7 +399,7 @@
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
if(H.z != 1)
|
||||
if(H.z != ZLEVEL_STATION)
|
||||
continue
|
||||
if(!H.HasDisease(D))
|
||||
H.ForceContractDisease(D)
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
if(findtext(msg, "%s"))
|
||||
msg = replacetext(msg, "%s", user.p_s())
|
||||
|
||||
msg = replace_pronoun(user, msg)
|
||||
|
||||
var/mob/living/L = user
|
||||
for(var/obj/item/weapon/implant/I in L.implants)
|
||||
I.trigger(key, L)
|
||||
@@ -61,6 +63,15 @@
|
||||
user.visible_message(msg)
|
||||
log_emote("[key_name(user)] : [msg]")
|
||||
|
||||
/datum/emote/proc/replace_pronoun(mob/user, message)
|
||||
if(findtext(message, "their"))
|
||||
message = replacetext(message, "their", user.p_their())
|
||||
if(findtext(message, "them"))
|
||||
message = replacetext(message, "them", user.p_them())
|
||||
if(findtext(message, "%s"))
|
||||
message = replacetext(message, "%s", user.p_s())
|
||||
return message
|
||||
|
||||
/datum/emote/proc/select_message_type(mob/user)
|
||||
. = message
|
||||
if(!muzzle_ignore && user.is_muzzled() && emote_type == EMOTE_AUDIBLE)
|
||||
|
||||
@@ -1,10 +1,48 @@
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1)
|
||||
set waitfor = 0
|
||||
src = null //so we don't abort once src is deleted
|
||||
#define EXPLOSION_THROW_SPEED 4
|
||||
|
||||
GLOBAL_LIST_EMPTY(explosions)
|
||||
//Against my better judgement, I will return the explosion datum
|
||||
//If I see any GC errors for it I will find you
|
||||
//and I will gib you
|
||||
/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
|
||||
return new /datum/explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
|
||||
|
||||
//This datum creates 3 async tasks
|
||||
//1 GatherSpiralTurfsProc runs spiral_range_turfs(tick_checked = TRUE) to populate the affected_turfs list
|
||||
//2 CaculateExplosionBlock adds the blockings to the cached_exp_block list
|
||||
//3 The main thread explodes the prepared turfs
|
||||
|
||||
/datum/explosion
|
||||
var/explosion_id
|
||||
var/started_at
|
||||
var/running = TRUE
|
||||
var/stopped = 0 //This is the number of threads stopped !DOESN'T COUNT THREAD 2!
|
||||
var/static/id_counter = 0
|
||||
|
||||
#define EX_PREPROCESS_EXIT_CHECK \
|
||||
if(!running) {\
|
||||
stopped = 2;\
|
||||
qdel(src);\
|
||||
return;\
|
||||
}
|
||||
|
||||
#define EX_PREPROCESS_CHECK_TICK \
|
||||
if(TICK_CHECK) {\
|
||||
stoplag();\
|
||||
EX_PREPROCESS_EXIT_CHECK\
|
||||
}
|
||||
|
||||
/datum/explosion/New(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
|
||||
set waitfor = FALSE
|
||||
|
||||
var/id = ++id_counter
|
||||
explosion_id = id
|
||||
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
GLOB.explosions += src
|
||||
if(isnull(flame_range))
|
||||
flame_range = light_impact_range
|
||||
if(isnull(flash_range))
|
||||
@@ -30,14 +68,13 @@
|
||||
//I would make this not ex_act the thing that triggered the explosion,
|
||||
//but everything that explodes gives us their loc or a get_turf()
|
||||
//and somethings expect us to ex_act them so they can qdel()
|
||||
sleep(1) //tldr, let the calling proc call qdel(src) before we explode
|
||||
stoplag() //tldr, let the calling proc call qdel(src) before we explode
|
||||
|
||||
var/static/explosionid = 1
|
||||
var/id = explosionid++
|
||||
var/start = world.timeofday
|
||||
EX_PREPROCESS_EXIT_CHECK
|
||||
|
||||
started_at = REALTIMEOFDAY
|
||||
|
||||
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
var/list/cached_exp_block = list()
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
|
||||
@@ -53,23 +90,27 @@
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
if(!silent)
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
if(M && M.client)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == epicenter.z)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//postpone processing for a bit
|
||||
var/postponeCycles = max(round(devastation_range/8),1)
|
||||
@@ -77,66 +118,52 @@
|
||||
SSmachines.postpone(postponeCycles)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/E
|
||||
if(smoke)
|
||||
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
E = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
E = new
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
for(var/turf/T in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
cached_exp_block[T] = 0
|
||||
if(T.density && T.explosion_block)
|
||||
cached_exp_block[T] += T.explosion_block
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density && D.explosion_block)
|
||||
cached_exp_block[T] += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
cached_exp_block[T] += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
cached_exp_block[T] += B.explosion_block
|
||||
CHECK_TICK
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//flash mobs
|
||||
if(flash_range)
|
||||
for(var/mob/living/L in viewers(flash_range, epicenter))
|
||||
L.flash_act()
|
||||
|
||||
CHECK_TICK
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep
|
||||
for(var/turf/T in affected_turfs)
|
||||
var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter)
|
||||
|
||||
if (!T)
|
||||
continue
|
||||
var/reactionary = config.reactionary_explosions
|
||||
var/list/cached_exp_block
|
||||
|
||||
if(reactionary)
|
||||
cached_exp_block = CaculateExplosionBlock(affected_turfs)
|
||||
|
||||
//lists are guaranteed to contain at least 1 turf at this point
|
||||
|
||||
var/iteration = 0
|
||||
var/affTurfLen = affected_turfs.len
|
||||
var/expBlockLen = cached_exp_block.len
|
||||
for(var/TI in affected_turfs)
|
||||
var/turf/T = TI
|
||||
++iteration
|
||||
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
|
||||
var/dist = init_dist
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
if(reactionary)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epicenter)
|
||||
Trajectory = get_step_towards(Trajectory, epicenter)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = 0
|
||||
var/flame_dist = dist < flame_range
|
||||
var/throw_dist = dist
|
||||
|
||||
if(dist < flame_range)
|
||||
flame_dist = 1
|
||||
|
||||
if(dist < devastation_range)
|
||||
dist = 1
|
||||
else if(dist < heavy_impact_range)
|
||||
@@ -148,27 +175,61 @@
|
||||
|
||||
//------- EX_ACT AND TURF FIRES -------
|
||||
|
||||
if(T)
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
exploded_this_tick += T
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
exploded_this_tick += T
|
||||
|
||||
//--- THROW ITEMS AROUND ---
|
||||
|
||||
var/throw_dir = get_dir(epicenter,T)
|
||||
for(var/obj/item/I in T)
|
||||
if(I && !I.anchored)
|
||||
if(!I.anchored)
|
||||
var/throw_range = rand(throw_dist, max_range)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, I.throw_speed)
|
||||
I.throw_speed = EXPLOSION_THROW_SPEED //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, EXPLOSION_THROW_SPEED)
|
||||
|
||||
if(TICK_CHECK)
|
||||
//wait for the lists to repop
|
||||
var/break_condition
|
||||
if(reactionary)
|
||||
//If we've caught up to the density checker thread and there are no more turfs to process
|
||||
break_condition = iteration == expBlockLen && iteration < affTurfLen
|
||||
else
|
||||
//If we've caught up to the turf gathering thread and it's still running
|
||||
break_condition = iteration == affTurfLen && !stopped
|
||||
|
||||
if(break_condition || TICK_CHECK)
|
||||
stoplag()
|
||||
|
||||
if(!running)
|
||||
break
|
||||
|
||||
//update the trackers
|
||||
affTurfLen = affected_turfs.len
|
||||
expBlockLen = cached_exp_block.len
|
||||
|
||||
if(break_condition)
|
||||
if(reactionary)
|
||||
//until there are more block checked turfs than what we are currently at
|
||||
//or the explosion has stopped
|
||||
UNTIL(iteration < affTurfLen || !running)
|
||||
else
|
||||
//until there are more gathered turfs than what we are currently at
|
||||
//or there are no more turfs to gather/the explosion has stopped
|
||||
UNTIL(iteration < expBlockLen || stopped)
|
||||
|
||||
if(!running)
|
||||
break
|
||||
|
||||
//update the trackers
|
||||
affTurfLen = affected_turfs.len
|
||||
expBlockLen = cached_exp_block.len
|
||||
|
||||
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
|
||||
if(exploded_this_tick.len > circumference) //only do this every revolution
|
||||
for(var/Unexplode in exploded_this_tick)
|
||||
@@ -182,24 +243,67 @@
|
||||
UnexplodeT.explosion_level = 0
|
||||
exploded_this_tick.Cut()
|
||||
|
||||
var/took = (world.timeofday-start)/10
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
var/took = (REALTIMEOFDAY - started_at) / 10
|
||||
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
if(GLOB.Debug2)
|
||||
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
|
||||
|
||||
//Machines which report explosions.
|
||||
for(var/array in GLOB.doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(epicenter,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range)
|
||||
if(running) //if we aren't in a hurry
|
||||
//Machines which report explosions.
|
||||
for(var/array in GLOB.doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, took,orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
|
||||
return 1
|
||||
++stopped
|
||||
qdel(src)
|
||||
|
||||
#undef EX_PREPROCESS_EXIT_CHECK
|
||||
#undef EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//asyncly populate the affected_turfs list
|
||||
/datum/explosion/proc/GatherSpiralTurfs(range, turf/epicenter)
|
||||
set waitfor = FALSE
|
||||
. = list()
|
||||
spiral_range_turfs(range, epicenter, outlist = ., tick_checked = TRUE)
|
||||
++stopped
|
||||
|
||||
/proc/secondaryexplosion(turf/epicenter, range)
|
||||
for(var/turf/tile in spiral_range_turfs(range, epicenter))
|
||||
tile.ex_act(2)
|
||||
/datum/explosion/proc/CaculateExplosionBlock(list/affected_turfs)
|
||||
set waitfor = FALSE
|
||||
|
||||
. = list()
|
||||
var/processed = 0
|
||||
while(!stopped && running)
|
||||
var/I
|
||||
for(I in (processed + 1) to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = affected_turfs[I]
|
||||
var/current_exp_block = T.density ? T.explosion_block : 0
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density)
|
||||
current_exp_block += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
current_exp_block += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
current_exp_block += B.explosion_block
|
||||
|
||||
.[T] = current_exp_block
|
||||
|
||||
if(TICK_CHECK)
|
||||
break
|
||||
|
||||
processed = I
|
||||
stoplag()
|
||||
|
||||
/datum/explosion/Destroy()
|
||||
running = FALSE
|
||||
if(stopped < 2) //wait for main thread and spiral_range thread
|
||||
return QDEL_HINT_IWILLGC
|
||||
GLOB.explosions -= src
|
||||
return ..()
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
@@ -1,37 +1,44 @@
|
||||
/datum/getrev
|
||||
var/originmastercommit
|
||||
var/originmastercommit
|
||||
var/commit
|
||||
var/list/testmerge = list()
|
||||
var/has_pr_details = FALSE //example data in a testmerge entry when this is true: https://api.github.com/repositories/3234987/pulls/22586
|
||||
var/has_pr_details = FALSE //tgs2 support
|
||||
var/date
|
||||
|
||||
/datum/getrev/New()
|
||||
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
|
||||
if(fexists(SERVICE_PR_TEST_JSON))
|
||||
testmerge = json_decode(file2text(SERVICE_PR_TEST_JSON))
|
||||
else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
|
||||
var/list/tmp = world.file2list("..\\prtestjob.lk")
|
||||
for(var/I in tmp)
|
||||
if(I)
|
||||
testmerge |= I
|
||||
|
||||
|
||||
log_world("Running /tg/ revision:")
|
||||
var/list/logs = world.file2list(".git/logs/HEAD")
|
||||
if(logs)
|
||||
logs = splittext(logs[logs.len - 1], " ")
|
||||
date = unix2date(text2num(logs[5]))
|
||||
commit = logs[2]
|
||||
log_world("[date]")
|
||||
logs = world.file2list(".git/logs/refs/remotes/origin/master")
|
||||
if(logs)
|
||||
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
|
||||
|
||||
var/list/logs = world.file2list(".git/logs/HEAD")
|
||||
if(logs)
|
||||
logs = splittext(logs[logs.len - 1], " ")
|
||||
date = unix2date(text2num(logs[5]))
|
||||
commit = logs[2]
|
||||
log_world("[date]")
|
||||
logs = world.file2list(".git/logs/refs/remotes/origin/master")
|
||||
if(logs)
|
||||
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
|
||||
|
||||
if(testmerge.len)
|
||||
log_world(commit)
|
||||
for(var/line in testmerge)
|
||||
if(line)
|
||||
log_world("Test merge active of PR #[line]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]")
|
||||
log_world("Based off origin/master commit [originmastercommit]")
|
||||
if(world.RunningService())
|
||||
var/tmcommit = testmerge[line]["commit"]
|
||||
log_world("Test merge active of PR #[line] commit [tmcommit]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]")
|
||||
else //tgs2 support
|
||||
log_world("Test merge active of PR #[line]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]")
|
||||
log_world("Based off origin/master commit [originmastercommit]")
|
||||
else
|
||||
log_world(originmastercommit)
|
||||
log_world(originmastercommit)
|
||||
|
||||
/datum/getrev/proc/DownloadPRDetails()
|
||||
if(!config.githubrepoid)
|
||||
@@ -66,8 +73,11 @@
|
||||
return ""
|
||||
. = header ? "The following pull requests are currently test merged:<br>" : ""
|
||||
for(var/line in testmerge)
|
||||
var/details = ""
|
||||
if(has_pr_details)
|
||||
var/cm = testmerge[line]["commit"]
|
||||
var/details
|
||||
if(world.RunningService())
|
||||
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
|
||||
else if(has_pr_details) //tgs2 support
|
||||
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"])
|
||||
. += "<a href='[config.githuburl]/pull/[line]'>#[line][details]</a><br>"
|
||||
|
||||
@@ -76,14 +86,14 @@
|
||||
set name = "Show Server Revision"
|
||||
set desc = "Check the current server code revision"
|
||||
|
||||
if(GLOB.revdata.originmastercommit)
|
||||
if(GLOB.revdata.originmastercommit)
|
||||
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
|
||||
var/prefix = ""
|
||||
var/prefix = ""
|
||||
if(GLOB.revdata.testmerge.len)
|
||||
to_chat(src, GLOB.revdata.GetTestMergeInfo())
|
||||
prefix = "Based off origin/master commit: "
|
||||
var/pc = GLOB.revdata.originmastercommit
|
||||
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
prefix = "Based off origin/master commit: "
|
||||
var/pc = GLOB.revdata.originmastercommit
|
||||
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
else
|
||||
to_chat(src, "Revision unknown")
|
||||
to_chat(src, "<b>Current Infomational Settings:</b>")
|
||||
@@ -94,7 +104,7 @@
|
||||
to_chat(src, "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes")
|
||||
to_chat(src, "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes")
|
||||
if(config.show_game_type_odds)
|
||||
if(SSticker.IsRoundInProgress())
|
||||
if(SSticker.IsRoundInProgress())
|
||||
var/prob_sum = 0
|
||||
var/current_odds_differ = FALSE
|
||||
var/list/probs = list()
|
||||
@@ -110,13 +120,13 @@
|
||||
probs[ctag] = 1
|
||||
prob_sum += config.probabilities[ctag]
|
||||
if(current_odds_differ)
|
||||
to_chat(src, "<b>Game Mode Odds for current round:</b>")
|
||||
to_chat(src, "<b>Game Mode Odds for current round:</b>")
|
||||
for(var/ctag in probs)
|
||||
if(config.probabilities[ctag] > 0)
|
||||
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
|
||||
to_chat(src, "[ctag] [percentage]%")
|
||||
|
||||
to_chat(src, "<b>All Game Mode Odds:</b>")
|
||||
to_chat(src, "<b>All Game Mode Odds:</b>")
|
||||
var/sum = 0
|
||||
for(var/ctag in config.probabilities)
|
||||
sum += config.probabilities[ctag]
|
||||
|
||||
@@ -43,18 +43,18 @@
|
||||
|
||||
//cleans up ALL references :)
|
||||
/datum/holocall/Destroy()
|
||||
user.reset_perspective()
|
||||
if(user.client)
|
||||
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
|
||||
chunk.remove(eye)
|
||||
user.remote_control = null
|
||||
if(!QDELETED(user))
|
||||
user.reset_perspective()
|
||||
if(user.client)
|
||||
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
|
||||
chunk.remove(eye)
|
||||
user.remote_control = null
|
||||
user = null
|
||||
QDEL_NULL(eye)
|
||||
|
||||
user = null
|
||||
|
||||
if(hologram)
|
||||
hologram.HC = null
|
||||
hologram = null
|
||||
calling_holopad.outgoing_call = null
|
||||
hologram = null
|
||||
|
||||
for(var/I in dialed_holopads)
|
||||
var/obj/machinery/holopad/H = I
|
||||
@@ -62,6 +62,7 @@
|
||||
dialed_holopads.Cut()
|
||||
|
||||
if(calling_holopad)
|
||||
calling_holopad.outgoing_call = null
|
||||
calling_holopad.SetLightsAndPower()
|
||||
calling_holopad = null
|
||||
if(connected_holopad)
|
||||
@@ -86,7 +87,7 @@
|
||||
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
|
||||
testing("Holocall connection failure: graceful [graceful]")
|
||||
if(H == connected_holopad || H == calling_holopad)
|
||||
if(!graceful)
|
||||
if(!graceful && H != calling_holopad)
|
||||
calling_holopad.say("Connection failure.")
|
||||
qdel(src)
|
||||
return
|
||||
@@ -152,9 +153,7 @@
|
||||
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
|
||||
|
||||
if(.)
|
||||
if(connected_holopad)
|
||||
. = !QDELETED(connected_holopad) && connected_holopad.is_operational()
|
||||
else
|
||||
if(!connected_holopad)
|
||||
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
|
||||
if(!.)
|
||||
calling_holopad.say("No answer recieved.")
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
var/minetype = "lavaland"
|
||||
|
||||
var/list/transition_config = list(MAIN_STATION = CROSSLINKED,
|
||||
CENTCOMM = SELFLOOPING,
|
||||
var/list/transition_config = list(CENTCOMM = SELFLOOPING,
|
||||
MAIN_STATION = CROSSLINKED,
|
||||
EMPTY_AREA_1 = CROSSLINKED,
|
||||
EMPTY_AREA_2 = CROSSLINKED,
|
||||
MINING = SELFLOOPING,
|
||||
|
||||
@@ -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
|
||||
@@ -1288,7 +1289,6 @@
|
||||
else if (istype(M) && length(M.viruses))
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
D.cure(0)
|
||||
sleep(0) //because deleting of virus is done through spawn(0)
|
||||
if("infected")
|
||||
if (check_rights(R_ADMIN, 0))
|
||||
var/mob/living/carbon/human/H = current
|
||||
@@ -1447,7 +1447,7 @@
|
||||
special_role = "Wizard"
|
||||
assigned_role = "Wizard"
|
||||
if(!GLOB.wizardstart.len)
|
||||
current.loc = pick(GLOB.latejoin)
|
||||
SSjob.SendToLateJoin(current)
|
||||
to_chat(current, "HOT INSERTION, GO GO GO")
|
||||
else
|
||||
current.loc = pick(GLOB.wizardstart)
|
||||
|
||||
@@ -608,6 +608,23 @@ GLOBAL_LIST_EMPTY(mutations_list)
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/stoner
|
||||
name = "Stoner"
|
||||
quality = NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel...totally chill, man!</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel like you have a better sense of time.</span>"
|
||||
|
||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/common)
|
||||
|
||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/common)
|
||||
owner.remove_language(/datum/language/beachbum)
|
||||
|
||||
/datum/mutation/human/laser_eyes
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
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
|
||||
|
||||
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
|
||||
|
||||
/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 +74,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 +91,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
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
if(offsetdir == ridden_dir)
|
||||
var/list/diroffsets = offsets[offsetdir]
|
||||
buckled_mob.pixel_x = diroffsets[1]
|
||||
if(diroffsets.len == 2)
|
||||
if(diroffsets.len >= 2)
|
||||
buckled_mob.pixel_y = diroffsets[2]
|
||||
if(diroffsets.len == 3)
|
||||
buckled_mob.layer = diroffsets[3]
|
||||
@@ -164,7 +164,7 @@
|
||||
|
||||
|
||||
/datum/riding/janicart/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(-12, 7), "[EAST]" = list(0, 7), "[WEST]" = list( 12, 7))
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 7), "[EAST]" = list(-12, 7), "[WEST]" = list( 12, 7))
|
||||
|
||||
//scooter
|
||||
/datum/riding/scooter/handle_vehicle_layer()
|
||||
|
||||
@@ -241,10 +241,4 @@
|
||||
id = "miracle"
|
||||
suffix = "miracle.dmm"
|
||||
name = "Ordinary Space Tile"
|
||||
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
|
||||
|
||||
/datum/map_template/ruin/space/dragoon
|
||||
id = "dragoon"
|
||||
suffix = "dragoontomb.dmm"
|
||||
name = "Sky Bulge Tomb"
|
||||
description = "A tomb of a dice-loving dragoon in space. Turns out he got too good and jumped too high. Contains the Sky Bulge, which when thrown, warps the thrower."
|
||||
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
|
||||
@@ -1,15 +1,5 @@
|
||||
//Largely negative status effects go here, even if they have small benificial effects
|
||||
|
||||
/datum/status_effect/sigil_mark //allows the affected target to always trigger sigils while mindless
|
||||
id = "sigil_mark"
|
||||
duration = -1
|
||||
alert_type = null
|
||||
var/stat_allowed = DEAD //if owner's stat is below this, will remove itself
|
||||
|
||||
/datum/status_effect/sigil_mark/tick()
|
||||
if(owner.stat < stat_allowed)
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
|
||||
id = "his_wrath"
|
||||
duration = -1
|
||||
|
||||
18
code/datums/status_effects/neutral.dm
Normal file
18
code/datums/status_effects/neutral.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
//entirely neutral or internal status effects go here
|
||||
|
||||
/datum/status_effect/sigil_mark //allows the affected target to always trigger sigils while mindless
|
||||
id = "sigil_mark"
|
||||
duration = -1
|
||||
alert_type = null
|
||||
var/stat_allowed = DEAD //if owner's stat is below this, will remove itself
|
||||
|
||||
/datum/status_effect/sigil_mark/tick()
|
||||
if(owner.stat < stat_allowed)
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
|
||||
id = "crusher_damage"
|
||||
duration = -1
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
alert_type = null
|
||||
var/total_damage = 0
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user)
|
||||
if(user.z != 1)
|
||||
if(user.z != ZLEVEL_STATION)
|
||||
to_chat(user, "<span class='notice'>You should probably wait until you reach the station.</span>")
|
||||
return
|
||||
if(used)
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
/datum/gang_item/clothing/hands,
|
||||
/datum/gang_item/clothing/belt,
|
||||
|
||||
/datum/gang_item/weapon/shuriken,
|
||||
/datum/gang_item/weapon/shuriken,
|
||||
/datum/gang_item/weapon/switchblade,
|
||||
/datum/gang_item/weapon/improvised,
|
||||
/datum/gang_item/weapon/ammo/improvised_ammo,
|
||||
@@ -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
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
/datum/gang_item/clothing/hat
|
||||
name = "Pimp Hat"
|
||||
id = "hat"
|
||||
cost = 18
|
||||
cost = 16
|
||||
item_path = /obj/item/clothing/head/collectable/petehat/gang
|
||||
|
||||
/obj/item/clothing/head/collectable/petehat/gang
|
||||
@@ -121,7 +121,7 @@
|
||||
/datum/gang_item/clothing/mask
|
||||
name = "Golden Death Mask"
|
||||
id = "mask"
|
||||
cost = 20
|
||||
cost = 18
|
||||
item_path = /obj/item/clothing/mask/gskull
|
||||
|
||||
/obj/item/clothing/mask/gskull
|
||||
@@ -133,7 +133,7 @@
|
||||
/datum/gang_item/clothing/shoes
|
||||
name = "Bling Boots"
|
||||
id = "boots"
|
||||
cost = 25
|
||||
cost = 22
|
||||
item_path = /obj/item/clothing/shoes/gang
|
||||
|
||||
/obj/item/clothing/shoes/gang
|
||||
@@ -144,14 +144,14 @@
|
||||
/datum/gang_item/clothing/neck
|
||||
name = "Gold Necklace"
|
||||
id = "necklace"
|
||||
cost = 10
|
||||
cost = 9
|
||||
item_path = /obj/item/clothing/neck/necklace/dope
|
||||
|
||||
|
||||
/datum/gang_item/clothing/hands
|
||||
name = "Decorative Brass Knuckles"
|
||||
id = "hand"
|
||||
cost = 12
|
||||
cost = 11
|
||||
item_path = /obj/item/clothing/gloves/gang
|
||||
|
||||
/obj/item/clothing/gloves/gang
|
||||
@@ -163,7 +163,7 @@
|
||||
/datum/gang_item/clothing/belt
|
||||
name = "Badass Belt"
|
||||
id = "belt"
|
||||
cost = 15
|
||||
cost = 13
|
||||
item_path = /obj/item/weapon/storage/belt/military/gang
|
||||
|
||||
/obj/item/weapon/storage/belt/military/gang
|
||||
@@ -215,7 +215,6 @@
|
||||
name = "Sawn-Off Improvised Shotgun"
|
||||
id = "sawn"
|
||||
cost = 6
|
||||
item_path = /obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/sawn
|
||||
|
||||
/datum/gang_item/weapon/ammo/improvised_ammo
|
||||
name = "Box of Buckshot"
|
||||
@@ -236,16 +235,24 @@
|
||||
item_path = /obj/item/ammo_box/magazine/m10mm
|
||||
|
||||
/datum/gang_item/weapon/sniper
|
||||
name = ".50cal Sniper Rifle"
|
||||
name = "Black Market .50cal Sniper Rifle"
|
||||
id = "sniper"
|
||||
cost = 40
|
||||
item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle
|
||||
|
||||
/datum/gang_item/weapon/ammo/sniper_ammo
|
||||
name = "Standard .50cal Sniper Rounds"
|
||||
name = "Smuggled .50cal Sniper Rounds"
|
||||
id = "sniper_ammo"
|
||||
cost = 15
|
||||
item_path = /obj/item/ammo_box/magazine/sniper_rounds
|
||||
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang
|
||||
|
||||
|
||||
/datum/gang_item/weapon/ammo/sleeper_ammo
|
||||
name = "Illicit Tranquilizer Cartridges"
|
||||
id = "sniper_ammo"
|
||||
cost = 15
|
||||
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang/sleeper
|
||||
|
||||
|
||||
/datum/gang_item/weapon/machinegun
|
||||
name = "Mounted Machine Gun"
|
||||
@@ -326,6 +333,7 @@
|
||||
if(spawn_msg)
|
||||
to_chat(user, spawn_msg)
|
||||
|
||||
|
||||
/datum/gang_item/equipment/wetwork_boots
|
||||
name = "Wetwork boots"
|
||||
id = "wetwork"
|
||||
@@ -412,7 +420,7 @@
|
||||
/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
var/area/usrarea = get_area(user.loc)
|
||||
var/usrturf = get_turf(user.loc)
|
||||
if(initial(usrarea.name) == "Space" || isspaceturf(usrturf) || usr.z != 1)
|
||||
if(initial(usrarea.name) == "Space" || isspaceturf(usrturf) || usr.z != ZLEVEL_STATION)
|
||||
to_chat(user, "<span class='warning'>You can only use this on the station!</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -194,7 +197,7 @@
|
||||
return 0
|
||||
|
||||
var/turf/userturf = get_turf(user)
|
||||
if(userturf.z != 1) //Shuttle can only be recalled while on station
|
||||
if(userturf.z != ZLEVEL_STATION) //Shuttle can only be recalled while on station
|
||||
to_chat(user, "<span class='warning'>\icon[src]Error: Device out of range of station communication arrays.</span>")
|
||||
recalling = 0
|
||||
return 0
|
||||
@@ -212,7 +215,7 @@
|
||||
log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.")
|
||||
message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1)
|
||||
userturf = get_turf(user)
|
||||
if(userturf.z == 1) //Check one more time that they are on station.
|
||||
if(userturf.z == ZLEVEL_STATION) //Check one more time that they are on station.
|
||||
if(SSshuttle.cancelEvac(user))
|
||||
gang.recalls -= 1
|
||||
return 1
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs."
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!canUseTopic() || malf_cooldown)
|
||||
if(!canUseTopic() || malf_cooldown > world.time)
|
||||
return
|
||||
|
||||
for(var/I in GLOB.rcd_list)
|
||||
@@ -203,9 +203,7 @@
|
||||
RCD.detonate_pulse()
|
||||
|
||||
to_chat(src, "<span class='warning'>RCD detonation pulse emitted.</span>")
|
||||
malf_cooldown = TRUE
|
||||
sleep(100)
|
||||
malf_cooldown = FALSE
|
||||
malf_cooldown = world.time + 100
|
||||
|
||||
/datum/AI_Module/large/mecha_domination
|
||||
module_name = "Viral Mech Domination"
|
||||
@@ -446,7 +444,7 @@
|
||||
set name = "Reactivate Cameranet"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(!canUseTopic() || malf_cooldown)
|
||||
if(!canUseTopic() || malf_cooldown > world.time)
|
||||
return
|
||||
var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun.
|
||||
|
||||
@@ -469,9 +467,7 @@
|
||||
break
|
||||
to_chat(src, "<span class='notice'>Diagnostic complete! Operations completed: [fixedcams].</span>")
|
||||
|
||||
malf_cooldown = 1
|
||||
spawn(30) //Lag protection
|
||||
malf_cooldown = 0
|
||||
malf_cooldown = world.time + 30
|
||||
|
||||
/datum/AI_Module/large/upgrade_cameras
|
||||
module_name = "Upgrade Camera Network"
|
||||
|
||||
@@ -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
|
||||
@@ -211,13 +212,12 @@
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
|
||||
H.Sleeping(8)
|
||||
H.uncuff()
|
||||
if(console && console.pad && console.pad.teleport_target)
|
||||
H.forceMove(console.pad.teleport_target)
|
||||
H.uncuff()
|
||||
return
|
||||
//Area not chosen / It's not safe area - teleport to arrivals
|
||||
H.forceMove(pick(GLOB.latejoin))
|
||||
H.uncuff()
|
||||
SSjob.SendToLateJoin(H, FALSE)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -142,7 +142,8 @@
|
||||
return
|
||||
|
||||
//First we spawn a dude.
|
||||
var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
|
||||
var/mob/living/carbon/human/new_character = new//The mob being spawned.
|
||||
SSjob.SendToLateJoin(new_character)
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
new_character.dna.update_dna_identity()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -331,8 +331,8 @@
|
||||
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
|
||||
return
|
||||
else
|
||||
connected_message("Authorized Ejection")
|
||||
SPEAK("An authorized ejection of [clonemind.name] has occurred.")
|
||||
connected_message("Emergency Ejection")
|
||||
SPEAK("An emergency ejection of [clonemind.name] has occurred. Survival not guaranteed.")
|
||||
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
|
||||
go_out()
|
||||
else
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -134,12 +134,10 @@
|
||||
D["Cancel"] = "Cancel"
|
||||
for(var/obj/machinery/camera/C in L)
|
||||
if(!C.network)
|
||||
spawn(0)
|
||||
throw EXCEPTION("Camera in a cameranet has no camera network")
|
||||
stack_trace("Camera in a cameranet has no camera network")
|
||||
continue
|
||||
if(!(istype(C.network,/list)))
|
||||
spawn(0)
|
||||
throw EXCEPTION("Camera in a cameranet has a non-list camera network")
|
||||
stack_trace("Camera in a cameranet has a non-list camera network")
|
||||
continue
|
||||
var/list/tempnetwork = C.network&network
|
||||
if(tempnetwork.len)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
var/list/buffer[NUMBER_OF_BUFFERS]
|
||||
|
||||
var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
|
||||
var/injectorready = 0 //world timer cooldown var
|
||||
var/current_screen = "mainmenu"
|
||||
var/obj/machinery/dna_scannernew/connected = null
|
||||
var/obj/item/weapon/disk/data/diskette = null
|
||||
@@ -61,8 +61,7 @@
|
||||
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
|
||||
if(!isnull(connected))
|
||||
break
|
||||
spawn(250)
|
||||
injectorready = 1
|
||||
injectorready = world.time + INJECTOR_TIMEOUT
|
||||
return
|
||||
return
|
||||
|
||||
@@ -213,7 +212,7 @@
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UE]'>Occupant:Delayed</a> "
|
||||
if(injectorready)
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ue'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
@@ -227,7 +226,7 @@
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UI]'>Occupant:Delayed</a> "
|
||||
if(injectorready)
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ui'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
@@ -240,7 +239,7 @@
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_MIXED]'>Occupant:Delayed</a> "
|
||||
if(injectorready)
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>UI+UE Injector</span>"
|
||||
@@ -251,7 +250,7 @@
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span> "
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a> "
|
||||
if(injectorready)
|
||||
if(injectorready < world.time )
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=se'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
@@ -391,7 +390,7 @@
|
||||
if("mixed")
|
||||
apply_buffer(SCANNER_ACTION_MIXED,num)
|
||||
if("injector")
|
||||
if(num && injectorready)
|
||||
if(num && injectorready < world.time)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot))
|
||||
@@ -439,9 +438,7 @@
|
||||
if(connected)
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
if(I)
|
||||
injectorready = 0
|
||||
spawn(INJECTOR_TIMEOUT)
|
||||
injectorready = 1
|
||||
injectorready = world.time + INJECTOR_TIMEOUT
|
||||
if("loaddisk")
|
||||
if(num && diskette && diskette.fields)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
|
||||
@@ -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
|
||||
@@ -330,16 +333,14 @@
|
||||
/obj/machinery/door/airlock/proc/shock(mob/user, prb)
|
||||
if(!hasPower()) // unpowered, no shock
|
||||
return FALSE
|
||||
if(hasShocked)
|
||||
if(hasShocked > world.time)
|
||||
return FALSE //Already shocked someone recently?
|
||||
if(!prob(prb))
|
||||
return FALSE //you lucked out, no shock for you
|
||||
do_sparks(5, TRUE, src)
|
||||
var/tmp/check_range = TRUE
|
||||
if(electrocute_mob(user, get_area(src), src, 1, check_range))
|
||||
hasShocked = TRUE
|
||||
spawn(10)
|
||||
hasShocked = FALSE
|
||||
hasShocked = world.time + 10
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -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,19 +51,18 @@ 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
|
||||
|
||||
/obj/machinery/holopad/Destroy()
|
||||
if(outgoing_call)
|
||||
LAZYADD(holo_calls, outgoing_call)
|
||||
outgoing_call.ConnectionFailure(src)
|
||||
|
||||
for(var/I in holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
HC.ConnectionFailure(src)
|
||||
LAZYCLEARLIST(holo_calls)
|
||||
|
||||
for (var/I in masters)
|
||||
clear_holo(I)
|
||||
@@ -74,7 +73,14 @@ Possible to do for anyone motivated enough:
|
||||
if (powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= ~NOPOWER
|
||||
stat |= NOPOWER
|
||||
if(outgoing_call)
|
||||
outgoing_call.ConnectionFailure(src)
|
||||
|
||||
/obj/machinery/holopad/obj_break()
|
||||
. = ..()
|
||||
if(outgoing_call)
|
||||
outgoing_call.ConnectionFailure(src)
|
||||
|
||||
/obj/machinery/holopad/RefreshParts()
|
||||
var/holograph_range = 4
|
||||
@@ -112,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)
|
||||
|
||||
@@ -157,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
|
||||
@@ -392,4 +408,4 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
req_components = list(/obj/item/weapon/stock_parts/capacitor = 1)
|
||||
|
||||
#undef HOLOPAD_PASSIVE_POWER_USAGE
|
||||
#undef HOLOGRAM_POWER_USAGE
|
||||
#undef HOLOGRAM_POWER_USAGE
|
||||
|
||||
@@ -58,15 +58,11 @@
|
||||
var/p_dir = text2num(href_list["dir"])
|
||||
var/obj/item/pipe/P = new (src.loc, pipe_type=p_type, dir=p_dir)
|
||||
P.add_fingerprint(usr)
|
||||
wait = 1
|
||||
spawn(10)
|
||||
wait = 0
|
||||
wait = world.time + 10
|
||||
if(href_list["makemeter"])
|
||||
if(!wait)
|
||||
if(wait < world.time )
|
||||
new /obj/item/pipe_meter(src.loc)
|
||||
wait = 1
|
||||
spawn(15)
|
||||
wait = 0
|
||||
wait = world.time + 15
|
||||
return
|
||||
|
||||
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params)
|
||||
@@ -165,7 +161,7 @@ Nah
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["dmake"])
|
||||
if(!wait)
|
||||
if(wait < world.time)
|
||||
var/p_type = text2num(href_list["dmake"])
|
||||
var/obj/structure/disposalconstruct/C = new (src.loc,p_type)
|
||||
|
||||
@@ -176,9 +172,7 @@ Nah
|
||||
|
||||
C.add_fingerprint(usr)
|
||||
C.update_icon()
|
||||
wait = 1
|
||||
spawn(15)
|
||||
wait = 0
|
||||
wait = world.time + 15
|
||||
return
|
||||
|
||||
//transit tube dispenser
|
||||
@@ -216,7 +210,7 @@ Nah
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(!wait)
|
||||
if(wait < world.time)
|
||||
if(href_list["tube"])
|
||||
var/tube_type = text2num(href_list["tube"])
|
||||
var/obj/structure/C
|
||||
@@ -241,7 +235,5 @@ Nah
|
||||
C = new /obj/structure/c_transit_tube_pod(loc)
|
||||
if(C)
|
||||
C.add_fingerprint(usr)
|
||||
wait = 1
|
||||
spawn(15)
|
||||
wait = 0
|
||||
wait = world.time + 15
|
||||
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)
|
||||
|
||||
@@ -45,12 +45,14 @@
|
||||
// register for radio system
|
||||
|
||||
/obj/machinery/status_display/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
GLOB.ai_status_displays.Add(src)
|
||||
SSradio.add_object(src, frequency)
|
||||
|
||||
/obj/machinery/status_display/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
GLOB.ai_status_displays.Remove(src)
|
||||
return ..()
|
||||
|
||||
// timed process
|
||||
|
||||
@@ -68,8 +68,7 @@
|
||||
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [COORD(T)]")
|
||||
src = null
|
||||
spawn(rand(150,300))
|
||||
qdel(P)
|
||||
QDEL_IN(P, rand(150,300))
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
|
||||
/obj/effect/landmark/latejoin/Initialize(mapload)
|
||||
..()
|
||||
GLOB.latejoin += loc
|
||||
SSjob.latejoin_trackers += loc
|
||||
qdel(src)
|
||||
|
||||
// carp.
|
||||
|
||||
@@ -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
|
||||
@@ -127,8 +127,8 @@
|
||||
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
|
||||
|
||||
spawn(0)
|
||||
new /obj/effect/hallucination/delusion(victim.loc,victim,force_kind="demon",duration=duration,skip_nearby=0)
|
||||
|
||||
new /obj/effect/hallucination/delusion(victim.loc,victim,"demon",duration,0)
|
||||
|
||||
var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw.flags |= NODROP
|
||||
victim.drop_all_held_items()
|
||||
|
||||
@@ -169,7 +169,9 @@
|
||||
/obj/effect/temp_visual/fire
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
duration = 20
|
||||
light_range = 3
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
duration = 10
|
||||
|
||||
/obj/effect/temp_visual/revenant
|
||||
name = "spooky lights"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"Traitor", "Nuke Op", "Cultist", "Clockwork Cultist",
|
||||
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer",
|
||||
"Ash Walker", "Deathsquad Officer", "Ian", "Slaughter Demon",
|
||||
"Laughter Demon")
|
||||
"Laughter Demon", "Private Security Officer")
|
||||
var/pushed_over = FALSE //If the cutout is pushed over and has to be righted
|
||||
var/deceptive = FALSE //If the cutout actually appears as what it portray and not a discolored version
|
||||
|
||||
@@ -168,6 +168,11 @@
|
||||
desc = "A cardboard cutout of a laughter demon."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "bowmon"
|
||||
if("Private Security Officer")
|
||||
name = "Private Security Officer"
|
||||
desc = "A cardboard cutout of a private security officer."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "cutout_ntsec"
|
||||
return 1
|
||||
|
||||
/obj/item/cardboard_cutout/setDir(newdir)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
name = ""
|
||||
desc = ""
|
||||
density = 0
|
||||
var/can_move = 1
|
||||
var/can_move = 0
|
||||
var/obj/item/device/chameleon/master = null
|
||||
|
||||
/obj/effect/dummy/chameleon/proc/activate(mob/M, saved_appearance, obj/item/device/chameleon/C)
|
||||
@@ -126,19 +126,21 @@
|
||||
if(isspaceturf(loc) || !direction)
|
||||
return //No magical space movement!
|
||||
|
||||
if(can_move)
|
||||
can_move = 0
|
||||
if(can_move < world.time)
|
||||
var/amount
|
||||
switch(user.bodytemperature)
|
||||
if(300 to INFINITY)
|
||||
spawn(10) can_move = 1
|
||||
amount = 10
|
||||
if(295 to 300)
|
||||
spawn(13) can_move = 1
|
||||
amount = 13
|
||||
if(280 to 295)
|
||||
spawn(16) can_move = 1
|
||||
amount = 16
|
||||
if(260 to 280)
|
||||
spawn(20) can_move = 1
|
||||
amount = 20
|
||||
else
|
||||
spawn(25) can_move = 1
|
||||
amount = 25
|
||||
|
||||
can_move = world.time + amount
|
||||
step(src, direction)
|
||||
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)
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
"<span class='warning'>You bop [M] on the head!</span>")
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1)
|
||||
if(2)
|
||||
if(!scooldown)
|
||||
if(scooldown < world.time)
|
||||
if(M.health >= 0)
|
||||
if(ishuman(M)||ismonkey(M))
|
||||
M.electrocute_act(5, "[user]", safety = 1)
|
||||
@@ -128,11 +128,9 @@
|
||||
"<span class='danger'>You shock [M] to no effect.</span>")
|
||||
playsound(loc, 'sound/effects/sparks2.ogg', 50, 1, -1)
|
||||
user.cell.charge -= 500
|
||||
scooldown = TRUE
|
||||
spawn(20)
|
||||
scooldown = FALSE
|
||||
scooldown = world.time + 20
|
||||
if(3)
|
||||
if(!ccooldown)
|
||||
if(ccooldown < world.time)
|
||||
if(M.health >= 0)
|
||||
if(ishuman(M))
|
||||
user.visible_message("<span class='userdanger'>[user] crushes [M] in their grip!</span>", \
|
||||
@@ -143,9 +141,7 @@
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1, -1)
|
||||
M.adjustBruteLoss(15)
|
||||
user.cell.charge -= 300
|
||||
ccooldown = TRUE
|
||||
spawn(10)
|
||||
ccooldown = FALSE
|
||||
ccooldown = world.time + 10
|
||||
|
||||
/obj/item/borg/cyborghug/peacekeeper
|
||||
shockallowed = TRUE
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
origin_tech = "bluespace=6;materials=3"
|
||||
materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT)
|
||||
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
|
||||
novariants = TRUE
|
||||
var/crystal_type = /obj/item/weapon/ore/bluespace_crystal/refined
|
||||
|
||||
/obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user