diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 82633fdc70..f67f095a4f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,3 @@
-[Feature Freeze!]: # We are currently not considering any balance or antagonist oriented pull requests. Full details, as well as ways to bypass this freeze, are available here https://github.com/tgstation/tgstation/pull/28223
-
-
[Changelogs]: # (Please make a changelog if you're adding, removing or changing content that'll affect players. This includes, but is not limited to, new features, sprites, sounds; balance changes; map edits and important fixes)
[]: # (See here for how to easily make a changelog: https://github.com/tgstation/tgstation/wiki/Changelogs. An example changelog has been provided below. Please edit or remove)
diff --git a/SQL/database_changelog.txt.rej b/SQL/database_changelog.txt.rej
new file mode 100644
index 0000000000..1b201ec4aa
--- /dev/null
+++ b/SQL/database_changelog.txt.rej
@@ -0,0 +1,15 @@
+diff a/SQL/database_changelog.txt b/SQL/database_changelog.txt (rejected hunks)
+@@ -1,10 +1,10 @@
+ Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255.
+
+-The latest database version is 3.1; The query to update the schema revision table is:
++The latest database version is 3.0; The query to update the schema revision table is:
+
+-UPDATE `schema_revision` SET major = 3, minor = 1 LIMIT 1;
++INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0);
+ or
+-UPDATE `SS13_schema_revision` SET major = 3, minor = 1 LIMIT 1;
++INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0);
+
+ ----------------------------------------------------
+
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 4cc0b5c158..b4b78673a1 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -49675,7 +49675,7 @@
/turf/open/floor/plating,
/area/maintenance/department/engine)
"cdF" = (
-/obj/structure/closet/secure_closet/miner,
+/obj/structure/closet/secure_closet/miner/unlocked,
/turf/open/floor/plating,
/area/shuttle/auxillary_base)
"cdG" = (
diff --git a/apc_repair.dmi b/apc_repair.dmi
new file mode 100644
index 0000000000..6e861eef61
Binary files /dev/null and b/apc_repair.dmi differ
diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm
index 82d030bf08..24e10a24d1 100644
--- a/code/__DEFINES/logging.dm
+++ b/code/__DEFINES/logging.dm
@@ -1,15 +1,16 @@
//Investigate logging defines
-#define INVESTIGATE_ATMOS "atmos"
-#define INVESTIGATE_BOTANY "botany"
-#define INVESTIGATE_CARGO "cargo"
-#define INVESTIGATE_EXPERIMENTOR "experimentor"
-#define INVESTIGATE_GRAVITY "gravity"
-#define INVESTIGATE_RECORDS "records"
-#define INVESTIGATE_SINGULO "singulo"
-#define INVESTIGATE_SUPERMATTER "supermatter"
-#define INVESTIGATE_TELESCI "telesci"
-#define INVESTIGATE_WIRES "wires"
+#define INVESTIGATE_ATMOS "atmos"
+#define INVESTIGATE_BOTANY "botany"
+#define INVESTIGATE_CARGO "cargo"
+#define INVESTIGATE_EXPERIMENTOR "experimentor"
+#define INVESTIGATE_GRAVITY "gravity"
+#define INVESTIGATE_RECORDS "records"
+#define INVESTIGATE_SINGULO "singulo"
+#define INVESTIGATE_SUPERMATTER "supermatter"
+#define INVESTIGATE_TELESCI "telesci"
+#define INVESTIGATE_WIRES "wires"
#define INVESTIGATE_PORTAL "portals"
+#define INVESTIGATE_HALLUCINATIONS "hallucinations"
//Individual logging defines
#define INDIVIDUAL_ATTACK_LOG "Attack log"
diff --git a/code/__DEFINES/logging.dm.rej b/code/__DEFINES/logging.dm.rej
new file mode 100644
index 0000000000..6a7a358a9c
--- /dev/null
+++ b/code/__DEFINES/logging.dm.rej
@@ -0,0 +1,9 @@
+diff a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm (rejected hunks)
+@@ -9,6 +9,7 @@
+ #define INVESTIGATE_SUPERMATTER "supermatter"
+ #define INVESTIGATE_TELESCI "telesci"
+ #define INVESTIGATE_WIRES "wires"
++#define INVESTIGATE_HALLUCINATIONS "hallucinations"
+
+ //Individual logging defines
+ #define INDIVIDUAL_ATTACK_LOG "Attack log"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index d6299ba42c..4342766be7 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -8,7 +8,7 @@
//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
+ to_chat(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 .....
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 9c64fb8b74..9646f03252 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -320,7 +320,7 @@
return r
// Returns the key based on the index
-#define KEYBYINDEX(L, index) (((index <= L:len) && (index > 0)) ? L[index] : null)
+#define KEYBYINDEX(L, index) (((index <= length(L)) && (index > 0)) ? L[index] : null)
/proc/count_by_type(list/L, type)
var/i = 0
@@ -468,7 +468,7 @@
. |= key_list[key]
//Picks from the list, with some safeties, and returns the "default" arg if it fails
-#define DEFAULTPICK(L, default) ((islist(L) && L:len) ? pick(L) : default)
+#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
#define LAZYINITLIST(L) if (!L) L = list()
#define UNSETEMPTY(L) if (L && !L.len) L = null
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 2dd2e42129..05b6aa1a15 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -1,3 +1,10 @@
+//wrapper macros for easier grepping
+#define DIRECT_OUTPUT(A, B) A << B
+#define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image)
+#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound)
+#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
+#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
+
//print a warning message to world.log
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
/proc/warning(msg)
@@ -20,13 +27,13 @@
/proc/log_admin(text)
GLOB.admin_log.Add(text)
if (config.log_admin)
- GLOB.world_game_log << "\[[time_stamp()]]ADMIN: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text]")
//Items using this proc are stripped from public logs - use with caution
/proc/log_admin_private(text)
GLOB.admin_log.Add(text)
if (config.log_admin)
- GLOB.world_game_log << "\[[time_stamp()]]ADMINPRIVATE: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMINPRIVATE: [text]")
/proc/log_adminsay(text)
if (config.log_adminchat)
@@ -38,65 +45,65 @@
/proc/log_game(text)
if (config.log_game)
- GLOB.world_game_log << "\[[time_stamp()]]GAME: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text]")
/proc/log_vote(text)
if (config.log_vote)
- GLOB.world_game_log << "\[[time_stamp()]]VOTE: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text]")
/proc/log_access(text)
if (config.log_access)
- GLOB.world_game_log << "\[[time_stamp()]]ACCESS: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ACCESS: [text]")
/proc/log_say(text)
if (config.log_say)
- GLOB.world_game_log << "\[[time_stamp()]]SAY: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SAY: [text]")
/proc/log_prayer(text)
if (config.log_prayer)
- GLOB.world_game_log << "\[[time_stamp()]]PRAY: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PRAY: [text]")
/proc/log_law(text)
if (config.log_law)
- GLOB.world_game_log << "\[[time_stamp()]]LAW: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LAW: [text]")
/proc/log_ooc(text)
if (config.log_ooc)
- GLOB.world_game_log << "\[[time_stamp()]]OOC: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]OOC: [text]")
/proc/log_whisper(text)
if (config.log_whisper)
- GLOB.world_game_log << "\[[time_stamp()]]WHISPER: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [text]")
/proc/log_emote(text)
if (config.log_emote)
- GLOB.world_game_log << "\[[time_stamp()]]EMOTE: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [text]")
/proc/log_attack(text)
if (config.log_attack)
- GLOB.world_attack_log << "\[[time_stamp()]]ATTACK: [text]"
+ WRITE_FILE(GLOB.world_attack_log, "\[[time_stamp()]]ATTACK: [text]")
/proc/log_pda(text)
if (config.log_pda)
- GLOB.world_game_log << "\[[time_stamp()]]PDA: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PDA: [text]")
/proc/log_comment(text)
if (config.log_pda)
//reusing the PDA option because I really don't think news comments are worth a config option
- GLOB.world_game_log << "\[[time_stamp()]]COMMENT: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]COMMENT: [text]")
/proc/log_chat(text)
if (config.log_pda)
- GLOB.world_game_log << "\[[time_stamp()]]CHAT: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]")
/proc/log_sql(text)
if(config.sql_enabled)
- GLOB.world_game_log << "\[[time_stamp()]]SQL: [text]"
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SQL: [text]")
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
- GLOB.world_runtime_log << text
- world.log << text
+ WRITE_FILE(GLOB.world_runtime_log, text)
+ SEND_TEXT(world.log, text)
// Helper procs for building detailed log lines
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index d150e86f45..9b1507771a 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -418,7 +418,7 @@
/proc/showCandidatePollWindow(mob/M, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE)
set waitfor = 0
- M << 'sound/misc/notice2.ogg' //Alerting them to their consideration
+ SEND_SOUND(M, 'sound/misc/notice2.ogg') //Alerting them to their consideration
if(flashwindow)
window_flash(M.client)
switch(ignore_category ? askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
@@ -426,7 +426,7 @@
to_chat(M, "Choice registered: Yes.")
if(time_passed + poll_time <= world.time)
to_chat(M, "Sorry, you answered too late to be considered!")
- M << 'sound/machines/buzz-sigh.ogg'
+ SEND_SOUND(M, 'sound/machines/buzz-sigh.ogg')
candidates -= M
else
candidates += M
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 855675a29f..b245b1f146 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -712,7 +712,8 @@ The _flatIcons list is a cache for generated icon files.
if(!current)
curIndex++ //Try the next layer
continue
- currentLayer = current:layer
+ var/image/I = current
+ currentLayer = I.layer
if(currentLayer<0) // Special case for FLY_LAYER
if(currentLayer <= -1000) return flat
if(pSet == 0) // Underlay
@@ -747,22 +748,22 @@ The _flatIcons list is a cache for generated icon files.
// Dimensions of overlay being added
var/{addX1;addX2;addY1;addY2}
- for(var/I in layers)
-
- if(I:alpha == 0)
+ for(var/V in layers)
+ var/image/I = V
+ if(I.alpha == 0)
continue
if(I == copy) // 'I' is an /image based on the object being flattened.
curblend = BLEND_OVERLAY
- add = icon(I:icon, I:icon_state, I:dir)
+ add = icon(I.icon, I.icon_state, I.dir)
else // 'I' is an appearance object.
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
// Find the new dimensions of the flat icon to fit the added overlay
- addX1 = min(flatX1, I:pixel_x+1)
- addX2 = max(flatX2, I:pixel_x+add.Width())
- addY1 = min(flatY1, I:pixel_y+1)
- addY2 = max(flatY2, I:pixel_y+add.Height())
+ addX1 = min(flatX1, I.pixel_x+1)
+ addX2 = max(flatX2, I.pixel_x+add.Width())
+ addY1 = min(flatY1, I.pixel_y+1)
+ addY2 = max(flatY2, I.pixel_y+add.Height())
if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2)
// Resize the flattened icon so the new icon fits
@@ -771,7 +772,7 @@ The _flatIcons list is a cache for generated icon files.
flatY1=addY1;flatY2=addY2
// Blend the overlay into the flattened icon
- flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
+ flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
if(A.color)
flat.Blend(A.color, ICON_MULTIPLY)
@@ -782,10 +783,11 @@ The _flatIcons list is a cache for generated icon files.
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
- for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it.
- if(I:layer>A.layer)
+ for(var/V in A.overlays)//For every image in overlays. var/image/I will not work, don't try it.
+ var/image/I = V
+ if(I.layer>A.layer)
continue//If layer is greater than what we need, skip it.
- var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects.
+ var/icon/image_overlay = new(I.icon,I.icon_state)//Blend only works with icon objects.
//Also, icons cannot directly set icon_state. Slower than changing variables but whatever.
alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay.
return alpha_mask//And now return the mask.
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 924f8daf08..cb64f3fb22 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -1,6 +1,3 @@
-//wrapper macro for sending images that makes grepping easy
-#define SEND_IMAGE(target, image) target << image
-
/proc/random_blood_type()
return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index 70bb8b2db6..a617437ac3 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -24,11 +24,12 @@
announcement += "
[html_encode(text)]
"
announcement += "
"
+ var/s = sound(sound)
for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && M.can_hear())
to_chat(M, announcement)
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
- M << sound(sound)
+ SEND_SOUND(M, s)
/proc/print_command_report(text = "", title = null, announce=TRUE)
if(!title)
@@ -55,6 +56,6 @@
to_chat(M, "[title]
[message]
")
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
if(alert)
- M << sound('sound/misc/notice1.ogg')
+ SEND_SOUND(M, sound('sound/misc/notice1.ogg'))
else
- M << sound('sound/misc/notice2.ogg')
+ SEND_SOUND(M, sound('sound/misc/notice2.ogg'))
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index ef89caa490..53691d122e 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -556,7 +556,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
var/list/tosend = list()
tosend["data"] = finalized
- log << json_encode(tosend)
+ WRITE_FILE(log, json_encode(tosend))
//Used for applying byonds text macros to strings that are loaded at runtime
/proc/apply_text_macros(string)
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index c32c481291..abf2c1f937 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -275,7 +275,7 @@
if(M.config_tag)
if(!(M.config_tag in modes)) // ensure each mode is added only once
- GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration."
+ WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.")
modes += M.config_tag
mode_names[M.config_tag] = M.name
probabilities[M.config_tag] = M.probability
@@ -548,7 +548,7 @@
if("irc_announce_new_game")
irc_announce_new_game = TRUE
else
- GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
+ WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
else if(type == "game_options")
switch(name)
@@ -611,13 +611,13 @@
if(mode_name in modes)
continuous[mode_name] = 1
else
- GLOB.config_error_log << "Unknown continuous configuration definition: [mode_name]."
+ WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].")
if("midround_antag")
var/mode_name = lowertext(value)
if(mode_name in modes)
midround_antag[mode_name] = 1
else
- GLOB.config_error_log << "Unknown midround antagonist configuration definition: [mode_name]."
+ WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].")
if("midround_antag_time_check")
midround_antag_time_check = text2num(value)
if("midround_antag_life_check")
@@ -633,9 +633,9 @@
if(mode_name in modes)
min_pop[mode_name] = text2num(mode_value)
else
- GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]."
+ WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].")
else
- GLOB.config_error_log << "Incorrect minimum population configuration definition: [mode_name] [mode_value]."
+ WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].")
if("max_pop")
var/pop_pos = findtext(value, " ")
var/mode_name = null
@@ -647,9 +647,9 @@
if(mode_name in modes)
max_pop[mode_name] = text2num(mode_value)
else
- GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]."
+ WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].")
else
- GLOB.config_error_log << "Incorrect maximum population configuration definition: [mode_name] [mode_value]."
+ WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].")
if("shuttle_refuel_delay")
shuttle_refuel_delay = text2num(value)
if("show_game_type_odds")
@@ -677,9 +677,9 @@
if(prob_name in modes)
probabilities[prob_name] = text2num(prob_value)
else
- GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]."
+ WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].")
else
- GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_value]."
+ WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].")
if("protect_roles_from_antagonist")
protect_roles_from_antagonist = 1
@@ -726,7 +726,7 @@
// Value is in the form "LAWID,NUMBER"
var/list/L = splittext(value, ",")
if(L.len != 2)
- GLOB.config_error_log << "Invalid LAW_WEIGHT: " + t
+ WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t)
continue
var/lawid = L[1]
var/weight = text2num(L[2])
@@ -781,7 +781,7 @@
if("mice_roundstart")
mice_roundstart = text2num(value)
else
- GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
+ WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
else if(type == "policies")
policies[name] = value
@@ -839,7 +839,7 @@
if ("disabled")
currentmap = null
else
- GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
+ WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'")
/datum/configuration/proc/loadsql(filename)
@@ -883,7 +883,7 @@
if("feedback_tableprefix")
global.sqlfdbktableprefix = value
else
- GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
+ WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
/datum/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm
index afa77b0207..3344afcaaa 100644
--- a/code/controllers/subsystem/blackbox.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -250,7 +250,7 @@ SUBSYSTEM_DEF(blackbox)
return 0
return value
-/datum/feedback_variable/proc/get_variable()
+/datum/feedback_variable/proc/get_variable()
return variable
/datum/feedback_variable/proc/set_details(text)
@@ -260,12 +260,12 @@ SUBSYSTEM_DEF(blackbox)
/datum/feedback_variable/proc/add_details(text)
if (istext(text))
if (!details)
- details = text
+ details = "\"[text]\""
else
- details += " [text]"
+ details += " | \"[text]\""
-/datum/feedback_variable/proc/get_details()
+/datum/feedback_variable/proc/get_details()
return details
/datum/feedback_variable/proc/get_parsed()
- return list(variable,value,details)
+ return list(variable,value,details)
\ No newline at end of file
diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm
index e5e83c85fc..2a1a04e21d 100644
--- a/code/controllers/subsystem/pai.dm
+++ b/code/controllers/subsystem/pai.dm
@@ -149,7 +149,6 @@ SUBSYSTEM_DEF(pai)
continue
if(!(ROLE_PAI in G.client.prefs.be_special))
continue
- //G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
to_chat(G, "[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.")
addtimer(CALLBACK(src, .proc/spam_again), spam_delay)
var/list/available = list()
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index f4eebe95be..a0dc7c526d 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -49,7 +49,7 @@ SUBSYSTEM_DEF(persistence)
satchel_string = pick_n_take(expanded_old_satchels)
old_secret_satchels = jointext(expanded_old_satchels,"#")
- secret_satchels[SSmapping.config.map_name] << old_secret_satchels
+ WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
var/list/chosen_satchel = splittext(satchel_string,"|")
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(persistence)
if(isemptylist(savable_obj))
continue
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
- secret_satchels[SSmapping.config.map_name] << old_secret_satchels
+ WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
@@ -181,14 +181,14 @@ SUBSYSTEM_DEF(persistence)
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
- chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
+ WRITE_FILE(chisel_messages_sav[SSmapping.config.map_name], json_encode(saved_messages))
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
saved_messages += list(M.pack()) // dm eats one list
/datum/controller/subsystem/persistence/proc/CollectTrophies()
- trophy_sav << json_encode(saved_trophies)
+ WRITE_FILE(trophy_sav, json_encode(saved_trophies))
/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
if(!T.added_roundstart && T.showpiece)
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 8aff552076..d88d788d37 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -101,8 +101,6 @@ SUBSYSTEM_DEF(shuttle)
T.color = "#00ffff"
#endif
- //world.log << "[transit_turfs.len] transit turfs registered"
-
/datum/controller/subsystem/shuttle/fire()
for(var/thing in mobile)
if(!thing)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index d897b290d4..c7c50f4d04 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -225,7 +225,7 @@ SUBSYSTEM_DEF(ticker)
round_start_time = world.time
to_chat(world, "Welcome to [station_name()], enjoy your stay!")
- world << sound('sound/ai/welcome.ogg')
+ SEND_SOUND(world, sound('sound/ai/welcome.ogg'))
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)
@@ -300,7 +300,7 @@ SUBSYSTEM_DEF(ticker)
if("nuclear emergency") //Nuke wasn't on station when it blew up
flick("intro_nuke",cinematic)
sleep(35)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb)
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
@@ -308,12 +308,12 @@ SUBSYSTEM_DEF(ticker)
cinematic.icon_state = null
flick("intro_cult",cinematic)
sleep(25)
- world << sound('sound/magic/enter_blood.ogg')
+ SEND_SOUND(world, sound('sound/magic/enter_blood.ogg'))
sleep(28)
- world << sound('sound/machines/terminal_off.ogg')
+ SEND_SOUND(world, sound('sound/machines/terminal_off.ogg'))
sleep(20)
flick("station_corrupted",cinematic)
- world << sound('sound/effects/ghost.ogg')
+ SEND_SOUND(world, sound('sound/effects/ghost.ogg'))
actually_blew_up = FALSE
if("gang war") //Gang Domination (just show the override screen)
cinematic.icon_state = "intro_malf_still"
@@ -323,19 +323,19 @@ SUBSYSTEM_DEF(ticker)
if("fake") //The round isn't over, we're just freaking people out for fun
flick("intro_nuke",cinematic)
sleep(35)
- world << sound('sound/items/bikehorn.ogg')
+ SEND_SOUND(world, sound('sound/items/bikehorn.ogg'))
flick("summary_selfdes",cinematic)
actually_blew_up = FALSE
else
flick("intro_nuke",cinematic)
sleep(35)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb)
if(NUKE_MISS_STATION || NUKE_SYNDICATE_BASE) //nuke was nowhere nearby //TODO: a really distant explosion animation
sleep(50)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb)
actually_blew_up = station_missed == NUKE_SYNDICATE_BASE //don't kill everyone on station if it detonated off station
else //station was destroyed
@@ -346,42 +346,42 @@ SUBSYSTEM_DEF(ticker)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb)
cinematic.icon_state = "summary_nukewin"
if("AI malfunction") //Malf (screen,explosion,summary)
flick("intro_malf",cinematic)
sleep(76)
flick("station_explode_fade_red",cinematic)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb) //TODO: If we ever decide to actually detonate the vault bomb
cinematic.icon_state = "summary_malf"
if("blob") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_selfdes"
if("cult") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_cult"
if("no_core") //Nuke failed to detonate as it had no core
flick("intro_nuke",cinematic)
sleep(35)
flick("station_intact",cinematic)
- world << sound('sound/ambience/signal.ogg')
+ SEND_SOUND(world, sound('sound/ambience/signal.ogg'))
addtimer(CALLBACK(src, .proc/finish_cinematic, null, FALSE), 100)
return //Faster exit, since nothing happened
else //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red", cinematic)
- world << sound('sound/effects/explosionfar.ogg')
+ SEND_SOUND(world, sound('sound/effects/explosionfar.ogg'))
station_explosion_detonation(bomb)
cinematic.icon_state = "summary_selfdes"
//If its actually the end of the round, wait for it to end.
@@ -636,7 +636,7 @@ SUBSYSTEM_DEF(ticker)
if(living_player_count() < config.hard_popcap)
if(next_in_line && next_in_line.client)
to_chat(next_in_line, "A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<")
- next_in_line << sound('sound/misc/notice1.ogg')
+ SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg'))
next_in_line.LateChoices()
return
queued_players -= next_in_line //Client disconnected, remove he
@@ -804,7 +804,7 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
var/F = file("data/mode.txt")
fdel(F)
- F << the_mode
+ WRITE_FILE(F, the_mode)
/datum/controller/subsystem/ticker/proc/SetRoundEndSound(the_sound)
set waitfor = FALSE
@@ -858,4 +858,4 @@ SUBSYSTEM_DEF(ticker)
'sound/roundend/disappointed.ogg'\
)
- world << sound(round_end_sound)
+ SEND_SOUND(world, sound(round_end_sound))
diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm
index 6c5466d8d9..a0bcb5feec 100644
--- a/code/controllers/subsystem/title.dm
+++ b/code/controllers/subsystem/title.dm
@@ -53,7 +53,7 @@ SUBSYSTEM_DEF(title)
/datum/controller/subsystem/title/Shutdown()
if(file_path)
var/F = file("data/previous_title.dat")
- F << file_path
+ WRITE_FILE(F, file_path)
for(var/thing in GLOB.clients)
if(!thing)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 16fbeb8462..ecaa70387b 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -169,7 +169,7 @@
/datum/action/item_action/toggle_firemode
name = "Toggle Firemode"
-
+
/datum/action/item_action/rcl
name = "Change Cable Color"
button_icon_state = "rcl_rainbow"
@@ -490,7 +490,8 @@
var/obj/effect/proc_holder/spell/S = target
S.action = src
name = S.name
- icon_icon = S.action_icon
+ desc = S.desc
+ button_icon = S.action_icon
button_icon_state = S.action_icon_state
background_icon_state = S.action_background_icon_state
button.name = name
diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm
index c8f00d1995..077fb94e52 100644
--- a/code/datums/antagonists/devil.dm
+++ b/code/datums/antagonists/devil.dm
@@ -280,7 +280,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
if(!D)
return
to_chat(world, "\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"")
- world << 'sound/hallucinations/veryfar_noise.ogg'
+ SEND_SOUND(world, sound('sound/hallucinations/veryfar_noise.ogg'))
give_appropriate_spells()
D.convert_to_archdevil()
if(istype(D.loc, /obj/effect/dummy/slaughter/))
diff --git a/code/datums/antagonists/ninja.dm b/code/datums/antagonists/ninja.dm
index 6948740687..4efb17f154 100644
--- a/code/datums/antagonists/ninja.dm
+++ b/code/datums/antagonists/ninja.dm
@@ -141,7 +141,7 @@
/datum/antagonist/ninja/greet()
- owner.current << sound('sound/effects/ninja_greeting.ogg')
+ SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!")
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index e519cf6af3..87c6ad7334 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -929,6 +929,26 @@
manipulate_organs(C)
href_list["datumrefresh"] = href_list["editorgans"]
+ else if(href_list["hallucinate"])
+ if(!check_rights(0))
+ return
+
+ var/mob/living/carbon/C = locate(href_list["hallucinate"]) in GLOB.mob_list
+ if(!istype(C))
+ to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
+ return
+
+ var/list/hallucinations = subtypesof(/datum/hallucination)
+ var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations
+ if(!usr)
+ return
+ if(QDELETED(C))
+ to_chat(usr, "Mob doesn't exist anymore")
+ return
+
+ if(result)
+ new result(C, TRUE)
+
else if(href_list["makehuman"])
if(!check_rights(R_SPAWN))
return
diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm
index f913d49573..9bfd5b0baf 100644
--- a/code/datums/diseases/advance/symptoms/hallucigen.dm
+++ b/code/datums/diseases/advance/symptoms/hallucigen.dm
@@ -59,4 +59,4 @@ Bonus
else
if(prob(base_message_chance))
to_chat(M, "[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]")
- M.hallucination += (15 * power)
+ M.hallucination += (45 * power)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 7017149d53..d943e417e5 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -805,11 +805,11 @@
possible_targets += possible_target.current
var/mob/def_target = null
- var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain, /datum/objective/maroon)
- if (objective&&(objective.type in objective_list) && objective:target)
- def_target = objective:target.current
+ var/list/objective_list = typecacheof(list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain, /datum/objective/maroon))
+ if (is_type_in_typecache(objective, objective_list) && objective.target)
+ def_target = objective.target.current
- var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
+ var/mob/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
if (!new_target)
return
@@ -817,12 +817,12 @@
if (new_target == "Free objective")
new_objective = new objective_path
new_objective.owner = src
- new_objective:target = null
+ new_objective.target = null
new_objective.explanation_text = "Free objective"
else
new_objective = new objective_path
new_objective.owner = src
- new_objective:target = new_target:mind
+ new_objective.target = new_target.mind
//Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
new_objective.update_explanation_text()
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 485ca00515..c15ede7b3e 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -37,7 +37,7 @@
icon_state = "shadow_mend"
/datum/status_effect/void_price/tick()
- owner << sound('sound/magic/summon_karp.ogg', volume = 25)
+ SEND_SOUND(owner, sound('sound/magic/summon_karp.ogg', volume = 25))
owner.adjustBruteLoss(3)
@@ -247,7 +247,7 @@
for(var/datum/mind/B in SSticker.mode.cult)
if(isliving(B.current))
var/mob/living/M = B.current
- M << 'sound/hallucinations/veryfar_noise.ogg'
+ SEND_SOUND(M, sound('sound/hallucinations/veryfar_noise.ogg'))
to_chat(M, "The Cult's Master, [owner], has fallen in \the [A]!")
/datum/status_effect/cult_master/tick()
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
index 7b43bf6396..f4f2fc089c 100644
--- a/code/datums/weather/weather.dm
+++ b/code/datums/weather/weather.dm
@@ -69,7 +69,7 @@
if(telegraph_message)
to_chat(M, telegraph_message)
if(telegraph_sound)
- M << sound(telegraph_sound)
+ SEND_SOUND(M, sound(telegraph_sound))
addtimer(CALLBACK(src, .proc/start), telegraph_duration)
/datum/weather/proc/start()
@@ -83,7 +83,7 @@
if(weather_message)
to_chat(M, weather_message)
if(weather_sound)
- M << sound(weather_sound)
+ SEND_SOUND(M, sound(weather_sound))
START_PROCESSING(SSweather, src)
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
@@ -98,7 +98,7 @@
if(end_message)
to_chat(M, end_message)
if(end_sound)
- M << sound(end_sound)
+ SEND_SOUND(M, sound(end_sound))
STOP_PROCESSING(SSweather, src)
addtimer(CALLBACK(src, .proc/end), end_duration)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 1b8d25aa51..218cb59f41 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -439,7 +439,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
// Ambience goes down here -- make sure to list each area separately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(L.client && !L.client.ambience_playing && L.client.prefs.toggles & SOUND_SHIP_AMBIENCE)
L.client.ambience_playing = 1
- L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ)
+ SEND_SOUND(L, sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ))
if(!(L.client && (L.client.prefs.toggles & SOUND_AMBIENCE)))
return //General ambience check is below the ship ambience so one can play without the other
@@ -448,7 +448,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
var/sound = pick(ambientsounds)
if(!L.client.played)
- L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)
+ SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE))
L.client.played = 1
sleep(600) //ewww - this is very very bad
if(L.&& L.client)
diff --git a/code/game/area/areas.dm.rej b/code/game/area/areas.dm.rej
new file mode 100644
index 0000000000..3c097d1229
--- /dev/null
+++ b/code/game/area/areas.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/area/areas.dm b/code/game/area/areas.dm (rejected hunks)
+@@ -432,7 +432,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
+ // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
+ if(L.client && !L.client.ambience_playing && L.client.prefs.toggles & SOUND_SHIP_AMBIENCE)
+ L.client.ambience_playing = 1
+- L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ)
++ SEND_SOUND(L, sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ))
+
+ if(!(L.client && (L.client.prefs.toggles & SOUND_AMBIENCE)))
+ return //General ambience check is below the ship ambience so one can play without the other
diff --git a/code/game/communications.dm b/code/game/communications.dm
index 66bb91ef59..19c3f87460 100644
--- a/code/game/communications.dm
+++ b/code/game/communications.dm
@@ -292,7 +292,7 @@ GLOBAL_VAR_INIT(RADIO_MAGNETS, "9")
/datum/signal/proc/debug_print()
if (source)
- . = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n"
+ . = "signal = {source = '[source]' [COORD(source)]\n"
else
. = "signal = {source = '[source]' ()\n"
for (var/i in data)
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index 8da7cb3169..8a6d0063b9 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -110,7 +110,7 @@
SSticker.mode.apprentices += M.mind
M.mind.special_role = "apprentice"
SSticker.mode.update_wiz_icons_added(M.mind)
- M << sound('sound/effects/magic.ogg')
+ SEND_SOUND(M, sound('sound/effects/magic.ogg'))
var/newname = copytext(sanitize(input(M, "You are [wizard_name]'s apprentice. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
if (!newname)
newname = randomname
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index deef4367e0..f6bf8539e0 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -171,8 +171,8 @@
if(candidates.len) //if we got at least one candidate, they're a blobbernaut now.
var/client/C = pick(candidates)
blobber.key = C.key
- blobber << 'sound/effects/blobattack.ogg'
- blobber << 'sound/effects/attackblob.ogg'
+ SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
+ SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
to_chat(blobber, "You are a blobbernaut!")
to_chat(blobber, "You are powerful, hard to kill, and slowly regenerate near nodes and cores, but will slowly die if not near the blob or if the factory that made you is killed.")
to_chat(blobber, "You can communicate with other blobbernauts and GLOB.overminds via :b")
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 0c216f1c38..9bce7319f8 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -235,7 +235,7 @@
if(istype(I, /obj/item/device/analyzer))
user.changeNext_move(CLICK_CD_MELEE)
to_chat(user, "The analyzer beeps once, then reports:
")
- user << 'sound/machines/ping.ogg'
+ SEND_SOUND(user, sound('sound/machines/ping.ogg'))
chemeffectreport(user)
typereport(user)
else
diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm
index 099d991062..7afce8aa27 100644
--- a/code/game/gamemodes/changeling/powers/shriek.dm
+++ b/code/game/gamemodes/changeling/powers/shriek.dm
@@ -16,10 +16,10 @@
C.confused += 25
C.Jitter(50)
else
- C << sound('sound/effects/screech.ogg')
+ SEND_SOUND(C, sound('sound/effects/screech.ogg'))
if(issilicon(M))
- M << sound('sound/weapons/flash.ogg')
+ SEND_SOUND(M, sound('sound/weapons/flash.ogg'))
M.Knockdown(rand(100,200))
for(var/obj/machinery/light/L in range(4, user))
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index 4a1ca367ce..382aaec10d 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -150,7 +150,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(prob(ratvarian_prob))
message = text2ratvar(message)
to_chat(invoker, "\"[message]\"")
- invoker << 'sound/magic/clockwork/invoke_general.ogg'
+ SEND_SOUND(invoker, sound('sound/magic/clockwork/invoke_general.ogg'))
return TRUE
/datum/clockwork_scripture/proc/check_offstation_penalty()
diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm
index a7fb90d253..647b47e7fa 100644
--- a/code/game/gamemodes/cult/cult_comms.dm
+++ b/code/game/gamemodes/cult/cult_comms.dm
@@ -103,13 +103,13 @@
if(B.current)
B.current.update_action_buttons_icon()
if(!B.current.incapacitated())
- B.current << 'sound/hallucinations/im_here1.ogg'
+ SEND_SOUND(B.current, 'sound/hallucinations/im_here1.ogg')
to_chat(B.current, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.")
sleep(100)
var/list/asked_cultists = list()
for(var/datum/mind/B in SSticker.mode.cult)
if(B.current && B.current != Nominee && !B.current.incapacitated())
- B.current << 'sound/magic/exit_blood.ogg'
+ SEND_SOUND(B.current, 'sound/magic/exit_blood.ogg')
asked_cultists += B.current
var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 300, group = asked_cultists)
if(QDELETED(Nominee) || Nominee.incapacitated())
@@ -280,7 +280,7 @@
for(var/datum/mind/B in SSticker.mode.cult)
if(B.current && B.current.stat != DEAD && B.current.client)
to_chat(B.current, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!")
- B.current << pick(sound('sound/hallucinations/over_here2.ogg',0,1,75), sound('sound/hallucinations/over_here3.ogg',0,1,75))
+ SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75))
B.current.client.images += GLOB.blood_target_image
attached_action.owner.update_action_buttons_icon()
remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.")
@@ -324,7 +324,7 @@
return FALSE
if(cooldown > world.time)
if(!PM.active)
- owner << "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can pulse again!"
+ to_chat(owner, "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can pulse again!")
return FALSE
return ..()
@@ -367,7 +367,7 @@
if(!attached_action.throwing)
attached_action.throwing = TRUE
attached_action.throwee = target
- ranged_ability_user << 'sound/weapons/thudswoosh.ogg'
+ SEND_SOUND(ranged_ability_user, sound('sound/weapons/thudswoosh.ogg'))
to_chat(ranged_ability_user,"You reach through the veil with your mind's eye and seize [target]!")
return
else
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 69b730d574..4c80f53b94 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -538,7 +538,7 @@ structure_check() searches for nearby cultist structures required for the invoca
mob_to_revive = input(user, "Choose a cultist to revive.", "Cultist to Revive") as null|anything in potential_revive_mobs
else
mob_to_revive = potential_revive_mobs[1]
- if(!src || QDELETED(src) || rune_in_use || !validness_checks(mob_to_revive, user))
+ if(QDELETED(src) || !validness_checks(mob_to_revive, user))
rune_in_use = FALSE
return
if(user.name == "Herbert West")
diff --git a/code/game/gamemodes/cult/supply.dm b/code/game/gamemodes/cult/supply.dm
index 71b8c941b1..23270c3d6c 100644
--- a/code/game/gamemodes/cult/supply.dm
+++ b/code/game/gamemodes/cult/supply.dm
@@ -29,7 +29,6 @@
return 0
/obj/item/weapon/paper/talisman/supply/Topic(href, href_list)
- world.log << "[usr], [href], [href_list]"
if(QDELETED(src) || usr.incapacitated() || !in_range(src, usr))
return
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index e8b77c1172..c5b94d983f 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -270,7 +270,7 @@
if(target.use(25))
new /obj/structure/constructshell(T)
to_chat(user, "The talisman clings to the metal and twists it into a construct shell!")
- user << sound('sound/effects/magic.ogg',0,1,25)
+ SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
invoke(user, 1)
qdel(src)
else
@@ -281,7 +281,7 @@
new /obj/item/stack/sheet/runed_metal(T,quantity)
target.use(quantity)
to_chat(user, "The talisman clings to the plasteel, transforming it into runed metal!")
- user << sound('sound/effects/magic.ogg',0,1,25)
+ SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
invoke(user, 1)
if(uses <= 0)
qdel(src)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 2a0cd230d5..790319e362 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -120,7 +120,7 @@
var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len)
var/list/datum/game_mode/usable_modes = list()
for(var/datum/game_mode/G in runnable_modes)
- if(G.reroll_friendly)
+ if(G.reroll_friendly && living_crew >= G.required_players)
usable_modes += G
else
qdel(G)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 8c8108962e..5bc162ee8f 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -375,8 +375,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
minor_announce("[key] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
/obj/machinery/doomsday_device/proc/detonate(z_level = ZLEVEL_STATION)
- for(var/mob/M in GLOB.player_list)
- M << 'sound/machines/alarm.ogg'
+ sound_to_playing_players('sound/machines/alarm.ogg')
sleep(100)
for(var/mob/living/L in GLOB.mob_list)
var/turf/T = get_turf(L)
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 68ed9abd35..c24ab53ef5 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -654,7 +654,7 @@
to_chat(M, "[link] [rendered]")
/mob/living/simple_animal/hostile/swarmer/proc/ContactSwarmers()
- var/message = input(src, "Announce to other swarmers", "Swarmer contact")
+ var/message = stripped_input(src, "Announce to other swarmers", "Swarmer contact")
// TODO get swarmers their own colour rather than just boldtext
if(message)
swarmer_chat(message)
diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm
index dcd2ef2673..af27833d15 100644
--- a/code/game/gamemodes/miniantags/morph/morph.dm
+++ b/code/game/gamemodes/miniantags/morph/morph.dm
@@ -224,7 +224,7 @@
player_mind.special_role = "Morph"
SSticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
- S << 'sound/magic/mutate.ogg'
+ SEND_SOUND(S, sound('sound/magic/mutate.ogg'))
message_admins("[key_name_admin(S)] has been made into a morph by an event.")
log_game("[key_name(S)] was spawned as a morph by an event.")
spawned_mobs += S
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index afbc597c29..e16c21e2e2 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -74,7 +74,7 @@
generated_objectives_and_spells = TRUE
mind.remove_all_antag()
mind.wipe_memory()
- src << 'sound/effects/ghost.ogg'
+ SEND_SOUND(src, sound('sound/effects/ghost.ogg'))
var/datum/objective/revenant/objective = new
objective.owner = mind
mind.objectives += objective
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
index e9b417de1a..bcb2218fe6 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
@@ -42,7 +42,7 @@
SSticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.")
- S << 'sound/magic/demon_dies.ogg'
+ SEND_SOUND(S, 'sound/magic/demon_dies.ogg')
message_admins("[key_name_admin(S)] has been made into a slaughter demon by an event.")
log_game("[key_name(S)] was spawned as a slaughter demon by an event.")
spawned_mobs += S
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 755f6dd0c9..d36cab4881 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -421,8 +421,7 @@
yes_code = FALSE
safety = TRUE
update_icon()
- for(var/mob/M in GLOB.player_list)
- M << 'sound/machines/alarm.ogg'
+ sound_to_playing_players('sound/machines/alarm.ogg')
if(SSticker && SSticker.mode)
SSticker.mode.explosion_in_progress = 1
sleep(100)
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 5f65c2a96d..6f1ae8e1dd 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -476,7 +476,7 @@
GiveHint(target)
else if(istype(I, /obj/item/weapon/bikehorn))
to_chat(target, "HONK")
- target << 'sound/items/airhorn.ogg'
+ SEND_SOUND(target, 'sound/items/airhorn.ogg')
target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 06c4cce2bc..9fdcea6aaf 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -403,7 +403,7 @@
flash_color(mob_occupant, flash_color="#960000", flash_time=100)
to_chat(mob_occupant, "Agony blazes across your consciousness as your body is torn apart.
Is this what dying is like? Yes it is.")
playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
- mob_occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
+ SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50))
QDEL_IN(mob_occupant, 40)
/obj/machinery/clonepod/relaymove(mob/user)
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index a54ab19907..7330f2d072 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -473,7 +473,6 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if ("reg")
if (authenticated)
var/t2 = modify
- //var/t1 = input(usr, "What name?", "ID computer", null) as text
if ((authenticated && modify == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc)))
var/newName = reject_bad_name(href_list["reg"])
if(newName)
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index ce6430d75c..75a73a5067 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -89,7 +89,7 @@
playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0)
if(prob(25))
for(var/mob/living/silicon/ai/AI in active_ais())
- AI << sound('sound/machines/terminal_alert.ogg', volume = 10) //Very quiet for balance reasons
+ SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons
if("logout")
authenticated = 0
playsound(src, 'sound/machines/terminal_off.ogg', 50, 0)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 352ddfa4db..f71066f8dd 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -309,7 +309,7 @@
message = noserver
else
if(auth)
- var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
+ var/dkey = trim(stripped_input(usr, "Please enter the decryption key."))
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index 60ac43cb41..3f18cc29e9 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -21,7 +21,7 @@
return
if(!connected)
- viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!"
+ say("Cannot locate mass driver connector. Cancelling firing sequence!")
return
for(var/obj/machinery/door/poddoor/M in range(range, src))
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 624d853808..94047727bc 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -233,9 +233,13 @@
return
else /*if(src.justzap)*/
return
- else if(user.hallucination > 50 && ishuman(user) && prob(10) && src.operating == FALSE)
- hallucinate_shock(user)
- return
+ else if(user.hallucinating() && ishuman(user) && prob(4) && !operating)
+ var/mob/living/carbon/human/H = user
+ if(H.gloves)
+ var/obj/item/clothing/gloves/G = H.gloves
+ if(G.siemens_coefficient)//not insulated
+ hallucinate_shock(H)
+ return
if (cyclelinkedairlock)
if (!shuttledocked && !emergency && !cyclelinkedairlock.shuttledocked && !cyclelinkedairlock.emergency && allowed(user))
if(cyclelinkedairlock.operating)
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index a3f2424a9a..a0086b7258 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -390,7 +390,7 @@
new /obj/effect/temp_visual/cult/sac(loc)
var/atom/throwtarget
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
- L << pick(sound('sound/hallucinations/turn_around1.ogg',0,1,50), sound('sound/hallucinations/turn_around2.ogg',0,1,50))
+ SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
flash_color(L, flash_color="#960000", flash_time=20)
L.Knockdown(40)
L.throw_at(throwtarget, 5, 1,src)
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index ba4b7b53e3..545414577e 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -96,7 +96,8 @@
colour2 = rgb(255,128,0)
if(ismob(AM))
- if(AM:client)
+ var/mob/M = AM
+ if(M.client)
colour = rgb(255,0,0)
else
colour = rgb(255,128,128)
@@ -242,7 +243,8 @@
colour = rgb(255,255,0)
if(ismob(AM))
- if(AM:client)
+ var/mob/M = AM
+ if(M.client)
colour = rgb(255,0,0)
else
colour = rgb(255,128,128)
diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm
index 2183ec6448..20fd729304 100644
--- a/code/game/machinery/robot_fabricator.dm
+++ b/code/game/machinery/robot_fabricator.dm
@@ -11,31 +11,29 @@
idle_power_usage = 20
active_power_usage = 5000
-/obj/machinery/robotic_fabricator/attackby(obj/item/O, mob/user, params)
+/obj/machinery/robotic_fabricator/attackby(obj/item/O, mob/living/user, params)
if (istype(O, /obj/item/stack/sheet/metal))
- if (src.metal_amount < 150000)
- var/count = 0
- src.add_overlay("fab-load-metal")
- spawn(15)
- if(O)
- if(!O:amount)
- return
- while(metal_amount < 150000 && O:amount)
- src.metal_amount += O:materials[MAT_METAL] /*O:height * O:width * O:length * 100000*/
- O:amount--
- count++
-
- if (O:amount < 1)
- qdel(O)
-
- to_chat(user, "You insert [count] metal sheet\s into \the [src].")
- cut_overlay("fab-load-metal")
- updateDialog()
+ if (metal_amount < 150000)
+ add_overlay("fab-load-metal")
+ addtimer(CALLBACK(src, .proc/FinishLoadingMetal, O, user), 15)
else
to_chat(user, "\The [src] is full.")
else
return ..()
+/obj/machinery/robotic_fabricator/proc/FinishLoadingMetal(obj/item/stack/sheet/metal/M, mob/living/user)
+ cut_overlay("fab-load-metal")
+ if(QDELETED(M) || QDELETED(user))
+ return
+ var/count = 0
+ while(metal_amount < 150000 && !QDELETED(M))
+ metal_amount += M.materials[MAT_METAL]
+ M.use(1)
+ count++
+
+ to_chat(user, "You insert [count] metal sheet\s into \the [src].")
+ updateDialog()
+
/obj/machinery/robotic_fabricator/power_change()
if (powered())
stat &= ~NOPOWER
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index a7d857844a..c857ddaf16 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -10,9 +10,9 @@
max_integrity = 200 //The shield can only take so much beating (prevents perma-prisons)
CanAtmosPass = ATMOS_PASS_DENSITY
-/obj/structure/emergency_shield/New()
- src.setDir(pick(1,2,3,4))
- ..()
+/obj/structure/emergency_shield/Initialize()
+ . = ..()
+ setDir(pick(GLOB.cardinals))
air_update_turf(1)
/obj/structure/emergency_shield/Destroy()
diff --git a/code/game/machinery/shieldgen.dm.rej b/code/game/machinery/shieldgen.dm.rej
new file mode 100644
index 0000000000..12ce2d21dc
--- /dev/null
+++ b/code/game/machinery/shieldgen.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm (rejected hunks)
+@@ -12,7 +12,7 @@
+
+ /obj/structure/emergency_shield/Initialize()
+ . = ..()
+- setDir(pick(1,2,3,4))
++ setDir(pick(GLOB.cardinals))
+ air_update_turf(1)
+
+ /obj/structure/emergency_shield/Destroy()
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index dd8581af69..1e7c2b9f20 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -37,10 +37,7 @@
src.update_chassis_page()
chassis.occupant_message("The [src] is destroyed!")
chassis.log_append_to_last("[src] is destroyed.",1)
- if(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon))
- chassis.occupant << sound('sound/mecha/weapdestr.ogg',volume=50)
- else
- chassis.occupant << sound('sound/mecha/critdestr.ogg',volume=50)
+ SEND_SOUND(chassis.occupant, sound(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon) ? 'sound/mecha/weapdestr.ogg' : 'sound/mecha/critdestr.ogg', volume=50))
chassis = null
return ..()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index b0c16dcfa7..28f2b0fb18 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -596,7 +596,7 @@
/obj/mecha/proc/setInternalDamage(int_dam_flag)
internal_damage |= int_dam_flag
log_append_to_last("Internal damage of type [int_dam_flag].",1)
- occupant << sound('sound/machines/warning-buzzer.ogg',wait=0)
+ SEND_SOUND(occupant, sound('sound/machines/warning-buzzer.ogg',wait=0))
diag_hud_set_mechstat()
return
@@ -707,14 +707,14 @@
icon_state = initial(icon_state)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
if(!internal_damage)
- occupant << sound('sound/mecha/nominal.ogg',volume=50)
+ SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50))
AI.cancel_camera()
AI.controlled_mech = src
AI.remote_control = src
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
- to_chat(AI, "[AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" \
- : "You have been uploaded to a mech's onboard computer."]")
+ to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" :\
+ "You have been uploaded to a mech's onboard computer.")
to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.")
if(interaction == AI_TRANS_FROM_CARD)
GrantActions(AI, FALSE) //No eject/return to core action for AI uploaded by card
@@ -860,7 +860,7 @@
setDir(dir_in)
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
if(!internal_damage)
- occupant << sound('sound/mecha/nominal.ogg',volume=50)
+ SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50))
return 1
else
return 0
@@ -914,7 +914,7 @@
setDir(dir_in)
log_message("[mmi_as_oc] moved in as pilot.")
if(!internal_damage)
- occupant << sound('sound/mecha/nominal.ogg',volume=50)
+ SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50))
GrantActions(brainmob)
return TRUE
diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm
index 050498d8f1..4102ba914b 100644
--- a/code/game/mecha/mecha_actions.dm
+++ b/code/game/mecha/mecha_actions.dm
@@ -242,7 +242,7 @@
chassis.occupant_message("Zoom mode [chassis.zoom_mode?"en":"dis"]abled.")
if(chassis.zoom_mode)
owner.client.change_view(12)
- owner << sound('sound/mecha/imag_enh.ogg',volume=50)
+ SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50))
else
owner.client.change_view(world.view) //world.view - default mob view size
UpdateButtonIcon()
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index ef4531b2d6..80b291e571 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -121,13 +121,13 @@
if(!victim.client || !istype(victim))
return
to_chat(victim, "RIP AND TEAR")
- victim << 'sound/misc/e1m1.ogg'
+ SEND_SOUND(victim, sound('sound/misc/e1m1.ogg'))
var/old_color = victim.client.color
var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
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,"demon",duration,0)
+ new /datum/hallucination/delusion(victim, TRUE, "demon",duration,0)
var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
chainsaw.flags |= NODROP
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 3d7e575215..ae84bd2f2c 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -147,7 +147,7 @@ MASS SPECTROMETER
if (M.getCloneLoss())
to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.")
if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
- to_chat(user, "\tBloodstream analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.")
+ to_chat(user, "\tBloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals.")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\tSubject brain function is non-existent.")
else if (M.getBrainLoss() >= 60)
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index c21ff386bd..4663e2142a 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -8,7 +8,7 @@
desc = "Regulates the transfer of air between two tanks"
var/obj/item/weapon/tank/tank_one
var/obj/item/weapon/tank/tank_two
- var/obj/item/device/attached_device
+ var/obj/item/device/assembly/attached_device
var/mob/attacher = null
var/valve_open = FALSE
var/toggle = 1
@@ -99,8 +99,8 @@
toggle_valve()
else if(attached_device)
if(href_list["rem_device"])
- attached_device.loc = get_turf(src)
- attached_device:holder = null
+ attached_device.forceMove(get_turf(src))
+ attached_device.holder = null
attached_device = null
update_icon()
if(href_list["device"])
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 0e6d6cc66f..1829538a01 100755
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -26,6 +26,7 @@
var/create_full = FALSE
var/create_with_tank = FALSE
var/igniter_type = /obj/item/device/assembly/igniter
+ trigger_guard = TRIGGER_GUARD_NORMAL
/obj/item/weapon/flamethrower/Destroy()
if(weldtool)
@@ -69,12 +70,7 @@
if(flag)
return // too close
if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.dna.check_mutation(HULK))
- to_chat(user, "Your meaty finger is much too large for the trigger guard!")
- return
- if(NOGUNS in H.dna.species.species_traits)
- to_chat(user, "Your fingers don't fit in the trigger guard!")
+ if(!can_trigger_gun(user))
return
if(user && user.get_active_held_item() == src) // Make sure our user is still holding us
var/turf/target_turf = get_turf(target)
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index 238022d209..8e1cf3301e 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -320,6 +320,8 @@
desc = "Particularly twisted dieties grant gifts of dubious value."
icon_state = "arm_blade"
item_state = "arm_blade"
+ lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
flags = ABSTRACT | NODROP
w_class = WEIGHT_CLASS_HUGE
sharpness = IS_SHARP
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index e893fec6ac..ab61e7b916 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -26,6 +26,7 @@
var/fire_mode = PCANNON_FIREALL
var/automatic = FALSE
var/clumsyCheck = TRUE
+ trigger_guard = TRIGGER_GUARD_NORMAL
/obj/item/weapon/pneumatic_cannon/CanItemAutoclick()
return automatic
@@ -108,11 +109,7 @@
if(!istype(user) && !target)
return
var/discharge = 0
- if(user.dna.check_mutation(HULK))
- to_chat(user, "Your meaty finger is much too large for the trigger guard!")
- return
- if(NOGUNS in user.dna.species.species_traits)
- to_chat(user, "Your fingers don't fit in the trigger guard!")
+ if(!can_trigger_gun(user))
return
if(!loadedItems || !loadedWeightClass)
to_chat(user, "\The [src] has nothing loaded.")
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index bb723ffb33..53bfe5d64c 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -1,4 +1,5 @@
/obj/item/weapon
+ var/trigger_guard = TRIGGER_GUARD_NONE
/obj/item/weapon/banhammer
desc = "A banhammer"
@@ -584,3 +585,8 @@
throwforce = 0
flags = DROPDEL | ABSTRACT
attack_verb = list("bopped")
+
+/obj/item/weapon/proc/can_trigger_gun(mob/living/user)
+ if(!user.can_use_guns(src))
+ return FALSE
+ return TRUE
\ No newline at end of file
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index e478ff5d92..d141f71b7a 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -1,12 +1,13 @@
/obj/structure/flora
resistance_flags = FLAMMABLE
+ obj_integrity = 150
max_integrity = 150
- anchored = TRUE
+ anchored = 1
//trees
/obj/structure/flora/tree
name = "tree"
- density = TRUE
+ density = 1
pixel_x = -16
layer = FLY_LAYER
var/cut = FALSE
@@ -25,7 +26,7 @@
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0)
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "tree_stump"
- density = FALSE
+ density = 0
pixel_x = -16
name += " stump"
cut = TRUE
@@ -45,14 +46,14 @@
/obj/structure/flora/tree/pine/Initialize()
icon_state = "pine_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/Initialize()
- ..()
+ . = ..()
icon_state = "pine_c"
/obj/structure/flora/tree/dead
@@ -64,7 +65,7 @@
icon_state = "palm1"
/obj/structure/flora/tree/palm/Initialize()
- ..()
+ . = ..()
icon_state = pick("palm1","palm2")
pixel_x = 0
@@ -76,7 +77,7 @@
/obj/structure/flora/tree/dead/Initialize()
icon_state = "tree_[rand(1, 6)]"
- ..()
+ . = ..()
/obj/structure/flora/tree/jungle
name = "tree"
@@ -88,12 +89,7 @@
/obj/structure/flora/tree/jungle/Initialize()
icon_state = "[icon_state][rand(1, 6)]"
- ..()
-
-/obj/structure/flora/tree/jungle/small
- pixel_y = 0
- pixel_x = -32
- icon = 'icons/obj/flora/jungletreesmall.dmi'
+ . = ..()
//grass
/obj/structure/flora/grass
@@ -106,7 +102,7 @@
/obj/structure/flora/grass/brown/Initialize()
icon_state = "snowgrass[rand(1, 3)]bb"
- ..()
+ . = ..()
/obj/structure/flora/grass/green
@@ -114,14 +110,14 @@
/obj/structure/flora/grass/green/Initialize()
icon_state = "snowgrass[rand(1, 3)]gb"
- ..()
+ . = ..()
/obj/structure/flora/grass/both
icon_state = "snowgrassall1"
/obj/structure/flora/grass/both/Initialize()
icon_state = "snowgrassall[rand(1, 3)]"
- ..()
+ . = ..()
//bushes
@@ -129,11 +125,11 @@
name = "bush"
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
- anchored = TRUE
+ anchored = 1
/obj/structure/flora/bush/Initialize()
icon_state = "snowbush[rand(1, 6)]"
- ..()
+ . = ..()
//newbushes
@@ -145,112 +141,112 @@
/obj/structure/flora/ausbushes/Initialize()
if(icon_state == "firstbush_1")
icon_state = "firstbush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/reedbush
icon_state = "reedbush_1"
/obj/structure/flora/ausbushes/reedbush/Initialize()
icon_state = "reedbush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/leafybush
icon_state = "leafybush_1"
/obj/structure/flora/ausbushes/leafybush/Initialize()
icon_state = "leafybush_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/palebush
icon_state = "palebush_1"
/obj/structure/flora/ausbushes/palebush/Initialize()
icon_state = "palebush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/stalkybush
icon_state = "stalkybush_1"
/obj/structure/flora/ausbushes/stalkybush/Initialize()
icon_state = "stalkybush_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/grassybush
icon_state = "grassybush_1"
/obj/structure/flora/ausbushes/grassybush/Initialize()
icon_state = "grassybush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/fernybush
icon_state = "fernybush_1"
/obj/structure/flora/ausbushes/fernybush/Initialize()
icon_state = "fernybush_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/sunnybush
icon_state = "sunnybush_1"
/obj/structure/flora/ausbushes/sunnybush/Initialize()
icon_state = "sunnybush_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/genericbush
icon_state = "genericbush_1"
/obj/structure/flora/ausbushes/genericbush/Initialize()
icon_state = "genericbush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/pointybush
icon_state = "pointybush_1"
/obj/structure/flora/ausbushes/pointybush/Initialize()
icon_state = "pointybush_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/lavendergrass
icon_state = "lavendergrass_1"
/obj/structure/flora/ausbushes/lavendergrass/Initialize()
icon_state = "lavendergrass_[rand(1, 4)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/ywflowers
icon_state = "ywflowers_1"
/obj/structure/flora/ausbushes/ywflowers/Initialize()
icon_state = "ywflowers_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/brflowers
icon_state = "brflowers_1"
/obj/structure/flora/ausbushes/brflowers/Initialize()
icon_state = "brflowers_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/ppflowers
icon_state = "ppflowers_1"
/obj/structure/flora/ausbushes/ppflowers/Initialize()
icon_state = "ppflowers_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/sparsegrass
icon_state = "sparsegrass_1"
/obj/structure/flora/ausbushes/sparsegrass/Initialize()
icon_state = "sparsegrass_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/ausbushes/fullgrass
icon_state = "fullgrass_1"
/obj/structure/flora/ausbushes/fullgrass/Initialize()
icon_state = "fullgrass_[rand(1, 3)]"
- ..()
+ . = ..()
/obj/item/weapon/twohanded/required/kirbyplants
name = "potted plant"
@@ -308,10 +304,10 @@
desc = "A volcanic rock"
icon = 'icons/obj/flora/rocks.dmi'
resistance_flags = FIRE_PROOF
- density = TRUE
+ density = 1
/obj/structure/flora/rock/Initialize()
- ..()
+ . = ..()
icon_state = "[icon_state][rand(1,3)]"
/obj/structure/flora/rock/pile
@@ -319,7 +315,7 @@
desc = "A pile of rocks"
/obj/structure/flora/rock/pile/Initialize()
- ..()
+ . = ..()
icon_state = "[icon_state][rand(1,3)]"
//Jungle grass
@@ -333,7 +329,7 @@
/obj/structure/flora/grass/jungle/Initialize()
icon_state = "[icon_state][rand(1, 5)]"
- ..()
+ . = ..()
/obj/structure/flora/grass/jungle/b
icon_state = "grassb"
@@ -348,7 +344,7 @@
density = FALSE
/obj/structure/flora/rock/jungle/Initialize()
- ..()
+ . = ..()
icon_state = "[initial(icon_state)][rand(1,5)]"
@@ -361,7 +357,7 @@
/obj/structure/flora/junglebush/Initialize()
icon_state = "[icon_state][rand(1, 3)]"
- ..()
+ . = ..()
/obj/structure/flora/junglebush/b
icon_state = "bushb"
diff --git a/code/game/objects/structures/flora.dm.rej b/code/game/objects/structures/flora.dm.rej
new file mode 100644
index 0000000000..8257ec2122
--- /dev/null
+++ b/code/game/objects/structures/flora.dm.rej
@@ -0,0 +1,28 @@
+diff a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm (rejected hunks)
+@@ -89,7 +89,7 @@
+
+ /obj/structure/flora/tree/jungle/Initialize()
+ icon_state = "[icon_state][rand(1, 6)]"
+- ..()
++ . = ..()
+
+ //grass
+ /obj/structure/flora/grass
+@@ -307,7 +307,7 @@
+ density = 1
+
+ /obj/structure/flora/rock/Initialize()
+- ..()
++ . = ..()
+ icon_state = "[icon_state][rand(1,3)]"
+
+ /obj/structure/flora/rock/pile
+@@ -381,5 +381,5 @@
+ pixel_y = -16
+
+ /obj/structure/flora/rock/pile/largejungle/Initialize()
+- ..()
+- icon_state = "[initial(icon_state)][rand(1,3)]"
+\ No newline at end of file
++ . = ..()
++ icon_state = "[initial(icon_state)][rand(1,3)]"
diff --git a/code/game/sound.dm b/code/game/sound.dm
index c728071e50..ff35915b08 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -78,7 +78,7 @@
S.y = 1
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
- src << S
+ SEND_SOUND(src, S)
/proc/sound_to_playing_players(sound, volume = 100, vary)
sound = get_sfx(sound)
@@ -94,13 +94,13 @@
next_channel = 1
/mob/proc/stop_sound_channel(chan)
- src << sound(null, repeat = 0, wait = 0, channel = chan)
+ SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
/client/proc/playtitlemusic()
UNTIL(SSticker.login_music) //wait for SSticker init to set the login music
if(prefs && (prefs.toggles & SOUND_LOBBY))
- src << sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS
+ SEND_SOUND(src, sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS)
/proc/get_rand_frequency()
return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
@@ -175,7 +175,3 @@
'sound/vore/prey/death_07.ogg','sound/vore/prey/death_08.ogg','sound/vore/prey/death_09.ogg',
'sound/vore/prey/death_10.ogg')
return soundin
-
-/proc/playsound_global(file, repeat = 0, wait, channel, volume)
- for(var/V in GLOB.clients)
- V << sound(file, repeat, wait, channel, volume)
diff --git a/code/game/sound.dm.rej b/code/game/sound.dm.rej
new file mode 100644
index 0000000000..003c8b9975
--- /dev/null
+++ b/code/game/sound.dm.rej
@@ -0,0 +1,9 @@
+diff a/code/game/sound.dm b/code/game/sound.dm (rejected hunks)
+@@ -145,7 +145,3 @@
+ if ("can_open")
+ soundin = pick('sound/effects/can_open1.ogg', 'sound/effects/can_open2.ogg', 'sound/effects/can_open3.ogg')
+ return soundin
+-
+-/proc/playsound_global(file, repeat = 0, wait, channel, volume)
+- for(var/V in GLOB.clients)
+- V << sound(file, repeat, wait, channel, volume)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 82ff907a04..a990530056 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -18,6 +18,7 @@
var/sound
/turf/open/indestructible/sound/Entered(var/mob/AM)
+ ..()
if(istype(AM))
playsound(src,sound,50,1)
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 968e782984..a51240c969 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -22,6 +22,7 @@
return
/turf/open/chasm/Entered(atom/movable/AM)
+ ..()
START_PROCESSING(SSobj, src)
drop_stuff(AM)
diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm
index c7e6973c4d..b877fa9eac 100644
--- a/code/game/turfs/space/transit.dm
+++ b/code/game/turfs/space/transit.dm
@@ -25,6 +25,7 @@
dir = EAST
/turf/open/space/transit/Entered(atom/movable/AM, atom/OldLoc)
+ ..()
if(!locate(/obj/structure/lattice) in src)
throw_atom(AM)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index b204406d05..4342d12714 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -160,6 +160,7 @@
return TRUE //Nothing found to block so return success!
/turf/Entered(atom/movable/AM)
+ ..()
if(explosion_level && AM.ex_check(explosion_id))
AM.ex_act(explosion_level)
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
index 23bf656b8c..e580b306b3 100644
--- a/code/modules/admin/DB_ban/functions.dm
+++ b/code/modules/admin/DB_ban/functions.dm
@@ -83,10 +83,10 @@
var/a_computerid
var/a_ip
- if(src.owner && istype(src.owner, /client))
- a_ckey = src.owner:ckey
- a_computerid = src.owner:computer_id
- a_ip = src.owner:address
+ if(istype(owner))
+ a_ckey = owner.ckey
+ a_computerid = owner.computer_id
+ a_ip = owner.address
if(blockselfban)
if(a_ckey == ckey)
@@ -309,12 +309,12 @@
to_chat(usr, "Database update failed due to multiple bans having the same ID. Contact the database admin.")
return
- if(!src.owner || !istype(src.owner, /client))
+ if(!istype(owner))
return
- var/unban_ckey = src.owner:ckey
- var/unban_computerid = src.owner:computer_id
- var/unban_ip = src.owner:address
+ var/unban_ckey = owner.ckey
+ var/unban_computerid = owner.computer_id
+ var/unban_ip = owner.address
var/sql_update = "UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = INET_ATON('[unban_ip]') WHERE id = [id]"
var/datum/DBQuery/query_unban = SSdbcore.NewQuery(sql_update)
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 1ff2360923..5ea980a91d 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -109,14 +109,14 @@ GLOBAL_PROTECT(Banlist)
else
GLOB.Banlist.dir.Add("[ckey][computerid]")
GLOB.Banlist.cd = "/base/[ckey][computerid]"
- GLOB.Banlist["key"] << ckey
- GLOB.Banlist["id"] << computerid
- GLOB.Banlist["ip"] << address
- GLOB.Banlist["reason"] << reason
- GLOB.Banlist["bannedby"] << bannedby
- GLOB.Banlist["temp"] << temp
+ WRITE_FILE(GLOB.Banlist["key"], ckey)
+ WRITE_FILE(GLOB.Banlist["id"], computerid)
+ WRITE_FILE(GLOB.Banlist["ip"], address)
+ WRITE_FILE(GLOB.Banlist["reason"], reason)
+ WRITE_FILE(GLOB.Banlist["bannedby"], bannedby)
+ WRITE_FILE(GLOB.Banlist["temp"], temp)
if (temp)
- GLOB.Banlist["minutes"] << bantimestamp
+ WRITE_FILE(GLOB.Banlist["minutes"], bantimestamp)
if(!temp)
create_message("note", ckey, bannedby, "Permanently banned - [reason]", null, null, 0, 0)
else
@@ -211,17 +211,17 @@ GLOBAL_PROTECT(Banlist)
GLOB.Banlist.cd = "/base"
GLOB.Banlist.dir.Add("trash[i]trashid[i]")
GLOB.Banlist.cd = "/base/trash[i]trashid[i]"
- GLOB.Banlist["key"] << "trash[i]"
+ WRITE_FILE(GLOB.Banlist["key"], "trash[i]")
else
GLOB.Banlist.cd = "/base"
GLOB.Banlist.dir.Add("[last]trashid[i]")
GLOB.Banlist.cd = "/base/[last]trashid[i]"
- GLOB.Banlist["key"] << last
- GLOB.Banlist["id"] << "trashid[i]"
- GLOB.Banlist["reason"] << "Trashban[i]."
- GLOB.Banlist["temp"] << a
- GLOB.Banlist["minutes"] << GLOB.CMinutes + rand(1,2000)
- GLOB.Banlist["bannedby"] << "trashmin"
+ WRITE_FILE(GLOB.Banlist["key"], last)
+ WRITE_FILE(GLOB.Banlist["id"], "trashid[i]")
+ WRITE_FILE(GLOB.Banlist["reason"], "Trashban[i].")
+ WRITE_FILE(GLOB.Banlist["temp"], a)
+ WRITE_FILE(GLOB.Banlist["minutes"], GLOB.CMinutes + rand(1,2000))
+ WRITE_FILE(GLOB.Banlist["bannedby"], "trashmin")
last = "trash[i]"
GLOB.Banlist.cd = "/base"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 7c20421d3c..5943e753a0 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -595,7 +595,7 @@
log_admin("[key_name(usr)] delayed the round start.")
else
to_chat(world, "The game will start in [newtime] seconds.")
- world << 'sound/ai/attention.ogg'
+ SEND_SOUND(world, sound('sound/ai/attention.ogg'))
log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.")
SSblackbox.add_details("admin_verb","Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 54feb11532..2ca0593e8d 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -5,7 +5,7 @@
F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
"
-/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY) )
+/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS) )
set name = "Investigate"
set category = "Admin"
if(!holder)
diff --git a/code/modules/admin/admin_investigate.dm.rej b/code/modules/admin/admin_investigate.dm.rej
new file mode 100644
index 0000000000..d58adb0f78
--- /dev/null
+++ b/code/modules/admin/admin_investigate.dm.rej
@@ -0,0 +1 @@
+garbage
\ No newline at end of file
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 73c2d8067e..828fbb2e91 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -142,7 +142,7 @@ GLOBAL_PROTECT(admin_ranks)
else
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
- GLOB.world_game_log << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
+ WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admin_ranks()
return
@@ -220,7 +220,7 @@ GLOBAL_PROTECT(admin_ranks)
else
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
- GLOB.world_game_log << "Failed to connect to database in load_admins(). Reverting to legacy system."
+ WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admins(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index c3185c7b21..04a4b7877a 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -390,7 +390,7 @@
SSblackbox.add_details("admin_secrets_fun_used","Chinese Cartoons")
message_admins("[key_name_admin(usr)] made everything kawaii.")
for(var/mob/living/carbon/human/H in GLOB.mob_list)
- H << sound('sound/ai/animes.ogg')
+ SEND_SOUND(H, sound('sound/ai/animes.ogg'))
if(H.dna.species.id == "human")
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 818b0d6f09..ac047429c8 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -6,7 +6,7 @@
log_admin("[key_name(usr)] tried to use the admin panel without authorization.")
return
if(href_list["ahelp"])
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN, TRUE))
return
var/ahelp_ref = href_list["ahelp"]
@@ -506,10 +506,10 @@
ban_unban_log_save("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
message_admins("[key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]")
GLOB.Banlist.cd = "/base/[banfolder]"
- GLOB.Banlist["reason"] << reason
- GLOB.Banlist["temp"] << temp
- GLOB.Banlist["minutes"] << minutes
- GLOB.Banlist["bannedby"] << usr.ckey
+ WRITE_FILE(GLOB.Banlist["reason"], reason)
+ WRITE_FILE(GLOB.Banlist["temp"], temp)
+ WRITE_FILE(GLOB.Banlist["minutes"], minutes)
+ WRITE_FILE(GLOB.Banlist["bannedby"], usr.ckey)
GLOB.Banlist.cd = "/base"
SSblackbox.inc("ban_edit",1)
unbanpanel()
@@ -1697,7 +1697,7 @@
message_admins("[key_name(H)] got their cookie, spawned by [key_name(src.owner)].")
SSblackbox.inc("admin_cookies_spawned",1)
to_chat(H, "Your prayers have been answered!! You received the best cookie!")
- H << 'sound/effects/pray_chaplain.ogg'
+ SEND_SOUND(H, sound('sound/effects/pray_chaplain.ogg'))
else if(href_list["adminsmite"])
if(!check_rights(R_ADMIN|R_FUN))
diff --git a/code/modules/admin/verbs/BrokenInhands.dm b/code/modules/admin/verbs/BrokenInhands.dm
index 89eccf285d..732ae9e91c 100644
--- a/code/modules/admin/verbs/BrokenInhands.dm
+++ b/code/modules/admin/verbs/BrokenInhands.dm
@@ -28,7 +28,7 @@
if(text)
var/F = file("broken_icons.txt")
fdel(F)
- F << text
+ WRITE_FILE(F, text)
to_chat(world, "Completely successfully and written to [F]")
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 44755c46fc..b19c736e14 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -259,7 +259,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//send this msg to all admins
for(var/client/X in GLOB.admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
- X << 'sound/effects/adminhelp.ogg'
+ SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
window_flash(X, ignorepref = TRUE)
to_chat(X, admin_msg)
@@ -347,7 +347,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(initiator)
initiator.giveadminhelpverb()
- initiator << 'sound/effects/adminhelp.ogg'
+ SEND_SOUND(initiator, sound('sound/effects/adminhelp.ogg'))
to_chat(initiator, "- AdminHelp Rejected! -")
to_chat(initiator, "Your admin help was rejected. The adminhelp verb has been returned to you so that you may try again.")
diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm
index 7f4dd3ebb9..ec1091bb3c 100644
--- a/code/modules/admin/verbs/adminjump.dm
+++ b/code/modules/admin/verbs/adminjump.dm
@@ -84,11 +84,11 @@
var/list/keys = list()
for(var/mob/M in GLOB.player_list)
keys += M.client
- var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
+ var/client/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
if(!selection)
to_chat(src, "No keys found.")
return
- var/mob/M = selection:mob
+ var/mob/M = selection.mob
log_admin("[key_name(usr)] jumped to [key_name(M)]")
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]")
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 31fb08da36..db29021463 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -167,7 +167,7 @@
//play the recieving admin the adminhelp sound (if they have them enabled)
if(recipient.prefs.toggles & SOUND_ADMINHELP)
- recipient << 'sound/effects/adminhelp.ogg'
+ SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg'))
else
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
@@ -182,7 +182,7 @@
admin_ticket_log(recipient, "PM From [key_name_admin(src)]: [keywordparsedmsg]")
//always play non-admin recipients the adminhelp sound
- recipient << 'sound/effects/adminhelp.ogg'
+ SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg'))
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
if(config.popup_admin_pm)
@@ -301,7 +301,7 @@
window_flash(C, ignorepref = TRUE)
//always play non-admin recipients the adminhelp sound
- C << 'sound/effects/adminhelp.ogg'
+ SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
C.ircreplyamount = IRCREPLYCOUNT
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index c69628c625..66438d1fac 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -316,10 +316,8 @@ GLOBAL_PROTECT(AdminProcCallCount)
alert("Wait until the game starts")
return
if(ishuman(M))
- log_admin("[key_name(src)] has alienized [M.key].")
- spawn(0)
- M:Alienize()
- SSblackbox.add_details("admin_verb","Make Alien") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ INVOKE_ASYNC(M, /mob/living/carbon/human/proc/Alienize)
+ SSblackbox.add_details("admin_verb","Make Alien") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] made [key_name(M)] into an alien.")
message_admins("[key_name_admin(usr)] made [key_name(M)] into an alien.")
else
@@ -333,10 +331,8 @@ GLOBAL_PROTECT(AdminProcCallCount)
alert("Wait until the game starts")
return
if(ishuman(M))
- log_admin("[key_name(src)] has slimeized [M.key].")
- spawn(0)
- M:slimeize()
- SSblackbox.add_details("admin_verb","Make Slime") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ INVOKE_ASYNC(M, /mob/living/carbon/human/proc/slimeize)
+ SSblackbox.add_details("admin_verb","Make Slime") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] made [key_name(M)] into a slime.")
message_admins("[key_name_admin(usr)] made [key_name(M)] into a slime.")
else
@@ -461,12 +457,14 @@ GLOBAL_PROTECT(AdminProcCallCount)
if(worn)
if(istype(worn, /obj/item/device/pda))
- worn:id = id
- id.loc = worn
+ var/obj/item/device/pda/PDA = worn
+ PDA.id = id
+ id.forceMove(PDA)
else if(istype(worn, /obj/item/weapon/storage/wallet))
- worn:front_id = id
- id.loc = worn
- worn.update_icon()
+ var/obj/item/weapon/storage/wallet/W = worn
+ W.front_id = id
+ id.forceMove(W)
+ W.update_icon()
else
H.equip_to_slot(id,slot_wear_id)
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 15b619f653..a4482154d8 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -78,8 +78,9 @@
continue
output += " [filters[filter]]: [f.len]
"
for (var/device in f)
- if (isobj(device))
- output += " [device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])
"
+ if (istype(device, /atom))
+ var/atom/A = device
+ output += " [device] ([A.x],[A.y],[A.z] in area [get_area(device)])
"
else
output += " [device]
"
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index eb4c3a5f10..2bac326710 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -30,7 +30,7 @@
for(var/mob/M in GLOB.player_list)
if(M.client.prefs.toggles & SOUND_MIDI)
- M << admin_sound
+ SEND_SOUND(M, admin_sound)
SSblackbox.add_details("admin_verb","Play Global Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -68,5 +68,5 @@
message_admins("[key_name_admin(src)] stopped all currently playing sounds.")
for(var/mob/M in GLOB.player_list)
if(M.client)
- M << sound(null)
+ SEND_SOUND(M, sound(null))
SSblackbox.add_details("admin_verb","Stop All Playing Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index ff39c36b9b..bbe1c48b6a 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -40,7 +40,7 @@
to_chat(C, msg)
if(C.prefs.toggles & SOUND_PRAYERS)
if(usr.job == "Chaplain")
- C << 'sound/effects/pray.ogg'
+ SEND_SOUND(C, sound('sound/effects/pray.ogg'))
to_chat(usr, "Your prayers have been received by the gods.")
SSblackbox.add_details("admin_verb","Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 03720d9d81..6cd8efdd1d 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -44,7 +44,8 @@
qdel(src)
return
- if((istype(W, /obj/item/weapon/weldingtool) && W:welding))
+ var/obj/item/weapon/weldingtool/WT = W
+ if((istype(WT) && WT.welding))
if(!status)
status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index d733dfc3fb..a45536430a 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -189,8 +189,9 @@
#define CONNECTED 2
#define EMPTY 4
#define LOW 8
-#define FULL 16
-#define DANGER 32
+#define MEDIUM 16
+#define FULL 32
+#define DANGER 64
/obj/machinery/portable_atmospherics/canister/update_icon()
if(stat & BROKEN)
cut_overlays()
@@ -207,9 +208,11 @@
var/pressure = air_contents.return_pressure()
if(pressure < 10)
update |= EMPTY
- else if(pressure < ONE_ATMOSPHERE)
+ else if(pressure < 5 * ONE_ATMOSPHERE)
update |= LOW
- else if(pressure < 15 * ONE_ATMOSPHERE)
+ else if(pressure < 10 * ONE_ATMOSPHERE)
+ update |= MEDIUM
+ else if(pressure < 40 * ONE_ATMOSPHERE)
update |= FULL
else
update |= DANGER
@@ -222,9 +225,9 @@
add_overlay("can-open")
if(update & CONNECTED)
add_overlay("can-connector")
- if(update & EMPTY)
+ if(update & LOW)
add_overlay("can-o0")
- else if(update & LOW)
+ else if(update & MEDIUM)
add_overlay("can-o1")
else if(update & FULL)
add_overlay("can-o2")
@@ -234,6 +237,7 @@
#undef CONNECTED
#undef EMPTY
#undef LOW
+#undef MEDIUM
#undef FULL
#undef DANGER
diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm
index 15117c1cbb..7926cfc34d 100644
--- a/code/modules/cargo/console.dm
+++ b/code/modules/cargo/console.dm
@@ -145,7 +145,7 @@
var/reason = ""
if(requestonly)
- reason = input("Reason:", name, "") as text|null
+ reason = stripped_input("Reason:", name, "")
if(isnull(reason) || ..())
return
diff --git a/code/modules/cargo/console.dm.rej b/code/modules/cargo/console.dm.rej
new file mode 100644
index 0000000000..e8798f179a
--- /dev/null
+++ b/code/modules/cargo/console.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm (rejected hunks)
+@@ -145,7 +145,7 @@
+
+ var/reason = ""
+ if(requestonly)
+- reason = stripped_input("Reason:", name, "") as text|null
++ reason = stripped_input("Reason:", name, "")
+ if(isnull(reason) || ..())
+ return
+
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 44b518e7b8..20b4440b97 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -73,7 +73,7 @@
return
//Logs all hrefs
- GLOB.world_href_log << "[time_stamp(show_ds = TRUE)] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
"
+ WRITE_FILE(GLOB.world_href_log, "[time_stamp(show_ds = TRUE)] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
")
// Admin PM
if(href_list["priv_msg"])
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index f846f52625..244afc69f3 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -226,34 +226,34 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
return 0
S.cd = "/"
- S["version"] << SAVEFILE_VERSION_MAX //updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date
+ WRITE_FILE(S["version"] , SAVEFILE_VERSION_MAX) //updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date
//general preferences
- S["ooccolor"] << ooccolor
- S["lastchangelog"] << lastchangelog
- S["UI_style"] << UI_style
- S["hotkeys"] << hotkeys
- S["tgui_fancy"] << tgui_fancy
- S["tgui_lock"] << tgui_lock
- S["windowflash"] << windowflashing
- S["be_special"] << be_special
- S["default_slot"] << default_slot
- S["toggles"] << toggles
- S["chat_toggles"] << chat_toggles
- S["ghost_form"] << ghost_form
- S["ghost_orbit"] << ghost_orbit
- S["ghost_accs"] << ghost_accs
- S["ghost_others"] << ghost_others
- S["preferred_map"] << preferred_map
- S["ignoring"] << ignoring
- S["ghost_hud"] << ghost_hud
- S["inquisitive_ghost"] << inquisitive_ghost
- S["uses_glasses_colour"]<< uses_glasses_colour
- S["clientfps"] << clientfps
- S["parallax"] << parallax
- S["menuoptions"] << menuoptions
- S["enable_tips"] << enable_tips
- S["tip_delay"] << tip_delay
+ WRITE_FILE(S["ooccolor"], ooccolor)
+ WRITE_FILE(S["lastchangelog"], lastchangelog)
+ WRITE_FILE(S["UI_style"], UI_style)
+ WRITE_FILE(S["hotkeys"], hotkeys)
+ WRITE_FILE(S["tgui_fancy"], tgui_fancy)
+ WRITE_FILE(S["tgui_lock"], tgui_lock)
+ WRITE_FILE(S["windowflash"], windowflashing)
+ WRITE_FILE(S["be_special"], be_special)
+ WRITE_FILE(S["default_slot"], default_slot)
+ WRITE_FILE(S["toggles"], toggles)
+ WRITE_FILE(S["chat_toggles"], chat_toggles)
+ WRITE_FILE(S["ghost_form"], ghost_form)
+ WRITE_FILE(S["ghost_orbit"], ghost_orbit)
+ WRITE_FILE(S["ghost_accs"], ghost_accs)
+ WRITE_FILE(S["ghost_others"], ghost_others)
+ WRITE_FILE(S["preferred_map"], preferred_map)
+ WRITE_FILE(S["ignoring"], ignoring)
+ WRITE_FILE(S["ghost_hud"], ghost_hud)
+ WRITE_FILE(S["inquisitive_ghost"], inquisitive_ghost)
+ WRITE_FILE(S["uses_glasses_colour"], uses_glasses_colour)
+ WRITE_FILE(S["clientfps"], clientfps)
+ WRITE_FILE(S["parallax"], parallax)
+ WRITE_FILE(S["menuoptions"], menuoptions)
+ WRITE_FILE(S["enable_tips"], enable_tips)
+ WRITE_FILE(S["tip_delay"], tip_delay)
//citadel code
S["arousable"] << arousable
@@ -273,7 +273,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot))
if(slot != default_slot)
default_slot = slot
- S["default_slot"] << slot
+ WRITE_FILE(S["default_slot"] , slot)
S.cd = "/character[slot]"
var/needs_update = savefile_needs_update(S)
@@ -292,7 +292,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pref_species = new rando_race()
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
- S["features["mcolor"]"] << "#FFF"
+ WRITE_FILE(S["features["mcolor"]"] , "#FFF")
//Character
S["OOC_Notes"] >> metadata
@@ -470,53 +470,53 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["version"] << SAVEFILE_VERSION_MAX //load_character will sanitize any bad data, so assume up-to-date.
//Character
- S["OOC_Notes"] << metadata
- S["real_name"] << real_name
- S["name_is_always_random"] << be_random_name
- S["body_is_always_random"] << be_random_body
- S["gender"] << gender
- S["age"] << age
- S["hair_color"] << hair_color
- S["facial_hair_color"] << facial_hair_color
- S["eye_color"] << eye_color
- S["skin_tone"] << skin_tone
- S["hair_style_name"] << hair_style
- S["facial_style_name"] << facial_hair_style
- S["underwear"] << underwear
- S["undershirt"] << undershirt
- S["socks"] << socks
- S["backbag"] << backbag
- S["uplink_loc"] << uplink_spawn_loc
- S["species"] << pref_species.id
- S["feature_mcolor"] << features["mcolor"]
- S["feature_lizard_tail"] << features["tail_lizard"]
- S["feature_human_tail"] << features["tail_human"]
- S["feature_lizard_snout"] << features["snout"]
- S["feature_lizard_horns"] << features["horns"]
- S["feature_human_ears"] << features["ears"]
- S["feature_lizard_frills"] << features["frills"]
- S["feature_lizard_spines"] << features["spines"]
- S["feature_lizard_body_markings"] << features["body_markings"]
- S["feature_lizard_legs"] << features["legs"]
- S["clown_name"] << custom_names["clown"]
- S["mime_name"] << custom_names["mime"]
- S["ai_name"] << custom_names["ai"]
- S["cyborg_name"] << custom_names["cyborg"]
- S["religion_name"] << custom_names["religion"]
- S["deity_name"] << custom_names["deity"]
- S["prefered_security_department"] << prefered_security_department
+ WRITE_FILE(S["OOC_Notes"] , metadata)
+ WRITE_FILE(S["real_name"] , real_name)
+ WRITE_FILE(S["name_is_always_random"] , be_random_name)
+ WRITE_FILE(S["body_is_always_random"] , be_random_body)
+ WRITE_FILE(S["gender"] , gender)
+ WRITE_FILE(S["age"] , age)
+ WRITE_FILE(S["hair_color"] , hair_color)
+ WRITE_FILE(S["facial_hair_color"] , facial_hair_color)
+ WRITE_FILE(S["eye_color"] , eye_color)
+ WRITE_FILE(S["skin_tone"] , skin_tone)
+ WRITE_FILE(S["hair_style_name"] , hair_style)
+ WRITE_FILE(S["facial_style_name"] , facial_hair_style)
+ WRITE_FILE(S["underwear"] , underwear)
+ WRITE_FILE(S["undershirt"] , undershirt)
+ WRITE_FILE(S["socks"] , socks)
+ WRITE_FILE(S["backbag"] , backbag)
+ WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
+ WRITE_FILE(S["species"] , pref_species.id)
+ WRITE_FILE(S["feature_mcolor"] , features["mcolor"])
+ WRITE_FILE(S["feature_lizard_tail"] , features["tail_lizard"])
+ WRITE_FILE(S["feature_human_tail"] , features["tail_human"])
+ WRITE_FILE(S["feature_lizard_snout"] , features["snout"])
+ WRITE_FILE(S["feature_lizard_horns"] , features["horns"])
+ WRITE_FILE(S["feature_human_ears"] , features["ears"])
+ WRITE_FILE(S["feature_lizard_frills"] , features["frills"])
+ WRITE_FILE(S["feature_lizard_spines"] , features["spines"])
+ WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"])
+ WRITE_FILE(S["feature_lizard_legs"] , features["legs"])
+ WRITE_FILE(S["clown_name"] , custom_names["clown"])
+ WRITE_FILE(S["mime_name"] , custom_names["mime"])
+ WRITE_FILE(S["ai_name"] , custom_names["ai"])
+ WRITE_FILE(S["cyborg_name"] , custom_names["cyborg"])
+ WRITE_FILE(S["religion_name"] , custom_names["religion"])
+ WRITE_FILE(S["deity_name"] , custom_names["deity"])
+ WRITE_FILE(S["prefered_security_department"] , prefered_security_department)
//Jobs
- S["joblessrole"] << joblessrole
- S["job_civilian_high"] << job_civilian_high
- S["job_civilian_med"] << job_civilian_med
- S["job_civilian_low"] << job_civilian_low
- S["job_medsci_high"] << job_medsci_high
- S["job_medsci_med"] << job_medsci_med
- S["job_medsci_low"] << job_medsci_low
- S["job_engsec_high"] << job_engsec_high
- S["job_engsec_med"] << job_engsec_med
- S["job_engsec_low"] << job_engsec_low
+ WRITE_FILE(S["joblessrole"] , joblessrole)
+ WRITE_FILE(S["job_civilian_high"] , job_civilian_high)
+ WRITE_FILE(S["job_civilian_med"] , job_civilian_med)
+ WRITE_FILE(S["job_civilian_low"] , job_civilian_low)
+ WRITE_FILE(S["job_medsci_high"] , job_medsci_high)
+ WRITE_FILE(S["job_medsci_med"] , job_medsci_med)
+ WRITE_FILE(S["job_medsci_low"] , job_medsci_low)
+ WRITE_FILE(S["job_engsec_high"] , job_engsec_high)
+ WRITE_FILE(S["job_engsec_med"] , job_engsec_med)
+ WRITE_FILE(S["job_engsec_low"] , job_engsec_low)
//Citadel
S["feature_exhibitionist"] << features["exhibitionist"]
diff --git a/code/modules/client/preferences_savefile.dm.rej b/code/modules/client/preferences_savefile.dm.rej
new file mode 100644
index 0000000000..3cdbf2cd44
--- /dev/null
+++ b/code/modules/client/preferences_savefile.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm (rejected hunks)
+@@ -193,7 +193,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
+ return 0
+ S.cd = "/"
+
+- WRITE_FILE(S["version"] , SAVEFILE_VERSION_MAX //updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date)
++ WRITE_FILE(S["version"] , SAVEFILE_VERSION_MAX) //updates (or failing that the sanity checks) will ensure data is not invalid at load. Assume up-to-date
+
+ //general preferences
+ WRITE_FILE(S["ooccolor"], ooccolor)
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index d56b6e0619..1d04964a8b 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -229,7 +229,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)()
set name = "Stop Sounds"
set category = "Preferences"
set desc = "Stop Current Sounds"
- usr << sound(null)
+ SEND_SOUND(usr, sound(null))
SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index bd6ffe5f67..bf34ee9f18 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -253,6 +253,7 @@ BLIND // can't see anything
slot_flags = SLOT_HEAD
var/blockTracking = 0 //For AI tracking
var/can_toggle = null
+ dynamic_hair_suffix = "+generic"
/obj/item/clothing/head/Initialize()
. = ..()
diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm
index 8ec8d00c77..67ce9ea370 100644
--- a/code/modules/clothing/head/collectable.dm
+++ b/code/modules/clothing/head/collectable.dm
@@ -14,6 +14,7 @@
name = "collectable slime cap!"
desc = "It just latches right in place!"
icon_state = "slime"
+ dynamic_hair_suffix = ""
/obj/item/clothing/head/collectable/xenom
name = "collectable xenomorph helmet!"
@@ -25,6 +26,7 @@
desc = "A rare chef's hat meant for hat collectors!"
icon_state = "chef"
item_state = "chef"
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/chef
@@ -53,6 +55,7 @@
name = "collectable police officer's hat"
desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
icon_state = "policehelm"
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/warden
@@ -95,6 +98,7 @@
desc = "The fur feels... a bit too realistic."
icon_state = "kitty"
item_state = "kitty"
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/kitty
@@ -103,6 +107,7 @@
desc = "Not as lucky as the feet!"
icon_state = "bunny"
item_state = "bunny"
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/rabbit
@@ -125,6 +130,7 @@
name = "collectable HoS hat"
desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!"
icon_state = "hoscap"
+ dynamic_hair_suffix = ""
/obj/item/clothing/head/collectable/HoP
name = "collectable HoP hat"
@@ -138,6 +144,7 @@
icon_state = "thunderdome"
item_state = "thunderdome"
resistance_flags = 0
+ flags_inv = HIDEHAIR
/obj/item/clothing/head/collectable/swat
name = "collectable SWAT helmet"
@@ -145,3 +152,4 @@
icon_state = "swat"
item_state = "swat"
resistance_flags = 0
+ flags_inv = HIDEHAIR
diff --git a/code/modules/clothing/head/collectable.dm.rej b/code/modules/clothing/head/collectable.dm.rej
new file mode 100644
index 0000000000..82a9962cb8
--- /dev/null
+++ b/code/modules/clothing/head/collectable.dm.rej
@@ -0,0 +1,9 @@
+diff a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm (rejected hunks)
+@@ -4,7 +4,6 @@
+ /obj/item/clothing/head/collectable
+ name = "collectable hat"
+ desc = "A rare collectable hat."
+- dynamic_hair_suffix = "+detective"
+
+
+ /obj/item/clothing/head/collectable/petehat
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 28fe8cacfb..6eefb458ed 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -10,6 +10,7 @@
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
resistance_flags = FIRE_PROOF
+ dynamic_hair_suffix = "+generic"
dog_fashion = /datum/dog_fashion/head
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index f100df4366..24d8049ac7 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -12,6 +12,7 @@
strip_delay = 60
resistance_flags = 0
flags_cover = HEADCOVERSEYES
+ flags_inv = HIDEHAIR
dog_fashion = /datum/dog_fashion/head/helmet
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 23b3da72ef..6a127f571b 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -7,6 +7,7 @@
desc = "The commander in chef's head wear."
strip_delay = 10
equip_delay_other = 10
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/chef
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
@@ -62,6 +63,7 @@
item_state = "cage"
worn_x_dimension = 64
worn_y_dimension = 64
+ dynamic_hair_suffix = ""
/obj/item/clothing/head/witchunter_hat
@@ -99,6 +101,7 @@
desc = "A beret, a mime's favorite headwear."
icon_state = "beret"
dog_fashion = /datum/dog_fashion/head/beret
+ dynamic_hair_suffix = ""
/obj/item/clothing/head/beret/black
name = "black beret"
@@ -118,6 +121,7 @@
icon_state = "hoscap"
armor = list(melee = 40, bullet = 30, laser = 25, energy = 10, bomb = 25, bio = 10, rad = 0, fire = 50, acid = 60)
strip_delay = 80
+ dynamic_hair_suffix = ""
/obj/item/clothing/head/HoS/syndicate
name = "syndicate cap"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 2c972ccc70..959c28d45e 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -1,287 +1,290 @@
-
-
-/obj/item/clothing/head/centhat
- name = "\improper CentCom hat"
- icon_state = "centcom"
- desc = "It's good to be emperor."
- item_state = "that"
- flags_inv = 0
- armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 50, acid = 50)
- strip_delay = 80
-
-/obj/item/clothing/head/powdered_wig
- name = "powdered wig"
- desc = "A powdered wig."
- icon_state = "pwig"
- item_state = "pwig"
-
-/obj/item/clothing/head/that
- name = "top-hat"
- desc = "It's an amish looking hat."
- icon_state = "tophat"
- item_state = "that"
- dog_fashion = /datum/dog_fashion/head
- throwforce = 1
-
-/obj/item/clothing/head/canada
- name = "striped red tophat"
- desc = "it smells like fresh donut holes / il sent comme des trous de beignets frais"
- icon_state = "canada"
- item_state = "canada"
-
-/obj/item/clothing/head/redcoat
- name = "redcoat's hat"
- icon_state = "redcoat"
- desc = "'I guess it's a redhead.'"
-
-/obj/item/clothing/head/mailman
- name = "mailman's hat"
- icon_state = "mailman"
- desc = "'Right-on-time' mail service head wear."
-
-/obj/item/clothing/head/plaguedoctorhat
- name = "plague doctor's hat"
- desc = "These were once used by plague doctors. They're pretty much useless."
- icon_state = "plaguedoctor"
- permeability_coefficient = 0.01
-
-/obj/item/clothing/head/hasturhood
- name = "hastur's hood"
- desc = "It's unspeakably stylish."
- icon_state = "hasturhood"
- flags_inv = HIDEHAIR
- flags_cover = HEADCOVERSEYES
-
-/obj/item/clothing/head/nursehat
- name = "nurse's hat"
- desc = "It allows quick identification of trained medical personnel."
- icon_state = "nursehat"
-
- dog_fashion = /datum/dog_fashion/head/nurse
-
-/obj/item/clothing/head/syndicatefake
- name = "black space-helmet replica"
- icon_state = "syndicate-helm-black-red"
- item_state = "syndicate-helm-black-red"
- desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!"
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/cueball
- name = "cueball helmet"
- desc = "A large, featureless white orb meant to be worn on your head. How do you even see out of this thing?"
- icon_state = "cueball"
- item_state="cueball"
- flags_cover = HEADCOVERSEYES|HEADCOVERSMOUTH
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/snowman
- name = "Snowman Head"
- desc = "A ball of white styrofoam. So festive."
- icon_state = "snowman_h"
- item_state = "snowman_h"
- flags_cover = HEADCOVERSEYES
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/justice
- name = "justice hat"
- desc = "Fight for what's righteous!"
- icon_state = "justicered"
- item_state = "justicered"
- flags_inv = HIDEHAIR|HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
- flags_cover = HEADCOVERSEYES
-
-/obj/item/clothing/head/justice/blue
- icon_state = "justiceblue"
- item_state = "justiceblue"
-
-/obj/item/clothing/head/justice/yellow
- icon_state = "justiceyellow"
- item_state = "justiceyellow"
-
-/obj/item/clothing/head/justice/green
- icon_state = "justicegreen"
- item_state = "justicegreen"
-
-/obj/item/clothing/head/justice/pink
- icon_state = "justicepink"
- item_state = "justicepink"
-
-/obj/item/clothing/head/rabbitears
- name = "rabbit ears"
- desc = "Wearing these makes you look useless, and only good for your sex appeal."
- icon_state = "bunny"
-
- dog_fashion = /datum/dog_fashion/head/rabbit
-
-
-/obj/item/clothing/head/flatcap
- name = "flat cap"
- desc = "A working man's cap."
- icon_state = "flat_cap"
- item_state = "detective"
-
-/obj/item/clothing/head/pirate
- name = "pirate hat"
- desc = "Yarr."
- icon_state = "pirate"
- item_state = "pirate"
- dog_fashion = /datum/dog_fashion/head/pirate
-
-/obj/item/clothing/head/pirate/captain
- icon_state = "hgpiratecap"
- item_state = "hgpiratecap"
-
-/obj/item/clothing/head/bandana
- name = "pirate bandana"
- desc = "Yarr."
- icon_state = "bandana"
- item_state = "bandana"
-
-/obj/item/clothing/head/bowler
- name = "bowler-hat"
- desc = "Gentleman, elite aboard!"
- icon_state = "bowler"
- item_state = "bowler"
-
-/obj/item/clothing/head/witchwig
- name = "witch costume wig"
- desc = "Eeeee~heheheheheheh!"
- icon_state = "witch"
- item_state = "witch"
- flags_inv = HIDEHAIR
-
-/obj/item/clothing/head/chicken
- name = "chicken suit head"
- desc = "Bkaw!"
- icon_state = "chickenhead"
- item_state = "chickensuit"
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/griffin
- name = "griffon head"
- desc = "Why not 'eagle head'? Who knows."
- icon_state = "griffinhat"
- item_state = "griffinhat"
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/bearpelt
- name = "bear pelt hat"
- desc = "Fuzzy."
- icon_state = "bearpelt"
- item_state = "bearpelt"
-
-/obj/item/clothing/head/xenos
- name = "xenos helmet"
- icon_state = "xenos"
- item_state = "xenos_helm"
- desc = "A helmet made out of chitinous alien hide."
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
-
-/obj/item/clothing/head/fedora
- name = "fedora"
- icon_state = "fedora"
- item_state = "fedora"
- armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50)
- desc = "A really cool hat if you're a mobster. A really lame hat if you're not."
- dynamic_hair_suffix = "+detective"
- pockets = /obj/item/weapon/storage/internal/pocket/small
-
-/obj/item/clothing/head/fedora/suicide_act(mob/user)
- if(user.gender == FEMALE)
- return 0
- var/mob/living/carbon/human/H = user
- user.visible_message("[user] is donning [src]! It looks like they're trying to be nice to girls.")
- user.say("M'lady.")
- sleep(10)
- H.facial_hair_style = "Neckbeard"
- return(BRUTELOSS)
-
-/obj/item/clothing/head/sombrero
- name = "sombrero"
- icon_state = "sombrero"
- item_state = "sombrero"
- desc = "You can practically taste the fiesta."
- flags_inv = HIDEHAIR
-
- dog_fashion = /datum/dog_fashion/head/sombrero
-
-/obj/item/clothing/head/sombrero/green
- name = "green sombrero"
- icon_state = "greensombrero"
- item_state = "greensombrero"
- desc = "As elegant as a dancing cactus."
- flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
- dog_fashion = null
-
-/obj/item/clothing/head/sombrero/shamebrero
- name = "shamebrero"
- icon_state = "shamebrero"
- item_state = "shamebrero"
- desc = "Once it's on, it never comes off."
- flags = NODROP
- dog_fashion = null
-
-/obj/item/clothing/head/cone
- desc = "This cone is trying to warn you of something!"
- name = "warning cone"
- icon = 'icons/obj/janitor.dmi'
- icon_state = "cone"
- item_state = "cone"
- force = 1
- throwforce = 3
- throw_speed = 2
- throw_range = 5
- w_class = WEIGHT_CLASS_SMALL
- attack_verb = list("warned", "cautioned", "smashed")
- resistance_flags = 0
-
-/obj/item/clothing/head/santa
- name = "santa hat"
- desc = "On the first day of christmas my employer gave to me!"
- icon_state = "santahatnorm"
- item_state = "that"
- cold_protection = HEAD
- min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
- dog_fashion = /datum/dog_fashion/head/santa
-
-/obj/item/clothing/head/jester
- name = "jester hat"
+/obj/item/clothing/head/centhat
+ name = "\improper Centcom hat"
+ icon_state = "centcom"
+ desc = "It's good to be emperor."
+ item_state = "that"
+ flags_inv = 0
+ armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 50, acid = 50)
+ strip_delay = 80
+
+/obj/item/clothing/head/powdered_wig
+ name = "powdered wig"
+ desc = "A powdered wig."
+ icon_state = "pwig"
+ item_state = "pwig"
+
+/obj/item/clothing/head/that
+ name = "top-hat"
+ desc = "It's an amish looking hat."
+ icon_state = "tophat"
+ item_state = "that"
+ dog_fashion = /datum/dog_fashion/head
+ throwforce = 1
+
+/obj/item/clothing/head/canada
+ name = "striped red tophat"
+ desc = "it smells like fresh donut holes / il sent comme des trous de beignets frais"
+ icon_state = "canada"
+ item_state = "canada"
+
+/obj/item/clothing/head/redcoat
+ name = "redcoat's hat"
+ icon_state = "redcoat"
+ desc = "'I guess it's a redhead.'"
+
+/obj/item/clothing/head/mailman
+ name = "mailman's hat"
+ icon_state = "mailman"
+ desc = "'Right-on-time' mail service head wear."
+
+/obj/item/clothing/head/plaguedoctorhat
+ name = "plague doctor's hat"
+ desc = "These were once used by plague doctors. They're pretty much useless."
+ icon_state = "plaguedoctor"
+ permeability_coefficient = 0.01
+
+/obj/item/clothing/head/hasturhood
+ name = "hastur's hood"
+ desc = "It's unspeakably stylish."
+ icon_state = "hasturhood"
+ flags_inv = HIDEHAIR
+ flags_cover = HEADCOVERSEYES
+
+/obj/item/clothing/head/nursehat
+ name = "nurse's hat"
+ desc = "It allows quick identification of trained medical personnel."
+ icon_state = "nursehat"
+ dynamic_hair_suffix = ""
+
+ dog_fashion = /datum/dog_fashion/head/nurse
+
+/obj/item/clothing/head/syndicatefake
+ name = "black space-helmet replica"
+ icon_state = "syndicate-helm-black-red"
+ item_state = "syndicate-helm-black-red"
+ desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!"
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/cueball
+ name = "cueball helmet"
+ desc = "A large, featureless white orb meant to be worn on your head. How do you even see out of this thing?"
+ icon_state = "cueball"
+ item_state="cueball"
+ flags_cover = HEADCOVERSEYES|HEADCOVERSMOUTH
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/snowman
+ name = "Snowman Head"
+ desc = "A ball of white styrofoam. So festive."
+ icon_state = "snowman_h"
+ item_state = "snowman_h"
+ flags_cover = HEADCOVERSEYES
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/justice
+ name = "justice hat"
+ desc = "Fight for what's righteous!"
+ icon_state = "justicered"
+ item_state = "justicered"
+ flags_inv = HIDEHAIR|HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
+ flags_cover = HEADCOVERSEYES
+
+/obj/item/clothing/head/justice/blue
+ icon_state = "justiceblue"
+ item_state = "justiceblue"
+
+/obj/item/clothing/head/justice/yellow
+ icon_state = "justiceyellow"
+ item_state = "justiceyellow"
+
+/obj/item/clothing/head/justice/green
+ icon_state = "justicegreen"
+ item_state = "justicegreen"
+
+/obj/item/clothing/head/justice/pink
+ icon_state = "justicepink"
+ item_state = "justicepink"
+
+/obj/item/clothing/head/rabbitears
+ name = "rabbit ears"
+ desc = "Wearing these makes you look useless, and only good for your sex appeal."
+ icon_state = "bunny"
+ dynamic_hair_suffix = ""
+
+ dog_fashion = /datum/dog_fashion/head/rabbit
+
+
+/obj/item/clothing/head/flatcap
+ name = "flat cap"
+ desc = "A working man's cap."
+ icon_state = "flat_cap"
+ item_state = "detective"
+
+/obj/item/clothing/head/pirate
+ name = "pirate hat"
+ desc = "Yarr."
+ icon_state = "pirate"
+ item_state = "pirate"
+ dog_fashion = /datum/dog_fashion/head/pirate
+
+/obj/item/clothing/head/pirate/captain
+ icon_state = "hgpiratecap"
+ item_state = "hgpiratecap"
+
+/obj/item/clothing/head/bandana
+ name = "pirate bandana"
+ desc = "Yarr."
+ icon_state = "bandana"
+ item_state = "bandana"
+ dynamic_hair_suffix = ""
+
+/obj/item/clothing/head/bowler
+ name = "bowler-hat"
+ desc = "Gentleman, elite aboard!"
+ icon_state = "bowler"
+ item_state = "bowler"
+ dynamic_hair_suffix = ""
+
+/obj/item/clothing/head/witchwig
+ name = "witch costume wig"
+ desc = "Eeeee~heheheheheheh!"
+ icon_state = "witch"
+ item_state = "witch"
+ flags_inv = HIDEHAIR
+
+/obj/item/clothing/head/chicken
+ name = "chicken suit head"
+ desc = "Bkaw!"
+ icon_state = "chickenhead"
+ item_state = "chickensuit"
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/griffin
+ name = "griffon head"
+ desc = "Why not 'eagle head'? Who knows."
+ icon_state = "griffinhat"
+ item_state = "griffinhat"
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/bearpelt
+ name = "bear pelt hat"
+ desc = "Fuzzy."
+ icon_state = "bearpelt"
+ item_state = "bearpelt"
+
+/obj/item/clothing/head/xenos
+ name = "xenos helmet"
+ icon_state = "xenos"
+ item_state = "xenos_helm"
+ desc = "A helmet made out of chitinous alien hide."
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+
+/obj/item/clothing/head/fedora
+ name = "fedora"
+ icon_state = "fedora"
+ item_state = "fedora"
+ armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50)
+ desc = "A really cool hat if you're a mobster. A really lame hat if you're not."
+ pockets = /obj/item/weapon/storage/internal/pocket/small
+
+/obj/item/clothing/head/fedora/suicide_act(mob/user)
+ if(user.gender == FEMALE)
+ return 0
+ var/mob/living/carbon/human/H = user
+ user.visible_message("[user] is donning [src]! It looks like they're trying to be nice to girls.")
+ user.say("M'lady.")
+ sleep(10)
+ H.facial_hair_style = "Neckbeard"
+ return(BRUTELOSS)
+
+/obj/item/clothing/head/sombrero
+ name = "sombrero"
+ icon_state = "sombrero"
+ item_state = "sombrero"
+ desc = "You can practically taste the fiesta."
+ flags_inv = HIDEHAIR
+
+ dog_fashion = /datum/dog_fashion/head/sombrero
+
+/obj/item/clothing/head/sombrero/green
+ name = "green sombrero"
+ icon_state = "greensombrero"
+ item_state = "greensombrero"
+ desc = "As elegant as a dancing cactus."
+ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
+ dog_fashion = null
+
+/obj/item/clothing/head/sombrero/shamebrero
+ name = "shamebrero"
+ icon_state = "shamebrero"
+ item_state = "shamebrero"
+ desc = "Once it's on, it never comes off."
+ flags = NODROP
+ dog_fashion = null
+
+/obj/item/clothing/head/cone
+ desc = "This cone is trying to warn you of something!"
+ name = "warning cone"
+ icon = 'icons/obj/janitor.dmi'
+ icon_state = "cone"
+ item_state = "cone"
+ force = 1
+ throwforce = 3
+ throw_speed = 2
+ throw_range = 5
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("warned", "cautioned", "smashed")
+ resistance_flags = 0
+
+/obj/item/clothing/head/santa
+ name = "santa hat"
+ desc = "On the first day of christmas my employer gave to me!"
+ icon_state = "santahatnorm"
+ item_state = "that"
+ cold_protection = HEAD
+ min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
+ dog_fashion = /datum/dog_fashion/head/santa
+
+/obj/item/clothing/head/jester
+ name = "jester hat"
desc = "A hat with bells, to add some merriness to the suit."
- icon_state = "jester_hat"
-
-/obj/item/clothing/head/rice_hat
- name = "rice hat"
- desc = "Welcome to the rice fields, motherfucker."
- icon_state = "rice_hat"
-
-/obj/item/clothing/head/lizard
- name = "lizardskin cloche hat"
- desc = "How many lizards died to make this hat? Not enough."
- icon_state = "lizard"
-
-/obj/item/clothing/head/papersack
- name = "paper sack hat"
- desc = "A paper sack with crude holes cut out for eyes. Useful for hiding one's identity or ugliness."
- icon_state = "papersack"
- flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
-
-/obj/item/clothing/head/papersack/smiley
- name = "paper sack hat"
- desc = "A paper sack with crude holes cut out for eyes and a sketchy smile drawn on the front. Not creepy at all."
- icon_state = "papersack_smile"
- flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
-
-/obj/item/clothing/head/crown
- name = "crown"
- desc = "A crown fit for a king, a petty king maybe."
- icon_state = "crown"
- armor = list(melee = 15, bullet = 0, laser = 0,energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
- resistance_flags = FIRE_PROOF
-
-/obj/item/clothing/head/crown/fancy
- name = "magnificent crown"
- desc = "A crown worn by only the highest emperors of the land."
- icon_state = "fancycrown"
+ icon_state = "jester_hat"
+ dynamic_hair_suffix = ""
+
+/obj/item/clothing/head/rice_hat
+ name = "rice hat"
+ desc = "Welcome to the rice fields, motherfucker."
+ icon_state = "rice_hat"
+
+/obj/item/clothing/head/lizard
+ name = "lizardskin cloche hat"
+ desc = "How many lizards died to make this hat? Not enough."
+ icon_state = "lizard"
+
+/obj/item/clothing/head/papersack
+ name = "paper sack hat"
+ desc = "A paper sack with crude holes cut out for eyes. Useful for hiding one's identity or ugliness."
+ icon_state = "papersack"
+ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
+
+/obj/item/clothing/head/papersack/smiley
+ name = "paper sack hat"
+ desc = "A paper sack with crude holes cut out for eyes and a sketchy smile drawn on the front. Not creepy at all."
+ icon_state = "papersack_smile"
+ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
+
+/obj/item/clothing/head/crown
+ name = "crown"
+ desc = "A crown fit for a king, a petty king maybe."
+ icon_state = "crown"
+ armor = list(melee = 15, bullet = 0, laser = 0,energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
+ resistance_flags = FIRE_PROOF
+ dynamic_hair_suffix = ""
+
+/obj/item/clothing/head/crown/fancy
+ name = "magnificent crown"
+ desc = "A crown worn by only the highest emperors of the land."
+ icon_state = "fancycrown"
/obj/item/clothing/head/scarecrow_hat
name = "scarecrow hat"
@@ -297,4 +300,5 @@
/obj/item/clothing/head/jester/alt
name = "jester hat"
desc = "A hat with bells, to add some merriness to the suit."
- icon_state = "jester_hat2"
\ No newline at end of file
+ icon_state = "jester_hat2"
+ dynamic_hair_suffix = ""
diff --git a/code/modules/clothing/head/misc.dm.rej b/code/modules/clothing/head/misc.dm.rej
new file mode 100644
index 0000000000..df85f74b20
--- /dev/null
+++ b/code/modules/clothing/head/misc.dm.rej
@@ -0,0 +1,16 @@
+diff a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm (rejected hunks)
+@@ -250,7 +250,7 @@
+ name = "jester hat"
+ desc = "A hat with bells, to add some merriness to the suit."
+ icon_state = "jester_hat"
+- dynamic_hair_suffix = "null"
++ dynamic_hair_suffix = ""
+
+ /obj/item/clothing/head/rice_hat
+ name = "rice hat"
+@@ -302,4 +302,4 @@
+ name = "jester hat"
+ desc = "A hat with bells, to add some merriness to the suit."
+ icon_state = "jester_hat2"
+- dynamic_hair_suffix = "null"
++ dynamic_hair_suffix = ""
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 4c14fc0422..d15c7dd5f4 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -125,6 +125,7 @@
desc = "A pair of kitty ears. Meow!"
icon_state = "kitty"
color = "#999999"
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/kitty
@@ -150,6 +151,7 @@
flags_inv = 0
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
brightness_on = 1 //luminosity when on
+ dynamic_hair_suffix = ""
dog_fashion = /datum/dog_fashion/head/reindeer
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index 66b62d3a67..abdb42d5b3 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -338,7 +338,7 @@
name = "Death Commando"
uniform = /obj/item/clothing/under/color/green
- suit = /obj/item/clothing/suit/space/hardsuit/shielded/swat
+ suit = /obj/item/clothing/suit/space/hardsuit/deathsquad
shoes = /obj/item/clothing/shoes/combat/swat
gloves = /obj/item/clothing/gloves/combat
mask = /obj/item/clothing/mask/gas/sechailer/swat
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 4dcc0207b9..7f8be87a2e 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -200,7 +200,7 @@
item_color = "mining"
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
- heat_protection = CHEST|GROIN|LEGS|ARMS
+ heat_protection = HEAD
armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50, fire = 50, acid = 75)
brightness_on = 7
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank/internals, /obj/item/weapon/resonator, /obj/item/device/mining_scanner, /obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/gun/energy/kinetic_accelerator)
@@ -216,6 +216,7 @@
armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50, fire = 50, acid = 75)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank/internals, /obj/item/weapon/storage/bag/ore, /obj/item/weapon/pickaxe)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining
+ heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
//Syndicate hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/syndi
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index 1ab499fcb5..6c91fee8c5 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -17,19 +17,16 @@
if(M.wear_suit)
fibertext = "Material from \a [M.wear_suit]."
if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & CHEST))
if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
- //world.log << "Added fibertext: [fibertext]"
suit_fibers += fibertext
if(!(M.wear_suit.body_parts_covered & HANDS))
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
suit_fibers += fibertext
else if(M.w_uniform)
fibertext = "Fibers from \a [M.w_uniform]."
@@ -39,12 +36,10 @@
if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
suit_fibers += "Material from a pair of [M.gloves.name]."
else if(M.gloves)
fibertext = "Material from a pair of [M.gloves.name]."
if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- //world.log << "Added fibertext: [fibertext]"
suit_fibers += "Material from a pair of [M.gloves.name]."
diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm
index e2cce14db3..93605ea78a 100644
--- a/code/modules/error_handler/error_handler.dm
+++ b/code/modules/error_handler/error_handler.dm
@@ -55,7 +55,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
var/skipcount = abs(error_cooldown[erroruid]) - 1
error_cooldown[erroruid] = 0
if(skipcount > 0)
- world.log << "\[[time_stamp()]] Skipped [skipcount] runtimes in [E.file],[E.line]."
+ SEND_TEXT(world.log, "\[[time_stamp()]] Skipped [skipcount] runtimes in [E.file],[E.line].")
GLOB.error_cache.log_error(E, skip_count = skipcount)
error_last_seen[erroruid] = world.time
@@ -92,9 +92,9 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
if(GLOB.error_cache)
GLOB.error_cache.log_error(E, desclines)
- world.log << "\[[time_stamp()]] Runtime in [E.file],[E.line]: [E]"
+ SEND_TEXT(world.log, "\[[time_stamp()]] Runtime in [E.file],[E.line]: [E]")
for(var/line in desclines)
- world.log << line
+ SEND_TEXT(world.log, line)
/* This logs the runtime in the old format */
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index 8f634003f5..1386995c28 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -70,7 +70,7 @@
if(!H.client || !istype(H))
return
to_chat(H, "Honk...")
- H << 'sound/spookoween/scary_clown_appear.ogg'
+ SEND_SOUND(H, sound('sound/spookoween/scary_clown_appear.ogg'))
var/turf/T = get_turf(H)
if(T)
new /obj/effect/hallucination/simple/clown(T, H, 50)
diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm
index 888b87cc02..9658d8b144 100644
--- a/code/modules/events/portal_storm.dm
+++ b/code/modules/events/portal_storm.dm
@@ -68,11 +68,11 @@
/datum/round_event/portal_storm/announce()
set waitfor = 0
- playsound_global('sound/magic/lightning_chargeup.ogg', repeat=0, channel=1, volume=100)
+ sound_to_playing_players('sound/magic/lightning_chargeup.ogg')
sleep(80)
priority_announce("Massive bluespace anomaly detected en route to [station_name()]. Brace for impact.")
sleep(20)
- playsound_global('sound/magic/lightningbolt.ogg', repeat=0, channel=1, volume=100)
+ sound_to_playing_players('sound/magic/lightningbolt.ogg')
/datum/round_event/portal_storm/tick()
spawn_effects()
diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm
index f6ffab2da8..3dee4a1f49 100644
--- a/code/modules/events/wizard/fakeexplosion.dm
+++ b/code/modules/events/wizard/fakeexplosion.dm
@@ -6,6 +6,5 @@
earliest_start = 0
/datum/round_event/wizard/fake_explosion/start()
- for(var/mob/M in GLOB.player_list)
- M << 'sound/machines/alarm.ogg'
+ sound_to_playing_players('sound/machines/alarm.ogg')
addtimer(CALLBACK(SSticker, /datum/controller/subsystem/ticker/.proc/station_explosion_cinematic, 1, "fake"), 100) //:o)
\ No newline at end of file
diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm
index ffec648771..1ba052c4c0 100644
--- a/code/modules/events/wizard/imposter.dm
+++ b/code/modules/events/wizard/imposter.dm
@@ -55,4 +55,4 @@
I.log_message("Is an imposter!", INDIVIDUAL_ATTACK_LOG)
to_chat(I, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!")
- I << sound('sound/effects/magic.ogg')
+ SEND_SOUND(I, sound('sound/effects/magic.ogg'))
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index c1b0a387e4..2b8fe4b064 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -11,51 +11,83 @@ Gunshots/explosions/opening doors/less rare audio (done)
*/
+#define HAL_LINES_FILE "hallucination.json"
+
/mob/living/carbon
var/image/halimage
var/image/halbody
var/obj/halitem
var/hal_screwyhud = SCREWYHUD_NONE
- var/handling_hal = 0
+ var/next_hallucination = 0
+
+GLOBAL_LIST_INIT(hallucinations_minor, list(
+ /datum/hallucination/sounds,
+ /datum/hallucination/bolts,
+ /datum/hallucination/whispers,
+ /datum/hallucination/message,
+ /datum/hallucination/hudscrew))
+
+GLOBAL_LIST_INIT(hallucinations_medium, list(
+ /datum/hallucination/fake_alert,
+ /datum/hallucination/items,
+ /datum/hallucination/items_other,
+ /datum/hallucination/dangerflash,
+ /datum/hallucination/bolts,
+ /datum/hallucination/fake_flood,
+ /datum/hallucination/husks,
+ /datum/hallucination/battle,
+ /datum/hallucination/fire,
+ /datum/hallucination/self_delusion))
+
+GLOBAL_LIST_INIT(hallucinations_major, list(
+ /datum/hallucination/fakeattacker,
+ /datum/hallucination/death,
+ /datum/hallucination/xeno_attack,
+ /datum/hallucination/singularity_scare,
+ /datum/hallucination/delusion,
+ /datum/hallucination/oh_yeah))
/mob/living/carbon/proc/handle_hallucinations()
- if(handling_hal)
+ if(world.time < next_hallucination)
return
- //Least obvious
- var/list/minor = list("sounds"=25,"bolts_minor"=5,"whispers"=15,"message"=10,"hudscrew"=15)
- //Something's wrong here
- var/list/medium = list("fake_alert"=15,"items"=10,"items_other"=10,"dangerflash"=10,"bolts"=5,"flood"=5,"husks"=10,"battle"=15,"self_delusion"=10)
- //AAAAH
- var/list/major = list("fake"=20,"death"=10,"xeno"=10,"singulo"=10,"borer"=10,"delusion"=20,"koolaid"=10)
+ if(hallucination)
+ var/list/current = GLOB.hallucinations_minor
+ if(prob(25) && hallucination > 100)
+ current = GLOB.hallucinations_medium
+ else if(prob(10) && hallucination > 200)
+ current = GLOB.hallucinations_major
+ var/halpick = pick(current)
+ new halpick(src, FALSE)
- handling_hal = 1
- while(hallucination > 20)
- sleep(rand(200,500)/(hallucination/25))
- if(prob(20))
- continue
- var/list/current = list()
- switch(rand(100))
- if(1 to 50)
- current = minor
- if(51 to 85)
- current = medium
- if(86 to 100)
- current = major
+/mob/living/carbon/proc/set_screwyhud(hud_type)
+ hal_screwyhud = hud_type
+ update_health_hud()
- var/halpick = pickweight(current)
+/datum/hallucination
+ var/mob/living/carbon/target
+ var/cost = 5 //affects the amount of hallucination reduced, and cooldown until the next hallucination
+ var/feedback_details //extra info for investigate
- hallucinate(halpick)
- handling_hal = 0
+/datum/hallucination/New(mob/living/carbon/T, forced = TRUE)
+ set waitfor = 0
+ target = T
+ if(!forced)
+ target.hallucination = max(0, target.hallucination - cost)
+ target.next_hallucination = world.time + (rand(cost * 0.5, cost * 3) * 10)
+
+/datum/hallucination/proc/wake_and_restore()
+ target.set_screwyhud(SCREWYHUD_NONE)
+ target.SetSleeping(0)
+
+/datum/hallucination/Destroy()
+ target.investigate_log("was afflicted with a hallucination of type [type]. [feedback_details]", INVESTIGATE_HALLUCINATIONS)
+ return ..()
/obj/effect/hallucination
invisibility = INVISIBILITY_OBSERVER
var/mob/living/carbon/target = null
-/obj/effect/hallucination/proc/wake_and_restore()
- target.hal_screwyhud = SCREWYHUD_NONE
- target.SetSleeping(0)
-
/obj/effect/hallucination/simple
var/image_icon = 'icons/mob/alien.dmi'
var/image_state = "alienh_pounce"
@@ -64,13 +96,14 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/col_mod = null
var/image/current_image = null
var/image_layer = MOB_LAYER
- var/active = 1 //qdelery
+ var/active = TRUE //qdelery
/obj/effect/hallucination/simple/Initialize(mapload, var/mob/living/carbon/T)
..()
target = T
current_image = GetImage()
- if(target.client) target.client.images |= current_image
+ if(target.client)
+ target.client.images |= current_image
/obj/effect/hallucination/simple/proc/GetImage()
var/image/I = image(image_icon,src,image_state,image_layer,dir=src.dir)
@@ -82,10 +115,12 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/hallucination/simple/proc/Show(update=1)
if(active)
- if(target.client) target.client.images.Remove(current_image)
+ if(target.client)
+ target.client.images.Remove(current_image)
if(update)
current_image = GetImage()
- if(target.client) target.client.images |= current_image
+ if(target.client)
+ target.client.images |= current_image
/obj/effect/hallucination/simple/update_icon(new_state,new_icon,new_px=0,new_py=0)
image_state = new_state
@@ -101,36 +136,39 @@ Gunshots/explosions/opening doors/less rare audio (done)
Show()
/obj/effect/hallucination/simple/Destroy()
- if(target.client) target.client.images.Remove(current_image)
- active = 0
+ if(target.client)
+ target.client.images.Remove(current_image)
+ active = FALSE
return ..()
#define FAKE_FLOOD_EXPAND_TIME 20
#define FAKE_FLOOD_MAX_RADIUS 10
-/obj/effect/hallucination/fake_flood
+/datum/hallucination/fake_flood
//Plasma starts flooding from the nearby vent
+ var/turf/center
var/list/flood_images = list()
var/list/turf/flood_turfs = list()
var/image_icon = 'icons/effects/tile_effects.dmi'
var/image_state = "plasma"
var/radius = 0
var/next_expand = 0
+ cost = 25
-/obj/effect/hallucination/fake_flood/Initialize(mapload, var/mob/living/carbon/T)
+/datum/hallucination/fake_flood/New(mob/living/carbon/T, forced = TRUE)
..()
- target = T
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in orange(7,target))
if(!U.welded)
- src.loc = U.loc
+ center = get_turf(U)
break
- flood_images += image(image_icon,src,image_state,MOB_LAYER)
- flood_turfs += get_turf(src.loc)
+ feedback_details += "Vent Coords: [center.x],[center.y],[center.z]"
+ flood_images += image(image_icon,center,image_state,MOB_LAYER)
+ flood_turfs += center
if(target.client) target.client.images |= flood_images
next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
START_PROCESSING(SSobj, src)
-/obj/effect/hallucination/fake_flood/process()
+/datum/hallucination/fake_flood/process()
if(next_expand <= world.time)
radius++
if(radius > FAKE_FLOOD_MAX_RADIUS)
@@ -138,10 +176,10 @@ Gunshots/explosions/opening doors/less rare audio (done)
return
Expand()
if((get_turf(target) in flood_turfs) && !target.internal)
- target.hallucinate("fake_alert", "tox_in_air")
+ new /datum/hallucination/fake_alert(target, TRUE, "tox_in_air")
next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
-/obj/effect/hallucination/fake_flood/proc/Expand()
+/datum/hallucination/fake_flood/proc/Expand()
for(var/turf/FT in flood_turfs)
for(var/dir in GLOB.cardinals)
var/turf/T = get_step(FT, dir)
@@ -152,7 +190,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
if(target.client)
target.client.images |= flood_images
-/obj/effect/hallucination/fake_flood/Destroy()
+/datum/hallucination/fake_flood/Destroy()
STOP_PROCESSING(SSobj, src)
qdel(flood_turfs)
flood_turfs = list()
@@ -167,7 +205,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
image_icon = 'icons/mob/alien.dmi'
image_state = "alienh_pounce"
-/obj/effect/hallucination/simple/xeno/Initialize(mapload, var/mob/living/carbon/T)
+/obj/effect/hallucination/simple/xeno/Initialize(mapload, mob/living/carbon/T)
..()
name = "alien hunter ([rand(1, 1000)])"
@@ -177,18 +215,19 @@ Gunshots/explosions/opening doors/less rare audio (done)
target.Knockdown(100)
target.visible_message("[target] flails around wildly.","[name] pounces on you!")
-/obj/effect/hallucination/xeno_attack
+/datum/hallucination/xeno_attack
//Xeno crawls from nearby vent,jumps at you, and goes back in
var/obj/machinery/atmospherics/components/unary/vent_pump/pump = null
var/obj/effect/hallucination/simple/xeno/xeno = null
+ cost = 25
-/obj/effect/hallucination/xeno_attack/Initialize(mapload, var/mob/living/carbon/T)
+/datum/hallucination/xeno_attack/New(mob/living/carbon/T, forced = TRUE)
..()
- target = T
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in orange(7,target))
if(!U.welded)
pump = U
break
+ feedback_details += "Vent Coords: [pump.x],[pump.y],[pump.z]"
if(pump)
xeno = new(pump.loc,target)
sleep(10)
@@ -200,7 +239,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
sleep(10)
var/xeno_name = xeno.name
to_chat(target, "[xeno_name] begins climbing into the ventilation system...")
- sleep(10)
+ sleep(30)
qdel(xeno)
to_chat(target, "[xeno_name] scrambles into the ventilation ducts!")
qdel(src)
@@ -209,7 +248,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
image_icon = 'icons/mob/animal.dmi'
image_state = "clown"
-/obj/effect/hallucination/simple/clown/Initialize(mapload, var/mob/living/carbon/T,duration)
+/obj/effect/hallucination/simple/clown/Initialize(mapload, mob/living/carbon/T, duration)
..(loc, T)
name = pick(GLOB.clown_names)
QDEL_IN(src,duration)
@@ -217,59 +256,27 @@ Gunshots/explosions/opening doors/less rare audio (done)
/obj/effect/hallucination/simple/clown/scary
image_state = "scary_clown"
-/obj/effect/hallucination/simple/borer
- image_icon = 'icons/mob/borer.dmi'
- image_state = "brainslug"
-
-/obj/effect/hallucination/borer
- //A borer unconsciouss you and crawls in your ear
- var/obj/machinery/atmospherics/components/unary/vent_pump/pump = null
- var/obj/effect/hallucination/simple/borer/borer = null
-
-/obj/effect/hallucination/borer/Initialize(mapload, var/mob/living/carbon/T)
- ..()
- target = T
- for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in orange(7,target))
- if(!U.welded)
- pump = U
- break
- if(pump)
- borer = new(pump.loc,target)
- for(var/i=0, i<11, i++)
- walk_to(borer, get_step(borer, get_cardinal_dir(borer, T)))
- if(borer.Adjacent(T))
- to_chat(T, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
- T.Stun(80)
- sleep(50)
- qdel(borer)
- sleep(rand(60, 90))
- to_chat(T, "Primary [rand(1000,9999)] states: [pick("Hello","Hi","You're my slave now!","Don't try to get rid of me...")]")
- break
- sleep(4)
- if(!QDELETED(borer))
- qdel(borer)
- qdel(src)
-
/obj/effect/hallucination/simple/bubblegum
name = "Bubblegum"
image_icon = 'icons/mob/lavaland/96x96megafauna.dmi'
image_state = "bubblegum"
px = -32
-/obj/effect/hallucination/oh_yeah
+/datum/hallucination/oh_yeah
var/obj/effect/hallucination/simple/bubblegum/bubblegum
var/image/fakebroken
var/image/fakerune
+ cost = 75
-/obj/effect/hallucination/oh_yeah/Initialize(mapload, var/mob/living/carbon/T)
+/datum/hallucination/oh_yeah/New(mob/living/carbon/T, forced = TRUE)
. = ..()
- target = T
var/turf/closed/wall/wall
for(var/turf/closed/wall/W in range(7,target))
wall = W
break
if(!wall)
return INITIALIZE_HINT_QDEL
+ feedback_details += "Source: [wall.x],[wall.y],[wall.z]"
fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER)
var/turf/landing = get_turf(target)
@@ -283,7 +290,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
bubblegum = new(wall, target)
addtimer(CALLBACK(src, .proc/bubble_attack, landing), 10)
-/obj/effect/hallucination/oh_yeah/proc/bubble_attack(turf/landing)
+/datum/hallucination/oh_yeah/proc/bubble_attack(turf/landing)
var/charged = FALSE //only get hit once
while(get_turf(bubblegum) != landing && target && target.stat != DEAD)
bubblegum.forceMove(get_step_towards(bubblegum, landing))
@@ -301,7 +308,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
sleep(30)
qdel(src)
-/obj/effect/hallucination/oh_yeah/Destroy()
+/datum/hallucination/oh_yeah/Destroy()
if(target.client)
target.client.images.Remove(fakebroken)
target.client.images.Remove(fakerune)
@@ -310,23 +317,24 @@ Gunshots/explosions/opening doors/less rare audio (done)
QDEL_NULL(bubblegum)
return ..()
-/obj/effect/hallucination/singularity_scare
+/datum/hallucination/singularity_scare
//Singularity moving towards you.
//todo Hide where it moved with fake space images
var/obj/effect/hallucination/simple/singularity/s = null
+ cost = 75
-/obj/effect/hallucination/singularity_scare/Initialize(mapload, var/mob/living/carbon/T)
+/datum/hallucination/singularity_scare/New(mob/living/carbon/T, forced = TRUE)
..()
- target = T
var/turf/start = get_turf(T)
var/screen_border = pick(SOUTH,EAST,WEST,NORTH)
- for(var/i = 0,i<11,i++)
+ for(var/i in 1 to 13)
start = get_step(start,screen_border)
+ feedback_details += "Source: [start.x],[start.y],[start.z]"
s = new(start,target)
s.parent = src
- for(var/i = 0,i<11,i++)
- sleep(5)
- s.loc = get_step(get_turf(s),get_dir(s,target))
+ for(var/i in 1 to 13)
+ sleep(10)
+ s.forceMove(get_step(get_turf(s),get_dir(s,target)))
s.Show()
s.Eat()
qdel(s)
@@ -337,64 +345,72 @@ Gunshots/explosions/opening doors/less rare audio (done)
image_layer = MASSIVE_OBJ_LAYER
px = -96
py = -96
- var/obj/effect/hallucination/singularity_scare/parent
+ var/datum/hallucination/singularity_scare/parent
/obj/effect/hallucination/simple/singularity/proc/Eat(atom/OldLoc, Dir)
var/target_dist = get_dist(src,target)
if(target_dist<=3) //"Eaten"
- target.hal_screwyhud = SCREWYHUD_CRIT
+ target.set_screwyhud(SCREWYHUD_DEAD)
target.SetUnconscious(160)
- addtimer(CALLBACK(parent, .proc/wake_and_restore), rand(30, 50))
+ addtimer(CALLBACK(parent, /datum/hallucination/.proc/wake_and_restore), rand(30, 50))
-/obj/effect/hallucination/battle
+/datum/hallucination/battle
+ cost = 15
-/obj/effect/hallucination/battle/Initialize(mapload, var/mob/living/carbon/T)
+/datum/hallucination/battle/New(mob/living/carbon/T, forced = TRUE, battle_type)
..()
- target = T
var/hits = rand(3,6)
- switch(rand(1,5))
- if(1) //Laser fight
- for(var/i=0,i