From 81476df8260546e6f9603ba7a9aa7f89d6d4d1ea Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 23 Dec 2019 17:38:18 +0100 Subject: [PATCH 001/151] Added more options --- SQL/paradise_schema.sql | 3 ++- SQL/paradise_schema_prefixed.sql | 3 ++- SQL/updates/9-10.sql | 6 ++++++ code/controllers/configuration.dm | 8 +------- code/controllers/subsystem/afk.dm | 19 +++++++++--------- code/modules/client/preference/preferences.dm | 20 ++++++++++++++++--- .../client/preference/preferences_mysql.dm | 14 ++++++++----- config/example/config.txt | 8 +------- config/example/dbconfig.txt | 2 +- 9 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 SQL/updates/9-10.sql diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 1e4692b7e3b..4162607d7c4 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -268,7 +268,8 @@ CREATE TABLE `player` ( `atklog` smallint(4) DEFAULT '0', `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', - `afk_watch` tinyint(1) NOT NULL DEFAULT '0', + `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', + `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index aa5d5895e56..af36f520cd9 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -267,7 +267,8 @@ CREATE TABLE `SS13_player` ( `atklog` smallint(4) DEFAULT '0', `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', - `afk_watch` tinyint(1) NOT NULL DEFAULT '0', + `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', + `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql new file mode 100644 index 00000000000..cb2c9c79279 --- /dev/null +++ b/SQL/updates/9-10.sql @@ -0,0 +1,6 @@ +# Change afk_watch to AFK_WATCH_warn_minutes and AFK_WATCH_cryo_minutes which gives users the option to make use of the AFK watcher subsystem +ALTER TABLE `player` ADD `AFK_WATCH_warn_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `afk_watch`; +UPDATE `player` SET `AFK_WATCH_warn_minutes` = 5 WHERE `afk_watch` = 1; +ALTER TABLE `player` ADD `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `AFK_WATCH_warn_minutes`; +UPDATE `player` SET `AFK_WATCH_cryo_minutes` = 2 WHERE `afk_watch` = 1; +ALTER TABLE `player` DROP COLUMN `afk_watch`; \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 8ae35d52179..497bcefd4f4 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -72,9 +72,7 @@ var/assistantlimit = 0 //enables assistant limiting var/assistantratio = 2 //how many assistants to security members - // The AFK subsystem will not be activated if any of the below config values are equal or less than 0 - var/warn_afk_minimum = 0 // How long till you get a warning while being AFK - var/auto_cryo_afk = 0 // How long till you get put into cryo when you're AFK + // The AFK subsystem will not be activated if the below config values are equal or less than 0 var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic) var/auto_cryo_ssd_mins = 0 @@ -318,10 +316,6 @@ if("shadowling_max_age") config.shadowling_max_age = text2num(value) - if("warn_afk_minimum") - config.warn_afk_minimum = text2num(value) - if("auto_cryo_afk") - config.auto_cryo_afk = text2num(value) if("auto_despawn_afk") config.auto_despawn_afk = text2num(value) diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 9f409fd35b4..4a092f3fed4 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(afk) /datum/controller/subsystem/afk/Initialize() - if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0) + if(config.auto_despawn_afk <= 0) flags |= SS_NO_FIRE /datum/controller/subsystem/afk/fire() @@ -19,28 +19,29 @@ SUBSYSTEM_DEF(afk) continue var/turf/T + var/afk_warn_min // Only players and players with the AFK watch enabled // No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags - if(!H.client || !H.client.prefs.afk_watch || !H.mind || \ + if(!H.client || !(afk_warn_min = H.client.prefs.AFK_WATCH_warn_minutes) || !H.mind || \ H.stat || H.restrained() || !H.job || H.mind.special_role || \ !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization if(afk_players[H.ckey]) toRemove += H.ckey continue - + var/mins_afk = round(H.client.inactivity / 600) - if(mins_afk < config.warn_afk_minimum) + if(mins_afk < afk_warn_min) if(afk_players[H.ckey]) toRemove += H.ckey continue - + var/afk_cryo_min = H.client.prefs.AFK_WATCH_cryo_minutes + afk_warn_min if(!afk_players[H.ckey]) afk_players[H.ckey] = AFK_WARNED - warn(H, "You are AFK for [mins_afk] minutes. You will be cryod after [config.auto_cryo_afk] total minutes and fully despawned after [config.auto_despawn_afk] total minutes. Please move or click in game if you want to avoid being despawned.") + warn(H, "You are AFK for [mins_afk] minutes. You will be cryod after [afk_cryo_min] total minutes and fully despawned after another [config.auto_despawn_afk] minutes. Please move or click in game if you want to avoid being despawned.") else var/area/A = T.loc // Turfs loc is the area if(afk_players[H.ckey] == AFK_WARNED) - if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod) + if(mins_afk >= afk_cryo_min && A.can_get_auto_cryod) if(A.fast_despawn) toRemove += H.ckey warn(H, "You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.") @@ -49,9 +50,9 @@ SUBSYSTEM_DEF(afk) else if(cryo_ssd(H)) afk_players[H.ckey] = AFK_CRYOD msg_admins(H, mins_afk, T, "put into cryostorage") - warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for [config.auto_despawn_afk] total minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.") + warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.") - else if(mins_afk >= config.auto_despawn_afk) + else if(mins_afk >= config.auto_despawn_afk + afk_cryo_min) var/obj/machinery/cryopod/P = H.loc msg_admins(H, mins_afk, T, "forcefully despawned") warn(H, "You are have been despawned after being AFK for [mins_afk] minutes.") diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 11eb454a241..0eb93a7404b 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -93,7 +93,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/clientfps = 0 var/atklog = ATKLOG_ALL var/fuid // forum userid - var/afk_watch = FALSE // If the player wants to be kept track of by the AFK system + var/AFK_WATCH_warn_minutes = 0 // Number of minutes after which the player gets warned + var/AFK_WATCH_cryo_minutes = 0 // Number of minutes after (after the warning) which the player gets cryod //ghostly preferences var/ghost_anonsay = 0 @@ -442,7 +443,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "

General Settings

" if(user.client.holder) dat += "Adminhelp sound: [(sound & SOUND_ADMINHELP)?"On":"Off"]
" - dat += "AFK Cryoing: [(afk_watch) ? "Yes" : "No"]
" + dat += "AFK Cryoing: [(AFK_WATCH_warn_minutes) ? "On ([AFK_WATCH_warn_minutes], [AFK_WATCH_cryo_minutes])" : "Off"]
" + dat += "Ambient Occlusion: [toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]
" dat += "Attack Animations: [(show_ghostitem_attack) ? "Yes" : "No"]
" if(unlock_content) @@ -2000,7 +2002,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts windowflashing = !windowflashing if("afk_watch") - afk_watch = !afk_watch + var/afk_new = input(user, "Select a new amount of minutes after which you get warned for being AFK, between 0 and 10 (0 will deactivate)", UI_style_alpha) as num + if(afk_new == 0) + // deactivate the system + AFK_WATCH_warn_minutes = 0 + AFK_WATCH_cryo_minutes = 0 + else + if(!afk_new | !(afk_new <= 10 && afk_new >= 1)) return + AFK_WATCH_warn_minutes = afk_new + afk_new = input(user, "Select a new amount of minutes after which you get cryod for being AFK, between 1 and 5", UI_style_alpha) as num + if(!afk_new | !(afk_new <= 5 && afk_new >= 1)) + AFK_WATCH_cryo_minutes = AFK_WATCH_cryo_minutes ? AFK_WATCH_cryo_minutes : 2 // Return to prior value or default to 2 + else + AFK_WATCH_cryo_minutes = afk_new if("UIcolor") var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 6090538f2b3..20fe3514c8d 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -20,7 +20,8 @@ clientfps, atklog, fuid, - afk_watch, + AFK_WATCH_warn_minutes, + AFK_WATCH_cryo_minutes, parallax FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} @@ -54,8 +55,9 @@ clientfps = text2num(query.item[17]) atklog = text2num(query.item[18]) fuid = text2num(query.item[19]) - afk_watch = text2num(query.item[20]) - parallax = text2num(query.item[21]) + AFK_WATCH_warn_minutes = text2num(query.item[20]) + AFK_WATCH_cryo_minutes = text2num(query.item[21]) + parallax = text2num(query.item[22]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -76,7 +78,8 @@ clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps)) atklog = sanitize_integer(atklog, 0, 100, initial(atklog)) fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid)) - afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch)) + AFK_WATCH_warn_minutes = sanitize_integer(AFK_WATCH_warn_minutes, 0, 10, initial(AFK_WATCH_warn_minutes)) + AFK_WATCH_cryo_minutes = sanitize_integer(AFK_WATCH_cryo_minutes, 0, 5, initial(AFK_WATCH_cryo_minutes)) parallax = sanitize_integer(parallax, 0, 16, initial(parallax)) return 1 @@ -108,7 +111,8 @@ ghost_anonsay='[ghost_anonsay]', clientfps='[clientfps]', atklog='[atklog]', - afk_watch='[afk_watch]', + AFK_WATCH_warn_minutes='[AFK_WATCH_warn_minutes]', + AFK_WATCH_cryo_minutes='[AFK_WATCH_cryo_minutes]', parallax='[parallax]' WHERE ckey='[C.ckey]'"} ) diff --git a/config/example/config.txt b/config/example/config.txt index 7dfdc1e413a..dbf7b0be050 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -88,13 +88,7 @@ LOG_ADMINWARN ## Amount of minutes that a person has to be AFK before he'll be listed on the "List AFK players" verb #LIST_AFK_MINIMUM 5 -## Amount of minutes that a person has to be AFK before he will be warned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating -WARN_AFK_MINIMUM 0 - -## Amount of minutes that a person has to be AFK before he will be cryod by the AFK subsystem. Leave this 0 to prevent the subsystem from activating -AUTO_CRYO_AFK 0 - -## Amount of minutes that a person has to be AFK before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating +## Number of minutes that a person has to be AFK in the cryo tubes before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating AUTO_DESPAWN_AFK 0 ## probablities for game modes chosen in "secret" and "random" modes diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index ad859d92543..654a7e348d5 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -9,7 +9,7 @@ ## This value must be set to the version of the paradise schema in use. ## If this value does not match, the SQL database will not be loaded and an error will be generated. ## Roundstart will be delayed. -DB_VERSION 9 +DB_VERSION 10 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. From 377ae7671bfadf043aad8bbc247080c83b86350d Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 23 Dec 2019 19:29:23 +0100 Subject: [PATCH 002/151] Added the abitility to turn the AFK system on when you're antag --- SQL/paradise_schema.sql | 1 + SQL/paradise_schema_prefixed.sql | 1 + SQL/updates/9-10.sql | 3 ++- code/controllers/configuration.dm | 2 +- code/controllers/subsystem/afk.dm | 4 ++-- code/modules/client/preference/preferences.dm | 6 +++++- code/modules/client/preference/preferences_mysql.dm | 6 +++++- 7 files changed, 17 insertions(+), 6 deletions(-) diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 4162607d7c4..316330eca41 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -270,6 +270,7 @@ CREATE TABLE `player` ( `fupdate` smallint(4) NULL DEFAULT '0', `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', + 'AFK_WATCH_antag' tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index af36f520cd9..94d34935d99 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -269,6 +269,7 @@ CREATE TABLE `SS13_player` ( `fupdate` smallint(4) NULL DEFAULT '0', `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', + 'AFK_WATCH_antag' tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql index cb2c9c79279..88e3ebda2b5 100644 --- a/SQL/updates/9-10.sql +++ b/SQL/updates/9-10.sql @@ -1,6 +1,7 @@ -# Change afk_watch to AFK_WATCH_warn_minutes and AFK_WATCH_cryo_minutes which gives users the option to make use of the AFK watcher subsystem +# Change afk_watch to AFK_WATCH_warn_minutes, AFK_WATCH_cryo_minutes and AFK_WATCH_antag which gives users the option to make use of the AFK watcher subsystem ALTER TABLE `player` ADD `AFK_WATCH_warn_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `afk_watch`; UPDATE `player` SET `AFK_WATCH_warn_minutes` = 5 WHERE `afk_watch` = 1; ALTER TABLE `player` ADD `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `AFK_WATCH_warn_minutes`; UPDATE `player` SET `AFK_WATCH_cryo_minutes` = 2 WHERE `afk_watch` = 1; +ALTER TABLE `player` ADD `AFK_WATCH_antag` tinyint(1) NOT NULL DEFAULT '0' AFTER `AFK_WATCH_cryo_minutes`; ALTER TABLE `player` DROP COLUMN `afk_watch`; \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 497bcefd4f4..4a60f8d7438 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -72,7 +72,7 @@ var/assistantlimit = 0 //enables assistant limiting var/assistantratio = 2 //how many assistants to security members - // The AFK subsystem will not be activated if the below config values are equal or less than 0 + // The AFK subsystem will not be activated if the below config value is equal or less than 0 var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic) var/auto_cryo_ssd_mins = 0 diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 4a092f3fed4..94e2de34b2a 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -21,9 +21,9 @@ SUBSYSTEM_DEF(afk) var/turf/T var/afk_warn_min // Only players and players with the AFK watch enabled - // No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags + // No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags (if they have the preference option off) if(!H.client || !(afk_warn_min = H.client.prefs.AFK_WATCH_warn_minutes) || !H.mind || \ - H.stat || H.restrained() || !H.job || H.mind.special_role || \ + H.stat || H.restrained() || !H.job || (H.mind.special_role && !H.client.prefs.AFK_WATCH_antag) || \ !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization if(afk_players[H.ckey]) toRemove += H.ckey diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 0eb93a7404b..6559a808c41 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -95,6 +95,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/fuid // forum userid var/AFK_WATCH_warn_minutes = 0 // Number of minutes after which the player gets warned var/AFK_WATCH_cryo_minutes = 0 // Number of minutes after (after the warning) which the player gets cryod + var/AFK_WATCH_antag = FALSE // If you will cryo when you have a special role //ghostly preferences var/ghost_anonsay = 0 @@ -443,7 +444,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "

General Settings

" if(user.client.holder) dat += "Adminhelp sound: [(sound & SOUND_ADMINHELP)?"On":"Off"]
" - dat += "AFK Cryoing: [(AFK_WATCH_warn_minutes) ? "On ([AFK_WATCH_warn_minutes], [AFK_WATCH_cryo_minutes])" : "Off"]
" + dat += "AFK Cryoing: [(AFK_WATCH_warn_minutes) ? "On ([AFK_WATCH_warn_minutes], [AFK_WATCH_cryo_minutes], [AFK_WATCH_antag ? "Y" : "N"])" : "Off"]
" dat += "Ambient Occlusion: [toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]
" dat += "Attack Animations: [(show_ghostitem_attack) ? "Yes" : "No"]
" @@ -2007,14 +2008,17 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts // deactivate the system AFK_WATCH_warn_minutes = 0 AFK_WATCH_cryo_minutes = 0 + AFK_WATCH_antag = FALSE else if(!afk_new | !(afk_new <= 10 && afk_new >= 1)) return AFK_WATCH_warn_minutes = afk_new afk_new = input(user, "Select a new amount of minutes after which you get cryod for being AFK, between 1 and 5", UI_style_alpha) as num if(!afk_new | !(afk_new <= 5 && afk_new >= 1)) AFK_WATCH_cryo_minutes = AFK_WATCH_cryo_minutes ? AFK_WATCH_cryo_minutes : 2 // Return to prior value or default to 2 + AFK_WATCH_antag = AFK_WATCH_antag ? AFK_WATCH_antag : FALSE else AFK_WATCH_cryo_minutes = afk_new + AFK_WATCH_antag = alert(user, "Do you want to activate the AFK system when you have a special status? (Think of antag, mindslaved, ERT etc)", "Antag activation", "Yes", "No") == "Yes" if("UIcolor") var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 20fe3514c8d..14055980620 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -22,6 +22,7 @@ fuid, AFK_WATCH_warn_minutes, AFK_WATCH_cryo_minutes, + AFK_WATCH_antag, parallax FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} @@ -57,7 +58,8 @@ fuid = text2num(query.item[19]) AFK_WATCH_warn_minutes = text2num(query.item[20]) AFK_WATCH_cryo_minutes = text2num(query.item[21]) - parallax = text2num(query.item[22]) + AFK_WATCH_antag = text2num(query.item[22]) + parallax = text2num(query.item[23]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -80,6 +82,7 @@ fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid)) AFK_WATCH_warn_minutes = sanitize_integer(AFK_WATCH_warn_minutes, 0, 10, initial(AFK_WATCH_warn_minutes)) AFK_WATCH_cryo_minutes = sanitize_integer(AFK_WATCH_cryo_minutes, 0, 5, initial(AFK_WATCH_cryo_minutes)) + AFK_WATCH_antag = sanitize_integer(AFK_WATCH_antag, 0, 1, initial(AFK_WATCH_antag)) parallax = sanitize_integer(parallax, 0, 16, initial(parallax)) return 1 @@ -113,6 +116,7 @@ atklog='[atklog]', AFK_WATCH_warn_minutes='[AFK_WATCH_warn_minutes]', AFK_WATCH_cryo_minutes='[AFK_WATCH_cryo_minutes]', + AFK_WATCH_antag='[AFK_WATCH_antag]', parallax='[parallax]' WHERE ckey='[C.ckey]'"} ) From 14242045eca71ea0ca74456c14c5e80765555494 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Tue, 24 Dec 2019 11:39:53 +0100 Subject: [PATCH 003/151] Rework AFK system after discussing with head --- SQL/paradise_schema.sql | 4 +- SQL/paradise_schema_prefixed.sql | 4 +- SQL/updates/9-10.sql | 7 --- code/controllers/configuration.dm | 10 +++- code/controllers/subsystem/afk.dm | 55 ++++++++++++------- code/modules/client/preference/preferences.dm | 25 ++------- .../client/preference/preferences_mysql.dm | 18 ++---- config/example/config.txt | 8 ++- 8 files changed, 62 insertions(+), 69 deletions(-) delete mode 100644 SQL/updates/9-10.sql diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 316330eca41..1e4692b7e3b 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -268,9 +268,7 @@ CREATE TABLE `player` ( `atklog` smallint(4) DEFAULT '0', `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', - `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', - `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', - 'AFK_WATCH_antag' tinyint(1) NOT NULL DEFAULT '0', + `afk_watch` tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index 94d34935d99..aa5d5895e56 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -267,9 +267,7 @@ CREATE TABLE `SS13_player` ( `atklog` smallint(4) DEFAULT '0', `fuid` bigint(20) NULL DEFAULT NULL, `fupdate` smallint(4) NULL DEFAULT '0', - `AFK_WATCH_warn_minutes` tinyint(2) NOT NULL DEFAULT '0', - `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0', - 'AFK_WATCH_antag' tinyint(1) NOT NULL DEFAULT '0', + `afk_watch` tinyint(1) NOT NULL DEFAULT '0', `parallax` tinyint(1) DEFAULT '8', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql deleted file mode 100644 index 88e3ebda2b5..00000000000 --- a/SQL/updates/9-10.sql +++ /dev/null @@ -1,7 +0,0 @@ -# Change afk_watch to AFK_WATCH_warn_minutes, AFK_WATCH_cryo_minutes and AFK_WATCH_antag which gives users the option to make use of the AFK watcher subsystem -ALTER TABLE `player` ADD `AFK_WATCH_warn_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `afk_watch`; -UPDATE `player` SET `AFK_WATCH_warn_minutes` = 5 WHERE `afk_watch` = 1; -ALTER TABLE `player` ADD `AFK_WATCH_cryo_minutes` tinyint(1) NOT NULL DEFAULT '0' AFTER `AFK_WATCH_warn_minutes`; -UPDATE `player` SET `AFK_WATCH_cryo_minutes` = 2 WHERE `afk_watch` = 1; -ALTER TABLE `player` ADD `AFK_WATCH_antag` tinyint(1) NOT NULL DEFAULT '0' AFTER `AFK_WATCH_cryo_minutes`; -ALTER TABLE `player` DROP COLUMN `afk_watch`; \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 4a60f8d7438..10dbb653453 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -72,7 +72,9 @@ var/assistantlimit = 0 //enables assistant limiting var/assistantratio = 2 //how many assistants to security members - // The AFK subsystem will not be activated if the below config value is equal or less than 0 + // The AFK subsystem will not be activated if any of the below config values are equal or less than 0 + var/warn_afk_minimum = 0 // How long till you get a warning while being AFK + var/auto_cryo_afk = 0 // How long till you get put into cryo when you're AFK var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic) var/auto_cryo_ssd_mins = 0 @@ -315,7 +317,11 @@ if("shadowling_max_age") config.shadowling_max_age = text2num(value) - + + if("warn_afk_minimum") + config.warn_afk_minimum = text2num(value) + if("auto_cryo_afk") + config.auto_cryo_afk = text2num(value) if("auto_despawn_afk") config.auto_despawn_afk = text2num(value) diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 94e2de34b2a..13c843b75dd 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -1,15 +1,22 @@ -#define AFK_WARNED 1 -#define AFK_CRYOD 2 +#define AFK_WARNED 1 +#define AFK_CRYOD 2 +#define AFK_ADMINS_WARNED 2 + +#define AFK_FAST_CRYO_WARN 3 +#define AFK_FAST_CRYO_CRYO 5 SUBSYSTEM_DEF(afk) name = "AFK Watcher" wait = 300 flags = SS_BACKGROUND var/list/afk_players = list() // Associative list. ckey as key and AFK state as value + var/list/non_cryo_antags = list( \ + SPECIAL_ROLE_ABDUCTOR_AGENT, SPECIAL_ROLE_ABDUCTOR_SCIENTIST, \ + SPECIAL_ROLE_SHADOWLING, SPECIAL_ROLE_WIZARD, SPECIAL_ROLE_WIZARD_APPRENTICE, SPECIAL_ROLE_NUKEOPS) /datum/controller/subsystem/afk/Initialize() - if(config.auto_despawn_afk <= 0) + if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0) flags |= SS_NO_FIRE /datum/controller/subsystem/afk/fire() @@ -19,22 +26,22 @@ SUBSYSTEM_DEF(afk) continue var/turf/T - var/afk_warn_min - // Only players and players with the AFK watch enabled - // No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags (if they have the preference option off) - if(!H.client || !(afk_warn_min = H.client.prefs.AFK_WATCH_warn_minutes) || !H.mind || \ - H.stat || H.restrained() || !H.job || (H.mind.special_role && !H.client.prefs.AFK_WATCH_antag) || \ - !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization + // Only players who have a mind + // No dead, unconcious, restrained, people without jobs, people on other Z levels than the station + if(!H.client || !H.mind || H.stat || H.restrained() || \ + !H.job || !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization if(afk_players[H.ckey]) toRemove += H.ckey continue var/mins_afk = round(H.client.inactivity / 600) + var/afk_warn_min = H.client.prefs.afk_fast_cryo ? AFK_FAST_CRYO_WARN : config.warn_afk_minimum if(mins_afk < afk_warn_min) if(afk_players[H.ckey]) toRemove += H.ckey continue - var/afk_cryo_min = H.client.prefs.AFK_WATCH_cryo_minutes + afk_warn_min + + var/afk_cryo_min = H.client.prefs.afk_fast_cryo ? AFK_FAST_CRYO_CRYO : config.auto_cryo_afk if(!afk_players[H.ckey]) afk_players[H.ckey] = AFK_WARNED warn(H, "You are AFK for [mins_afk] minutes. You will be cryod after [afk_cryo_min] total minutes and fully despawned after another [config.auto_despawn_afk] minutes. Please move or click in game if you want to avoid being despawned.") @@ -45,16 +52,21 @@ SUBSYSTEM_DEF(afk) if(A.fast_despawn) toRemove += H.ckey warn(H, "You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.") - msg_admins(H, mins_afk, T, "forcefully despawned", "AFK in a fast despawn area") + log_admins(H, mins_afk, T, "despawned", "AFK in a fast despawn area") force_cryo_human(H) - else if(cryo_ssd(H)) - afk_players[H.ckey] = AFK_CRYOD - msg_admins(H, mins_afk, T, "put into cryostorage") - warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.") + else + if(can_cryo_antag(H)) + if(cryo_ssd(H)) + afk_players[H.ckey] = AFK_CRYOD + log_admins(H, mins_afk, T, "put into cryostorage") + warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.") + else + message_admins("[key_name_admin(H)] at ([get_area(T).name] [ADMIN_JMP(T)]) is AFK for [mins_afk] and can't be cryod due to it's antag status: ([H.mind.special_role]).") + afk_players[H.ckey] = AFK_ADMINS_WARNED else if(mins_afk >= config.auto_despawn_afk + afk_cryo_min) var/obj/machinery/cryopod/P = H.loc - msg_admins(H, mins_afk, T, "forcefully despawned") + log_admins(H, mins_afk, T, "despawned") warn(H, "You are have been despawned after being AFK for [mins_afk] minutes.") toRemove += H.ckey P.despawn_occupant() @@ -67,9 +79,11 @@ SUBSYSTEM_DEF(afk) if(H.client) window_flash(H.client) -/datum/controller/subsystem/afk/proc/msg_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info) +/datum/controller/subsystem/afk/proc/can_cryo_antag(mob/living/carbon/human/H) + return !(H.mind.special_role in non_cryo_antags) + +/datum/controller/subsystem/afk/proc/log_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info) log_admin("[key_name(H)] has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]") - message_admins("[key_name_admin(H)] at ([get_area(location).name] [ADMIN_JMP(location)]) has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]") /datum/controller/subsystem/afk/proc/removeFromWatchList(list/toRemove) for(var/C in toRemove) @@ -79,4 +93,7 @@ SUBSYSTEM_DEF(afk) break #undef AFK_WARNED -#undef AFK_CRYOD \ No newline at end of file +#undef AFK_CRYOD +#undef AFK_ADMINS_WARNED +#undef AFK_FAST_CRYO_WARN +#undef AFK_FAST_CRYO_CRYO \ No newline at end of file diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 6559a808c41..2ba3580980f 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -93,9 +93,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/clientfps = 0 var/atklog = ATKLOG_ALL var/fuid // forum userid - var/AFK_WATCH_warn_minutes = 0 // Number of minutes after which the player gets warned - var/AFK_WATCH_cryo_minutes = 0 // Number of minutes after (after the warning) which the player gets cryod - var/AFK_WATCH_antag = FALSE // If you will cryo when you have a special role + var/afk_fast_cryo = FALSE // If they want to be put into cryo the fast way by the AFK subsystem //ghostly preferences var/ghost_anonsay = 0 @@ -444,7 +442,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "

General Settings

" if(user.client.holder) dat += "Adminhelp sound: [(sound & SOUND_ADMINHELP)?"On":"Off"]
" - dat += "AFK Cryoing: [(AFK_WATCH_warn_minutes) ? "On ([AFK_WATCH_warn_minutes], [AFK_WATCH_cryo_minutes], [AFK_WATCH_antag ? "Y" : "N"])" : "Off"]
" + dat += "AFK Fast Cryoing: [(afk_fast_cryo) ? "On" : "Off"]
" dat += "Ambient Occlusion: [toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]
" dat += "Attack Animations: [(show_ghostitem_attack) ? "Yes" : "No"]
" @@ -2002,23 +2000,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("winflash") windowflashing = !windowflashing - if("afk_watch") - var/afk_new = input(user, "Select a new amount of minutes after which you get warned for being AFK, between 0 and 10 (0 will deactivate)", UI_style_alpha) as num - if(afk_new == 0) - // deactivate the system - AFK_WATCH_warn_minutes = 0 - AFK_WATCH_cryo_minutes = 0 - AFK_WATCH_antag = FALSE - else - if(!afk_new | !(afk_new <= 10 && afk_new >= 1)) return - AFK_WATCH_warn_minutes = afk_new - afk_new = input(user, "Select a new amount of minutes after which you get cryod for being AFK, between 1 and 5", UI_style_alpha) as num - if(!afk_new | !(afk_new <= 5 && afk_new >= 1)) - AFK_WATCH_cryo_minutes = AFK_WATCH_cryo_minutes ? AFK_WATCH_cryo_minutes : 2 // Return to prior value or default to 2 - AFK_WATCH_antag = AFK_WATCH_antag ? AFK_WATCH_antag : FALSE - else - AFK_WATCH_cryo_minutes = afk_new - AFK_WATCH_antag = alert(user, "Do you want to activate the AFK system when you have a special status? (Think of antag, mindslaved, ERT etc)", "Antag activation", "Yes", "No") == "Yes" + if("afk_fast_cryo") + afk_fast_cryo = alert(user, "Would you like to be qualified for the fast cryoing? Being AFK for 5 minutes will result in cryoing then (instead of [config.auto_cryo_afk])", "Fast cryoing", "Yes", "No") == "Yes" if("UIcolor") var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 14055980620..2a30c3dd359 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -20,9 +20,7 @@ clientfps, atklog, fuid, - AFK_WATCH_warn_minutes, - AFK_WATCH_cryo_minutes, - AFK_WATCH_antag, + afk_watch, parallax FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} @@ -56,10 +54,8 @@ clientfps = text2num(query.item[17]) atklog = text2num(query.item[18]) fuid = text2num(query.item[19]) - AFK_WATCH_warn_minutes = text2num(query.item[20]) - AFK_WATCH_cryo_minutes = text2num(query.item[21]) - AFK_WATCH_antag = text2num(query.item[22]) - parallax = text2num(query.item[23]) + afk_fast_cryo = text2num(query.item[20]) + parallax = text2num(query.item[21]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -80,9 +76,7 @@ clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps)) atklog = sanitize_integer(atklog, 0, 100, initial(atklog)) fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid)) - AFK_WATCH_warn_minutes = sanitize_integer(AFK_WATCH_warn_minutes, 0, 10, initial(AFK_WATCH_warn_minutes)) - AFK_WATCH_cryo_minutes = sanitize_integer(AFK_WATCH_cryo_minutes, 0, 5, initial(AFK_WATCH_cryo_minutes)) - AFK_WATCH_antag = sanitize_integer(AFK_WATCH_antag, 0, 1, initial(AFK_WATCH_antag)) + afk_fast_cryo = sanitize_integer(afk_fast_cryo, 0, 1, initial(afk_fast_cryo)) parallax = sanitize_integer(parallax, 0, 16, initial(parallax)) return 1 @@ -114,9 +108,7 @@ ghost_anonsay='[ghost_anonsay]', clientfps='[clientfps]', atklog='[atklog]', - AFK_WATCH_warn_minutes='[AFK_WATCH_warn_minutes]', - AFK_WATCH_cryo_minutes='[AFK_WATCH_cryo_minutes]', - AFK_WATCH_antag='[AFK_WATCH_antag]', + afk_watch='[afk_fast_cryo]', parallax='[parallax]' WHERE ckey='[C.ckey]'"} ) diff --git a/config/example/config.txt b/config/example/config.txt index dbf7b0be050..865a95fb307 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -88,7 +88,13 @@ LOG_ADMINWARN ## Amount of minutes that a person has to be AFK before he'll be listed on the "List AFK players" verb #LIST_AFK_MINIMUM 5 -## Number of minutes that a person has to be AFK in the cryo tubes before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating +## Amount of minutes that a person has to be AFK before he will be warned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating. With fast cryoing this will be 3 minutes +WARN_AFK_MINIMUM 0 + +## Amount of minutes that a person has to be AFK before he will be cryod by the AFK subsystem. Leave this 0 to prevent the subsystem from activating. With fast cryoing this will be 5 minutes +AUTO_CRYO_AFK 0 + +## Amount of minutes that a person has to be AFK before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating. This is the timer after they get put into cryo AUTO_DESPAWN_AFK 0 ## probablities for game modes chosen in "secret" and "random" modes From c4614e1bb981d1c6c941867902ded829a5988e7b Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Tue, 24 Dec 2019 11:44:32 +0100 Subject: [PATCH 004/151] Cleanup --- code/controllers/configuration.dm | 2 +- code/controllers/subsystem/afk.dm | 4 ++-- code/modules/client/preference/preferences.dm | 1 - config/example/dbconfig.txt | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 10dbb653453..8ae35d52179 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -317,7 +317,7 @@ if("shadowling_max_age") config.shadowling_max_age = text2num(value) - + if("warn_afk_minimum") config.warn_afk_minimum = text2num(value) if("auto_cryo_afk") diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 13c843b75dd..6aefb4b28f7 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -33,14 +33,14 @@ SUBSYSTEM_DEF(afk) if(afk_players[H.ckey]) toRemove += H.ckey continue - + var/mins_afk = round(H.client.inactivity / 600) var/afk_warn_min = H.client.prefs.afk_fast_cryo ? AFK_FAST_CRYO_WARN : config.warn_afk_minimum if(mins_afk < afk_warn_min) if(afk_players[H.ckey]) toRemove += H.ckey continue - + var/afk_cryo_min = H.client.prefs.afk_fast_cryo ? AFK_FAST_CRYO_CRYO : config.auto_cryo_afk if(!afk_players[H.ckey]) afk_players[H.ckey] = AFK_WARNED diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 2ba3580980f..56f7dcd4107 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -443,7 +443,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(user.client.holder) dat += "Adminhelp sound: [(sound & SOUND_ADMINHELP)?"On":"Off"]
" dat += "AFK Fast Cryoing: [(afk_fast_cryo) ? "On" : "Off"]
" - dat += "Ambient Occlusion: [toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]
" dat += "Attack Animations: [(show_ghostitem_attack) ? "Yes" : "No"]
" if(unlock_content) diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index 654a7e348d5..ad859d92543 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -9,7 +9,7 @@ ## This value must be set to the version of the paradise schema in use. ## If this value does not match, the SQL database will not be loaded and an error will be generated. ## Roundstart will be delayed. -DB_VERSION 10 +DB_VERSION 9 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. From 3f89a00415a7753c093d8274f6776d77d3844aaa Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 9 Jan 2020 17:59:34 +1100 Subject: [PATCH 005/151] Adds IPC plushie and toast, toast is made via IPC plushie. --- code/game/objects/items/toys.dm | 13 ++++++++++++ .../food_and_drinks/food/foods/bread.dm | 19 ++++++++++++++++++ icons/obj/food/food.dmi | Bin 97979 -> 98385 bytes icons/obj/toy.dmi | Bin 77735 -> 78263 bytes 4 files changed, 32 insertions(+) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 0ad64e24f23..66f5ebbf874 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1085,6 +1085,19 @@ obj/item/toy/cards/deck/syndicate/black return ..() +/obj/item/toy/plushie/ipcplushie + name = "ipc plushie" + desc = "An adorable ipc plushie, straight from New Canaan. Arguably more durable than the real deal. Toaster functionality included." + icon_state = "plushie_ipc" + item_state = "plushie_ipc" + +/obj/item/toy/plushie/ipcplushie/attackby(obj/item/B, mob/user, params) + if(istype(B, /obj/item/reagent_containers/food/snacks/breadslice)) + new /obj/item/reagent_containers/food/snacks/toast(get_turf(loc)) + to_chat(user, " You insert bread into the toaster. ") + playsound(loc, 'sound/machines/ding.ogg', 50, 1) + qdel(B) + //New generation TG plushies /obj/item/toy/plushie/lizardplushie diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm index d888a532c01..e26a45ca88b 100644 --- a/code/modules/food_and_drinks/food/foods/bread.dm +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -166,6 +166,23 @@ list_reagents = list("nutriment" = 2, "vitamin" = 2) tastes = list("bread" = 2) +/obj/item/reagent_containers/food/snacks/toast + name = "Toast" + desc = "Yeah! Toast!" + icon_state = "toast" + filling_color = "#B2580E" + bitesize = 3 + list_reagents = list("nutriment" = 3) + tastes = list("toast" = 2) + + /*name = "Toast" + desc = "Yeah! Toast!" + icon_state = "toast" + filling_color = "#b2580e" + bitesize = 3 + list_reagents = list("nutriment" = 3) + tastes = list("toast" = 2)*/ + /obj/item/reagent_containers/food/snacks/jelliedtoast name = "Jellied Toast" desc = "A slice of bread covered with delicious jam." @@ -198,3 +215,5 @@ trash = /obj/item/trash/waffles filling_color = "#E6DEB5" list_reagents = list("nutriment" = 8, "vitamin" = 1) + + diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index aea237f5bed3be518b1bbceef927798252caaf94..fdd520c1b145359ebde99d91706c5f0f3975d49a 100644 GIT binary patch delta 7915 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 UWAN_<(9NTx@mRf9)h6oy08Lt!bpQYW diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 511b578ad4a29b89a1ae13de6c8aeda120ee1540..1ef7016307de59d80f1054b932a070b35c98960f 100644 GIT binary patch delta 18760 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 delta 18228 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 e6ciem{|EdI;1Li(u~^Rl0000 Date: Fri, 10 Jan 2020 13:44:46 +1100 Subject: [PATCH 006/151] made IPC capital, added return statement, and deleted usless taost comment. --- code/game/objects/items/toys.dm | 4 +++- code/modules/food_and_drinks/food/foods/bread.dm | 8 -------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 66f5ebbf874..e414eb3d53c 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1086,7 +1086,7 @@ obj/item/toy/cards/deck/syndicate/black ..() /obj/item/toy/plushie/ipcplushie - name = "ipc plushie" + name = "IPC plushie" desc = "An adorable ipc plushie, straight from New Canaan. Arguably more durable than the real deal. Toaster functionality included." icon_state = "plushie_ipc" item_state = "plushie_ipc" @@ -1097,6 +1097,8 @@ obj/item/toy/cards/deck/syndicate/black to_chat(user, " You insert bread into the toaster. ") playsound(loc, 'sound/machines/ding.ogg', 50, 1) qdel(B) + else + return ..() //New generation TG plushies diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm index e26a45ca88b..55255658233 100644 --- a/code/modules/food_and_drinks/food/foods/bread.dm +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -174,14 +174,6 @@ bitesize = 3 list_reagents = list("nutriment" = 3) tastes = list("toast" = 2) - - /*name = "Toast" - desc = "Yeah! Toast!" - icon_state = "toast" - filling_color = "#b2580e" - bitesize = 3 - list_reagents = list("nutriment" = 3) - tastes = list("toast" = 2)*/ /obj/item/reagent_containers/food/snacks/jelliedtoast name = "Jellied Toast" From f13d1adeb5d30e64f4351ffa2cfdd78f431b3123 Mon Sep 17 00:00:00 2001 From: AzuleUtama <44248086+AzuleUtama@users.noreply.github.com> Date: Fri, 24 Apr 2020 19:26:06 +0100 Subject: [PATCH 007/151] Buffs gygax deflect, power and equipment --- code/game/mecha/combat/gygax.dm | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index d9ec4412ab3..78e4da1b773 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -39,7 +39,7 @@ icon_state = "darkgygax" initial_icon = "darkgygax" max_integrity = 300 - deflect_chance = 15 + deflect_chance = 20 armor = list(melee = 40, bullet = 40, laser = 50, energy = 35, bomb = 20, bio = 0, rad =20, fire = 100, acid = 100) max_temperature = 35000 leg_overload_coeff = 100 @@ -50,16 +50,24 @@ starting_voice = /obj/item/mecha_modkit/voice/syndicate destruction_sleep_duration = 1 +/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) + . = ..() + thrusters_action.Grant(user, src) + +/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) + . = ..() + thrusters_action.Remove(user) + /obj/mecha/combat/gygax/dark/loaded/New() ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang + ME = new /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter/precise + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay ME.attach(src) /obj/mecha/combat/gygax/dark/add_cell() - cell = new /obj/item/stock_parts/cell/hyper(src) + cell = new /obj/item/stock_parts/cell/bluespace(src) From d677c9d0a3a564768fc55600434f5b7cffcaf33b Mon Sep 17 00:00:00 2001 From: AzuleUtama <44248086+AzuleUtama@users.noreply.github.com> Date: Sat, 25 Apr 2020 02:35:59 +0100 Subject: [PATCH 008/151] Fixed thrustors --- code/game/mecha/combat/gygax.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 78e4da1b773..0898936cbfb 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -54,7 +54,7 @@ . = ..() thrusters_action.Grant(user, src) -/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) +/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) . = ..() thrusters_action.Remove(user) From e2d046ee6f8483d029b8ef406cf6464e8ef09e4a Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Mar 2020 11:48:11 -0500 Subject: [PATCH 009/151] code refactor/cleanup --- .../game/objects/structures/tank_dispenser.dm | 99 +++++++++++-------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 854bc18ce00..4d9f82abbbd 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -5,28 +5,40 @@ icon_state = "dispenser" density = 1 anchored = 1.0 - var/oxygentanks = 10 - var/plasmatanks = 10 - var/list/oxytanks = list() //sorry for the similar var names - var/list/platanks = list() + var/starting_oxygen_tanks = 10 // The starting amount of oxygen tanks the dispenser gets when it's spawned + var/starting_plasma_tanks = 10 // Starting amount of plasma tanks + var/list/stored_oxygen_tanks = list() // List of currently stored oxygen tanks + var/list/stored_plasma_tanks = list() // And plasma tanks /obj/structure/dispenser/oxygen - plasmatanks = 0 + starting_plasma_tanks = 0 /obj/structure/dispenser/plasma - oxygentanks = 0 + starting_oxygen_tanks = 0 /obj/structure/dispenser/New() ..() + initialize_tanks() update_icon() +/obj/structure/dispenser/proc/initialize_tanks() + for(var/I in 1 to starting_plasma_tanks) + var/obj/item/tank/plasma/P = new(src) + stored_plasma_tanks.Add(P) + + for(var/I in 1 to starting_oxygen_tanks) + var/obj/item/tank/oxygen/O = new(src) + stored_oxygen_tanks.Add(O) + /obj/structure/dispenser/update_icon() overlays.Cut() - switch(oxygentanks) - if(1 to 3) overlays += "oxygen-[oxygentanks]" + var/oxy_tank_amount = stored_oxygen_tanks.len + switch(oxy_tank_amount) + if(1 to 3) overlays += "oxygen-[oxy_tank_amount]" if(4 to INFINITY) overlays += "oxygen-4" - switch(plasmatanks) - if(1 to 4) overlays += "plasma-[plasmatanks]" + var/pla_tank_amount = stored_plasma_tanks.len + switch(pla_tank_amount) + if(1 to 4) overlays += "plasma-[pla_tank_amount]" if(5 to INFINITY) overlays += "plasma-5" /obj/structure/dispenser/attack_hand(mob/user) @@ -38,7 +50,7 @@ /obj/structure/dispenser/attack_ghost(mob/user) ui_interact(user) -/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) user.set_machine(src) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) @@ -47,17 +59,16 @@ /obj/structure/dispenser/ui_data(user) var/list/data = list() - data["o_tanks"] = oxygentanks - data["p_tanks"] = plasmatanks + data["o_tanks"] = stored_oxygen_tanks.len + data["p_tanks"] = stored_plasma_tanks.len return data /obj/structure/dispenser/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/tank/oxygen) || istype(I, /obj/item/tank/air) || istype(I, /obj/item/tank/anesthetic)) - if(oxygentanks < 10) + if(stored_oxygen_tanks.len < 10) user.drop_item() I.forceMove(src) - oxytanks.Add(I) - oxygentanks++ + stored_oxygen_tanks.Add(I) update_icon() to_chat(user, "You put [I] in [src].") else @@ -65,11 +76,10 @@ SSnanoui.update_uis(src) return if(istype(I, /obj/item/tank/plasma)) - if(plasmatanks < 10) + if(stored_plasma_tanks.len < 10) user.drop_item() I.forceMove(src) - platanks.Add(I) - plasmatanks++ + stored_plasma_tanks.Add(I) update_icon() to_chat(user, "You put [I] in [src].") else @@ -88,40 +98,43 @@ /obj/structure/dispenser/Topic(href, href_list) if(..()) - return 1 + return TRUE if(Adjacent(usr)) usr.set_machine(src) + + // The oxygen tank button if(href_list["oxygen"]) - if(oxygentanks > 0) - var/obj/item/tank/oxygen/O - if(oxytanks.len == oxygentanks) - O = oxytanks[1] - oxytanks.Remove(O) - else - O = new /obj/item/tank/oxygen(loc) - O.loc = loc - to_chat(usr, "You take [O] out of [src].") - oxygentanks-- - update_icon() + if(!stored_oxygen_tanks.len) // No more tanks in the machine + return + + var/obj/item/tank/O = stored_oxygen_tanks[1] // Get the first tank in the list + stored_oxygen_tanks.Remove(O) // remove it from the list since we are ejecting the tank + + if(!usr.put_in_hands(O)) // Try to place it in the user's hands first + O.forceMove(loc) // If hands are full, place it at the location of the tank dispenser + to_chat(usr, "You take [O] out of [src].") + update_icon() + + // The plasma tank button if(href_list["plasma"]) - if(plasmatanks > 0) - var/obj/item/tank/plasma/P - if(platanks.len == plasmatanks) - P = platanks[1] - platanks.Remove(P) - else - P = new /obj/item/tank/plasma(loc) - P.loc = loc - to_chat(usr, "You take [P] out of [src].") - plasmatanks-- - update_icon() + if(!stored_plasma_tanks.len) + return + + var/obj/item/tank/P = stored_plasma_tanks[1] + stored_plasma_tanks.Remove(P) + + if(!usr.put_in_hands(P)) + P.forceMove(loc) + to_chat(usr, "You take [P] out of [src].") + update_icon() + add_fingerprint(usr) updateUsrDialog() SSnanoui.update_uis(src) else SSnanoui.close_user_uis(usr,src) - return 1 + return TRUE /obj/structure/tank_dispenser/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) From 3db924a2026a78a0c8fe025c98dbf0e4d663f95c Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Mar 2020 12:02:13 -0500 Subject: [PATCH 010/151] fucking map variables, compiler doesn't catch them --- _maps/map_files/RandomZLevels/evil_santa.dmm | 2 +- _maps/map_files/RandomZLevels/moonoutpost19.dmm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/RandomZLevels/evil_santa.dmm b/_maps/map_files/RandomZLevels/evil_santa.dmm index ff5d4df54b9..0a92eaa1b29 100644 --- a/_maps/map_files/RandomZLevels/evil_santa.dmm +++ b/_maps/map_files/RandomZLevels/evil_santa.dmm @@ -650,7 +650,7 @@ /area/awaymission/challenge/start) "bT" = ( /obj/structure/dispenser/oxygen{ - oxygentanks = 9 + starting_oxygen_tanks = 9 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plasteel, diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index affcac8c979..26ff48b4d88 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -2432,7 +2432,7 @@ }) "dy" = ( /obj/structure/dispenser/oxygen{ - oxygentanks = 9 + starting_oxygen_tanks = 9 }, /obj/machinery/light/small{ active_power_usage = 0; From 9c4274690cfd613d86b39d73fa1fd58e65f0f603 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 14 Mar 2020 15:15:42 -0500 Subject: [PATCH 011/151] review changes --- .../game/objects/structures/tank_dispenser.dm | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 4d9f82abbbd..35557cd0274 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -21,6 +21,17 @@ initialize_tanks() update_icon() +/obj/structure/dispenser/Destroy() + ..() + remove_all_tanks() + +/obj/structure/dispenser/proc/remove_all_tanks() + for(var/P in stored_plasma_tanks) + qdel(P) + + for(var/O in stored_oxygen_tanks) + qdel(O) + /obj/structure/dispenser/proc/initialize_tanks() for(var/I in 1 to starting_plasma_tanks) var/obj/item/tank/plasma/P = new(src) @@ -34,12 +45,17 @@ overlays.Cut() var/oxy_tank_amount = stored_oxygen_tanks.len switch(oxy_tank_amount) - if(1 to 3) overlays += "oxygen-[oxy_tank_amount]" - if(4 to INFINITY) overlays += "oxygen-4" + if(1 to 3) + overlays += "oxygen-[oxy_tank_amount]" + if(4 to INFINITY) + overlays += "oxygen-4" + var/pla_tank_amount = stored_plasma_tanks.len switch(pla_tank_amount) - if(1 to 4) overlays += "plasma-[pla_tank_amount]" - if(5 to INFINITY) overlays += "plasma-5" + if(1 to 4) + overlays += "plasma-[pla_tank_amount]" + if(5 to INFINITY) + overlays += "plasma-5" /obj/structure/dispenser/attack_hand(mob/user) if(..()) From ffdace086df36b72da9ff4ddfd4d29c7c672d244 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 14 Mar 2020 23:02:32 -0500 Subject: [PATCH 012/151] QDEL_LIST --- code/game/objects/structures/tank_dispenser.dm | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 35557cd0274..878e74eaf5d 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -23,14 +23,8 @@ /obj/structure/dispenser/Destroy() ..() - remove_all_tanks() - -/obj/structure/dispenser/proc/remove_all_tanks() - for(var/P in stored_plasma_tanks) - qdel(P) - - for(var/O in stored_oxygen_tanks) - qdel(O) + QDEL_LIST(stored_plasma_tanks) + QDEL_LIST(stored_oxygen_tanks) /obj/structure/dispenser/proc/initialize_tanks() for(var/I in 1 to starting_plasma_tanks) From 355eb2a26830dd4de85506363ec5135f3aeaaa90 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Fri, 24 Apr 2020 15:38:58 -0500 Subject: [PATCH 013/151] add some procs for duplicate code + antidrop check --- .../game/objects/structures/tank_dispenser.dm | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 878e74eaf5d..12dbb486a26 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -75,27 +75,13 @@ /obj/structure/dispenser/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/tank/oxygen) || istype(I, /obj/item/tank/air) || istype(I, /obj/item/tank/anesthetic)) - if(stored_oxygen_tanks.len < 10) - user.drop_item() - I.forceMove(src) - stored_oxygen_tanks.Add(I) - update_icon() - to_chat(user, "You put [I] in [src].") - else - to_chat(user, "[src] is full.") - SSnanoui.update_uis(src) + try_insert_tank(user, stored_oxygen_tanks, I) return + if(istype(I, /obj/item/tank/plasma)) - if(stored_plasma_tanks.len < 10) - user.drop_item() - I.forceMove(src) - stored_plasma_tanks.Add(I) - update_icon() - to_chat(user, "You put [I] in [src].") - else - to_chat(user, "[src] is full.") - SSnanoui.update_uis(src) + try_insert_tank(user, stored_plasma_tanks, I) return + if(istype(I, /obj/item/wrench)) if(anchored) to_chat(user, "You lean down and unwrench [src].") @@ -115,37 +101,49 @@ // The oxygen tank button if(href_list["oxygen"]) - if(!stored_oxygen_tanks.len) // No more tanks in the machine - return - - var/obj/item/tank/O = stored_oxygen_tanks[1] // Get the first tank in the list - stored_oxygen_tanks.Remove(O) // remove it from the list since we are ejecting the tank - - if(!usr.put_in_hands(O)) // Try to place it in the user's hands first - O.forceMove(loc) // If hands are full, place it at the location of the tank dispenser - to_chat(usr, "You take [O] out of [src].") - update_icon() + try_remove_tank(usr, stored_oxygen_tanks) // The plasma tank button if(href_list["plasma"]) - if(!stored_plasma_tanks.len) - return - - var/obj/item/tank/P = stored_plasma_tanks[1] - stored_plasma_tanks.Remove(P) - - if(!usr.put_in_hands(P)) - P.forceMove(loc) - to_chat(usr, "You take [P] out of [src].") - update_icon() + try_remove_tank(usr, stored_plasma_tanks) add_fingerprint(usr) updateUsrDialog() - SSnanoui.update_uis(src) + SSnanoui.try_update_ui(usr, src) else SSnanoui.close_user_uis(usr,src) return TRUE +/// Called when the user clicks on the oxygen or plasma tank UI buttons, and tries to withdraw a tank. +/obj/structure/dispenser/proc/try_remove_tank(mob/living/user, list/tank_list) + if(!tank_list.len) + return // There are no tanks left to withdraw. + + var/obj/item/tank/T = tank_list[1] + tank_list.Remove(T) + + if(!user.put_in_hands(T)) + T.forceMove(loc) // If the user's hands are full, place it on the tile of the dispenser. + + to_chat(user, "You take [T] out of [src].") + update_icon() + +/// Called when the user clicks on the dispenser with a tank. Tries to insert the tank into the dispenser, and updates the UI if successful. +/obj/structure/dispenser/proc/try_insert_tank(mob/living/user, list/tank_list, obj/item/tank/T) + if(!tank_list.len >= 10) + to_chat(user, "[src] is full.") + return + + if(!user.drop_item()) // Antidrop check + to_chat(user, "[T] is stuck to your hand!") + return + + T.forceMove(src) + tank_list.Add(T) + update_icon() + to_chat(user, "You put [T] in [src].") + SSnanoui.try_update_ui(user, src) + /obj/structure/tank_dispenser/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) for(var/X in src) From 4ef41cbb6ce711aee6e2ee0528be541ea13a9ca8 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 26 Apr 2020 03:19:31 -0500 Subject: [PATCH 014/151] define and LAZYLEN --- .../game/objects/structures/tank_dispenser.dm | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 12dbb486a26..f430f94ab87 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -1,3 +1,5 @@ +#define MAX_TANK_STORAGE 10 + /obj/structure/dispenser name = "tank storage unit" desc = "A simple yet bulky storage device for gas tanks. Has room for up to ten oxygen tanks, and ten plasma tanks." @@ -5,8 +7,8 @@ icon_state = "dispenser" density = 1 anchored = 1.0 - var/starting_oxygen_tanks = 10 // The starting amount of oxygen tanks the dispenser gets when it's spawned - var/starting_plasma_tanks = 10 // Starting amount of plasma tanks + var/starting_oxygen_tanks = MAX_TANK_STORAGE // The starting amount of oxygen tanks the dispenser gets when it's spawned + var/starting_plasma_tanks = MAX_TANK_STORAGE // Starting amount of plasma tanks var/list/stored_oxygen_tanks = list() // List of currently stored oxygen tanks var/list/stored_plasma_tanks = list() // And plasma tanks @@ -37,14 +39,14 @@ /obj/structure/dispenser/update_icon() overlays.Cut() - var/oxy_tank_amount = stored_oxygen_tanks.len + var/oxy_tank_amount = LAZYLEN(stored_oxygen_tanks) switch(oxy_tank_amount) if(1 to 3) overlays += "oxygen-[oxy_tank_amount]" if(4 to INFINITY) overlays += "oxygen-4" - var/pla_tank_amount = stored_plasma_tanks.len + var/pla_tank_amount = LAZYLEN(stored_plasma_tanks) switch(pla_tank_amount) if(1 to 4) overlays += "plasma-[pla_tank_amount]" @@ -69,8 +71,8 @@ /obj/structure/dispenser/ui_data(user) var/list/data = list() - data["o_tanks"] = stored_oxygen_tanks.len - data["p_tanks"] = stored_plasma_tanks.len + data["o_tanks"] = LAZYLEN(stored_oxygen_tanks) + data["p_tanks"] = LAZYLEN(stored_plasma_tanks) return data /obj/structure/dispenser/attackby(obj/item/I, mob/user, params) @@ -116,7 +118,7 @@ /// Called when the user clicks on the oxygen or plasma tank UI buttons, and tries to withdraw a tank. /obj/structure/dispenser/proc/try_remove_tank(mob/living/user, list/tank_list) - if(!tank_list.len) + if(!LAZYLEN(tank_list)) return // There are no tanks left to withdraw. var/obj/item/tank/T = tank_list[1] @@ -130,7 +132,7 @@ /// Called when the user clicks on the dispenser with a tank. Tries to insert the tank into the dispenser, and updates the UI if successful. /obj/structure/dispenser/proc/try_insert_tank(mob/living/user, list/tank_list, obj/item/tank/T) - if(!tank_list.len >= 10) + if(LAZYLEN(tank_list) >= MAX_TANK_STORAGE) to_chat(user, "[src] is full.") return @@ -151,3 +153,5 @@ I.forceMove(loc) new /obj/item/stack/sheet/metal(loc, 2) qdel(src) + +#undef MAX_TANK_STORAGE From cf93b2315805e078b4749220ce788531765bed5b Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 27 Apr 2020 12:23:48 -0500 Subject: [PATCH 015/151] rebase and remove some var from proc args --- code/game/objects/structures/tank_dispenser.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index f430f94ab87..9fc69686953 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -62,7 +62,7 @@ /obj/structure/dispenser/attack_ghost(mob/user) ui_interact(user) -/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) +/obj/structure/dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, master_ui = null, datum/topic_state/state = GLOB.default_state) user.set_machine(src) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) From 18551d633a93ee4c335306cfd9b9c8ac32800a21 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 16 May 2020 17:37:45 -0500 Subject: [PATCH 016/151] cut_overlays and return ..() --- code/game/objects/structures/tank_dispenser.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 9fc69686953..692d15d79ec 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -24,9 +24,9 @@ update_icon() /obj/structure/dispenser/Destroy() - ..() QDEL_LIST(stored_plasma_tanks) QDEL_LIST(stored_oxygen_tanks) + return ..() /obj/structure/dispenser/proc/initialize_tanks() for(var/I in 1 to starting_plasma_tanks) @@ -38,7 +38,7 @@ stored_oxygen_tanks.Add(O) /obj/structure/dispenser/update_icon() - overlays.Cut() + cut_overlays() var/oxy_tank_amount = LAZYLEN(stored_oxygen_tanks) switch(oxy_tank_amount) if(1 to 3) From 41afecb4ffe5bc76c035bd0dd60c46cf3ea20b7e Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 13:26:12 -0400 Subject: [PATCH 017/151] removes check karma verb and moves it to karma panel instead --- code/modules/karma/karma.dm | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index cccf9977ad6..6d1693d3ec0 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -153,19 +153,6 @@ GLOBAL_LIST_EMPTY(karma_spenders) sql_report_karma(src, M) -/client/verb/check_karma() - set name = "Check Karma" - set desc = "Reports how much karma you have accrued." - set category = "Special Verbs" - - if(config.disable_karma) - to_chat(src, "Karma is disabled.") - return - - var/currentkarma = verify_karma() - if(!isnull(currentkarma)) - to_chat(usr, {"
You have [currentkarma] available."}) - /client/proc/verify_karma() var/currentkarma = 0 if(!GLOB.dbcon.IsConnected()) @@ -262,6 +249,9 @@ GLOBAL_LIST_EMPTY(karma_spenders) if(!refundable.len) dat += "You do not have any refundable karma purchases.
" + var/currentkarma = verify_karma() + dat += "
You have [currentkarma] available." + dat += "
PLEASE NOTE THAT PEOPLE WHO TRY TO GAME THE KARMA SYSTEM WILL END UP ON THE WALL OF SHAME. THIS INCLUDES BUT IS NOT LIMITED TO TRADES, OOC KARMA BEGGING, CODE EXPLOITS, ETC." dat += "" From 66b6864d8a6a74000247359c2914c4014b5702f4 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 14:37:46 -0400 Subject: [PATCH 018/151] Show in karma menu unlocked jobs and species --- code/modules/karma/karma.dm | 93 ++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 6d1693d3ec0..0caa4ed9b6d 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -182,6 +182,23 @@ GLOBAL_LIST_EMPTY(karma_spenders) karmashopmenu() /client/proc/karmashopmenu() + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + query.Execute() + + var/list/joblist + var/list/specieslist + var/dbjob + var/dbspecies + var/dbckey + while(query.NextRow()) + dbckey = query.item[2] + dbjob = query.item[3] + dbspecies = query.item[4] + + if(dbckey) + joblist = splittext(dbjob,",") + specieslist = splittext(dbspecies,",") + var/dat = "
" dat += "Job Unlocks" dat += "Species Unlocks" @@ -191,26 +208,64 @@ GLOBAL_LIST_EMPTY(karma_spenders) switch(karma_tab) if(0) // Job Unlocks - dat += {" - Unlock Barber -- 5KP
- Unlock Brig Physician -- 5KP
- Unlock Nanotrasen Representative -- 30KP
- Unlock Blueshield -- 30KP
- Unlock Security Pod Pilot -- 30KP
- Unlock Mechanic -- 30KP
- Unlock Magistrate -- 45KP
- "} + if(!("Barber" in joblist)) + dat += "Unlock Barber -- 5KP
" + else + dat += "Barber Unlocked
" + if(!("Brig Physican" in joblist)) + dat += "Unlock Brig Physician -- 5KP
" + else + dat += "Brig Physician Unlocked
" + if(!("Nanotrasen Representative" in joblist)) + dat += "Unlock Nanotrasen Representative -- 30KP
" + else + dat += "Nanotrasen Representative Unlocked
" + if(!("Blueshield" in joblist)) + dat += "Unlock Blueshield -- 30KP
" + else + dat += "Blueshield Unlocked
" + if(!("Security Pod Pilot" in joblist)) + dat += "Unlock Security Pod Pilot -- 30KP
" + else + dat += "Security Pod Pilot Unlocked
" + if(!("Mechanic" in joblist)) + dat += "Unlock Mechanic -- 30KP
" + else + dat += "Mechanic Unlocked
" + if(!("Magistrate" in joblist)) + dat += "Unlock Magistrate -- 45KP
" + else + dat+= "Magistrate Unlocked
" if(1) // Species Unlocks - dat += {" - Unlock Machine People -- 15KP
- Unlock Kidan -- 30KP
- Unlock Grey -- 30KP
- Unlock Drask -- 30KP
- Unlock Vox -- 45KP
- Unlock Slime People -- 45KP
- Unlock Plasmaman -- 45KP
- "} + if(!("Machine" in specieslist)) + dat += "Unlock Machine People -- 15KP
" + else + dat += "Machine People Unlocked
" + if(!("Kidan" in specieslist)) + dat += "Unlock Kidan -- 30KP
" + else + dat += "Kidan Unlocked
" + if(!("Grey" in specieslist)) + dat += "Unlock Grey -- 30KP
" + else + dat += "Grey Unlocked
" + if(!("Drask" in specieslist)) + dat += "Unlock Drask -- 30KP
" + else + dat += "Drask Unlocked
" + if(!("Vox" in specieslist)) + dat += "Unlock Vox -- 45KP
" + else + dat += "Vox Unlocked
" + if(!("Slime People" in specieslist)) + dat += "Unlock Slime People -- 45KP
" + else + dat += "Slime People Unlocked
" + if(!("Plasmaman" in specieslist)) + dat += "Unlock Plasmaman -- 45KP
" + else + dat += "Plasmaman Unlocked
" if(2) // Karma Refunds var/list/refundable = list() @@ -273,8 +328,10 @@ GLOBAL_LIST_EMPTY(karma_spenders) name = DBname if(category == "job") DB_job_unlock(name,price) + karmashopmenu() else if(category == "species") DB_species_unlock(name,price) + karmashopmenu() /client/proc/DB_job_unlock(var/job,var/cost) var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") From bda4a6053e4d1f8822929ded3c986b797a94dbad Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:06:38 -0400 Subject: [PATCH 019/151] Add some color to text --- code/modules/karma/karma.dm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 0caa4ed9b6d..bf35a9b80b6 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -211,61 +211,61 @@ GLOBAL_LIST_EMPTY(karma_spenders) if(!("Barber" in joblist)) dat += "Unlock Barber -- 5KP
" else - dat += "Barber Unlocked
" + dat += "Barber - Unlocked
" if(!("Brig Physican" in joblist)) dat += "Unlock Brig Physician -- 5KP
" else - dat += "Brig Physician Unlocked
" + dat += "Brig Physician - Unlocked
" if(!("Nanotrasen Representative" in joblist)) dat += "Unlock Nanotrasen Representative -- 30KP
" else - dat += "Nanotrasen Representative Unlocked
" + dat += "Nanotrasen Representative - Unlocked
" if(!("Blueshield" in joblist)) dat += "Unlock Blueshield -- 30KP
" else - dat += "Blueshield Unlocked
" + dat += "Blueshield - Unlocked
" if(!("Security Pod Pilot" in joblist)) dat += "Unlock Security Pod Pilot -- 30KP
" else - dat += "Security Pod Pilot Unlocked
" + dat += "Security Pod Pilot - Unlocked
" if(!("Mechanic" in joblist)) dat += "Unlock Mechanic -- 30KP
" else - dat += "Mechanic Unlocked
" + dat += "Mechanic - Unlocked
" if(!("Magistrate" in joblist)) dat += "Unlock Magistrate -- 45KP
" else - dat+= "Magistrate Unlocked
" + dat+= "Magistrate - Unlocked
" if(1) // Species Unlocks if(!("Machine" in specieslist)) dat += "Unlock Machine People -- 15KP
" else - dat += "Machine People Unlocked
" + dat += "Machine People - Unlocked
" if(!("Kidan" in specieslist)) dat += "Unlock Kidan -- 30KP
" else - dat += "Kidan Unlocked
" + dat += "Kidan - Unlocked
" if(!("Grey" in specieslist)) dat += "Unlock Grey -- 30KP
" else - dat += "Grey Unlocked
" + dat += "Grey - Unlocked
" if(!("Drask" in specieslist)) dat += "Unlock Drask -- 30KP
" else - dat += "Drask Unlocked
" + dat += "Drask - Unlocked
" if(!("Vox" in specieslist)) dat += "Unlock Vox -- 45KP
" else - dat += "Vox Unlocked
" + dat += "Vox - Unlocked
" if(!("Slime People" in specieslist)) dat += "Unlock Slime People -- 45KP
" else - dat += "Slime People Unlocked
" + dat += "Slime People - Unlocked
" if(!("Plasmaman" in specieslist)) dat += "Unlock Plasmaman -- 45KP
" else - dat += "Plasmaman Unlocked
" + dat += "Plasmaman - Unlocked
" if(2) // Karma Refunds var/list/refundable = list() From 6fce4c1452c549c1f2b09280c8ccba00f16c0799 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:07:56 -0400 Subject: [PATCH 020/151] Re-add check_karma verb --- code/modules/karma/karma.dm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index bf35a9b80b6..3d9d2fa56de 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -153,6 +153,19 @@ GLOBAL_LIST_EMPTY(karma_spenders) sql_report_karma(src, M) +/client/verb/check_karma() + set name = "Check Karma" + set desc = "Reports how much karma you have accrued." + set category = "Special Verbs" + + if(config.disable_karma) + to_chat(src, "Karma is disabled.") + return + + var/currentkarma = verify_karma() + if(!isnull(currentkarma)) + to_chat(usr, {"
You have [currentkarma] available."}) + /client/proc/verify_karma() var/currentkarma = 0 if(!GLOB.dbcon.IsConnected()) From 1e284a4b43bb08db3cae2d83d09eee00e5c6bd73 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:28:05 -0400 Subject: [PATCH 021/151] Sanitation all around --- code/modules/karma/karma.dm | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 3d9d2fa56de..2935cd394be 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -4,9 +4,9 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver) var/sqlspendername = sanitizeSQL(spender.name) - var/sqlspenderkey = spender.ckey + var/sqlspenderkey = sanitizeSQL(spender.ckey) var/sqlreceivername = sanitizeSQL(receiver.name) - var/sqlreceiverkey = receiver.ckey + var/sqlreceiverkey = sanitizeSQL(receiver.ckey) var/sqlreceiverrole = "None" var/sqlreceiverspecial = "None" @@ -28,7 +28,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver) log_game("SQL ERROR during karma logging. Error : \[[err]\]\n") - query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[receiver.ckey]'") + query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sqlreceiverkey]'") query.Execute() var/karma @@ -38,7 +38,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver) karma = text2num(query.item[3]) if(karma == null) karma = 1 - query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[receiver.ckey]', [karma])") + query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[sqlreceiverkey]', [karma])") if(!query.Execute()) var/err = query.ErrorMsg() log_game("SQL ERROR during karmatotal logging (adding new key). Error : \[[err]\]\n") @@ -168,11 +168,12 @@ GLOBAL_LIST_EMPTY(karma_spenders) /client/proc/verify_karma() var/currentkarma = 0 + var/sanitzedkey = sanitizeSQL(src.ckey) if(!GLOB.dbcon.IsConnected()) to_chat(usr, "Unable to connect to karma database. Please try again later.
") return else - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[src.ckey]'") + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'") query.Execute() var/totalkarma @@ -195,7 +196,8 @@ GLOBAL_LIST_EMPTY(karma_spenders) karmashopmenu() /client/proc/karmashopmenu() - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + var/sanitzedkey = sanitizeSQL(usr.ckey) + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'") query.Execute() var/list/joblist @@ -318,7 +320,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dat += "You do not have any refundable karma purchases.
" var/currentkarma = verify_karma() - dat += "
You have [currentkarma] available." + dat += "
You have [currentkarma] available.
" dat += "
PLEASE NOTE THAT PEOPLE WHO TRY TO GAME THE KARMA SYSTEM WILL END UP ON THE WALL OF SHAME. THIS INCLUDES BUT IS NOT LIMITED TO TRADES, OOC KARMA BEGGING, CODE EXPLOITS, ETC." dat += "
" @@ -347,7 +349,8 @@ GLOBAL_LIST_EMPTY(karma_spenders) karmashopmenu() /client/proc/DB_job_unlock(var/job,var/cost) - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + var/sanitzedkey = sanitizeSQL(usr.ckey) + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'") query.Execute() var/dbjob @@ -356,7 +359,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dbckey = query.item[2] dbjob = query.item[3] if(!dbckey) - query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[usr.ckey]','[job]')") + query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[sanitzedkey]','[job]')") if(!query.Execute()) queryErrorLog(query.ErrorMsg(),"adding new key") return @@ -383,7 +386,8 @@ GLOBAL_LIST_EMPTY(karma_spenders) return /client/proc/DB_species_unlock(var/species,var/cost) - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + var/sanitzedkey = sanitizeSQL(usr.ckey) + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'") query.Execute() var/dbspecies @@ -392,7 +396,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dbckey = query.item[2] dbspecies = query.item[4] if(!dbckey) - query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[usr.ckey]','[species]')") + query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[sanitzedkey]','[species]')") if(!query.Execute()) queryErrorLog(query.ErrorMsg(),"adding new key") return @@ -419,7 +423,8 @@ GLOBAL_LIST_EMPTY(karma_spenders) return /client/proc/karmacharge(var/cost,var/refund = FALSE) - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[usr.ckey]'") + var/sanitzedkey = sanitizeSQL(usr.ckey) + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitizeSQL]'") query.Execute() while(query.NextRow()) @@ -428,7 +433,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) spent -= cost else spent += cost - query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[usr.ckey]'") + query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[sanitizeSQL]'") if(!query.Execute()) queryErrorLog(query.ErrorMsg(),"updating existing entry") return @@ -438,6 +443,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) return /client/proc/karmarefund(var/type,var/name,var/cost) + var/sanitzedkey = sanitizeSQL(usr.ckey) switch(name) if("Tajaran Ambassador","Unathi Ambassador","Skrell Ambassador","Diona Ambassador","Kidan Ambassador", "Slime People Ambassador","Grey Ambassador","Vox Ambassador","Customs Officer") @@ -448,7 +454,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) to_chat(usr, "That job is not refundable.") return - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'") query.Execute() var/dbjob @@ -491,7 +497,8 @@ GLOBAL_LIST_EMPTY(karma_spenders) message_admins("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n") /client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") + var/sanitzedkey = sanitizeSQL(usr.ckey) + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'") query.Execute() var/dbjob From 7b6aa33869835f9c3c03991a9f6c404ba75cdc2b Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:29:09 -0400 Subject: [PATCH 022/151] Syntaxfix --- code/modules/karma/karma.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 2935cd394be..134cc25fcd2 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -424,7 +424,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) /client/proc/karmacharge(var/cost,var/refund = FALSE) var/sanitzedkey = sanitizeSQL(usr.ckey) - var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitizeSQL]'") + var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'") query.Execute() while(query.NextRow()) @@ -433,7 +433,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) spent -= cost else spent += cost - query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[sanitizeSQL]'") + query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[sanitzedkey]'") if(!query.Execute()) queryErrorLog(query.ErrorMsg(),"updating existing entry") return From 37db9d9df1245f5b4a51a3be82eb121dae211cfc Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:41:09 -0400 Subject: [PATCH 023/151] Moved current karma above unlocks --- code/modules/karma/karma.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 134cc25fcd2..dd9483d9c87 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -221,6 +221,9 @@ GLOBAL_LIST_EMPTY(karma_spenders) dat += "" dat += "
" + var/currentkarma = verify_karma() + dat += "
You have [currentkarma] available.

" + switch(karma_tab) if(0) // Job Unlocks if(!("Barber" in joblist)) @@ -319,9 +322,6 @@ GLOBAL_LIST_EMPTY(karma_spenders) if(!refundable.len) dat += "You do not have any refundable karma purchases.
" - var/currentkarma = verify_karma() - dat += "
You have [currentkarma] available.
" - dat += "
PLEASE NOTE THAT PEOPLE WHO TRY TO GAME THE KARMA SYSTEM WILL END UP ON THE WALL OF SHAME. THIS INCLUDES BUT IS NOT LIMITED TO TRADES, OOC KARMA BEGGING, CODE EXPLOITS, ETC." dat += "" From 82c431a1b8bb39779f07629dc1e77772c1e326ee Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Thu, 21 May 2020 16:50:39 -0400 Subject: [PATCH 024/151] Final placement of currentkarma --- code/modules/karma/karma.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index dd9483d9c87..f7d8b12f80c 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -222,7 +222,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dat += "
" var/currentkarma = verify_karma() - dat += "
You have [currentkarma] available.

" + dat += "You have [currentkarma] available.

" switch(karma_tab) if(0) // Job Unlocks From d065268efdb0bb4c50d9c726639fd7fb9d446c26 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 25 May 2020 21:15:26 +0200 Subject: [PATCH 025/151] Gives flashes and cameras a flash --- code/game/objects/items/devices/flash.dm | 4 +++- code/modules/paperwork/photography.dm | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index b8602e671c3..6c2379b7606 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -67,7 +67,7 @@ times_used = max(0, times_used) //sanity -/obj/item/flash/proc/try_use_flash(var/mob/user = null) +/obj/item/flash/proc/try_use_flash(mob/user = null) flash_recharge(user) if(broken) @@ -75,6 +75,8 @@ playsound(src.loc, use_sound, 100, 1) flick("[initial(icon_state)]2", src) + set_light(2, 1, COLOR_WHITE) + addtimer(CALLBACK(src, /atom./proc/set_light, 0), 2) times_used++ if(user && !clown_check(user)) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 8d0525c5eb1..1134f7a0752 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -324,24 +324,26 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." return mob_detail -/obj/item/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) - if(!on || !pictures_left || ismob(target.loc)) return +/obj/item/camera/afterattack(atom/target, mob/user, flag) + if(!on || !pictures_left || ismob(target.loc)) + return captureimage(target, user, flag) playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3) - + set_light(3, 2, LIGHT_COLOR_TUNGSTEN) + addtimer(CALLBACK(src, /atom./proc/set_light, 0), 2) pictures_left-- desc = "A polaroid camera. It has [pictures_left] photos left." to_chat(user, "[pictures_left] photos left.") icon_state = icon_off - on = 0 + on = FALSE if(istype(src,/obj/item/camera/spooky)) if(user.mind && user.mind.assigned_role == "Chaplain" && see_ghosts) if(prob(24)) handle_haunt(user) spawn(64) icon_state = icon_on - on = 1 + on = TRUE /obj/item/camera/proc/can_capture_turf(turf/T, mob/user) var/viewer = user From caaa43439f4302418bd7ff31d70fb253bd58e4d1 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 25 May 2020 21:19:51 +0200 Subject: [PATCH 026/151] Small refactor --- code/game/objects/items/devices/flash.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 6c2379b7606..58848f3f7e4 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -71,18 +71,18 @@ flash_recharge(user) if(broken) - return 0 + return FALSE - playsound(src.loc, use_sound, 100, 1) + playsound(loc, use_sound, 100, 1) flick("[initial(icon_state)]2", src) set_light(2, 1, COLOR_WHITE) addtimer(CALLBACK(src, /atom./proc/set_light, 0), 2) times_used++ if(user && !clown_check(user)) - return 0 + return FALSE - return 1 + return TRUE /obj/item/flash/proc/flash_carbon(var/mob/living/carbon/M, var/mob/user = null, var/power = 5, targeted = 1) From 881b5c748cce342ca51993a93888f22222169857 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 25 May 2020 23:17:13 +0200 Subject: [PATCH 027/151] include flashers --- code/game/machinery/flasher.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index b7b7e35eef6..57057ad510a 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -58,6 +58,8 @@ playsound(loc, 'sound/weapons/flash.ogg', 100, 1) flick("[base_state]_flash", src) + set_light(2, 1, COLOR_WHITE) + addtimer(CALLBACK(src, /atom./proc/set_light, 0), 2) last_flash = world.time use_power(1000) From a93c4d9cdc6ab43b84b0397262c4bcba41f45da4 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Wed, 27 May 2020 13:51:32 -0500 Subject: [PATCH 028/151] Invisible cloning pod fix --- code/game/machinery/cloning.dm | 20 ++++++++++++++------ code/game/objects/effects/misc.dm | 2 +- icons/obj/cloning.dmi | Bin 8069 -> 7962 bytes 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index a98d7b08c13..378f92238bc 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ desc = "An electronically-lockable pod for growing organic tissue." density = 1 icon = 'icons/obj/cloning.dmi' - icon_state = "pod_0" + icon_state = "pod_idle" req_access = list(ACCESS_GENETICS) //For premature unlocking. var/mob/living/carbon/human/occupant @@ -419,7 +419,9 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ /obj/machinery/clonepod/screwdriver_act(mob/user, obj/item/I) . = TRUE - default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I) + // These icon states don't really matter since we need to call update_icon() to handle panel open/closed overlays anyway. + default_deconstruction_screwdriver(user, null, null, I) + update_icon() /obj/machinery/clonepod/wrench_act(mob/user, obj/item/I) . = TRUE @@ -545,11 +547,17 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ /obj/machinery/clonepod/update_icon() ..() - icon_state = "pod_0" + cut_overlays() + + if(panel_open) + add_overlay(list("panel_open")) + if(occupant && !(stat & NOPOWER)) - icon_state = "pod_1" - else if(mess && !panel_open) - icon_state = "pod_g" + icon_state = "pod_cloning" + else if(mess) + icon_state = "pod_mess" + else + icon_state = "pod_idle" /obj/machinery/clonepod/relaymove(mob/user) if(user.stat == CONSCIOUS) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 434c0af1136..a0006fd00d6 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -88,7 +88,7 @@ name = "horrific experiment" desc = "Some sort of pod filled with blood and vicerea. You swear you can see it moving..." icon = 'icons/obj/cloning.dmi' - icon_state = "pod_g" + icon_state = "pod_mess" //Makes a tile fully lit no matter what diff --git a/icons/obj/cloning.dmi b/icons/obj/cloning.dmi index 69abac9ee4fadfd1a7b8333cd891cb9e14608cdc..83f5d6352d259e62b57f73008554261c35331d7d 100644 GIT binary patch literal 7962 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 Q^Z)<=07*qoM6N<$g2E`SGynhq literal 8069 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 T6!QT{00000NkvXXu0mjfU3wE1 From 622c3ce9c3adfd4f3024a251a0b79c39dff4ed0b Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Wed, 27 May 2020 14:30:19 -0500 Subject: [PATCH 029/151] no list --- code/game/machinery/cloning.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 378f92238bc..c622b12c94c 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -550,7 +550,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ cut_overlays() if(panel_open) - add_overlay(list("panel_open")) + add_overlay("panel_open") if(occupant && !(stat & NOPOWER)) icon_state = "pod_cloning" From 2d252f3b6747f0a06d200489021d7a5a33afea1b Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Wed, 27 May 2020 21:29:58 +0100 Subject: [PATCH 030/151] Annihilates the global iterator --- code/datums/helper_datums/global_iterator.dm | 152 ------------------- code/modules/spacepods/spacepod.dm | 41 ++--- paradise.dme | 1 - 3 files changed, 15 insertions(+), 179 deletions(-) delete mode 100644 code/datums/helper_datums/global_iterator.dm diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm deleted file mode 100644 index 214045941b5..00000000000 --- a/code/datums/helper_datums/global_iterator.dm +++ /dev/null @@ -1,152 +0,0 @@ -/* -README: - -The global_iterator datum is supposed to provide a simple and robust way to -create some constantly "looping" processes with ability to stop and restart them at will. -Generally, the only thing you want to play with (meaning, redefine) is the process() proc. -It must contain all the things you want done. - -Control functions: - new - used to create datum. First argument (optional) - var list(to use in process() proc) as list, - second (optional) - autostart control. - If autostart == TRUE, the loop will be started immediately after datum creation. - - start(list/arguments) - starts the loop. Takes arguments(optional) as a list, which is then used - by process() proc. Returns null if datum already active, 1 if loop started succesfully and 0 if there's - an error in supplied arguments (not list or empty list). - - stop() - stops the loop. Returns null if datum is already inactive and 1 on success. - - set_delay(new_delay) - sets the delay between iterations. Pretty selfexplanatory. - Returns 0 on error(new_delay is not numerical), 1 otherwise. - - set_process_args(list/arguments) - passes the supplied arguments to the process() proc. - - active() - Returns 1 if datum is active, 0 otherwise. - - toggle() - toggles datum state. Returns new datum state (see active()). - -Misc functions: - - get_last_exec_time() - Returns the time of last iteration. - - get_last_exec_time_as_text() - Returns the time of last iteration as text - - -Control vars: - - delay - delay between iterations - - check_for_null - if equals TRUE, on each iteration the supplied arguments will be checked for nulls. - If some varible equals null (and null only), the loop is stopped. - Usefull, if some var unexpectedly becomes null - due to object deletion, for example. - Of course, you can also check the variables inside process() proc to prevent runtime errors. - -Data storage vars: - - result - stores the value returned by process() proc -*/ - -/datum/global_iterator - var/control_switch = 0 - var/delay = 10 - var/list/arg_list = new - var/last_exec = null - var/check_for_null = 1 - var/forbid_garbage = 0 - var/result - var/state = 0 - -/datum/global_iterator/New(list/arguments=null,autostart=1) - delay = delay>0?(delay):1 - if(forbid_garbage) //prevents garbage collection with tag != null - tag = "\ref[src]" - set_process_args(arguments) - if(autostart) - start() - return - -/datum/global_iterator/proc/main() - state = 1 - while(src && control_switch) - last_exec = world.timeofday - if(check_for_null && has_null_args()) - stop() - return 0 - result = process(arglist(arg_list)) - for(var/sleep_time=delay;sleep_time>0;sleep_time--) //uhh, this is ugly. But I see no other way to terminate sleeping proc. Such disgrace. - if(!control_switch) - return 0 - sleep(1) - return 0 - -/datum/global_iterator/proc/start(list/arguments=null) - if(active()) - return - if(arguments) - if(!set_process_args(arguments)) - return 0 - if(!state_check()) //the main loop is sleeping, wait for it to terminate. - return - control_switch = 1 - spawn() - state = main() - return 1 - -/datum/global_iterator/proc/stop() - if(!active()) - return - control_switch = 0 - spawn(-1) //report termination error but don't wait for state_check(). - state_check() - return 1 - -/datum/global_iterator/proc/state_check() - var/lag = 0 - while(state) - sleep(1) - if(++lag>10) - CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.") - return 1 - -/datum/global_iterator/process() - return - -/datum/global_iterator/proc/active() - return control_switch - -/datum/global_iterator/proc/has_null_args() - if(null in arg_list) - return 1 - return 0 - - -/datum/global_iterator/proc/set_delay(new_delay) - if(isnum(new_delay)) - delay = max(1, round(new_delay)) - return 1 - else - return 0 - -/datum/global_iterator/proc/get_last_exec_time() - return (last_exec||0) - -/datum/global_iterator/proc/get_last_exec_time_as_text() - return (time2text(last_exec)||"Wasn't executed yet") - -/datum/global_iterator/proc/set_process_args(list/arguments) - if(arguments && istype(arguments, /list) && arguments.len) - arg_list = arguments - return 1 - else -// to_chat(world, "Invalid arguments supplied for [src.type], ref = \ref[src]") - return 0 - -/datum/global_iterator/proc/toggle_null_checks() - check_for_null = !check_for_null - return check_for_null - -/datum/global_iterator/proc/toggle() - if(!stop()) - start() - return active() diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index de24c351c4a..1da2e1d0e33 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -37,8 +37,6 @@ var/datum/gas_mixture/cabin_air var/obj/machinery/portable_atmospherics/canister/internal_tank var/use_internal_tank = 0 - var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature - var/datum/global_iterator/pr_give_air //moves air from tank to cabin var/datum/effect_system/trail_follow/ion/space_trail/ion_trail @@ -117,8 +115,6 @@ src.ion_trail.set_up(src) src.ion_trail.start() src.use_internal_tank = 1 - pr_int_temp_processor = new /datum/global_iterator/pod_preserve_temp(list(src)) - pr_give_air = new /datum/global_iterator/pod_tank_give_air(list(src)) equipment_system = new(src) equipment_system.installed_modules += battery GLOB.spacepods_list += src @@ -127,6 +123,7 @@ cargo_hold.storage_slots = 0 //You need to install cargo modules to use it. cargo_hold.max_w_class = 5 //fit almost anything cargo_hold.max_combined_w_class = 0 //you can optimize your stash with larger items + START_PROCESSING(SSobj, src) /obj/spacepod/Destroy() if(equipment_system.cargo_system) @@ -136,8 +133,6 @@ QDEL_NULL(battery) QDEL_NULL(cabin_air) QDEL_NULL(internal_tank) - QDEL_NULL(pr_int_temp_processor) - QDEL_NULL(pr_give_air) QDEL_NULL(ion_trail) occupant_sanity_check() if(pilot) @@ -148,13 +143,14 @@ M.forceMove(get_turf(src)) passengers -= M GLOB.spacepods_list -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/spacepod/process() + give_air() + regulate_temp() if(src.empcounter > 0) src.empcounter-- - else - STOP_PROCESSING(SSobj, src) /obj/spacepod/proc/update_icons() if(!pod_overlays) @@ -998,22 +994,17 @@ return 1 -/datum/global_iterator/pod_preserve_temp //normalizing cabin air temperature to 20 degrees celsium - delay = 20 - - process(var/obj/spacepod/spacepod) - if(spacepod.cabin_air && spacepod.cabin_air.return_volume() > 0) - var/delta = spacepod.cabin_air.temperature - T20C - spacepod.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) - -/datum/global_iterator/pod_tank_give_air - delay = 15 - -/datum/global_iterator/pod_tank_give_air/process(var/obj/spacepod/spacepod) - if(spacepod && spacepod.internal_tank) - var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air() - var/datum/gas_mixture/cabin_air = spacepod.cabin_air +// Fun fact, these procs are just copypastes from mech code +// And have been for the past 4 years +// Please send help +/obj/spacepod/proc/regulate_temp() + if(cabin_air && cabin_air.return_volume() > 0) + var/delta = cabin_air.temperature - T20C + cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) +/obj/spacepod/proc/give_air() + if(internal_tank) + var/datum/gas_mixture/tank_air = internal_tank.return_air() var/release_pressure = ONE_ATMOSPHERE var/cabin_pressure = cabin_air.return_pressure() var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) @@ -1024,7 +1015,7 @@ var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) cabin_air.merge(removed) else if(pressure_delta < 0) //cabin pressure higher than release pressure - var/datum/gas_mixture/t_air = spacepod.get_turf_air() + var/datum/gas_mixture/t_air = get_turf_air() pressure_delta = cabin_pressure - release_pressure if(t_air) pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) @@ -1035,8 +1026,6 @@ t_air.merge(removed) else //just delete the cabin gas, we're in space or some shit qdel(removed) - else - return stop() /obj/spacepod/relaymove(mob/user, direction) if(user != src.pilot) diff --git a/paradise.dme b/paradise.dme index acc84e8d18f..3e4d100880a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -360,7 +360,6 @@ #include "code\datums\diseases\advance\symptoms\youth.dm" #include "code\datums\helper_datums\construction_datum.dm" #include "code\datums\helper_datums\events.dm" -#include "code\datums\helper_datums\global_iterator.dm" #include "code\datums\helper_datums\icon_snapshot.dm" #include "code\datums\helper_datums\input.dm" #include "code\datums\helper_datums\map_template.dm" From 8b8423574ab2838da577a6b4c2aa55aca925eb3a Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Wed, 27 May 2020 16:12:03 -0500 Subject: [PATCH 031/151] borg alt click fix --- code/game/objects/items/weapons/storage/storage.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 0aa7d976082..5b54f32d707 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -83,7 +83,7 @@ return /obj/item/storage/AltClick(mob/user) - if(Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE)) + if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE)) orient2hud(user) if(user.s_active) user.s_active.close(user) From 934ef6dcd04e7a5cd2c682caa2abd26228c2527f Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Wed, 27 May 2020 18:11:40 -0500 Subject: [PATCH 032/151] guardian coms fix --- .../gamemodes/miniantags/guardian/guardian.dm | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 126587a0c97..850c6ef57bd 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -182,15 +182,18 @@ input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "") else input = message - if(!input) return + if(!input) + return - for(var/mob/M in GLOB.mob_list) - if(M == summoner) - to_chat(M, "[src]: [input]") - log_say("(GUARDIAN to [key_name(M)]) [input]", src) - else if(M in GLOB.dead_mob_list && M.client && M.stat == DEAD && !isnewplayer(M)) - to_chat(M, "Guardian Communication from [src] ([ghost_follow_link(src, ghost=M)]): [input]") + // Show the message to the host and to the guardian. + to_chat(summoner, "[src]: [input]") to_chat(src, "[src]: [input]") + log_say("(GUARDIAN to [key_name(summoner)]) [input]", src) + + // Show the message to any ghosts/dead players. + for(var/mob/M in GLOB.dead_mob_list) + if(M && M.client && M.stat == DEAD && !isnewplayer(M)) + to_chat(M, "Guardian Communication from [src] ([ghost_follow_link(src, ghost=M)]): [input]") //override set to true if message should be passed through instead of going to host communication /mob/living/simple_animal/hostile/guardian/say(message, override = FALSE) @@ -208,18 +211,23 @@ set category = "Guardian" set desc = "Communicate telepathically with your guardian." var/input = stripped_input(src, "Please enter a message to tell your guardian.", "Message", "") - if(!input) return + if(!input) + return - for(var/mob/M in GLOB.mob_list) - if(istype(M, /mob/living/simple_animal/hostile/guardian)) - var/mob/living/simple_animal/hostile/guardian/G = M - if(G.summoner == src) - to_chat(G, "[src]: [input]") - log_say("(GUARDIAN to [key_name(G)]) [input]", src) + // Find the guardian in our host's contents. + var/mob/living/simple_animal/hostile/guardian/G = locate() in contents + if(!G) + return - else if(M in GLOB.dead_mob_list && M.client && M.stat == DEAD && !isnewplayer(M)) - to_chat(M, "Guardian Communication from [src] ([ghost_follow_link(src, ghost=M)]): [input]") + // Show the message to our guardian and to host. + to_chat(G, "[src]: [input]") to_chat(src, "[src]: [input]") + log_say("(GUARDIAN to [key_name(G)]) [input]", src) + + // Show the message to any ghosts/dead players. + for(var/mob/M in GLOB.dead_mob_list) + if(M && M.client && M.stat == DEAD && !isnewplayer(M)) + to_chat(M, "Guardian Communication from [src] ([ghost_follow_link(src, ghost=M)]): [input]") /mob/living/proc/guardian_recall() set name = "Recall Guardian" From 960e9833e6d840bc44f3fad9d15f41b9f7a75924 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 28 May 2020 10:08:41 +0200 Subject: [PATCH 033/151] Better feedback to user --- code/modules/client/preference/preferences.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 67e61c71577..569ecd3e3ff 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -2001,8 +2001,11 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts windowflashing = !windowflashing if("afk_watch") - to_chat(user, "You will now get put into cryo dorms after [config.auto_cryo_afk] minutes. \ + if(!afk_watch) + to_chat(user, "You will now get put into cryo dorms after [config.auto_cryo_afk] minutes. \ Then after [config.auto_despawn_afk] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.") + else + to_chat(user, "Automatic cryoing turned off.") afk_watch = !afk_watch if("UIcolor") From cb499f1a6cbca5faa142cfdd6bde9be33deec0a6 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 28 May 2020 10:26:24 +0200 Subject: [PATCH 034/151] log_admins -> log_afk_action --- code/controllers/subsystem/afk.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 5fbc37e41b9..81a4e4cb3d9 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -50,14 +50,14 @@ SUBSYSTEM_DEF(afk) if(A.fast_despawn) toRemove += H.ckey warn(H, "You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.") - log_admins(H, mins_afk, T, "despawned", "AFK in a fast despawn area") + log_afk_action(H, mins_afk, T, "despawned", "AFK in a fast despawn area") force_cryo_human(H) else if(!(H.mind.special_role in non_cryo_antags)) if(cryo_ssd(H)) H.create_log(MISC_LOG, "Put into cryostorage by the AFK subsystem") afk_players[H.ckey] = AFK_CRYOD - log_admins(H, mins_afk, T, "put into cryostorage") + log_afk_action(H, mins_afk, T, "put into cryostorage") warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. \ After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. \ Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.") @@ -66,7 +66,7 @@ SUBSYSTEM_DEF(afk) afk_players[H.ckey] = AFK_ADMINS_WARNED else if(afk_players[H.ckey] != AFK_ADMINS_WARNED && mins_afk >= config.auto_despawn_afk) - log_admins(H, mins_afk, T, "despawned") + log_afk_action(H, mins_afk, T, "despawned") warn(H, "You are have been despawned after being AFK for [mins_afk] minutes.") toRemove += H.ckey force_cryo_human(H) @@ -79,7 +79,7 @@ SUBSYSTEM_DEF(afk) if(H.client) window_flash(H.client) -/datum/controller/subsystem/afk/proc/log_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info) +/datum/controller/subsystem/afk/proc/log_afk_action(mob/living/carbon/human/H, mins_afk, turf/location, action, info) log_admin("[key_name(H)] has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]") /datum/controller/subsystem/afk/proc/removeFromWatchList(list/toRemove) From 793f18c5e55ae8d643a490dc8f5805ecaeabdfe3 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Thu, 28 May 2020 15:16:53 +0100 Subject: [PATCH 035/151] Fixes dupe processing --- code/modules/spacepods/spacepod.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 1da2e1d0e33..2e3c89017ef 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -284,7 +284,6 @@ deal_damage(80 / severity) if(empcounter < (40 / severity)) empcounter = 40 / severity - START_PROCESSING(SSobj, src) switch(severity) if(1) From 2cbe6f470ce7b1228a66c92c0c516d21dd0fd041 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 28 May 2020 12:57:08 -0500 Subject: [PATCH 036/151] call parent --- code/game/objects/items/weapons/storage/storage.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 5b54f32d707..55b25ad725a 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -90,6 +90,7 @@ show_to(user) playsound(loc, "rustle", 50, 1, -5) add_fingerprint(user) + return ..() /obj/item/storage/proc/return_inv() From dd3749f75ceca2ae909d924627f7e4aa44356003 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 28 May 2020 13:34:58 -0500 Subject: [PATCH 037/151] say logs --- code/game/gamemodes/miniantags/guardian/guardian.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 850c6ef57bd..7c7f7a9f694 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -189,6 +189,7 @@ to_chat(summoner, "[src]: [input]") to_chat(src, "[src]: [input]") log_say("(GUARDIAN to [key_name(summoner)]) [input]", src) + create_log(SAY_LOG, "GUARDIAN to HOST: [input]", summoner) // Show the message to any ghosts/dead players. for(var/mob/M in GLOB.dead_mob_list) @@ -223,6 +224,7 @@ to_chat(G, "[src]: [input]") to_chat(src, "[src]: [input]") log_say("(GUARDIAN to [key_name(G)]) [input]", src) + create_log(SAY_LOG, "HOST to GUARDIAN: [input]", G) // Show the message to any ghosts/dead players. for(var/mob/M in GLOB.dead_mob_list) From 26112b53adf601ea2fa0a7d5ec84321948a519c0 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Fri, 29 May 2020 13:41:28 +0100 Subject: [PATCH 038/151] Fixes whiteship spawning above station --- _maps/map_files/generic/tcommsat-blown.dmm | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/_maps/map_files/generic/tcommsat-blown.dmm b/_maps/map_files/generic/tcommsat-blown.dmm index ee06423a8be..e31ba89348a 100644 --- a/_maps/map_files/generic/tcommsat-blown.dmm +++ b/_maps/map_files/generic/tcommsat-blown.dmm @@ -119,10 +119,6 @@ /obj/structure/lattice, /turf/space, /area/space/nearstation) -"be" = ( -/obj/item/trash/cheesie, -/turf/space, -/area/space/nearstation) "bj" = ( /turf/simulated/floor/plating/airless, /area/space/nearstation) @@ -957,6 +953,17 @@ }, /turf/simulated/floor/plating/airless, /area/AIsattele) +"ji" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 10; + height = 35; + id = "whiteship_away"; + name = "Deep Space"; + width = 21 + }, +/turf/space, +/area/space) "yn" = ( /turf/space, /area/space/nearstation) @@ -8721,7 +8728,7 @@ aa aa aa aa -be +aa aa aa aa @@ -17223,7 +17230,7 @@ aa aa aa aa -aa +ji aa aa aa From f57c5422bac8743930fb9db8ea1d7753f1d67aa1 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Fri, 29 May 2020 21:52:45 +0200 Subject: [PATCH 039/151] fixes the virus event --- code/datums/diseases/_MobProcs.dm | 10 ++++++- code/modules/events/disease_outbreak.dm | 37 ++++++++++--------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index 63fa3af0605..81312cdfcc4 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -126,11 +126,19 @@ AddDisease(D) +/** + * Forces the mob to contract a virus. If the mob can have viruses. Ignores clothing and other protection + * Returns TRUE if it succeeds. False if it doesn't + * + * Arguments: + * * D - the disease the mob will try to contract + */ //Same as ContractDisease, except never overidden clothes checks /mob/proc/ForceContractDisease(datum/disease/D) if(!CanContractDisease(D)) - return 0 + return FALSE AddDisease(D) + return TRUE /mob/living/carbon/human/CanContractDisease(datum/disease/D) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 291ae55c743..6e2dc876603 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -1,43 +1,36 @@ /datum/event/disease_outbreak announceWhen = 15 - - var/datum/disease/advance/virus_type + var/datum/disease/D /datum/event/disease_outbreak/setup() announceWhen = rand(15, 30) + if(prob(25)) + var/virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan) + D = new virus_type() + else + var/datum/disease/advance/A = new /datum/disease/advance + A.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns + GLOB.verbs)) // random silly name + A.GenerateSymptoms(1,9,6) + A.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10))) + D = A + + D.carrier = TRUE /datum/event/disease_outbreak/announce() GLOB.event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') /datum/event/disease_outbreak/start() - if(prob(25)) - virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan) - else - virus_type = new /datum/disease/advance - virus_type.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns,GLOB.verbs)) // random silly name - virus_type.GenerateSymptoms(1,9,6) - virus_type.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10))) for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) - if(issmall(H)) //don't infect monkies; that's a waste - continue if(!H.client) continue - if(VIRUSIMMUNE in H.dna.species.species_traits) //don't let virus immune things get diseases they're not supposed to get. + if(issmall(H)) //don't infect monkies; that's a waste continue var/turf/T = get_turf(H) if(!T) continue if(!is_station_level(T.z)) continue - var/foundAlready = FALSE // don't infect someone that already has the virus - for(var/thing in H.viruses) - foundAlready = TRUE - break - if(H.stat == DEAD || foundAlready) - continue - var/datum/disease/advance/D - D = virus_type - D.carrier = TRUE - H.AddDisease(D) + if(!H.ForceContractDisease(D)) + continue break From 8b2e843c8a5bd807fc4a4801ec24d52a16281bbc Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Fri, 29 May 2020 23:02:28 +0200 Subject: [PATCH 040/151] Changes the absorb objectives text --- code/game/gamemodes/objective.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index de15f62d09d..bedc3c4809b 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -475,7 +475,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) n_p++ target_amount = min(target_amount, n_p) - explanation_text = "Absorb [target_amount] compatible genomes." + explanation_text = "Acquire [target_amount] compatible genomes. The 'Extract DNA Sting' can be used to stealthily get genomes without killing somebody." return target_amount /datum/objective/absorb/check_completion() From 645dfe20520bf7398fc8601a246f6a43be62466a Mon Sep 17 00:00:00 2001 From: trololiver112 <59520813+trololiver112@users.noreply.github.com> Date: Fri, 29 May 2020 23:52:19 +0200 Subject: [PATCH 041/151] Fixes the Changeling tentacle grab logging --- code/game/gamemodes/changeling/powers/mutations.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index d225ac6886a..707f3d57573 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -321,7 +321,7 @@ if(INTENT_GRAB) C.visible_message("[L] is grabbed by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!") - add_attack_logs(src, C, "[src] has grabbed [C] and pulled them towards [H] with a tentacle") + add_attack_logs(H, C, "[H] grabbed [C] with a changeling tentacle") C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(H, /mob/proc/tentacle_grab, C)) return 1 From 79273910425f4b0e623768613e0cd46b2c039bce Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sat, 30 May 2020 11:07:40 +0100 Subject: [PATCH 042/151] Cleans up some awful code from the ticker --- code/controllers/subsystem/statistics.dm | 28 ++++++++++++++++ code/controllers/subsystem/ticker.dm | 27 +++++----------- code/defines/procs/statistics.dm | 41 ------------------------ paradise.dme | 1 + 4 files changed, 37 insertions(+), 60 deletions(-) create mode 100644 code/controllers/subsystem/statistics.dm diff --git a/code/controllers/subsystem/statistics.dm b/code/controllers/subsystem/statistics.dm new file mode 100644 index 00000000000..3a0bf7e51e2 --- /dev/null +++ b/code/controllers/subsystem/statistics.dm @@ -0,0 +1,28 @@ +SUBSYSTEM_DEF(statistics) + name = "Statistics" + wait = 6000 // 10 minute delay between fires + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME // Only count time actually ingame to avoid logging pre-round dips + offline_implications = "Player count and admin count statistics will no longer be logged to the database. No immediate action is needed." + + +/datum/controller/subsystem/statistics/Initialize(start_timeofday) + if(!config.sql_enabled) + flags |= SS_NO_FIRE // Disable firing if SQL is disabled + return ..() + +/datum/controller/subsystem/statistics/fire(resumed = 0) + sql_poll_players() + +/datum/controller/subsystem/statistics/proc/sql_poll_players() + if(!config.sql_enabled) + return + var/playercount = GLOB.clients.len + var/admincount = GLOB.admins.len + if(!GLOB.dbcon.IsConnected()) + log_game("SQL ERROR during player polling. Failed to connect.") + else + var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") + var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time) VALUES ([playercount], [admincount], '[sqltime]')") + if(!query.Execute()) + var/err = query.ErrorMsg() + log_game("SQL ERROR during playercount polling. Error: \[[err]\]\n") diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c05d96bb441..228f1a7c528 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -29,7 +29,7 @@ SUBSYSTEM_DEF(ticker) var/pregame_timeleft // This is used for calculations var/delay_end = 0 //if set to nonzero, the round will not restart on it's own var/triai = 0//Global holder for Triumvirate - var/initialtpass = 0 //holder for inital autotransfer vote timer + var/next_autotransfer = 0 //holder for inital autotransfer vote timer var/obj/screen/cinematic = null //used for station explosion cinematic var/round_end_announced = 0 // Spam Prevention. Announce round end only once. var/ticker_going = TRUE // This used to be in the unused globals, but it turns out its actually used in a load of places. Its now a ticker var because its related to round stuff, -aa @@ -90,6 +90,11 @@ SUBSYSTEM_DEF(ticker) delay_end = 0 // reset this in case round start was delayed mode.process() mode.process_job_tasks() + + if(world.time > next_autotransfer) + SSvote.autotransfer() + next_autotransfer = world.time + config.vote_autotransfer_interval + var/game_finished = SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || mode.station_was_nuked if(config.continuous_rounds) mode.check_finished() // some modes contain var-changing code in here, so call even if we don't uses result @@ -111,19 +116,6 @@ SUBSYSTEM_DEF(ticker) else world.Reboot("Round ended.", "end_proper", "proper completion") - -/datum/controller/subsystem/ticker/proc/votetimer() - var/timerbuffer = 0 - if(initialtpass == 0) - timerbuffer = config.vote_autotransfer_initial - else - timerbuffer = config.vote_autotransfer_interval - spawn(timerbuffer) - SSvote.autotransfer() - initialtpass = 1 - votetimer() - - /datum/controller/subsystem/ticker/proc/setup() cultdat = setupcult() //Create and announce mode @@ -281,11 +273,8 @@ SUBSYSTEM_DEF(ticker) auto_toggle_ooc(0) // Turn it off round_start_time = world.time - if(config.sql_enabled) - spawn(3000) - statistic_cycle() // Polls population totals regularly and stores them in an SQL DB - - votetimer() + // Sets the auto shuttle vote to happen after the config duration + next_autotransfer = world.time + config.vote_autotransfer_initial for(var/mob/new_player/N in GLOB.mob_list) if(N.client) diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm index e6e111880fb..094e4f9ca2b 100644 --- a/code/defines/procs/statistics.dm +++ b/code/defines/procs/statistics.dm @@ -1,35 +1,3 @@ -/proc/sql_poll_players() - if(!config.sql_enabled) - return - var/playercount = 0 - for(var/mob/M in GLOB.player_list) - if(M.client) - playercount += 1 - establish_db_connection() - if(!GLOB.dbcon.IsConnected()) - log_game("SQL ERROR during player polling. Failed to connect.") - else - var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") - var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, time) VALUES ([playercount], '[sqltime]')") - if(!query.Execute()) - var/err = query.ErrorMsg() - log_game("SQL ERROR during player polling. Error : \[[err]\]\n") - - -/proc/sql_poll_admins() - if(!config.sql_enabled) - return - var/admincount = GLOB.admins.len - establish_db_connection() - if(!GLOB.dbcon.IsConnected()) - log_game("SQL ERROR during admin polling. Failed to connect.") - else - var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") - var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (admincount, time) VALUES ([admincount], '[sqltime]')") - if(!query.Execute()) - var/err = query.ErrorMsg() - log_game("SQL ERROR during admin polling. Error : \[[err]\]\n") - /proc/sql_report_round_start() // TODO if(!config.sql_enabled) @@ -110,15 +78,6 @@ var/err = query.ErrorMsg() log_game("SQL ERROR during death reporting. Error : \[[err]\]\n") -/proc/statistic_cycle() - if(!config.sql_enabled) - return - while(1) - sql_poll_players() - sleep(600) - sql_poll_admins() - sleep(6000) //Poll every ten minutes - //This proc is used for feedback. It is executed at round end. /proc/sql_commit_feedback() if(!GLOB.blackbox) diff --git a/paradise.dme b/paradise.dme index 3e4d100880a..c3dcfbd3c2d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -242,6 +242,7 @@ #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\shuttles.dm" #include "code\controllers\subsystem\spacedrift.dm" +#include "code\controllers\subsystem\statistics.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\throwing.dm" #include "code\controllers\subsystem\ticker.dm" From 0f15670ced25bd3d43be81641724c835bce66965 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Sat, 30 May 2020 15:10:21 +0200 Subject: [PATCH 043/151] Spread infestation description change --- code/game/gamemodes/changeling/powers/spiders.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/changeling/powers/spiders.dm b/code/game/gamemodes/changeling/powers/spiders.dm index 82b2db6ac7b..778ec768e55 100644 --- a/code/game/gamemodes/changeling/powers/spiders.dm +++ b/code/game/gamemodes/changeling/powers/spiders.dm @@ -1,7 +1,7 @@ /datum/action/changeling/spiders name = "Spread Infestation" desc = "Our form divides, creating arachnids which will grow into deadly beasts." - helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 DNA absorptions." + helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 stored DNA." button_icon_state = "spread_infestation" chemical_cost = 45 dna_cost = 1 From 70ca3b01013fd2f31fcf2ac5796327999434dc19 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sat, 30 May 2020 15:04:44 -0400 Subject: [PATCH 044/151] Helps Organs GC Better (#13506) --- .../mob/living/carbon/brain/brain_item.dm | 8 ++--- .../surgery/organs/augments_internal.dm | 29 ++++++++++++------- code/modules/surgery/organs/heart.dm | 13 +++++---- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 0b6bcededaf..10e57b5a893 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -26,11 +26,9 @@ mmi_icon = 'icons/mob/alien.dmi' mmi_icon_state = "AlienMMI" -/obj/item/organ/internal/brain/New() - ..() - spawn(5) - if(brainmob && brainmob.client) - brainmob.client.screen.len = null //clear the hud +/obj/item/organ/internal/brain/Destroy() + QDEL_NULL(brainmob) + return ..() /obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H) brainmob = new(src) diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 510d3b32171..19ff7fa37d8 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -141,9 +141,11 @@ /obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) if(crit_fail || emp_proof) return - crit_fail = 1 - spawn(90 / severity) - crit_fail = 0 + crit_fail = TRUE + addtimer(CALLBACK(src, .proc/reboot), 90 / severity) + +/obj/item/organ/internal/cyberimp/brain/anti_stun/proc/reboot() + crit_fail = FALSE /obj/item/organ/internal/cyberimp/brain/clown_voice name = "Comical implant" @@ -230,11 +232,13 @@ if(owner.stat == DEAD) return if(owner.nutrition <= hunger_threshold) - synthesizing = 1 + synthesizing = TRUE to_chat(owner, "You feel less hungry...") owner.adjust_nutrition(50) - spawn(50) - synthesizing = 0 + addtimer(CALLBACK(src, .proc/synth_cool), 50) + +/obj/item/organ/internal/cyberimp/chest/nutriment/proc/synth_cool() + synthesizing = FALSE /obj/item/organ/internal/cyberimp/chest/nutriment/emp_act(severity) if(!owner || emp_proof) @@ -309,10 +313,15 @@ var/mob/living/carbon/human/H = owner if(H.stat != DEAD && prob(50 / severity)) H.set_heartattack(TRUE) - spawn(600 / severity) - H.set_heartattack(FALSE) - if(H.stat == CONSCIOUS) - to_chat(H, "You feel your heart beating again!") + addtimer(CALLBACK(src, .proc/undo_heart_attack), 600 / severity) + +/obj/item/organ/internal/cyberimp/chest/reviver/proc/undo_heart_attack() + var/mob/living/carbon/human/H = owner + if(!istype(H)) + return + H.set_heartattack(FALSE) + if(H.stat == CONSCIOUS) + to_chat(H, "You feel your heart beating again!") //BOX O' IMPLANTS diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 51175fd53be..8308a793ca9 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -23,9 +23,8 @@ Stop() return - spawn(120) - if(!owner) - Stop() + if(!special) + addtimer(CALLBACK(src, .proc/stop_if_unowned), 120) /obj/item/organ/internal/heart/emp_act(intensity) if(!is_robotic() || emp_proof) @@ -43,14 +42,16 @@ return if(!beating) Restart() - spawn(80) - if(!owner) - Stop() + addtimer(CALLBACK(src, .proc/stop_if_unowned), 80) /obj/item/organ/internal/heart/safe_replace(mob/living/carbon/human/target) Restart() ..() +/obj/item/organ/internal/heart/proc/stop_if_unowned() + if(!owner) + Stop() + /obj/item/organ/internal/heart/proc/Stop() beating = FALSE update_icon() From ac49debfceccc685c439ac1b135a55b7d99bbcd2 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Sun, 31 May 2020 20:48:01 +0200 Subject: [PATCH 045/151] Make light_constructs use X_acts --- code/modules/power/lighting.dm | 127 +++++++++++++++++---------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 78c2561ae7d..44967c5d4ed 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -39,81 +39,86 @@ if(3) . += "The casing is closed." -/obj/machinery/light_construct/attackby(obj/item/W as obj, mob/living/user as mob, params) - src.add_fingerprint(user) - if(istype(W, /obj/item/wrench)) - if(src.stage == 1) - playsound(src.loc, W.usesound, 75, 1) - to_chat(usr, "You begin deconstructing [src].") - if(!do_after(usr, 30 * W.toolspeed, target = src)) +/obj/machinery/light_construct/wrench_act(mob/living/user, obj/item/I) + . = TRUE + switch(stage) + if(1) + to_chat(user, "You begin deconstructing [src].") + if(!I.use_tool(src, user, 30, volume = I.tool_volume)) return - new /obj/item/stack/sheet/metal( get_turf(src.loc), sheets_refunded ) - user.visible_message("[user.name] deconstructs [src].", \ - "You deconstruct [src].", "You hear a noise.") - playsound(src.loc, W.usesound, 75, 1) + new /obj/item/stack/sheet/metal(get_turf(loc), sheets_refunded) + user.visible_message("[user.name] deconstructs [src].", \ + "You deconstruct [src].", "You hear a noise.") qdel(src) - if(src.stage == 2) - to_chat(usr, "You have to remove the wires first.") - return + if(2) + to_chat(user, "You have to remove the wires first.") + if(3) + to_chat(user, "You have to unscrew the case first.") - if(src.stage == 3) - to_chat(usr, "You have to unscrew the case first.") - return - - if(istype(W, /obj/item/wirecutters)) - if(src.stage != 2) return - src.stage = 1 - switch(fixture_type) - if("tube") - src.icon_state = "tube-construct-stage1" - if("bulb") - src.icon_state = "bulb-construct-stage1" - new /obj/item/stack/cable_coil(get_turf(src.loc), 1, paramcolor = COLOR_RED) - user.visible_message("[user.name] removes the wiring from [src].", \ - "You remove the wiring from [src].", "You hear a noise.") - playsound(loc, W.usesound, 100, 1) +/obj/machinery/light_construct/wirecutter_act(mob/living/user, obj/item/I) + if(stage != 2) return + . = TRUE + if(!I.use_tool(src, user, 0)) + return + playsound(loc, I.usesound, 100, 1) + . = TRUE + stage = 1 + switch(fixture_type) + if("tube") + icon_state = "tube-construct-stage1" + if("bulb") + icon_state = "bulb-construct-stage1" + new /obj/item/stack/cable_coil(get_turf(loc), 1, paramcolor = COLOR_RED) + user.visible_message("[user] removes the wiring from [src].", \ + "You remove the wiring from [src].", "You hear a noise.") + +/obj/machinery/light_construct/screwdriver_act(mob/living/user, obj/item/I) + if(stage != 2) + return + . = TRUE + if(!I.use_tool(src, user, 0)) + return + switch(fixture_type) + if("tube") + icon_state = "tube-empty" + if("bulb") + icon_state = "bulb-empty" + stage = 3 + user.visible_message("[user] closes [src]'s casing.", \ + "You close [src]'s casing.", "You hear a noise.") + playsound(loc, I.usesound, 75, 1) + + switch(fixture_type) + if("tube") + newlight = new /obj/machinery/light/built(loc) + if("bulb") + newlight = new /obj/machinery/light/small/built(loc) + + newlight.dir = dir + transfer_fingerprints_to(newlight) + qdel(src) + +/obj/machinery/light_construct/attackby(obj/item/W, mob/living/user, params) + add_fingerprint(user) if(istype(W, /obj/item/stack/cable_coil)) - if(src.stage != 1) return + if(stage != 1) + return var/obj/item/stack/cable_coil/coil = W coil.use(1) switch(fixture_type) if("tube") - src.icon_state = "tube-construct-stage2" + icon_state = "tube-construct-stage2" if("bulb") - src.icon_state = "bulb-construct-stage2" - src.stage = 2 + icon_state = "bulb-construct-stage2" + stage = 2 playsound(loc, coil.usesound, 50, 1) - user.visible_message("[user.name] adds wires to [src].", \ - "You add wires to [src].") + user.visible_message("[user.name] adds wires to [src].", \ + "You add wires to [src].") return - if(istype(W, /obj/item/screwdriver)) - if(src.stage == 2) - switch(fixture_type) - if("tube") - src.icon_state = "tube-empty" - if("bulb") - src.icon_state = "bulb-empty" - src.stage = 3 - user.visible_message("[user.name] closes [src]'s casing.", \ - "You close [src]'s casing.", "You hear a noise.") - playsound(src.loc, W.usesound, 75, 1) - - switch(fixture_type) - - if("tube") - newlight = new /obj/machinery/light/built(src.loc) - if("bulb") - newlight = new /obj/machinery/light/small/built(src.loc) - - newlight.dir = src.dir - src.transfer_fingerprints_to(newlight) - qdel(src) - return - else - return ..() + return ..() /obj/machinery/light_construct/blob_act(obj/structure/blob/B) if(B && B.loc == loc) From ca1467efdbc596cb2d33a465e1e4c1618694a8c8 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 1 Jun 2020 22:53:38 +0200 Subject: [PATCH 046/151] You won't hit an airlock now when using a wirecutter --- code/game/machinery/doors/airlock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1a8828012dc..73d0e9281e1 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -949,7 +949,7 @@ About the new airlock wires panel: if(note) remove_airlock_note(user, TRUE) else - return interact_with_panel(user) + interact_with_panel(user) /obj/machinery/door/airlock/multitool_act(mob/user, obj/item/I) if(!headbutt_shock_check(user)) From ba0897928f27c60366d9e75b20d375cc5c42e700 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Tue, 2 Jun 2020 12:40:24 +0100 Subject: [PATCH 047/151] Renames the old station Delta wing to Theta --- .../RandomRuins/SpaceRuins/oldstation.dmm | 224 +++++++++--------- .../mission_code/ruins/oldstation.dm | 12 +- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm index 58eae91a94f..6562103334e 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm @@ -510,10 +510,10 @@ /area/template_noop) "bu" = ( /turf/simulated/wall/rust, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bv" = ( /turf/simulated/wall, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bw" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, @@ -615,7 +615,7 @@ "bM" = ( /obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/blood/old, @@ -623,16 +623,16 @@ /obj/effect/decal/cleanable/cobweb, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bO" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bP" = ( /obj/structure/sign/poster/official/science, /turf/simulated/wall/rust, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bQ" = ( /turf/simulated/wall/rust, /area/ruin/space/ancientstation/hivebot) @@ -647,7 +647,7 @@ "bS" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/crate, @@ -662,7 +662,7 @@ /obj/item/bonesetter, /obj/item/stack/medical/bruise_pack/advanced, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "bU" = ( /obj/machinery/door/airlock/command, /turf/simulated/floor/plasteel/airless, @@ -764,7 +764,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/command{ - name = "Delta Station Access" + name = "Theta Station Access" }, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/powered) @@ -779,7 +779,7 @@ /obj/effect/spawner/window/reinforced, /obj/structure/transit_tube, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ck" = ( /obj/structure/lattice/catwalk, /turf/simulated/floor/plating/airless, @@ -789,19 +789,19 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cm" = ( /obj/effect/decal/cleanable/dirt, /obj/item/stack/medical/bruise_pack, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cn" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/command, /obj/structure/barricade/wooden, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "co" = ( /obj/effect/decal/cleanable/blood/oil, /mob/living/simple_animal/hostile/hivebot, @@ -818,7 +818,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cq" = ( /obj/structure/cable{ d1 = 4; @@ -830,7 +830,7 @@ /obj/machinery/door/airlock/science, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cr" = ( /obj/structure/cable{ d1 = 1; @@ -840,14 +840,14 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cs" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/science, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ct" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-dead" @@ -855,12 +855,12 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cu" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/maintenance_hatch, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cv" = ( /obj/effect/decal/cleanable/blood/oil, /obj/effect/decal/remains/robot{ @@ -964,7 +964,7 @@ /obj/item/pickaxe, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cJ" = ( /obj/machinery/light{ icon_state = "tube1"; @@ -973,7 +973,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cK" = ( /obj/effect/decal/remains/robot{ icon_state = "gib5" @@ -998,7 +998,7 @@ /obj/machinery/door/airlock/science, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -1006,7 +1006,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -1015,7 +1015,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cP" = ( /obj/effect/decal/cleanable/blood/oil, /mob/living/simple_animal/hostile/hivebot/strong, @@ -1033,7 +1033,7 @@ /obj/item/tank/plasma/full, /obj/item/tank/plasma/full, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "cR" = ( /obj/structure/table, /obj/item/storage/firstaid/ancient, @@ -1065,7 +1065,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ dir = 1; - name = "Delta Prototype Lab APC"; + name = "Thete Prototype Lab APC"; pixel_y = 24; report_power_alarm = 0; start_charge = 0 @@ -1165,7 +1165,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "di" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 @@ -1173,7 +1173,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dj" = ( /turf/simulated/wall/rust, /area/ruin/space/ancientstation/rnd) @@ -1206,7 +1206,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dp" = ( /obj/machinery/power/solar, /obj/structure/cable/yellow{ @@ -1227,7 +1227,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dr" = ( /obj/item/roller, /obj/effect/decal/cleanable/dirt, @@ -1314,7 +1314,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dD" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ @@ -1344,7 +1344,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dI" = ( /obj/machinery/door/airlock/medical/glass{ name = "Medical Bay" @@ -1368,7 +1368,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot/strong, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "dL" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -1514,7 +1514,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "eb" = ( /obj/machinery/light{ dir = 8 @@ -1575,7 +1575,7 @@ pixel_x = 28 }, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ei" = ( /obj/item/circuitboard/sleeper, /obj/effect/decal/cleanable/dirt, @@ -1695,13 +1695,13 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ew" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ex" = ( /obj/machinery/firealarm{ dir = 4; @@ -1719,12 +1719,12 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ez" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/emitter, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "eA" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel/airless{ @@ -1888,7 +1888,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "eT" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/r_n_d/protolathe, @@ -1926,7 +1926,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/field/generator, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "eY" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -2009,7 +2009,7 @@ /obj/item/apc_electronics, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fj" = ( /obj/structure/cable{ d1 = 1; @@ -2035,12 +2035,12 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fm" = ( /obj/machinery/light{ dir = 8 @@ -2079,7 +2079,7 @@ "fq" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fr" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -2134,7 +2134,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fx" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -2143,7 +2143,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2152,7 +2152,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fz" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2162,7 +2162,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "fA" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2519,7 +2519,7 @@ icon_state = "4-8" }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ga" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2531,7 +2531,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gb" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2548,7 +2548,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gc" = ( /mob/living/simple_animal/hostile/carp, /turf/template_noop, @@ -2574,7 +2574,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ge" = ( /obj/structure/table, /obj/structure/cable{ @@ -2724,14 +2724,14 @@ /obj/item/trash/plate, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gx" = ( /obj/structure/chair{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gy" = ( /obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, @@ -2746,7 +2746,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/power/rad_collector, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gB" = ( /obj/item/solar_assembly, /turf/simulated/floor/plating/airless, @@ -2816,7 +2816,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gK" = ( /obj/machinery/processor, /obj/effect/decal/cleanable/dirt, @@ -2860,13 +2860,13 @@ /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gQ" = ( /obj/structure/cable{ d1 = 1; @@ -2906,7 +2906,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gU" = ( /obj/machinery/light{ icon_state = "tube1"; @@ -2915,7 +2915,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gV" = ( /obj/structure/cable{ d1 = 1; @@ -2932,7 +2932,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot/strong, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "gX" = ( /obj/machinery/computer{ desc = "A computer long since rendered non-functional due to lack of maintenance. Spitting out error messages."; @@ -3035,7 +3035,7 @@ }, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "hk" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -3072,7 +3072,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot/strong, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ho" = ( /obj/machinery/light/small{ dir = 8 @@ -3145,7 +3145,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "hu" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -3265,7 +3265,7 @@ req_one_access_txt = "271" }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "hF" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel{ @@ -3414,14 +3414,14 @@ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "hV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/particle_accelerator/particle_emitter/right{ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "hW" = ( /obj/machinery/light/small{ dir = 8 @@ -3508,13 +3508,13 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ dir = 1; - name = "Delta Main Corridor APC"; + name = "Theta Main Corridor APC"; pixel_y = 24; report_power_alarm = 0; start_charge = 0 }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ie" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 @@ -3529,14 +3529,14 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "if" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ig" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair{ @@ -3602,7 +3602,7 @@ pixel_x = 28 }, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "in" = ( /turf/simulated/floor/plating/airless, /area/ruin/space/ancientstation/atmo) @@ -3676,7 +3676,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ix" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, @@ -3690,19 +3690,19 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iz" = ( /obj/machinery/atmospherics/unary/vent_pump{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iA" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/recharge_station, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iB" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3821,7 +3821,7 @@ id_tag = "ancient" }, /obj/machinery/door/airlock/command{ - name = "Delta Station Access" + name = "Theta Station Access" }, /turf/simulated/floor/plasteel, /area/ruin/space/ancientstation/powered) @@ -3856,7 +3856,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iS" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3865,14 +3865,14 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/science, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iT" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3880,7 +3880,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3891,7 +3891,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iW" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3921,7 +3921,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iY" = ( /obj/machinery/light/small{ dir = 4 @@ -3931,7 +3931,7 @@ /obj/item/flash, /obj/item/flash, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "iZ" = ( /obj/structure/closet/crate/radiation, /obj/item/stack/sheet/mineral/uranium{ @@ -4005,7 +4005,7 @@ icon_state = "plant-dead" }, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "ji" = ( /obj/structure/cable{ d1 = 4; @@ -4014,7 +4014,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jj" = ( /obj/structure/cable{ d1 = 4; @@ -4025,7 +4025,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/science, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jk" = ( /obj/structure/cable{ d1 = 4; @@ -4035,7 +4035,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jl" = ( /obj/structure/cable{ d1 = 2; @@ -4044,27 +4044,27 @@ }, /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jm" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/particle_accelerator/particle_emitter/center{ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jn" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/science, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jo" = ( /obj/effect/decal/cleanable/dirt, /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-dead" }, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "jp" = ( /obj/structure/cable{ d1 = 1; @@ -4241,7 +4241,7 @@ }, /obj/machinery/power/apc{ dir = 4; - name = "Delta RnD APC"; + name = "Theta RnD APC"; pixel_x = 24; report_power_alarm = 0; start_charge = 0 @@ -4726,7 +4726,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/door/firedoor, @@ -4734,14 +4734,14 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kO" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kP" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -4757,39 +4757,39 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kR" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kS" = ( /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/particle_accelerator/particle_emitter/left{ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kU" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/particle_accelerator/fuel_chamber{ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/particle_accelerator/end_cap{ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kW" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -4813,7 +4813,7 @@ icon = 'icons/obj/machines/particle_accelerator3.dmi' }, /turf/simulated/floor/plating, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "kZ" = ( /obj/structure/lattice/catwalk, /turf/simulated/floor/plating, @@ -4860,13 +4860,13 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "le" = ( /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "lf" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -4878,7 +4878,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "lg" = ( /obj/structure/cable{ d1 = 4; @@ -4888,7 +4888,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "lh" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/firealarm{ @@ -4897,7 +4897,7 @@ }, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "li" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/decal/cleanable/dirt, @@ -5151,7 +5151,7 @@ /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "lE" = ( /obj/machinery/light/small{ dir = 4 @@ -5207,7 +5207,7 @@ }, /mob/living/simple_animal/hostile/hivebot, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) "lL" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/vest/old, @@ -5240,7 +5240,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/warning_stripes/arrow, /turf/simulated/floor/plasteel, -/area/ruin/space/ancientstation/deltacorridor) +/area/ruin/space/ancientstation/thetacorridor) (1,1,1) = {" aa diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index e939cf06f32..4d3c54f8f4b 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -105,7 +105,7 @@ /obj/item/paper/fluff/ruins/oldstation/damagereport name = "Damage Report" - info = "*Damage Report*

Alpha Station - Destroyed

Beta Station - Catastrophic Damage. Medical, destroyed. Atmospherics, partially destroyed. Engine Core, destroyed.

Charlie Station - Intact. Loss of oxygen to eastern side of main corridor.

Delta Station - Intact. WARNING: Unknown force occupying Delta Station. Intent unknown. Species unknown. Numbers unknown.

Recommendation - Reestablish station powernet via solar array. Reestablish station atmospherics system to restore air." + info = "*Damage Report*

Alpha Station - Destroyed

Beta Station - Catastrophic Damage. Medical, destroyed. Atmospherics, partially destroyed. Engine Core, destroyed.

Charlie Station - Intact. Loss of oxygen to eastern side of main corridor.

Theta Station - Intact. WARNING: Unknown force occupying Theta Station. Intent unknown. Species unknown. Numbers unknown.

Recommendation - Reestablish station powernet via solar array. Reestablish station atmospherics system to restore air." /obj/item/paper/fluff/ruins/oldstation/protosuit name = "B01-RIG Hardsuit Report" @@ -145,7 +145,7 @@ info = "Artificial Program's report to surviving crewmembers.

Crew were placed into cryostasis on March 10th, 2445.

Crew were awoken from cryostasis around June, 2557.

\ SIGNIFICANT EVENTS OF NOTE
1: The primary radiation detectors were taken offline after 112 years due to power failure, secondary radiation detectors showed no residual \ radiation on station. Deduction, primarily detector was malfunctioning and was producing a radiation signal when there was none.

2: A data burst from a nearby Nanotrasen Space \ - Station was received, this data burst contained research data that has been uploaded to our RnD labs.

3: Unknown invasion force has occupied Delta station." + Station was received, this data burst contained research data that has been uploaded to our RnD labs.

3: Unknown invasion force has occupied Theta station." /obj/item/paper/fluff/ruins/oldstation/generator_manual name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator manual" @@ -350,16 +350,16 @@ name = "Charlie Station Security" icon_state = "red" -/area/ruin/space/ancientstation/deltacorridor - name = "Delta Station Main Corridor" +/area/ruin/space/ancientstation/thetacorridor + name = "Theta Station Main Corridor" icon_state = "green" /area/ruin/space/ancientstation/proto - name = "Delta Station Prototype Lab" + name = "Theta Station Prototype Lab" icon_state = "toxlab" /area/ruin/space/ancientstation/rnd - name = "Delta Station Research and Development" + name = "Theta Station Research and Development" icon_state = "toxlab" /area/ruin/space/ancientstation/hivebot From 6cf3cba557defcb2a711f28bcc6e2145ccecfb9d Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Tue, 2 Jun 2020 21:38:43 +0100 Subject: [PATCH 048/151] Removes something which shouldnt really exist here --- .../client/preference/preferences_mysql.dm | 4 ++++ .../mob/living/carbon/human/body_accessories.dm | 9 --------- icons/mob/body_accessory_64.dmi | Bin 783 -> 0 bytes 3 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 icons/mob/body_accessory_64.dmi diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 811d163c955..94f724b77a6 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -320,6 +320,10 @@ if(!rlimb_data) src.rlimb_data = list() if(!loadout_gear) loadout_gear = list() + // Check if the current body accessory exists + if(!GLOB.body_accessory_by_name[body_accessory]) + body_accessory = null + return 1 /datum/preferences/proc/save_character(client/C) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index e214f6068bb..043a704ab0c 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -77,15 +77,6 @@ GLOBAL_LIST_INIT(body_accessory_by_species, list("None" = null)) /datum/body_accessory/body blend_mode = ICON_MULTIPLY -/datum/body_accessory/body/snake - name = "Snake" - - icon = 'icons/mob/body_accessory_64.dmi' - icon_state = "snake" - - pixel_x_offset = -16 - - //Tails /datum/body_accessory/tail icon = 'icons/mob/body_accessory.dmi' diff --git a/icons/mob/body_accessory_64.dmi b/icons/mob/body_accessory_64.dmi deleted file mode 100644 index 72d7f5e0d4647f7c743b8642b269ef8c8871c134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 783 zcmV+q1MvKbP)C0000sP)t-sz`($l zmzJ`!vBSf|sHdiyn3#u$hSAZ{+S=NJfPjvUje2@|kdKeJxVWyauBWG_tgNiGv$KvX zg!cdd00DGTPE!Ct=GbNc004A)R9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo` zEh^5;&r`5fFwryM;w;ZhDainG%uKjAGg33tGfIFQVtE>VN0R;|DVON*LEO4*a9KMy;f^AExwDhOmgRC0RR91007_*atrWLDiF-=f zGC=GMFy}4~R9x=5JAmnzJp=3wQ0DmFJChx52NxTcj|`C0z^;5ca2n82Vj!A<^_9MV z4K6l+k#DUAGO+ZT_2|kI^XfE^v!=h*TAOCTyAMp6`z;A;b?(KBs%r*vl8bvEE`24^ zbDgJGUmT=^>(&1|AUxj_|1|~x00000{~LEj`Q3pE>!oc`;jQV#TbZ5)h{iHTjT@*# z0+6??T8@goFprUQ+(6D_uqMFsl%QBSRqR$AMAu+zQ=e=qR`7pGe=ll_-N#cf6JRqb zd!78L1Ito5tLkE2M$o`kRsV=%v-)@~rnC+)jxiivgSi5HN*`h8s=VXiocS!xvwha| zb8H_-2F!uUTiCnxeXDQCcdl-mn9oD*hmH#F!>v^vE@4OlH3=(=GHya|929#RF`vj- zzNdwWJ|qb50u5+!_Nco~eeGbo*MI{( Date: Wed, 3 Jun 2020 16:28:24 +0200 Subject: [PATCH 049/151] Review fixes --- code/modules/power/lighting.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 44967c5d4ed..0a31d882488 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -47,7 +47,7 @@ if(!I.use_tool(src, user, 30, volume = I.tool_volume)) return new /obj/item/stack/sheet/metal(get_turf(loc), sheets_refunded) - user.visible_message("[user.name] deconstructs [src].", \ + user.visible_message("[user] deconstructs [src].", \ "You deconstruct [src].", "You hear a noise.") qdel(src) if(2) @@ -95,7 +95,7 @@ if("bulb") newlight = new /obj/machinery/light/small/built(loc) - newlight.dir = dir + newlight.setDir(dir) transfer_fingerprints_to(newlight) qdel(src) From 70b46d8aeab7e90bfe3f32d8990c90b834ca5ed6 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Wed, 3 Jun 2020 21:43:30 -0400 Subject: [PATCH 050/151] Life refactor (#13471) * Life Refactor WIP * part 2 * part 3 * runtime fix * newlines * tweaks * perspective checks * fixes * remote view tweaks * more fixes * robot fixes * better updating * cleaned up icon procs * less proc call overhead * performance gains * more optimization * shorter lists, removal of unecesary code * gene OOP and dna styling cleanup * oops * axe disabilities * typeless loop * various tweaks and fixes * brain checks * runtime fixes * cryo vision fixes --- code/ATMOSPHERICS/atmospherics.dm | 4 + code/__DEFINES/genetics.dm | 123 ++-- code/__HELPERS/game.dm | 2 +- code/__HELPERS/unsorted.dm | 2 +- code/_globalvars/lists/mobs.dm | 41 +- code/_onclick/click.dm | 10 +- code/_onclick/hud/other_mobs.dm | 4 + code/_onclick/hud/screen_objects.dm | 6 +- code/controllers/subsystem/afk.dm | 2 +- code/controllers/subsystem/jobs.dm | 5 +- code/controllers/subsystem/mobs.dm | 12 +- code/controllers/subsystem/weather.dm | 2 +- code/datums/diseases/advance/advance.dm | 2 +- .../diseases/advance/symptoms/deafness.dm | 2 +- code/datums/diseases/advance/symptoms/skin.dm | 4 +- code/datums/holocall.dm | 1 - code/datums/mind.dm | 4 +- code/datums/spells/cluwne.dm | 12 +- code/datums/spells/devil.dm | 1 - code/datums/spells/genetic.dm | 5 - code/datums/spells/horsemask.dm | 2 +- code/datums/spells/summonitem.dm | 8 +- code/datums/spells/touch_attacks.dm | 8 +- code/datums/spells/wizard.dm | 2 +- code/datums/wires/wires.dm | 2 +- code/game/atoms.dm | 14 +- code/game/dna/dna2.dm | 203 ++++--- code/game/dna/dna2_domutcheck.dm | 10 +- code/game/dna/dna2_helpers.dm | 95 +-- code/game/dna/dna_modifier.dm | 532 +++++++++-------- code/game/dna/genes/disabilities.dm | 168 +++--- code/game/dna/genes/gene.dm | 46 +- code/game/dna/genes/goon_disabilities.dm | 51 +- code/game/dna/genes/goon_powers.dm | 91 ++- code/game/dna/genes/monkey.dm | 9 +- code/game/dna/genes/powers.dm | 141 +++-- code/game/dna/genes/vg_disabilities.dm | 10 +- code/game/dna/genes/vg_powers.dm | 57 +- code/game/gamemodes/blob/overmind.dm | 8 +- code/game/gamemodes/blob/powers.dm | 2 +- .../changeling/powers/augmented_eyesight.dm | 2 +- .../gamemodes/changeling/powers/fakedeath.dm | 5 +- .../gamemodes/changeling/powers/mutations.dm | 4 +- code/game/gamemodes/cult/cult_comms.dm | 4 +- .../gamemodes/devil/true_devil/inventory.dm | 10 +- code/game/gamemodes/miniantags/borer/borer.dm | 2 - .../gamemodes/miniantags/guardian/guardian.dm | 6 +- .../miniantags/slaughter/slaughter.dm | 2 +- code/game/gamemodes/revolution/revolution.dm | 2 +- code/game/gamemodes/setupgame.dm | 2 +- .../shadowling/shadowling_abilities.dm | 4 +- code/game/gamemodes/vampire/vampire_powers.dm | 2 +- code/game/gamemodes/wizard/artefact.dm | 4 +- code/game/gamemodes/wizard/spellbook.dm | 2 +- code/game/machinery/adv_med.dm | 12 +- code/game/machinery/computer/camera.dm | 5 +- .../machinery/computer/camera_advanced.dm | 7 +- code/game/machinery/cryo.dm | 10 +- code/game/machinery/cryopod.dm | 2 +- code/game/machinery/transformer.dm | 2 +- code/game/mecha/mecha.dm | 1 - .../effects/decals/Cleanable/humans.dm | 2 +- code/game/objects/items/devices/camera_bug.dm | 22 +- .../objects/items/devices/enginepicker.dm | 2 +- code/game/objects/items/devices/flashlight.dm | 2 +- code/game/objects/items/devices/scanners.dm | 6 +- .../objects/items/robot/robot_upgrades.dm | 2 +- code/game/objects/items/weapons/cigs.dm | 2 +- .../objects/items/weapons/dnascrambler.dm | 2 +- .../objects/items/weapons/gift_wrappaper.dm | 3 +- .../objects/items/weapons/melee/energy.dm | 4 +- code/game/objects/items/weapons/shields.dm | 2 +- .../crates_lockers/closets/statue.dm | 4 +- .../transit_tubes/transit_tube_pod.dm | 8 +- code/game/objects/structures/watercloset.dm | 24 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/debug.dm | 20 +- code/modules/admin/verbs/randomverbs.dm | 4 +- .../awaymissions/mission_code/wildwest.dm | 20 +- code/modules/client/client defines.dm | 1 - code/modules/clothing/glasses/glasses.dm | 3 +- code/modules/clothing/spacesuits/rig/rig.dm | 2 +- code/modules/clothing/suits/hood.dm | 2 +- code/modules/clothing/suits/toggles.dm | 2 +- code/modules/events/disease_outbreak.dm | 2 +- code/modules/events/ion_storm.dm | 2 +- code/modules/events/mass_hallucination.dm | 2 +- code/modules/events/sentience.dm | 2 +- .../events/spontaneous_appendicitis.dm | 2 +- code/modules/flufftext/Hallucination.dm | 6 +- code/modules/martial_arts/martial.dm | 2 +- .../mining/lavaland/loot/colossus_loot.dm | 6 +- code/modules/mob/dead/observer/observer.dm | 33 -- code/modules/mob/holder.dm | 1 - code/modules/mob/inventory.dm | 4 +- code/modules/mob/language.dm | 2 +- code/modules/mob/living/carbon/alien/alien.dm | 21 +- .../carbon/alien/humanoid/caste/drone.dm | 3 +- .../carbon/alien/humanoid/caste/hunter.dm | 23 - .../carbon/alien/humanoid/caste/sentinel.dm | 22 - .../living/carbon/alien/humanoid/empress.dm | 33 +- .../living/carbon/alien/humanoid/humanoid.dm | 1 - .../mob/living/carbon/alien/humanoid/life.dm | 69 --- .../mob/living/carbon/alien/humanoid/queen.dm | 31 +- .../carbon/alien/humanoid/update_icons.dm | 43 +- .../mob/living/carbon/alien/larva/larva.dm | 6 +- .../mob/living/carbon/alien/larva/life.dm | 69 +-- code/modules/mob/living/carbon/alien/life.dm | 12 + .../living/carbon/alien/special/facehugger.dm | 2 +- code/modules/mob/living/carbon/brain/MMI.dm | 4 +- code/modules/mob/living/carbon/brain/brain.dm | 3 +- .../mob/living/carbon/brain/brain_item.dm | 4 +- code/modules/mob/living/carbon/brain/life.dm | 6 +- code/modules/mob/living/carbon/carbon.dm | 2 +- .../mob/living/carbon/human/appearance.dm | 4 +- code/modules/mob/living/carbon/human/death.dm | 23 +- code/modules/mob/living/carbon/human/emote.dm | 6 +- code/modules/mob/living/carbon/human/human.dm | 15 +- .../mob/living/carbon/human/human_damage.dm | 2 - .../mob/living/carbon/human/human_defense.dm | 16 +- .../mob/living/carbon/human/human_organs.dm | 14 +- .../mob/living/carbon/human/inventory.dm | 55 +- code/modules/mob/living/carbon/human/life.dm | 539 +++++++++--------- code/modules/mob/living/carbon/human/say.dm | 2 +- .../living/carbon/human/species/_species.dm | 101 +--- .../mob/living/carbon/human/species/slime.dm | 2 +- .../living/carbon/human/species/tajaran.dm | 2 +- .../mob/living/carbon/human/species/unathi.dm | 2 +- .../mob/living/carbon/human/species/vox.dm | 2 +- .../living/carbon/human/species/vulpkanin.dm | 2 +- .../mob/living/carbon/human/species/wryn.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 143 ++--- .../mob/living/carbon/human/update_stat.dm | 2 +- code/modules/mob/living/carbon/life.dm | 127 +++-- .../mob/living/carbon/update_status.dm | 6 +- code/modules/mob/living/damage_procs.dm | 2 + code/modules/mob/living/death.dm | 5 +- code/modules/mob/living/life.dm | 204 ++++--- code/modules/mob/living/living.dm | 14 +- code/modules/mob/living/silicon/ai/life.dm | 4 +- .../mob/living/silicon/ai/update_status.dm | 2 +- code/modules/mob/living/silicon/pai/life.dm | 28 +- .../modules/mob/living/silicon/robot/death.dm | 2 +- .../mob/living/silicon/robot/drone/drone.dm | 2 + .../silicon/robot/drone/update_status.dm | 2 +- .../mob/living/silicon/robot/inventory.dm | 1 + code/modules/mob/living/silicon/robot/life.dm | 77 +-- .../modules/mob/living/silicon/robot/robot.dm | 34 +- .../mob/living/silicon/robot/robot_damage.dm | 12 +- .../mob/living/silicon/robot/update_status.dm | 9 +- .../mob/living/simple_animal/bot/bot.dm | 14 - .../mob/living/simple_animal/bot/mulebot.dm | 8 - .../mob/living/simple_animal/constructs.dm | 147 +++-- .../hostile/megafauna/bubblegum.dm | 2 +- .../living/simple_animal/hostile/statue.dm | 2 +- .../living/simple_animal/hostile/syndicate.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 10 +- .../mob/living/simple_animal/slime/slime.dm | 2 +- code/modules/mob/living/stat_states.dm | 2 +- code/modules/mob/living/status_procs.dm | 44 +- code/modules/mob/living/update_status.dm | 24 +- code/modules/mob/mob.dm | 51 +- code/modules/mob/mob_defines.dm | 2 - code/modules/mob/mob_helpers.dm | 8 +- code/modules/mob/new_player/new_player.dm | 4 +- .../mob/new_player/preferences_setup.dm | 2 +- code/modules/mob/typing_indicator.dm | 2 +- .../programs/research/airestorer.dm | 2 +- code/modules/ninja/energy_katana.dm | 2 +- code/modules/paperwork/paperplane.dm | 2 +- code/modules/power/singularity/narsie.dm | 2 +- code/modules/power/supermatter/supermatter.dm | 2 +- code/modules/reagents/chemistry/holder.dm | 1 + code/modules/reagents/chemistry/reagents.dm | 10 +- .../reagents/chemistry/reagents/medicine.dm | 2 +- .../reagents/chemistry/reagents/water.dm | 10 +- code/modules/recycling/disposal.dm | 25 +- code/modules/recycling/sortingmachinery.dm | 2 +- code/modules/research/experimentor.dm | 4 +- code/modules/surgery/organs/ears.dm | 4 +- code/modules/surgery/organs/eyes.dm | 12 +- code/modules/surgery/organs/organ_external.dm | 6 +- icons/mob/screen_alien.dmi | Bin 26909 -> 26695 bytes 183 files changed, 1943 insertions(+), 2286 deletions(-) diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 507142c0892..002b3ecc691 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -343,3 +343,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) /obj/machinery/atmospherics/update_remote_sight(mob/user) user.sight |= (SEE_TURFS|BLIND) . = ..() + +//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. +/obj/machinery/atmospherics/proc/can_see_pipes() + return TRUE diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index 4ac05376e9d..58571e8b1ca 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -24,78 +24,61 @@ /////////////////////////////////////// // MUTATIONS /////////////////////////////////////// + // Generic mutations: -#define TK 1 -#define COLDRES 2 -#define XRAY 3 -#define HULK 4 -#define CLUMSY 5 -#define FAT 6 -#define HUSK 7 -#define NOCLONE 8 - -// Extra powers: -#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes - -//species mutation -#define WINGDINGS 10 // Ayy lmao - -//2spooky -#define SKELETON 29 -#define PLANT 30 - -// Other Mutations: -#define BREATHLESS 100 // no breathing -#define REMOTE_VIEW 101 // remote viewing -#define REGEN 102 // health regen -#define RUN 103 // no slowdown -#define REMOTE_TALK 104 // remote talking -#define MORPH 105 // changing appearance -#define HEATRES 106 // heat resistance -#define HALLUCINATE 107 // hallucinations -#define FINGERPRINTS 108 // no fingerprints -#define NO_SHOCK 109 // insulated hands -#define DWARF 110 // table climbing - -// Goon muts -#define OBESITY 200 // Decreased metabolism -// 201 undefined -#define STRONG 202 // (Nothing) -#define SOBER 203 // Increased alcohol metabolism -#define PSY_RESIST 204 // Block remoteview -// 205 undefined -#define EMPATH 206 //Read minds -#define COMIC 207 //Comic Sans - -// /vg/ muts -#define LOUD 208 // CAUSES INTENSE YELLING -#define DIZZY 210 // Trippy. - -#define LISP 300 -#define RADIOACTIVE 301 -#define CHAV 302 -#define SWEDISH 303 -#define SCRAMBLED 304 -#define HORNS 305 -#define IMMOLATE 306 -#define CLOAK 307 -#define CHAMELEON 308 -#define CRYO 309 -#define EATER 310 - -#define JUMPY 400 -#define POLYMORPH 401 - +#define TK "telekenesis" +#define COLDRES "cold_resistance" +#define XRAY "xray" +#define HULK "hulk" +#define CLUMSY "clumsy" +#define FAT "fat" +#define HUSK "husk" +#define NOCLONE "noclone" +#define LASER "eyelaser" // harm intent - click anywhere to shoot lasers from eyes +#define WINGDINGS "wingdings" // Ayy lmao +#define SKELETON "skeleton" +#define BREATHLESS "breathless" // no breathing +#define REMOTE_VIEW "remove_view" // remote viewing +#define REGEN "regeneration" // health regen +#define RUN "increased_run" // no slowdown +#define REMOTE_TALK "remote_talk" // remote talking +#define MORPH "morph" // changing appearance +#define HEATRES "heat_resistance" // heat resistance +#define HALLUCINATE "hallucinate" // hallucinations +#define FINGERPRINTS "no_prints" // no fingerprints +#define NO_SHOCK "no_shock" // insulated hands +#define DWARF "dwarf" // table climbing +#define OBESITY "obesity" // Decreased metabolism +#define STRONG "strong" // (Nothing) +#define SOBER "sober" // Increased alcohol metabolism +#define PSY_RESIST "psy_resist" // Block remoteview +#define EMPATH "empathy" //Read minds +#define COMIC "comic_sans" //Comic Sans +#define LOUD "loudness" // CAUSES INTENSE YELLING +#define DIZZY "dizzy" // Trippy. +#define LISP "lisp" +#define RADIOACTIVE "radioactive" +#define CHAV "chav" +#define SWEDISH "swedish" +#define SCRAMBLED "scrambled" +#define HORNS "horns" +#define IMMOLATE "immolate" +#define CLOAK "cloak" +#define CHAMELEON "chameleon" +#define CRYO "cryokinesis" +#define EATER "matter_eater" +#define JUMPY "jumpy" +#define POLYMORPH "polymorph" //disabilities -#define NEARSIGHTED 1 -#define EPILEPSY 2 -#define COUGHING 4 -#define TOURETTES 8 -#define NERVOUS 16 -#define BLIND 32 -#define COLOURBLIND 64 -#define MUTE 128 -#define DEAF 256 +#define NEARSIGHTED "nearsighted" +#define EPILEPSY "epilepsy" +#define COUGHING "coughing" +#define TOURETTES "tourettes" +#define NERVOUS "nervous" +#define BLINDNESS "blind" +#define COLOURBLIND "colorblind" +#define MUTE "mute" +#define DEAF "deaf" //Nutrition levels for humans. No idea where else to put it #define NUTRITION_LEVEL_FAT 600 diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 2217271a2e7..366b8b3bcd9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -408,7 +408,7 @@ /proc/alone_in_area(var/area/the_area, var/mob/must_be_alone, var/check_type = /mob/living/carbon) var/area/our_area = get_area(the_area) - for(var/C in GLOB.living_mob_list) + for(var/C in GLOB.alive_mob_list) if(!istype(C, check_type)) continue if(C == must_be_alone) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index a8066f62a37..aa130bb3ca9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -320,7 +320,7 @@ Turf and target are seperate in case you want to teleport some distance from a t //When a borg is activated, it can choose which AI it wants to be slaved to /proc/active_ais() . = list() - for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list) if(A.stat == DEAD) continue if(A.control_disabled == 1) diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index b6fcae25061..2caa158757c 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -3,30 +3,31 @@ GLOBAL_LIST_EMPTY(all_species) GLOBAL_LIST_EMPTY(all_languages) GLOBAL_LIST_EMPTY(language_keys) // Table of say codes for all languages GLOBAL_LIST_EMPTY(all_superheroes) -GLOBAL_LIST_INIT(whitelisted_species, list()) +GLOBAL_LIST_EMPTY(whitelisted_species) -GLOBAL_LIST_INIT(clients, list()) //list of all clients -GLOBAL_LIST_INIT(admins, list()) //list of all clients whom are admins -GLOBAL_LIST_INIT(deadmins, list()) //list of all clients who have used the de-admin verb. -GLOBAL_LIST_INIT(directory, list()) //list of all ckeys with associated client -GLOBAL_LIST_INIT(stealthminID, list()) //reference list with IDs that store ckeys, for stealthmins +GLOBAL_LIST_EMPTY(clients) //list of all clients +GLOBAL_LIST_EMPTY(admins) //list of all clients whom are admins +GLOBAL_LIST_EMPTY(deadmins) //list of all clients who have used the de-admin verb. +GLOBAL_LIST_EMPTY(directory) //list of all ckeys with associated client +GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys, for stealthmins //Since it didn't really belong in any other category, I'm putting this here //This is for procs to replace all the goddamn 'in world's that are chilling around the code -GLOBAL_LIST_INIT(player_list, list()) //List of all mobs **with clients attached**. Excludes /mob/new_player -GLOBAL_LIST_INIT(mob_list, list()) //List of all mobs, including clientless -GLOBAL_LIST_INIT(silicon_mob_list, list()) //List of all silicon mobs, including clientless -GLOBAL_LIST_INIT(spirits, list()) //List of all the spirits, including Masks -GLOBAL_LIST_INIT(living_mob_list, list()) //List of all alive mobs, including clientless. Excludes /mob/new_player -GLOBAL_LIST_INIT(dead_mob_list, list()) //List of all dead mobs, including clientless. Excludes /mob/new_player -GLOBAL_LIST_INIT(respawnable_list, list()) //List of all mobs, dead or in mindless creatures that still be respawned. -GLOBAL_LIST_INIT(non_respawnable_keys, list()) //List of ckeys that are excluded from respawning for remainder of round. +GLOBAL_LIST_EMPTY(player_list) //List of all mobs **with clients attached**. Excludes /mob/new_player +GLOBAL_LIST_EMPTY(mob_list) //List of all mobs, including clientless +GLOBAL_LIST_EMPTY(silicon_mob_list) //List of all silicon mobs, including clientless +GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes +GLOBAL_LIST_EMPTY(spirits) //List of all the spirits, including Masks +GLOBAL_LIST_EMPTY(alive_mob_list) //List of all alive mobs, including clientless. Excludes /mob/new_player +GLOBAL_LIST_EMPTY(dead_mob_list) //List of all dead mobs, including clientless. Excludes /mob/new_player +GLOBAL_LIST_EMPTY(respawnable_list) //List of all mobs, dead or in mindless creatures that still be respawned. +GLOBAL_LIST_EMPTY(non_respawnable_keys) //List of ckeys that are excluded from respawning for remainder of round. GLOBAL_LIST_INIT(simple_animals, list(list(), list(), list(), list())) //One for each AI_* status define, List of all simple animals, including clientless -GLOBAL_LIST_INIT(bots_list, list()) //List of all bots(beepsky, medibots,etc) +GLOBAL_LIST_EMPTY(bots_list) //List of all bots(beepsky, medibots,etc) -GLOBAL_LIST_INIT(med_hud_users, list()) -GLOBAL_LIST_INIT(sec_hud_users, list()) -GLOBAL_LIST_INIT(antag_hud_users, list()) -GLOBAL_LIST_INIT(surgeries_list, list()) -GLOBAL_LIST_INIT(hear_radio_list, list()) //Mobs that hear the radio even if there's no client +GLOBAL_LIST_EMPTY(med_hud_users) +GLOBAL_LIST_EMPTY(sec_hud_users) +GLOBAL_LIST_EMPTY(antag_hud_users) +GLOBAL_LIST_EMPTY(surgeries_list) +GLOBAL_LIST_EMPTY(hear_radio_list) //Mobs that hear the radio even if there's no client diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 20e50bb3054..d840f64bb4a 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -134,9 +134,9 @@ if(W == A) W.attack_self(src) if(hand) - update_inv_l_hand(0) + update_inv_l_hand() else - update_inv_r_hand(0) + update_inv_r_hand() return // operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper) @@ -258,6 +258,9 @@ Makes the mob face the direction of the clicked thing */ /mob/proc/MiddleShiftClickOn(atom/A) + return + +/mob/living/MiddleShiftClickOn(atom/A) if(incapacitated()) return var/face_dir = get_cardinal_dir(src, A) @@ -273,6 +276,9 @@ Makes the mob constantly face the object (until it's out of sight) */ /mob/proc/MiddleShiftControlClickOn(atom/A) + return + +/mob/living/MiddleShiftControlClickOn(atom/A) var/face_uid = A.UID() if(forced_look == face_uid || A == src) forced_look = null diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index f03d436bcaf..8f243dfcdc1 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -3,6 +3,10 @@ /datum/hud/simple_animal/New(mob/user) ..() + + mymob.healths = new /obj/screen/healths() + infodisplay += mymob.healths + var/obj/screen/using using = new /obj/screen/act_intent/simple_animal() using.icon_state = mymob.a_intent diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c0f5cfd5f3b..1423720f8f6 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -371,15 +371,15 @@ return 1 if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech return 1 - + if(hud?.mymob && slot_id) var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) if(inv_item) return inv_item.Click(location, control, params) if(usr.attack_ui(slot_id)) - usr.update_inv_l_hand(0) - usr.update_inv_r_hand(0) + usr.update_inv_l_hand() + usr.update_inv_r_hand() return 1 /obj/screen/inventory/hand diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm index 9122e6a16c6..8e578856c6a 100644 --- a/code/controllers/subsystem/afk.dm +++ b/code/controllers/subsystem/afk.dm @@ -15,7 +15,7 @@ SUBSYSTEM_DEF(afk) /datum/controller/subsystem/afk/fire() var/list/toRemove = list() - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(!H.ckey) // Useless non ckey creatures continue diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 1d6fd410f9b..ef89317d0f5 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -497,13 +497,14 @@ SUBSYSTEM_DEF(jobs) job.after_spawn(H) //Gives glasses to the vision impaired - if(H.disabilities & DISABILITY_FLAG_NEARSIGHTED) + if(NEARSIGHTED in H.mutations) var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) if(equipped != 1) var/obj/item/clothing/glasses/G = H.glasses if(istype(G) && !G.prescription) - G.prescription = 1 + G.prescription = TRUE G.name = "prescription [G.name]" + H.update_nearsighted_effects() return H diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 8345822ca80..9445dd2717a 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(mobs) var/static/list/cubemonkeys = list() /datum/controller/subsystem/mobs/stat_entry() - ..("P:[GLOB.mob_list.len]") + ..("P:[GLOB.mob_living_list.len]") /datum/controller/subsystem/mobs/Initialize(start_timeofday) clients_by_zlevel = new /list(world.maxz,0) @@ -21,17 +21,17 @@ SUBSYSTEM_DEF(mobs) /datum/controller/subsystem/mobs/fire(resumed = 0) var/seconds = wait * 0.1 if(!resumed) - src.currentrun = GLOB.mob_list.Copy() + src.currentrun = GLOB.mob_living_list.Copy() //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun var/times_fired = src.times_fired while(currentrun.len) - var/mob/M = currentrun[currentrun.len] + var/mob/living/L = currentrun[currentrun.len] currentrun.len-- - if(M) - M.Life(seconds, times_fired) + if(L) + L.Life(seconds, times_fired) else - GLOB.mob_list.Remove(M) + GLOB.mob_living_list.Remove(L) if(MC_TICK_CHECK) return diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm index 7b08bd3ca48..bf405444110 100644 --- a/code/controllers/subsystem/weather.dm +++ b/code/controllers/subsystem/weather.dm @@ -20,7 +20,7 @@ SUBSYSTEM_DEF(weather) var/datum/weather/W = V if(W.aesthetic || W.stage != MAIN_STAGE) continue - for(var/i in GLOB.living_mob_list) + for(var/i in GLOB.mob_living_list) var/mob/living/L = i if(W.can_weather_act(L)) W.weather_act(L) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 5464bd9f012..9aeade59a1d 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -396,7 +396,7 @@ GLOBAL_LIST_INIT(advance_cures, list( for(var/datum/disease/advance/AD in GLOB.active_diseases) AD.Refresh() - for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) if(!is_station_level(H.z)) continue if(!H.HasDisease(D)) diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index 1a9bba6961e..a3111478b26 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -33,7 +33,7 @@ Bonus if(3, 4) to_chat(M, "[pick("You hear a ringing in your ear.", "Your ears pop.")]") if(5) - if(!(M.disabilities & DEAF)) + if(!(DEAF in M.mutations)) to_chat(M, "Your ears pop and begin ringing loudly!") M.BecomeDeaf() spawn(200) diff --git a/code/datums/diseases/advance/symptoms/skin.dm b/code/datums/diseases/advance/symptoms/skin.dm index aa5a3494584..a3346dce800 100644 --- a/code/datums/diseases/advance/symptoms/skin.dm +++ b/code/datums/diseases/advance/symptoms/skin.dm @@ -35,7 +35,7 @@ BONUS switch(A.stage) if(5) H.s_tone = -85 - H.update_body(0) + H.update_body() else H.visible_message("[H] looks a bit pale...", "Your skin suddenly appears lighter...") @@ -79,7 +79,7 @@ BONUS switch(A.stage) if(5) H.s_tone = 85 - H.update_body(0) + H.update_body() else H.visible_message("[H] looks a bit dark...", "Your skin suddenly appears darker...") diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index b8684072c3f..369c01cce42 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -148,7 +148,6 @@ eye.eye_user = user eye.name = "Camera Eye ([user.name])" user.remote_control = eye - user.remote_view = 1 user.reset_perspective(eye) eye.setLoc(get_turf(H)) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 83e69bdf5b1..7d3a73abf24 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1688,7 +1688,7 @@ if(H.w_uniform) jumpsuit = H.w_uniform jumpsuit.color = team_color - H.update_inv_w_uniform(0,0) + H.update_inv_w_uniform() add_attack_logs(missionary, current, "Converted to a zealot for [convert_duration/600] minutes") addtimer(CALLBACK(src, .proc/remove_zealot, jumpsuit), convert_duration) //deconverts after the timer expires @@ -1705,7 +1705,7 @@ jumpsuit.color = initial(jumpsuit.color) //reset the jumpsuit no matter where our mind is if(ishuman(current)) //but only try updating us if we are still a human type since it is a human proc var/mob/living/carbon/human/H = current - H.update_inv_w_uniform(0,0) + H.update_inv_w_uniform() to_chat(current, "You seem to have forgotten the events of the past 10 minutes or so, and your head aches a bit as if someone beat it savagely with a stick.") to_chat(current, "This means you don't remember who you were working for or what you were doing.") diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm index 91df261e9c2..19a12055fef 100644 --- a/code/datums/spells/cluwne.dm +++ b/code/datums/spells/cluwne.dm @@ -36,10 +36,10 @@ unEquip(gloves, 1) if(!istype(wear_mask, /obj/item/clothing/mask/cursedclown)) //Infinite loops otherwise unEquip(wear_mask, 1) - equip_to_slot_if_possible(new /obj/item/clothing/under/cursedclown, slot_w_uniform, 1, 1, 1) - equip_to_slot_if_possible(new /obj/item/clothing/gloves/cursedclown, slot_gloves, 1, 1, 1) - equip_to_slot_if_possible(new /obj/item/clothing/mask/cursedclown, slot_wear_mask, 1, 1, 1) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/cursedclown, slot_shoes, 1, 1, 1) + equip_to_slot_if_possible(new /obj/item/clothing/under/cursedclown, slot_w_uniform, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/gloves/cursedclown, slot_gloves, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/mask/cursedclown, slot_wear_mask, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/shoes/cursedclown, slot_shoes, TRUE, TRUE) /mob/living/carbon/human/proc/makeAntiCluwne() to_chat(src, "You don't feel very funny.") @@ -83,5 +83,5 @@ unEquip(gloves, 1) qdel(G) - equip_to_slot_if_possible(new /obj/item/clothing/under/lawyer/black, slot_w_uniform, 1, 1, 1) - equip_to_slot_if_possible(new /obj/item/clothing/shoes/black, slot_shoes, 1, 1, 1) + equip_to_slot_if_possible(new /obj/item/clothing/under/lawyer/black, slot_w_uniform, TRUE, TRUE) + equip_to_slot_if_possible(new /obj/item/clothing/shoes/black, slot_shoes, TRUE, TRUE) diff --git a/code/datums/spells/devil.dm b/code/datums/spells/devil.dm index 12e2a44a8c1..27b2fcb8851 100644 --- a/code/datums/spells/devil.dm +++ b/code/datums/spells/devil.dm @@ -142,7 +142,6 @@ return 0 fakefire() forceMove(get_turf(src)) - reset_perspective() visible_message("[src] appears in a firey blaze!") playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1) spawn(15) diff --git a/code/datums/spells/genetic.dm b/code/datums/spells/genetic.dm index 3c2f997e461..d95c6212486 100644 --- a/code/datums/spells/genetic.dm +++ b/code/datums/spells/genetic.dm @@ -2,7 +2,6 @@ name = "Genetic" desc = "This spell inflicts a set of mutations and disabilities upon the target." - var/disabilities = 0 //bits var/list/mutations = list() //mutation strings var/duration = 100 //deciseconds /* @@ -20,16 +19,12 @@ for(var/mob/living/target in targets) for(var/x in mutations) target.mutations.Add(x) - /* if(x == HULK && ishuman(target)) - target:hulk_time=world.time + duration */ - target.disabilities |= disabilities target.update_mutations() //update target's mutation overlays var/mob/living/carbon/human/H = target if(ishuman(target)) H.update_body() spawn(duration) target.mutations.Remove(mutations) - target.disabilities &= ~disabilities target.update_mutations() if(ishuman(target)) H.update_body() diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 2c000a0d232..0140fbdf951 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -43,6 +43,6 @@ "Your face burns up, and shortly after the fire you realise you have the face of a horse!") if(!target.unEquip(target.wear_mask)) qdel(target.wear_mask) - target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) + target.equip_to_slot_if_possible(magichead, slot_wear_mask, TRUE, TRUE) target.flash_eyes() diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index c3301f4d6ab..2a8e1d94526 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -104,12 +104,12 @@ if(target.hand) //left active hand - if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, 0, 1, 1)) - if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, 0, 1, 1)) + if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, FALSE, TRUE)) + if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, FALSE, TRUE)) butterfingers = 1 else //right active hand - if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, 0, 1, 1)) - if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, 0, 1, 1)) + if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, FALSE, TRUE)) + if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, FALSE, TRUE)) butterfingers = 1 if(butterfingers) item_to_retrieve.loc = target.loc diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm index d656bccac4a..c242a1aa52f 100644 --- a/code/datums/spells/touch_attacks.dm +++ b/code/datums/spells/touch_attacks.dm @@ -27,12 +27,12 @@ var/hand_handled = 1 attached_hand = new hand_path(src) if(user.hand) //left active hand - if(!user.equip_to_slot_if_possible(attached_hand, slot_l_hand, 0, 1, 1)) - if(!user.equip_to_slot_if_possible(attached_hand, slot_r_hand, 0, 1, 1)) + if(!user.equip_to_slot_if_possible(attached_hand, slot_l_hand, FALSE, TRUE)) + if(!user.equip_to_slot_if_possible(attached_hand, slot_r_hand, FALSE, TRUE)) hand_handled = 0 else //right active hand - if(!user.equip_to_slot_if_possible(attached_hand, slot_r_hand, 0, 1, 1)) - if(!user.equip_to_slot_if_possible(attached_hand, slot_l_hand, 0, 1, 1)) + if(!user.equip_to_slot_if_possible(attached_hand, slot_r_hand, FALSE, TRUE)) + if(!user.equip_to_slot_if_possible(attached_hand, slot_l_hand, FALSE, TRUE)) hand_handled = 0 if(!hand_handled) qdel(attached_hand) diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index cf7e6fa3217..6a951ac66a0 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -304,7 +304,7 @@ sound = 'sound/magic/blind.ogg' /obj/effect/proc_holder/spell/targeted/genetic/blind - disabilities = BLIND + mutations = list(BLINDNESS) duration = 300 sound = 'sound/magic/blind.ogg' diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 1a407f2ec50..907e6a695e1 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -87,7 +87,7 @@ GLOBAL_LIST_INIT(wireColours, list("red", "blue", "green", "black", "orange", "b if(ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) - if(eyes && H.disabilities & COLOURBLIND) + if(eyes && (COLOURBLIND in H.mutations)) replace_colours = eyes.replace_colours diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1cb0ee3baad..365e06aca4b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -202,9 +202,7 @@ else return null -/atom/proc/check_eye(user as mob) - if(istype(user, /mob/living/silicon/ai)) // WHYYYY - return 1 +/atom/proc/check_eye(user) return /atom/proc/on_reagent_change() @@ -618,19 +616,19 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) if(wear_suit) wear_suit.add_blood(blood_dna, color) wear_suit.blood_color = color - update_inv_wear_suit(1) + update_inv_wear_suit() else if(w_uniform) w_uniform.add_blood(blood_dna, color) w_uniform.blood_color = color - update_inv_w_uniform(1) + update_inv_w_uniform() if(head) head.add_blood(blood_dna, color) head.blood_color = color - update_inv_head(0,0) + update_inv_head() if(glasses) glasses.add_blood(blood_dna, color) glasses.blood_color = color - update_inv_glasses(0) + update_inv_glasses() if(gloves) var/obj/item/clothing/gloves/G = gloves G.add_blood(blood_dna, color) @@ -642,7 +640,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) transfer_blood_dna(blood_dna) verbs += /mob/living/carbon/human/proc/bloody_doodle - update_inv_gloves(1) //handles bloody hands overlays and updating + update_inv_gloves() //handles bloody hands overlays and updating return 1 /obj/item/proc/add_blood_overlay(color) diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index ceabae25973..1a92210f570 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -22,17 +22,17 @@ GLOBAL_LIST_EMPTY(bad_blocks) /datum/dna // READ-ONLY, GETS OVERWRITTEN // DO NOT FUCK WITH THESE OR BYOND WILL EAT YOUR FACE - var/uni_identity="" // Encoded UI - var/struc_enzymes="" // Encoded SE - var/unique_enzymes="" // MD5 of player name + var/uni_identity = "" // Encoded UI + var/struc_enzymes = "" // Encoded SE + var/unique_enzymes = "" // MD5 of player name // Original Encoded SE, for use with Ryetalin - var/struc_enzymes_original="" // Encoded SE + var/struc_enzymes_original = "" // Encoded SE var/list/SE_original[DNA_SE_LENGTH] // Internal dirtiness checks - var/dirtyUI=0 - var/dirtySE=0 + var/dirtyUI = 0 + var/dirtySE = 0 // Okay to read, but you're an idiot if you do. // BLOCK = VALUE @@ -50,10 +50,10 @@ GLOBAL_LIST_EMPTY(bad_blocks) // USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION! /datum/dna/proc/Clone() var/datum/dna/new_dna = new() - new_dna.unique_enzymes=unique_enzymes - new_dna.struc_enzymes_original=struc_enzymes_original // will make clone's SE the same as the original, do we want this? + new_dna.unique_enzymes = unique_enzymes + new_dna.struc_enzymes_original = struc_enzymes_original // will make clone's SE the same as the original, do we want this? new_dna.blood_type = blood_type - new_dna.real_name=real_name + new_dna.real_name = real_name new_dna.species = new species.type for(var/b=1;b<=DNA_SE_LENGTH;b++) new_dna.SE[b]=SE[b] @@ -68,17 +68,17 @@ GLOBAL_LIST_EMPTY(bad_blocks) /////////////////////////////////////// // Create random UI. -/datum/dna/proc/ResetUI(var/defer=0) +/datum/dna/proc/ResetUI(defer = FALSE) for(var/i=1,i<=DNA_UI_LENGTH,i++) switch(i) if(DNA_UI_SKIN_TONE) - SetUIValueRange(DNA_UI_SKIN_TONE,rand(1,220),220,1) // Otherwise, it gets fucked + SetUIValueRange(DNA_UI_SKIN_TONE, rand(1, 220), 220, 1) // Otherwise, it gets fucked else UI[i]=rand(0,4095) if(!defer) UpdateUI() -/datum/dna/proc/ResetUIFrom(var/mob/living/carbon/human/character) +/datum/dna/proc/ResetUIFrom(mob/living/carbon/human/character) // INITIALIZE! ResetUI(1) // Hair @@ -135,83 +135,90 @@ GLOBAL_LIST_EMPTY(bad_blocks) UpdateUI() // Set a DNA UI block's raw value. -/datum/dna/proc/SetUIValue(var/block,var/value,var/defer=0) - if(block<=0) return - ASSERT(value>0) - ASSERT(value<=4095) +/datum/dna/proc/SetUIValue(block, value, defer = FALSE) + if(block <= 0) + return + ASSERT(value > 0) + ASSERT(value <= 4095) UI[block]=value - dirtyUI=1 + dirtyUI = 1 if(!defer) UpdateUI() // Get a DNA UI block's raw value. -/datum/dna/proc/GetUIValue(var/block) - if(block<=0) return 0 +/datum/dna/proc/GetUIValue(block) + if(block <= 0) + return FALSE return UI[block] // Set a DNA UI block's value, given a value and a max possible value. // Used in hair and facial styles (value being the index and maxvalue being the len of the hairstyle list) -/datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue,var/defer=0) - if(block<=0) +/datum/dna/proc/SetUIValueRange(block, value, maxvalue, defer = FALSE) + if(block <= 0) return if(value == 0) value = 1 - ASSERT(maxvalue<=4095) + ASSERT(maxvalue <= 4095) var/range = (4095 / maxvalue) if(value) - SetUIValue(block,round(value * range),defer) + SetUIValue(block,round(value * range), defer) // Getter version of above. -/datum/dna/proc/GetUIValueRange(var/block,var/maxvalue) - if(block<=0) return 0 +/datum/dna/proc/GetUIValueRange(block, maxvalue) + if(block <= 0) + return FALSE var/value = GetUIValue(block) - return round(1 +(value / 4096)*maxvalue) + return round(1 + (value / 4096) * maxvalue) // Is the UI gene "on" or "off"? // For UI, this is simply a check of if the value is > 2050. -/datum/dna/proc/GetUIState(var/block) - if(block<=0) return +/datum/dna/proc/GetUIState(block) + if(block <= 0) + return return UI[block] > 2050 // Set UI gene "on" (1) or "off" (0) -/datum/dna/proc/SetUIState(var/block,var/on,var/defer=0) - if(block<=0) return +/datum/dna/proc/SetUIState(block, on, defer = FALSE) + if(block <= 0) + return var/val if(on) - val=rand(2050,4095) + val = rand(2050, 4095) else - val=rand(1,2049) - SetUIValue(block,val,defer) + val=rand(1, 2049) + SetUIValue(block, val, defer) // Get a hex-encoded UI block. -/datum/dna/proc/GetUIBlock(var/block) +/datum/dna/proc/GetUIBlock(block) return EncodeDNABlock(GetUIValue(block)) // Do not use this unless you absolutely have to. // Set a block from a hex string. This is inefficient. If you can, use SetUIValue(). // Used in DNA modifiers. -/datum/dna/proc/SetUIBlock(var/block,var/value,var/defer=0) - if(block<=0) return - return SetUIValue(block,hex2num(value),defer) +/datum/dna/proc/SetUIBlock(block, value, defer = FALSE) + if(block <= 0) + return + return SetUIValue(block, hex2num(value), defer) // Get a sub-block from a block. -/datum/dna/proc/GetUISubBlock(var/block,var/subBlock) - return copytext(GetUIBlock(block),subBlock,subBlock+1) +/datum/dna/proc/GetUISubBlock(block, subBlock) + return copytext(GetUIBlock(block), subBlock, subBlock + 1) // Do not use this unless you absolutely have to. // Set a block from a hex string. This is inefficient. If you can, use SetUIValue(). // Used in DNA modifiers. -/datum/dna/proc/SetUISubBlock(var/block,var/subBlock, var/newSubBlock, var/defer=0) - if(block<=0) return - var/oldBlock=GetUIBlock(block) - var/newBlock="" - for(var/i=1, i<=length(oldBlock), i++) +/datum/dna/proc/SetUISubBlock(block, subBlock, newSubBlock, defer = FALSE) + if(block <= 0) + return + var/oldBlock = GetUIBlock(block) + var/newBlock = "" + for(var/i = 1, i <= length(oldBlock), i++) if(i==subBlock) - newBlock+=newSubBlock + newBlock += newSubBlock else - newBlock+=copytext(oldBlock,i,i+1) - SetUIBlock(block,newBlock,defer) + newBlock += copytext(oldBlock, i, i + 1) + SetUIBlock(block, newBlock, defer) /////////////////////////////////////// // STRUCTURAL ENZYMES @@ -220,126 +227,134 @@ GLOBAL_LIST_EMPTY(bad_blocks) // "Zeroes out" all of the blocks. /datum/dna/proc/ResetSE() for(var/i = 1, i <= DNA_SE_LENGTH, i++) - SetSEValue(i,rand(1,1024),1) + SetSEValue(i, rand(1, 1024), 1) UpdateSE() // Set a DNA SE block's raw value. -/datum/dna/proc/SetSEValue(var/block,var/value,var/defer=0) +/datum/dna/proc/SetSEValue(block, value, defer = FALSE) - if(block<=0) return - ASSERT(value>=0) - ASSERT(value<=4095) - SE[block]=value - dirtySE=1 + if(block<=0) + return + ASSERT(value >= 0) + ASSERT(value <= 4095) + SE[block] = value + dirtySE = 1 if(!defer) UpdateSE() //testing("SetSEBlock([block],[value],[defer]): [value] -> [GetSEValue(block)]") // Get a DNA SE block's raw value. -/datum/dna/proc/GetSEValue(var/block) - if(block<=0) return 0 +/datum/dna/proc/GetSEValue(block) + if(block <= 0) + return FALSE return SE[block] // Set a DNA SE block's value, given a value and a max possible value. // Might be used for species? -/datum/dna/proc/SetSEValueRange(var/block,var/value,var/maxvalue) - if(block<=0) return - ASSERT(maxvalue<=4095) +/datum/dna/proc/SetSEValueRange(block, value, maxvalue) + if(block <= 0) + return + ASSERT(maxvalue <= 4095) var/range = round(4095 / maxvalue) if(value) - SetSEValue(block, value * range - rand(1,range-1)) + SetSEValue(block, value * range - rand(1, range - 1)) // Getter version of above. -/datum/dna/proc/GetSEValueRange(var/block,var/maxvalue) - if(block<=0) return 0 +/datum/dna/proc/GetSEValueRange(block, maxvalue) + if(block <= 0) + return FALSE var/value = GetSEValue(block) - return round(1 +(value / 4096)*maxvalue) + return round(1 + (value / 4096) * maxvalue) // Is the block "on" (1) or "off" (0)? (Un-assigned genes are always off.) -/datum/dna/proc/GetSEState(var/block) - if(block<=0) return 0 - var/list/BOUNDS=GetDNABounds(block) - var/value=GetSEValue(block) +/datum/dna/proc/GetSEState(block) + if(block <= 0) + return FALSE + var/list/BOUNDS = GetDNABounds(block) + var/value = GetSEValue(block) return (value >= BOUNDS[DNA_ON_LOWERBOUND]) // Set a block "on" or "off". -/datum/dna/proc/SetSEState(var/block,var/on,var/defer=0) - if(block<=0) return +/datum/dna/proc/SetSEState(block, on, defer = FALSE) + if(block <= 0) + return var/list/BOUNDS=GetDNABounds(block) var/val if(on) - val=rand(BOUNDS[DNA_ON_LOWERBOUND],BOUNDS[DNA_ON_UPPERBOUND]) + val = rand(BOUNDS[DNA_ON_LOWERBOUND], BOUNDS[DNA_ON_UPPERBOUND]) else - val=rand(1,BOUNDS[DNA_OFF_UPPERBOUND]) - SetSEValue(block,val,defer) + val = rand(1, BOUNDS[DNA_OFF_UPPERBOUND]) + SetSEValue(block, val, defer) // Get hex-encoded SE block. -/datum/dna/proc/GetSEBlock(var/block) +/datum/dna/proc/GetSEBlock(block) return EncodeDNABlock(GetSEValue(block)) // Do not use this unless you absolutely have to. // Set a block from a hex string. This is inefficient. If you can, use SetUIValue(). // Used in DNA modifiers. -/datum/dna/proc/SetSEBlock(var/block,var/value,var/defer=0) - if(block<=0) return +/datum/dna/proc/SetSEBlock(block, value, defer = FALSE) + if(block <= 0) + return var/nval=hex2num(value) //testing("SetSEBlock([block],[value],[defer]): [value] -> [nval]") - return SetSEValue(block,nval,defer) + return SetSEValue(block, nval, defer) -/datum/dna/proc/GetSESubBlock(var/block,var/subBlock) - return copytext(GetSEBlock(block),subBlock,subBlock+1) +/datum/dna/proc/GetSESubBlock(block, subBlock) + return copytext(GetSEBlock(block), subBlock, subBlock + 1) // Do not use this unless you absolutely have to. // Set a sub-block from a hex character. This is inefficient. If you can, use SetUIValue(). // Used in DNA modifiers. -/datum/dna/proc/SetSESubBlock(var/block,var/subBlock, var/newSubBlock, var/defer=0) - if(block<=0) return +/datum/dna/proc/SetSESubBlock(block, subBlock, newSubBlock, defer = FALSE) + if(block <= 0) + return var/oldBlock=GetSEBlock(block) - var/newBlock="" - for(var/i=1, i<=length(oldBlock), i++) + var/newBlock = "" + for(var/i = 1, i <= length(oldBlock), i++) if(i==subBlock) newBlock+=newSubBlock else - newBlock+=copytext(oldBlock,i,i+1) + newBlock += copytext(oldBlock, i, i + 1) //testing("SetSESubBlock([block],[subBlock],[newSubBlock],[defer]): [oldBlock] -> [newBlock]") - SetSEBlock(block,newBlock,defer) + SetSEBlock(block, newBlock, defer) -/proc/EncodeDNABlock(var/value) - return add_zero2(num2hex(value,1), 3) +/proc/EncodeDNABlock(value) + return add_zero2(num2hex(value, 1), 3) /datum/dna/proc/UpdateUI() - src.uni_identity="" + uni_identity = "" for(var/block in UI) uni_identity += EncodeDNABlock(block) //testing("New UI: [uni_identity]") - dirtyUI=0 + dirtyUI = 0 /datum/dna/proc/UpdateSE() //var/oldse=struc_enzymes - struc_enzymes="" + struc_enzymes = "" for(var/block in SE) struc_enzymes += EncodeDNABlock(block) //testing("Old SE: [oldse]") //testing("New SE: [struc_enzymes]") - dirtySE=0 + dirtySE = 0 // BACK-COMPAT! // Just checks our character has all the crap it needs. -/datum/dna/proc/check_integrity(var/mob/living/carbon/human/character) +/datum/dna/proc/check_integrity(mob/living/carbon/human/character) if(character) if(UI.len != DNA_UI_LENGTH) ResetUIFrom(character) - if(length(struc_enzymes)!= 3*DNA_SE_LENGTH) + if(length(struc_enzymes)!= 3 * DNA_SE_LENGTH) ResetSE() if(length(unique_enzymes) != 32) unique_enzymes = md5(character.real_name) else - if(length(uni_identity) != 3*DNA_UI_LENGTH) + if(length(uni_identity) != 3 * DNA_UI_LENGTH) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4" - if(length(struc_enzymes)!= 3*DNA_SE_LENGTH) + if(length(struc_enzymes)!= 3 * DNA_SE_LENGTH) struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6" // BACK-COMPAT! diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index 0091745c518..16eee549bf2 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -3,7 +3,7 @@ // M: Mob to mess with // connected: Machine we're in, type unchecked so I doubt it's used beyond monkeying // flags: See below, bitfield. -/proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0) +/proc/domutcheck(mob/living/M, connected = null, flags = 0) for(var/datum/dna/gene/gene in GLOB.dna_genes) if(!M || !M.dna) return @@ -13,7 +13,7 @@ domutation(gene, M, connected, flags) // Use this to force a mut check on a single gene! -/proc/genemutcheck(var/mob/living/M, var/block, var/connected=null, var/flags=0) +/proc/genemutcheck(mob/living/M, block, connected = null, flags = 0) if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure. var/mob/living/carbon/human/H = M if(NO_DNA in H.dna.species.species_traits) @@ -27,9 +27,9 @@ domutation(gene, M, connected, flags) -/proc/domutation(var/datum/dna/gene/gene, var/mob/living/M, var/connected=null, var/flags=0) +/proc/domutation(datum/dna/gene/gene, mob/living/M, connected = null, flags = 0) if(!gene || !istype(gene)) - return 0 + return FALSE // Current state var/gene_active = M.dna.GetSEState(gene.block) @@ -37,7 +37,7 @@ // Sanity checks, don't skip. if(!gene.can_activate(M,flags) && gene_active) //testing("[M] - Failed to activate [gene.name] (can_activate fail).") - return 0 + return FALSE var/defaultgenes // Do not mutate inherent species abilities if(ishuman(M)) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 1857848c2c9..435133a3796 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -9,58 +9,61 @@ t = "0[t]" temp1 = t if(length(t) > u) - temp1 = copytext(t,2,u+1) + temp1 = copytext(t, 2, u + 1) return temp1 // DNA Gene activation boundaries, see dna2.dm. // Returns a list object with 4 numbers. -/proc/GetDNABounds(var/block) - var/list/BOUNDS=GLOB.dna_activity_bounds[block] +/proc/GetDNABounds(block) + var/list/BOUNDS = GLOB.dna_activity_bounds[block] if(!istype(BOUNDS)) return DNA_DEFAULT_BOUNDS return BOUNDS // Give Random Bad Mutation to M -/proc/randmutb(var/mob/living/M) - if(!M || !M.dna) return +/proc/randmutb(mob/living/M) + if(!M || !M.dna) + return M.dna.check_integrity() var/block = pick(GLOB.bad_blocks) M.dna.SetSEState(block, 1) // Give Random Good Mutation to M -/proc/randmutg(var/mob/living/M) - if(!M || !M.dna) return +/proc/randmutg(mob/living/M) + if(!M || !M.dna) + return M.dna.check_integrity() var/block = pick(GLOB.good_blocks) M.dna.SetSEState(block, 1) // Random Appearance Mutation -/proc/randmuti(var/mob/living/M) - if(!M || !M.dna) return +/proc/randmuti(mob/living/M) + if(!M || !M.dna) + return M.dna.check_integrity() - M.dna.SetUIValue(rand(1,DNA_UI_LENGTH),rand(1,4095)) + M.dna.SetUIValue(rand(1, DNA_UI_LENGTH), rand(1, 4095)) // Scramble UI or SE. -/proc/scramble(var/UI, var/mob/M, var/prob) - if(!M || !M.dna) return +/proc/scramble(UI, mob/M, prob) + if(!M || !M.dna) + return M.dna.check_integrity() if(UI) - for(var/i = 1, i <= DNA_UI_LENGTH-1, i++) + for(var/i = 1, i <= DNA_UI_LENGTH - 1, i++) if(prob(prob)) - M.dna.SetUIValue(i,rand(1,4095),1) + M.dna.SetUIValue(i, rand(1, 4095), 1) M.dna.UpdateUI() M.UpdateAppearance() else - for(var/i = 1, i <= DNA_SE_LENGTH-1, i++) + for(var/i = 1, i <= DNA_SE_LENGTH - 1, i++) if(prob(prob)) - M.dna.SetSEValue(i,rand(1,4095),1) + M.dna.SetSEValue(i, rand(1, 4095), 1) M.dna.UpdateSE() domutcheck(M, null) - return // I haven't yet figured out what the fuck this is supposed to do. -/proc/miniscramble(input,rs,rd) +/proc/miniscramble(input, rs, rd) var/output output = null if(input == "C" || input == "D" || input == "E" || input == "F") @@ -79,7 +82,7 @@ // input: YOUR TARGET // rs: RAD STRENGTH // rd: DURATION -/proc/miniscrambletarget(input,rs,rd) +/proc/miniscrambletarget(input, rs, rd) var/output = null switch(input) if("0") @@ -124,11 +127,11 @@ // Use mob.UpdateAppearance() instead. // Simpler. Don't specify UI in order for the mob to use its own. -/mob/proc/UpdateAppearance(var/list/UI=null) - if(istype(src, /mob/living/carbon/human)) +/mob/proc/UpdateAppearance(list/UI = null) + if(istype(src, /mob/living/carbon/human)) // WHY?! if(UI!=null) - src.dna.UI=UI - src.dna.UpdateUI() + dna.UI = UI + dna.UpdateUI() dna.check_integrity() var/mob/living/carbon/human/H = src var/obj/item/organ/external/head/head_organ = H.get_organ("head") @@ -169,9 +172,9 @@ H.regenerate_icons() - return 1 + return TRUE else - return 0 + return FALSE /* ORGAN WRITING PROCS @@ -219,9 +222,9 @@ // In absence of eyes, possibly randomize the eye color DNA? return - SetUIValueRange(DNA_UI_EYES_R, color2R(eyes_organ.eye_colour), 255, 1) - SetUIValueRange(DNA_UI_EYES_G, color2G(eyes_organ.eye_colour), 255, 1) - SetUIValueRange(DNA_UI_EYES_B, color2B(eyes_organ.eye_colour), 255, 1) + SetUIValueRange(DNA_UI_EYES_R, color2R(eyes_organ.eye_colour), 255, 1) + SetUIValueRange(DNA_UI_EYES_G, color2G(eyes_organ.eye_colour), 255, 1) + SetUIValueRange(DNA_UI_EYES_B, color2B(eyes_organ.eye_colour), 255, 1) /datum/dna/proc/head_traits_to_dna(obj/item/organ/external/head/head_organ) if(!head_organ) @@ -241,26 +244,26 @@ head_organ.ha_style = "None" var/headacc = GLOB.head_accessory_styles_list.Find(head_organ.ha_style) - SetUIValueRange(DNA_UI_HAIR_R, color2R(head_organ.hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR_G, color2G(head_organ.hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR_B, color2B(head_organ.hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR_R, color2R(head_organ.hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR_G, color2G(head_organ.hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR_B, color2B(head_organ.hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR2_R, color2R(head_organ.sec_hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR2_G, color2G(head_organ.sec_hair_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR2_B, color2B(head_organ.sec_hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR2_R, color2R(head_organ.sec_hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR2_G, color2G(head_organ.sec_hair_colour), 255, 1) + SetUIValueRange(DNA_UI_HAIR2_B, color2B(head_organ.sec_hair_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD_R, color2R(head_organ.facial_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD_G, color2G(head_organ.facial_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD_B, color2B(head_organ.facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD_R, color2R(head_organ.facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD_G, color2G(head_organ.facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD_B, color2B(head_organ.facial_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD2_R, color2R(head_organ.sec_facial_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD2_G, color2G(head_organ.sec_facial_colour), 255, 1) - SetUIValueRange(DNA_UI_BEARD2_B, color2B(head_organ.sec_facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD2_R, color2R(head_organ.sec_facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD2_G, color2G(head_organ.sec_facial_colour), 255, 1) + SetUIValueRange(DNA_UI_BEARD2_B, color2B(head_organ.sec_facial_colour), 255, 1) - SetUIValueRange(DNA_UI_HACC_R, color2R(head_organ.headacc_colour), 255, 1) - SetUIValueRange(DNA_UI_HACC_G, color2G(head_organ.headacc_colour), 255, 1) - SetUIValueRange(DNA_UI_HACC_B, color2B(head_organ.headacc_colour), 255, 1) + SetUIValueRange(DNA_UI_HACC_R, color2R(head_organ.headacc_colour), 255, 1) + SetUIValueRange(DNA_UI_HACC_G, color2G(head_organ.headacc_colour), 255, 1) + SetUIValueRange(DNA_UI_HACC_B, color2B(head_organ.headacc_colour), 255, 1) - SetUIValueRange(DNA_UI_HAIR_STYLE, hair, GLOB.hair_styles_full_list.len, 1) - SetUIValueRange(DNA_UI_BEARD_STYLE, beard, GLOB.facial_hair_styles_list.len, 1) - SetUIValueRange(DNA_UI_HACC_STYLE, headacc, GLOB.head_accessory_styles_list.len, 1) + SetUIValueRange(DNA_UI_HAIR_STYLE, hair, GLOB.hair_styles_full_list.len, 1) + SetUIValueRange(DNA_UI_BEARD_STYLE, beard, GLOB.facial_hair_styles_list.len, 1) + SetUIValueRange(DNA_UI_HACC_STYLE, headacc, GLOB.head_accessory_styles_list.len, 1) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index c06dc24c545..a6ec98e8866 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -10,15 +10,15 @@ //list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0), /datum/dna2/record var/datum/dna/dna = null - var/types=0 - var/name="Empty" + var/types = 0 + var/name = "Empty" // Stuff for cloners - var/id=null - var/implant=null - var/ckey=null - var/mind=null - var/languages=null + var/id = null + var/implant = null + var/ckey = null + var/mind = null + var/languages = null /datum/dna2/record/proc/GetData() var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0) @@ -28,7 +28,7 @@ ser["data"] = dna.SE else ser["data"] = dna.UI - ser["owner"] = src.dna.real_name + ser["owner"] = dna.real_name ser["label"] = name if(types & DNA2_BUF_UI) ser["type"] = "ui" @@ -54,13 +54,13 @@ desc = "It scans DNA structures." icon = 'icons/obj/cryogenic2.dmi' icon_state = "scanner_open" - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 50 active_power_usage = 300 interact_offline = 1 - var/locked = 0 + var/locked = FALSE var/mob/living/carbon/occupant = null var/obj/item/reagent_containers/glass/beaker = null var/opened = 0 @@ -106,31 +106,29 @@ /obj/machinery/dna_scannernew/AllowDrop() return FALSE -/obj/machinery/dna_scannernew/relaymove(mob/user as mob) +/obj/machinery/dna_scannernew/relaymove(mob/user) if(user.stat) return - src.go_out() - return + go_out() /obj/machinery/dna_scannernew/verb/eject() set src in oview(1) set category = null set name = "Eject DNA Scanner" - if(usr.stat != 0) + if(usr.incapacitated()) return eject_occupant() add_fingerprint(usr) - return /obj/machinery/dna_scannernew/Destroy() eject_occupant() return ..() /obj/machinery/dna_scannernew/proc/eject_occupant() - src.go_out() + go_out() for(var/obj/O in src) if(!istype(O,/obj/item/circuitboard/clonescanner) && \ !istype(O,/obj/item/stock_parts) && \ @@ -146,14 +144,12 @@ set category = null set name = "Enter DNA Scanner" - if(usr.stat != 0) - return if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other return if(!ishuman(usr)) //Make sure they're a mob that has dna to_chat(usr, "Try as you might, you can not climb up into the [src].") return - if(src.occupant) + if(occupant) to_chat(usr, "The [src] is already occupied!") return if(usr.abiotic()) @@ -164,12 +160,11 @@ return usr.stop_pulling() usr.forceMove(src) - src.occupant = usr - src.icon_state = "scanner_occupied" - src.add_fingerprint(usr) - return + occupant = usr + icon_state = "scanner_occupied" + add_fingerprint(usr) -/obj/machinery/dna_scannernew/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) +/obj/machinery/dna_scannernew/MouseDrop_T(atom/movable/O, mob/user) if(!istype(O)) return if(O.loc == user) //no you can't pull things out of your ass @@ -208,27 +203,27 @@ if(user.pulling == L) user.stop_pulling() -/obj/machinery/dna_scannernew/attackby(var/obj/item/item as obj, var/mob/user as mob, params) - if(exchange_parts(user, item)) +/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params) + if(exchange_parts(user, I)) return - else if(istype(item, /obj/item/reagent_containers/glass)) + else if(istype(I, /obj/item/reagent_containers/glass)) if(beaker) to_chat(user, "A beaker is already loaded into the machine.") return if(!user.drop_item()) - to_chat(user, "\The [item] is stuck to you!") + to_chat(user, "\The [I] is stuck to you!") return - beaker = item - item.forceMove(src) - user.visible_message("[user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!") + beaker = I + I.forceMove(src) + user.visible_message("[user] adds \a [I] to \the [src]!", "You add \a [I] to \the [src]!") return - if(istype(item, /obj/item/grab)) - var/obj/item/grab/G = item + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I if(!ismob(G.affecting)) return - if(src.occupant) + if(occupant) to_chat(user, "The scanner is already occupied!") return if(G.affecting.abiotic()) @@ -241,7 +236,7 @@ to_chat(usr, "Close the maintenance panel first.") return put_in(G.affecting) - src.add_fingerprint(user) + add_fingerprint(user) qdel(G) return return ..() @@ -249,7 +244,7 @@ /obj/machinery/dna_scannernew/crowbar_act(mob/user, obj/item/I) if(default_deconstruction_crowbar(user, I)) for(var/obj/thing in contents) // in case there is something in the scanner - thing.forceMove(src.loc) + thing.forceMove(loc) /obj/machinery/dna_scannernew/screwdriver_act(mob/user, obj/item/I) if(occupant) @@ -258,15 +253,15 @@ if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I)) return TRUE -/obj/machinery/dna_scannernew/relaymove(mob/user as mob) +/obj/machinery/dna_scannernew/relaymove(mob/user) if(user.incapacitated()) - return 0 //maybe they should be able to get out with cuffs, but whatever + return FALSE //maybe they should be able to get out with cuffs, but whatever go_out() -/obj/machinery/dna_scannernew/proc/put_in(var/mob/M) +/obj/machinery/dna_scannernew/proc/put_in(mob/M) M.forceMove(src) - src.occupant = M - src.icon_state = "scanner_occupied" + occupant = M + icon_state = "scanner_occupied" // search for ghosts, if the corpse is empty and the scanner is connected to a cloner if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \ @@ -275,20 +270,19 @@ || locate(/obj/machinery/computer/cloning, get_step(src, WEST))) occupant.notify_ghost_cloning(source = src) - return /obj/machinery/dna_scannernew/proc/go_out() - if(!src.occupant) + if(!occupant) to_chat(usr, "The scanner is empty!") return - if(src.locked) + if(locked) to_chat(usr, "The scanner is locked!") return - src.occupant.forceMove(src.loc) - src.occupant = null - src.icon_state = "scanner_open" + occupant.forceMove(loc) + occupant = null + icon_state = "scanner_open" /obj/machinery/dna_scannernew/ex_act(severity) if(occupant) @@ -305,18 +299,17 @@ // Checks if occupants can be irradiated/mutated - prevents exploits where wearing full rad protection would still let you gain mutations /obj/machinery/dna_scannernew/proc/radiation_check() if(!occupant) - return 1 + return TRUE if(ishuman(occupant)) var/mob/living/carbon/human/H = occupant if(NO_DNA in H.dna.species.species_traits) - return 1 + return TRUE var/radiation_protection = occupant.run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm.") if(radiation_protection > NEGATE_MUTATION_THRESHOLD) - return 1 - - return 0 + return TRUE + return FALSE /obj/machinery/computer/scan_consolenew name = "\improper DNA Modifier access console" @@ -324,7 +317,7 @@ icon = 'icons/obj/computer.dmi' icon_screen = "dna" icon_keyboard = "med_key" - density = 1 + density = TRUE circuit = /obj/item/circuitboard/scan_consolenew var/selected_ui_block = 1.0 var/selected_ui_subblock = 1.0 @@ -336,22 +329,22 @@ var/radiation_intensity = 1.0 var/list/datum/dna2/record/buffers[3] var/irradiating = 0 - var/injector_ready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete + var/injector_ready = FALSE //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete var/obj/machinery/dna_scannernew/connected = null var/obj/item/disk/data/disk = null var/selected_menu_key = null - anchored = 1 + anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 400 - var/waiting_for_user_input=0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X + var/waiting_for_user_input = 0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X -/obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob, params) +/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/disk/data)) //INSERT SOME diskS - if(!src.disk) + if(!disk) user.drop_item() I.forceMove(src) - src.disk = I + disk = I to_chat(user, "You insert [I].") SSnanoui.update_uis(src) // update all UIs attached to src() return @@ -368,39 +361,30 @@ if(!isnull(connected)) break spawn(250) - src.injector_ready = 1 - return - return + injector_ready = TRUE -/obj/machinery/computer/scan_consolenew/proc/all_dna_blocks(var/list/buffer) +/obj/machinery/computer/scan_consolenew/proc/all_dna_blocks(list/buffer) var/list/arr = list() for(var/i = 1, i <= buffer.len, i++) arr += "[i]:[EncodeDNABlock(buffer[i])]" return arr -/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(var/obj/item/dnainjector/I, var/blk, var/datum/dna2/record/buffer) +/obj/machinery/computer/scan_consolenew/proc/setInjectorBlock(obj/item/dnainjector/I, blk, datum/dna2/record/buffer) var/pos = findtext(blk,":") - if(!pos) return 0 + if(!pos) + return FALSE var/id = text2num(copytext(blk,1,pos)) - if(!id) return 0 + if(!id) + return FALSE I.block = id I.buf = buffer - return 1 + return TRUE -/* -/obj/machinery/computer/scan_consolenew/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - if(!( src.status )) //remove this - return - return -*/ - -/obj/machinery/computer/scan_consolenew/attack_ai(user as mob) - src.add_hiddenprint(user) +/obj/machinery/computer/scan_consolenew/attack_ai(mob/user) + add_hiddenprint(user) attack_hand(user) -/obj/machinery/computer/scan_consolenew/attack_hand(user as mob) +/obj/machinery/computer/scan_consolenew/attack_hand(mob/user) if(isnull(connected)) for(dir in list(NORTH,EAST,SOUTH,WEST)) connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) @@ -427,7 +411,7 @@ * * @return nothing */ -/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) if(user == connected.occupant) return @@ -445,7 +429,7 @@ /obj/machinery/computer/scan_consolenew/ui_data(mob/user, datum/topic_state/state) var/data[0] data["selectedMenuKey"] = selected_menu_key - data["locked"] = src.connected.locked + data["locked"] = connected.locked data["hasOccupant"] = connected.occupant ? 1 : 0 data["isInjectorReady"] = injector_ready @@ -464,7 +448,7 @@ data["disk"] = diskData var/list/new_buffers = list() - for(var/datum/dna2/record/buf in src.buffers) + for(var/datum/dna2/record/buf in buffers) new_buffers += list(buf.GetData()) data["buffers"]=new_buffers @@ -481,7 +465,7 @@ data["selectedUITargetHex"] = selected_ui_target_hex var/occupantData[0] - if(!src.connected.occupant || !src.connected.occupant.dna) + if(!connected.occupant || !connected.occupant.dna) occupantData["name"] = null occupantData["stat"] = null occupantData["isViableSubject"] = null @@ -496,7 +480,7 @@ occupantData["name"] = connected.occupant.dna.real_name occupantData["stat"] = connected.occupant.stat occupantData["isViableSubject"] = 1 - if((NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna || (NO_DNA in connected.occupant.dna.species.species_traits)) + if((NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna || (NO_DNA in connected.occupant.dna.species.species_traits)) occupantData["isViableSubject"] = 0 occupantData["health"] = connected.occupant.health occupantData["maxHealth"] = connected.occupant.maxHealth @@ -520,173 +504,173 @@ /obj/machinery/computer/scan_consolenew/Topic(href, href_list) if(..()) - return 0 // don't update uis + return FALSE // don't update uis if(!istype(usr.loc, /turf)) - return 0 // don't update uis - if(!src || !src.connected) - return 0 // don't update uis + return FALSE // don't update uis + if(!src || !connected) + return FALSE // don't update uis if(irradiating) // Make sure that it isn't already irradiating someone... - return 0 // don't update uis + return FALSE // don't update uis add_fingerprint(usr) if(href_list["selectMenuKey"]) selected_menu_key = href_list["selectMenuKey"] - return 1 // return 1 forces an update to all Nano uis attached to src + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["toggleLock"]) - if((src.connected && src.connected.occupant)) - src.connected.locked = !( src.connected.locked ) - return 1 // return 1 forces an update to all Nano uis attached to src + if((connected && connected.occupant)) + connected.locked = !(connected.locked) + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["pulseRadiation"]) - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it SSnanoui.update_uis(src) // update all UIs attached to src - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds + sleep(10 * radiation_duration) // sleep for radiation_duration seconds irradiating = 0 - src.connected.locked = lock_state + connected.locked = lock_state - if(!src.connected.occupant) - return 1 // return 1 forces an update to all Nano uis attached to src + if(!connected.occupant) + return TRUE // return 1 forces an update to all Nano uis attached to src - var/radiation = (((src.radiation_intensity*3)+src.radiation_duration*3) / connected.damage_coeff) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) - if(src.connected.radiation_check()) - return 1 + var/radiation = (((radiation_intensity * 3) + radiation_duration * 3) / connected.damage_coeff) + connected.occupant.apply_effect(radiation, IRRADIATE, 0) + if(connected.radiation_check()) + return TRUE if(prob(95)) if(prob(75)) - randmutb(src.connected.occupant) + randmutb(connected.occupant) else - randmuti(src.connected.occupant) + randmuti(connected.occupant) else if(prob(95)) - randmutg(src.connected.occupant) + randmutg(connected.occupant) else - randmuti(src.connected.occupant) + randmuti(connected.occupant) - return 1 // return 1 forces an update to all Nano uis attached to src + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["radiationDuration"]) if(text2num(href_list["radiationDuration"]) > 0) - if(src.radiation_duration < 20) - src.radiation_duration += 2 + if(radiation_duration < 20) + radiation_duration += 2 else - if(src.radiation_duration > 2) - src.radiation_duration -= 2 - return 1 // return 1 forces an update to all Nano uis attached to src + if(radiation_duration > 2) + radiation_duration -= 2 + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["radiationIntensity"]) if(text2num(href_list["radiationIntensity"]) > 0) - if(src.radiation_intensity < 10) - src.radiation_intensity++ + if(radiation_intensity < 10) + radiation_intensity++ else - if(src.radiation_intensity > 1) - src.radiation_intensity-- - return 1 // return 1 forces an update to all Nano uis attached to src + if(radiation_intensity > 1) + radiation_intensity-- + return TRUE // return 1 forces an update to all Nano uis attached to src //////////////////////////////////////////////////////// if(href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) > 0) - if(src.selected_ui_target < 15) - src.selected_ui_target++ - src.selected_ui_target_hex = src.selected_ui_target + if(selected_ui_target < 15) + selected_ui_target++ + selected_ui_target_hex = selected_ui_target switch(selected_ui_target) if(10) - src.selected_ui_target_hex = "A" + selected_ui_target_hex = "A" if(11) - src.selected_ui_target_hex = "B" + selected_ui_target_hex = "B" if(12) - src.selected_ui_target_hex = "C" + selected_ui_target_hex = "C" if(13) - src.selected_ui_target_hex = "D" + selected_ui_target_hex = "D" if(14) - src.selected_ui_target_hex = "E" + selected_ui_target_hex = "E" if(15) - src.selected_ui_target_hex = "F" + selected_ui_target_hex = "F" else - src.selected_ui_target = 0 - src.selected_ui_target_hex = 0 - return 1 // return 1 forces an update to all Nano uis attached to src + selected_ui_target = 0 + selected_ui_target_hex = 0 + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) < 1) - if(src.selected_ui_target > 0) - src.selected_ui_target-- - src.selected_ui_target_hex = src.selected_ui_target + if(selected_ui_target > 0) + selected_ui_target-- + selected_ui_target_hex = selected_ui_target switch(selected_ui_target) if(10) - src.selected_ui_target_hex = "A" + selected_ui_target_hex = "A" if(11) - src.selected_ui_target_hex = "B" + selected_ui_target_hex = "B" if(12) - src.selected_ui_target_hex = "C" + selected_ui_target_hex = "C" if(13) - src.selected_ui_target_hex = "D" + selected_ui_target_hex = "D" if(14) - src.selected_ui_target_hex = "E" + selected_ui_target_hex = "E" else - src.selected_ui_target = 15 - src.selected_ui_target_hex = "F" - return 1 // return 1 forces an update to all Nano uis attached to src + selected_ui_target = 15 + selected_ui_target_hex = "F" + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["selectUIBlock"] && href_list["selectUISubblock"]) // This chunk of code updates selected block / sub-block based on click var/select_block = text2num(href_list["selectUIBlock"]) var/select_subblock = text2num(href_list["selectUISubblock"]) if((select_block <= DNA_UI_LENGTH) && (select_block >= 1)) - src.selected_ui_block = select_block + selected_ui_block = select_block if((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1)) - src.selected_ui_subblock = select_subblock - return 1 // return 1 forces an update to all Nano uis attached to src + selected_ui_subblock = select_subblock + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["pulseUIRadiation"]) - var/block = src.connected.occupant.dna.GetUISubBlock(src.selected_ui_block,src.selected_ui_subblock) + var/block = connected.occupant.dna.GetUISubBlock(selected_ui_block, selected_ui_subblock) - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it SSnanoui.update_uis(src) // update all UIs attached to src - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds + sleep(10 * radiation_duration) // sleep for radiation_duration seconds irradiating = 0 - src.connected.locked = lock_state + connected.locked = lock_state - if(!src.connected.occupant) - return 1 + if(!connected.occupant) + return TRUE - if(prob((80 + (src.radiation_duration / 2)))) - var/radiation = (src.radiation_intensity+src.radiation_duration) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) + if(prob((80 + (radiation_duration / 2)))) + var/radiation = (radiation_intensity + radiation_duration) + connected.occupant.apply_effect(radiation,IRRADIATE,0) - if(src.connected.radiation_check()) - return 1 + if(connected.radiation_check()) + return TRUE - block = miniscrambletarget(num2text(selected_ui_target), src.radiation_intensity, src.radiation_duration) - src.connected.occupant.dna.SetUISubBlock(src.selected_ui_block,src.selected_ui_subblock,block) - src.connected.occupant.UpdateAppearance() + block = miniscrambletarget(num2text(selected_ui_target), radiation_intensity, radiation_duration) + connected.occupant.dna.SetUISubBlock(selected_ui_block, selected_ui_subblock, block) + connected.occupant.UpdateAppearance() else - var/radiation = ((src.radiation_intensity*2)+src.radiation_duration) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) - if(src.connected.radiation_check()) - return 1 + var/radiation = ((radiation_intensity * 2) + radiation_duration) + connected.occupant.apply_effect(radiation, IRRADIATE, 0) + if(connected.radiation_check()) + return TRUE - if(prob(20+src.radiation_intensity)) - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) + if(prob(20 + radiation_intensity)) + randmutb(connected.occupant) + domutcheck(connected.occupant, connected) else - randmuti(src.connected.occupant) - src.connected.occupant.UpdateAppearance() - return 1 // return 1 forces an update to all Nano uis attached to src + randmuti(connected.occupant) + connected.occupant.UpdateAppearance() + return TRUE // return 1 forces an update to all Nano uis attached to src //////////////////////////////////////////////////////// if(href_list["injectRejuvenators"]) if(!connected.occupant) - return 0 + return FALSE var/inject_amount = round(text2num(href_list["injectRejuvenators"]), 5) // round to nearest 5 if(inject_amount < 0) // Since the user can actually type the commands himself, some sanity checking inject_amount = 0 @@ -694,7 +678,7 @@ inject_amount = 50 connected.beaker.reagents.trans_to(connected.occupant, inject_amount) connected.beaker.reagents.reaction(connected.occupant) - return 1 // return 1 forces an update to all Nano uis attached to src + return TRUE // return 1 forces an update to all Nano uis attached to src //////////////////////////////////////////////////////// @@ -702,73 +686,73 @@ var/select_block = text2num(href_list["selectSEBlock"]) var/select_subblock = text2num(href_list["selectSESubblock"]) if((select_block <= DNA_SE_LENGTH) && (select_block >= 1)) - src.selected_se_block = select_block + selected_se_block = select_block if((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1)) - src.selected_se_subblock = select_subblock + selected_se_subblock = select_subblock //testing("User selected block [selected_se_block] (sent [select_block]), subblock [selected_se_subblock] (sent [select_block]).") - return 1 // return 1 forces an update to all Nano uis attached to src + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["pulseSERadiation"]) - var/block = src.connected.occupant.dna.GetSESubBlock(src.selected_se_block,src.selected_se_subblock) + var/block = connected.occupant.dna.GetSESubBlock(selected_se_block, selected_se_subblock) //var/original_block=block - //testing("Irradiating SE block [src.selected_se_block]:[src.selected_se_subblock] ([block])...") + //testing("Irradiating SE block [selected_se_block]:[selected_se_subblock] ([block])...") - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1 //lock it + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it SSnanoui.update_uis(src) // update all UIs attached to src - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds + sleep(10 * radiation_duration) // sleep for radiation_duration seconds irradiating = 0 - src.connected.locked = lock_state + connected.locked = lock_state - if(src.connected.occupant) - if(prob((80 + ((src.radiation_duration / 2) + (connected.precision_coeff ** 3))))) - var/radiation = ((src.radiation_intensity+src.radiation_duration) / connected.damage_coeff) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) + if(connected.occupant) + if(prob((80 + ((radiation_duration / 2) + (connected.precision_coeff ** 3))))) + var/radiation = ((radiation_intensity + radiation_duration) / connected.damage_coeff) + connected.occupant.apply_effect(radiation, IRRADIATE, 0) - if(src.connected.radiation_check()) + if(connected.radiation_check()) return 1 var/real_SE_block=selected_se_block - block = miniscramble(block, src.radiation_intensity, src.radiation_duration) + block = miniscramble(block, radiation_intensity, radiation_duration) if(prob(20)) - if(src.selected_se_block > 1 && src.selected_se_block < DNA_SE_LENGTH/2) + if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2) real_SE_block++ - else if(src.selected_se_block > DNA_SE_LENGTH/2 && src.selected_se_block < DNA_SE_LENGTH) + else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH) real_SE_block-- - //testing("Irradiated SE block [real_SE_block]:[src.selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") - connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) - domutcheck(src.connected.occupant,src.connected) + //testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") + connected.occupant.dna.SetSESubBlock(real_SE_block, selected_se_subblock, block) + domutcheck(connected.occupant, connected) else - var/radiation = (((src.radiation_intensity*2)+src.radiation_duration) / connected.damage_coeff) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) + var/radiation = (((radiation_intensity * 2) + radiation_duration) / connected.damage_coeff) + connected.occupant.apply_effect(radiation, IRRADIATE, 0) - if(src.connected.radiation_check()) + if(connected.radiation_check()) return 1 - if(prob(80-src.radiation_duration)) + if(prob(80 - radiation_duration)) //testing("Random bad mut!") - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) + randmutb(connected.occupant) + domutcheck(connected.occupant, connected) else - randmuti(src.connected.occupant) + randmuti(connected.occupant) //testing("Random identity mut!") - src.connected.occupant.UpdateAppearance() - return 1 // return 1 forces an update to all Nano uis attached to src + connected.occupant.UpdateAppearance() + return TRUE // return 1 forces an update to all Nano uis attached to src if(href_list["ejectBeaker"]) if(connected.beaker) var/obj/item/reagent_containers/glass/B = connected.beaker B.forceMove(connected.loc) connected.beaker = null - return 1 + return TRUE if(href_list["ejectOccupant"]) connected.eject_occupant() - return 1 + return TRUE // Transfer Buffer Management if(href_list["bufferOption"]) @@ -776,113 +760,113 @@ // These bufferOptions do not require a bufferId if(bufferOption == "wipeDisk") - if((isnull(src.disk)) || (src.disk.read_only)) - //src.temphtml = "Invalid disk. Please try again." - return 0 + if((isnull(disk)) || (disk.read_only)) + //temphtml = "Invalid disk. Please try again." + return FALSE - src.disk.buf=null - //src.temphtml = "Data saved." - return 1 + disk.buf = null + //temphtml = "Data saved." + return TRUE if(bufferOption == "ejectDisk") - if(!src.disk) + if(!disk) return - src.disk.forceMove(get_turf(src)) - src.disk = null - return 1 + disk.forceMove(get_turf(src)) + disk = null + return TRUE // All bufferOptions from here on require a bufferId if(!href_list["bufferId"]) - return 0 + return FALSE var/bufferId = text2num(href_list["bufferId"]) if(bufferId < 1 || bufferId > 3) - return 0 // Not a valid buffer id + return FALSE // Not a valid buffer id if(bufferOption == "saveUI") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf = new databuf.types = DNA2_BUF_UI // DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna.Clone() + databuf.dna = connected.occupant.dna.Clone() if(ishuman(connected.occupant)) databuf.dna.real_name=connected.occupant.name databuf.name = "Unique Identifier" - src.buffers[bufferId] = databuf - return 1 + buffers[bufferId] = databuf + return TRUE if(bufferOption == "saveUIAndUE") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf = new databuf.types = DNA2_BUF_UI|DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna.Clone() + databuf.dna = connected.occupant.dna.Clone() if(ishuman(connected.occupant)) databuf.dna.real_name=connected.occupant.dna.real_name databuf.name = "Unique Identifier + Unique Enzymes" - src.buffers[bufferId] = databuf - return 1 + buffers[bufferId] = databuf + return TRUE if(bufferOption == "saveSE") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf = new databuf.types = DNA2_BUF_SE - databuf.dna = src.connected.occupant.dna.Clone() + databuf.dna = connected.occupant.dna.Clone() if(ishuman(connected.occupant)) - databuf.dna.real_name=connected.occupant.dna.real_name + databuf.dna.real_name = connected.occupant.dna.real_name databuf.name = "Structural Enzymes" - src.buffers[bufferId] = databuf - return 1 + buffers[bufferId] = databuf + return TRUE if(bufferOption == "clear") - src.buffers[bufferId]=new /datum/dna2/record() - return 1 + buffers[bufferId] = new /datum/dna2/record() + return TRUE if(bufferOption == "changeLabel") - var/datum/dna2/record/buf = src.buffers[bufferId] + var/datum/dna2/record/buf = buffers[bufferId] var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null) buf.name = text - src.buffers[bufferId] = buf - return 1 + buffers[bufferId] = buf + return TRUE if(bufferOption == "transfer") - if(!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna) - return 1 + if(!connected.occupant || (NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna) + return TRUE irradiating = 2 - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it + var/lock_state = connected.locked + connected.locked = TRUE //lock it SSnanoui.update_uis(src) // update all UIs attached to src sleep(2 SECONDS) irradiating = 0 - src.connected.locked = lock_state + connected.locked = lock_state var/radiation = (rand(20,50) / connected.damage_coeff) - src.connected.occupant.apply_effect(radiation,IRRADIATE,0) + connected.occupant.apply_effect(radiation, IRRADIATE, 0) - if(src.connected.radiation_check()) - return 1 + if(connected.radiation_check()) + return TRUE - var/datum/dna2/record/buf = src.buffers[bufferId] + var/datum/dna2/record/buf = buffers[bufferId] if((buf.types & DNA2_BUF_UI)) if((buf.types & DNA2_BUF_UE)) - src.connected.occupant.real_name = buf.dna.real_name - src.connected.occupant.name = buf.dna.real_name - src.connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) + connected.occupant.real_name = buf.dna.real_name + connected.occupant.name = buf.dna.real_name + connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) else if(buf.types & DNA2_BUF_SE) - src.connected.occupant.dna.SE = buf.dna.SE.Copy() - src.connected.occupant.dna.UpdateSE() - domutcheck(src.connected.occupant,src.connected) - return 1 + connected.occupant.dna.SE = buf.dna.SE.Copy() + connected.occupant.dna.UpdateSE() + domutcheck(connected.occupant, connected) + return TRUE if(bufferOption == "createInjector") if(injector_ready && !waiting_for_user_input) var/success = 1 var/obj/item/dnainjector/I = new /obj/item/dnainjector - var/datum/dna2/record/buf = src.buffers[bufferId] + var/datum/dna2/record/buf = buffers[bufferId] buf = buf.copy() if(href_list["createBlockInjector"]) waiting_for_user_input=1 @@ -897,35 +881,35 @@ I.buf = buf waiting_for_user_input = 0 if(success) - I.forceMove(src.loc) + I.forceMove(loc) I.name += " ([buf.name])" if(connected) I.damage_coeff = connected.damage_coeff - src.injector_ready = 0 + injector_ready = FALSE spawn(300) - src.injector_ready = 1 - return 1 + injector_ready = TRUE + return TRUE if(bufferOption == "loadDisk") - if((isnull(src.disk)) || (!src.disk.buf)) - //src.temphtml = "Invalid disk. Please try again." - return 0 + if((isnull(disk)) || (!disk.buf)) + //temphtml = "Invalid disk. Please try again." + return FALSE - src.buffers[bufferId]=src.disk.buf.copy() - //src.temphtml = "Data loaded." - return 1 + buffers[bufferId] = disk.buf.copy() + //temphtml = "Data loaded." + return TRUE if(bufferOption == "saveDisk") - if((isnull(src.disk)) || (src.disk.read_only)) - //src.temphtml = "Invalid disk. Please try again." - return 0 + if((isnull(disk)) || (disk.read_only)) + //temphtml = "Invalid disk. Please try again." + return FALSE - var/datum/dna2/record/buf = src.buffers[bufferId] + var/datum/dna2/record/buf = buffers[bufferId] - src.disk.buf = buf.copy() - src.disk.name = "data disk - '[buf.dna.real_name]'" - //src.temphtml = "Data saved." - return 1 + disk.buf = buf.copy() + disk.name = "data disk - '[buf.dna.real_name]'" + //temphtml = "Data saved." + return TRUE /////////////////////////// DNA MACHINES diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index e1af06f2ff4..48ffb648121 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -7,113 +7,144 @@ ///////////////////// /datum/dna/gene/disability - name="DISABILITY" + name = "DISABILITY" // Mutation to give (or 0) - var/mutation=0 - - // Disability to give (or 0) - var/disability=0 + var/mutation = 0 // Activation message - var/activation_message="" + var/activation_message = "" // Yay, you're no longer growing 3 arms - var/deactivation_message="" + var/deactivation_message = "" -/datum/dna/gene/disability/can_activate(var/mob/M,var/flags) - return 1 // Always set! +/datum/dna/gene/disability/can_activate(mob/M, flags) + return TRUE // Always set! -/datum/dna/gene/disability/activate(var/mob/living/M, var/connected, var/flags) +/datum/dna/gene/disability/activate(mob/living/M, connected, flags) ..() - if(mutation && !(mutation in M.mutations)) - M.mutations.Add(mutation) - if(disability) - M.disabilities|=disability + M.mutations |= mutation if(activation_message) to_chat(M, "[activation_message]") else testing("[name] has no activation message.") -/datum/dna/gene/disability/deactivate(var/mob/living/M, var/connected, var/flags) +/datum/dna/gene/disability/deactivate(mob/living/M, connected, flags) ..() - if(mutation && (mutation in M.mutations)) - M.mutations.Remove(mutation) - if(disability) - M.disabilities &= ~disability + M.mutations.Remove(mutation) if(deactivation_message) to_chat(M, "[deactivation_message]") else testing("[name] has no deactivation message.") /datum/dna/gene/disability/hallucinate - name="Hallucinate" - activation_message="Your mind says 'Hello'." - deactivation_message ="Sanity returns. Or does it?" + name = "Hallucinate" + activation_message = "Your mind says 'Hello'." + deactivation_message = "Sanity returns. Or does it?" instability = -GENE_INSTABILITY_MODERATE - mutation=HALLUCINATE + mutation = HALLUCINATE /datum/dna/gene/disability/hallucinate/New() - block=GLOB.hallucinationblock + ..() + block = GLOB.hallucinationblock + +/datum/dna/gene/disability/hallucinate/OnMobLife(mob/living/carbon/human/H) + if(prob(1)) + H.Hallucinate(20) /datum/dna/gene/disability/epilepsy - name="Epilepsy" - activation_message="You get a headache." - deactivation_message ="Your headache is gone, at last." + name = "Epilepsy" + activation_message = "You get a headache." + deactivation_message = "Your headache is gone, at last." instability = -GENE_INSTABILITY_MODERATE - disability=EPILEPSY + mutation = EPILEPSY /datum/dna/gene/disability/epilepsy/New() - block=GLOB.epilepsyblock + ..() + block = GLOB.epilepsyblock + +/datum/dna/gene/disability/epilepsy/OnMobLife(mob/living/carbon/human/H) + if((prob(1) && H.paralysis < 1)) + H.visible_message("[src] starts having a seizure!","You have a seizure!") + H.Paralyse(10) + H.Jitter(1000) /datum/dna/gene/disability/cough - name="Coughing" - activation_message="You start coughing." - deactivation_message ="Your throat stops aching." + name = "Coughing" + activation_message = "You start coughing." + deactivation_message = "Your throat stops aching." instability = -GENE_INSTABILITY_MINOR - disability=COUGHING + mutation = COUGHING /datum/dna/gene/disability/cough/New() - block=GLOB.coughblock + ..() + block = GLOB.coughblock + +/datum/dna/gene/disability/cough/OnMobLife(mob/living/carbon/human/H) + if((prob(5) && H.paralysis <= 1)) + H.drop_item() + H.emote("cough") /datum/dna/gene/disability/clumsy - name="Clumsiness" - activation_message="You feel lightheaded." - deactivation_message ="You regain some control of your movements" + name = "Clumsiness" + activation_message = "You feel lightheaded." + deactivation_message = "You regain some control of your movements" instability = -GENE_INSTABILITY_MINOR - mutation=CLUMSY + mutation = CLUMSY /datum/dna/gene/disability/clumsy/New() - block=GLOB.clumsyblock + ..() + block = GLOB.clumsyblock /datum/dna/gene/disability/tourettes - name="Tourettes" - activation_message="You twitch." - deactivation_message ="Your mouth tastes like soap." + name = "Tourettes" + activation_message = "You twitch." + deactivation_message = "Your mouth tastes like soap." instability = -GENE_INSTABILITY_MODERATE - disability=TOURETTES + mutation = TOURETTES /datum/dna/gene/disability/tourettes/New() - block=GLOB.twitchblock + ..() + block = GLOB.twitchblock + +/datum/dna/gene/disability/tourettes/OnMobLife(mob/living/carbon/human/H) + if((prob(10) && H.paralysis <= 1)) + H.Stun(10) + switch(rand(1, 3)) + if(1) + H.emote("twitch") + if(2 to 3) + H.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") + var/x_offset_old = H.pixel_x + var/y_offset_old = H.pixel_y + var/x_offset = H.pixel_x + rand(-2, 2) + var/y_offset = H.pixel_y + rand(-1, 1) + animate(H, pixel_x = x_offset, pixel_y = y_offset, time = 1) + animate(H, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1) /datum/dna/gene/disability/nervousness - name="Nervousness" + name = "Nervousness" activation_message="You feel nervous." deactivation_message ="You feel much calmer." - disability=NERVOUS + mutation = NERVOUS /datum/dna/gene/disability/nervousness/New() - block=GLOB.nervousblock + ..() + block = GLOB.nervousblock +/datum/dna/gene/disability/nervousness/OnMobLife(mob/living/carbon/human/H) + if(prob(10)) + H.Stuttering(10) /datum/dna/gene/disability/blindness - name="Blindness" + name = "Blindness" activation_message = "You can't seem to see anything." deactivation_message = "You can see now, in case you didn't notice..." instability = -GENE_INSTABILITY_MAJOR - disability = BLIND + mutation = BLINDNESS /datum/dna/gene/disability/blindness/New() + ..() block = GLOB.blindblock /datum/dna/gene/disability/blindness/activate(mob/M, connected, flags) @@ -130,51 +161,54 @@ activation_message = "You feel a peculiar prickling in your eyes while your perception of colour changes." deactivation_message ="Your eyes tingle unsettlingly, though everything seems to become alot more colourful." instability = -GENE_INSTABILITY_MODERATE - disability = COLOURBLIND + mutation = COLOURBLIND /datum/dna/gene/disability/colourblindness/New() - block=GLOB.colourblindblock + ..() + block = GLOB.colourblindblock -/datum/dna/gene/disability/colourblindness/activate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/disability/colourblindness/activate(mob/M, connected, flags) ..() M.update_client_colour() //Handle the activation of the colourblindness on the mob. M.update_icons() //Apply eyeshine as needed. -/datum/dna/gene/disability/colourblindness/deactivate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/disability/colourblindness/deactivate(mob/M, connected, flags) ..() M.update_client_colour() //Handle the deactivation of the colourblindness on the mob. M.update_icons() //Remove eyeshine as needed. /datum/dna/gene/disability/deaf - name="Deafness" + name = "Deafness" activation_message="It's kinda quiet." deactivation_message ="You can hear again!" instability = -GENE_INSTABILITY_MAJOR - disability=DEAF + mutation = DEAF /datum/dna/gene/disability/deaf/New() - block=GLOB.deafblock + ..() + block = GLOB.deafblock -/datum/dna/gene/disability/deaf/activate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/disability/deaf/activate(mob/M, connected, flags) ..() M.MinimumDeafTicks(1) /datum/dna/gene/disability/nearsighted - name="Nearsightedness" + name = "Nearsightedness" activation_message="Your eyes feel weird..." deactivation_message ="You can see clearly now" instability = -GENE_INSTABILITY_MODERATE - disability=NEARSIGHTED + mutation = NEARSIGHTED /datum/dna/gene/disability/nearsighted/New() - block=GLOB.glassesblock + ..() + block = GLOB.glassesblock /datum/dna/gene/disability/nearsighted/activate(mob/living/M, connected, flags) - . = ..() + ..() M.update_nearsighted_effects() /datum/dna/gene/disability/nearsighted/deactivate(mob/living/M, connected, flags) - . = ..() + ..() M.update_nearsighted_effects() /datum/dna/gene/disability/lisp @@ -186,9 +220,9 @@ /datum/dna/gene/disability/lisp/New() ..() - block=GLOB.lispblock + block = GLOB.lispblock -/datum/dna/gene/disability/lisp/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/lisp/OnSay(mob/M, message) return replacetext(message,"s","th") /datum/dna/gene/disability/comic @@ -196,9 +230,10 @@ desc = "This will only bring death and destruction." activation_message = "Uh oh!" deactivation_message = "Well thank god that's over with." - mutation=COMIC + mutation = COMIC /datum/dna/gene/disability/comic/New() + ..() block = GLOB.comicblock /datum/dna/gene/disability/wingdings @@ -210,9 +245,10 @@ mutation = WINGDINGS /datum/dna/gene/disability/wingdings/New() + ..() block = GLOB.wingdingsblock -/datum/dna/gene/disability/wingdings/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/wingdings/OnSay(mob/M, message) var/list/chars = string2charlist(message) var/garbled_message = "" for(var/C in chars) diff --git a/code/game/dna/genes/gene.dm b/code/game/dna/genes/gene.dm index a8357a437f1..1509cd098a4 100644 --- a/code/game/dna/genes/gene.dm +++ b/code/game/dna/genes/gene.dm @@ -11,63 +11,61 @@ /datum/dna/gene // Display name - var/name="BASE GENE" + var/name = "BASE GENE" // Probably won't get used but why the fuck not var/desc="Oh god who knows what this does." // Set in initialize()! // What gene activates this? - var/block=0 + var/block = 0 // Any of a number of GENE_ flags. - var/flags=0 + var/flags = 0 // Chance of the gene to cause adverse effects when active - var/instability=0 + var/instability = 0 /* * Is the gene active in this mob's DNA? */ -/datum/dna/gene/proc/is_active(var/mob/M) +/datum/dna/gene/proc/is_active(mob/M) return M.active_genes && (type in M.active_genes) // Return 1 if we can activate. // HANDLE MUTCHK_FORCED HERE! -/datum/dna/gene/proc/can_activate(var/mob/M, var/flags) - return 0 +/datum/dna/gene/proc/can_activate(mob/M, flags) + return FALSE // Called when the gene activates. Do your magic here. -/datum/dna/gene/proc/activate(var/mob/living/M, var/connected, var/flags) +/datum/dna/gene/proc/activate(mob/living/M, connected, flags) M.gene_stability -= instability - return /** * Called when the gene deactivates. Undo your magic here. * Only called when the block is deactivated. */ -/datum/dna/gene/proc/deactivate(var/mob/living/M, var/connected, var/flags) +/datum/dna/gene/proc/deactivate(mob/living/M, connected, flags) M.gene_stability += instability - return // This section inspired by goone's bioEffects. /** * Called in each life() tick. */ -/datum/dna/gene/proc/OnMobLife(var/mob/M) +/datum/dna/gene/proc/OnMobLife(mob/M) return /** * Called when the mob dies */ -/datum/dna/gene/proc/OnMobDeath(var/mob/M) +/datum/dna/gene/proc/OnMobDeath(mob/M) return /** * Called when the mob says shit */ -/datum/dna/gene/proc/OnSay(var/mob/M, var/message) +/datum/dna/gene/proc/OnSay(mob/M, message) return message /** @@ -77,7 +75,7 @@ * @params g Gender (m or f) */ /datum/dna/gene/proc/OnDrawUnderlays(mob/M, g) - return 0 + return FALSE ///////////////////// @@ -93,34 +91,34 @@ /datum/dna/gene/basic - name="BASIC GENE" + name = "BASIC GENE" // Mutation to give - var/mutation=0 + var/mutation = 0 // Activation probability - var/activation_prob=100 + var/activation_prob = 100 // Possible activation messages - var/list/activation_messages=list() + var/list/activation_messages = list() // Possible deactivation messages - var/list/deactivation_messages=list() + var/list/deactivation_messages = list() -/datum/dna/gene/basic/can_activate(var/mob/M,var/flags) +/datum/dna/gene/basic/can_activate(mob/M, flags) if(flags & MUTCHK_FORCED) - return 1 + return TRUE // Probability check return prob(activation_prob) -/datum/dna/gene/basic/activate(var/mob/M) +/datum/dna/gene/basic/activate(mob/M, connected, flags) ..() M.mutations.Add(mutation) if(activation_messages.len) var/msg = pick(activation_messages) to_chat(M, "[msg]") -/datum/dna/gene/basic/deactivate(var/mob/M) +/datum/dna/gene/basic/deactivate(mob/living/M, connected, flags) ..() M.mutations.Remove(mutation) if(deactivation_messages.len) diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index f8c9f53d0e5..7615f737cd0 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -13,13 +13,13 @@ activation_message = "You feel unable to express yourself at all." deactivation_message = "You feel able to speak freely again." instability = -GENE_INSTABILITY_MODERATE - disability = MUTE + mutation = MUTE /datum/dna/gene/disability/mute/New() ..() - block=GLOB.muteblock + block = GLOB.muteblock -/datum/dna/gene/disability/mute/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/mute/OnSay(mob/M, message) return "" //////////////////////////////////////// @@ -36,27 +36,26 @@ /datum/dna/gene/disability/radioactive/New() ..() - block=GLOB.radblock + block = GLOB.radblock -/datum/dna/gene/disability/radioactive/can_activate(var/mob/M,var/flags) +/datum/dna/gene/disability/radioactive/can_activate(mob/M, flags) if(!..()) - return 0 + return FALSE if(ishuman(M)) var/mob/living/carbon/human/H = M if((RADIMMUNE in H.dna.species.species_traits) && !(flags & MUTCHK_FORCED)) - return 0 - return 1 + return FALSE + return TRUE -/datum/dna/gene/disability/radioactive/OnMobLife(var/mob/living/owner) - var/radiation_amount = abs(min(owner.radiation - 20,0)) - owner.apply_effect(radiation_amount, IRRADIATE) - for(var/mob/living/L in range(1, owner)) - if(L == owner) +/datum/dna/gene/disability/radioactive/OnMobLife(mob/living/carbon/human/H) + var/radiation_amount = abs(min(H.radiation - 20,0)) + H.apply_effect(radiation_amount, IRRADIATE) + for(var/mob/living/L in range(1, H)) + if(L == H) continue - to_chat(L, "You are enveloped by a soft green glow emanating from [owner].") + to_chat(L, "You are enveloped by a soft green glow emanating from [H].") L.apply_effect(5, IRRADIATE) - return /datum/dna/gene/disability/radioactive/OnDrawUnderlays(mob/M, g) return "rads_s" @@ -76,7 +75,7 @@ /datum/dna/gene/disability/fat/New() ..() - block=GLOB.fatblock + block = GLOB.fatblock // WAS: /datum/bioEffect/chav /datum/dna/gene/disability/speech/chav @@ -88,9 +87,9 @@ /datum/dna/gene/disability/speech/chav/New() ..() - block=GLOB.chavblock + block = GLOB.chavblock -/datum/dna/gene/disability/speech/chav/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/speech/chav/OnSay(mob/M, message) // THIS ENTIRE THING BEGS FOR REGEX message = replacetext(message,"dick","prat") message = replacetext(message,"comdom","knob'ead") @@ -127,9 +126,9 @@ /datum/dna/gene/disability/speech/swedish/New() ..() - block=GLOB.swedeblock + block = GLOB.swedeblock -/datum/dna/gene/disability/speech/swedish/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/speech/swedish/OnSay(mob/M, message) // svedish message = replacetextEx(message,"W","V") message = replacetextEx(message,"w","v") @@ -157,10 +156,10 @@ /datum/dna/gene/disability/unintelligable/New() ..() - block=GLOB.scrambleblock + block = GLOB.scrambleblock -/datum/dna/gene/disability/unintelligable/OnSay(var/mob/M, var/message) - var/prefix=copytext(message,1,2) +/datum/dna/gene/disability/unintelligable/OnSay(mob/M, message) + var/prefix = copytext(message,1,2) if(prefix == ";") message = copytext(message,2) else if(prefix in list(":","#")) @@ -197,7 +196,7 @@ /datum/dna/gene/disability/strong/New() ..() - block=GLOB.strongblock + block = GLOB.strongblock // WAS: /datum/bioEffect/horns /datum/dna/gene/disability/horns @@ -209,7 +208,7 @@ /datum/dna/gene/disability/horns/New() ..() - block=GLOB.hornsblock + block = GLOB.hornsblock /datum/dna/gene/disability/horns/OnDrawUnderlays(mob/M, g) return "horns_s" @@ -223,7 +222,7 @@ deactivation_messages = list("You no longer feel uncomfortably hot.") mutation = IMMOLATE - spelltype=/obj/effect/proc_holder/spell/targeted/immolate + spelltype = /obj/effect/proc_holder/spell/targeted/immolate /datum/dna/gene/basic/grant_spell/immolate/New() ..() diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index fd2f300e8fb..87bbdf97c5c 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -2,26 +2,28 @@ // WAS: /datum/bioEffect/alcres /datum/dna/gene/basic/sober - name="Sober" - activation_messages=list("You feel unusually sober.") + name = "Sober" + activation_messages = list("You feel unusually sober.") deactivation_messages = list("You feel like you could use a stiff drink.") - mutation=SOBER + mutation = SOBER /datum/dna/gene/basic/sober/New() - block=GLOB.soberblock + ..() + block = GLOB.soberblock //WAS: /datum/bioEffect/psychic_resist /datum/dna/gene/basic/psychic_resist - name="Psy-Resist" + name = "Psy-Resist" desc = "Boosts efficiency in sectors of the brain commonly associated with meta-mental energies." activation_messages = list("Your mind feels closed.") deactivation_messages = list("You feel oddly exposed.") - mutation=PSY_RESIST + mutation = PSY_RESIST /datum/dna/gene/basic/psychic_resist/New() - block=GLOB.psyresistblock + ..() + block = GLOB.psyresistblock ///////////////////////// // Stealth Enhancers @@ -30,16 +32,16 @@ /datum/dna/gene/basic/stealth instability = GENE_INSTABILITY_MODERATE -/datum/dna/gene/basic/stealth/can_activate(var/mob/M, var/flags) +/datum/dna/gene/basic/stealth/can_activate(mob/M, flags) // Can only activate one of these at a time. if(is_type_in_list(/datum/dna/gene/basic/stealth,M.active_genes)) testing("Cannot activate [type]: /datum/dna/gene/basic/stealth in M.active_genes.") - return 0 - return ..(M,flags) + return FALSE + return ..() -/datum/dna/gene/basic/stealth/deactivate(var/mob/M) - ..(M) - M.alpha=255 +/datum/dna/gene/basic/stealth/deactivate(mob/living/M, connected, flags) + ..() + M.alpha = 255 // WAS: /datum/bioEffect/darkcloak /datum/dna/gene/basic/stealth/darkcloak @@ -47,13 +49,14 @@ desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect." activation_messages = list("You begin to fade into the shadows.") deactivation_messages = list("You become fully visible.") - activation_prob=25 + activation_prob = 25 mutation = CLOAK /datum/dna/gene/basic/stealth/darkcloak/New() - block=GLOB.shadowblock + ..() + block = GLOB.shadowblock -/datum/dna/gene/basic/stealth/darkcloak/OnMobLife(var/mob/M) +/datum/dna/gene/basic/stealth/darkcloak/OnMobLife(mob/M) var/turf/simulated/T = get_turf(M) if(!istype(T)) return @@ -69,13 +72,14 @@ desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still." activation_messages = list("You feel one with your surroundings.") deactivation_messages = list("You feel oddly visible.") - activation_prob=25 + activation_prob = 25 mutation = CHAMELEON /datum/dna/gene/basic/stealth/chameleon/New() - block=GLOB.chameleonblock + ..() + block = GLOB.chameleonblock -/datum/dna/gene/basic/stealth/chameleon/OnMobLife(var/mob/M) +/datum/dna/gene/basic/stealth/chameleon/OnMobLife(mob/M) if((world.time - M.last_movement) >= 30 && !M.stat && M.canmove && !M.restrained()) M.alpha -= 25 else @@ -86,27 +90,27 @@ /datum/dna/gene/basic/grant_spell var/obj/effect/proc_holder/spell/spelltype -/datum/dna/gene/basic/grant_spell/activate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/grant_spell/activate(mob/M, connected, flags) M.AddSpell(new spelltype(null)) ..() - return 1 + return TRUE -/datum/dna/gene/basic/grant_spell/deactivate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/grant_spell/deactivate(mob/M, connected, flags) for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list) if(istype(S, spelltype)) M.RemoveSpell(S) ..() - return 1 + return TRUE /datum/dna/gene/basic/grant_verb var/verbtype -/datum/dna/gene/basic/grant_verb/activate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/grant_verb/activate(mob/M, connected, flags) ..() M.verbs += verbtype - return 1 + return TRUE -/datum/dna/gene/basic/grant_verb/deactivate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/grant_verb/deactivate(mob/M, connected, flags) ..() M.verbs -= verbtype @@ -183,8 +187,6 @@ new/obj/effect/self_deleting(C.loc, icon('icons/effects/genetics.dmi', "cryokinesis")) - return - /obj/effect/self_deleting density = 0 opacity = 0 @@ -193,12 +195,11 @@ desc = "" //layer = 15 -/obj/effect/self_deleting/New(var/atom/location, var/icon/I, var/duration = 20, var/oname = "something") - src.name = oname +/obj/effect/self_deleting/New(atom/location, icon/I, duration = 20, oname = "something") + name = oname loc=location - src.icon = I - spawn(duration) - qdel(src) + icon = I + QDEL_IN(src, duration) /////////////////////////////////////////////////////////////////////////////////////////// @@ -255,7 +256,7 @@ /obj/item/implant ) -/obj/effect/proc_holder/spell/targeted/eat/proc/doHeal(var/mob/user) +/obj/effect/proc_holder/spell/targeted/eat/proc/doHeal(mob/user) if(ishuman(user)) var/mob/living/carbon/human/H = user for(var/name in H.bodyparts_by_name) @@ -300,12 +301,12 @@ perform(targets, user = user) /obj/effect/proc_holder/spell/targeted/eat/proc/check_mouth(mob/user = usr) - var/can_eat = 1 + var/can_eat = TRUE if(iscarbon(user)) var/mob/living/carbon/C = user if((C.head && (C.head.flags_cover & HEADCOVERSMOUTH)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSMOUTH) && !C.wear_mask.mask_adjusted)) to_chat(C, "Your mouth is covered, preventing you from eating!") - can_eat = 0 + can_eat = FALSE return can_eat /obj/effect/proc_holder/spell/targeted/eat/cast(list/targets, mob/user = usr) @@ -320,17 +321,17 @@ if(!istype(limb)) to_chat(user, "You can't eat this part of them!") revert_cast() - return 0 + return FALSE if(istype(limb,/obj/item/organ/external/head)) // Bullshit, but prevents being unable to clone someone. to_chat(user, "You try to put \the [limb] in your mouth, but [the_item.p_their()] ears tickle your throat!") revert_cast() - return 0 + return FALSE if(istype(limb,/obj/item/organ/external/chest)) // Bullshit, but prevents being able to instagib someone. to_chat(user, "You try to put [the_item.p_their()] [limb] in your mouth, but it's too big to fit!") revert_cast() - return 0 + return FALSE user.visible_message("[user] begins stuffing [the_item]'s [limb.name] into [user.p_their()] gaping maw!") var/oldloc = H.loc if(!do_mob(user,H,EAT_MOB_DELAY)) @@ -350,7 +351,6 @@ playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0) qdel(the_item) doHeal(user) - return //////////////////////////////////////////////////////////////////////// @@ -387,7 +387,7 @@ action_icon_state = "genetic_jump" /obj/effect/proc_holder/spell/targeted/leap/cast(list/targets, mob/user = usr) - var/failure = 0 + var/failure = FALSE if(istype(user.loc,/mob/) || user.lying || user.stunned || user.buckled || user.stat) to_chat(user, "You can't jump right now!") return @@ -397,7 +397,7 @@ for(var/mob/M in range(user, 1)) if(M.pulling == user) if(!M.restrained() && M.stat == 0 && M.canmove && user.Adjacent(M)) - failure = 1 + failure = TRUE else M.stop_pulling() @@ -409,12 +409,12 @@ user.visible_message("[user] attempts to leap away but is slammed back down to the ground!", "You attempt to leap away but are suddenly slammed back down to the ground!", "You hear the flexing of powerful muscles and suddenly a crash as a body hits the floor.") - return 0 + return FALSE var/prevLayer = user.layer var/prevFlying = user.flying user.layer = 9 - user.flying = 1 + user.flying = TRUE for(var/i=0, i<10, i++) step(user, user.dir) if(i < 5) user.pixel_y += 8 @@ -508,7 +508,7 @@ activation_messages = list("You suddenly notice more about others than you did before.") deactivation_messages = list("You no longer feel able to sense intentions.") instability = GENE_INSTABILITY_MINOR - mutation=EMPATH + mutation = EMPATH /datum/dna/gene/basic/grant_spell/empath/New() ..() @@ -614,4 +614,3 @@ to_chat(M, "You sense [user.name] reading your mind.") else if(prob(5) || M.mind.assigned_role=="Chaplain") to_chat(M, "You sense someone intruding upon your thoughts...") - return diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 3b6182ecf63..583b2c75836 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -1,10 +1,11 @@ /datum/dna/gene/monkey - name="Monkey" + name = "Monkey" /datum/dna/gene/monkey/New() - block=GLOB.monkeyblock + ..() + block = GLOB.monkeyblock -/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) +/datum/dna/gene/monkey/can_activate(mob/M, flags) return ishuman(M) /datum/dna/gene/monkey/activate(mob/living/carbon/human/H, connected, flags) @@ -21,7 +22,7 @@ H.regenerate_icons() H.SetStunned(1) - H.canmove = 0 + H.canmove = FALSE H.icon = null H.invisibility = 101 var/has_primitive_form = H.dna.species.primitive_form // cache this diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index 465a58cab25..d893c64565c 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -3,109 +3,121 @@ /////////////////////////////////// /datum/dna/gene/basic/nobreath - name="No Breathing" - activation_messages=list("You feel no need to breathe.") - deactivation_messages=list("You feel the need to breathe, once more.") + name = "No Breathing" + activation_messages = list("You feel no need to breathe.") + deactivation_messages = list("You feel the need to breathe, once more.") instability = GENE_INSTABILITY_MODERATE mutation = BREATHLESS - activation_prob=25 + activation_prob = 25 /datum/dna/gene/basic/nobreath/New() + ..() block = GLOB.breathlessblock /datum/dna/gene/basic/regenerate - name="Regenerate" - activation_messages=list("Your wounds start healing.") - deactivation_messages=list("Your regenerative powers feel like they've vanished.") + name = "Regenerate" + activation_messages = list("Your wounds start healing.") + deactivation_messages = list("Your regenerative powers feel like they've vanished.") instability = GENE_INSTABILITY_MINOR - mutation=REGEN + mutation = REGEN /datum/dna/gene/basic/regenerate/New() - block=GLOB.regenerateblock + ..() + block = GLOB.regenerateblock + +/datum/dna/gene/basic/regenerate/OnMobLife(mob/living/carbon/human/H) + H.adjustBruteLoss(-0.1, FALSE) + H.adjustFireLoss(-0.1) /datum/dna/gene/basic/increaserun - name="Super Speed" - activation_messages=list("You feel swift and unencumbered.") - deactivation_messages=list("You feel slow.") + name = "Super Speed" + activation_messages = list("You feel swift and unencumbered.") + deactivation_messages = list("You feel slow.") instability = GENE_INSTABILITY_MINOR - mutation=RUN + mutation = RUN /datum/dna/gene/basic/increaserun/New() - block=GLOB.increaserunblock + ..() + block = GLOB.increaserunblock -/datum/dna/gene/basic/increaserun/can_activate(var/mob/M,var/flags) +/datum/dna/gene/basic/increaserun/can_activate(mob/M, flags) if(!..()) - return 0 + return FALSE if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.dna.species && H.dna.species.speed_mod && !(flags & MUTCHK_FORCED)) - return 0 - return 1 + return FALSE + return TRUE /datum/dna/gene/basic/heat_resist - name="Heat Resistance" - activation_messages=list("Your skin is icy to the touch.") - deactivation_messages=list("Your skin no longer feels icy to the touch.") + name = "Heat Resistance" + activation_messages = list("Your skin is icy to the touch.") + deactivation_messages = list("Your skin no longer feels icy to the touch.") instability = GENE_INSTABILITY_MODERATE mutation = HEATRES /datum/dna/gene/basic/heat_resist/New() - block=GLOB.coldblock + ..() + block = GLOB.coldblock /datum/dna/gene/basic/heat_resist/OnDrawUnderlays(mob/M, g) return "cold_s" /datum/dna/gene/basic/cold_resist - name="Cold Resistance" - activation_messages=list("Your body is filled with warmth.") - deactivation_messages=list("Your body is no longer filled with warmth.") + name = "Cold Resistance" + activation_messages = list("Your body is filled with warmth.") + deactivation_messages = list("Your body is no longer filled with warmth.") instability = GENE_INSTABILITY_MODERATE mutation = COLDRES /datum/dna/gene/basic/cold_resist/New() - block=GLOB.fireblock + ..() + block = GLOB.fireblock /datum/dna/gene/basic/cold_resist/OnDrawUnderlays(mob/M, g) return "fire_s" /datum/dna/gene/basic/noprints - name="No Prints" - activation_messages=list("Your fingers feel numb.") - deactivation_messages=list("your fingers no longer feel numb.") + name = "No Prints" + activation_messages = list("Your fingers feel numb.") + deactivation_messages = list("your fingers no longer feel numb.") instability = GENE_INSTABILITY_MINOR - mutation=FINGERPRINTS + mutation = FINGERPRINTS /datum/dna/gene/basic/noprints/New() - block=GLOB.noprintsblock + ..() + block = GLOB.noprintsblock /datum/dna/gene/basic/noshock - name="Shock Immunity" - activation_messages=list("Your skin feels dry and unreactive.") - deactivation_messages=list("Your skin no longer feels dry and unreactive.") + name = "Shock Immunity" + activation_messages = list("Your skin feels dry and unreactive.") + deactivation_messages = list("Your skin no longer feels dry and unreactive.") instability = GENE_INSTABILITY_MODERATE - mutation=NO_SHOCK + mutation = NO_SHOCK /datum/dna/gene/basic/noshock/New() - block=GLOB.shockimmunityblock + ..() + block = GLOB.shockimmunityblock /datum/dna/gene/basic/midget - name="Midget" - activation_messages=list("Everything around you seems bigger now...") + name = "Midget" + activation_messages = list("Everything around you seems bigger now...") deactivation_messages = list("Everything around you seems to shrink...") instability = GENE_INSTABILITY_MINOR - mutation=DWARF + mutation = DWARF /datum/dna/gene/basic/midget/New() - block=GLOB.smallsizeblock + ..() + block = GLOB.smallsizeblock -/datum/dna/gene/basic/midget/activate(var/mob/M, var/connected, var/flags) - ..(M,connected,flags) +/datum/dna/gene/basic/midget/activate(mob/M, connected, flags) + ..() M.pass_flags |= PASSTABLE M.resize = 0.8 M.update_transform() -/datum/dna/gene/basic/midget/deactivate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/midget/deactivate(mob/M, connected, flags) ..() M.pass_flags &= ~PASSTABLE M.resize = 1.25 @@ -113,31 +125,32 @@ // OLD HULK BEHAVIOR /datum/dna/gene/basic/hulk - name="Hulk" - activation_messages=list("Your muscles hurt.") - deactivation_messages=list("Your muscles shrink.") + name = "Hulk" + activation_messages = list("Your muscles hurt.") + deactivation_messages = list("Your muscles shrink.") instability = GENE_INSTABILITY_MAJOR - mutation=HULK - activation_prob=15 + mutation = HULK + activation_prob = 15 /datum/dna/gene/basic/hulk/New() - block=GLOB.hulkblock + ..() + block = GLOB.hulkblock -/datum/dna/gene/basic/hulk/activate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/hulk/activate(mob/M, connected, flags) ..() var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH M.status_flags &= ~status -/datum/dna/gene/basic/hulk/deactivate(var/mob/M, var/connected, var/flags) +/datum/dna/gene/basic/hulk/deactivate(mob/M, connected, flags) ..() M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH /datum/dna/gene/basic/hulk/OnDrawUnderlays(mob/M, g) if(HULK in M.mutations) return "hulk_[g]_s" - return 0 + return FALSE -/datum/dna/gene/basic/hulk/OnMobLife(var/mob/living/carbon/human/M) +/datum/dna/gene/basic/hulk/OnMobLife(mob/living/carbon/human/M) if(!istype(M)) return if((HULK in M.mutations) && M.health <= 0) @@ -150,15 +163,16 @@ to_chat(M, "You suddenly feel very weak.") /datum/dna/gene/basic/xray - name="X-Ray Vision" - activation_messages=list("The walls suddenly disappear.") - deactivation_messages=list("the walls around you re-appear.") + name = "X-Ray Vision" + activation_messages = list("The walls suddenly disappear.") + deactivation_messages = list("the walls around you re-appear.") instability = GENE_INSTABILITY_MAJOR - mutation=XRAY - activation_prob=15 + mutation = XRAY + activation_prob = 15 /datum/dna/gene/basic/xray/New() - block=GLOB.xrayblock + ..() + block = GLOB.xrayblock /datum/dna/gene/basic/xray/activate(mob/living/M, connected, flags) ..() @@ -171,15 +185,16 @@ M.update_icons() //Remove eyeshine as needed. /datum/dna/gene/basic/tk - name="Telekenesis" + name = "Telekenesis" activation_messages = list("You feel smarter.") deactivation_messages = list("You feel dumber.") instability = GENE_INSTABILITY_MAJOR - mutation=TK - activation_prob=15 + mutation = TK + activation_prob = 15 /datum/dna/gene/basic/tk/New() - block=GLOB.teleblock + ..() + block = GLOB.teleblock /datum/dna/gene/basic/tk/OnDrawUnderlays(mob/M, g) return "telekinesishead_s" diff --git a/code/game/dna/genes/vg_disabilities.dm b/code/game/dna/genes/vg_disabilities.dm index d423f0bf89b..c2ad1559b6a 100644 --- a/code/game/dna/genes/vg_disabilities.dm +++ b/code/game/dna/genes/vg_disabilities.dm @@ -8,11 +8,11 @@ /datum/dna/gene/disability/speech/loud/New() ..() - block=GLOB.loudblock + block = GLOB.loudblock -/datum/dna/gene/disability/speech/loud/OnSay(var/mob/M, var/message) +/datum/dna/gene/disability/speech/loud/OnSay(mob/M, message) message = replacetext(message,".","!") message = replacetext(message,"?","?!") message = replacetext(message,"!","!!") @@ -28,15 +28,15 @@ /datum/dna/gene/disability/dizzy/New() ..() - block=GLOB.dizzyblock + block = GLOB.dizzyblock -/datum/dna/gene/disability/dizzy/OnMobLife(var/mob/living/carbon/human/M) +/datum/dna/gene/disability/dizzy/OnMobLife(mob/living/carbon/human/M) if(!istype(M)) return if(DIZZY in M.mutations) M.Dizzy(300) /datum/dna/gene/disability/dizzy/deactivate(mob/living/M, connected, flags) - . = ..() + ..() M.SetDizzy(0) diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 5ed6c705a17..cc54d817752 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -4,10 +4,10 @@ name = "Morphism" desc = "Enables the subject to reconfigure their appearance to that of any human." spelltype =/obj/effect/proc_holder/spell/targeted/morph - activation_messages=list("Your body feels if can alter its appearance.") + activation_messages = list("Your body feels if can alter its appearance.") deactivation_messages = list("Your body doesn't feel capable of altering its appearance.") instability = GENE_INSTABILITY_MINOR - mutation=MORPH + mutation = MORPH /datum/dna/gene/basic/grant_spell/morph/New() ..() @@ -29,7 +29,8 @@ action_icon_state = "genetic_morph" /obj/effect/proc_holder/spell/targeted/morph/cast(list/targets, mob/user = usr) - if(!ishuman(user)) return + if(!ishuman(user)) + return if(istype(user.loc,/mob/)) to_chat(user, "You can't change your appearance right now!") @@ -176,21 +177,21 @@ M.visible_message("[src] morphs and changes [p_their()] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") /datum/dna/gene/basic/grant_spell/remotetalk - name="Telepathy" - activation_messages=list("You feel you can project your thoughts.") - deactivation_messages=list("You no longer feel you can project your thoughts.") + name = "Telepathy" + activation_messages = list("You feel you can project your thoughts.") + deactivation_messages = list("You no longer feel you can project your thoughts.") instability = GENE_INSTABILITY_MINOR - mutation=REMOTE_TALK + mutation = REMOTE_TALK spelltype =/obj/effect/proc_holder/spell/targeted/remotetalk /datum/dna/gene/basic/grant_spell/remotetalk/New() ..() - block=GLOB.remotetalkblock + block = GLOB.remotetalkblock -/datum/dna/gene/basic/grant_spell/remotetalk/activate(mob/user) +/datum/dna/gene/basic/grant_spell/remotetalk/activate(mob/living/M, connected, flags) ..() - user.AddSpell(new /obj/effect/proc_holder/spell/targeted/mindscan(null)) + M.AddSpell(new /obj/effect/proc_holder/spell/targeted/mindscan(null)) /datum/dna/gene/basic/grant_spell/remotetalk/deactivate(mob/user) ..() @@ -336,22 +337,23 @@ return ..() /datum/dna/gene/basic/grant_spell/remoteview - name="Remote Viewing" - activation_messages=list("Your mind can see things from afar.") - deactivation_messages=list("Your mind can no longer can see things from afar.") + name = "Remote Viewing" + activation_messages = list("Your mind can see things from afar.") + deactivation_messages = list("Your mind can no longer can see things from afar.") instability = GENE_INSTABILITY_MINOR - mutation=REMOTE_VIEW + mutation = REMOTE_VIEW spelltype =/obj/effect/proc_holder/spell/targeted/remoteview /datum/dna/gene/basic/grant_spell/remoteview/New() - block=GLOB.remoteviewblock + ..() + block = GLOB.remoteviewblock /obj/effect/proc_holder/spell/targeted/remoteview name = "Remote View" desc = "Spy on people from any range!" - charge_max = 600 + charge_max = 100 clothes_req = 0 stat_allowed = 0 @@ -363,18 +365,23 @@ /obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr) var/list/targets = list() - var/list/remoteviewers = new /list() - for(var/mob/M in GLOB.living_mob_list) + var/list/remoteviewers = list() + for(var/mob/M in GLOB.alive_mob_list) + if(M == user) + continue if(PSY_RESIST in M.mutations) continue if(REMOTE_VIEW in M.mutations) remoteviewers += M - if(!remoteviewers.len || remoteviewers.len == 1) + if(!LAZYLEN(remoteviewers)) to_chat(user, "No valid targets with remote view were found!") start_recharge() return - targets += input("Choose the target to spy on.", "Targeting") as mob in remoteviewers - + targets += input("Choose the target to spy on.", "Targeting") as null|anything in remoteviewers + if(!targets) + to_chat(user, "You decide against remote viewing.") + start_recharge() + return perform(targets, user = user) /obj/effect/proc_holder/spell/targeted/remoteview/cast(list/targets, mob/user = usr) @@ -386,15 +393,15 @@ var/mob/target - if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab/)) + if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab)) to_chat(H, "Your mind is too busy with that telekinetic grab.") H.remoteview_target = null - H.reset_perspective(0) + H.reset_perspective() return if(H.client.eye != user.client.mob) H.remoteview_target = null - H.reset_perspective(0) + H.reset_perspective() return for(var/mob/living/L in targets) @@ -405,4 +412,4 @@ H.reset_perspective(target) else H.remoteview_target = null - H.reset_perspective(0) + H.reset_perspective() diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 74ed59d2469..0c2342328a2 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -35,11 +35,15 @@ color = blob_reagent_datum.complementary_color ..() + START_PROCESSING(SSobj, src) -/mob/camera/blob/Life(seconds, times_fired) +/mob/camera/blob/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/mob/camera/blob/process() if(!blob_core) qdel(src) - ..() /mob/camera/blob/Login() ..() diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index bdbd875a3dc..6f2eed39499 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -357,7 +357,7 @@ if(!surrounding_turfs.len) return - for(var/mob/living/simple_animal/hostile/blob/blobspore/BS in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/blob/blobspore/BS in GLOB.alive_mob_list) if(isturf(BS.loc) && get_dist(BS, T) <= 35) BS.LoseTarget() BS.Goto(pick(surrounding_turfs), BS.move_to_delay) diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index 4663fef8b97..34a2d67b58b 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -49,7 +49,7 @@ /obj/item/organ/internal/cyberimp/eyes/shield/ling/on_life() ..() var/obj/item/organ/internal/eyes/E = owner.get_int_organ(/obj/item/organ/internal/eyes) - if(owner.eye_blind || owner.eye_blurry || (owner.disabilities & BLIND) || (owner.disabilities & NEARSIGHTED) || (E.damage > 0)) + if(owner.eye_blind || owner.eye_blurry || (BLINDNESS in owner.mutations) || (NEARSIGHTED in owner.mutations) || (E.damage > 0)) owner.reagents.add_reagent("oculine", 1) /obj/item/organ/internal/cyberimp/eyes/shield/ling/prepare_eat() diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm index d403059b0c7..61882b85287 100644 --- a/code/game/gamemodes/changeling/powers/fakedeath.dm +++ b/code/game/gamemodes/changeling/powers/fakedeath.dm @@ -16,11 +16,8 @@ user.emote("deathgasp") user.timeofdeath = world.time user.status_flags |= FAKEDEATH //play dead - user.update_stat("fakedeath sting") + user.updatehealth("fakedeath sting") user.update_canmove() - user.med_hud_set_health() - user.handle_hud_icons_health() - user.med_hud_set_status() user.mind.changeling.regenerating = TRUE addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index d225ac6886a..ce62242ca0f 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -95,8 +95,8 @@ user.unEquip(user.head) user.unEquip(user.wear_suit) - user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1) - user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1) + user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, TRUE, TRUE) + user.equip_to_slot_if_possible(new helmet_type(user), slot_head, TRUE, TRUE) var/datum/changeling/changeling = user.mind.changeling changeling.chem_recharge_slowdown += recharge_slowdown diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 375a02251bc..6533547902f 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -23,7 +23,7 @@ if(!message) return - if((user.disabilities & MUTE) || user.mind.miming) //Under vow of silence/mute? + if((MUTE in user.mutations) || user.mind.miming) //Under vow of silence/mute? user.visible_message("[user] appears to whisper to themselves.","You begin to whisper to yourself.") //Make them do *something* abnormal. else user.whisper("O bidai nabora se[pick("'","`")]sma!") // Otherwise book club sayings. @@ -32,7 +32,7 @@ if(!user) return - if(!((user.disabilities & MUTE) || user.mind.miming)) // If they aren't mute/miming, commence the whisperting + if(!((MUTE in user.mutations) || user.mind.miming)) // If they aren't mute/miming, commence the whisperting user.whisper(message) var/my_message if(istype(user, /mob/living/simple_animal/slaughter/cult)) //Harbringers of the Slaughter diff --git a/code/game/gamemodes/devil/true_devil/inventory.dm b/code/game/gamemodes/devil/true_devil/inventory.dm index 437203e2e91..3f5446d88bc 100644 --- a/code/game/gamemodes/devil/true_devil/inventory.dm +++ b/code/game/gamemodes/devil/true_devil/inventory.dm @@ -5,7 +5,7 @@ return 1 return 0 -/mob/living/carbon/true_devil/update_inv_r_hand(var/update_icons=1) +/mob/living/carbon/true_devil/update_inv_r_hand() ..() if(r_hand) var/t_state = r_hand.item_state @@ -17,11 +17,10 @@ devil_overlays[DEVIL_R_HAND_LAYER] = I else devil_overlays[DEVIL_R_HAND_LAYER] = null - if(update_icons) - update_icons() + update_icons() -/mob/living/carbon/true_devil/update_inv_l_hand(var/update_icons=1) +/mob/living/carbon/true_devil/update_inv_l_hand() ..() if(l_hand) var/t_state = l_hand.item_state @@ -33,8 +32,7 @@ devil_overlays[DEVIL_L_HAND_LAYER] = I else devil_overlays[DEVIL_L_HAND_LAYER] = null - if(update_icons) - update_icons() + update_icons() /mob/living/carbon/true_devil/proc/remove_overlay(cache_index) if(devil_overlays[cache_index]) diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index fa797ac929b..f99a00567ae 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -590,8 +590,6 @@ GrantBorerActions() RemoveInfestActions() forceMove(get_turf(host)) - - reset_perspective(null) machine = null host.reset_perspective(null) diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index 126587a0c97..cc481a01d54 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -112,7 +112,7 @@ summoner.death() -/mob/living/simple_animal/hostile/guardian/handle_hud_icons_health() +/mob/living/simple_animal/hostile/guardian/update_health_hud() if(summoner) var/resulthealth if(iscarbon(summoner)) @@ -121,8 +121,6 @@ resulthealth = round((summoner.health / summoner.maxHealth) * 100) if(hud_used) hud_used.guardianhealthdisplay.maptext = "
[resulthealth]%
" - med_hud_set_health() - med_hud_set_status() /mob/living/simple_animal/hostile/guardian/adjustHealth(amount, updating_health = TRUE) //The spirit is invincible, but passes on damage to the summoner var/damage = amount * damage_transfer @@ -286,7 +284,7 @@ var/name_list = list("Aries", "Leo", "Sagittarius", "Taurus", "Virgo", "Capricorn", "Gemini", "Libra", "Aquarius", "Cancer", "Scorpio", "Pisces") /obj/item/guardiancreator/attack_self(mob/living/user) - for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.alive_mob_list) if(G.summoner == user) to_chat(user, "You already have a [mob_name]!") return diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 73ab05a00aa..e3ce78d582a 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -139,7 +139,7 @@ /obj/effect/proc_holder/spell/targeted/sense_victims/cast(list/targets, mob/user) var/list/victims = targets - for(var/mob/living/L in GLOB.living_mob_list) + for(var/mob/living/L in GLOB.alive_mob_list) if(!L.stat && !iscultist(L) && L.key && L != usr) victims.Add(L) if(!targets.len) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 00ce24b6c46..a38982905bc 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -336,7 +336,7 @@ if(head_revolutionaries.len || GAMEMODE_IS_REVOLUTION) var/num_revs = 0 var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.living_mob_list) + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) if(survivor.ckey) num_survivors++ if(survivor.mind) diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index c7c46d89c19..f6ba6504381 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -34,7 +34,7 @@ //message_admins("Assigning DNA blocks:") // Standard muts - GLOB.blindblock = getAssignedBlock("BLIND", numsToAssign) + GLOB.blindblock = getAssignedBlock("BLINDNESS", numsToAssign) GLOB.colourblindblock = getAssignedBlock("COLOURBLIND", numsToAssign) GLOB.deafblock = getAssignedBlock("DEAF", numsToAssign) GLOB.hulkblock = getAssignedBlock("HULK", numsToAssign, DNA_HARD_BOUNDS, good=1) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 37f7296bd4e..2cafb1bc219 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -375,7 +375,7 @@ to_chat(target, "You focus your telepathic energies abound, harnessing and drawing together the strength of your thralls.") - for(M in GLOB.living_mob_list) + for(M in GLOB.alive_mob_list) if(is_thrall(M)) thralls++ to_chat(M, "You feel hooks sink into your mind and pull.") @@ -413,7 +413,7 @@ else if(thralls >= victory_threshold) to_chat(target, "You are now powerful enough to ascend. Use the Ascendance ability when you are ready. This will kill all of your thralls.") to_chat(target, "You may find Ascendance in the Shadowling Evolution tab.") - for(M in GLOB.living_mob_list) + for(M in GLOB.alive_mob_list) if(is_shadow(M)) var/obj/effect/proc_holder/spell/targeted/collective_mind/CM if(CM in M.mind.spell_list) diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 032bab0b6e8..2c7cee9d61a 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -243,7 +243,7 @@ scramble(1, H, 100) H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species. H.sync_organ_dna(assimilate = 1) - H.update_body(0) + H.update_body() H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. H.reset_markings() //...Or markings. H.dna.ResetUIFrom(H) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index da7c6d4e1de..205fd63d9c6 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -809,7 +809,7 @@ GLOBAL_LIST_EMPTY(multiverse) return return ..() -/obj/item/voodoo/check_eye(mob/user as mob) +/obj/item/voodoo/check_eye(mob/user) if(loc != user) user.reset_perspective(null) user.unset_machine() @@ -866,7 +866,7 @@ GLOBAL_LIST_EMPTY(multiverse) possible = list() if(!link) return - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(md5(H.dna.uni_identity) in link.fingerprints) possible |= H diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index a7eb5d135e9..b76b31255e9 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -1011,7 +1011,7 @@ magichead.voicechange = 1 //NEEEEIIGHH if(!user.unEquip(user.wear_mask)) qdel(user.wear_mask) - user.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) + user.equip_to_slot_if_possible(magichead, slot_wear_mask, TRUE, TRUE) qdel(src) else to_chat(user, "I say thee neigh") diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 9d96ec94b99..1ee30b6e9d0 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -314,9 +314,9 @@ occupantData["intOrgan"] = intOrganData - occupantData["blind"] = (occupant.disabilities & BLIND) - occupantData["colourblind"] = (occupant.disabilities & COLOURBLIND) - occupantData["nearsighted"] = (occupant.disabilities & NEARSIGHTED) + occupantData["blind"] = (BLINDNESS in occupant.mutations) + occupantData["colourblind"] = (COLOURBLIND in occupant.mutations) + occupantData["nearsighted"] = (NEARSIGHTED in occupant.mutations) data["occupant"] = occupantData return data @@ -498,11 +498,11 @@ dat += "[i.name]N/A[i.damage][infection]:[mech][dead]" dat += "" dat += "" - if(occupant.disabilities & BLIND) + if(BLINDNESS in occupant.mutations) dat += "Cataracts detected.
" - if(occupant.disabilities & COLOURBLIND) + if(COLOURBLIND in occupant.mutations) dat += "Photoreceptor abnormalities detected.
" - if(occupant.disabilities & NEARSIGHTED) + if(NEARSIGHTED in occupant.mutations) dat += "Retinal misalignment detected.
" else dat += "[src] is empty." diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 1649397a68f..3f8fc080bf8 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -53,6 +53,9 @@ return TRUE /obj/machinery/computer/security/check_eye(mob/user) + if((stat & (NOPOWER|BROKEN)) || user.incapacitated() || !user.has_vision()) + user.unset_machine() + return if(!(user in watchers)) user.unset_machine() return @@ -65,8 +68,6 @@ return if(!can_access_camera(C, user)) user.unset_machine() - return - return 1 /obj/machinery/computer/security/on_unset_machine(mob/user) watchers.Remove(user) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 76242c4a0e4..bc1bfe6135b 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -37,17 +37,14 @@ eyeobj.RemoveImages() eyeobj.eye_user = null user.remote_control = null - user.remote_view = FALSE current_user = null user.unset_machine() playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) /obj/machinery/computer/camera_advanced/check_eye(mob/user) - if((stat & (NOPOWER|BROKEN)) || !Adjacent(user) || !user.has_vision() || user.incapacitated()) + if((stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || !user.has_vision() || user.incapacitated()) user.unset_machine() - return 0 - return 1 /obj/machinery/computer/camera_advanced/Destroy() if(current_user) @@ -99,8 +96,6 @@ current_user = user eyeobj.eye_user = user eyeobj.name = "Camera Eye ([user.name])" - // This should be able to be excised once the full view refactor rolls out - user.remote_view = 1 user.remote_control = eyeobj user.reset_perspective(eyeobj) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 756a22259f0..c7dc139446a 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -533,11 +533,17 @@ /datum/data/function/proc/display() return -/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user) +/obj/machinery/atmospherics/unary/cryo_cell/get_remote_view_fullscreens(mob/user) user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) -/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user) +/obj/machinery/atmospherics/unary/cryo_cell/update_remote_sight(mob/living/user) return //we don't see the pipe network while inside cryo. +/obj/machinery/atmospherics/unary/cryo_cell/can_crawl_through() + return // can't ventcrawl in or out of cryo. + +/obj/machinery/atmospherics/unary/cryo_cell/can_see_pipes() + return FALSE // you can't see the pipe network when inside a cryo cell. + #undef AUTO_EJECT_HEALTHY #undef AUTO_EJECT_DEAD diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index de077917adf..49b75588468 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -444,7 +444,7 @@ control_computer.frozen_crew += "[occupant.real_name]" var/ailist[] = list() - for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list) ailist += A if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index c0b1c44f806..cc9fc3e4666 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -317,7 +317,7 @@ scramble(1, H, 100) H.generate_name() H.sync_organ_dna(assimilate = 1) - H.update_body(0) + H.update_body() H.reset_hair() H.dna.ResetUIFrom(H) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 7efa81863b6..610436406d8 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1102,7 +1102,6 @@ occupant = H H.stop_pulling() H.forceMove(src) - H.reset_perspective(src) add_fingerprint(H) GrantActions(H, human_occupant = 1) forceMove(loc) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 1e7ad8397ee..b7eea1b367f 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(splatter_cache) user.blood_DNA |= blood_DNA.Copy() user.bloody_hands += taken user.hand_blood_color = basecolor - user.update_inv_gloves(1) + user.update_inv_gloves() user.verbs += /mob/living/carbon/human/proc/bloody_doodle /obj/effect/decal/cleanable/blood/can_bloodcrawl_in() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index 7acf6b61a6d..7724d499e7e 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -54,21 +54,21 @@ user.set_machine(src) interact(user) -/obj/item/camera_bug/check_eye(var/mob/user as mob) - if(user.stat || loc != user || !user.canmove || !user.has_vision() || !current) - user.reset_perspective(null) +/obj/item/camera_bug/check_eye(mob/user) + if(loc != user || user.incapacitated() || !user.has_vision() || !current) user.unset_machine() - return null - - var/turf/T = get_turf(user.loc) - if(T.z != current.z || !current.can_use()) + return FALSE + var/turf/T_user = get_turf(user.loc) + var/turf/T_current = get_turf(current) + if(!atoms_share_level(T_user, T_current) || !current.can_use()) to_chat(user, "[src] has lost the signal.") current = null - user.reset_perspective(null) user.unset_machine() - return null + return FALSE + return TRUE - return 1 +/obj/item/camera_bug/on_unset_machine(mob/user) + user.reset_perspective(null) /obj/item/camera_bug/proc/get_cameras() if(world.time > (last_net_update + 100)) @@ -182,7 +182,6 @@ /obj/item/camera_bug/Topic(var/href,var/list/href_list) if(usr != loc) usr.unset_machine() - usr.reset_perspective(null) usr << browse(null, "window=camerabug") return usr.set_machine(src) @@ -233,7 +232,6 @@ interact() else usr.unset_machine() - usr.reset_perspective(null) usr << browse(null, "window=camerabug") return else diff --git a/code/game/objects/items/devices/enginepicker.dm b/code/game/objects/items/devices/enginepicker.dm index a2fa30a243b..0fd3a591560 100644 --- a/code/game/objects/items/devices/enginepicker.dm +++ b/code/game/objects/items/devices/enginepicker.dm @@ -76,7 +76,7 @@ new G(T) //Spawns the switch-selected engine on the chosen beacon's turf var/ailist[] = list() - for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list) ailist += A if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 4ce64a859ec..307964ca25c 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -74,7 +74,7 @@ if(istype(H)) //robots and aliens are unaffected var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) - if(M.stat == DEAD || !eyes || M.disabilities & BLIND) //mob is dead or fully blind + if(M.stat == DEAD || !eyes || (BLINDNESS in M.mutations)) //mob is dead or fully blind to_chat(user, "[M]'s pupils are unresponsive to the light!") else if((XRAY in M.mutations) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms). to_chat(user, "[M]'s pupils glow eerily!") diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 6d0f6d1dfe1..0d8873a6377 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -859,11 +859,11 @@ REAGENT SCANNER dat += "[i.name]N/A[i.damage][infection]:[mech]" dat += "" dat += "" - if(target.disabilities & BLIND) + if(BLINDNESS in target.mutations) dat += "Cataracts detected.
" - if(target.disabilities & COLOURBLIND) + if(COLOURBLIND in target.mutations) dat += "Photoreceptor abnormalities detected.
" - if(target.disabilities & NEARSIGHTED) + if(NEARSIGHTED in target.mutations) dat += "Retinal misalignment detected.
" return dat diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index a13bce6fb61..43178a85ef8 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -74,7 +74,7 @@ R.stat = CONSCIOUS GLOB.dead_mob_list -= R //please never forget this ever kthx - GLOB.living_mob_list += R + GLOB.alive_mob_list += R R.notify_ai(1) return 1 diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 24c904bc9d3..98a7b769642 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -360,7 +360,7 @@ LIGHTERS ARE IN LIGHTERS.DM lit = FALSE icon_state = icon_off item_state = icon_off - M.update_inv_wear_mask(0) + M.update_inv_wear_mask() STOP_PROCESSING(SSobj, src) return smoke() diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm index c2dc8e285ab..1dcc4a942c2 100644 --- a/code/game/objects/items/weapons/dnascrambler.dm +++ b/code/game/objects/items/weapons/dnascrambler.dm @@ -45,7 +45,7 @@ scramble(1, H, 100) H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species. H.sync_organ_dna(assimilate = 1) - H.update_body(0) + H.update_body() H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. H.reset_markings() //...Or markings. H.dna.ResetUIFrom(H) diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 5a3286bfc05..48edcc826e6 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -49,8 +49,7 @@ to_chat(user, "You cut open the present.") for(var/mob/M in src) //Should only be one but whatever. - M.loc = src.loc - M.reset_perspective(null) + M.forceMove(loc) qdel(src) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index c3f2e50174b..006de63af17 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -37,7 +37,7 @@ return BRUTELOSS|FIRELOSS /obj/item/melee/energy/attack_self(mob/living/carbon/user) - if(user.disabilities & CLUMSY && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) to_chat(user, "You accidentally cut yourself with [src], like a doofus!") user.take_organ_damage(5,5) active = !active @@ -290,7 +290,7 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.disabilities & CLUMSY && prob(50)) + if((CLUMSY in H.mutations) && prob(50)) to_chat(H, "You accidentally cut yourself with [src], like a doofus!") H.take_organ_damage(10,10) active = !active diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 362ab601685..19e56e161e3 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -76,7 +76,7 @@ return (active) /obj/item/shield/energy/attack_self(mob/living/carbon/human/user) - if(user.disabilities & CLUMSY && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) to_chat(user, "You beat yourself in the head with [src].") user.take_organ_damage(5) active = !active diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 501abd4922d..e285c6a0ae9 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -19,7 +19,7 @@ L.buckled = 0 L.anchored = 0 L.forceMove(src) - L.disabilities += MUTE + L.mutations |= MUTE max_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues intialTox = L.getToxLoss() intialFire = L.getFireLoss() @@ -69,7 +69,7 @@ for(var/mob/living/M in src) M.forceMove(loc) - M.disabilities -= MUTE + M.mutations -= MUTE M.take_overall_damage((M.health - obj_integrity - 100),0) //any new damage the statue incurred is transfered to the mob ..() diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 7095fd4eeda..8984dc60a52 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -144,9 +144,7 @@ if(istype(mob, /mob) && mob.client) // If the pod is not in a tube at all, you can get out at any time. if(!(locate(/obj/structure/transit_tube) in loc)) - mob.loc = loc - mob.client.Move(get_step(loc, direction), direction) - mob.reset_perspective(null) + mob.forceMove(loc) //if(moving && istype(loc, /turf/space)) // Todo: If you get out of a moving pod in space, you should move as well. @@ -158,9 +156,7 @@ if(!station.pod_moving) if(direction == station.dir) if(station.icon_state == "open") - mob.loc = loc - mob.client.Move(get_step(loc, direction), direction) - mob.reset_perspective(null) + mob.forceMove(loc) else station.open_animation() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index a529dc3a6e7..87107f97abe 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -411,7 +411,7 @@ M.l_hand.clean_blood() if(M.back) if(M.back.clean_blood()) - M.update_inv_back(0) + M.update_inv_back() if(ishuman(M)) var/mob/living/carbon/human/H = M var/washgloves = 1 @@ -437,38 +437,38 @@ if(H.head) if(H.head.clean_blood()) - H.update_inv_head(0,0) + H.update_inv_head() if(H.wear_suit) if(H.wear_suit.clean_blood()) - H.update_inv_wear_suit(0,0) + H.update_inv_wear_suit() else if(H.w_uniform) if(H.w_uniform.clean_blood()) - H.update_inv_w_uniform(0,0) + H.update_inv_w_uniform() if(H.gloves && washgloves) if(H.gloves.clean_blood()) - H.update_inv_gloves(0,0) + H.update_inv_gloves() if(H.shoes && washshoes) if(H.shoes.clean_blood()) - H.update_inv_shoes(0,0) + H.update_inv_shoes() if(H.wear_mask && washmask) if(H.wear_mask.clean_blood()) - H.update_inv_wear_mask(0) + H.update_inv_wear_mask() if(H.glasses && washglasses) if(H.glasses.clean_blood()) - H.update_inv_glasses(0) + H.update_inv_glasses() if(H.l_ear && washears) if(H.l_ear.clean_blood()) - H.update_inv_ears(0) + H.update_inv_ears() if(H.r_ear && washears) if(H.r_ear.clean_blood()) - H.update_inv_ears(0) + H.update_inv_ears() if(H.belt) if(H.belt.clean_blood()) - H.update_inv_belt(0) + H.update_inv_belt() else if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags if(M.wear_mask.clean_blood()) - M.update_inv_wear_mask(0) + M.update_inv_wear_mask() else O.clean_blood() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7826a005e7d..1a040d46e90 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1980,7 +1980,7 @@ to_chat(usr, "ERROR: This mob ([H]) has no mind!") return var/list/possible_traitors = list() - for(var/mob/living/player in GLOB.living_mob_list) + for(var/mob/living/player in GLOB.alive_mob_list) if(player.client && player.mind && player.stat != DEAD && player != H) if(ishuman(player) && !player.mind.special_role) if(player.client && (ROLE_TRAITOR in player.client.prefs.be_special) && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, "Syndicate")) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 32dcf3daa7b..c92e100b641 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -716,23 +716,25 @@ GLOBAL_PROTECT(AdminProcCaller) if(!check_rights(R_DEBUG)) return - switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Silicons","Clients","Respawnable Mobs")) + switch(input("Which list?") in list("Players", "Admins", "Mobs", "Living Mobs", "Alive Mobs", "Dead Mobs", "Silicons", "Clients", "Respawnable Mobs")) if("Players") - to_chat(usr, jointext(GLOB.player_list,",")) + to_chat(usr, jointext(GLOB.player_list, ",")) if("Admins") - to_chat(usr, jointext(GLOB.admins,",")) + to_chat(usr, jointext(GLOB.admins, ",")) if("Mobs") - to_chat(usr, jointext(GLOB.mob_list,",")) + to_chat(usr, jointext(GLOB.mob_list, ",")) if("Living Mobs") - to_chat(usr, jointext(GLOB.living_mob_list,",")) + to_chat(usr, jointext(GLOB.mob_living_list, ",")) + if("Alive Mobs") + to_chat(usr, jointext(GLOB.alive_mob_list, ",")) if("Dead Mobs") - to_chat(usr, jointext(GLOB.dead_mob_list,",")) + to_chat(usr, jointext(GLOB.dead_mob_list, ",")) if("Silicons") - to_chat(usr, jointext(GLOB.silicon_mob_list,",")) + to_chat(usr, jointext(GLOB.silicon_mob_list, ",")) if("Clients") - to_chat(usr, jointext(GLOB.clients,",")) + to_chat(usr, jointext(GLOB.clients, ",")) if("Respawnable Mobs") - to_chat(usr, jointext(GLOB.respawnable_list,",")) + to_chat(usr, jointext(GLOB.respawnable_list, ",")) /client/proc/cmd_display_del_log() set category = "Debug" diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 13a258e4212..a7763f31fb1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -979,7 +979,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/role_string var/obj_count = 0 var/obj_string = "" - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(!isLivingSSD(H)) continue mins_ssd = round((world.time - H.last_logout) / 600) @@ -1016,7 +1016,7 @@ Traitors and the like can also be revived with the previous role mostly intact. msg += "AFK Players:
" msg += "" var/mins_afk - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(H.client == null || H.stat == DEAD) // No clientless or dead continue mins_afk = round(H.client.inactivity / 600) diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index ca79a1ea2a6..5aa3e89192f 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -173,23 +173,9 @@ to_chat(C, "Death is not your end!") spawn(rand(800,1200)) - if(C.stat == DEAD) - GLOB.dead_mob_list -= C - GLOB.living_mob_list += C - C.stat = CONSCIOUS - C.timeofdeath = 0 - C.setToxLoss(0) - C.setOxyLoss(0) - C.setCloneLoss(0) - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.radiation = 0 - C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss()) - C.reagents.clear_reagents() + C.revive() to_chat(C, "You have regenerated.") C.visible_message("[usr] appears to wake from the dead, having healed all wounds.") - C.update_canmove() return 1 /obj/item/wildwest_communicator @@ -247,7 +233,7 @@ used = TRUE /obj/item/wildwest_communicator/proc/stand_down() - for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in GLOB.alive_mob_list) W.on_alert = FALSE /mob/living/simple_animal/hostile/syndicate/ranged/wildwest @@ -262,6 +248,6 @@ // putting this up here so we don't say anything after deathgasp if(can_die() && !on_alert) say("How could you betray the Syndicate?") - for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in GLOB.alive_mob_list) W.on_alert = TRUE return ..(gibbed) diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index a063fafd736..3cd6458afdf 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -20,7 +20,6 @@ var/skip_antag = FALSE //TRUE when a player declines to be included for the selection process of game mode antagonists. var/move_delay = 1 var/moving = null - var/adminobs = null var/area = null var/time_died_as_mouse = null //when the client last died as a mouse diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 1b9c87f56e5..011bc60cdc4 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -376,7 +376,6 @@ desc = "Covers the eyes, preventing sight." icon_state = "blindfold" item_state = "blindfold" - //vision_flags = BLIND flash_protect = 2 tint = 3 //to make them blind prescription_upgradable = 0 @@ -412,7 +411,7 @@ if(M.glasses == src) M.EyeBlind(3) M.EyeBlurry(5) - if(!(M.disabilities & NEARSIGHTED)) + if(!(NEARSIGHTED in M.mutations)) M.BecomeNearsighted() spawn(100) M.CureNearsighted() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 3608ee85164..cd4ac697406 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -798,7 +798,7 @@ to_chat(wearer, "You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.") return use_obj.forceMove(wearer) - if(!wearer.equip_to_slot_if_possible(use_obj, equip_to, 0, 1)) + if(!wearer.equip_to_slot_if_possible(use_obj, equip_to, FALSE, TRUE)) use_obj.forceMove(src) else if(wearer) diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index 83f0fcfc211..be05ced4fd8 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -59,7 +59,7 @@ if(H.head) to_chat(H,"You're already wearing something on your head!") return - else if(H.equip_to_slot_if_possible(hood, slot_head, 0, 0, 1)) + else if(H.equip_to_slot_if_possible(hood, slot_head, FALSE, FALSE)) suit_adjusted = 1 icon_state = "[initial(icon_state)]_hood" H.update_inv_wear_suit() diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index c329d8a0033..7e1a993fca4 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -68,7 +68,7 @@ if(H.head) to_chat(H, "You're already wearing something on your head!") return - else if(H.equip_to_slot_if_possible(helmet, slot_head, 0 ,0, 1)) + else if(H.equip_to_slot_if_possible(helmet, slot_head, FALSE, FALSE)) to_chat(H, "You engage the helmet on the hardsuit.") suittoggled = TRUE H.update_inv_wear_suit() diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 6e2dc876603..1bc00c93025 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -20,7 +20,7 @@ GLOB.event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') /datum/event/disease_outbreak/start() - for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) if(!H.client) continue if(issmall(H)) //don't infect monkies; that's a waste diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 021004c6ee9..90718ef2928 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -22,7 +22,7 @@ /datum/event/ion_storm/start() //AI laws - for(var/mob/living/silicon/ai/M in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/M in GLOB.alive_mob_list) if(M.stat != DEAD && M.see_in_dark != FALSE) var/message = generate_ion_law(ionMessage) if(message) diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index 6aceefcd41a..196642ce39c 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -2,7 +2,7 @@ announceWhen = rand(0, 20) /datum/event/mass_hallucination/start() - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) var/armor = H.getarmor(type = "rad") if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected continue diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 4dfe181bdb5..918746f4595 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -8,7 +8,7 @@ var/list/potential = list() var/sentience_type = SENTIENCE_ORGANIC - for(var/mob/living/simple_animal/L in GLOB.living_mob_list) + for(var/mob/living/simple_animal/L in GLOB.alive_mob_list) var/turf/T = get_turf(L) if (T.z != 1) continue diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index fb9c146d7cd..53923f4d124 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -1,5 +1,5 @@ /datum/event/spontaneous_appendicitis/start() - for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) if(issmall(H)) //don't infect monkies; that's a waste. continue if(!H.client) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 32e209f98f6..51ac13d4e13 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -460,7 +460,7 @@ Gunshots/explosions/opening doors/less rare audio (done) target = T var/image/A = null var/kind = force_kind ? force_kind : pick("clown", "corgi", "carp", "skeleton", "demon","zombie") - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(H == target) continue if(skip_nearby && (H in view(target))) @@ -539,7 +539,7 @@ Gunshots/explosions/opening doors/less rare audio (done) var/mob/living/carbon/human/clone = null var/clone_weapon = null - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(H.stat || H.lying) continue clone = H @@ -751,7 +751,7 @@ GLOBAL_LIST_INIT(non_fakeattack_weapons, list(/obj/item/gun/projectile, /obj/ite target.client.images.Remove(speech_overlay) else // Radio talk var/list/humans = list() - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) humans += H person = pick(humans) target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ") diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 64e7cba86cd..478438c47cb 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -227,7 +227,7 @@ /obj/item/twohanded/bostaff/attack(mob/target, mob/living/user) add_fingerprint(user) - if((CLUMSY in user.disabilities) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) to_chat(user, "You club yourself over the head with [src].") user.Weaken(3) if(ishuman(user)) diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index ac4d6a1e551..0bde4d95464 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -306,7 +306,7 @@ if(H.stat == DEAD) H.set_species(/datum/species/shadow) H.revive() - H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal + H.mutations |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal H.grab_ghost(force = TRUE) /obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans @@ -458,7 +458,7 @@ if(isliving(A) && holder_animal) var/mob/living/L = A L.notransform = 1 - L.disabilities |= MUTE + L.mutations |= MUTE L.status_flags |= GODMODE L.mind.transfer_to(holder_animal) var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession @@ -468,7 +468,7 @@ /obj/structure/closet/stasis/dump_contents(var/kill = 1) STOP_PROCESSING(SSobj, src) for(var/mob/living/L in src) - L.disabilities &= ~MUTE + L.mutations -=MUTE L.status_flags &= ~GODMODE L.notransform = 0 if(holder_animal && !QDELETED(holder_animal)) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 91a57e1ccbe..dc7c2b4439e 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -91,10 +91,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) ..() /mob/dead/observer/Destroy() - if(ismob(following)) - var/mob/M = following - M.following_mobs -= src - following = null if(ghostimage) GLOB.ghost_images -= ghostimage QDEL_NULL(ghostimage) @@ -142,13 +138,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) Transfer_mind is there to check if mob is being deleted/not going to have a body. Works together with spawning an observer, noted above. */ -/mob/dead/observer/Life(seconds, times_fired) - ..() - if(!loc) return - if(!client) return 0 - - - /mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U) var/client/C = U.client for(var/mob/living/carbon/human/target in target_list) @@ -477,28 +466,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp setDir(2)//reset dir so the right directional sprites show up return ..() -/mob/proc/update_following() - . = get_turf(src) - for(var/mob/dead/observer/M in following_mobs) - if(M.following != src) - following_mobs -= M - else - if(M.loc != .) - M.forceMove(.) - -/mob - var/list/following_mobs = list() - -/mob/Move() - . = ..() - if(.) - update_following() - -/mob/Life(seconds, times_fired) - // to catch teleports etc which directly set loc - update_following() - return ..() - /mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" set name = "Jump to Mob" diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index ee9a3c3cca2..f89d19afaac 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -22,7 +22,6 @@ var/atom/movable/mob_container mob_container = M mob_container.forceMove(get_turf(src)) - M.reset_perspective() qdel(src) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 6d96d77c321..8f4f4dbb2da 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -214,9 +214,9 @@ if(M.equip_to_appropriate_slot(src)) if(M.hand) - M.update_inv_l_hand(0) + M.update_inv_l_hand() else - M.update_inv_r_hand(0) + M.update_inv_r_hand() return 1 if(M.s_active && M.s_active.can_be_inserted(src, 1)) //if storage active insert there diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 8445dec51ee..7f3a7049558 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -619,7 +619,7 @@ var/message_start_dead = "[name], [speaker.name] ([ghost_follow_link(speaker, ghost=M)])" M.show_message("[message_start_dead] [message_body]", 2) - for(var/mob/living/S in GLOB.living_mob_list) + for(var/mob/living/S in GLOB.alive_mob_list) if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) continue else if(isAI(S)) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 1b85c3e5386..247e0bcbab2 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -26,6 +26,8 @@ var/death_sound = 'sound/voice/hiss6.ogg' /mob/living/carbon/alien/New() + ..() + create_reagents(1000) verbs += /mob/living/verb/mob_sleep verbs += /mob/living/verb/lay_down alien_organs += new /obj/item/organ/internal/brain/xeno @@ -33,7 +35,6 @@ alien_organs += new /obj/item/organ/internal/ears for(var/obj/item/organ/internal/I in alien_organs) I.insert(src) - ..() /mob/living/carbon/alien/get_default_language() if(default_language) @@ -67,18 +68,6 @@ /mob/living/carbon/alien/check_eye_prot() return 2 -/mob/living/carbon/alien/updatehealth(reason = "none given") - if(status_flags & GODMODE) - health = maxHealth - stat = CONSCIOUS - return - health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - - update_stat("updatehealth([reason])") - med_hud_set_health() - med_hud_set_status() - handle_hud_icons_health() - /mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment) if(!environment) @@ -118,12 +107,6 @@ else clear_alert("alien_fire") -/mob/living/carbon/alien/handle_fire()//Aliens on fire code - if(..()) - return - bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up! - return - /mob/living/carbon/alien/IsAdvancedToolUser() return has_fine_manipulation diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index 2d894ee357e..99900183185 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -6,7 +6,6 @@ icon_state = "aliend_s" /mob/living/carbon/alien/humanoid/drone/New() - create_reagents(100) if(src.name == "alien drone") src.name = text("alien drone ([rand(1, 1000)])") src.real_name = src.name @@ -26,7 +25,7 @@ if(powerc(500)) // Queen check var/no_queen = 1 - for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list) + for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list) if(!Q.key && Q.get_int_organ(/obj/item/organ/internal/brain/)) continue no_queen = 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 73931aa7be9..f23f9b7aa42 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -6,7 +6,6 @@ icon_state = "alienh_s" /mob/living/carbon/alien/humanoid/hunter/New() - create_reagents(100) if(name == "alien hunter") name = text("alien hunter ([rand(1, 1000)])") real_name = name @@ -17,28 +16,6 @@ . = -1 //hunters are sanic . += ..() //but they still need to slow down on stun -/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health() - ..() //-Yvarov - - if(healths) - if(stat != 2) - switch(health) - if(125 to INFINITY) - healths.icon_state = "health0" - if(100 to 125) - healths.icon_state = "health1" - if(50 to 100) - healths.icon_state = "health2" - if(25 to 50) - healths.icon_state = "health3" - if(0 to 25) - healths.icon_state = "health4" - else - healths.icon_state = "health5" - else - healths.icon_state = "health6" - - /mob/living/carbon/alien/humanoid/hunter/handle_environment() if(m_intent == MOVE_INTENT_RUN || resting) ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index c436a43e4ff..4dd2d1b8569 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -33,7 +33,6 @@ overlays += I /mob/living/carbon/alien/humanoid/sentinel/New() - create_reagents(100) if(name == "alien sentinel") name = text("alien sentinel ([rand(1, 1000)])") real_name = name @@ -42,27 +41,6 @@ alien_organs += new /obj/item/organ/internal/xenos/neurotoxin ..() -/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health() - ..() //-Yvarov - - if(healths) - if(stat != 2) - switch(health) - if(150 to INFINITY) - healths.icon_state = "health0" - if(100 to 150) - healths.icon_state = "health1" - if(75 to 100) - healths.icon_state = "health2" - if(25 to 75) - healths.icon_state = "health3" - if(0 to 25) - healths.icon_state = "health4" - else - healths.icon_state = "health5" - else - healths.icon_state = "health6" - /* /mob/living/carbon/alien/humanoid/sentinel/verb/evolve() // -- TLE set name = "Evolve (250)" diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm index a64602d030c..63514686f3d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm @@ -30,17 +30,17 @@ overlays += I /mob/living/carbon/alien/humanoid/empress/New() - create_reagents(100) - //there should only be one queen - for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.living_mob_list) - if(E == src) continue - if(E.stat == DEAD) continue + for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.alive_mob_list) + if(E == src) + continue + if(E.stat == DEAD) + continue if(E.client) name = "alien grand princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. break - real_name = src.name + real_name = name alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/queen alien_organs += new /obj/item/organ/internal/xenos/acidgland alien_organs += new /obj/item/organ/internal/xenos/eggsac @@ -48,27 +48,6 @@ alien_organs += new /obj/item/organ/internal/xenos/neurotoxin ..() -/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health() - ..() //-Yvarov - - if(healths) - if(stat != 2) - switch(health) - if(250 to INFINITY) - healths.icon_state = "health0" - if(175 to 250) - healths.icon_state = "health1" - if(100 to 175) - healths.icon_state = "health2" - if(50 to 100) - healths.icon_state = "health3" - if(0 to 50) - healths.icon_state = "health4" - else - healths.icon_state = "health5" - else - healths.icon_state = "health6" - /mob/living/carbon/alien/humanoid/empress/verb/lay_egg() set name = "Lay Egg (250)" set desc = "Lay an egg to produce huggers to impregnate prey with." diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 63f6d3dcea9..e82488ee064 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -17,7 +17,6 @@ //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/humanoid/New() - create_reagents(1000) if(name == "alien") name = text("alien ([rand(1, 1000)])") real_name = name diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index 646f069970b..071987f808e 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -2,27 +2,6 @@ . = ..() update_icons() - - -/mob/living/carbon/alien/humanoid/handle_disabilities() - if(disabilities & EPILEPSY) - if((prob(1) && paralysis < 10)) - to_chat(src, "You have a seizure!") - Paralyse(10) - if(disabilities & COUGHING) - if((prob(5) && paralysis <= 1)) - drop_item() - emote("cough") - return - if(disabilities & TOURETTES) - if((prob(10) && paralysis <= 1)) - Stun(10) - emote("twitch") - return - if(disabilities & NERVOUS) - if(prob(10)) - stuttering = max(10, stuttering) - /mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost) var/temperature = current var/difference = abs(current-loc_temp) //get difference @@ -39,51 +18,3 @@ temperature = max(loc_temp, temperature-change) temp_change = (temperature - current) return temp_change - -/mob/living/carbon/alien/humanoid/handle_regular_status_updates() - updatehealth() - - if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP - SetSilence(0) - else //ALIVE. LIGHTS ARE ON - if(health < HEALTH_THRESHOLD_DEAD && check_death_method() || !get_int_organ(/obj/item/organ/internal/brain)) - death() - SetSilence(0) - return 1 - - //UNCONSCIOUS. NO-ONE IS HOME - if((getOxyLoss() > 50) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method())) - if(health <= 20 && prob(1)) - emote("gasp") - if(!reagents.has_reagent("epinephrine")) - adjustOxyLoss(1) - Paralyse(3) - - if(paralysis) - stat = UNCONSCIOUS - else if(sleeping) - stat = UNCONSCIOUS - if(prob(10) && health) - emote("hiss") - //CONSCIOUS - else - stat = CONSCIOUS - - /* What in the living hell is this?*/ - if(move_delay_add > 0) - move_delay_add = max(0, move_delay_add - rand(1, 2)) - - if(eye_blind) //blindness, heals slowly over time - AdjustEyeBlind(-1) - else if(eye_blurry) //blurry eyes heal slowly - AdjustEyeBlurry(-1) - - if(stuttering) - AdjustStuttering(-1) - - if(silent) - AdjustSilence(-1) - - if(druggy) - AdjustDruggy(-1) - return 1 diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 9390885c558..3adb87ad505 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -11,12 +11,12 @@ pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper. /mob/living/carbon/alien/humanoid/queen/New() - create_reagents(100) - //there should only be one queen - for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list) - if(Q == src) continue - if(Q.stat == DEAD) continue + for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list) + if(Q == src) + continue + if(Q.stat == DEAD) + continue if(Q.client) name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. break @@ -33,27 +33,6 @@ . = ..() . += 3 -/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health() - ..() //-Yvarov - - if(healths) - if(stat != DEAD) - switch(health) - if(250 to INFINITY) - healths.icon_state = "health0" - if(175 to 250) - healths.icon_state = "health1" - if(100 to 175) - healths.icon_state = "health2" - if(50 to 100) - healths.icon_state = "health3" - if(0 to 50) - healths.icon_state = "health4" - else - healths.icon_state = "health5" - else - healths.icon_state = "health6" - /mob/living/carbon/alien/humanoid/queen/can_inject(mob/user, error_msg, target_zone, penetrate_thick) return FALSE diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 4776f32596a..94c65095f01 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -56,13 +56,14 @@ /mob/living/carbon/alien/humanoid/regenerate_icons() ..() - if(notransform) return + if(notransform) + return - update_inv_head(0,0) - update_inv_wear_suit(0,0) - update_inv_r_hand(0) - update_inv_l_hand(0) - update_inv_pockets(0) + update_inv_head() + update_inv_wear_suit() + update_inv_r_hand() + update_inv_l_hand() + update_inv_pockets() update_icons() update_fire() update_transform() @@ -82,7 +83,7 @@ else overlays_standing[X_FIRE_LAYER] = null -/mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1) +/mob/living/carbon/alien/humanoid/update_inv_wear_suit() if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit] inv.update_icon() @@ -110,10 +111,10 @@ overlays_standing[X_SUIT_LAYER] = standing else overlays_standing[X_SUIT_LAYER] = null - if(update_icons) update_icons() + update_icons() -/mob/living/carbon/alien/humanoid/update_inv_head(var/update_icons=1) +/mob/living/carbon/alien/humanoid/update_inv_head() if(head) var/t_state = head.item_state if(!t_state) t_state = head.icon_state @@ -124,17 +125,19 @@ overlays_standing[X_HEAD_LAYER] = standing else overlays_standing[X_HEAD_LAYER] = null - if(update_icons) update_icons() + update_icons() -/mob/living/carbon/alien/humanoid/update_inv_pockets(var/update_icons=1) - if(l_store) l_store.screen_loc = ui_storage1 - if(r_store) r_store.screen_loc = ui_storage2 - if(update_icons) update_icons() +/mob/living/carbon/alien/humanoid/update_inv_pockets() + if(l_store) + l_store.screen_loc = ui_storage1 + if(r_store) + r_store.screen_loc = ui_storage2 + update_icons() -/mob/living/carbon/alien/humanoid/update_inv_r_hand(var/update_icons=1) - ..(1) +/mob/living/carbon/alien/humanoid/update_inv_r_hand() + ..() if(r_hand) var/t_state = r_hand.item_state if(!t_state) t_state = r_hand.icon_state @@ -142,10 +145,10 @@ overlays_standing[X_R_HAND_LAYER] = image("icon" = r_hand.righthand_file, "icon_state" = t_state) else overlays_standing[X_R_HAND_LAYER] = null - if(update_icons) update_icons() + update_icons() -/mob/living/carbon/alien/humanoid/update_inv_l_hand(var/update_icons=1) - ..(1) +/mob/living/carbon/alien/humanoid/update_inv_l_hand() + ..() if(l_hand) var/t_state = l_hand.item_state if(!t_state) t_state = l_hand.icon_state @@ -153,7 +156,7 @@ overlays_standing[X_L_HAND_LAYER] = image("icon" = l_hand.lefthand_file, "icon_state" = t_state) else overlays_standing[X_L_HAND_LAYER] = null - if(update_icons) update_icons() + update_icons() //Xeno Overlays Indexes////////// diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index a55126ec045..aeee677b905 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -5,8 +5,8 @@ pass_flags = PASSTABLE | PASSMOB mob_size = MOB_SIZE_SMALL - maxHealth = 30 - health = 30 + maxHealth = 25 + health = 25 density = 0 var/amount_grown = 0 @@ -17,7 +17,6 @@ //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/larva/New() - create_reagents(100) if(name == "alien larva") name = "alien larva ([rand(1, 1000)])" real_name = name @@ -25,7 +24,6 @@ add_language("Xenomorph") add_language("Hivemind") alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/larva - ..() //This needs to be fixed diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index fd1543673e6..496a12cbf82 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -1,57 +1,28 @@ /mob/living/carbon/alien/larva/Life(seconds, times_fired) - if(..()) //still breathing + set invisibility = 0 + if(notransform) + return + if(..()) //not dead and not in stasis // GROW! if(amount_grown < max_grown) amount_grown++ + update_icons() - //some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder - update_icons() - -/mob/living/carbon/alien/larva/handle_regular_status_updates() - updatehealth() - - if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP - SetSilence(0) - else //ALIVE. LIGHTS ARE ON - if(health < -25 || !get_int_organ(/obj/item/organ/internal/brain)) +/mob/living/carbon/alien/larva/update_stat(reason = "None given") + if(status_flags & GODMODE) + return + if(stat != DEAD) + if(health <= -maxHealth || !get_int_organ(/obj/item/organ/internal/brain)) death() - SetSilence(0) - return 1 + return - //UNCONSCIOUS. NO-ONE IS HOME - if((getOxyLoss() > 25) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method())) - //if( health <= 20 && prob(1) ) - // spawn(0) - // emote("gasp") - if(!reagents.has_reagent("epinephrine")) - adjustOxyLoss(1) - Paralyse(3) - - if(paralysis) - stat = UNCONSCIOUS - else if(sleeping) - stat = UNCONSCIOUS - if(prob(10) && health) - emote("hiss_") - //CONSCIOUS + if(paralysis || sleeping || getOxyLoss() > 50 || (HEALTH_THRESHOLD_CRIT <= health && check_death_method())) + if(stat == CONSCIOUS) + KnockOut() + create_debug_log("fell unconscious, trigger reason: [reason]") else - stat = CONSCIOUS - - /* What in the living hell is this?*/ - if(move_delay_add > 0) - move_delay_add = max(0, move_delay_add - rand(1, 2)) - - if(eye_blind) //blindness, heals slowly over time - AdjustEyeBlind(-1) - else if(eye_blurry) //blurry eyes heal slowly - AdjustEyeBlurry(-1) - - if(stuttering) - AdjustStuttering(-1) - - if(silent) - AdjustSilence(-1) - - if(druggy) - AdjustDruggy(-1) - return 1 + if(stat == UNCONSCIOUS) + WakeUp() + create_debug_log("woke up, trigger reason: [reason]") + update_damage_hud() + update_health_hud() diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index a584f66dc97..5a1d08a010a 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -28,3 +28,15 @@ //BREATH TEMPERATURE handle_breath_temperature(breath) + +/mob/living/carbon/alien/handle_status_effects() + ..() + //natural reduction of movement delay due to stun. + if(move_delay_add > 0) + move_delay_add = max(0, move_delay_add - rand(1, 2)) + +/mob/living/carbon/alien/handle_fire()//Aliens on fire code + . = ..() + if(.) //if the mob isn't on fire anymore + return + adjust_bodytemperature(BODYTEMP_HEATING_MAX) //If you're on fire, you heat up! diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 5b80f6d032f..1dcd76c0358 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -146,7 +146,7 @@ "[src] tears [W] off of [target]'s face!") src.loc = target - target.equip_to_slot(src, slot_wear_mask,,0) + target.equip_to_slot_if_possible(src, slot_wear_mask, FALSE, TRUE) if(!sterile) M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 130a2e3a574..16014e7c353 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -49,7 +49,7 @@ brainmob.stat = CONSCIOUS GLOB.respawnable_list -= brainmob GLOB.dead_mob_list -= brainmob//Update dem lists - GLOB.living_mob_list += brainmob + GLOB.alive_mob_list += brainmob held_brain = B if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff @@ -157,7 +157,7 @@ brainmob.container = null//Reset brainmob mmi var. brainmob.forceMove(held_brain) //Throw mob into brain. GLOB.respawnable_list += brainmob - GLOB.living_mob_list -= brainmob//Get outta here + GLOB.alive_mob_list -= brainmob//Get outta here held_brain.brainmob = brainmob//Set the brain to use the brainmob held_brain.brainmob.cancel_camera() brainmob = null//Set mmi brainmob var to null diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index ec80d6a44b4..386d5ae138f 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -7,9 +7,8 @@ icon_state = "brain1" /mob/living/carbon/brain/New() - create_reagents(330) - add_language("Galactic Common") ..() + add_language("Galactic Common") /mob/living/carbon/brain/Destroy() if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 10e57b5a893..93f31d0128c 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -70,7 +70,7 @@ if(istype(owner,/mob/living/carbon/human)) var/mob/living/carbon/human/H = owner - H.update_hair(1) + H.update_hair() . = ..() /obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0) @@ -82,7 +82,7 @@ brain_already_exists = 1 var/mob/living/carbon/human/H = target - H.update_hair(1) + H.update_hair() if(!brain_already_exists) if(brainmob) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 6bd88e5e111..0faa238190e 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -28,13 +28,11 @@ var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0) adjustFireLoss(5.0*discomfort) -/mob/living/carbon/brain/handle_regular_status_updates() +/mob/living/carbon/brain/Life() . = ..() - if(.) - if(!container && (health < HEALTH_THRESHOLD_DEAD && check_death_method() || ((world.time - timeofhostdeath) > config.revival_brain_life))) + if(!container && (world.time - timeofhostdeath) > config.revival_brain_life) death() - return 0 /mob/living/carbon/brain/breathe() return diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 3efcc7a9ce9..74c5a71c94b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -486,7 +486,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven /mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine) - if(!istype(starting_machine) || !starting_machine.returnPipenet()) + if(!istype(starting_machine) || !starting_machine.returnPipenet() || !starting_machine.can_see_pipes()) return var/datum/pipeline/pipeline = starting_machine.returnPipenet() var/list/totalMembers = list() diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index bc4b5b43b1c..58c6a39e6c1 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -131,7 +131,7 @@ m_styles["head"] = "None" update_markings() - update_body(1, 1) //Update the body and force limb icon regeneration to update the head with the new icon. + update_body(TRUE) //Update the body and force limb icon regeneration to update the head with the new icon. if(wear_mask) update_inv_wear_mask() return 1 @@ -469,7 +469,7 @@ scramble(1, src, 100) real_name = random_name(gender, dna.species.name) //Give them a name that makes sense for their species. sync_organ_dna(assimilate = 1) - update_body(0) + update_body() reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. reset_markings() //...Or markings. dna.ResetUIFrom(src) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index aa8643173f4..6b7a0a2b15d 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -103,7 +103,6 @@ set_heartattack(FALSE) SSmobs.cubemonkeys -= src if(dna.species) - dna.species.handle_hud_icons(src) //Handle species-specific deaths. dna.species.handle_death(gibbed, src) @@ -124,10 +123,10 @@ if(. && healthdoll) // We're alive again, so re-build the entire healthdoll healthdoll.cached_healthdoll_overlays.Cut() + update_health_hud() // Update healthdoll if(dna.species) dna.species.update_sight(src) - dna.species.handle_hud_icons(src) /mob/living/carbon/human/proc/makeSkeleton() var/obj/item/organ/external/head/H = get_organ("head") @@ -146,14 +145,14 @@ H.alt_head = initial(H.alt_head) H.handle_alt_icon() m_styles = DEFAULT_MARKING_STYLES - update_fhair(0) - update_hair(0) - update_head_accessory(0) - update_markings(0) + update_fhair() + update_hair() + update_head_accessory() + update_markings() mutations.Add(SKELETON) mutations.Add(NOCLONE) - update_body(0) + update_body() update_mutantrace() return @@ -172,11 +171,11 @@ H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE if(H.h_style) H.h_style = "Bald" - update_fhair(0) - update_hair(0) + update_fhair() + update_hair() mutations.Add(HUSK) - update_body(0) + update_body() update_mutantrace() return @@ -190,6 +189,6 @@ var/obj/item/organ/external/head/H = bodyparts_by_name["head"] if(istype(H)) H.disfigured = FALSE - update_body(0) - update_mutantrace(0) + update_body() + update_mutantrace() UpdateAppearance() // reset hair from DNA diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index c1f6acdefe5..a34f02bc868 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -256,12 +256,12 @@ if(body_accessory) if(body_accessory.try_restrictions(src)) message = "[src] starts wagging [p_their()] tail." - start_tail_wagging(1) + start_tail_wagging() else if(dna.species.bodyflags & TAIL_WAGGING) if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL)) message = "[src] starts wagging [p_their()] tail." - start_tail_wagging(1) + start_tail_wagging() else return else @@ -271,7 +271,7 @@ if("swag", "swags") if(dna.species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging [p_their()] tail." - stop_tail_wagging(1) + stop_tail_wagging() else return m_type = 1 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7d1073fbdb2..828dc25322c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -18,10 +18,10 @@ dna = new /datum/dna(null) // Species name is handled by set_species() - set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE) - ..() + set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE) + if(dna.species) real_name = dna.species.get_random_name(gender) name = real_name @@ -658,7 +658,7 @@ else if(place_item) usr.unEquip(place_item) - equip_to_slot_if_possible(place_item, pocket_id, 0, 1) + equip_to_slot_if_possible(place_item, pocket_id, FALSE, TRUE) add_attack_logs(usr, src, "Equipped with [place_item]", isLivingSSD(src) ? null : ATKLOG_ALL) // Update strip window @@ -1169,7 +1169,7 @@ qdel(feet_blood_DNA) bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0) blood_state = BLOOD_STATE_NOT_BLOODY - update_inv_shoes(1) + update_inv_shoes() return 1 /mob/living/carbon/human/cuff_resist(obj/item/I) @@ -1349,7 +1349,7 @@ dna.species.create_organs(src) for(var/obj/item/thing in kept_items) - equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0) + equip_to_slot_if_possible(thing, kept_items[thing]) thing.flags = item_flags[thing] // Reset the flags to the origional ones //Handle default hair/head accessories for created mobs. @@ -1399,7 +1399,7 @@ UpdateAppearance() overlays.Cut() - update_mutantrace(1) + update_mutantrace() regenerate_icons() if(dna.species) @@ -1962,3 +1962,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(O && O.glowing) O.toggle_biolum(TRUE) visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.") + +/mob/living/carbon/human/proc/get_perceived_trauma() + return min(health, maxHealth - getStaminaLoss()) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index f2a976e46d2..89aa7854264 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -19,8 +19,6 @@ ChangeToHusk() update_stat("updatehealth([reason])") med_hud_set_health() - med_hud_set_status() - handle_hud_icons_health() /mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE) if(status_flags & GODMODE) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index d698a68c6d5..82b61a04391 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -457,13 +457,13 @@ emp_act if(bloody)//Apply blood if(wear_mask) wear_mask.add_mob_blood(src) - update_inv_wear_mask(0) + update_inv_wear_mask() if(head) head.add_mob_blood(src) - update_inv_head(0,0) + update_inv_head() if(glasses && prob(33)) glasses.add_mob_blood(src) - update_inv_glasses(0) + update_inv_glasses() if("chest")//Easier to score a stun but lasts less time @@ -475,10 +475,10 @@ emp_act if(bloody) if(wear_suit) wear_suit.add_mob_blood(src) - update_inv_wear_suit(1) + update_inv_wear_suit() if(w_uniform) w_uniform.add_mob_blood(src) - update_inv_w_uniform(1) + update_inv_w_uniform() @@ -525,16 +525,16 @@ emp_act else add_mob_blood(source) bloody_hands = amount - update_inv_gloves(1) //updates on-mob overlays for bloody hands and/or bloody gloves + update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves /mob/living/carbon/human/proc/bloody_body(var/mob/living/source) if(wear_suit) wear_suit.add_mob_blood(source) - update_inv_wear_suit(0) + update_inv_wear_suit() return if(w_uniform) w_uniform.add_mob_blood(source) - update_inv_w_uniform(1) + update_inv_w_uniform() /mob/living/carbon/human/proc/handle_suit_punctures(var/damtype, var/damage) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index ea62f2fb5f9..b4a65b110a9 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -8,12 +8,15 @@ /mob/living/carbon/human/var/list/bodyparts_by_name = list() // map organ names to organs // Takes care of organ related updates, such as broken and missing limbs -/mob/living/carbon/human/proc/handle_organs() +/mob/living/carbon/human/handle_organs() + ..() //processing internal organs is pretty cheap, do that first. - for(var/obj/item/organ/internal/I in internal_organs) + for(var/X in internal_organs) + var/obj/item/organ/internal/I = X I.process() - for(var/obj/item/organ/external/E in bodyparts) + for(var/Y in bodyparts) + var/obj/item/organ/external/E = Y E.process() if(!lying && world.time - l_move_time < 15) @@ -109,6 +112,11 @@ do_sparks(5, 0, src) +/mob/living/carbon/human/handle_germs() + ..() + if(gloves && germ_level > gloves.germ_level && prob(10)) + gloves.germ_level += 1 + /mob/living/carbon/human/proc/becomeSlim() to_chat(src, "You feel fit again!") mutations.Remove(FAT) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index ea48884df9b..954d4e8fa55 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -178,8 +178,7 @@ //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() -//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc. -/mob/living/carbon/human/equip_to_slot(obj/item/I, slot, redraw_mob = 1) +/mob/living/carbon/human/equip_to_slot(obj/item/I, slot) if(!slot) return if(!istype(I)) @@ -203,40 +202,40 @@ switch(slot) if(slot_back) back = I - update_inv_back(redraw_mob) + update_inv_back() if(slot_wear_mask) wear_mask = I if((wear_mask.flags & BLOCKHAIR) || (wear_mask.flags & BLOCKHEADHAIR)) - update_hair(redraw_mob) //rebuild hair - update_fhair(redraw_mob) - update_head_accessory(redraw_mob) + update_hair() //rebuild hair + update_fhair() + update_head_accessory() if(hud_list.len) sec_hud_set_ID() wear_mask_update(I, toggle_off = TRUE) - update_inv_wear_mask(redraw_mob) + update_inv_wear_mask() if(slot_handcuffed) handcuffed = I - update_inv_handcuffed(redraw_mob) + update_inv_handcuffed() if(slot_legcuffed) legcuffed = I - update_inv_legcuffed(redraw_mob) + update_inv_legcuffed() if(slot_l_hand) l_hand = I - update_inv_l_hand(redraw_mob) + update_inv_l_hand() if(slot_r_hand) r_hand = I - update_inv_r_hand(redraw_mob) + update_inv_r_hand() if(slot_belt) belt = I - update_inv_belt(redraw_mob) + update_inv_belt() if(slot_wear_id) wear_id = I if(hud_list.len) sec_hud_set_ID() - update_inv_wear_id(redraw_mob) + update_inv_wear_id() if(slot_wear_pda) wear_pda = I - update_inv_wear_pda(redraw_mob) + update_inv_wear_pda() if(slot_l_ear) l_ear = I if(l_ear.slot_flags & SLOT_TWOEARS) @@ -245,7 +244,7 @@ r_ear = O O.layer = ABOVE_HUD_LAYER O.plane = ABOVE_HUD_PLANE - update_inv_ears(redraw_mob) + update_inv_ears() if(slot_r_ear) r_ear = I if(r_ear.slot_flags & SLOT_TWOEARS) @@ -254,7 +253,7 @@ l_ear = O O.layer = ABOVE_HUD_LAYER O.plane = ABOVE_HUD_PLANE - update_inv_ears(redraw_mob) + update_inv_ears() if(slot_glasses) glasses = I var/obj/item/clothing/glasses/G = I @@ -264,42 +263,42 @@ update_nearsighted_effects() if(G.vision_flags || G.see_in_dark || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) update_sight() - update_inv_glasses(redraw_mob) + update_inv_glasses() update_client_colour() if(slot_gloves) gloves = I - update_inv_gloves(redraw_mob) + update_inv_gloves() if(slot_head) head = I if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR)) - update_hair(redraw_mob) //rebuild hair - update_fhair(redraw_mob) - update_head_accessory(redraw_mob) + update_hair() //rebuild hair + update_fhair() + update_head_accessory() // paper + bandanas if(istype(I, /obj/item/clothing/head)) var/obj/item/clothing/head/hat = I if(hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha)) update_sight() head_update(I) - update_inv_head(redraw_mob) + update_inv_head() if(slot_shoes) shoes = I - update_inv_shoes(redraw_mob) + update_inv_shoes() if(slot_wear_suit) wear_suit = I - update_inv_wear_suit(redraw_mob) + update_inv_wear_suit() if(slot_w_uniform) w_uniform = I - update_inv_w_uniform(redraw_mob) + update_inv_w_uniform() if(slot_l_store) l_store = I - update_inv_pockets(redraw_mob) + update_inv_pockets() if(slot_r_store) r_store = I - update_inv_pockets(redraw_mob) + update_inv_pockets() if(slot_s_store) s_store = I - update_inv_s_store(redraw_mob) + update_inv_s_store() if(slot_in_backpack) if(get_active_hand() == I) unEquip(I) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8f548100650..c74340d0901 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1,18 +1,26 @@ /mob/living/carbon/human/Life(seconds, times_fired) + set invisibility = 0 + if(notransform) + return + + . = ..() + + if(QDELETED(src)) + return FALSE + life_tick++ voice = GetVoice() - if(..()) + if(.) //not dead if(check_mutations) domutcheck(src,null) update_mutations() - check_mutations=0 + check_mutations = FALSE handle_pain() handle_heartbeat() - handle_drunk() dna.species.handle_life(src) if(!client) dna.species.handle_npc(src) @@ -24,45 +32,45 @@ if(stat == DEAD) handle_decay() - if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle - return //We go ahead and process them 5 times for HUD images and other stuff though. - //Update our name based on whether our face is obscured/disfigured name = get_visible_name() pulse = handle_pulse(times_fired) - if(mind && mind.vampire) + if(mind?.vampire) mind.vampire.handle_vampire() if(life_tick == 1) regenerate_icons() // Make sure the inventory updates - handle_ghosted() - handle_ssd() + if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained()) + handle_ghosted() + if(player_logged > 0 && stat != DEAD && job) + handle_ssd() + + if(stat != DEAD) + return TRUE /mob/living/carbon/human/proc/handle_ghosted() - if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained()) - if(key) - player_ghosted = 0 - else - player_ghosted++ - if(player_ghosted % 150 == 0) - force_cryo_human(src) + if(key) + player_ghosted = 0 + else + player_ghosted++ + if(player_ghosted % 150 == 0) + force_cryo_human(src) /mob/living/carbon/human/proc/handle_ssd() - if(player_logged > 0 && stat != DEAD && job) - player_logged++ - if(istype(loc, /obj/machinery/cryopod)) + player_logged++ + if(istype(loc, /obj/machinery/cryopod)) + return + if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0) + var/turf/T = get_turf(src) + if(!is_station_level(T.z)) return - if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0) - var/turf/T = get_turf(src) - if(!is_station_level(T.z)) - return - var/area/A = get_area(src) - if(cryo_ssd(src)) - var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40) - P.name = "NT SSD Teleportation Portal" - if(A.fast_despawn) - force_cryo_human(src) + var/area/A = get_area(src) + if(cryo_ssd(src)) + var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40) + P.name = "NT SSD Teleportation Portal" + if(A.fast_despawn) + force_cryo_human(src) /mob/living/carbon/human/calculate_affecting_pressure(var/pressure) ..() @@ -80,38 +88,35 @@ /mob/living/carbon/human/handle_disabilities() - if(disabilities & EPILEPSY) - if((prob(1) && paralysis < 1)) - visible_message("[src] starts having a seizure!","You have a seizure!") - Paralyse(10) - Jitter(1000) + //Vision //god knows why this is here + var/obj/item/organ/vision + if(dna.species.vision_organ) + vision = get_int_organ(dna.species.vision_organ) - // If we have the gene for being crazy, have random events. - if(dna.GetSEState(GLOB.hallucinationblock)) - if(prob(1)) - Hallucinate(20) + if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. + SetEyeBlind(0) + SetEyeBlurry(0) - if(disabilities & COUGHING) - if((prob(5) && paralysis <= 1)) - drop_item() - emote("cough") - if(disabilities & TOURETTES) - if((prob(10) && paralysis <= 1)) - Stun(10) - switch(rand(1, 3)) - if(1) - emote("twitch") - if(2 to 3) - var/tourettes = pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS") - say("[prob(50) ? ";" : ""][tourettes]") - var/x_offset = pixel_x + rand(-2,2) //Should probably be moved into the twitch emote at some point. - var/y_offset = pixel_y + rand(-1,1) - animate(src, pixel_x = pixel_x + x_offset, pixel_y = pixel_y + y_offset, time = 1) - animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1) + else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind. + EyeBlind(2) + EyeBlurry(2) - if(disabilities & NERVOUS) - if(prob(10)) - Stuttering(10) + else + //blindness + if(BLINDNESS in mutations) // Disabled-blind, doesn't get better on its own + + else if(eye_blind) // Blindness, heals slowly over time + AdjustEyeBlind(-1) + + else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold) && eye_blurry) //resting your eyes with a blindfold heals blurry eyes faster + AdjustEyeBlurry(-3) + + //blurry sight + if(vision.is_bruised()) // Vision organs impaired? Permablurry. + EyeBlurry(2) + + if(eye_blurry) // Blurry eyes heal slowly + AdjustEyeBlurry(-1) if(getBrainLoss() >= 60 && stat != DEAD) if(prob(3)) @@ -607,6 +612,7 @@ // nutrition decrease if(nutrition > 0 && stat != DEAD) + handle_nutrition_alerts() // THEY HUNGER var/hunger_rate = hunger_drain if(satiety > 0) @@ -656,22 +662,25 @@ AdjustSleeping(1) Paralyse(5) - AdjustConfused(-1) + if(confused) + AdjustConfused(-1) // decrement dizziness counter, clamped to 0 if(resting) - AdjustDizzy(-15) - AdjustJitter(-15) + if(dizziness) + AdjustDizzy(-15) + if(jitteriness) + AdjustJitter(-15) else - AdjustDizzy(-3) - AdjustJitter(-3) + if(dizziness) + AdjustDizzy(-3) + if(jitteriness) + AdjustJitter(-3) if(NO_INTORGANS in dna.species.species_traits) return handle_trace_chems() - return //TODO: DEFERRED - /mob/living/carbon/human/handle_drunk() var/slur_start = 30 //12u ethanol, 30u whiskey FOR HUMANS var/confused_start = 40 @@ -683,55 +692,54 @@ var/collapse_start = 75 var/braindamage_start = 120 var/alcohol_strength = drunk - var/sober_str=!(SOBER in mutations)?1:2 + var/sober_str =! (SOBER in mutations) ? 1 : 2 - if(drunk) - alcohol_strength/=sober_str + alcohol_strength /= sober_str - var/obj/item/organ/internal/liver/L - if(!isSynthetic()) - L = get_int_organ(/obj/item/organ/internal/liver) + var/obj/item/organ/internal/liver/L + if(!isSynthetic()) + L = get_int_organ(/obj/item/organ/internal/liver) + if(L) + alcohol_strength *= L.alcohol_intensity + else + alcohol_strength *= 5 + + if(alcohol_strength >= slur_start) //slurring + Slur(drunk) + if(alcohol_strength >= brawl_start) //the drunken martial art + if(!istype(martial_art, /datum/martial_art/drunk_brawling)) + var/datum/martial_art/drunk_brawling/F = new + F.teach(src, 1) + if(alcohol_strength < brawl_start) //removing the art + if(istype(martial_art, /datum/martial_art/drunk_brawling)) + martial_art.remove(src) + if(alcohol_strength >= confused_start && prob(33)) //confused walking + if(!confused) + Confused(1) + AdjustConfused(3 / sober_str) + if(alcohol_strength >= blur_start) //blurry eyes + EyeBlurry(10 / sober_str) + if(!isSynthetic()) //stuff only for non-synthetics + if(alcohol_strength >= vomit_start) //vomiting + if(prob(8)) + fakevomit() + if(alcohol_strength >= pass_out) + Paralyse(5 / sober_str) + Drowsy(30 / sober_str) if(L) - alcohol_strength *= L.alcohol_intensity - else - alcohol_strength *= 5 - - if(alcohol_strength >= slur_start) //slurring - Slur(drunk) - if(alcohol_strength >= brawl_start) //the drunken martial art - if(!istype(martial_art, /datum/martial_art/drunk_brawling)) - var/datum/martial_art/drunk_brawling/F = new - F.teach(src,1) - if(alcohol_strength < brawl_start) //removing the art - if(istype(martial_art, /datum/martial_art/drunk_brawling)) - martial_art.remove(src) - if(alcohol_strength >= confused_start && prob(33)) //confused walking - if(!confused) Confused(1) - AdjustConfused(3/sober_str) - if(alcohol_strength >= blur_start) //blurry eyes - EyeBlurry(10/sober_str) - if(!isSynthetic()) //stuff only for non-synthetics - if(alcohol_strength >= vomit_start) //vomiting - if(prob(8)) - fakevomit() - if(alcohol_strength >= pass_out) - Paralyse(5/sober_str) - Drowsy(30/sober_str) - if(L) - L.receive_damage(0.1, 1) - adjustToxLoss(0.1) - else //stuff only for synthetics - if(alcohol_strength >= spark_start && prob(25)) - do_sparks(3, 1, src) - if(alcohol_strength >= collapse_start && prob(10)) - emote("collapse") - do_sparks(3, 1, src) - if(alcohol_strength >= braindamage_start && prob(10)) - adjustBrainLoss(1) + L.receive_damage(0.1, 1) + adjustToxLoss(0.1) + else //stuff only for synthetics + if(alcohol_strength >= spark_start && prob(25)) + do_sparks(3, 1, src) + if(alcohol_strength >= collapse_start && prob(10)) + emote("collapse") + do_sparks(3, 1, src) + if(alcohol_strength >= braindamage_start && prob(10)) + adjustBrainLoss(1) if(!has_booze()) AdjustDrunk(-0.5) - return /mob/living/carbon/human/proc/has_booze() //checks if the human has ethanol or its subtypes inside for(var/A in reagents.reagent_list) @@ -740,180 +748,154 @@ return 1 return 0 -/mob/living/carbon/human/handle_regular_status_updates() +/mob/living/carbon/human/handle_critical_condition() if(status_flags & GODMODE) return 0 - . = ..() + var/guaranteed_death_threshold = health + (getOxyLoss() * 0.5) - (getFireLoss() * 0.67) - (getBruteLoss() * 0.67) - if(.) //alive - if(REGEN in mutations) - heal_overall_damage(0.1, 0.1) + if(getBrainLoss() >= 120 || (guaranteed_death_threshold) <= -500) + death() + return - if(paralysis) - stat = UNCONSCIOUS + if(getBrainLoss() >= 100) // braindeath + AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25) + Weaken(30) - else if(sleeping) + if(!check_death_method()) + if(health <= HEALTH_THRESHOLD_DEAD) + var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01) + if(prob(deathchance)) + death() + return - stat = UNCONSCIOUS + if(health <= HEALTH_THRESHOLD_CRIT) + if(prob(5)) + emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver")) + AdjustStuttering(5, bound_lower = 0, bound_upper = 5) + EyeBlurry(5) + if(prob(7)) + AdjustConfused(2) + if(prob(5)) + Paralyse(2) + switch(health) + if(-INFINITY to -100) + adjustOxyLoss(1) + if(prob(health * -0.1)) + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.set_heartattack(TRUE) + if(prob(health * -0.2)) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + Paralyse(5) + if(-99 to -80) + adjustOxyLoss(1) + if(prob(4)) + to_chat(src, "Your chest hurts...") + Paralyse(2) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + if(-79 to -50) + adjustOxyLoss(1) + if(prob(10)) + var/datum/disease/D = new /datum/disease/critical/shock + ForceContractDisease(D) + if(prob(health * -0.08)) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + if(prob(6)) + to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!") + Weaken(3) + if(prob(3)) + Paralyse(2) + if(-49 to 0) + adjustOxyLoss(1) + if(prob(3)) + var/datum/disease/D = new /datum/disease/critical/shock + ForceContractDisease(D) + if(prob(5)) + to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!") + Weaken(3) - if(mind) - if(mind.vampire) - if(istype(loc, /obj/structure/closet/coffin)) - adjustBruteLoss(-1) - adjustFireLoss(-1) - adjustToxLoss(-1) - - else if(status_flags & FAKEDEATH) - stat = UNCONSCIOUS - - //Vision //god knows why this is here - var/obj/item/organ/vision - if(dna.species.vision_organ) - vision = get_int_organ(dna.species.vision_organ) - - if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. - SetEyeBlind(0) - SetEyeBlurry(0) - - else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind. - EyeBlind(2) - EyeBlurry(2) - - else - //blindness - if(disabilities & BLIND) // Disabled-blind, doesn't get better on its own - - else if(eye_blind) // Blindness, heals slowly over time - AdjustEyeBlind(-1) - - else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster - AdjustEyeBlurry(-3) - - //blurry sight - if(vision.is_bruised()) // Vision organs impaired? Permablurry. - EyeBlurry(2) - - if(eye_blurry) // Blurry eyes heal slowly - AdjustEyeBlurry(-1) - - - if(flying) - animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING) - animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING) - - // If you're dirty, your gloves will become dirty, too. - if(gloves && germ_level > gloves.germ_level && prob(10)) - gloves.germ_level += 1 - - handle_organs() - - var/guaranteed_death_threshold = health + (getOxyLoss() * 0.5) - (getFireLoss() * 0.67) - (getBruteLoss() * 0.67) - - if(getBrainLoss() >= 120 || (guaranteed_death_threshold) <= -500) - death() - return - - if(getBrainLoss() >= 100) // braindeath - AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25) - Weaken(30) - - if(!check_death_method()) - if(health <= HEALTH_THRESHOLD_DEAD) - var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01) - if(prob(deathchance)) - death() - return - - if(health <= HEALTH_THRESHOLD_CRIT) - if(prob(5)) - emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver")) - AdjustStuttering(5, bound_lower = 0, bound_upper = 5) - EyeBlurry(5) - if(prob(7)) - AdjustConfused(2) - if(prob(5)) - Paralyse(2) - switch(health) - if(-INFINITY to -100) - adjustOxyLoss(1) - if(prob(health * -0.1)) - if(ishuman(src)) - var/mob/living/carbon/human/H = src - H.set_heartattack(TRUE) - if(prob(health * -0.2)) - var/datum/disease/D = new /datum/disease/critical/heart_failure - ForceContractDisease(D) - Paralyse(5) - if(-99 to -80) - adjustOxyLoss(1) - if(prob(4)) - to_chat(src, "Your chest hurts...") - Paralyse(2) - var/datum/disease/D = new /datum/disease/critical/heart_failure - ForceContractDisease(D) - if(-79 to -50) - adjustOxyLoss(1) - if(prob(10)) - var/datum/disease/D = new /datum/disease/critical/shock - ForceContractDisease(D) - if(prob(health * -0.08)) - var/datum/disease/D = new /datum/disease/critical/heart_failure - ForceContractDisease(D) - if(prob(6)) - to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!") - Weaken(3) - if(prob(3)) - Paralyse(2) - if(-49 to 0) - adjustOxyLoss(1) - if(prob(3)) - var/datum/disease/D = new /datum/disease/critical/shock - ForceContractDisease(D) - if(prob(5)) - to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!") - Weaken(3) - - else //dead - SetSilence(0) - - -/mob/living/carbon/human/handle_vision() - if(machine) - if(!machine.check_eye(src)) - reset_perspective(null) +/mob/living/carbon/human/update_health_hud() + if(!client) + return + if(dna.species.update_health_hud()) + return else - var/isRemoteObserve = 0 - if((REMOTE_VIEW in mutations) && remoteview_target) - isRemoteObserve = 1 + if(healths) + var/health_amount = get_perceived_trauma() + if(..(health_amount)) //not dead + switch(hal_screwyhud) + if(SCREWYHUD_CRIT) + healths.icon_state = "health6" + if(SCREWYHUD_DEAD) + healths.icon_state = "health7" + if(SCREWYHUD_HEALTHY) + healths.icon_state = "health0" - if(remoteview_target.stat != CONSCIOUS) - to_chat(src, "Your psy-connection grows too faint to maintain!") - isRemoteObserve = 0 + if(healthdoll) + if(stat == DEAD) + healthdoll.icon_state = "healthdoll_DEAD" + if(healthdoll.overlays.len) + healthdoll.overlays.Cut() + else + var/list/new_overlays = list() + var/list/cached_overlays = healthdoll.cached_healthdoll_overlays + // Use the dead health doll as the base, since we have proper "healthy" overlays now + healthdoll.icon_state = "healthdoll_DEAD" + for(var/obj/item/organ/external/O in bodyparts) + var/damage = O.burn_dam + O.brute_dam + var/comparison = (O.max_damage/5) + var/icon_num = 0 + if(damage) + icon_num = 1 + if(damage > (comparison)) + icon_num = 2 + if(damage > (comparison*2)) + icon_num = 3 + if(damage > (comparison*3)) + icon_num = 4 + if(damage > (comparison*4)) + icon_num = 5 + new_overlays += "[O.limb_name][icon_num]" + healthdoll.overlays += (new_overlays - cached_overlays) + healthdoll.overlays -= (cached_overlays - new_overlays) + healthdoll.cached_healthdoll_overlays = new_overlays - if(PSY_RESIST in remoteview_target.mutations) - to_chat(src, "Your mind is shut out!") - isRemoteObserve = 0 +/mob/living/carbon/human/proc/handle_nutrition_alerts() //This is a terrible abuse of the alert system; something like this should be a HUD element + if(NO_HUNGER in dna.species.species_traits) + return + if(mind?.vampire && (mind in SSticker.mode.vampires)) //Vampires + switch(nutrition) + if(NUTRITION_LEVEL_FULL to INFINITY) + throw_alert("nutrition", /obj/screen/alert/fat/vampire) + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + throw_alert("nutrition", /obj/screen/alert/full/vampire) + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + throw_alert("nutrition", /obj/screen/alert/well_fed/vampire) + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + throw_alert("nutrition", /obj/screen/alert/fed/vampire) + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + throw_alert("nutrition", /obj/screen/alert/hungry/vampire) + else + throw_alert("nutrition", /obj/screen/alert/starving/vampire) - // Not on the station or mining? - var/turf/temp_turf = get_turf(remoteview_target) - if(!(temp_turf in config.contact_levels)) - to_chat(src, "Your psy-connection grows too faint to maintain!") - isRemoteObserve = 0 - - if(remote_view) - isRemoteObserve = 1 - - if(!isRemoteObserve && client && !client.adminobs) - remoteview_target = null - reset_perspective(null) - -/mob/living/carbon/human/handle_hud_icons() - dna.species.handle_hud_icons(src) - -/mob/living/carbon/human/handle_hud_icons_health() - dna.species.handle_hud_icons_health(src) - handle_hud_icons_health_overlay() + else //Any other non-vampires + switch(nutrition) + if(NUTRITION_LEVEL_FULL to INFINITY) + throw_alert("nutrition", /obj/screen/alert/fat) + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + throw_alert("nutrition", /obj/screen/alert/full) + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + throw_alert("nutrition", /obj/screen/alert/well_fed) + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + throw_alert("nutrition", /obj/screen/alert/fed) + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + throw_alert("nutrition", /obj/screen/alert/hungry) + else + throw_alert("nutrition", /obj/screen/alert/starving) /mob/living/carbon/human/handle_random_events() // Puke if toxloss is too high @@ -942,15 +924,14 @@ clear_alert("embeddedobject") /mob/living/carbon/human/handle_changeling() - if(mind) - if(mind.changeling) - mind.changeling.regenerate(src) - if(hud_used) - hud_used.lingchemdisplay.invisibility = 0 - hud_used.lingchemdisplay.maptext = "
[round(mind.changeling.chem_charges)]
" - else - if(hud_used) - hud_used.lingchemdisplay.invisibility = 101 + if(mind.changeling) + mind.changeling.regenerate(src) + if(hud_used) + hud_used.lingchemdisplay.invisibility = 0 + hud_used.lingchemdisplay.maptext = "
[round(mind.changeling.chem_charges)]
" + else + if(hud_used) + hud_used.lingchemdisplay.invisibility = 101 /mob/living/carbon/human/proc/handle_pulse(times_fired) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index b53fa03cebf..98edb60c6bf 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -151,7 +151,7 @@ if(S.speaking && S.speaking.flags & NO_STUTTER) continue - if(silent || (disabilities & MUTE)) + if(silent || (MUTE in mutations)) S.message = "" if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 06b42202b45..21695e25e78 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -754,105 +754,8 @@ return FALSE //Unsupported slot -/datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H) - return min(H.health, H.maxHealth - H.getStaminaLoss()) - -/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H) - if(!H.client) - return - handle_hud_icons_health(H) - H.handle_hud_icons_health_overlay() - handle_hud_icons_nutrition(H) - -/datum/species/proc/handle_hud_icons_health(mob/living/carbon/H) - if(!H.client) - return - handle_hud_icons_health_side(H) - handle_hud_icons_health_doll(H) - -/datum/species/proc/handle_hud_icons_health_side(mob/living/carbon/human/H) - if(H.healths) - if(H.stat == DEAD || (H.status_flags & FAKEDEATH)) - H.healths.icon_state = "health7" - else - switch(H.hal_screwyhud) - if(SCREWYHUD_CRIT) H.healths.icon_state = "health6" - if(SCREWYHUD_DEAD) H.healths.icon_state = "health7" - if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0" - else - switch(get_perceived_trauma(H)) - if(100 to INFINITY) H.healths.icon_state = "health0" - if(80 to 100) H.healths.icon_state = "health1" - if(60 to 80) H.healths.icon_state = "health2" - if(40 to 60) H.healths.icon_state = "health3" - if(20 to 40) H.healths.icon_state = "health4" - if(0 to 20) H.healths.icon_state = "health5" - else H.healths.icon_state = "health6" - -/datum/species/proc/handle_hud_icons_health_doll(mob/living/carbon/human/H) - if(H.healthdoll) - if(H.stat == DEAD || (H.status_flags & FAKEDEATH)) - H.healthdoll.icon_state = "healthdoll_DEAD" - if(H.healthdoll.overlays.len) - H.healthdoll.overlays.Cut() - else - var/list/new_overlays = list() - var/list/cached_overlays = H.healthdoll.cached_healthdoll_overlays - // Use the dead health doll as the base, since we have proper "healthy" overlays now - H.healthdoll.icon_state = "healthdoll_DEAD" - for(var/obj/item/organ/external/O in H.bodyparts) - var/damage = O.burn_dam + O.brute_dam - var/comparison = (O.max_damage/5) - var/icon_num = 0 - if(damage) - icon_num = 1 - if(damage > (comparison)) - icon_num = 2 - if(damage > (comparison*2)) - icon_num = 3 - if(damage > (comparison*3)) - icon_num = 4 - if(damage > (comparison*4)) - icon_num = 5 - new_overlays += "[O.limb_name][icon_num]" - H.healthdoll.overlays += (new_overlays - cached_overlays) - H.healthdoll.overlays -= (cached_overlays - new_overlays) - H.healthdoll.cached_healthdoll_overlays = new_overlays - -/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H) - if(NO_HUNGER in species_traits) - return FALSE - if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires - switch(H.nutrition) - if(NUTRITION_LEVEL_FULL to INFINITY) - H.throw_alert("nutrition", /obj/screen/alert/fat/vampire) - if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) - H.throw_alert("nutrition", /obj/screen/alert/full/vampire) - if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) - H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire) - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) - H.throw_alert("nutrition", /obj/screen/alert/fed/vampire) - if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) - H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire) - else - H.throw_alert("nutrition", /obj/screen/alert/starving/vampire) - return 1 - - else ///Any other non-vampires - switch(H.nutrition) - if(NUTRITION_LEVEL_FULL to INFINITY) - H.throw_alert("nutrition", /obj/screen/alert/fat) - if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) - H.throw_alert("nutrition", /obj/screen/alert/full) - if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) - H.throw_alert("nutrition", /obj/screen/alert/well_fed) - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) - H.throw_alert("nutrition", /obj/screen/alert/fed) - if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) - H.throw_alert("nutrition", /obj/screen/alert/hungry) - else - H.throw_alert("nutrition", /obj/screen/alert/starving) - return 1 +/datum/species/proc/update_health_hud(mob/living/carbon/human/H) + return FALSE /* Returns the path corresponding to the corresponding organ diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index 0a708db223f..60f972b69a4 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -95,7 +95,7 @@ var/obj/item/organ/external/E = H.bodyparts_by_name[organname] if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime)) E.sync_colour_to_human(H) - H.update_hair(0) + H.update_hair() H.update_body() ..() diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm index 1b1589cb6fd..903e4a32332 100644 --- a/code/modules/mob/living/carbon/human/species/tajaran.dm +++ b/code/modules/mob/living/carbon/human/species/tajaran.dm @@ -56,4 +56,4 @@ "is holding their breath!") /datum/species/tajaran/handle_death(gibbed, mob/living/carbon/human/H) - H.stop_tail_wagging(1) + H.stop_tail_wagging() diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm index 61c34ab41d9..d4e9b02cd9b 100644 --- a/code/modules/mob/living/carbon/human/species/unathi.dm +++ b/code/modules/mob/living/carbon/human/species/unathi.dm @@ -104,7 +104,7 @@ return /datum/species/unathi/handle_death(gibbed, mob/living/carbon/human/H) - H.stop_tail_wagging(1) + H.stop_tail_wagging() /datum/species/unathi/ashwalker name = "Ash Walker" diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm index e803a33f3ec..6ac20e77b9b 100644 --- a/code/modules/mob/living/carbon/human/species/vox.dm +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -76,7 +76,7 @@ speciesbox = /obj/item/storage/box/survival_vox /datum/species/vox/handle_death(gibbed, mob/living/carbon/human/H) - H.stop_tail_wagging(1) + H.stop_tail_wagging() /datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H) if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm index 9a313042d2d..920cd86659d 100644 --- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm +++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -50,4 +50,4 @@ "is holding their breath!") /datum/species/vulpkanin/handle_death(gibbed, mob/living/carbon/human/H) - H.stop_tail_wagging(1) + H.stop_tail_wagging() diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm index 9e02e2e28be..080a67a032b 100644 --- a/code/modules/mob/living/carbon/human/species/wryn.dm +++ b/code/modules/mob/living/carbon/human/species/wryn.dm @@ -50,7 +50,7 @@ /datum/species/wryn/handle_death(gibbed, mob/living/carbon/human/H) - for(var/mob/living/carbon/C in GLOB.living_mob_list) + for(var/mob/living/carbon/C in GLOB.alive_mob_list) if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) to_chat(C, "Your antennae tingle as you are overcome with pain...") to_chat(C, "It feels like part of you has died.") // This is bullshit diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index cbc768cdd02..2cce48d51c2 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -77,14 +77,14 @@ There are several things that need to be remembered: If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call it manually: e.g. - update_inv_head(0) - update_inv_l_hand(0) + update_inv_head() + update_inv_l_hand() update_inv_r_hand() //<---calls update_icons() or equivillantly: - update_inv_head(0) - update_inv_l_hand(0) - update_inv_r_hand(0) + update_inv_head() + update_inv_l_hand() + update_inv_r_hand() update_icons() > If you need to update all overlays you can use regenerate_icons(). it works exactly like update_clothing used to. @@ -124,7 +124,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists -/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1) +/mob/living/carbon/human/UpdateDamageIcon() // first check whether something actually changed about damage appearance var/damage_appearance = "" @@ -164,7 +164,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //BASE MOB SPRITE -/mob/living/carbon/human/proc/update_body(var/update_icons=1, var/rebuild_base=0) +/mob/living/carbon/human/proc/update_body(rebuild_base = FALSE) remove_overlay(BODY_LAYER) remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's remove_overlay(UNDERWEAR_LAYER) @@ -281,19 +281,19 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[BODY_LAYER] = standing apply_overlay(BODY_LAYER) //tail - update_tail_layer(0) + update_tail_layer() update_int_organs() //head accessory - update_head_accessory(0) + update_head_accessory() //markings - update_markings(0) + update_markings() //hair - update_hair(0) - update_fhair(0) + update_hair() + update_fhair() //MARKINGS OVERLAY -/mob/living/carbon/human/proc/update_markings(var/update_icons=1) +/mob/living/carbon/human/proc/update_markings() //Reset our markings. remove_overlay(MARKINGS_LAYER) @@ -325,7 +325,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(MARKINGS_LAYER) //HEAD ACCESSORY OVERLAY -/mob/living/carbon/human/proc/update_head_accessory(var/update_icons=1) +/mob/living/carbon/human/proc/update_head_accessory() //Reset our head accessory remove_overlay(HEAD_ACCESSORY_LAYER) remove_overlay(HEAD_ACC_OVER_LAYER) @@ -362,7 +362,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //HAIR OVERLAY -/mob/living/carbon/human/proc/update_hair(var/update_icons=1) +/mob/living/carbon/human/proc/update_hair() //Reset our hair remove_overlay(HAIR_LAYER) @@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //FACIAL HAIR OVERLAY -/mob/living/carbon/human/proc/update_fhair(var/update_icons=1) +/mob/living/carbon/human/proc/update_fhair() //Reset our facial hair remove_overlay(FHAIR_LAYER) remove_overlay(FHAIR_OVER_LAYER) @@ -447,7 +447,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) -/mob/living/carbon/human/update_mutations(var/update_icons=1) +/mob/living/carbon/human/update_mutations() remove_overlay(MUTATIONS_LAYER) var/mutable_appearance/standing = mutable_appearance('icons/effects/genetics.dmi', layer = -MUTATIONS_LAYER) var/add_image = 0 @@ -478,7 +478,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(MUTATIONS_LAYER) -/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1) +/mob/living/carbon/human/proc/update_mutantrace() //BS12 EDIT var/skel = (SKELETON in mutations) if(skel) @@ -486,8 +486,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) else skeleton = null - update_hair(0) - update_fhair(0) + update_hair() + update_fhair() /mob/living/carbon/human/update_fire() @@ -501,41 +501,42 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //For legacy support. /mob/living/carbon/human/regenerate_icons() ..() - if(notransform) return - update_mutations(0) - update_body(0, 1) //Update the body and force limb icon regeneration. - update_hair(0) - update_head_accessory(0) - update_fhair(0) - update_mutantrace(0) - update_inv_w_uniform(0,0) - update_inv_wear_id(0) - update_inv_gloves(0,0) - update_inv_glasses(0) - update_inv_ears(0) - update_inv_shoes(0,0) - update_inv_s_store(0) - update_inv_wear_mask(0) - update_inv_head(0,0) - update_inv_belt(0) - update_inv_back(0) - update_inv_wear_suit(0) - update_inv_r_hand(0) - update_inv_l_hand(0) - update_inv_handcuffed(0) - update_inv_legcuffed(0) - update_inv_pockets(0) - update_inv_wear_pda(0) - UpdateDamageIcon(0) + if(notransform) + return + update_mutations() + update_body(TRUE) //Update the body and force limb icon regeneration. + update_hair() + update_head_accessory() + update_fhair() + update_mutantrace() + update_inv_w_uniform() + update_inv_wear_id() + update_inv_gloves() + update_inv_glasses() + update_inv_ears() + update_inv_shoes() + update_inv_s_store() + update_inv_wear_mask() + update_inv_head() + update_inv_belt() + update_inv_back() + update_inv_wear_suit() + update_inv_r_hand() + update_inv_l_hand() + update_inv_handcuffed() + update_inv_legcuffed() + update_inv_pockets() + update_inv_wear_pda() + UpdateDamageIcon() force_update_limbs() - update_tail_layer(0) + update_tail_layer() overlays.Cut() // Force all overlays to regenerate update_fire() update_icons() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv -/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1) +/mob/living/carbon/human/update_inv_w_uniform() remove_overlay(UNIFORM_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_w_uniform] @@ -593,7 +594,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) thing.plane = initial(thing.plane) apply_overlay(UNIFORM_LAYER) -/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1) +/mob/living/carbon/human/update_inv_wear_id() remove_overlay(ID_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_id] @@ -609,7 +610,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[ID_LAYER] = mutable_appearance('icons/mob/mob.dmi', "id", layer = -ID_LAYER) apply_overlay(ID_LAYER) -/mob/living/carbon/human/update_inv_gloves(var/update_icons=1) +/mob/living/carbon/human/update_inv_gloves() remove_overlay(GLOVES_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves] @@ -646,7 +647,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(GLOVES_LAYER) -/mob/living/carbon/human/update_inv_glasses(var/update_icons=1) +/mob/living/carbon/human/update_inv_glasses() remove_overlay(GLASSES_LAYER) remove_overlay(GLASSES_OVER_LAYER) remove_overlay(OVER_MASK_LAYER) @@ -687,7 +688,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) update_misc_effects() -/mob/living/carbon/human/update_inv_ears(var/update_icons=1) +/mob/living/carbon/human/update_inv_ears() remove_overlay(EARS_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_l_ear] @@ -735,7 +736,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER) apply_overlay(EARS_LAYER) -/mob/living/carbon/human/update_inv_shoes(var/update_icons=1) +/mob/living/carbon/human/update_inv_shoes() remove_overlay(SHOES_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_shoes] @@ -771,7 +772,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[SHOES_LAYER] = bloodsies apply_overlay(SHOES_LAYER) -/mob/living/carbon/human/update_inv_s_store(var/update_icons=1) +/mob/living/carbon/human/update_inv_s_store() remove_overlay(SUIT_STORE_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_s_store] @@ -792,7 +793,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(SUIT_STORE_LAYER) -/mob/living/carbon/human/update_inv_head(var/update_icons=1) +/mob/living/carbon/human/update_inv_head() ..() remove_overlay(HEAD_LAYER) if(client && hud_used) @@ -818,7 +819,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[HEAD_LAYER] = standing apply_overlay(HEAD_LAYER) -/mob/living/carbon/human/update_inv_belt(var/update_icons=1) +/mob/living/carbon/human/update_inv_belt() remove_overlay(BELT_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt] @@ -844,7 +845,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(BELT_LAYER) -/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1) +/mob/living/carbon/human/update_inv_wear_suit() remove_overlay(SUIT_LAYER) if(client && hud_used) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit] @@ -885,8 +886,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[SUIT_LAYER] = standing apply_overlay(SUIT_LAYER) - update_tail_layer(0) - update_collar(0) + update_tail_layer() + update_collar() /mob/living/carbon/human/update_inv_pockets() if(client && hud_used) @@ -919,7 +920,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) client.screen += wear_pda wear_pda.screen_loc = ui_pda -/mob/living/carbon/human/update_inv_wear_mask(var/update_icons = 1) +/mob/living/carbon/human/update_inv_wear_mask() ..() remove_overlay(FACEMASK_LAYER) if(client && hud_used) @@ -955,7 +956,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(FACEMASK_LAYER) -/mob/living/carbon/human/update_inv_back(var/update_icons=1) +/mob/living/carbon/human/update_inv_back() ..() remove_overlay(BACK_LAYER) if(back) @@ -978,7 +979,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[BACK_LAYER] = standing apply_overlay(BACK_LAYER) -/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1) +/mob/living/carbon/human/update_inv_handcuffed() remove_overlay(HANDCUFF_LAYER) if(handcuffed) if(istype(handcuffed, /obj/item/restraints/handcuffs/pinkcuffs)) @@ -987,7 +988,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", layer = -HANDCUFF_LAYER) apply_overlay(HANDCUFF_LAYER) -/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1) +/mob/living/carbon/human/update_inv_legcuffed() remove_overlay(LEGCUFF_LAYER) clear_alert("legcuffed") if(legcuffed) @@ -1000,7 +1001,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(LEGCUFF_LAYER) -/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1) +/mob/living/carbon/human/update_inv_r_hand() ..() remove_overlay(R_HAND_LAYER) if(r_hand) @@ -1019,7 +1020,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(R_HAND_LAYER) -/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1) +/mob/living/carbon/human/update_inv_l_hand() ..() remove_overlay(L_HAND_LAYER) if(l_hand) @@ -1060,7 +1061,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) client.screen += I -/mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1) +/mob/living/carbon/human/proc/update_tail_layer() remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER. remove_overlay(TAIL_LAYER) /* This will be one of two things: If the species' tail is overlapped by limbs, this will be only the N direction icon so tails @@ -1135,7 +1136,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(TAIL_LAYER) apply_overlay(TAIL_UNDERLIMBS_LAYER) -/mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1) +/mob/living/carbon/human/proc/start_tail_wagging() remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER. remove_overlay(TAIL_LAYER) /* This will be one of two things: If the species' tail is overlapped by limbs, this will be only the N direction icon so tails @@ -1211,10 +1212,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) apply_overlay(TAIL_LAYER) apply_overlay(TAIL_UNDERLIMBS_LAYER) -/mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1) +/mob/living/carbon/human/proc/stop_tail_wagging() remove_overlay(TAIL_UNDERLIMBS_LAYER) remove_overlay(TAIL_LAYER) - update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites + update_tail_layer() //just trigger a full update for normal stationary sprites /mob/living/carbon/human/proc/update_int_organs() remove_overlay(INTORGAN_LAYER) @@ -1236,7 +1237,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //Adds a collar overlay above the helmet layer if the suit has one // Suit needs an identically named sprite in icons/mob/collar.dmi // For suits with sprite_sheets, an identically named sprite needs to exist in a file like this icons/mob/species/[species_name_here]/collar.dmi. -/mob/living/carbon/human/proc/update_collar(var/update_icons=1) +/mob/living/carbon/human/proc/update_collar() remove_overlay(COLLAR_LAYER) var/icon/C = new('icons/mob/collar.dmi') var/mutable_appearance/standing = null @@ -1282,7 +1283,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) /mob/living/carbon/human/proc/force_update_limbs() for(var/obj/item/organ/external/O in bodyparts) O.sync_colour_to_human(src) - update_body(0) + update_body() /mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers) var/list/out = new diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm index 14c87e13722..d5d1801e1a7 100644 --- a/code/modules/mob/living/carbon/human/update_stat.dm +++ b/code/modules/mob/living/carbon/human/update_stat.dm @@ -12,7 +12,7 @@ /mob/living/carbon/human/update_nearsighted_effects() var/obj/item/clothing/glasses/G = glasses - if((disabilities & NEARSIGHTED) && (!istype(G) || !G.prescription)) + if((NEARSIGHTED in mutations) && (!istype(G) || !G.prescription)) overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) else clear_fullscreen("nearsighted") diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 87832154876..d7754b32f43 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,25 +1,35 @@ /mob/living/carbon/Life(seconds, times_fired) set invisibility = 0 - set background = BACKGROUND_ENABLED if(notransform) return - if(!loc) + + if(damageoverlaytemp) + damageoverlaytemp = 0 + update_damage_hud() + + if(stat != DEAD) + handle_organs() + + . = ..() + + if(QDELETED(src)) return - if(..()) - . = 1 + if(.) //not dead handle_blood() - for(var/obj/item/organ/internal/O in internal_organs) - O.on_life() - handle_patches() - handle_changeling() + if(LAZYLEN(processing_patches)) + handle_patches() + if(mind) + handle_changeling() handle_wetness(times_fired) // Increase germ_level regularly - if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level - germ_level++ + handle_germs() + + if(stat != DEAD) + return TRUE /////////////// @@ -192,6 +202,11 @@ else update_action_buttons_icon() +/mob/living/carbon/proc/handle_organs() + for(var/thing in internal_organs) + var/obj/item/organ/internal/O = thing + O.on_life() + /mob/living/carbon/handle_diseases() for(var/thing in viruses) var/datum/disease/D = thing @@ -234,8 +249,7 @@ /mob/living/carbon/handle_chemicals_in_body() - if(reagents) - reagents.metabolize(src) + reagents.metabolize(src) /mob/living/carbon/proc/handle_wetness(times_fired) @@ -262,7 +276,9 @@ if(stam_regen_start_time <= world.time) if(stam_paralyzed) update_stamina() - setStaminaLoss(0, FALSE) + if(staminaloss) + setStaminaLoss(0, FALSE) + update_health_hud() var/restingpwr = 1 + 4 * resting @@ -322,6 +338,11 @@ /mob/living/carbon/handle_sleeping() if(..()) + if(mind?.vampire) + if(istype(loc, /obj/structure/closet/coffin)) + adjustBruteLoss(-1, FALSE) + adjustFireLoss(-1, FALSE) + adjustToxLoss(-1) handle_dreams() adjustStaminaLoss(-10) var/comfort = 1 @@ -337,44 +358,45 @@ comfort += 1 //Aren't naps SO much better when drunk? AdjustDrunk(-0.2*comfort) //reduce drunkenness while sleeping. if(comfort > 1 && prob(3))//You don't heal if you're just sleeping on the floor without a blanket. - adjustBruteLoss(-1*comfort) - adjustFireLoss(-1*comfort) + adjustBruteLoss(-1 * comfort, FALSE) + adjustFireLoss(-1 * comfort) if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT) emote("snore") + // Keep SSD people asleep if(player_logged) Sleeping(2) return sleeping -/mob/living/carbon/handle_hud_icons() - return - -/mob/living/carbon/handle_hud_icons_health() +/mob/living/carbon/update_health_hud(shown_health_amount) if(!client) return if(healths) if(stat != DEAD) - switch(health) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" + . = TRUE + if(shown_health_amount == null) + shown_health_amount = health + if(shown_health_amount >= maxHealth) + healths.icon_state = "health0" + else if(shown_health_amount > maxHealth * 0.8) + healths.icon_state = "health1" + else if(shown_health_amount > maxHealth * 0.6) + healths.icon_state = "health2" + else if(shown_health_amount > maxHealth * 0.4) + healths.icon_state = "health3" + else if(shown_health_amount > maxHealth * 0.2) + healths.icon_state = "health4" + else if(shown_health_amount > 0) + healths.icon_state = "health5" + else + healths.icon_state = "health6" else healths.icon_state = "health7" - handle_hud_icons_health_overlay() -/mob/living/carbon/proc/handle_hud_icons_health_overlay() +/mob/living/carbon/update_damage_hud() + if(!client) + return if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT) if(check_death_method()) var/severity = 0 @@ -441,20 +463,23 @@ clear_fullscreen("brute") /mob/living/carbon/proc/handle_patches() - if(LAZYLEN(processing_patches)) - var/multiple_patch_multiplier = processing_patches.len > 1 ? (processing_patches.len * 1.5) : 1 - var/applied_amount = 0.35 * multiple_patch_multiplier + var/multiple_patch_multiplier = processing_patches.len > 1 ? (processing_patches.len * 1.5) : 1 + var/applied_amount = 0.35 * multiple_patch_multiplier - for(var/patch in processing_patches) - var/obj/item/reagent_containers/food/pill/patch/P = patch + for(var/patch in processing_patches) + var/obj/item/reagent_containers/food/pill/patch/P = patch - if(P.reagents && P.reagents.total_volume) - var/fractional_applied_amount = applied_amount / P.reagents.total_volume - P.reagents.reaction(src, REAGENT_TOUCH, fractional_applied_amount, P.needs_to_apply_reagents) - P.needs_to_apply_reagents = FALSE - P.reagents.trans_to(src, applied_amount * 0.5) - P.reagents.remove_any(applied_amount * 0.5) - else - if(!P.reagents || P.reagents.total_volume <= 0) - processing_patches -= P - qdel(P) + if(P.reagents && P.reagents.total_volume) + var/fractional_applied_amount = applied_amount / P.reagents.total_volume + P.reagents.reaction(src, REAGENT_TOUCH, fractional_applied_amount, P.needs_to_apply_reagents) + P.needs_to_apply_reagents = FALSE + P.reagents.trans_to(src, applied_amount * 0.5) + P.reagents.remove_any(applied_amount * 0.5) + else + if(!P.reagents || P.reagents.total_volume <= 0) + processing_patches -= P + qdel(P) + +/mob/living/carbon/proc/handle_germs() + if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level + germ_level++ diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm index b67953c7e69..918968800ce 100644 --- a/code/modules/mob/living/carbon/update_status.dm +++ b/code/modules/mob/living/carbon/update_status.dm @@ -2,12 +2,10 @@ if(status_flags & GODMODE) return if(stat != DEAD) -// if(health <= min_health) if(health <= HEALTH_THRESHOLD_DEAD && check_death_method()) death() create_debug_log("died of damage, trigger reason: [reason]") return -// if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health) if(paralysis || sleeping || (check_death_method() && getOxyLoss() > 50) || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT && check_death_method()) if(stat == CONSCIOUS) KnockOut() @@ -16,6 +14,9 @@ if(stat == UNCONSCIOUS) WakeUp() create_debug_log("woke up, trigger reason: [reason]") + update_damage_hud() + update_health_hud() + med_hud_set_status() /mob/living/carbon/update_stamina() var/stam = getStaminaLoss() @@ -24,7 +25,6 @@ else if(stam_paralyzed) stam_paralyzed = FALSE update_canmove() - handle_hud_icons_health() /mob/living/carbon/can_hear() . = FALSE diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index fa1c392334d..60f186631b7 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -269,6 +269,7 @@ if(amount > 0) stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME if(updating) + update_health_hud() update_stamina() /mob/living/proc/setStaminaLoss(amount, updating = TRUE) @@ -284,6 +285,7 @@ if(amount > 0) stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME if(updating) + update_health_hud() update_stamina() /mob/living/proc/getMaxHealth() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 0984c56decb..6af90792355 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -61,10 +61,13 @@ if(mind && suiciding) mind.suicided = TRUE + reset_perspective(null) clear_fullscreens() update_sight() update_action_buttons_icon() + update_damage_hud() + update_health_hud() med_hud_set_health() med_hud_set_status() if(!gibbed && !QDELETED(src)) @@ -83,7 +86,7 @@ timeofdeath = world.time create_log(ATTACK_LOG, "died[gibbed ? " (Gibbed)": ""]") - GLOB.living_mob_list -= src + GLOB.alive_mob_list -= src GLOB.dead_mob_list += src if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 5ab604e5b3e..6d020ccdad1 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -1,12 +1,10 @@ -/mob/living/Life(seconds, times_fired) +/mob/living/proc/Life(seconds, times_fired) + set waitfor = FALSE set invisibility = 0 - set background = BACKGROUND_ENABLED - if(notransform) - return FALSE - if(!loc) - return FALSE - var/datum/gas_mixture/environment = loc.return_air() + if(flying) //TODO: Better floating + animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING) + animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING) if(client || registered_z) // This is a temporary error tracker to make sure we've caught everything var/turf/T = get_turf(src) @@ -17,28 +15,44 @@ else if (!client && registered_z) log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.") update_z(null) + + if(notransform) + return FALSE + if(!loc) + return FALSE + if(stat != DEAD) //Chemicals in the body - handle_chemicals_in_body() + if(reagents) + handle_chemicals_in_body() + if(QDELETED(src)) // some chems can gib mobs + return + + if(stat != DEAD) //Mutations and radiation handle_mutations_and_radiation() + if(stat != DEAD) //Breathing, if applicable handle_breathing(times_fired) + if(stat != DEAD) //Random events (vomiting etc) handle_random_events() - . = 1 + if(LAZYLEN(viruses)) + handle_diseases() - handle_diseases() + if(QDELETED(src)) // diseases can qdel the mob via transformations + return //Heart Attack, if applicable if(stat != DEAD) handle_heartattack() //Handle temperature/pressure differences between body and environment + var/datum/gas_mixture/environment = loc.return_air() if(environment) handle_environment(environment) @@ -49,19 +63,38 @@ update_gravity(mob_has_gravity()) - update_pulling() + if(pulling) + update_pulling() for(var/obj/item/grab/G in src) G.process() - if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc. + if(stat != DEAD) + handle_critical_condition() + + if(stat != DEAD) // Status & health update, are we dead or alive etc. handle_disabilities() // eye, ear, brain damages + + if(stat != DEAD) handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc - if(client) - handle_regular_hud_updates() + if(stat != DEAD) + if(forced_look) + if(!isnum(forced_look)) + var/atom/A = locateUID(forced_look) + if(istype(A)) + var/view = client ? client.view : world.view + if(get_dist(src, A) > view || !(src in viewers(view, A))) + forced_look = null + to_chat(src, "Your direction target has left your view, you are no longer facing anything.") + return + setDir() - ..() + if(machine) + machine.check_eye(src) + + if(stat != DEAD) + return TRUE /mob/living/proc/handle_breathing(times_fired) return @@ -71,7 +104,6 @@ /mob/living/proc/handle_mutations_and_radiation() radiation = 0 //so radiation don't accumulate in simple animals - return /mob/living/proc/handle_chemicals_in_body() return @@ -89,122 +121,54 @@ return /mob/living/proc/update_pulling() - if(pulling) - if(incapacitated()) - stop_pulling() - -//This updates the health and status of the mob (conscious, unconscious, dead) -/mob/living/proc/handle_regular_status_updates() - return stat != DEAD + if(incapacitated()) + stop_pulling() //this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc.. -/mob/living/proc/handle_status_effects() - handle_stunned() - handle_weakened() - handle_stuttering() - handle_silent() - handle_drugged() - handle_slurring() - handle_paralysed() - handle_sleeping() - handle_slowed() - handle_drunk() - handle_cultslurring() - - -/mob/living/proc/handle_stunned() +/mob/living/proc/handle_status_effects() // We check for the status effect in this proc as opposed to the procs below to avoid excessive proc call overhead if(stunned) AdjustStunned(-1, updating = 1, force = 1) - if(!stunned) - update_icons() - return stunned - -/mob/living/proc/handle_weakened() if(weakened) AdjustWeakened(-1, updating = 1, force = 1) - if(!weakened) - update_icons() - return weakened - -/mob/living/proc/handle_stuttering() if(stuttering) - stuttering = max(stuttering-1, 0) - return stuttering - -/mob/living/proc/handle_silent() + stuttering = max(stuttering - 1, 0) if(silent) AdjustSilence(-1) - return silent - -/mob/living/proc/handle_drugged() if(druggy) AdjustDruggy(-1) - return druggy - -/mob/living/proc/handle_slurring() if(slurring) AdjustSlur(-1) - return slurring - -/mob/living/proc/handle_cultslurring() - if(cultslurring) - AdjustCultSlur(-1) - return cultslurring - -/mob/living/proc/handle_paralysed() if(paralysis) AdjustParalysis(-1, updating = 1, force = 1) - return paralysis - -/mob/living/proc/handle_sleeping() if(sleeping) - AdjustSleeping(-1) - throw_alert("asleep", /obj/screen/alert/asleep) - else - clear_alert("asleep") - return sleeping - -/mob/living/proc/handle_slowed() + handle_sleeping() if(slowed) AdjustSlowed(-1) - return slowed + if(drunk) + handle_drunk() + if(cultslurring) + AdjustCultSlur(-1) + +/mob/living/proc/update_damage_hud() + return + +/mob/living/proc/handle_sleeping() + AdjustSleeping(-1) + return sleeping /mob/living/proc/handle_drunk() - if(drunk) - AdjustDrunk(-1) + AdjustDrunk(-1) return drunk /mob/living/proc/handle_disabilities() //Eyes - if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own + if((BLINDNESS in mutations) || stat) //blindness from disability or unconsciousness doesn't get better on its own EyeBlind(1) else if(eye_blind) //blindness, heals slowly over time AdjustEyeBlind(-1) else if(eye_blurry) //blurry eyes heal slowly AdjustEyeBlurry(-1) -//this handles hud updates. Calls update_vision() and handle_hud_icons() -/mob/living/proc/handle_regular_hud_updates() - if(!client) return 0 - - handle_vision() - handle_hud_icons() - - return 1 - -/mob/living/proc/handle_vision() - update_sight() - - if(stat == DEAD) - return - - if(machine) - if(!machine.check_eye(src)) - reset_perspective(null) - else - if(!remote_view && !client.adminobs) - reset_perspective(null) - // Gives a mob the vision of being dead /mob/living/proc/grant_death_vision() sight |= SEE_TURFS @@ -215,9 +179,37 @@ see_invisible = SEE_INVISIBLE_OBSERVER sync_lighting_plane_alpha() -/mob/living/proc/handle_hud_icons() - handle_hud_icons_health() +/mob/living/proc/handle_critical_condition() return -/mob/living/proc/handle_hud_icons_health() - return +/mob/living/update_health_hud() + if(!client) + return + if(healths) + var/severity = 0 + var/healthpercent = (health / maxHealth) * 100 + switch(healthpercent) + if(100 to INFINITY) + healths.icon_state = "health0" + if(80 to 100) + healths.icon_state = "health1" + severity = 1 + if(60 to 80) + healths.icon_state = "health2" + severity = 2 + if(40 to 60) + healths.icon_state = "health3" + severity = 3 + if(20 to 40) + healths.icon_state = "health4" + severity = 4 + if(1 to 20) + healths.icon_state = "health5" + severity = 5 + else + healths.icon_state = "health7" + severity = 6 + if(severity > 0) + overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity) + else + clear_fullscreen("brute") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8371cacaebe..dfa4bb61c9d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -3,6 +3,7 @@ var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] medhud.add_to_hud(src) faction += "\ref[src]" + GLOB.mob_living_list += src /mob/living/prepare_huds() ..() @@ -17,7 +18,7 @@ if(ranged_ability) ranged_ability.remove_ranged_ability(src) remove_from_all_data_huds() - + GLOB.mob_living_list -= src if(LAZYLEN(status_effects)) for(var/s in status_effects) var/datum/status_effect/S = s @@ -285,8 +286,9 @@ health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() update_stat("updatehealth([reason])") - handle_hud_icons_health() med_hud_set_health() + med_hud_set_status() + update_health_hud() //This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually @@ -759,7 +761,7 @@ //called when the mob receives a bright flash /mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash) - if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND))) + if(check_eye_prot() < intensity && (override_blindness_check || !(BLINDNESS in mutations))) overlay_fullscreen("flash", type) addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25) return 1 @@ -802,7 +804,7 @@ if(do_mob(src, who, what.put_on_delay)) if(what && Adjacent(who) && !(what.flags & NODROP)) unEquip(what) - who.equip_to_slot_if_possible(what, where, 0, 1) + who.equip_to_slot_if_possible(what, where, FALSE, TRUE) add_attack_logs(src, who, "Equipped [what]") /mob/living/singularity_act() @@ -1025,9 +1027,9 @@ if("stat") if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life GLOB.dead_mob_list -= src - GLOB.living_mob_list += src + GLOB.alive_mob_list += src if((stat < DEAD) && (var_value == DEAD))//Kill he - GLOB.living_mob_list -= src + GLOB.alive_mob_list -= src GLOB.dead_mob_list += src . = ..() switch(var_name) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 8d1555182a2..61151e35c92 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -37,7 +37,8 @@ else adjustOxyLoss(-1) - handle_stunned() + if(stunned) + AdjustStunned(-1, updating = 1, force = 1) var/area/my_area = get_area(src) @@ -140,7 +141,6 @@ else health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() update_stat("updatehealth([reason])") - diag_hud_set_status() diag_hud_set_health() diff --git a/code/modules/mob/living/silicon/ai/update_status.dm b/code/modules/mob/living/silicon/ai/update_status.dm index fd001956c67..8ee4a825631 100644 --- a/code/modules/mob/living/silicon/ai/update_status.dm +++ b/code/modules/mob/living/silicon/ai/update_status.dm @@ -9,7 +9,7 @@ else if(stat == UNCONSCIOUS) WakeUp() create_debug_log("woke up, trigger reason: [reason]") - //diag_hud_set_status() + diag_hud_set_status() /mob/living/silicon/ai/has_vision(information_only = FALSE) return ..() && !lacks_power() diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index d91b724370b..321362217a1 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -1,22 +1,18 @@ /mob/living/silicon/pai/Life(seconds, times_fired) . = ..() - if(.) - //if(secHUD == 1) - // process_sec_hud(src, 1) - ////if(medHUD == 1) - // process_med_hud(src, 1) - if(silence_time) - if(world.timeofday >= silence_time) - silence_time = null - to_chat(src, "Communication circuit reinitialized. Speech and messaging functionality restored.") + if(QDELETED(src) || stat == DEAD) + return + if(silence_time) + if(world.timeofday >= silence_time) + silence_time = null + to_chat(src, "Communication circuit reinitialized. Speech and messaging functionality restored.") - if(cable) - if(get_dist(src, cable) > 1) - var/turf/T = get_turf_or_move(loc) - for(var/mob/M in viewers(T)) - M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2) - qdel(src.cable) - cable = null + if(cable) + if(get_dist(src, cable) > 1) + var/turf/T = get_turf_or_move(loc) + for(var/mob/M in viewers(T)) + M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2) + QDEL_NULL(cable) /mob/living/silicon/pai/updatehealth(reason = "none given") if(status_flags & GODMODE) diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 224c706f324..72d9b210712 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -18,7 +18,7 @@ flick("gibbed-r", animation) robogibs(loc) - GLOB.living_mob_list -= src + GLOB.alive_mob_list -= src GLOB.dead_mob_list -= src QDEL_IN(animation, 15) QDEL_IN(src, 15) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index dc32deaf5a7..b181cec8ec0 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -18,6 +18,8 @@ magpulse = 1 mob_size = MOB_SIZE_SMALL + modules_break = FALSE + // We need to keep track of a few module items so we don't need to do list operations // every time we need them. These get set in New() after the module is chosen. var/obj/item/stack/sheet/metal/cyborg/stack_metal = null diff --git a/code/modules/mob/living/silicon/robot/drone/update_status.dm b/code/modules/mob/living/silicon/robot/drone/update_status.dm index 80eac952966..d64824b1876 100644 --- a/code/modules/mob/living/silicon/robot/drone/update_status.dm +++ b/code/modules/mob/living/silicon/robot/drone/update_status.dm @@ -4,7 +4,7 @@ /mob/living/silicon/robot/drone/update_stat(reason = "none given") if(status_flags & GODMODE) return - if(health <= -35 && stat != DEAD) + if(health <= -maxHealth && stat != DEAD) gib() create_debug_log("died of damage, trigger reason: [reason]") return diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index a68da651ee9..f5b7048c3a8 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -78,6 +78,7 @@ set_actions(O) else to_chat(src, "You need to disable a module first!") + check_module_damage(FALSE) update_icons() /mob/living/silicon/robot/proc/set_actions(obj/item/I) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d40e801ba5f..afdab2f5649 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -1,23 +1,20 @@ /mob/living/silicon/robot/Life(seconds, times_fired) set invisibility = 0 - set background = BACKGROUND_ENABLED - - if(src.notransform) + if(notransform) return - //Status updates, death etc. - clamp_values() + . = ..() - if(..()) + handle_equipment() + + // if Alive + if(.) + handle_robot_hud_updates() handle_robot_cell() process_locks() + update_items() process_queued_alarms() -/mob/living/silicon/robot/proc/clamp_values() - SetStunned(min(stunned, 30)) - SetParalysis(min(paralysis, 30)) - SetWeakened(min(weakened, 20)) - SetSleeping(0) /mob/living/silicon/robot/proc/handle_robot_cell() if(stat != DEAD) @@ -47,36 +44,13 @@ update_headlamp() diag_hud_set_borgcell() -/mob/living/silicon/robot/handle_regular_status_updates() - - . = ..() - +/mob/living/silicon/robot/proc/handle_equipment() if(camera && !scrambledcodes) if(stat == DEAD || wires.IsCameraCut()) camera.status = 0 else camera.status = 1 - if(sleeping) - AdjustSleeping(-1) - - if(.) //alive - if(!istype(src, /mob/living/silicon/robot/drone)) - if(health < 50) //Gradual break down of modules as more damage is sustained - if(uneq_module(module_state_3)) - to_chat(src, "SYSTEM ERROR: Module 3 OFFLINE.") - - if(health < 0) - if(uneq_module(module_state_2)) - to_chat(src, "SYSTEM ERROR: Module 2 OFFLINE.") - - if(health < -50) - if(uneq_module(module_state_1)) - to_chat(src, "CRITICAL ERROR: All modules OFFLINE.") - - diag_hud_set_health() - diag_hud_set_status() - //update the state of modules and components here if(stat != CONSCIOUS) uneq_all() @@ -86,18 +60,21 @@ else radio.on = 1 - return 1 - -/mob/living/silicon/robot/handle_hud_icons() - update_items() - update_cell() +/mob/living/silicon/robot/proc/SetEmagged(new_state) + emagged = new_state + update_icons() if(emagged) throw_alert("hacked", /obj/screen/alert/hacked) else clear_alert("hacked") - ..() -/mob/living/silicon/robot/handle_hud_icons_health() +/mob/living/silicon/robot/proc/handle_robot_hud_updates() + if(!client) + return + + update_cell_hud_icon() + +/mob/living/silicon/robot/update_health_hud() if(healths) if(stat != DEAD) if(health >= maxHealth) @@ -115,19 +92,7 @@ else healths.icon_state = "health7" - switch(bodytemperature) //310.055 optimal body temp - if(335 to INFINITY) - throw_alert("temp", /obj/screen/alert/hot/robot, 2) - if(320 to 335) - throw_alert("temp", /obj/screen/alert/hot/robot, 1) - if(300 to 320) - clear_alert("temp") - if(260 to 300) - throw_alert("temp", /obj/screen/alert/cold/robot, 1) - else - throw_alert("temp", /obj/screen/alert/cold/robot, 2) - -/mob/living/silicon/robot/proc/update_cell() +/mob/living/silicon/robot/proc/update_cell_hud_icon() if(cell) var/cellcharge = cell.charge/cell.maxcharge switch(cellcharge) @@ -146,7 +111,7 @@ -/mob/living/silicon/robot/proc/update_items() +/mob/living/silicon/robot/proc/update_items() // What in the Sam hell is this? if(client) for(var/obj/I in get_all_slots()) client.screen |= I diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index cf3067b934f..2eb1e4669ab 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -87,6 +87,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( var/braintype = "Cyborg" var/base_icon = "" var/crisis = 0 + var/modules_break = TRUE var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting. var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power. @@ -840,7 +841,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( return else sleep(6) - emagged = 1 + SetEmagged(TRUE) SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown if(src.hud_used) src.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. @@ -1157,16 +1158,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(cleaned_human.lying) if(cleaned_human.head) cleaned_human.head.clean_blood() - cleaned_human.update_inv_head(0,0) + cleaned_human.update_inv_head() if(cleaned_human.wear_suit) cleaned_human.wear_suit.clean_blood() - cleaned_human.update_inv_wear_suit(0,0) + cleaned_human.update_inv_wear_suit() else if(cleaned_human.w_uniform) cleaned_human.w_uniform.clean_blood() - cleaned_human.update_inv_w_uniform(0,0) + cleaned_human.update_inv_w_uniform() if(cleaned_human.shoes) cleaned_human.shoes.clean_blood() - cleaned_human.update_inv_shoes(0,0) + cleaned_human.update_inv_shoes() cleaned_human.clean_blood() to_chat(cleaned_human, "[src] cleans your face!") if(floor_only) @@ -1481,3 +1482,26 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( else uneq_active() // else unequip the module and put it back into the robot's inventory. return + +/mob/living/silicon/robot/proc/check_module_damage(makes_sound = TRUE) + if(modules_break) + if(health < 50) //Gradual break down of modules as more damage is sustained + if(uneq_module(module_state_3)) + if(makes_sound) + audible_message("[src] sounds an alarm! \"SYSTEM ERROR: Module 3 OFFLINE.\"") + playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, TRUE) + to_chat(src, "SYSTEM ERROR: Module 3 OFFLINE.") + + if(health < 0) + if(uneq_module(module_state_2)) + if(makes_sound) + audible_message("[src] sounds an alarm! \"SYSTEM ERROR: Module 2 OFFLINE.\"") + playsound(loc, 'sound/machines/warning-buzzer.ogg', 60, TRUE) + to_chat(src, "SYSTEM ERROR: Module 2 OFFLINE.") + + if(health < -50) + if(uneq_module(module_state_1)) + if(makes_sound) + audible_message("[src] sounds an alarm! \"CRITICAL ERROR: All modules OFFLINE.\"") + playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE) + to_chat(src, "CRITICAL ERROR: All modules OFFLINE.") diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm index c73d566b729..f4290d764d6 100644 --- a/code/modules/mob/living/silicon/robot/robot_damage.dm +++ b/code/modules/mob/living/silicon/robot/robot_damage.dm @@ -1,12 +1,6 @@ /mob/living/silicon/robot/updatehealth(reason = "none given") - if(status_flags & GODMODE) - health = maxHealth - stat = CONSCIOUS - return - health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss()) - update_stat("updatehealth([reason])") - handle_hud_icons_health() - diag_hud_set_health() + ..(reason) + check_module_damage() /mob/living/silicon/robot/getBruteLoss(repairable_only = FALSE) var/amount = 0 @@ -72,7 +66,7 @@ /mob/living/silicon/robot/heal_organ_damage(brute, burn, updating_health = TRUE) var/list/datum/robot_component/parts = get_damaged_components(brute, burn) - if(!LAZYLEN(parts)) + if(!LAZYLEN(parts)) return var/datum/robot_component/picked = pick(parts) picked.heal_damage(brute, burn, updating_health) diff --git a/code/modules/mob/living/silicon/robot/update_status.dm b/code/modules/mob/living/silicon/robot/update_status.dm index 5f1519395c7..91f9952c075 100644 --- a/code/modules/mob/living/silicon/robot/update_status.dm +++ b/code/modules/mob/living/silicon/robot/update_status.dm @@ -17,10 +17,12 @@ if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || paralysis || sleeping || resting || stunned || IsWeakened() || getOxyLoss() > maxHealth * 0.5) if(stat == CONSCIOUS) KnockOut() + update_headlamp() create_debug_log("fell unconscious, trigger reason: [reason]") else if(stat == UNCONSCIOUS) WakeUp() + update_headlamp() create_debug_log("woke up, trigger reason: [reason]") else if(health > 0) @@ -31,9 +33,10 @@ ghost << sound('sound/effects/genetics.ogg') create_attack_log("revived, trigger reason: [reason]") create_log(MISC_LOG, "revived, trigger reason: [reason]") - // diag_hud_set_status() - // diag_hud_set_health() - // update_health_hud() + + diag_hud_set_status() + diag_hud_set_health() + update_health_hud() /mob/living/silicon/robot/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" . = STATUS_UPDATE_CANMOVE diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 88d130ddc82..962b4722f39 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -1031,20 +1031,6 @@ Pass a positive integer as an argument to override a bot's default speed. Radio.talk_into(src, message, message_mode, verb, speaking) used_radios += Radio -/mob/living/simple_animal/bot/handle_hud_icons_health() - ..() - switch(bodytemperature) //310.055 optimal body temp - if(335 to INFINITY) - throw_alert("temp", /obj/screen/alert/hot/robot, 2) - if(320 to 335) - throw_alert("temp", /obj/screen/alert/hot/robot, 1) - if(300 to 320) - clear_alert("temp") - if(260 to 300) - throw_alert("temp", /obj/screen/alert/cold/robot, 1) - else - throw_alert("temp", /obj/screen/alert/cold/robot, 2) - /mob/living/simple_animal/bot/is_mechanical() return 1 diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index c89b160bf0e..728b050dd54 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -391,8 +391,6 @@ passenger = M load = M can_buckle = FALSE - // Not sure why this is done - reset_perspective(src) return TRUE return FALSE @@ -417,9 +415,6 @@ overlays.Cut() - if(ismob(load)) - var/mob/M = load - M.reset_perspective(null) unbuckle_all_mobs() if(load) @@ -446,9 +441,6 @@ AM.layer = initial(AM.layer) AM.pixel_y = initial(AM.pixel_y) AM.plane = initial(AM.plane) - if(ismob(AM)) - var/mob/M = AM - M.reset_perspective(null) /mob/living/simple_animal/bot/mulebot/call_bot() ..() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index ee03c204d48..f150005116e 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -333,73 +333,116 @@ ///ui stuff -/mob/living/simple_animal/hostile/construct/armoured/handle_hud_icons_health() - ..() +/mob/living/simple_animal/hostile/construct/armoured/update_health_hud() + if(!client) + return if(healths) switch(health) - if(250 to INFINITY) healths.icon_state = "juggernaut_health0" - if(208 to 249) healths.icon_state = "juggernaut_health1" - if(167 to 207) healths.icon_state = "juggernaut_health2" - if(125 to 166) healths.icon_state = "juggernaut_health3" - if(84 to 124) healths.icon_state = "juggernaut_health4" - if(42 to 83) healths.icon_state = "juggernaut_health5" - if(1 to 41) healths.icon_state = "juggernaut_health6" - else healths.icon_state = "juggernaut_health7" + if(250 to INFINITY) + healths.icon_state = "juggernaut_health0" + if(208 to 249) + healths.icon_state = "juggernaut_health1" + if(167 to 207) + healths.icon_state = "juggernaut_health2" + if(125 to 166) + healths.icon_state = "juggernaut_health3" + if(84 to 124) + healths.icon_state = "juggernaut_health4" + if(42 to 83) + healths.icon_state = "juggernaut_health5" + if(1 to 41) + healths.icon_state = "juggernaut_health6" + else + healths.icon_state = "juggernaut_health7" -/mob/living/simple_animal/hostile/construct/behemoth/handle_hud_icons_health() - ..() +/mob/living/simple_animal/hostile/construct/behemoth/update_health_hud() + if(!client) + return if(healths) switch(health) - if(750 to INFINITY) healths.icon_state = "juggernaut_health0" - if(625 to 749) healths.icon_state = "juggernaut_health1" - if(500 to 624) healths.icon_state = "juggernaut_health2" - if(375 to 499) healths.icon_state = "juggernaut_health3" - if(250 to 374) healths.icon_state = "juggernaut_health4" - if(125 to 249) healths.icon_state = "juggernaut_health5" - if(1 to 124) healths.icon_state = "juggernaut_health6" - else healths.icon_state = "juggernaut_health7" + if(750 to INFINITY) + healths.icon_state = "juggernaut_health0" + if(625 to 749) + healths.icon_state = "juggernaut_health1" + if(500 to 624) + healths.icon_state = "juggernaut_health2" + if(375 to 499) + healths.icon_state = "juggernaut_health3" + if(250 to 374) + healths.icon_state = "juggernaut_health4" + if(125 to 249) + healths.icon_state = "juggernaut_health5" + if(1 to 124) + healths.icon_state = "juggernaut_health6" + else + healths.icon_state = "juggernaut_health7" -/mob/living/simple_animal/hostile/construct/builder/handle_hud_icons_health() - ..() +/mob/living/simple_animal/hostile/construct/builder/update_health_hud() + if(!client) + return if(healths) switch(health) - if(50 to INFINITY) healths.icon_state = "artificer_health0" - if(42 to 49) healths.icon_state = "artificer_health1" - if(34 to 41) healths.icon_state = "artificer_health2" - if(26 to 33) healths.icon_state = "artificer_health3" - if(18 to 25) healths.icon_state = "artificer_health4" - if(10 to 17) healths.icon_state = "artificer_health5" - if(1 to 9) healths.icon_state = "artificer_health6" - else healths.icon_state = "artificer_health7" + if(50 to INFINITY) + healths.icon_state = "artificer_health0" + if(42 to 49) + healths.icon_state = "artificer_health1" + if(34 to 41) + healths.icon_state = "artificer_health2" + if(26 to 33) + healths.icon_state = "artificer_health3" + if(18 to 25) + healths.icon_state = "artificer_health4" + if(10 to 17) + healths.icon_state = "artificer_health5" + if(1 to 9) + healths.icon_state = "artificer_health6" + else + healths.icon_state = "artificer_health7" -/mob/living/simple_animal/hostile/construct/wraith/handle_hud_icons_health() - - ..() +/mob/living/simple_animal/hostile/construct/wraith/update_health_hud() + if(!client) + return if(healths) switch(health) - if(75 to INFINITY) healths.icon_state = "wraith_health0" - if(62 to 74) healths.icon_state = "wraith_health1" - if(50 to 61) healths.icon_state = "wraith_health2" - if(37 to 49) healths.icon_state = "wraith_health3" - if(25 to 36) healths.icon_state = "wraith_health4" - if(12 to 24) healths.icon_state = "wraith_health5" - if(1 to 11) healths.icon_state = "wraith_health6" - else healths.icon_state = "wraith_health7" + if(75 to INFINITY) + healths.icon_state = "wraith_health0" + if(62 to 74) + healths.icon_state = "wraith_health1" + if(50 to 61) + healths.icon_state = "wraith_health2" + if(37 to 49) + healths.icon_state = "wraith_health3" + if(25 to 36) + healths.icon_state = "wraith_health4" + if(12 to 24) + healths.icon_state = "wraith_health5" + if(1 to 11) + healths.icon_state = "wraith_health6" + else + healths.icon_state = "wraith_health7" -/mob/living/simple_animal/hostile/construct/harvester/handle_hud_icons_health() - - ..() +/mob/living/simple_animal/hostile/construct/harvester/update_health_hud() + if(!client) + return if(healths) switch(health) - if(150 to INFINITY) healths.icon_state = "harvester_health0" - if(125 to 149) healths.icon_state = "harvester_health1" - if(100 to 124) healths.icon_state = "harvester_health2" - if(75 to 99) healths.icon_state = "harvester_health3" - if(50 to 74) healths.icon_state = "harvester_health4" - if(25 to 49) healths.icon_state = "harvester_health5" - if(1 to 24) healths.icon_state = "harvester_health6" - else healths.icon_state = "harvester_health7" + if(150 to INFINITY) + healths.icon_state = "harvester_health0" + if(125 to 149) + healths.icon_state = "harvester_health1" + if(100 to 124) + healths.icon_state = "harvester_health2" + if(75 to 99) + healths.icon_state = "harvester_health3" + if(50 to 74) + healths.icon_state = "harvester_health4" + if(25 to 49) + healths.icon_state = "harvester_health5" + if(1 to 24) + healths.icon_state = "harvester_health6" + else + healths.icon_state = "harvester_health7" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 6cde07d0b8d..c9139ea7bfd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -79,7 +79,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload) . = ..() if(true_spawn) - for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.alive_mob_list) if(B != src) qdel(src) //There can be only one return diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 95ce5491395..105b9a02819 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -180,7 +180,7 @@ range = 10 /obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr) - for(var/mob/living/L in GLOB.living_mob_list) + for(var/mob/living/L in GLOB.alive_mob_list) if(L == user) continue var/turf/T = get_turf(L.loc) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index f3389108498..23970e88826 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -281,7 +281,7 @@ /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/LateInitialize() if(istype(depotarea)) var/list/key_candidates = list() - for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in GLOB.living_mob_list) + for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in GLOB.alive_mob_list) key_candidates += O if(key_candidates.len) var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O = pick(key_candidates) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2479f3c0674..ada8ed9896b 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -145,7 +145,7 @@ /mob/living/simple_animal/updatehealth(reason = "none given") ..(reason) health = Clamp(health, 0, maxHealth) - med_hud_set_status() + med_hud_set_health() /mob/living/simple_animal/StartResting(updating = 1) ..() @@ -166,12 +166,14 @@ /mob/living/simple_animal/update_stat(reason = "none given") if(status_flags & GODMODE) return - - ..(reason) if(stat != DEAD) - if(health < 1) + if(health <= 0) death() create_debug_log("died of damage, trigger reason: [reason]") + else + WakeUp() + create_debug_log("woke up, trigger reason: [reason]") + med_hud_set_status() /mob/living/simple_animal/proc/handle_automated_action() set waitfor = FALSE diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 91e6c502869..8c7d14b23f4 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -156,7 +156,7 @@ . += config.slime_delay -/mob/living/simple_animal/slime/handle_hud_icons_health() +/mob/living/simple_animal/slime/update_health_hud() if(hud_used) if(!client) return diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm index 926bdc5970d..eab88b5ec4d 100644 --- a/code/modules/mob/living/stat_states.dm +++ b/code/modules/mob/living/stat_states.dm @@ -51,7 +51,7 @@ log_game("[key_name(src)] came back to life at [atom_loc_line(get_turf(src))]") stat = CONSCIOUS GLOB.dead_mob_list -= src - GLOB.living_mob_list += src + GLOB.alive_mob_list += src if(mind) GLOB.respawnable_list -= src timeofdeath = null diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index b2871038155..7cd2b4414f7 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -125,10 +125,6 @@ var/stuttering = 0 var/weakened = 0 -/mob/living - // Bitfields - var/disabilities = 0 - // RESTING /mob/living/proc/StartResting(updating = 1) @@ -467,16 +463,16 @@ // Blind /mob/living/proc/BecomeBlind(updating = TRUE) - var/val_change = !(disabilities & BLIND) + var/val_change = !(BLINDNESS in mutations) . = val_change ? STATUS_UPDATE_BLIND : STATUS_UPDATE_NONE - disabilities |= BLIND + mutations |= BLINDNESS if(val_change && updating) update_blind_effects() /mob/living/proc/CureBlind(updating = TRUE) - var/val_change = !!(disabilities & BLIND) + var/val_change = !!(BLINDNESS in mutations) . = val_change ? STATUS_UPDATE_BLIND : STATUS_UPDATE_NONE - disabilities &= ~BLIND + mutations -= BLINDNESS if(val_change && updating) CureIfHasDisability(GLOB.blindblock) update_blind_effects() @@ -484,52 +480,52 @@ // Coughing /mob/living/proc/BecomeCoughing() - disabilities |= COUGHING + mutations |= COUGHING /mob/living/proc/CureCoughing() - disabilities &= ~COUGHING + mutations -= COUGHING CureIfHasDisability(GLOB.coughblock) // Deaf /mob/living/proc/BecomeDeaf() - disabilities |= DEAF + mutations |= DEAF /mob/living/proc/CureDeaf() - disabilities &= ~DEAF + mutations -= DEAF CureIfHasDisability(GLOB.deafblock) // Epilepsy /mob/living/proc/BecomeEpilepsy() - disabilities |= EPILEPSY + mutations |= EPILEPSY /mob/living/proc/CureEpilepsy() - disabilities &= ~EPILEPSY + mutations -= EPILEPSY CureIfHasDisability(GLOB.epilepsyblock) // Mute /mob/living/proc/BecomeMute() - disabilities |= MUTE + mutations |= MUTE /mob/living/proc/CureMute() - disabilities &= ~MUTE + mutations -= MUTE CureIfHasDisability(GLOB.muteblock) // Nearsighted /mob/living/proc/BecomeNearsighted(updating = TRUE) - var/val_change = !(disabilities & NEARSIGHTED) + var/val_change = !(NEARSIGHTED in mutations) . = val_change ? STATUS_UPDATE_NEARSIGHTED : STATUS_UPDATE_NONE - disabilities |= NEARSIGHTED + mutations |= NEARSIGHTED if(val_change && updating) update_nearsighted_effects() /mob/living/proc/CureNearsighted(updating = TRUE) - var/val_change = !!(disabilities & NEARSIGHTED) + var/val_change = !!(NEARSIGHTED in mutations) . = val_change ? STATUS_UPDATE_NEARSIGHTED : STATUS_UPDATE_NONE - disabilities &= ~NEARSIGHTED + mutations -= NEARSIGHTED if(val_change && updating) CureIfHasDisability(GLOB.glassesblock) update_nearsighted_effects() @@ -537,19 +533,19 @@ // Nervous /mob/living/proc/BecomeNervous() - disabilities |= NERVOUS + mutations |= NERVOUS /mob/living/proc/CureNervous() - disabilities &= ~NERVOUS + mutations -= NERVOUS CureIfHasDisability(GLOB.nervousblock) // Tourettes /mob/living/proc/BecomeTourettes() - disabilities |= TOURETTES + mutations |= TOURETTES /mob/living/proc/CureTourettes() - disabilities &= ~TOURETTES + mutations -= TOURETTES CureIfHasDisability(GLOB.twitchblock) /mob/living/proc/CureIfHasDisability(block) diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index d24301b0dd0..8ef178918b4 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -25,7 +25,7 @@ clear_alert("high") /mob/living/update_nearsighted_effects() - if(disabilities & NEARSIGHTED) + if(NEARSIGHTED in mutations) overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) else clear_fullscreen("nearsighted") @@ -41,17 +41,17 @@ // Whether the mob can hear things /mob/living/can_hear() - . = !(disabilities & DEAF) + . = !(DEAF in mutations) // Whether the mob is able to see // `information_only` is for stuff that's purely informational - like blindness overlays // This flag exists because certain things like angel statues expect this to be false for dead people /mob/living/has_vision(information_only = FALSE) - return (information_only && stat == DEAD) || !(eye_blind || (disabilities & BLIND) || stat) + return (information_only && stat == DEAD) || !(eye_blind || (BLINDNESS in mutations) || stat) // Whether the mob is capable of talking /mob/living/can_speak() - if(!(silent || (disabilities & MUTE))) + if(!(silent || (MUTE in mutations))) if(is_muzzled()) var/obj/item/clothing/mask/muzzle/M = wear_mask if(M.mute >= MUZZLE_MUTE_MUFFLE) @@ -112,22 +112,6 @@ /mob/living/proc/update_stamina() return -/mob/living/update_stat(reason = "None given") - if(status_flags & GODMODE) - return - if(stat != DEAD) - if(health <= HEALTH_THRESHOLD_DEAD && check_death_method()) - death() - create_debug_log("died of damage, trigger reason: [reason]") - else if(paralysis || status_flags & FAKEDEATH) - if(stat == CONSCIOUS) - KnockOut() - create_debug_log("fell unconscious, trigger reason: [reason]") - else - if(stat == UNCONSCIOUS) - WakeUp() - create_debug_log("woke up, trigger reason: [reason]") - /mob/living/vv_edit_var(var_name, var_value) . = ..() switch(var_name) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 6123c8429c5..235996e571f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,7 +1,7 @@ /mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. GLOB.mob_list -= src GLOB.dead_mob_list -= src - GLOB.living_mob_list -= src + GLOB.alive_mob_list -= src focus = null QDEL_NULL(hud_used) if(mind && mind.current == src) @@ -9,9 +9,6 @@ mobspellremove(src) QDEL_LIST(viruses) ghostize() - for(var/mob/dead/observer/M in following_mobs) - M.following = null - following_mobs = null QDEL_LIST_ASSOC_VAL(tkgrabbed_objects) for(var/I in tkgrabbed_objects) qdel(tkgrabbed_objects[I]) @@ -31,7 +28,7 @@ if(stat == DEAD) GLOB.dead_mob_list += src else - GLOB.living_mob_list += src + GLOB.alive_mob_list += src set_focus(src) prepare_huds() ..() @@ -174,21 +171,6 @@ /mob/proc/movement_delay() return 0 -/mob/proc/Life(seconds, times_fired) - set waitfor = FALSE - if(forced_look) - if(!isnum(forced_look)) - var/atom/A = locateUID(forced_look) - if(istype(A)) - var/view = client ? client.view : world.view - if(get_dist(src, A) > view || !(src in viewers(view, A))) - forced_look = null - to_chat(src, "Your direction target has left your view, you are no longer facing anything.") - return - setDir() -// handle_typing_indicator() - return - //This proc is called whenever someone clicks an inventory ui slot. /mob/proc/attack_ui(slot) var/obj/item/W = get_active_hand() @@ -204,10 +186,10 @@ src:update_hair() src:update_fhair() -/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1) - if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob)) +/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1) + if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning)) return 1 - else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob)) + else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning)) return 1 return 0 @@ -216,8 +198,7 @@ //This is a SAFE proc. Use this instead of equip_to_slot()! //set del_on_fail to have it delete W if it fails to equip //set disable_warning to disable the 'you are unable to equip that' warning. -//unset redraw_mob to prevent the mob from being redrawn at the end. -/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1) +/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, del_on_fail = 0, disable_warning = 0) if(!istype(W)) return 0 if(!W.mob_can_equip(src, slot, disable_warning)) @@ -229,17 +210,17 @@ return 0 - equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. + equip_to_slot(W, slot) //This proc should not ever fail. return 1 //This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. //In most cases you will want to use equip_to_slot_if_possible() -/mob/proc/equip_to_slot(obj/item/W as obj, slot) +/mob/proc/equip_to_slot(obj/item/W, slot) return //This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. /mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot) - return equip_to_slot_if_possible(W, slot, 1, 1, 0) + return equip_to_slot_if_possible(W, slot, TRUE, TRUE) // Convinience proc. Collects crap that fails to equip either onto the mob's back, or drops it. // Used in job equipping so shit doesn't pile up at the start loc. @@ -290,7 +271,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ for(var/slot in GLOB.slot_equipment_priority) if(istype(W,/obj/item/storage/) && slot == slot_head) // Storage items should be put on the belt before the head continue - if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //del_on_fail = 0; disable_warning = 0; redraw_mob = 1 + if(equip_to_slot_if_possible(W, slot, FALSE, TRUE)) //del_on_fail = 0; disable_warning = 0 return 1 return 0 @@ -527,12 +508,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ update_pipe_vision() /mob/dead/reset_perspective(atom/A) - if(client) - if(ismob(client.eye) && (client.eye != src)) - // Note to self: Use `client.eye` for ghost following in place - // of periodic ghost updates - var/mob/target = client.eye - target.following_mobs -= src . = ..() if(.) // Allows sharing HUDs with ghosts @@ -839,10 +814,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ if(client && mob_eye) client.eye = mob_eye - if(is_admin) - client.adminobs = 1 - if(mob_eye == client.mob || client.eye == client.mob) - client.adminobs = 0 /mob/verb/cancel_camera() set name = "Cancel Camera View" @@ -1092,7 +1063,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ if((usr in GLOB.respawnable_list) && (stat==2 || istype(usr,/mob/dead/observer))) var/list/creatures = list("Mouse") - for(var/mob/living/L in GLOB.living_mob_list) + for(var/mob/living/L in GLOB.alive_mob_list) if(safe_respawn(L.type) && L.stat!=2) if(!L.key) creatures += L diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index ee514930c95..dc77610b97e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -160,8 +160,6 @@ var/atom/movable/remote_control //Calls relaymove() to whatever it is - var/remote_view = 0 // Set to 1 to prevent view resets on Life - var/obj/control_object //Used by admins to possess objects. All mobs should have this var //Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything. diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 1e0f31ac6fe..df2a39c0930 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -521,11 +521,11 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM alert_overlay.plane = FLOAT_PLANE A.overlays += alert_overlay -/mob/proc/switch_to_camera(var/obj/machinery/camera/C) - if(!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || !has_vision() || !canmove)) - return 0 +/mob/proc/switch_to_camera(obj/machinery/camera/C) + if(!C.can_use() || incapacitated() || (get_dist(C, src) > 1 || machine != src || !has_vision())) + return FALSE check_eye(src) - return 1 + return TRUE /mob/proc/rename_character(oldname, newname) if(!newname) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 69e27595a07..af3d439df59 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -392,7 +392,7 @@ /mob/new_player/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message) if(SSticker.current_state == GAME_STATE_PLAYING) var/ailist[] = list() - for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list) ailist += A if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) @@ -424,7 +424,7 @@ /mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message) if(SSticker.current_state == GAME_STATE_PLAYING) var/ailist[] = list() - for(var/mob/living/silicon/ai/A in GLOB.living_mob_list) + for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list) ailist += A if(ailist.len) var/mob/living/silicon/ai/announcer = pick(ailist) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 880d9c167d6..77f8cc40da9 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -921,7 +921,7 @@ if(4) clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY) - if(disabilities & NEARSIGHTED) + if(disabilities & DISABILITY_FLAG_NEARSIGHTED) preview_icon.Blend(new /icon('icons/mob/eyes.dmi', "glasses"), ICON_OVERLAY) // Observers get tourist outfit. diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index 7b13ab68229..4dfbddc2d84 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -15,7 +15,7 @@ GLOBAL_DATUM(typing_indicator, /image) if(ishuman(src)) var/mob/living/carbon/human/H = src - if(H.disabilities & MUTE || H.silent) + if((MUTE in H.mutations) || H.silent) overlays -= GLOB.typing_indicator return diff --git a/code/modules/modular_computers/file_system/programs/research/airestorer.dm b/code/modules/modular_computers/file_system/programs/research/airestorer.dm index d5ff31af66b..a87a2cd87b4 100644 --- a/code/modules/modular_computers/file_system/programs/research/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/research/airestorer.dm @@ -78,7 +78,7 @@ A.stat = CONSCIOUS A.lying = 0 GLOB.dead_mob_list -= A - GLOB.living_mob_list += A + GLOB.alive_mob_list += A // Finished restoring if(A.health >= 100) ai_slot.locked = FALSE diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm index cf694e59d83..741f0399922 100644 --- a/code/modules/ninja/energy_katana.dm +++ b/code/modules/ninja/energy_katana.dm @@ -52,7 +52,7 @@ if(user.put_in_hands(src)) msg = "Your Energy Katana teleports into your hand!" - else if(user.equip_to_slot_if_possible(src, slot_belt, 0, 1, 1)) + else if(user.equip_to_slot_if_possible(src, slot_belt, FALSE, TRUE)) msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!
" else loc = get_turf(user) diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 7fac0e3386a..aa2a033f130 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -72,7 +72,7 @@ update_icon() else if(is_hot(P)) - if(user.disabilities & CLUMSY && prob(10)) + if((CLUMSY in user.mutations) && prob(10)) user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ "You miss [src] and accidentally light yourself on fire!") user.unEquip(P) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index cf3a16432c0..74acdf618d0 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -93,7 +93,7 @@ /obj/singularity/narsie/proc/pickcultist() //Narsie rewards his cultists with being devoured first, then picks a ghost to follow. --NEO var/list/cultists = list() var/list/noncultists = list() - for(var/mob/living/carbon/food in GLOB.living_mob_list) //we don't care about constructs or cult-Ians or whatever. cult-monkeys are fair game i guess + for(var/mob/living/carbon/food in GLOB.alive_mob_list) //we don't care about constructs or cult-Ians or whatever. cult-monkeys are fair game i guess var/turf/pos = get_turf(food) if(pos.z != src.z) continue diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index f8c23a696fa..7e1d4f59267 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -183,7 +183,7 @@ if(damage > explosion_point) if(get_turf(src)) var/turf/position = get_turf(src) - for(var/mob/living/mob in GLOB.living_mob_list) + for(var/mob/living/mob in GLOB.alive_mob_list) var/turf/mob_pos = get_turf(mob) if(mob_pos && mob_pos.z == position.z) if(ishuman(mob)) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index d18c9c1832b..5a0069632a2 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -331,6 +331,7 @@ M.update_canmove() if(update_flags & STATUS_UPDATE_STAMINA) M.update_stamina() + M.update_health_hud() if(update_flags & STATUS_UPDATE_BLIND) M.update_blind_effects() if(update_flags & STATUS_UPDATE_BLURRY) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 8cdb69062ff..f3b4181062e 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -203,9 +203,7 @@ return M.emote("deathgasp") M.status_flags |= FAKEDEATH - M.update_stat("fakedeath reagent") - M.med_hud_set_health() - M.med_hud_set_status() + M.updatehealth("fakedeath reagent") /datum/reagent/proc/fakerevive(mob/living/M) if(!(M.status_flags & FAKEDEATH)) @@ -215,10 +213,6 @@ if(M.resting) M.StopResting() M.status_flags &= ~(FAKEDEATH) - M.update_stat("fakedeath reagent end") - M.med_hud_set_status() - M.med_hud_set_health() if(M.healthdoll) M.healthdoll.cached_healthdoll_overlays.Cut() - if(M.dna.species) - M.dna.species.handle_hud_icons(M) + M.updatehealth("fakedeath reagent end") diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 262acae5f82..4a1f9213267 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -790,7 +790,7 @@ ..() return M.SetJitter(0) - var/needs_update = M.mutations.len > 0 || M.disabilities > 0 + var/needs_update = M.mutations.len > 0 if(needs_update) for(var/block = 1; block<=DNA_SE_LENGTH; block++) diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index c6960aac916..f975cac7293 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -96,21 +96,21 @@ C.l_hand.clean_blood() if(C.wear_mask) if(C.wear_mask.clean_blood()) - C.update_inv_wear_mask(0) + C.update_inv_wear_mask() if(ishuman(M)) var/mob/living/carbon/human/H = C if(H.head) if(H.head.clean_blood()) - H.update_inv_head(0,0) + H.update_inv_head() if(H.wear_suit) if(H.wear_suit.clean_blood()) - H.update_inv_wear_suit(0,0) + H.update_inv_wear_suit() else if(H.w_uniform) if(H.w_uniform.clean_blood()) - H.update_inv_w_uniform(0,0) + H.update_inv_w_uniform() if(H.shoes) if(H.shoes.clean_blood()) - H.update_inv_shoes(0,0) + H.update_inv_shoes() M.clean_blood() ..() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index e16ce4a0824..001bb1c98f4 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -330,7 +330,7 @@ // eject the contents of the disposal unit /obj/machinery/disposal/proc/eject() for(var/atom/movable/AM in src) - AM.loc = src.loc + AM.forceMove(loc) AM.pipe_eject(0) update() @@ -471,7 +471,7 @@ for(var/atom/movable/AM in H) target = get_offset_target_turf(src.loc, rand(5)-rand(5), rand(5)-rand(5)) - AM.loc = src.loc + AM.forceMove(loc) AM.pipe_eject(0) if(!istype(AM, /mob/living/silicon/robot/drone) && !istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z spawn(1) @@ -487,7 +487,7 @@ if(istype(I, /obj/item/projectile)) return if(prob(75)) - I.loc = src + I.forceMove(src) for(var/mob/M in viewers(src)) M.show_message("\the [I] lands in \the [src].", 3) update() @@ -550,7 +550,7 @@ // now everything inside the disposal gets put into the holder // note AM since can contain mobs or objs for(var/atom/movable/AM in D) - AM.loc = src + AM.forceMove(src) SEND_SIGNAL(AM, COMSIG_MOVABLE_DISPOSING, src, D) if(istype(AM, /mob/living/carbon/human)) var/mob/living/carbon/human/H = AM @@ -639,11 +639,10 @@ // used when a a holder meets a stuck holder /obj/structure/disposalholder/proc/merge(var/obj/structure/disposalholder/other) for(var/atom/movable/AM in other) - AM.loc = src // move everything in other holder to this one + AM.forceMove(src) // move everything in other holder to this one if(ismob(AM)) var/mob/M = AM - if(M.client) // if a client mob, update eye to follow this holder - M.client.eye = src + M.reset_perspective(src) // if a client mob, update eye to follow this holder if(other.has_fat_guy) has_fat_guy = 1 @@ -712,7 +711,7 @@ // this is unlikely, but just dump out everything into the turf in case for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) qdel(H) ..() @@ -807,7 +806,7 @@ playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) if(H) for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(direction) spawn(1) if(AM) @@ -822,7 +821,7 @@ for(var/atom/movable/AM in H) target = get_offset_target_turf(T, rand(5)-rand(5), rand(5)-rand(5)) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) spawn(1) if(AM) @@ -853,7 +852,7 @@ // this is unlikely, but just dump out everything into the turf in case for(var/atom/movable/AM in H) - AM.loc = T + AM.forceMove(T) AM.pipe_eject(0) qdel(H) return @@ -1361,10 +1360,6 @@ /atom/movable/proc/pipe_eject(var/direction) return -// check if mob has client, if so restore client view on eject -/mob/pipe_eject(var/direction) - reset_perspective(null) - /obj/effect/decal/cleanable/blood/gibs/pipe_eject(var/direction) var/list/dirs if(direction) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 403df48be69..ecf6b9887fc 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -25,7 +25,7 @@ /obj/structure/bigDelivery/attack_hand(mob/user as mob) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) if(wrapped) - wrapped.loc = get_turf(src) + wrapped.forceMove(get_turf(src)) if(istype(wrapped, /obj/structure/closet)) var/obj/structure/closet/O = wrapped O.welded = init_welded diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 3951cf23312..95cee124076 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -89,8 +89,8 @@ component_parts += new /obj/item/stock_parts/micro_laser(src) component_parts += new /obj/item/stock_parts/micro_laser(src) spawn(1) - trackedIan = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_list - trackedRuntime = locate(/mob/living/simple_animal/pet/cat/Runtime) in GLOB.mob_list + trackedIan = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list + trackedRuntime = locate(/mob/living/simple_animal/pet/cat/Runtime) in GLOB.mob_living_list SetTypeReactions() RefreshParts() diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 02b788eb7a5..bc57338dbbe 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -19,7 +19,7 @@ return var/mob/living/carbon/C = owner // genetic deafness prevents the body from using the ears, even if healthy - if(C.disabilities & DEAF) + if(DEAF in C.mutations) deaf = max(deaf, 1) else if(ishuman(C)) @@ -37,7 +37,7 @@ ear_damage = 0 var/mob/living/carbon/C = owner - if(istype(C) && C.disabilities & DEAF) + if(istype(C) && (DEAF in C.mutations)) deaf = 1 /obj/item/organ/internal/ears/proc/AdjustEarDamage(ddmg, ddeaf) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index e2b70207532..1b205f957ce 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -9,7 +9,7 @@ var/list/colourmatrix = null var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white. var/list/replace_colours = LIST_GREYSCALE_REPLACE - var/dependent_disabilities = null //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. + var/dependent_disabilities = list() //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. var/weld_proof = null //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will. var/vision_flags = 0 @@ -30,7 +30,7 @@ return eyes_icon /obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. - if(!is_robotic() && owner.disabilities & COLOURBLIND) + if(!is_robotic() && (COLOURBLIND in owner.mutations)) return colourblind_matrix else return colourmatrix @@ -44,16 +44,16 @@ if(istype(M) && eye_colour) M.update_body() //Apply our eye colour to the target. - if(!(M.disabilities & COLOURBLIND) && (dependent_disabilities & COLOURBLIND)) //If the eyes are colourblind and we're not, carry over the gene. - dependent_disabilities &= ~COLOURBLIND + if(!(COLOURBLIND in M.mutations) && (COLOURBLIND in dependent_disabilities)) //If the eyes are colourblind and we're not, carry over the gene. + dependent_disabilities -= COLOURBLIND M.dna.SetSEState(GLOB.colourblindblock,1) genemutcheck(M,GLOB.colourblindblock,null,MUTCHK_FORCED) else M.update_client_colour() //If we're here, that means the mob acquired the colourblindness gene while they didn't have eyes. Better handle it. /obj/item/organ/internal/eyes/remove(mob/living/carbon/human/M, special = 0) - if(!special && (M.disabilities & COLOURBLIND)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) - if(!(dependent_disabilities & COLOURBLIND)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. + if(!special && (COLOURBLIND in M.mutations)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) + if(!(COLOURBLIND in dependent_disabilities)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. dependent_disabilities |= COLOURBLIND M.dna.SetSEState(GLOB.colourblindblock,0) genemutcheck(M,GLOB.colourblindblock,null,MUTCHK_FORCED) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 1813a73cee1..0ae2f4c395a 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -68,7 +68,7 @@ icon_state = dead_icon if(owner) to_chat(owner, "You can't feel your [name] anymore...") - owner.update_body(update_sprite) + owner.update_body() if(vital) owner.death() @@ -672,12 +672,12 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/proc/mutate() src.status |= ORGAN_MUTATED if(owner) - owner.update_body(1, 1) //Forces all bodyparts to update in order to correctly render the deformed sprite. + owner.update_body(TRUE) //Forces all bodyparts to update in order to correctly render the deformed sprite. /obj/item/organ/external/proc/unmutate() src.status &= ~ORGAN_MUTATED if(owner) - owner.update_body(1, 1) //Forces all bodyparts to update in order to correctly return them to normal. + owner.update_body(TRUE) //Forces all bodyparts to update in order to correctly return them to normal. /obj/item/organ/external/proc/get_damage() //returns total damage return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? diff --git a/icons/mob/screen_alien.dmi b/icons/mob/screen_alien.dmi index c254b276bc5a576a800ea30910c4670df5bdcbd2..209ec83993967186a01e972175fdc6d1e3fa3c33 100644 GIT binary patch literal 26695 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 H-1NJ%>Q4;G8@LzvR`e}u zC24C^{v&Rr2dalV&F;@R#UJjVBS(c+q1!SLAdInTTX=+Chh=0_m7WcS!H9CG5zXyg z40!$A#-G52seW<|1^C9Ub^O0U5<+GHFp4(pglg1xqjJB~vrqsMuwT70Ht_`#+vx2` zL(w5;bERHwzD%F!OoupOc-!fhR9~YnU2%y1dV@^LvK-K2Clu~I&lR+kvG#_J&IrU)>|uLHH&<8PPZou zlyYxG4g&G$&7_tj0XtB*9L?}V=_TIr5yF+bpWbk{?s$($47}1yc%_k!Kzkb8rDxUS z@4uslpE)iz&$w)PBDT`vGZb&!lUR~91}KZ37QO=3a_=y?8|}d);(IZZ*mIAx|7G2h zY3H#C(}slWVtRF_DEp66^RC%oX)H>0meBnW9G|W+i9~VKc=w;rC~_F+Dt7f-!J{JC>r071XvYMVEid0`9G(cV3Jb- zNQn``r4LkF%7$zurLPT`f50FBC#XdbG%`Y7B&tH~F_aq(9YKQDYyR5zpZ$gHOwPN+ zoMTxRdeI)a#E)xd85;_OoG|C3&E!zh>kfvJ zjcf%CC7CufHaCb`;OKwn)$XT)kiGyS1wZJgt+l9ueuMaE8XFrhldKbGN_#L|W0w+O z<~zQGAE@eb)YhTJB8gYurg+$n-SYV$EZjEgSKAVL|Ju1Wjii*7iU@rQ?KS z_Mc76t;8AV3nG#J#Gg=OzJGQ&@beF4T>7Rs)Tcpl+NINZm!p{@eaoOl`RsG?Mx!mb z#z5+_7k0+HL4SFt8oT6P251bs?%xHDHT)aoPUxS)v1#yo`WAkjUh`98o&9FkoioXN zZ?;*zScg@9>YmpcA=@m~v=}~&v>1uALXz-bqQqki=Z9p`ATOEuL2UItISQ<#qM}A) z_q>`Ymy__9+oqpU(cQc0e?RW(dtEbswS2JaJ)>YNSvK0?L?Jy1xK&+JjOY`{+(bUz zSXDQO?YCyp$6uC&UMnx#fOe3!MP)g)Pa=yyI20f*ZJ!)mx!b?g{xaK5dAF6xy_x?b z{^(^4^oE$-CgChXuR@37Y{t@RHrz+;a>f!HQlq)y)MG#SoF(Xf^8bEo-}iIx4ehNv z-#I$7TobR|YTzj+@T<7^UH>4?@)G=4O|sufXde#gaTj;TUz|cC?Vjdc{CVgpljq9B zk=Fs9pDwtSGa#hwEld5-hBIR1_~om+Ws@4_dWwLn#T(x5k(f^|p28BG0a#GJUaqlO zNzU#0GSVYE=JvICYm)2t$h6I8gbi>H=}TIw4OYtkP}v8d+ kU@CF-&FJ<_nQMbG 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 ThI)e`;GwFhsZb(k8u0%BNn~#7 From 8a71c695cc1d4974b468b9aa7df8f6c03b1678e6 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Thu, 4 Jun 2020 14:36:29 +0100 Subject: [PATCH 051/151] Patches a hole --- code/modules/admin/player_panel.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 2a1d03b79aa..0d55840b5b8 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -2,6 +2,10 @@ /datum/admins/proc/player_panel_new()//The new one if(!usr.client.holder) return + // This stops the panel from being invoked by mentors who press F7. + if(!check_rights(R_ADMIN)) + message_admins("[key_name_admin(usr)] attempted to invoke player panel without admin rights. If this is a mentor, its a chance they accidentally hit F7. If this is NOT a mentor, there is a high chance an exploit is being used") + return var/dat = "Admin Player Panel" //javascript, the part that does most of the work~ From 763ba97c3754954948eac5dee1dc64250889fdcc Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 4 Jun 2020 22:21:54 +0200 Subject: [PATCH 052/151] Fix AI say logging and cult logging --- code/game/gamemodes/cult/cult_comms.dm | 1 + code/modules/mob/living/say.dm | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 375a02251bc..938f1a13aad 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -46,3 +46,4 @@ to_chat(M, " (F) [my_message] ") log_say("(CULT) [message]", user) + user.create_log(SAY_LOG, "(CULT) [message]") diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index edb62d0e013..c272952b6bf 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -172,6 +172,9 @@ proc/get_radio_key_from_channel(var/channel) var/list/hsp = handle_speech_problems(message_pieces, verb) verb = hsp["verb"] + // Do this so it gets logged for all types of communication + var/log_message = "[message_mode ? "([message_mode])" : ""] '[message]'" + create_log(SAY_LOG, log_message) var/list/used_radios = list() if(handle_message_mode(message_mode, message_pieces, verb, used_radios)) @@ -179,9 +182,7 @@ proc/get_radio_key_from_channel(var/channel) // Log of what we've said, plain message, no spans or junk // handle_message_mode should have logged this already if it handled it - var/log_message = "[message_mode ? "([message_mode])" : ""] '[message]'" say_log += log_message - create_log(SAY_LOG, log_message) // TODO after #13047: Include the channel log_say(log_message, src) var/list/handle_v = handle_speech_sound() @@ -364,7 +365,6 @@ proc/get_radio_key_from_channel(var/channel) say_log += "whisper: [message]" log_whisper(message, src) - create_log(SAY_LOG, "WHISPER: [message]") var/message_range = 1 var/eavesdropping_range = 2 var/watching_range = 5 From f6ea3204fd925d7a9b15c2ef8d50ccf06a42124d Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Thu, 4 Jun 2020 22:00:05 -0400 Subject: [PATCH 053/151] Hierophant Buff--Staff Nerf --- code/modules/mining/lavaland/loot/hierophant_loot.dm | 2 +- .../mob/living/simple_animal/hostile/megafauna/hierophant.dm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm index a3f6e738380..fc81e6399ae 100644 --- a/code/modules/mining/lavaland/loot/hierophant_loot.dm +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -93,7 +93,7 @@ blast_range = initial(blast_range) if(isliving(user)) var/mob/living/L = user - var/health_percent = L.health / L.maxHealth + var/health_percent = max(L.health / L.maxHealth, 0) // Don't go negative chaser_cooldown += round(health_percent * 20) //two tenths of a second for each missing 10% of health cooldown_time += round(health_percent * 10) //one tenth of a second for each missing 10% of health chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 716f5436223..a4a3481d61b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -452,6 +452,7 @@ Difficulty: Hard else burst_range = 3 INVOKE_ASYNC(src, .proc/burst, get_turf(src), 0.25) //melee attacks on living mobs cause it to release a fast burst if on cooldown + OpenFire() else devour(L) else From 34996bf36e711cc922e1c2bb81a1e229c8802737 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 4 Jun 2020 16:58:06 -0500 Subject: [PATCH 054/151] hud fix --- .../living/simple_animal/hostile/terror_spiders/princess.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm index 828e0e5f8f6..047219a151b 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm @@ -38,9 +38,12 @@ evolvequeen_action.Grant(src) /mob/living/simple_animal/hostile/poison/terror_spider/princess/proc/evolve_to_queen() - var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = new /mob/living/simple_animal/hostile/poison/terror_spider/queen(loc) + var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = new(loc) if(mind) mind.transfer_to(Q) + // Calling `transfer_to()` removes our new body (the Queen's) ability to see the med hud, so we have to re-add the queen here. + var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + U.add_hud_to(Q) qdel(src) /mob/living/simple_animal/hostile/poison/terror_spider/princess/DoWrap() From 77ffb3f102b64024bc9400112f233502e0cc4e48 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Fri, 5 Jun 2020 18:38:45 -0400 Subject: [PATCH 055/151] Various Life Refactor Fixes (#13536) * Disposal Movement Fix * guardian fix * SSD fix * blob mobs * wizard teleport fix --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 10 ++++++---- .../gamemodes/miniantags/guardian/guardian.dm | 2 +- code/game/objects/items/weapons/scrolls.dm | 2 +- code/modules/mob/living/carbon/life.dm | 7 ++++--- code/modules/recycling/disposal.dm | 16 ++++++++-------- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index fb26ce91698..b7bcd737dfd 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -51,7 +51,8 @@ speak_emote = list("pulses") var/obj/structure/blob/factory/factory = null var/list/human_overlays = list() - var/is_zombie = 0 + var/mob/living/carbon/human/oldguy + var/is_zombie = FALSE /mob/living/simple_animal/hostile/blob/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) ..() @@ -102,6 +103,7 @@ human_overlays = H.overlays update_icons() H.forceMove(src) + oldguy = H visible_message("The corpse of [H.name] suddenly rises!") /mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) @@ -130,9 +132,9 @@ if(factory) factory.spores -= src factory = null - if(contents) - for(var/mob/M in contents) - M.loc = get_turf(src) + if(oldguy) + oldguy.forceMove(get_turf(src)) + oldguy = null return ..() diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index cc481a01d54..c0e22515553 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -162,7 +162,7 @@ if(loc == summoner) forceMove(get_turf(summoner)) new /obj/effect/temp_visual/guardian/phase(loc) - src.client.eye = loc + reset_perspective() cooldown = world.time + 30 /mob/living/simple_animal/hostile/guardian/proc/Recall(forced = FALSE) diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 0f25239e4e4..14f3b0ab91f 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -100,7 +100,7 @@ break if(!success) - user.loc = pick(L) + user.forceMove(pick(L)) smoke.start() src.uses -= 1 diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index d7754b32f43..66e2e60f144 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -336,6 +336,10 @@ AdjustHallucinate(-2) + // Keep SSD people asleep + if(player_logged) + Sleeping(2) + /mob/living/carbon/handle_sleeping() if(..()) if(mind?.vampire) @@ -363,9 +367,6 @@ if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT) emote("snore") - // Keep SSD people asleep - if(player_logged) - Sleeping(2) return sleeping /mob/living/carbon/update_health_hud(shown_health_amount) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 001bb1c98f4..544deb8d11f 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -582,7 +582,7 @@ D.expel(src) // no trunk connected, so expel immediately return - loc = D.trunk + forceMove(D.trunk) active = 1 dir = DOWN spawn(1) @@ -746,9 +746,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -790,7 +790,7 @@ if(T.density) // dense ouput turf, so stop holder H.active = 0 - H.loc = src + H.forceMove(src) return if(T.intact && istype(T,/turf/simulated/floor)) //intact floor, pop the tile var/turf/simulated/floor/F = T @@ -1069,9 +1069,9 @@ var/obj/structure/disposalholder/H2 = locate() in P if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P @@ -1128,9 +1128,9 @@ if(H2 && !H2.active) H.merge(H2) - H.loc = P + H.forceMove(P) else // if wasn't a pipe, then set loc to turf - H.loc = T + H.forceMove(T) return null return P From a2ecd79be7c0743a82a49677fef26eea380901bd Mon Sep 17 00:00:00 2001 From: Patrick Meade Date: Fri, 5 Jun 2020 22:41:52 -0500 Subject: [PATCH 056/151] Rework power outage event (#13117) * Rework power outage event * Added compile time flag for event fixing itself when it ends * Review Cleanup 1 * Fixed up line ending conflicts * Going whole hog with a side of bacon * Whoops, forgot the sausage and Canadian Bacon * Better messaging and makes APC Overload an offical non-random event * Test merge feedback rework --- code/modules/events/apc_overload.dm | 63 +++++++++++++++++++ code/modules/events/apc_short.dm | 78 +++++++++++++++++++++++ code/modules/events/event_container.dm | 5 +- code/modules/events/grid_check.dm | 82 ------------------------- code/modules/power/apc.dm | 2 +- code/modules/power/smes.dm | 5 -- paradise.dme | 3 +- sound/AI/apc_overload.ogg | Bin 0 -> 67540 bytes sound/AI/apc_short.ogg | Bin 0 -> 62772 bytes 9 files changed, 147 insertions(+), 91 deletions(-) create mode 100644 code/modules/events/apc_overload.dm create mode 100644 code/modules/events/apc_short.dm delete mode 100644 code/modules/events/grid_check.dm create mode 100644 sound/AI/apc_overload.ogg create mode 100644 sound/AI/apc_short.ogg diff --git a/code/modules/events/apc_overload.dm b/code/modules/events/apc_overload.dm new file mode 100644 index 00000000000..a773e71a173 --- /dev/null +++ b/code/modules/events/apc_overload.dm @@ -0,0 +1,63 @@ +#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be broken + +/datum/event/apc_overload + var/const/announce_after_mc_ticks = 5 + var/const/delayed = FALSE + var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2 + var/const/event_min_duration_mc_ticks = announce_after_mc_ticks + + announceWhen = announce_after_mc_ticks + +/datum/event/apc_overload/setup() + endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks) + +/datum/event/apc_overload/start() + apc_overload_failure(announce=delayed) + var/sound/S = sound('sound/effects/powerloss.ogg') + for(var/mob/living/M in GLOB.player_list) + var/turf/T = get_turf(M) + if(!M.client || !is_station_level(T.z)) + continue + SEND_SOUND(M, S) + +/datum/event/apc_overload/announce() + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg') + +/datum/event/apc_overload/end() + return TRUE + +/proc/apc_overload_failure(announce=TRUE) + var/list/skipped_areas_apc = list( + /area/engine/engineering, + /area/turret_protected/ai) + + if(announce) + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg') + + // break APC_BREAK_PROBABILITY% of all of the APCs on the station + var/affected_apc_count = 0 + for(var/obj/machinery/power/apc/C in GLOB.apcs) + // skip any APCs that are too critical to break + var/area/current_area = get_area(C) + if((current_area.type in skipped_areas_apc) || !is_station_level(C.z)) + continue + // if we are going to break this one + if(prob(APC_BREAK_PROBABILITY)) + // if it has a cell, drain all the charge from the cell + if(C.cell) + C.cell.charge = 0 + // if it has a terminal, disconnect and delete the terminal + if(C.terminal) + var/obj/machinery/power/terminal/T = C.terminal + C.terminal.master = null + C.terminal = null + qdel(T) + // if it was operating, toggle off the breaker + if(C.operating) + C.toggle_breaker() + // no matter what, ensure the area knows something happened to the power + current_area.power_change() + affected_apc_count++ + log_and_message_admins("APC Overload event deleted [affected_apc_count] underfloor APC terminals.") + +#undef APC_BREAK_PROBABILITY diff --git a/code/modules/events/apc_short.dm b/code/modules/events/apc_short.dm new file mode 100644 index 00000000000..b128fe6c2e9 --- /dev/null +++ b/code/modules/events/apc_short.dm @@ -0,0 +1,78 @@ +#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be disabled + +/datum/event/apc_short + var/const/announce_after_mc_ticks = 5 + var/const/delayed = FALSE + var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2 + var/const/event_min_duration_mc_ticks = announce_after_mc_ticks + + announceWhen = announce_after_mc_ticks + +/datum/event/apc_short/setup() + endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks) + +/datum/event/apc_short/start() + power_failure(announce=delayed) + var/sound/S = sound('sound/effects/powerloss.ogg') + for(var/mob/living/M in GLOB.player_list) + var/turf/T = get_turf(M) + if(!M.client || !is_station_level(T.z)) + continue + SEND_SOUND(M, S) + +/datum/event/apc_short/announce() + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg') + +/datum/event/apc_short/end() + return TRUE + +/proc/power_failure(announce=TRUE) + var/list/skipped_areas_apc = list( + /area/engine/engineering, + /area/turret_protected/ai) + + if(announce) + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg') + + // break APC_BREAK_PROBABILITY% of all of the APCs on the station + var/affected_apc_count = 0 + for(var/obj/machinery/power/apc/C in GLOB.apcs) + // skip any APCs that are too critical to disable + var/area/current_area = get_area(C) + if((current_area.type in skipped_areas_apc) || !is_station_level(C.z)) + continue + // if we are going to break this one + if(prob(APC_BREAK_PROBABILITY)) + // if it has internal wires, cut the power wires + if(C.wires) + if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER1)) + C.wires.CutWireIndex(APC_WIRE_MAIN_POWER1) + if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER2)) + C.wires.CutWireIndex(APC_WIRE_MAIN_POWER2) + // if it was operating, toggle off the breaker + if(C.operating) + C.toggle_breaker() + // no matter what, ensure the area knows something happened to the power + current_area.power_change() + affected_apc_count++ + log_and_message_admins("APC Short event shorted out [affected_apc_count] APCs.") + +/proc/power_restore(announce=TRUE) + power_restore_quick(announce) + +/proc/power_restore_quick(announce=TRUE) + if(announce) + GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') + + // fix all of the SMESs + for(var/obj/machinery/power/smes/S in GLOB.machines) + if(!is_station_level(S.z)) + continue + S.charge = S.capacity + S.output_level = S.output_level_max + S.output_attempt = 1 + S.input_attempt = 1 + S.update_icon() + S.power_change() + +#undef APC_BREAK_PROBABILITY diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 9c744b8060a..908bc762315 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) /datum/event_container/mundane severity = EVENT_LEVEL_MUNDANE available_events = list( - // Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero + // Severity level, event name, event type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), @@ -157,7 +157,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)), //new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)), //new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "APC Short", /datum/event/apc_short, 200, list(ASSIGNMENT_ENGINEER = 60)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 25, list(ASSIGNMENT_MEDICAL = 50), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), @@ -191,6 +191,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1), //new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "APC Overload", /datum/event/apc_overload, 0), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 5), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1), diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm deleted file mode 100644 index 8da2a6d707e..00000000000 --- a/code/modules/events/grid_check.dm +++ /dev/null @@ -1,82 +0,0 @@ -/datum/event/grid_check //NOTE: Times are measured in master controller ticks! - announceWhen = 5 - -/datum/event/grid_check/setup() - endWhen = rand(30,120) - -/datum/event/grid_check/start() - power_failure(0) - var/sound/S = sound('sound/effects/powerloss.ogg') - for(var/mob/living/M in GLOB.player_list) - var/turf/T = get_turf(M) - if(!M.client || !is_station_level(T.z)) - continue - SEND_SOUND(M, S) - -/datum/event/grid_check/announce() - GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') - -/datum/event/grid_check/end() - power_restore() - -/proc/power_failure(var/announce = 1) - if(announce) - GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg') - - var/list/skipped_areas = list(/area/turret_protected/ai) - var/list/skipped_areas_apc = list(/area/engine/engineering) - - for(var/obj/machinery/power/smes/S in GLOB.machines) - var/area/current_area = get_area(S) - if((current_area.type in skipped_areas) || !is_station_level(S.z)) - continue - S.last_charge = S.charge - S.last_output_attempt = S.output_attempt - S.last_input_attempt = S.input_attempt - S.charge = 0 - S.inputting(0) - S.outputting(0) - S.update_icon() - S.power_change() - - for(var/obj/machinery/power/apc/C in GLOB.apcs) - var/area/current_area = get_area(C) - if((current_area.type in skipped_areas_apc) || !is_station_level(C.z)) - continue - if(C.cell) - C.cell.charge = 0 - -/proc/power_restore(var/announce = 1) - var/list/skipped_areas = list(/area/turret_protected/ai) - var/list/skipped_areas_apc = list(/area/engine/engineering) - - if(announce) - GLOB.event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') - for(var/obj/machinery/power/apc/C in GLOB.apcs) - var/area/current_area = get_area(C) - if((current_area.type in skipped_areas_apc) || !is_station_level(C.z)) - continue - if(C.cell) - C.cell.charge = C.cell.maxcharge - for(var/obj/machinery/power/smes/S in GLOB.machines) - var/area/current_area = get_area(S) - if((current_area.type in skipped_areas) || !is_station_level(S.z)) - continue - S.charge = S.last_charge - S.output_attempt = S.last_output_attempt - S.input_attempt = S.last_input_attempt - S.update_icon() - S.power_change() - -/proc/power_restore_quick(var/announce = 1) - if(announce) - GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') - for(var/obj/machinery/power/smes/S in GLOB.machines) - if(!is_station_level(S.z)) - continue - S.charge = S.capacity - S.output_level = S.output_level_max - S.output_attempt = 1 - S.input_attempt = 1 - S.update_icon() - S.power_change() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 89988ec9f55..234b885284e 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -244,7 +244,7 @@ else if(has_electronics && !terminal) . += "Electronics installed but not wired." else /* if(!has_electronics && !terminal) */ - . += "There is no electronics nor connected wires." + . += "There are no electronics nor connected wires." else if(stat & MAINT) . += "The cover is closed. Something wrong with it: it doesn't work." diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index f2e8fa53a8d..f88128ab974 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -29,11 +29,6 @@ var/output_level_max = 200000 // cap on output_level var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power - //Holders for powerout event. - var/last_output_attempt = 0 - var/last_input_attempt = 0 - var/last_charge = 0 - var/name_tag = null var/obj/machinery/power/terminal/terminal = null diff --git a/paradise.dme b/paradise.dme index c3dcfbd3c2d..f2dbf198ebd 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1485,7 +1485,8 @@ #include "code\modules\events\event_procs.dm" #include "code\modules\events\false_alarm.dm" #include "code\modules\events\floorcluwne.dm" -#include "code\modules\events\grid_check.dm" +#include "code\modules\events\apc_overload.dm" +#include "code\modules\events\apc_short.dm" #include "code\modules\events\headcrabs.dm" #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" diff --git a/sound/AI/apc_overload.ogg b/sound/AI/apc_overload.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ef9357b9eb64ff3a2fcc8ac82e90d9d087fb8bd2 GIT binary patch literal 67540 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

w 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

X}KWb6(I`N^`f|-Msr;*%NuDciK(C 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 BalZfn literal 0 HcmV?d00001 From 64f127526d18558d5e0431f7519f05c26dc95f87 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sat, 6 Jun 2020 04:50:58 +0100 Subject: [PATCH 057/151] Programmatic Profiler Access (#13524) * Programmatic Profiler Access * Why do I never proof-read until submitting --- .gitignore | 3 +++ code/game/world.dm | 4 ++++ code/modules/admin/admin_ranks.dm | 10 ++++++++++ code/modules/admin/admin_verbs.dm | 5 +++++ 4 files changed, 22 insertions(+) diff --git a/.gitignore b/.gitignore index e76c9f6db1d..648359d0a36 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ /config/* !config/**/*/ +# ignore cfg, an internal BYOND folder +/cfg/* + #ignore other, specific files and folers *.before data/ diff --git a/code/game/world.dm b/code/game/world.dm index 174a1662dd0..c1f6a076677 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -267,6 +267,10 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday) /world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time) if(reason == 1) //special reboot, do none of the normal stuff if(usr) + if(!check_rights(R_SERVER)) + message_admins("[key_name_admin(usr)] attempted to restart the server via the Profiler, without access.") + log_admin("[key_name(usr)] attempted to restart the server via the Profiler, without access.") + return message_admins("[key_name_admin(usr)] has requested an immediate world restart via client side debugging tools") log_admin("[key_name(usr)] has requested an immediate world restart via client side debugging tools") spawn(0) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index fdf3d0dc8d0..5956819d3d4 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -68,6 +68,10 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons C.holder = null GLOB.admins.Cut() + // Remove all profiler access + for(var/A in world.GetConfig("admin")) + world.SetConfig("APP/admin", A, null) + if(config.admin_legacy_system) load_admin_ranks() @@ -98,6 +102,9 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons //create the admin datum and store it for later use var/datum/admins/D = new /datum/admins(rank, rights, ckey) + if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES + world.SetConfig("APP/admin", ckey, "role=admin") + //find the client for a ckey if they are connected and associate them with the new admin datum D.associate(GLOB.directory[ckey]) @@ -122,6 +129,9 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons if(istext(rights)) rights = text2num(rights) var/datum/admins/D = new /datum/admins(rank, rights, ckey) + if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES + world.SetConfig("APP/admin", ckey, "role=admin") + //find the client for a ckey if they are connected and associate them with the new admin datum D.associate(GLOB.directory[ckey]) if(!GLOB.admin_datums) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 62cb627db17..4e3d2d65f30 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -247,6 +247,8 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list( verbs += GLOB.admin_verbs_server if(holder.rights & R_DEBUG) verbs += GLOB.admin_verbs_debug + spawn(1) + control_freak = 0 // Setting control_freak to 0 allows you to use the Profiler and other client-side tools if(holder.rights & R_POSSESS) verbs += GLOB.admin_verbs_possess if(holder.rights & R_PERMISSIONS) @@ -267,6 +269,9 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list( verbs += GLOB.admin_verbs_proccall if(holder.rights & R_VIEWRUNTIMES) verbs += /client/proc/view_runtimes + spawn(1) // This setting exposes the profiler for people with R_VIEWRUNTIMES. They must still have it set in cfg/admin.txt + control_freak = 0 + /client/proc/remove_admin_verbs() verbs.Remove( From 8e2b69f5dbb79802e4a4d34ab7a2c2ff07dec9d7 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Sat, 6 Jun 2020 09:55:00 +0200 Subject: [PATCH 058/151] Fixes the steal objective from runtiming --- code/game/gamemodes/objective.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index bedc3c4809b..0da5d8a3a0a 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -399,6 +399,9 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) if(!steal_target) return 1 // Free Objective + if(!owner.current) + return FALSE + var/list/all_items = owner.current.GetAllContents() for(var/obj/I in all_items) From 809c09f969aa4b6739ce8a2c5ec8e02a89e5f5cc Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sat, 6 Jun 2020 12:16:01 +0100 Subject: [PATCH 059/151] Fixes karma shop --- code/modules/karma/karma.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index f7d8b12f80c..837e3a21104 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -230,7 +230,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dat += "Unlock Barber -- 5KP
" else dat += "Barber - Unlocked
" - if(!("Brig Physican" in joblist)) + if(!("Brig Physician" in joblist)) dat += "Unlock Brig Physician -- 5KP
" else dat += "Brig Physician - Unlocked
" From 158c4e241e67219c07e3946cad3af84035fd9dec Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 6 Jun 2020 09:55:09 -0500 Subject: [PATCH 060/151] fix --- .../crates_lockers/closets/secure/personal.dm | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index 096133b6e0d..769bb6e6df7 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -54,36 +54,33 @@ new /obj/item/storage/backpack/satchel/withwallet( src ) new /obj/item/radio/headset( src ) -/obj/structure/closet/secure_closet/personal/attackby(obj/item/W as obj, mob/user as mob, params) - if(src.opened) - if(istype(W, /obj/item/grab)) - src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet - user.drop_item() - if(W) W.forceMove(loc) - else if(istype(W, /obj/item/card/id)) - if(src.broken) - to_chat(user, "It appears to be broken.") - return - var/obj/item/card/id/I = W - if(!I || !I.registered_name) return - if(src == user.loc) - to_chat(user, "You can't reach the lock from inside.") - else if(src.allowed(user) || !src.registered_name || (istype(I) && (src.registered_name == I.registered_name))) - //they can open all lockers, or nobody owns this, or they own this locker - src.locked = !( src.locked ) - if(src.locked) - src.icon_state = src.icon_locked - else - src.icon_state = src.icon_closed - registered_name = null - desc = initial(desc) +/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) + if(broken) + to_chat(user, "It appears to be broken.") + return - if(!src.registered_name && src.locked) - src.registered_name = I.registered_name - src.desc = "Owned by [I.registered_name]." - else - to_chat(user, "Access Denied") - else if((istype(W, /obj/item/card/emag) || istype(W, /obj/item/melee/energy/blade)) && !broken) - emag_act(user) - else + if(!istype(W, /obj/item/card/id)) return ..() + + var/obj/item/card/id/I = W + if(!I || !I.registered_name) + return + + if(src == user.loc) + to_chat(user, "You can't reach the lock from inside.") + + else if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) + //they can open all lockers, or nobody owns this, or they own this locker + locked = !locked + if(locked) + icon_state = icon_locked + else + icon_state = icon_closed + registered_name = null + desc = initial(desc) + + if(!registered_name && locked) + registered_name = I.registered_name + desc = "Owned by [I.registered_name]." + else + to_chat(user, "Access Denied") From 973e53be145dcc6825f21154e2cdfc4a534419c5 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 6 Jun 2020 10:04:46 -0500 Subject: [PATCH 061/151] nevermind this should go after --- .../structures/crates_lockers/closets/secure/personal.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index 769bb6e6df7..df7e1384ed9 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -55,13 +55,13 @@ new /obj/item/radio/headset( src ) /obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) + if(!istype(W, /obj/item/card/id)) + return ..() + if(broken) to_chat(user, "It appears to be broken.") return - if(!istype(W, /obj/item/card/id)) - return ..() - var/obj/item/card/id/I = W if(!I || !I.registered_name) return From 3b4bda996a431bb787e7675241f7e11f7847684c Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sat, 6 Jun 2020 19:59:04 +0100 Subject: [PATCH 062/151] Re-adds NTTC filtering --- code/game/machinery/tcomms/_base.dm | 2 ++ code/game/machinery/tcomms/core.dm | 37 +++++++++++++++++++++++- code/game/machinery/tcomms/nttc.dm | 7 +++++ nano/templates/tcomms_core.tmpl | 44 +++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/tcomms/_base.dm b/code/game/machinery/tcomms/_base.dm index a857afcef89..7fc2ddae23b 100644 --- a/code/game/machinery/tcomms/_base.dm +++ b/code/game/machinery/tcomms/_base.dm @@ -171,6 +171,8 @@ GLOBAL_LIST_EMPTY(tcomms_machines) var/vname /// List of all channels this can be sent or recieved on var/list/zlevels = list() + /// Should this signal be re-broadcasted (Can be modified by NTTC, defaults to TRUE) + var/pass = TRUE /** * Destructor for the TCM datum. diff --git a/code/game/machinery/tcomms/core.dm b/code/game/machinery/tcomms/core.dm index 9e638913f9d..3fdae14746f 100644 --- a/code/game/machinery/tcomms/core.dm +++ b/code/game/machinery/tcomms/core.dm @@ -1,5 +1,6 @@ #define UI_TAB_CONFIG "CONFIG" #define UI_TAB_LINKS "LINKS" +#define UI_TAB_FILTER "FILTER" /** * # Telecommunications Core @@ -81,6 +82,11 @@ // Now we can run NTTC tcm = nttc.modify_message(tcm) + // If the signal shouldnt be broadcast, dont broadcast it + if(!tcm.pass) + // We still return TRUE here because the signal was handled, even though we didnt broadcast + return TRUE + // Now we generate the list of where that signal should go to tcm.zlevels = reachable_zlevels tcm.zlevels |= tcm.source_level @@ -168,6 +174,9 @@ data["entries"] += list(list("addr" = "\ref[R]", "net_id" = R.network_id, "sector" = R.loc.z, "status" = status, "status_color" = status_color)) // End the shit + if(ui_tab == UI_TAB_FILTER) + data["filtered_users"] = nttc.filtering + return data /obj/machinery/tcomms/core/Topic(href, href_list) @@ -177,7 +186,7 @@ if(href_list["tab"]) // Make sure its a valid tab - if(href_list["tab"] in list(UI_TAB_CONFIG, UI_TAB_LINKS)) + if(href_list["tab"] in list(UI_TAB_CONFIG, UI_TAB_LINKS, UI_TAB_FILTER)) ui_tab = href_list["tab"] // Check if they did a href, but only for that current tab @@ -257,9 +266,35 @@ to_chat(usr, "Successfully changed password from [link_password] to [new_password].") link_password = new_password + if(ui_tab == UI_TAB_FILTER) + if(href_list["add_filter"]) + // This is a stripped input because I did NOT come this far for this system to be abused by HTML injection + var/name_to_add = stripped_input(usr, "Enter a name to add to the filtering list", "Name Entry") + if(name_to_add == "") + return + if(name_to_add in nttc.filtering) + to_chat(usr, "ERROR: User already in filtering list.") + else + nttc.filtering |= name_to_add + log_action(usr, "has added [name_to_add] to the NTTC filter list on core with ID [network_id]", TRUE) + to_chat(usr, "Successfully added [name_to_add] to the NTTC filtering list.") + + + if(href_list["remove_filter"]) + var/name_to_remove = href_list["remove_filter"] + if(!(name_to_remove in nttc.filtering)) + to_chat(usr, "ERROR: Name does not exist in filter list. Please file an issue report.") + else + var/confirm = alert(usr, "Are you sure you want to remove [name_to_remove] from the filtering list?", "Confirm Removal", "Yes", "No") + if(confirm == "Yes") + nttc.filtering -= name_to_remove + log_action(usr, "has removed [name_to_remove] from the NTTC filter list on core with ID [network_id]", TRUE) + to_chat(usr, "Successfully removed [name_to_remove] from the NTTC filtering list.") + // Hack to speed update the nanoUI SSnanoui.update_uis(src) #undef UI_TAB_CONFIG #undef UI_TAB_LINKS +#undef UI_TAB_FILTER diff --git a/code/game/machinery/tcomms/nttc.dm b/code/game/machinery/tcomms/nttc.dm index 6ee158c6cc0..14e932dcf7f 100644 --- a/code/game/machinery/tcomms/nttc.dm +++ b/code/game/machinery/tcomms/nttc.dm @@ -153,6 +153,10 @@ var/list/job_card_styles = list( JOB_STYLE_1, JOB_STYLE_2, JOB_STYLE_3, JOB_STYLE_4 ) + + // List of people who will get blocked out of comms + var/list/filtering = list() + // Used to determine what languages are allowable for conversion. Generated during runtime. var/list/valid_languages = list("--DISABLE--") @@ -220,6 +224,9 @@ // Primary signal modification. This is where all of the variables behavior are actually implemented. /datum/nttc_configuration/proc/modify_message(datum/tcomms_message/tcm) + // Check if they should be blacklisted right off the bat. We can save CPU if the message wont even be processed + if(tcm.sender_name in filtering) + tcm.pass = FALSE // All job and coloring shit if(toggle_job_color || toggle_name_color) var/job = tcm.sender_job diff --git a/nano/templates/tcomms_core.tmpl b/nano/templates/tcomms_core.tmpl index 028f087aec8..bc083e657a7 100644 --- a/nano/templates/tcomms_core.tmpl +++ b/nano/templates/tcomms_core.tmpl @@ -1,5 +1,6 @@ {{:helper.link('Device Configuration', 'wrench', {'tab' : "CONFIG"}, data.tab == "CONFIG" ? 'selected' : '')}} {{:helper.link('Device Links', 'link', {'tab' : "LINKS"}, data.tab == "LINKS" ? 'selected' : '')}} +{{:helper.link('User Filtering', 'user-times', {'tab' : "FILTER"}, data.tab == "FILTER" ? 'selected' : '')}} {{if data.tab == "CONFIG"}}

Core Configuration

@@ -136,4 +137,47 @@ {{/for}}
KeyReal NameJobMins AFKSpecial RoleAreaPPNCryo
+{{else data.tab == "FILTER"}} + +

Filtering List

+
+
+ {{:helper.link('Add User', 'plus', {'add_filter': 1})}} +
+
+
+ + + + + + + + + + + + + {{for data.filtered_users}} + + + + + {{/for}} + +
NameRemove
{{:value}}{{:helper.link('Remove', 'times', {'remove_filter' : value}, null, 'infoButton')}}
{{/if}} From 7088de6bab9f49a3a779c5eb71bafe01801909bb Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 6 Jun 2020 15:21:13 -0500 Subject: [PATCH 063/151] slippery component --- code/__DEFINES/inventory.dm | 3 -- code/datums/components/slippery.dm | 54 +++++++++++++++++++ code/game/atoms_movable.dm | 10 ++++ code/game/objects/items.dm | 19 ------- .../items/weapons/grenades/clowngrenade.dm | 34 ++++-------- code/game/objects/items/weapons/soap.dm | 10 ++-- code/modules/hydroponics/grown.dm | 10 ++-- code/modules/hydroponics/grown/banana.dm | 14 +++-- code/modules/hydroponics/growninedible.dm | 10 ++-- code/modules/hydroponics/plant_genes.dm | 6 +-- code/modules/mob/living/carbon/carbon.dm | 19 ++++--- code/modules/pda/pdas.dm | 9 ++-- paradise.dme | 1 + 13 files changed, 110 insertions(+), 89 deletions(-) create mode 100644 code/datums/components/slippery.dm diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index cec707b8196..23ac017f1ec 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -5,6 +5,3 @@ #define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in an inventory, ex: Defibrillator, Backpack, Space Suits #define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons #define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe - -#define TV_TRIP "trip" -#define TV_SLIP "slip" diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm new file mode 100644 index 00000000000..0ea8e313378 --- /dev/null +++ b/code/datums/components/slippery.dm @@ -0,0 +1,54 @@ +/** + This is a component that can be applied to any movable atom (mob or obj). + + While the atom has this component, any carbon mob that walks over it will slip. + Duration, tiles moved, and so on, depend on what variables are passed in when the component is added. +*/ +/datum/component/slippery + /// Text that gets displayed in the slip proc, i.e. "user slips on [description]" + var/description + /// The amount of stun to apply after slip. + var/stun + /// The amount of weaken to apply after slip. + var/weaken + /// The chance that walking over the parent will slip you. + var/slip_chance + /// The amount of tiles someone will be moved after slip. + var/slip_tiles + /// TRUE If this slip can be avoided by walking. + var/walking_is_safe + /// TRUE if having no slip shoes makes you immune to this slip. + var/noslip_is_immune + /// The verb that players will see when someone slips on the parent. In the form of "You [slip_verb]ped on". + var/slip_verb + +/datum/component/slippery/Initialize(_description, _stun = 0, _weaken = 0, _slip_chance = 100, _slip_tiles = 0, \ + _walking_is_safe = TRUE, _noslip_is_immune = TRUE, _slip_verb = "slip") + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + description = _description + stun = max(0, _stun) + weaken = max(0, _weaken) + slip_chance = max(0, _slip_chance) + slip_tiles = max(0, _slip_tiles) + walking_is_safe = _walking_is_safe + noslip_is_immune = _noslip_is_immune + slip_verb = _slip_verb + +/datum/component/slippery/RegisterWithParent() + RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) + +/datum/component/slippery/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED)) + +/** + Called whenever the parent recieves either the `MOVABLE_CROSSED` signal or the `ATOM_ENTERED` signal. + + Calls the `victim`'s `slip()` proc with the component's variables as arguments. + Additionally calls the parent's `after_slip()` proc on the `victim`. +*/ +/datum/component/slippery/proc/Slip(datum/source, mob/living/carbon/human/victim) + if(istype(victim) && prob(slip_chance) && victim.slip(description, stun, weaken, slip_tiles, walking_is_safe, noslip_is_immune, slip_verb)) + var/atom/movable/owner = parent + owner.after_slip(victim) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ac77d3d4553..dff58d485f5 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -330,6 +330,16 @@ SSspacedrift.processing[src] = src return 1 +/** + Base proc, intended to be overriden. + + This should only be called from one place: inside the slippery component. + Called after a human mob slips on this atom. + + If you want the person who slipped to have something special done to them, put it here. +*/ +/atom/movable/proc/after_slip(mob/living/carbon/human/H) + return //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index fba55ba0557..ab6ebe6a0fe 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -98,15 +98,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc. var/sprite_sheets_obj = null //Used to override hardcoded clothing inventory object dmis in human clothing proc. - var/trip_verb = TV_TRIP - var/trip_chance = 0 - - var/trip_stun = 0 - var/trip_weaken = 0 - var/trip_any = FALSE - var/trip_walksafe = TRUE - var/trip_tiles = 0 - //Tooltip vars var/in_inventory = FALSE //is this item equipped into an inventory slot or hand of a mob? var/tip_timer = 0 @@ -606,16 +597,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect /obj/item/proc/is_equivalent(obj/item/I) return I == src -/obj/item/Crossed(atom/movable/AM, oldloc) - . = ..() - if(prob(trip_chance) && ishuman(AM)) - var/mob/living/carbon/human/H = AM - on_trip(H) - -/obj/item/proc/on_trip(mob/living/carbon/human/H) - if(H.slip(src, trip_stun, trip_weaken, trip_tiles, trip_walksafe, trip_any, trip_verb)) - return TRUE - /obj/item/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) return diff --git a/code/game/objects/items/weapons/grenades/clowngrenade.dm b/code/game/objects/items/weapons/grenades/clowngrenade.dm index cfb2e1cad3d..1dcf250dfe4 100644 --- a/code/game/objects/items/weapons/grenades/clowngrenade.dm +++ b/code/game/objects/items/weapons/grenades/clowngrenade.dm @@ -13,22 +13,12 @@ /obj/item/grenade/clown_grenade/prime() ..() playsound(src.loc, 'sound/items/bikehorn.ogg', 25, -3) - /* - for(var/turf/simulated/floor/T in view(affected_area, src.loc)) - if(prob(75)) - banana(T) - */ var/i = 0 var/number = 0 for(var/direction in GLOB.alldirs) for(i = 0; i < 2; i++) number++ var/obj/item/grown/bananapeel/traitorpeel/peel = new /obj/item/grown/bananapeel/traitorpeel(get_turf(src.loc)) - /* var/direction = pick(alldirs) - var/spaces = pick(1;150, 2) - var/a = 0 - for(a = 0; a < spaces; a++) - step(peel,direction)*/ var/a = 1 if(number & 2) for(a = 1; a <= 2; a++) @@ -39,21 +29,17 @@ qdel(src) return -/obj/item/grown/bananapeel/traitorpeel - trip_stun = 0 - trip_weaken = 7 - trip_tiles = 4 - trip_walksafe = FALSE - - trip_chance = 100 - - -/obj/item/grown/bananapeel/traitorpeel/on_trip(mob/living/carbon/human/H) +/obj/item/grown/bananapeel/traitorpeel/New(newloc, obj/item/seeds/new_seed) . = ..() - if(.) - to_chat(H, "Your feet feel like they're on fire!") - H.take_overall_damage(0, rand(2,8)) - H.take_organ_damage(2) // Was 5 -- TLE + // The reason this AddComponent is here and not in ComponentInitialize() is because if it's put there, it will be ran before the parent New proc for /grown types. + // And then be overriden by the generic component placed onto it by the `/datum/plant_gene/trait/slip`. + AddComponent(/datum/component/slippery, src, 0, 7, 100, 4, FALSE) + +/obj/item/grown/bananapeel/traitorpeel/after_slip(mob/living/carbon/human/H) + to_chat(H, "Your feet feel like they're on fire!") + H.take_overall_damage(0, rand(2,8)) + H.take_organ_damage(2) + return ..() /obj/item/grown/bananapeel/traitorpeel/throw_impact(atom/hit_atom) var/burned = rand(1,3) diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index 62f65b5a6cc..cb220ff9565 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -11,15 +11,11 @@ throw_speed = 4 throw_range = 20 discrete = 1 - - trip_stun = 4 - trip_weaken = 2 - trip_chance = 100 - trip_walksafe = FALSE - trip_verb = TV_SLIP - var/cleanspeed = 50 //slower than mop +/obj/item/soap/ComponentInitialize() + AddComponent(/datum/component/slippery, src, 4, 2, 100, 0, FALSE) + /obj/item/soap/afterattack(atom/target, mob/user, proximity) if(!proximity) return //I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing. diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d86f6f8f4c5..f4a6a18e417 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -160,11 +160,11 @@ T.on_cross(src, AM) ..() -/obj/item/reagent_containers/food/snacks/grown/on_trip(mob/living/carbon/human/H) - . = ..() - if(. && seed) - for(var/datum/plant_gene/trait/T in seed.genes) - T.on_slip(src, H) +/obj/item/reagent_containers/food/snacks/grown/after_slip(mob/living/carbon/human/H) + if(!seed) + return + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_slip(src, H) // Glow gene procs /obj/item/reagent_containers/food/snacks/grown/generate_trash(atom/location) diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index dc78ff71335..0552f78ee92 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -118,12 +118,10 @@ /obj/item/grown/bananapeel/specialpeel //used by /obj/item/clothing/shoes/clown_shoes/banana_shoes name = "synthesized banana peel" desc = "A synthetic banana peel." - trip_stun = 2 - trip_weaken = 2 - trip_chance = 100 - trip_walksafe = FALSE - trip_verb = TV_SLIP -/obj/item/grown/bananapeel/specialpeel/on_trip(mob/living/carbon/human/H) - if(..()) - qdel(src) +/obj/item/grown/bananapeel/specialpeel/ComponentInitialize() + AddComponent(/datum/component/slippery, src, 2, 2, 100, 0, FALSE) + +/obj/item/grown/bananapeel/specialpeel/after_slip(mob/living/carbon/human/H) + . = ..() + qdel(src) diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 14a4b42ca5f..13263b4cc75 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -57,11 +57,11 @@ T.on_cross(src, AM) ..() -/obj/item/grown/on_trip(mob/living/carbon/human/H) - . = ..() - if(. && seed) - for(var/datum/plant_gene/trait/T in seed.genes) - T.on_slip(src, H) +/obj/item/grown/after_slip(mob/living/carbon/human/H) + if(!seed) + return + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_slip(src, H) /obj/item/grown/throw_impact(atom/hit_atom) if(!..()) //was it caught by a mob? diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index d20413d6331..19209a680ad 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -217,11 +217,7 @@ stun_len = min(stun_len, 7) // No fun allowed - G.trip_stun = stun_len - G.trip_weaken = stun_len - G.trip_chance = 100 - G.trip_verb = TV_SLIP - G.trip_walksafe = FALSE + G.AddComponent(/datum/component/slippery, G, stun_len, stun_len, 100, 0, FALSE) /datum/plant_gene/trait/cell_charge // Cell recharging trait. Charges all mob's power cells to (potency*rate)% mark when eaten. diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 74c5a71c94b..4b6d6c68603 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -977,25 +977,30 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven /mob/living/carbon/proc/slip(description, stun, weaken, tilesSlipped, walkSafely, slipAny, slipVerb = "slip") if(flying || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK)) - return 0 + return FALSE + if((lying) && (!(tilesSlipped))) - return 0 + return FALSE + if(!(slipAny)) if(istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src if(isobj(H.shoes) && H.shoes.flags & NOSLIP) - return 0 + return FALSE + if(tilesSlipped) - for(var/t = 0, t<=tilesSlipped, t++) - spawn (t) step(src, src.dir) + for(var/i in 1 to tilesSlipped) + spawn(i) + step(src, dir) + stop_pulling() to_chat(src, "You [slipVerb]ped on [description]!") - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) + playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3) // Something something don't run with scissors moving_diagonally = 0 //If this was part of diagonal move slipping will stop it. Stun(stun) Weaken(weaken) - return 1 + return TRUE /mob/living/carbon/proc/can_eat(flags = 255) return 1 diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm index 0e5c58f968a..f6f02e3457f 100644 --- a/code/modules/pda/pdas.dm +++ b/code/modules/pda/pdas.dm @@ -38,11 +38,8 @@ desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings." ttone = "honk" - trip_stun = 8 - trip_weaken = 5 - trip_chance = 100 - trip_walksafe = TRUE - trip_verb = TV_SLIP +/obj/item/pda/clown/ComponentInitialize() + AddComponent(/datum/component/slippery, src, 8, 5, 100) /obj/item/pda/mime default_cartridge = /obj/item/cartridge/mime @@ -191,7 +188,7 @@ var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) if(M) M.m_hidden = 1 - + //Some spare PDAs in a box /obj/item/storage/box/PDAs name = "spare PDAs" diff --git a/paradise.dme b/paradise.dme index c3dcfbd3c2d..a9165f49a76 100644 --- a/paradise.dme +++ b/paradise.dme @@ -300,6 +300,7 @@ #include "code\datums\components\label.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\paintable.dm" +#include "code\datums\components\slippery.dm" #include "code\datums\components\spawner.dm" #include "code\datums\components\squeak.dm" #include "code\datums\components\waddling.dm" From b0264e9f6e1f166bb74d3360df72e77b6644d270 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 6 Jun 2020 16:08:24 -0500 Subject: [PATCH 064/151] autodoc stuff --- code/datums/components/slippery.dm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index 0ea8e313378..baa93513f0a 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -1,9 +1,12 @@ /** - This is a component that can be applied to any movable atom (mob or obj). - - While the atom has this component, any carbon mob that walks over it will slip. - Duration, tiles moved, and so on, depend on what variables are passed in when the component is added. -*/ + * # Slip Component + * + * This is a component that can be applied to any movable atom (mob or obj). + * + * While the atom has this component, any human mob that walks over it will have a chance to slip. + * Duration, tiles moved, and so on, depend on what variables are passed in when the component is added. + * + */ /datum/component/slippery /// Text that gets displayed in the slip proc, i.e. "user slips on [description]" var/description From f4a079051447eeb6692b1b46a05e28db5020c453 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 16:29:52 -0400 Subject: [PATCH 065/151] Organ processing performance (#13534) * Organ Processing Performance * more optimization * indentation error * More OOP * compensation buff --- .../reagents/chemistry/reagents/medicine.dm | 23 +++++++++ code/modules/surgery/organs/organ.dm | 51 +++++++------------ code/modules/surgery/organs/organ_external.dm | 43 ++++------------ 3 files changed, 49 insertions(+), 68 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 4a1f9213267..e90789f9d8b 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -173,6 +173,29 @@ metabolization_rate = 0.2 taste_description = "antibiotics" +/datum/reagent/medicine/spaceacillin/on_mob_life(mob/living/M) + var/list/organs_list = list() + if(iscarbon(M)) + var/mob/living/carbon/C = M + organs_list += C.internal_organs + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + organs_list += H.bodyparts + + for(var/X in organs_list) + var/obj/item/organ/O = X + if(O.germ_level < INFECTION_LEVEL_ONE) + O.germ_level = 0 //cure instantly + else if(O.germ_level < INFECTION_LEVEL_TWO) + O.germ_level = max(M.germ_level - 25, 0) //at germ_level == 500, this should cure the infection in 34 seconds + else + O.germ_level = max(M.germ_level - 10, 0) // at germ_level == 1000, this will cure the infection in 1 minutes, 14 seconds + + organs_list.Cut() + M.germ_level = max(M.germ_level - 20, 0) // Reduces the mobs germ level, too + return ..() + /datum/reagent/medicine/silver_sulfadiazine name = "Silver Sulfadiazine" id = "silver_sulfadiazine" diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index a06cbf9456b..3dab4065f7d 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -116,18 +116,19 @@ necrotize() else if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs - //** Handle antibiotics and curing infections - handle_antibiotics() - handle_germ_effects() + // Handle antibiotics and curing infections + if(germ_level) + handle_germs() + return TRUE /obj/item/organ/proc/is_preserved() if(istype(loc,/obj/item/mmi)) germ_level = max(0, germ_level - 1) // So a brain can slowly recover from being left out of an MMI - return 1 + return TRUE if(is_found_within(/obj/structure/closet/crate/freezer)) - return 1 + return TRUE if(is_found_within(/obj/machinery/clonepod)) - return 1 + return TRUE if(isturf(loc)) if(world.time - last_freezer_update_time > freezer_update_period) // I don't want to loop through everything in the tile constantly, especially since it'll be a pile of organs @@ -142,7 +143,7 @@ return is_in_freezer // I'd like static varibles, please // You can do your cool location temperature organ preserving effects here! - return 0 + return FALSE /obj/item/organ/examine(mob/user) . = ..() @@ -152,33 +153,30 @@ else . += "It looks in need of repairs." -/obj/item/organ/proc/handle_germ_effects() - //** Handle the effects of infections - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - - if(germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) +/obj/item/organ/proc/handle_germs() + if(germ_level > 0 && germ_level < INFECTION_LEVEL_ONE / 2 && prob(30)) germ_level-- - if(germ_level >= INFECTION_LEVEL_ONE/2) + if(germ_level >= INFECTION_LEVEL_ONE / 2) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes - if(antibiotics < 5 && prob(round(germ_level/6))) + if(prob(round(germ_level / 6))) germ_level++ if(germ_level >= INFECTION_LEVEL_ONE) - var/fever_temperature = (owner.dna.species.heat_level_1 - owner.dna.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.dna.species.body_temperature - owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) + var/fever_temperature = (owner.dna.species.heat_level_1 - owner.dna.species.body_temperature - 5) * min(germ_level / INFECTION_LEVEL_TWO, 1) + owner.dna.species.body_temperature + owner.bodytemperature += between(0, (fever_temperature - T20C) / BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) if(germ_level >= INFECTION_LEVEL_TWO) var/obj/item/organ/external/parent = owner.get_organ(parent_organ) //spread germs - if(antibiotics < 5 && parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) )) + if(parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE * 2 || prob(30))) parent.germ_level++ -/obj/item/organ/internal/handle_germ_effects() +/obj/item/organ/internal/handle_germs() ..() if(germ_level >= INFECTION_LEVEL_TWO) if(prob(3)) //about once every 30 seconds - receive_damage(1,silent=prob(30)) + receive_damage(1, silent = prob(30)) /obj/item/organ/proc/rejuvenate() damage = 0 @@ -200,21 +198,6 @@ /obj/item/organ/proc/is_broken() return (damage >= min_broken_damage || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))) -//Germs -/obj/item/organ/proc/handle_antibiotics() - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - - if(!germ_level || antibiotics <= 0.4) - return - - if(germ_level < INFECTION_LEVEL_ONE) - germ_level = 0 //cure instantly - else if(germ_level < INFECTION_LEVEL_TWO) - germ_level -= 24 //at germ_level == 500, this should cure the infection in 15 seconds - else - germ_level -= 8 // at germ_level == 1000, this will cure the infection in 1 minute, 15 seconds - // Let's not drag this on, medbay has only so much antibiotics - //Adds autopsy data for used_weapon. /obj/item/organ/proc/add_autopsy_data(var/used_weapon = "Unknown", var/damage) var/datum/autopsy_data/W = autopsy_data[used_weapon] diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 0ae2f4c395a..143bf1d1ed6 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -305,10 +305,10 @@ This function completely restores a damaged organ to perfect condition. if(!(status & ORGAN_BROKEN)) perma_injury = 0 - //Infections - update_germs() - else - ..() + if(..()) + if(owner.germ_level > germ_level && infection_check()) + //Open wounds can become infected + germ_level++ //Updating germ levels. Handles organ germ levels and necrosis. /* @@ -325,40 +325,16 @@ the actual time is dependent on RNG. INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without - antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level. + antitox.. Note that amputating the affected organ does in fact remove the infection from the player's body. */ -/obj/item/organ/external/proc/update_germs() - if(is_robotic() || (NO_GERMS in owner.dna.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. - germ_level = 0 - return - - if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs - //** Syncing germ levels with external wounds - handle_germ_sync() - - //** Handle antibiotics and curing infections - handle_antibiotics() - - //** Handle the effects of infections - handle_germ_effects() - -/obj/item/organ/external/proc/handle_germ_sync() - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if(antibiotics < 5) - //Open wounds can become infected - if(owner.germ_level > germ_level && infection_check()) - germ_level++ - -/obj/item/organ/external/handle_germ_effects() +/obj/item/organ/external/handle_germs() if(germ_level < INFECTION_LEVEL_TWO) return ..() - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") - if(germ_level >= INFECTION_LEVEL_TWO) //spread the infection to internal organs var/obj/item/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once @@ -383,17 +359,16 @@ Note that amputating the affected organ does in fact remove the infection from t if(children) for(var/obj/item/organ/external/child in children) if(child.germ_level < germ_level && !child.is_robotic()) - if(child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) + if(child.germ_level < INFECTION_LEVEL_ONE * 2 || prob(30)) child.germ_level++ if(parent) if(parent.germ_level < germ_level && !parent.is_robotic()) - if(parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) + if(parent.germ_level < INFECTION_LEVEL_ONE * 2 || prob(30)) parent.germ_level++ - if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections + if(germ_level >= INFECTION_LEVEL_THREE) necrotize() - germ_level++ owner.adjustToxLoss(1) From 40968ce90782f8aefde11bcf1c05ebaf8ae96140 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 17:32:25 -0400 Subject: [PATCH 066/151] Dramatically Cuts Object Processing Down (#13564) --- code/game/objects/items/tools/welder.dm | 23 ++++++---- code/modules/reagents/chemistry/holder.dm | 17 -------- code/modules/reagents/chemistry/reagents.dm | 6 ++- .../chemistry/reagents/pyrotechnic.dm | 42 ++++++++++++------- .../reagents/chemistry/reagents/toxins.dm | 18 +++++--- paradise.dme | 4 +- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/code/game/objects/items/tools/welder.dm b/code/game/objects/items/tools/welder.dm index 270a44ee559..49f5bb4073b 100644 --- a/code/game/objects/items/tools/welder.dm +++ b/code/game/objects/items/tools/welder.dm @@ -35,10 +35,12 @@ ..() create_reagents(maximum_fuel) reagents.add_reagent("fuel", maximum_fuel) - if(refills_over_time) - reagents.reagents_generated_per_cycle += list("fuel" = 1) update_icon() +/obj/item/weldingtool/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + /obj/item/weldingtool/examine(mob/user) . = ..() if(get_dist(user, src) <= 0) @@ -49,11 +51,15 @@ return FIRELOSS /obj/item/weldingtool/process() - var/turf/T = get_turf(src) - if(T) // Implants for instance won't find a turf - T.hotspot_expose(2500, 5) - if(prob(5)) - remove_fuel(1) + if(tool_enabled) + var/turf/T = get_turf(src) + if(T) // Implants for instance won't find a turf + T.hotspot_expose(2500, 5) + if(prob(5)) + remove_fuel(1) + if(refills_over_time) + if(GET_FUEL < maximum_fuel) + reagents.add_reagent("fuel", 1) ..() /obj/item/weldingtool/attack_self(mob/user) @@ -77,7 +83,8 @@ playsound(loc, activation_sound, 50, 1) set_light(light_intensity) else - STOP_PROCESSING(SSobj, src) + if(!refills_over_time) + STOP_PROCESSING(SSobj, src) damtype = BRUTE force = 3 hitsound = "swing_hit" diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 5a0069632a2..8811d8f2584 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -13,7 +13,6 @@ var/list/datum/reagent/addiction_list = new/list() var/list/addiction_threshold_accumulated = new/list() var/flags - var/list/reagents_generated_per_cycle = new/list() /datum/reagents/New(maximum = 100, temperature_minimum, temperature_maximum) maximum_volume = maximum @@ -21,8 +20,6 @@ temperature_min = temperature_minimum if(temperature_maximum) temperature_max = temperature_maximum - if(!(flags & REAGENT_NOREACT)) - START_PROCESSING(SSobj, src) //I dislike having these here but map-objects are initialised before world/New() is called. >_> if(!GLOB.chemical_reagents_list) //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -361,23 +358,10 @@ od_chems.Add(R.id) return od_chems -/datum/reagents/process() - if(flags & REAGENT_NOREACT) - STOP_PROCESSING(SSobj, src) - return - for(var/thing in reagents_generated_per_cycle) - add_reagent(thing, reagents_generated_per_cycle[thing]) - for(var/datum/reagent/R in reagent_list) - R.on_tick() - /datum/reagents/proc/set_reacting(react = TRUE) if(react) - // Order is important, process() can remove from processing if - // the flag is present flags &= ~(REAGENT_NOREACT) - START_PROCESSING(SSobj, src) else - STOP_PROCESSING(SSobj, src) flags |= REAGENT_NOREACT /* @@ -906,7 +890,6 @@ /datum/reagents/Destroy() . = ..() - STOP_PROCESSING(SSobj, src) QDEL_LIST(reagent_list) reagent_list = null QDEL_LIST(addiction_list) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index f3b4181062e..7f0ed2c91dc 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -120,8 +120,10 @@ return // Called every time reagent containers process. -/datum/reagent/proc/on_tick(data) - return +/datum/reagent/process() + if(!holder || holder.flags & REAGENT_NOREACT) + return FALSE + return TRUE // Called when the reagent container is hit by an explosion /datum/reagent/proc/on_ex_act(severity) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index dc79b5f4b3c..9d85459f465 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -333,19 +333,26 @@ process_flags = ORGANIC | SYNTHETIC taste_description = "bitterness" +/datum/reagent/cryostylane/on_new(data) + ..() + START_PROCESSING(SSprocessing, src) + +/datum/reagent/cryostylane/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + /datum/reagent/cryostylane/on_mob_life(mob/living/M) //TODO: code freezing into an ice cube if(M.reagents.has_reagent("oxygen")) M.reagents.remove_reagent("oxygen", 1) M.bodytemperature -= 30 return ..() -/datum/reagent/cryostylane/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 2) - holder.remove_reagent("cryostylane", 2) - holder.temperature_reagents(holder.chem_temp - 200) - holder.temperature_reagents(holder.chem_temp - 200) - ..() +/datum/reagent/cryostylane/process() + if(..()) + if(holder.has_reagent("oxygen")) + holder.remove_reagent("oxygen", 2) + holder.remove_reagent("cryostylane", 2) + holder.temperature_reagents(holder.chem_temp - 200) /datum/reagent/cryostylane/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume) if(method == REAGENT_TOUCH) @@ -368,19 +375,26 @@ process_flags = ORGANIC | SYNTHETIC taste_description = "bitterness" +/datum/reagent/pyrosium/on_new(data) + ..() + START_PROCESSING(SSprocessing, src) + +/datum/reagent/pyrosium/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + /datum/reagent/pyrosium/on_mob_life(mob/living/M) if(M.reagents.has_reagent("oxygen")) M.reagents.remove_reagent("oxygen", 1) M.bodytemperature += 30 return ..() -/datum/reagent/pyrosium/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 2) - holder.remove_reagent("pyrosium", 2) - holder.temperature_reagents(holder.chem_temp + 200) - holder.temperature_reagents(holder.chem_temp + 200) - ..() +/datum/reagent/pyrosium/process() + if(..()) + if(holder.has_reagent("oxygen")) + holder.remove_reagent("oxygen", 2) + holder.remove_reagent("pyrosium", 2) + holder.temperature_reagents(holder.chem_temp + 200) /datum/reagent/firefighting_foam name = "Firefighting foam" diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 28ed544cb18..dec256ac455 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -192,6 +192,14 @@ color = "#7DFF00" taste_description = "slime" +/datum/reagent/stable_mutagen/on_new(data) + ..() + START_PROCESSING(SSprocessing, src) + +/datum/reagent/stable_mutagen/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + /datum/reagent/stable_mutagen/on_mob_life(mob/living/M) if(!ishuman(M) || !M.dna) return @@ -212,11 +220,11 @@ return ..() -/datum/reagent/stable_mutagen/on_tick() - var/datum/reagent/blood/B = locate() in holder.reagent_list - if(B && islist(B.data) && !data) - data = B.data.Copy() - ..() +/datum/reagent/stable_mutagen/process() + if(..()) + var/datum/reagent/blood/B = locate() in holder.reagent_list + if(B && islist(B.data) && !data) + data = B.data.Copy() /datum/reagent/romerol name = "romerol" diff --git a/paradise.dme b/paradise.dme index f2dbf198ebd..c137faf236f 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1472,6 +1472,8 @@ #include "code\modules\events\anomaly_grav.dm" #include "code\modules\events\anomaly_pyro.dm" #include "code\modules\events\anomaly_vortex.dm" +#include "code\modules\events\apc_overload.dm" +#include "code\modules\events\apc_short.dm" #include "code\modules\events\aurora_caelus.dm" #include "code\modules\events\blob.dm" #include "code\modules\events\brand_intelligence.dm" @@ -1485,8 +1487,6 @@ #include "code\modules\events\event_procs.dm" #include "code\modules\events\false_alarm.dm" #include "code\modules\events\floorcluwne.dm" -#include "code\modules\events\apc_overload.dm" -#include "code\modules\events\apc_short.dm" #include "code\modules\events\headcrabs.dm" #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" From 73e8781b0ad9c51a5593868e0f9330d38e7e47a5 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 18:52:44 -0400 Subject: [PATCH 067/151] Fixes Excessive PDA Creation (#13561) --- code/game/machinery/PDApainter.dm | 16 ++-- code/modules/clothing/chameleon.dm | 135 ++++++++++++++++++++--------- 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 3185cdcddd4..332df41f086 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -30,15 +30,11 @@ /obj/machinery/pdapainter/New() ..() var/blocked = list(/obj/item/pda/silicon/ai, /obj/item/pda/silicon/robot, /obj/item/pda/silicon/pai, /obj/item/pda/heads, - /obj/item/pda/clear, /obj/item/pda/syndicate) + /obj/item/pda/clear, /obj/item/pda/syndicate, /obj/item/pda/chameleon, /obj/item/pda/chameleon/broken) - for(var/P in typesof(/obj/item/pda)-blocked) - var/obj/item/pda/D = new P - - //D.name = "PDA Style [colorlist.len+1]" //Gotta set the name, otherwise it all comes up as "PDA" - D.name = D.icon_state //PDAs don't have unique names, but using the sprite names works. - - src.colorlist += D + for(var/thing in typesof(/obj/item/pda) - blocked) + var/obj/item/pda/P = thing + colorlist[initial(P.icon_state)] = initial(P.desc) /obj/machinery/pdapainter/Destroy() QDEL_NULL(storedpda) @@ -104,8 +100,8 @@ if(!in_range(src, user)) return - storedpda.icon_state = P.icon_state - storedpda.desc = P.desc + storedpda.icon_state = P + storedpda.desc = colorlist[P] else to_chat(user, "The [src] is empty.") diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index da0873f162f..38b49314667 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -9,6 +9,10 @@ ..() initialize_outfits() +/datum/action/chameleon_outfit/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + /datum/action/chameleon_outfit/proc/initialize_outfits() var/static/list/standard_outfit_options if(!standard_outfit_options) @@ -140,29 +144,29 @@ UpdateButtonIcon() /datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item) - // Species-related variables are lists, which can not be retrieved using initial(). As such, we need to instantiate the picked item. - var/obj/item/P = new picked_item(null) - - target.name = P.name - target.desc = P.desc - target.icon_state = P.icon_state + target.name = initial(picked_item.name) + target.desc = initial(picked_item.desc) + target.icon_state = initial(picked_item.icon_state) if(isitem(target)) var/obj/item/I = target - I.item_state = P.item_state - I.item_color = P.item_color + I.item_state = initial(picked_item.item_state) + I.item_color = initial(picked_item.item_color) - I.icon_override = P.icon_override - I.sprite_sheets = P.sprite_sheets + I.icon_override = initial(picked_item.icon_override) + if(initial(picked_item.sprite_sheets)) + // Species-related variables are lists, which can not be retrieved using initial(). As such, we need to instantiate the picked item. + var/obj/item/P = new picked_item(null) + I.sprite_sheets = P.sprite_sheets + qdel(P) - if(istype(I, /obj/item/clothing) && istype(P, /obj/item/clothing)) + if(istype(I, /obj/item/clothing) && istype(initial(picked_item), /obj/item/clothing)) var/obj/item/clothing/CL = I - var/obj/item/clothing/PCL = P - CL.flags_cover = PCL.flags_cover + var/obj/item/clothing/PCL = picked_item + CL.flags_cover = initial(PCL.flags_cover) - target.icon = P.icon - qdel(P) + target.icon = initial(picked_item.icon) /datum/action/item_action/chameleon/change/Trigger() if(!IsAvailable()) @@ -198,7 +202,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/under/chameleon/Initialize() +/obj/item/clothing/under/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/under @@ -206,11 +210,15 @@ chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/under, /obj/item/clothing/under/color, /obj/item/clothing/under/rank), only_root_path = TRUE) chameleon_action.initialize_disguises() +/obj/item/clothing/under/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/under/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/under/chameleon/broken/Initialize() +/obj/item/clothing/under/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -229,7 +237,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/suit/chameleon/Initialize() +/obj/item/clothing/suit/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/suit @@ -237,11 +245,15 @@ chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/suit/armor/abductor), only_root_path = TRUE) chameleon_action.initialize_disguises() +/obj/item/clothing/suit/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/suit/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/suit/chameleon/broken/Initialize() +/obj/item/clothing/suit/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -261,7 +273,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/glasses/chameleon/Initialize() +/obj/item/clothing/glasses/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/glasses @@ -269,11 +281,15 @@ chameleon_action.chameleon_blacklist = list() chameleon_action.initialize_disguises() +/obj/item/clothing/glasses/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/glasses/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/glasses/chameleon/broken/Initialize() +/obj/item/clothing/glasses/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -289,7 +305,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/glasses/hud/security/chameleon/Initialize() +/obj/item/clothing/glasses/hud/security/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/glasses @@ -297,11 +313,15 @@ chameleon_action.chameleon_blacklist = list() chameleon_action.initialize_disguises() +/obj/item/clothing/glasses/hud/security/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/glasses/hud/security/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/glasses/hud/security/chameleon/broken/Initialize() +/obj/item/clothing/glasses/hud/security/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -316,7 +336,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/gloves/chameleon/Initialize() +/obj/item/clothing/gloves/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/gloves @@ -324,11 +344,15 @@ chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/gloves, /obj/item/clothing/gloves/color), only_root_path = TRUE) chameleon_action.initialize_disguises() +/obj/item/clothing/gloves/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/gloves/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/gloves/chameleon/broken/Initialize() +/obj/item/clothing/gloves/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -347,7 +371,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/head/chameleon/Initialize() +/obj/item/clothing/head/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/head @@ -355,11 +379,15 @@ chameleon_action.chameleon_blacklist = list() chameleon_action.initialize_disguises() +/obj/item/clothing/head/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/head/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/head/chameleon/broken/Initialize() +/obj/item/clothing/head/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -389,7 +417,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/mask/chameleon/Initialize() +/obj/item/clothing/mask/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) @@ -402,13 +430,14 @@ /obj/item/clothing/mask/chameleon/Destroy() QDEL_NULL(voice_changer) + QDEL_NULL(chameleon_action) return ..() /obj/item/clothing/mask/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/clothing/mask/chameleon/broken/Initialize() +/obj/item/clothing/mask/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -423,7 +452,7 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/shoes/chameleon/Initialize() +/obj/item/clothing/shoes/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/shoes @@ -431,6 +460,10 @@ chameleon_action.chameleon_blacklist = list() chameleon_action.initialize_disguises() +/obj/item/clothing/shoes/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/clothing/shoes/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() @@ -442,7 +475,7 @@ desc = "A pair of black shoes." flags = NOSLIP -/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize() +/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -455,18 +488,22 @@ var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/storage/backpack/chameleon/Initialize() +/obj/item/storage/backpack/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/storage/backpack chameleon_action.chameleon_name = "Backpack" chameleon_action.initialize_disguises() +/obj/item/storage/backpack/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/storage/backpack/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/storage/backpack/chameleon/broken/Initialize() +/obj/item/storage/backpack/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -475,7 +512,7 @@ desc = "Holds tools." var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/storage/belt/chameleon/Initialize() +/obj/item/storage/belt/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) @@ -483,11 +520,15 @@ chameleon_action.chameleon_name = "Belt" chameleon_action.initialize_disguises() +/obj/item/storage/belt/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/storage/belt/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/storage/belt/chameleon/broken/Initialize() +/obj/item/storage/belt/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -495,18 +536,22 @@ name = "radio headset" var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/radio/headset/chameleon/Initialize() +/obj/item/radio/headset/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/radio/headset chameleon_action.chameleon_name = "Headset" chameleon_action.initialize_disguises() +/obj/item/radio/headset/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/radio/headset/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/radio/headset/chameleon/broken/Initialize() +/obj/item/radio/headset/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -514,7 +559,7 @@ name = "PDA" var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/pda/chameleon/Initialize() +/obj/item/pda/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/pda @@ -522,24 +567,32 @@ chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/pda/heads), only_root_path = TRUE) chameleon_action.initialize_disguises() +/obj/item/pda/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + /obj/item/pda/chameleon/emp_act(severity) . = ..() chameleon_action.emp_randomise() -/obj/item/pda/chameleon/broken/Initialize() +/obj/item/pda/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) /obj/item/stamp/chameleon var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/stamp/chameleon/Initialize() +/obj/item/stamp/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/stamp chameleon_action.chameleon_name = "Stamp" chameleon_action.initialize_disguises() -/obj/item/stamp/chameleon/broken/Initialize() +/obj/item/stamp/chameleon/Destroy() + QDEL_NULL(chameleon_action) + return ..() + +/obj/item/stamp/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) From fad4b8aafb5ed6545e8ad9e225593e111428a608 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 18:57:11 -0400 Subject: [PATCH 068/151] Fixes Epilepsy Having Epilepsy (#13563) --- code/game/dna/genes/disabilities.dm | 2 +- code/game/dna/genes/vg_powers.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index 48ffb648121..8b8a86009b9 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -65,7 +65,7 @@ /datum/dna/gene/disability/epilepsy/OnMobLife(mob/living/carbon/human/H) if((prob(1) && H.paralysis < 1)) - H.visible_message("[src] starts having a seizure!","You have a seizure!") + H.visible_message("[H] starts having a seizure!","You have a seizure!") H.Paralyse(10) H.Jitter(1000) diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index cc54d817752..9092448e398 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -174,7 +174,7 @@ M.update_dna() - M.visible_message("[src] morphs and changes [p_their()] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") + M.visible_message("[M] morphs and changes [M.p_their()] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") /datum/dna/gene/basic/grant_spell/remotetalk name = "Telepathy" From db633830fd4c4e40505409647adbc7607cdddde2 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 19:12:42 -0400 Subject: [PATCH 069/151] Fixes Vampire Vision (#13562) * Fixes Vampire Vision * comments --- code/game/gamemodes/vampire/vampire.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 6c22313ef6e..3caf860383d 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -227,6 +227,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(istype(spell, /obj/effect/proc_holder/spell)) owner.mind.AddSpell(spell) powers += spell + owner.update_sight() // Life updates conditionally, so we need to update sight here in case the vamp gets new vision based on his powers. Maybe one day refactor to be more OOP and on the vampire's ability datum. /datum/vampire/proc/get_ability(path) for(var/P in powers) @@ -244,6 +245,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha powers -= ability owner.mind.spell_list.Remove(ability) qdel(ability) + owner.update_sight() // Life updates conditionally, so we need to update sight here in case the vamp loses his vision based powers. Maybe one day refactor to be more OOP and on the vampire's ability datum. /datum/vampire/proc/update_owner(var/mob/living/carbon/human/current) //Called when a vampire gets cloned. This updates vampire.owner to the new body. if(current.mind && current.mind.vampire && current.mind.vampire.owner && (current.mind.vampire.owner != current)) From 033b03f3861de39a3c3721a6628c97010690f0d8 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Sun, 7 Jun 2020 19:19:45 -0400 Subject: [PATCH 070/151] NanoUI Brig Timers (#13487) * Initial NanoUI interface * Fix release button * Adding back flash function to brig timer * Updates to layout * Changed to popups for each entry, correctable * Fixes * Changed prisoner status to defines * Switch to defines * Re-add redundant printing check * Adds missing newline --- code/game/machinery/doors/brigdoors.dm | 192 +++++++++++-------------- nano/templates/brig_timer.tmpl | 91 ++++++++++++ 2 files changed, 174 insertions(+), 109 deletions(-) create mode 100644 nano/templates/brig_timer.tmpl diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 29549a05630..fc758d446f9 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -2,6 +2,7 @@ #define FONT_SIZE "5pt" #define FONT_COLOR "#09f" #define FONT_STYLE "Small Fonts" +#define CELL_NONE "None" /////////////////////////////////////////////////////////////////////////////////////////////// // Brig Door control displays. @@ -31,10 +32,13 @@ maptext_height = 26 maptext_width = 32 maptext_y = -1 - var/occupant = "None" - var/crimes = "None" + var/occupant = CELL_NONE + var/crimes = CELL_NONE var/time = 0 - var/officer = "None" + var/officer = CELL_NONE + var/prisoner_name = "" + var/prisoner_charge = "" + var/prisoner_time = "" /obj/machinery/door_timer/New() GLOB.celltimers_list += src @@ -45,33 +49,29 @@ return ..() /obj/machinery/door_timer/proc/print_report() - var/logname = input(usr, "Name of the guilty?","[id] log name") - var/logcharges = stripped_multiline_input(usr, "What have they been charged with?","[id] log charges") - - if(!logname || !logcharges) + if(occupant == CELL_NONE || crimes == CELL_NONE) return 0 - occupant = logname - crimes = logcharges + time = timetoset officer = usr.name for(var/obj/machinery/computer/prisoner/C in GLOB.prisoncomputer_list) var/obj/item/paper/P = new /obj/item/paper(C.loc) - P.name = "[id] log - [logname] [station_time_timestamp()]" + P.name = "[id] log - [occupant] [station_time_timestamp()]" P.info = "
[id] - Brig record



" P.info += {"
[station_name()] - Security Department

Admission data:

Log generated at: [station_time_timestamp()]
- Detainee: [logname]
+ Detainee: [occupant]
Duration: [seconds_to_time(timetoset / 10)]
- Charge(s): [logcharges]
+ Charge(s): [crimes]
Arresting Officer: [usr.name]


This log file was generated automatically upon activation of a cell timer."} playsound(C.loc, "sound/goonstation/machines/printer_dotmatrix.ogg", 50, 1) GLOB.cell_logs += P - var/datum/data/record/G = find_record("name", logname, GLOB.data_core.general) + var/datum/data/record/G = find_record("name", occupant, GLOB.data_core.general) var/prisoner_drank = "unknown" var/prisoner_trank = "unknown" if(G) @@ -80,9 +80,9 @@ if(G.fields["real_rank"]) // Ignore alt job titles - necessary for lookups prisoner_trank = G.fields["real_rank"] - var/datum/data/record/R = find_security_record("name", logname) + var/datum/data/record/R = find_security_record("name", occupant) - var/announcetext = "Detainee [logname] ([prisoner_drank]) has been incarcerated for [seconds_to_time(timetoset / 10)] for the charges of, '[logcharges]'. \ + var/announcetext = "Detainee [occupant] ([prisoner_drank]) has been incarcerated for [seconds_to_time(timetoset / 10)] for the charges of: '[crimes]'. \ Arresting Officer: [usr.name].[R ? "" : " Detainee record not found, manual record update required."]" Radio.autosay(announcetext, name, "Security", list(z)) @@ -91,7 +91,7 @@ if(R) prisoner = R - R.fields["criminal"] = "Incarcerated" + R.fields["criminal"] = SEC_RECORD_STATUS_INCARCERATED var/mob/living/carbon/human/M = usr var/rank = "UNKNOWN RANK" if(istype(M) && M.wear_id) @@ -99,7 +99,7 @@ rank = I.assignment if(!R.fields["comments"] || !islist(R.fields["comments"])) //copied from security computer code because apparently these need to be initialized R.fields["comments"] = list() - R.fields["comments"] += "Autogenerated by [name] on [GLOB.current_date_string] [station_time_timestamp()]
Sentenced to [timetoset/10] seconds for the charges of \"[logcharges]\" by [rank] [usr.name]." + R.fields["comments"] += "Autogenerated by [name] on [GLOB.current_date_string] [station_time_timestamp()]
Sentenced to [timetoset/10] seconds for the charges of \"[crimes]\" by [rank] [usr.name]." update_all_mob_security_hud() return 1 @@ -175,12 +175,10 @@ if(timing) if(timeleft() <= 0) Radio.autosay("Timer has expired. Releasing prisoner.", name, "Security", list(z)) - occupant = "None" + occupant = CELL_NONE timer_end() // open doors, reset timer, clear status screen timing = 0 . = PROCESS_KILL - - updateUsrDialog() update_icon() else timer_end() @@ -203,8 +201,8 @@ if(!printed) if(!print_report()) - timing = 0 - return 0 + timing = FALSE + return FALSE // Set releasetime releasetime = world.timeofday + timetoset @@ -237,14 +235,14 @@ return 0 // Reset vars - occupant = "None" - crimes = "None" + occupant = CELL_NONE + crimes = CELL_NONE time = 0 - officer = "None" + officer = CELL_NONE releasetime = 0 printed = 0 if(prisoner) - prisoner.fields["criminal"] = "Released" + prisoner.fields["criminal"] = SEC_RECORD_STATUS_RELEASED update_all_mob_security_hud() prisoner = null @@ -290,10 +288,11 @@ //Allows AIs to use door_timer, see human attack_hand function below /obj/machinery/door_timer/attack_ai(mob/user) - interact(user) + attack_hand(user) + ui_interact(user) /obj/machinery/door_timer/attack_ghost(mob/user) - interact(user) + ui_interact(user) //Allows humans to use door_timer //Opens dialog window when someone clicks on door timer @@ -302,98 +301,72 @@ /obj/machinery/door_timer/attack_hand(mob/user) if(..()) return - interact(user) + ui_interact(user) -/obj/machinery/door_timer/interact(mob/user) - // Used for the 'time left' display - var/second = round(timeleft() % 60) - var/minute = round((timeleft() - second) / 60) +/obj/machinery/door_timer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "brig_timer.tmpl", "Brig Timer", 500, 400) + ui.open() + ui.set_auto_update(TRUE) - // Used for 'set timer' - var/setsecond = round((timetoset / 10) % 60) - var/setminute = round(((timetoset / 10) - setsecond) / 60) +/obj/machinery/door_timer/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) + var/data[0] + data["cell_id"] = name + data["occupant"] = occupant + data["crimes"] = crimes + data["brigged_by"] = officer + data["time_set"] = seconds_to_clock(time / 10) + data["time_left"] = seconds_to_clock(timeleft()) + data["timing"] = timing + data["isAllowed"] = allowed(user) + data["prisoner_name"] = prisoner_name + data["prisoner_charge"] = prisoner_charge + data["prisoner_time"] = prisoner_time - user.set_machine(src) + return data - // dat - var/dat = "
Timer System:" - dat += " Door [id] controls
" - - // Start/Stop timer - if(timing) - dat += "Stop Timer and open door
" - else - dat += "Activate Timer and close door
" - - // Time Left display (uses releasetime) - dat += "Time Left: [(minute ? text("[minute]:") : null)][second]
" - dat += "
" - - // Set Timer display (uses timetoset) - if(timing) - dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond] Set
" - else - dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond]
" - - // Controls - dat += "Input Time" - - // Mounted flash controls - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - dat += "
Flash Charging" - else - dat += "
Activate Flash" - - dat += "

Close" - - var/datum/browser/popup = new(user, "door_timer", name, 400, 500) - popup.set_content(dat) - popup.open() - - -//Function for using door_timer dialog input, checks if user has permission -// href_list to -// "timing" turns on timer -// "tp" value to modify timer -// "fc" activates flasher -// "change" resets the timer to the timetoset amount while the timer is counting down -// Also updates dialog window and timer icon /obj/machinery/door_timer/Topic(href, href_list) - if(..()) - return 1 - if(!allowed(usr) && !usr.can_admin_interact()) return 1 - usr.set_machine(src) - - if(href_list["timing"]) - timing = text2num(href_list["timing"]) - - if(timing) - timer_start() - else - timer_end() - if(!isobserver(usr)) //spooky admin ghosts are in your brig, releasing your prisoners - Radio.autosay("Timer stopped manually by [usr.name].", name, "Security", list(z)) - - else - if(href_list["settime"]) - var/time = min(max(round(return_time_input(usr)), 0), 3600) - timeset(time) - - if(href_list["fc"]) - for(var/obj/machinery/flasher/F in targets) + if(href_list["flash"]) + for(var/obj/machinery/flasher/F in targets) + if(F.last_flash && (F.last_flash + 150) > world.time) + to_chat(usr, "Flash still charging.") + else F.flash() - if(href_list["change"]) - printed = 1 - timer_start() + if(href_list["release"]) + var/obj/machinery/door_timer/T = locate(href_list["release"]) + if(timing) + T.timer_end() + T.Radio.autosay("Timer stopped manually from cell control.", T.name, "Security", list(z)) + ui_interact(usr) - add_fingerprint(usr) - updateUsrDialog() - update_icon() + if(href_list["prisoner_name"]) + prisoner_name = input("Prisoner Name:", name, prisoner_name) as text|null + + if(href_list["prisoner_charge"]) + prisoner_charge = input("Prisoner Charge:", name, prisoner_charge) as text|null + + if(href_list["prisoner_time"]) + prisoner_time = input("Prisoner Time (in minutes):", name, prisoner_time) as num|null + prisoner_time = min(max(round(prisoner_time), 0), 60) + + if(href_list["set_timer"]) + if(!prisoner_name || !prisoner_charge || !prisoner_time) + return + timeset(prisoner_time * 60) + occupant = prisoner_name + crimes = prisoner_charge + prisoner_name = "" + prisoner_charge = "" + prisoner_time = "" + timing = TRUE + timer_start() + ui_interact(usr) + update_icon() //icon update function @@ -502,3 +475,4 @@ #undef FONT_COLOR #undef FONT_STYLE #undef CHARS_PER_LINE +#undef CELL_NONE diff --git a/nano/templates/brig_timer.tmpl b/nano/templates/brig_timer.tmpl new file mode 100644 index 00000000000..2cd1ab73a23 --- /dev/null +++ b/nano/templates/brig_timer.tmpl @@ -0,0 +1,91 @@ + +
+
+ Cell: +
+
+ {{:data.cell_id}} +
+
+
+
+ Occupant: +
+
+ {{:data.occupant}} +
+
+
+
+ Crimes: +
+
+ {{:data.crimes}} +
+
+
+
+ Brigged By: +
+
+ {{:data.brigged_by}} +
+
+
+
+ Time Brigged For: +
+
+ {{:data.time_set}} +
+
+
+
+ Time Left: +
+
+ {{:data.time_left}} +
+
+{{if data.isAllowed}} +
+
+ Actions: +
+
+ {{:helper.link('Flash', 'flash', {'flash' : 1}, null, data.isAllowed ? '' : 'dsabled')}} + {{:helper.link('Release', null, {'release' : 1}, null, data.isAllowed ? '' : 'disabled')}} +
+
+ {{if !data.timing}} +

Inmate Information

+
+
+ Name: +
+
+ {{:helper.link('Set', 'pencil', {'prisoner_name' : 'input'})}} {{:data.prisoner_name}} +
+
+
+
+ Charge: +
+
+ {{:helper.link('Set', 'pencil', {'prisoner_charge' : 'input'})}} {{:data.prisoner_charge}} +
+
+
+
+ Time (in minutes): +
+
+ {{:helper.link('Set', 'pencil', {'prisoner_time' : 'input'})}} {{:data.prisoner_time}} +
+
+ {{:helper.link('Submit', null, {'set_timer' : 1}, null, data.isAllowed ? '' : 'disabled')}} + {{/if}} +{{/if}} \ No newline at end of file From 38403e1bc7e531dd5c248b5cd7a6e3282afc4112 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Sun, 7 Jun 2020 19:26:23 -0400 Subject: [PATCH 071/151] Fixes Shoe Shackle Handcuff Upgrading (#13568) * Fixes Shoe Shackle Handcuff Upgrading * better --- code/modules/clothing/shoes/colour.dm | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 0bf54e8692f..5bf6b90c98e 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -86,21 +86,25 @@ name = "orange shoes" icon_state = "orange" item_color = "orange" + var/obj/item/restraints/handcuffs/shackles -/obj/item/clothing/shoes/orange/attack_self(mob/user as mob) - if(src.chained) - src.chained = null - src.slowdown = SHOES_SLOWDOWN - new /obj/item/restraints/handcuffs( user.loc ) - src.icon_state = "orange" - return +/obj/item/clothing/shoes/orange/Destroy() + QDEL_NULL(shackles) + return ..() -/obj/item/clothing/shoes/orange/attackby(obj/H, loc, params) - ..() - if(istype(H, /obj/item/restraints/handcuffs) && !chained && !(H.flags & NODROP)) - if(src.icon_state != "orange") return - qdel(H) - src.chained = 1 - src.slowdown = 15 - src.icon_state = "orange1" - return +/obj/item/clothing/shoes/orange/attack_self(mob/user) + if(shackles) + user.put_in_hands(shackles) + shackles = null + slowdown = SHOES_SLOWDOWN + icon_state = "orange" + +/obj/item/clothing/shoes/orange/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/restraints/handcuffs) && !shackles) + if(user.drop_item()) + I.forceMove(src) + shackles = I + slowdown = 15 + icon_state = "orange1" + return + return ..() From 0e9efb73be1152c49b0f9e3f14a9514fe5718b5e Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Mon, 8 Jun 2020 09:13:22 +0100 Subject: [PATCH 072/151] Gamebreaking bug fix immediately --- code/controllers/subsystem.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 4a125003389..68ee4bfeace 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -1,7 +1,7 @@ /datum/controller/subsystem // Metadata; you should define these. - name = "fire coderbus" //name of the subsystem + name = "fire codertrain" //name of the subsystem var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order. var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep From 44e3713c6f35159c2562677fd498af93d3c01d5c Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 8 Jun 2020 01:39:33 -0500 Subject: [PATCH 073/151] repair droid fix --- code/game/mecha/equipment/tools/other_tools.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 43937ab1111..61ba683ad18 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -206,6 +206,7 @@ /obj/item/mecha_parts/mecha_equipment/repair_droid/detach() chassis.overlays -= droid_overlay STOP_PROCESSING(SSobj, src) + return ..() /obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() if(!chassis) return From f6a3a44cb3cad69312b246fc438ad18b5697e482 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 8 Jun 2020 19:38:12 -0400 Subject: [PATCH 074/151] Adds Swarming Component --- code/datums/components/swarming.dm | 55 +++++++++++++++++++ code/game/atoms_movable.dm | 11 ++-- code/game/mecha/mecha.dm | 2 +- code/game/objects/effects/spiders.dm | 1 + .../carbon/alien/humanoid/humanoid_defense.dm | 2 +- .../carbon/alien/larva/larva_defense.dm | 2 +- code/modules/mob/living/living.dm | 6 +- .../living/simple_animal/animal_defense.dm | 2 +- .../mob/living/simple_animal/hostile/bees.dm | 1 + .../simple_animal/hostile/mining/hivelord.dm | 1 + .../simple_animal/hostile/spaceworms.dm | 2 +- .../living/simple_animal/hostile/syndicate.dm | 7 ++- .../living/simple_animal/posessed_object.dm | 2 +- paradise.dme | 1 + 14 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 code/datums/components/swarming.dm diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm new file mode 100644 index 00000000000..c9d20f1f702 --- /dev/null +++ b/code/datums/components/swarming.dm @@ -0,0 +1,55 @@ +/datum/component/swarming + var/offset_x = 0 + var/offset_y = 0 + var/is_swarming = FALSE + var/list/swarm_members = list() + +/datum/component/swarming/Initialize(max_x = 24, max_y = 24) + if(!ismovableatom(parent)) + return COMPONENT_INCOMPATIBLE + offset_x = rand(-max_x, max_x) + offset_y = rand(-max_y, max_y) + + RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm) + RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm) + +/datum/component/swarming/Destroy() + for(var/other in swarm_members) + var/datum/component/swarming/other_swarm = other + other_swarm.swarm_members -= src + if(!other_swarm.swarm_members.len) + other_swarm.unswarm() + swarm_members = null + return ..() + +/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM) + var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming) + if(!other_swarm) + return + swarm() + swarm_members |= other_swarm + other_swarm.swarm() + other_swarm.swarm_members |= src + +/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM) + var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming) + if(!other_swarm || !(other_swarm in swarm_members)) + return + swarm_members -= other_swarm + if(!swarm_members.len) + unswarm() + other_swarm.swarm_members -= src + if(!other_swarm.swarm_members.len) + other_swarm.unswarm() + +/datum/component/swarming/proc/swarm() + var/atom/movable/owner = parent + if(!is_swarming) + is_swarming = TRUE + animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2) + +/datum/component/swarming/proc/unswarm() + var/atom/movable/owner = parent + if(is_swarming) + animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2) + is_swarming = FALSE diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ac77d3d4553..9f2a0e09aee 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -233,6 +233,9 @@ SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM) SEND_SIGNAL(AM, COMSIG_CROSSED_MOVABLE, src) +/atom/movable/Uncrossed(atom/movable/AM) + SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM) + /atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump(). if(A && yes) SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A) @@ -501,7 +504,7 @@ target.fingerprintshidden += fingerprintshidden target.fingerprintslast = fingerprintslast -/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && (visual_effect_icon || used_item)) do_item_attack_animation(A, visual_effect_icon, used_item) @@ -509,10 +512,6 @@ return //don't do an animation if attacking self var/pixel_x_diff = 0 var/pixel_y_diff = 0 - var/final_pixel_y = initial(pixel_y) - if(end_pixel_y) - final_pixel_y = end_pixel_y - var/direction = get_dir(src, A) if(direction & NORTH) pixel_y_diff = 8 @@ -525,7 +524,7 @@ pixel_x_diff = -8 animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2) + animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, time = 2) /atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) var/image/I diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 610436406d8..4234064874a 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1454,7 +1454,7 @@ ..() -/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect) if(selected) used_item = selected diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index d97663759af..7af5d7a998f 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -98,6 +98,7 @@ pixel_x = rand(6,-6) pixel_y = rand(6,-6) START_PROCESSING(SSobj, src) + AddComponent(/datum/component/swarming) /obj/structure/spider/spiderling/Destroy() STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index e7f783acd72..3174879caac 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -55,7 +55,7 @@ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) visible_message("[M] has attempted to disarm [src]!") -/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && !visual_effect_icon) visual_effect_icon = ATTACK_EFFECT_CLAW ..() diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index 69e12b6ae19..d13dab884b2 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -31,7 +31,7 @@ step_away(src, user, 15) return TRUE -/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && !visual_effect_icon) visual_effect_icon = ATTACK_EFFECT_BITE ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index dfa4bb61c9d..9f768ffc76d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -740,7 +740,8 @@ clear_alert("weightless") else throw_alert("weightless", /obj/screen/alert/weightless) - float(!has_gravity) + if(!flying) + float(!has_gravity) /mob/living/proc/float(on) if(throwing) @@ -825,8 +826,7 @@ spawn_dust() gib() -/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) - end_pixel_y = get_standard_pixel_y_offset(lying) +/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!used_item) used_item = get_active_hand() ..() diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 2cfc5e746dc..b42f3275997 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -118,7 +118,7 @@ /mob/living/simple_animal/blob_act(obj/structure/blob/B) adjustBruteLoss(20) -/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) +/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect) if(!no_effect && !visual_effect_icon && melee_damage_upper) if(melee_damage_upper < 10) visual_effect_icon = ATTACK_EFFECT_PUNCH diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index c1e7548d9a3..3276416fe7f 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -60,6 +60,7 @@ /mob/living/simple_animal/hostile/poison/bees/New() ..() generate_bee_visuals() + AddComponent(/datum/component/swarming) /mob/living/simple_animal/hostile/poison/bees/Destroy() beegent = null diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index ca9b632e06a..a5248e98bb6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -90,6 +90,7 @@ /mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/death), 100) + AddComponent(/datum/component/swarming) /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm index fd569984920..07f26031ed5 100644 --- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm +++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm @@ -335,7 +335,7 @@ //Jiggle the whole worm forwards towards the next segment -/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) +/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect) ..() if(previousWorm) previousWorm.do_attack_animation(src) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 23970e88826..6f40dfe2a3f 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -349,7 +349,8 @@ icon = 'icons/mob/critter.dmi' icon_state = "viscerator_attack" icon_living = "viscerator_attack" - pass_flags = PASSTABLE + pass_flags = PASSTABLE | PASSMOB + a_intent = INTENT_HARM health = 15 maxHealth = 15 obj_damage = 0 @@ -365,3 +366,7 @@ gold_core_spawnable = HOSTILE_SPAWN del_on_death = 1 deathmessage = "is smashed into pieces!" + +/mob/living/simple_animal/hostile/viscerator/Initialize(mapload) + . = ..() + AddComponent(/datum/component/swarming) diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm index bde995d8edb..c3cb61d5970 100644 --- a/code/modules/mob/living/simple_animal/posessed_object.dm +++ b/code/modules/mob/living/simple_animal/posessed_object.dm @@ -27,7 +27,7 @@ . += "[src] appears to be having trouble staying afloat!" -/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) +/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect) ..() animate_ghostly_presence(src, -1, 20, 1) // Restart the floating animation after the attack animation, as it will be cancelled. diff --git a/paradise.dme b/paradise.dme index c137faf236f..7393d7c6bb7 100644 --- a/paradise.dme +++ b/paradise.dme @@ -302,6 +302,7 @@ #include "code\datums\components\paintable.dm" #include "code\datums\components\spawner.dm" #include "code\datums\components\squeak.dm" +#include "code\datums\components\swarming.dm" #include "code\datums\components\waddling.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" From 01a5723f8c3b8d01af29406de592517f06260eaf Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Mon, 8 Jun 2020 21:57:07 -0400 Subject: [PATCH 075/151] [s] Fixes Ghost Exploit (#13580) --- code/modules/shuttle/supply.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index e1aa537f8a8..50cf7ff7d28 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -102,7 +102,10 @@ var/pointsEarned for(var/atom/movable/MA in areaInstance) - if(MA.anchored) continue + if(MA.anchored) + continue + if(istype(MA, /mob/dead)) + continue SSshuttle.sold_atoms += " [MA.name]" // Must be in a crate (or a critter crate)! From 2c08ce843f458426d44a0205ab8386fbedfd4281 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 8 Jun 2020 22:33:29 -0500 Subject: [PATCH 076/151] personal locker fix --- .../structures/crates_lockers/closets/secure/personal.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index df7e1384ed9..7eab5858772 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -55,7 +55,7 @@ new /obj/item/radio/headset( src ) /obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) - if(!istype(W, /obj/item/card/id)) + if(opened || !istype(W, /obj/item/card/id)) return ..() if(broken) From 1b09dd7972ed077c5861f2be5075dbccdb7c6e1d Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Tue, 9 Jun 2020 12:47:05 -0400 Subject: [PATCH 077/151] Brigtimer runtime fix --- code/game/machinery/doors/brigdoors.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index fc758d446f9..8d842179db5 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -338,10 +338,9 @@ F.flash() if(href_list["release"]) - var/obj/machinery/door_timer/T = locate(href_list["release"]) if(timing) - T.timer_end() - T.Radio.autosay("Timer stopped manually from cell control.", T.name, "Security", list(z)) + timer_end() + Radio.autosay("Timer stopped manually from cell control.", name, "Security", list(z)) ui_interact(usr) if(href_list["prisoner_name"]) From bcc45f03b70665c410a53b87cb41363f0d6eae4f Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Tue, 9 Jun 2020 15:31:10 -0400 Subject: [PATCH 078/151] Cuts down on Pointless Status Effect Processing (#13582) --- code/datums/status_effects/status_effect.dm | 5 +++-- code/modules/mining/equipment/kinetic_crusher.dm | 4 ++++ .../mob/living/simple_animal/hostile/megafauna/megafauna.dm | 1 - .../mob/living/simple_animal/hostile/mining/mining.dm | 4 ---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 74abf104465..2580b1c9935 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -5,7 +5,7 @@ /datum/status_effect var/id = "effect" //Used for screen alerts. var/duration = -1 //How long the status effect lasts in DECISECONDS. Enter -1 for an effect that never ends unless removed through some means. - var/tick_interval = 10 //How many deciseconds between ticks, approximately. Leave at 10 for every second. + var/tick_interval = 10 //How many deciseconds between ticks, approximately. Leave at 10 for every second. Setting this to -1 will stop processing if duration is also unlimited. var/mob/living/owner //The mob affected by the status effect. var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted @@ -31,7 +31,8 @@ var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type) A.attached_effect = src //so the alert can reference us, if it needs to linked_alert = A //so we can reference the alert, if we need to - START_PROCESSING(SSfastprocess, src) + if(duration > 0 || initial(tick_interval) > 0) //don't process if we don't care + START_PROCESSING(SSfastprocess, src) return TRUE /datum/status_effect/Destroy() diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index f21978db625..4af48e7050a 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -65,6 +65,8 @@ user.drop_l_hand() return var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(!C) + C = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) var/target_health = target.health ..() for(var/t in trophies) @@ -101,6 +103,8 @@ if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) return var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(!C) + C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) var/target_health = L.health for(var/t in trophies) var/obj/item/crusher_trophy/T = t diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 4ce66ccd1d5..eed05d55e91 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -43,7 +43,6 @@ . = ..() if(internal_type && true_spawn) internal = new internal_type(src) - apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) for(var/action_type in attack_action_types) var/datum/action/innate/megafauna_attack/attack_action = new action_type() attack_action.Grant(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm index 7c7200e8588..a888fa7ee9a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm @@ -23,10 +23,6 @@ var/icon_aggro = null var/crusher_drop_mod = 25 -/mob/living/simple_animal/hostile/asteroid/Initialize(mapload) - . = ..() - apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - /mob/living/simple_animal/hostile/asteroid/Aggro() ..() if(vision_range != aggro_vision_range) From 6bf7df8131428c6606abe0392017408d2fb39518 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Tue, 9 Jun 2020 16:56:29 -0500 Subject: [PATCH 079/151] review tweaks --- code/datums/components/slippery.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index baa93513f0a..3e505eb0a8a 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -25,9 +25,8 @@ /// The verb that players will see when someone slips on the parent. In the form of "You [slip_verb]ped on". var/slip_verb -/datum/component/slippery/Initialize(_description, _stun = 0, _weaken = 0, _slip_chance = 100, _slip_tiles = 0, \ - _walking_is_safe = TRUE, _noslip_is_immune = TRUE, _slip_verb = "slip") - if(!ismovable(parent)) +/datum/component/slippery/Initialize(_description, _stun = 0, _weaken = 0, _slip_chance = 100, _slip_tiles = 0, _walking_is_safe = TRUE, _noslip_is_immune = TRUE, _slip_verb = "slip") + if(!isatom(parent)) return COMPONENT_INCOMPATIBLE description = _description From a3be213089dbba66c18bf3167df787aaea391106 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Tue, 9 Jun 2020 21:13:12 -0500 Subject: [PATCH 080/151] after_slip /atom level --- code/game/atoms.dm | 11 +++++++++++ code/game/atoms_movable.dm | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 365e06aca4b..abd224e409b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -395,6 +395,17 @@ /atom/proc/get_spooked() return +/** + Base proc, intended to be overriden. + + This should only be called from one place: inside the slippery component. + Called after a human mob slips on this atom. + + If you want the person who slipped to have something special done to them, put it here. +*/ +/atom/proc/after_slip(mob/living/carbon/human/H) + return + /atom/proc/add_hiddenprint(mob/living/M as mob) if(isnull(M)) return if(isnull(M.key)) return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index dff58d485f5..70926d7ba2b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -330,17 +330,6 @@ SSspacedrift.processing[src] = src return 1 -/** - Base proc, intended to be overriden. - - This should only be called from one place: inside the slippery component. - Called after a human mob slips on this atom. - - If you want the person who slipped to have something special done to them, put it here. -*/ -/atom/movable/proc/after_slip(mob/living/carbon/human/H) - return - //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum) set waitfor = 0 From 29ff5543b61b3599f234a38e77c5ef7307cc1737 Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Wed, 10 Jun 2020 11:53:41 +0100 Subject: [PATCH 081/151] Updates nano dependencies --- nano/assets/libraries.min.js | 4 +- nano/assets/nano.js | 4 +- nano/assets/nanoui.css | 4 +- nano/package-lock.json | 691 +++++++++++++++++++++++------------ nano/package.json | 13 +- 5 files changed, 470 insertions(+), 246 deletions(-) diff --git a/nano/assets/libraries.min.js b/nano/assets/libraries.min.js index d0c1ef9a46f..7dff02479a9 100644 --- a/nano/assets/libraries.min.js +++ b/nano/assets/libraries.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(d,e){function t(e,t){return t.toUpperCase()}var f=[],c=f.slice,g=f.concat,a=f.push,r=f.indexOf,n={},i=n.toString,m=n.hasOwnProperty,v={},o="1.11.3",C=function(e,t){return new C.fn.init(e,t)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,l=/^-ms-/,u=/-([\da-z])/gi;function p(e){var t="length"in e&&e.length,n=C.type(e);return"function"!==n&&!C.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function i(){v()}var e,d,x,o,r,g,p,m,w,u,c,v,T,s,y,b,a,h,C,_="sizzle"+1*new Date,E=n.document,S=0,N=0,l=oe(),D=oe(),k=oe(),j=function(e,t){return e===t&&(c=!0),0},A={}.hasOwnProperty,t=[],P=t.pop,H=t.push,M=t.push,L=t.slice,O=function(e,t){for(var n=0,i=e.length;n+~]|"+F+")"+F+"*"),Y=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),Q=new RegExp($),J=new RegExp("^"+q+"$"),V={ID:new RegExp("^#("+W+")"),CLASS:new RegExp("^\\.("+W+")"),TAG:new RegExp("^("+W.replace("w","w*")+")"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,ee=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,te=/[+~]/,ne=/'|\\/g,ie=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig");try{M.apply(t=L.call(E.childNodes),E.childNodes),t[E.childNodes.length].nodeType}catch(e){M={apply:t.length?function(e,t){H.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function re(e,t,n,i){var r,o,s,a,l,u,c,f,p,h;if((t?t.ownerDocument||t:E)!==T&&v(t),n=n||[],a=(t=t||T).nodeType,"string"!=typeof e||!e||1!==a&&9!==a&&11!==a)return n;if(!i&&y){if(11!==a&&(r=ee.exec(e)))if(s=r[1]){if(9===a){if(!(o=t.getElementById(s))||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&C(t,o)&&o.id===s)return n.push(o),n}else{if(r[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=r[3])&&d.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(d.qsa&&(!b||!b.test(e))){if(f=c=_,p=t,h=1!==a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){for(u=g(e),(c=t.getAttribute("id"))?f=c.replace(ne,"\\$&"):t.setAttribute("id",f),f="[id='"+f+"'] ",l=u.length;l--;)u[l]=f+ge(u[l]);p=te.test(e)&&he(t.parentNode)||t,h=u.join(",")}if(h)try{return M.apply(n,p.querySelectorAll(h)),n}catch(e){}finally{c||t.removeAttribute("id")}}}return m(e.replace(z,"$1"),t,n,i)}function oe(){var i=[];return function e(t,n){return i.push(t+" ")>x.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function se(e){return e[_]=!0,e}function ae(e){var t=T.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),i=e.length;i--;)x.attrHandle[n[i]]=t}function ue(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||1<<31)-(~e.sourceIndex||1<<31);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function ce(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function fe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function pe(s){return se(function(o){return o=+o,se(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function he(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=re.support={},r=re.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},v=re.setDocument=function(e){var t,n,l=e?e.ownerDocument||e:E;return l!==T&&9===l.nodeType&&l.documentElement?(s=(T=l).documentElement,(n=l.defaultView)&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),y=!r(l),d.attributes=ae(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ae(function(e){return e.appendChild(l.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=Z.test(l.getElementsByClassName),d.getById=ae(function(e){return s.appendChild(e).id=_,!l.getElementsByName||!l.getElementsByName(_).length}),d.getById?(x.find.ID=function(e,t){if(void 0!==t.getElementById&&y){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},x.filter.ID=function(e){var t=e.replace(ie,f);return function(e){return e.getAttribute("id")===t}}):(delete x.find.ID,x.filter.ID=function(e){var n=e.replace(ie,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}}),x.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},x.find.CLASS=d.getElementsByClassName&&function(e,t){if(y)return t.getElementsByClassName(e)},a=[],b=[],(d.qsa=Z.test(l.querySelectorAll))&&(ae(function(e){s.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&b.push("[*^$]="+F+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||b.push("\\["+F+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+_+"-]").length||b.push("~="),e.querySelectorAll(":checked").length||b.push(":checked"),e.querySelectorAll("a#"+_+"+*").length||b.push(".#.+[+~]")}),ae(function(e){var t=l.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&b.push("name"+F+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||b.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),b.push(",.*:")})),(d.matchesSelector=Z.test(h=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ae(function(e){d.disconnectedMatch=h.call(e,"div"),h.call(e,"[s!='']:x"),a.push("!=",$)}),b=b.length&&new RegExp(b.join("|")),a=a.length&&new RegExp(a.join("|")),t=Z.test(s.compareDocumentPosition),C=t||Z.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===l||e.ownerDocument===E&&C(E,e)?-1:t===l||t.ownerDocument===E&&C(E,t)?1:u?O(u,e)-O(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===l?-1:t===l?1:r?-1:o?1:u?O(u,e)-O(u,t):0;if(r===o)return ue(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?ue(s[i],a[i]):s[i]===E?-1:a[i]===E?1:0},l):T},re.matches=function(e,t){return re(e,null,null,t)},re.matchesSelector=function(e,t){if((e.ownerDocument||e)!==T&&v(e),t=t.replace(Y,"='$1']"),d.matchesSelector&&y&&(!a||!a.test(t))&&(!b||!b.test(t)))try{var n=h.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,f),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=g(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=l[e+" "];return t||(t=new RegExp("(^|"+F+")"+e+"("+F+"|$)"))&&l(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=re.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1(?:<\/\1>|)$/,x=/^.[^:#\[\.,]*$/;function w(e,n,i){if(C.isFunction(n))return C.grep(e,function(e,t){return!!n.call(e,t,e)!==i});if(n.nodeType)return C.grep(e,function(e){return e===n!==i});if("string"==typeof n){if(x.test(n))return C.filter(n,e,i);n=C.filter(n,e)}return C.grep(e,function(e){return 0<=C.inArray(e,n)!==i})}C.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?C.find.matchesSelector(i,e)?[i]:[]:C.find.matches(e,C.grep(t,function(e){return 1===e.nodeType}))},C.fn.extend({find:function(e){var t,n=[],i=this,r=i.length;if("string"!=typeof e)return this.pushStack(C(e).filter(function(){for(t=0;t)[^>]*|#([\w-]*))$/;(C.fn.init=function(e,t){var n,i;if(!e)return this;if("string"!=typeof e)return e.nodeType?(this.context=this[0]=e,this.length=1,this):C.isFunction(e)?void 0!==T.ready?T.ready(e):e(C):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),C.makeArray(e,this));if(!(n="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&3<=e.length?[null,e,null]:E.exec(e))||!n[1]&&t)return!t||t.jquery?(t||T).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof C?t[0]:t,C.merge(this,C.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:_,!0)),b.test(n[1])&&C.isPlainObject(t))for(n in t)C.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}if((i=_.getElementById(n[2]))&&i.parentNode){if(i.id!==n[2])return T.find(e);this.length=1,this[0]=i}return this.context=_,this.selector=e,this}).prototype=C.fn,T=C(_);var S=/^(?:parents|prev(?:Until|All))/,N={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}C.extend({dir:function(e,t,n){for(var i=[],r=e[t];r&&9!==r.nodeType&&(void 0===n||1!==r.nodeType||!C(r).is(n));)1===r.nodeType&&i.push(r),r=r[t];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),C.fn.extend({has:function(e){var t,n=C(e,this),i=n.length;return this.filter(function(){for(t=0;t
a",v.leadingWhitespace=3===t.firstChild.nodeType,v.tbody=!t.getElementsByTagName("tbody").length,v.htmlSerialize=!!t.getElementsByTagName("link").length,v.html5Clone="<:nav>"!==_.createElement("nav").cloneNode(!0).outerHTML,e.type="checkbox",e.checked=!0,n.appendChild(e),v.appendChecked=e.checked,t.innerHTML="",v.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,n.appendChild(t),t.innerHTML="",v.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,v.noCloneEvent=!0,t.attachEvent&&(t.attachEvent("onclick",function(){v.noCloneEvent=!1}),t.cloneNode(!0).click()),null==v.deleteExpando){v.deleteExpando=!0;try{delete t.test}catch(e){v.deleteExpando=!1}}}(),function(){var e,t,n=_.createElement("div");for(e in{submit:!0,change:!0,focusin:!0})t="on"+e,(v[e+"Bubbles"]=t in d)||(n.setAttribute(t,"t"),v[e+"Bubbles"]=!1===n.attributes[t].expando);n=null}();var Y=/^(?:input|select|textarea)$/i,Q=/^key/,J=/^(?:mouse|pointer|contextmenu)|click/,V=/^(?:focusinfocus|focusoutblur)$/,G=/^([^.]*)(?:\.(.+)|)$/;function K(){return!0}function Z(){return!1}function ee(){try{return _.activeElement}catch(e){}}function te(e){var t=ne.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}C.event={global:{},add:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C._data(e);if(m){for(n.handler&&(n=(l=n).handler,r=l.selector),n.guid||(n.guid=C.guid++),(s=m.events)||(s=m.events={}),(c=m.handle)||((c=m.handle=function(e){return typeof C===L||e&&C.event.triggered===e.type?void 0:C.event.dispatch.apply(c.elem,arguments)}).elem=e),a=(t=(t||"").match(j)||[""]).length;a--;)h=g=(o=G.exec(t[a])||[])[1],d=(o[2]||"").split(".").sort(),h&&(u=C.event.special[h]||{},h=(r?u.delegateType:u.bindType)||h,u=C.event.special[h]||{},f=C.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&C.expr.match.needsContext.test(r),namespace:d.join(".")},l),(p=s[h])||((p=s[h]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,i,d,c)||(e.addEventListener?e.addEventListener(h,c,!1):e.attachEvent&&e.attachEvent("on"+h,c))),u.add&&(u.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),r?p.splice(p.delegateCount++,0,f):p.push(f),C.event.global[h]=!0);e=null}},remove:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C.hasData(e)&&C._data(e);if(m&&(c=m.events)){for(u=(t=(t||"").match(j)||[""]).length;u--;)if(h=g=(a=G.exec(t[u])||[])[1],d=(a[2]||"").split(".").sort(),h){for(f=C.event.special[h]||{},p=c[h=(i?f.delegateType:f.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=p.length;o--;)s=p[o],!r&&g!==s.origType||n&&n.guid!==s.guid||a&&!a.test(s.namespace)||i&&i!==s.selector&&("**"!==i||!s.selector)||(p.splice(o,1),s.selector&&p.delegateCount--,f.remove&&f.remove.call(e,s));l&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,d,m.handle)||C.removeEvent(e,h,m.handle),delete c[h])}else for(h in c)C.event.remove(e,h+t[u],n,i,!0);C.isEmptyObject(c)&&(delete m.handle,C._removeData(e,"events"))}},trigger:function(e,t,n,i){var r,o,s,a,l,u,c,f=[n||_],p=m.call(e,"type")?e.type:e,h=m.call(e,"namespace")?e.namespace.split("."):[];if(s=u=n=n||_,3!==n.nodeType&&8!==n.nodeType&&!V.test(p+C.event.triggered)&&(0<=p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),o=p.indexOf(":")<0&&"on"+p,(e=e[C.expando]?e:new C.Event(p,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=h.join("."),e.namespace_re=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:C.makeArray(t,[e]),l=C.event.special[p]||{},i||!l.trigger||!1!==l.trigger.apply(n,t))){if(!i&&!l.noBubble&&!C.isWindow(n)){for(a=l.delegateType||p,V.test(a+p)||(s=s.parentNode);s;s=s.parentNode)f.push(s),u=s;u===(n.ownerDocument||_)&&f.push(u.defaultView||u.parentWindow||d)}for(c=0;(s=f[c++])&&!e.isPropagationStopped();)e.type=1]","i"),oe=/^\s+/,se=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ae=/<([\w:]+)/,le=/\s*$/g,ge={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:v.htmlSerialize?[0,"",""]:[1,"X
","
"]},me=te(_).appendChild(_.createElement("div"));function ve(e,t){var n,i,r=0,o=typeof e.getElementsByTagName!==L?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==L?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(i=n[r]);r++)!t||C.nodeName(i,t)?o.push(i):C.merge(o,ve(i,t));return void 0===t||t&&C.nodeName(e,t)?C.merge([e],o):o}function ye(e){X.test(e.type)&&(e.defaultChecked=e.checked)}function be(e,t){return C.nodeName(e,"table")&&C.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function xe(e){return e.type=(null!==C.find.attr(e,"type"))+"/"+e.type,e}function we(e){var t=he.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Te(e,t){for(var n,i=0;null!=(n=e[i]);i++)C._data(n,"globalEval",!t||C._data(t[i],"globalEval"))}function Ce(e,t){if(1===t.nodeType&&C.hasData(e)){var n,i,r,o=C._data(e),s=C._data(t,o),a=o.events;if(a)for(n in delete s.handle,s.events={},a)for(i=0,r=a[n].length;i")?o=e.cloneNode(!0):(me.innerHTML=e.outerHTML,me.removeChild(o=me.firstChild)),!(v.noCloneEvent&&v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||C.isXMLDoc(e)))for(i=ve(o),a=ve(e),s=0;null!=(r=a[s]);++s)i[s]&&_e(r,i[s]);if(t)if(n)for(a=a||ve(e),i=i||ve(o),s=0;null!=(r=a[s]);s++)Ce(r,i[s]);else Ce(e,o);return 0<(i=ve(o,"script")).length&&Te(i,!l&&ve(e,"script")),i=a=r=null,o},buildFragment:function(e,t,n,i){for(var r,o,s,a,l,u,c,f=e.length,p=te(t),h=[],d=0;d")+c[2],r=c[0];r--;)a=a.lastChild;if(!v.leadingWhitespace&&oe.test(o)&&h.push(t.createTextNode(oe.exec(o)[0])),!v.tbody)for(r=(o="table"!==l||le.test(o)?""!==c[1]||le.test(o)?0:a:a.firstChild)&&o.childNodes.length;r--;)C.nodeName(u=o.childNodes[r],"tbody")&&!u.childNodes.length&&o.removeChild(u);for(C.merge(h,a.childNodes),a.textContent="";a.firstChild;)a.removeChild(a.firstChild);a=p.lastChild}else h.push(t.createTextNode(o));for(a&&p.removeChild(a),v.appendChecked||C.grep(ve(h,"input"),ye),d=0;o=h[d++];)if((!i||-1===C.inArray(o,i))&&(s=C.contains(o.ownerDocument,o),a=ve(p.appendChild(o),"script"),s&&Te(a),n))for(r=0;o=a[r++];)pe.test(o.type||"")&&n.push(o);return a=null,p},cleanData:function(e,t){for(var n,i,r,o,s=0,a=C.expando,l=C.cache,u=v.deleteExpando,c=C.event.special;null!=(n=e[s]);s++)if((t||C.acceptData(n))&&(o=(r=n[a])&&l[r])){if(o.events)for(i in o.events)c[i]?C.event.remove(n,i):C.removeEvent(n,i,o.handle);l[r]&&(delete l[r],u?delete n[a]:typeof n.removeAttribute!==L?n.removeAttribute(a):n[a]=null,f.push(r))}}}),C.fn.extend({text:function(e){return U(this,function(e){return void 0===e?C.text(this):this.empty().append((this[0]&&this[0].ownerDocument||_).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||be(this,e).appendChild(e)})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=be(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?C.filter(e,this):this,r=0;null!=(n=i[r]);r++)t||1!==n.nodeType||C.cleanData(ve(n)),n.parentNode&&(t&&C.contains(n.ownerDocument,n)&&Te(ve(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&C.cleanData(ve(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&C.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return C.clone(this,e,t)})},html:function(e){return U(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(ie,""):void 0;if("string"==typeof e&&!ce.test(e)&&(v.htmlSerialize||!re.test(e))&&(v.leadingWhitespace||!oe.test(e))&&!ge[(ae.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(se,"<$1>");try{for(;n")).appendTo(t.documentElement))[0].contentWindow||Ee[0].contentDocument).document).write(),t.close(),n=De(e,t),Ee.detach()),Ne[e]=n),n}v.shrinkWrapBlocks=function(){return null!=Se?Se:(Se=!1,(t=_.getElementsByTagName("body")[0])&&t.style?(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),typeof e.style.zoom!==L&&(e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",e.appendChild(_.createElement("div")).style.width="5px",Se=3!==e.offsetWidth),t.removeChild(n),Se):void 0);var e,t,n};var je,Ae,Pe,He,Me,Le,Oe,Ie,Fe,We=/^margin/,qe=new RegExp("^("+B+")(?!px)[a-z%]+$","i"),Re=/^(top|right|bottom|left)$/;function $e(t,n){return{get:function(){var e=t();if(null!=e){if(!e)return(this.get=n).apply(this,arguments);delete this.get}}}}function Be(){var e,t,n,i;(t=_.getElementsByTagName("body")[0])&&t.style&&(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),e.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",Le=Oe=!1,Fe=!0,d.getComputedStyle&&(Le="1%"!==(d.getComputedStyle(e,null)||{}).top,Oe="4px"===(d.getComputedStyle(e,null)||{width:"4px"}).width,(i=e.appendChild(_.createElement("div"))).style.cssText=e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",e.style.width="1px",Fe=!parseFloat((d.getComputedStyle(i,null)||{}).marginRight),e.removeChild(i)),e.innerHTML="
t
",(i=e.getElementsByTagName("td"))[0].style.cssText="margin:0;border:0;padding:0;display:none",(Ie=0===i[0].offsetHeight)&&(i[0].style.display="",i[1].style.display="none",Ie=0===i[0].offsetHeight),t.removeChild(n))}d.getComputedStyle?(je=function(e){return e.ownerDocument.defaultView.opener?e.ownerDocument.defaultView.getComputedStyle(e,null):d.getComputedStyle(e,null)},Ae=function(e,t,n){var i,r,o,s,a=e.style;return s=(n=n||je(e))?n.getPropertyValue(t)||n[t]:void 0,n&&(""!==s||C.contains(e.ownerDocument,e)||(s=C.style(e,t)),qe.test(s)&&We.test(t)&&(i=a.width,r=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=i,a.minWidth=r,a.maxWidth=o)),void 0===s?s:s+""}):_.documentElement.currentStyle&&(je=function(e){return e.currentStyle},Ae=function(e,t,n){var i,r,o,s,a=e.style;return null==(s=(n=n||je(e))?n[t]:void 0)&&a&&a[t]&&(s=a[t]),qe.test(s)&&!Re.test(t)&&(i=a.left,(o=(r=e.runtimeStyle)&&r.left)&&(r.left=e.currentStyle.left),a.left="fontSize"===t?"1em":s,s=a.pixelLeft+"px",a.left=i,o&&(r.left=o)),void 0===s?s:s+""||"auto"}),(Pe=_.createElement("div")).innerHTML="
a",(He=(Me=Pe.getElementsByTagName("a")[0])&&Me.style)&&(He.cssText="float:left;opacity:.5",v.opacity="0.5"===He.opacity,v.cssFloat=!!He.cssFloat,Pe.style.backgroundClip="content-box",Pe.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===Pe.style.backgroundClip,v.boxSizing=""===He.boxSizing||""===He.MozBoxSizing||""===He.WebkitBoxSizing,C.extend(v,{reliableHiddenOffsets:function(){return null==Ie&&Be(),Ie},boxSizingReliable:function(){return null==Oe&&Be(),Oe},pixelPosition:function(){return null==Le&&Be(),Le},reliableMarginRight:function(){return null==Fe&&Be(),Fe}})),C.swap=function(e,t,n,i){var r,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];for(o in r=n.apply(e,i||[]),t)e.style[o]=s[o];return r};var ze=/alpha\([^)]*\)/i,Ue=/opacity\s*=\s*([^)]*)/,Xe=/^(none|table(?!-c[ea]).+)/,Ye=new RegExp("^("+B+")(.*)$","i"),Qe=new RegExp("^([+-])=("+B+")","i"),Je={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","O","Moz","ms"];function Ke(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),i=t,r=Ge.length;r--;)if((t=Ge[r]+n)in e)return t;return i}function Ze(e,t){for(var n,i,r,o=[],s=0,a=e.length;s
a",ut=at.getElementsByTagName("a")[0],ct=(lt=_.createElement("select")).appendChild(_.createElement("option")),st=at.getElementsByTagName("input")[0],ut.style.cssText="top:1px",v.getSetAttribute="t"!==at.className,v.style=/top/.test(ut.getAttribute("style")),v.hrefNormalized="/a"===ut.getAttribute("href"),v.checkOn=!!st.value,v.optSelected=ct.selected,v.enctype=!!_.createElement("form").enctype,lt.disabled=!0,v.optDisabled=!ct.disabled,(st=_.createElement("input")).setAttribute("value",""),v.input=""===st.getAttribute("value"),st.value="t",st.setAttribute("type","radio"),v.radioValue="t"===st.value;var xt=/\r/g;C.fn.extend({val:function(n){var i,e,r,t=this[0];return arguments.length?(r=C.isFunction(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=r?n.call(this,e,C(this).val()):n)?t="":"number"==typeof t?t+="":C.isArray(t)&&(t=C.map(t,function(e){return null==e?"":e+""})),(i=C.valHooks[this.type]||C.valHooks[this.nodeName.toLowerCase()])&&"set"in i&&void 0!==i.set(this,t,"value")||(this.value=t))})):t?(i=C.valHooks[t.type]||C.valHooks[t.nodeName.toLowerCase()])&&"get"in i&&void 0!==(e=i.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),C.extend({valHooks:{option:{get:function(e){var t=C.find.attr(e,"value");return null!=t?t:C.trim(C.text(e))}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,s=o?null:[],a=o?r+1:i.length,l=r<0?a:o?r:0;l").append(C.parseHTML(e)).find(i):e)}).complete(n&&function(e,t){s.each(n,r||[e.responseText,t,e])}),this},C.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){C.fn[t]=function(e){return this.on(t,e)}}),C.expr.filters.animated=function(t){return C.grep(C.timers,function(e){return t===e.elem}).length};var cn=d.document.documentElement;function fn(e){return C.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}C.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,u=C.css(e,"position"),c=C(e),f={};"static"===u&&(e.style.position="relative"),a=c.offset(),o=C.css(e,"top"),l=C.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1").outerWidth(1).jquery||D.each(["Width","Height"],function(e,n){var r="Width"===n?["Left","Right"]:["Top","Bottom"],i=n.toLowerCase(),o={innerWidth:D.fn.innerWidth,innerHeight:D.fn.innerHeight,outerWidth:D.fn.outerWidth,outerHeight:D.fn.outerHeight};function s(e,t,n,i){return D.each(r,function(){t-=parseFloat(D.css(e,"padding"+this))||0,n&&(t-=parseFloat(D.css(e,"border"+this+"Width"))||0),i&&(t-=parseFloat(D.css(e,"margin"+this))||0)}),t}D.fn["inner"+n]=function(e){return void 0===e?o["inner"+n].call(this):this.each(function(){D(this).css(i,s(this,e)+"px")})},D.fn["outer"+n]=function(e,t){return"number"!=typeof e?o["outer"+n].call(this,e):this.each(function(){D(this).css(i,s(this,e,!0,t)+"px")})}}),D.fn.addBack||(D.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),D("").data("a-b","a").removeData("a-b").data("a-b")&&(D.fn.removeData=(t=D.fn.removeData,function(e){return arguments.length?t.call(this,D.camelCase(e)):t.call(this)})),D.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),D.fn.extend({focus:(i=D.fn.focus,function(t,n){return"number"==typeof t?this.each(function(){var e=this;setTimeout(function(){D(e).focus(),n&&n.call(e)},t)}):i.apply(this,arguments)}),disableSelection:(n="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.bind(n+".ui-disableSelection",function(e){e.preventDefault()})}),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(e){if(void 0!==e)return this.css("zIndex",e);if(this.length)for(var t,n,i=D(this[0]);i.length&&i[0]!==document;){if(("absolute"===(t=i.css("position"))||"relative"===t||"fixed"===t)&&(n=parseInt(i.css("zIndex"),10),!isNaN(n)&&0!==n))return n;i=i.parent()}return 0}}),D.ui.plugin={add:function(e,t,n){var i,r=D.ui[e].prototype;for(i in n)r.plugins[i]=r.plugins[i]||[],r.plugins[i].push([t,n[i]])},call:function(e,t,n,i){var r,o=e.plugins[t];if(o&&(i||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(r=0;r",options:{disabled:!1,create:null},_createWidget:function(e,t){t=D(t||this.defaultElement||this)[0],this.element=D(t),this.uuid=a++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=D(),this.hoverable=D(),this.focusable=D(),t!==this&&(D.data(t,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===t&&this.destroy()}}),this.document=D(t.style?t.ownerDocument:t.document||t),this.window=D(this.document[0].defaultView||this.document[0].parentWindow)),this.options=D.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:D.noop,_getCreateEventData:D.noop,_create:D.noop,_init:D.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(D.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:D.noop,widget:function(){return this.element},option:function(e,t){var n,i,r,o=e;if(0===arguments.length)return D.widget.extend({},this.options);if("string"==typeof e)if(o={},e=(n=e.split(".")).shift(),n.length){for(i=o[e]=D.widget.extend({},this.options[e]),r=0;r=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){D.ui=D.ui||{};var r,T,C=Math.max,_=Math.abs,E=Math.round,i=/left|center|right/,o=/top|center|bottom/,s=/[\+\-]\d+(\.[\d]+)?%?/,a=/^\w+/,l=/%$/,t=D.fn.position;function S(e,t,n){return[parseFloat(e[0])*(l.test(e[0])?t/100:1),parseFloat(e[1])*(l.test(e[1])?n/100:1)]}function N(e,t){return parseInt(D.css(e,t),10)||0}D.position={scrollbarWidth:function(){if(void 0!==r)return r;var e,t,n=D("
"),i=n.children()[0];return D("body").append(n),e=i.offsetWidth,n.css("overflow","scroll"),e===(t=i.offsetWidth)&&(t=n[0].clientWidth),n.remove(),r=e-t},getScrollInfo:function(e){var t=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),n=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),i="scroll"===t||"auto"===t&&e.widthC(_(i),_(r))?o.important="horizontal":o.important="vertical",f.using.call(this,e,o)}),s.offset(D.extend(u,{using:e}))})},D.ui.position={fit:{left:function(e,t){var n,i=t.within,r=i.isWindow?i.scrollLeft:i.offset.left,o=i.width,s=e.left-t.collisionPosition.marginLeft,a=r-s,l=s+t.collisionWidth-o-r;t.collisionWidth>o?0o?0").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var t=this.document[0];if(this.handleElement.is(e.target))try{t.activeElement&&"body"!==t.activeElement.nodeName.toLowerCase()&&D(t.activeElement).blur()}catch(e){}},_mouseStart:function(e){var t=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),D.ui.ddmanager&&(D.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0n[2]&&(l=n[2]+this.offset.click.left),e.pageY-this.offset.click.top>n[3]&&(u=n[3]+this.offset.click.top)),s.grid&&(r=s.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,u=n?r-this.offset.click.top>=n[1]||r-this.offset.click.top>n[3]?r:r-this.offset.click.top>=n[1]?r-s.grid[1]:r+s.grid[1]:r,o=s.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,l=n?o-this.offset.click.left>=n[0]||o-this.offset.click.left>n[2]?o:o-this.offset.click.left>=n[0]?o-s.grid[0]:o+s.grid[0]:o),"y"===s.axis&&(l=this.originalPageX),"x"===s.axis&&(u=this.originalPageY)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(e,t,n){return n=n||this._uiHash(),D.ui.plugin.call(this,e,[t,n,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),n.offset=this.positionAbs),D.Widget.prototype._trigger.call(this,e,t,n)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),D.ui.plugin.add("draggable","connectToSortable",{start:function(t,e,n){var i=D.extend({},e,{item:n.element});n.sortables=[],D(n.options.connectToSortable).each(function(){var e=D(this).sortable("instance");e&&!e.options.disabled&&(n.sortables.push(e),e.refreshPositions(),e._trigger("activate",t,i))})},stop:function(t,e,n){var i=D.extend({},e,{item:n.element});n.cancelHelperRemoval=!1,D.each(n.sortables,function(){var e=this;e.isOver?(e.isOver=0,n.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,i))})},drag:function(n,i,r){D.each(r.sortables,function(){var e=!1,t=this;t.positionAbs=r.positionAbs,t.helperProportions=r.helperProportions,t.offset.click=r.offset.click,t._intersectsWith(t.containerCache)&&(e=!0,D.each(r.sortables,function(){return this.positionAbs=r.positionAbs,this.helperProportions=r.helperProportions,this.offset.click=r.offset.click,this!==t&&this._intersectsWith(this.containerCache)&&D.contains(t.element[0],this.element[0])&&(e=!1),e})),e?(t.isOver||(t.isOver=1,r._parent=i.helper.parent(),t.currentItem=i.helper.appendTo(t.element).data("ui-sortable-item",!0),t.options._helper=t.options.helper,t.options.helper=function(){return i.helper[0]},n.target=t.currentItem[0],t._mouseCapture(n,!0),t._mouseStart(n,!0,!0),t.offset.click.top=r.offset.click.top,t.offset.click.left=r.offset.click.left,t.offset.parent.left-=r.offset.parent.left-t.offset.parent.left,t.offset.parent.top-=r.offset.parent.top-t.offset.parent.top,r._trigger("toSortable",n),r.dropped=t.element,D.each(r.sortables,function(){this.refreshPositions()}),r.currentItem=r.element,t.fromOutside=r),t.currentItem&&(t._mouseDrag(n),i.position=t.position)):t.isOver&&(t.isOver=0,t.cancelHelperRemoval=!0,t.options._revert=t.options.revert,t.options.revert=!1,t._trigger("out",n,t._uiHash(t)),t._mouseStop(n,!0),t.options.revert=t.options._revert,t.options.helper=t.options._helper,t.placeholder&&t.placeholder.remove(),i.helper.appendTo(r._parent),r._refreshOffsets(n),i.position=r._generatePosition(n,!0),r._trigger("fromSortable",n),r.dropped=!1,D.each(r.sortables,function(){this.refreshPositions()}))})}}),D.ui.plugin.add("draggable","cursor",{start:function(e,t,n){var i=D("body"),r=n.options;i.css("cursor")&&(r._cursor=i.css("cursor")),i.css("cursor",r.cursor)},stop:function(e,t,n){var i=n.options;i._cursor&&D("body").css("cursor",i._cursor)}}),D.ui.plugin.add("draggable","opacity",{start:function(e,t,n){var i=D(t.helper),r=n.options;i.css("opacity")&&(r._opacity=i.css("opacity")),i.css("opacity",r.opacity)},stop:function(e,t,n){var i=n.options;i._opacity&&D(t.helper).css("opacity",i._opacity)}}),D.ui.plugin.add("draggable","scroll",{start:function(e,t,n){n.scrollParentNotHidden||(n.scrollParentNotHidden=n.helper.scrollParent(!1)),n.scrollParentNotHidden[0]!==n.document[0]&&"HTML"!==n.scrollParentNotHidden[0].tagName&&(n.overflowOffset=n.scrollParentNotHidden.offset())},drag:function(e,t,n){var i=n.options,r=!1,o=n.scrollParentNotHidden[0],s=n.document[0];o!==s&&"HTML"!==o.tagName?(i.axis&&"x"===i.axis||(n.overflowOffset.top+o.offsetHeight-e.pageY")[0],x=c.each,b.style.cssText="background-color:rgba(1,1,1,.5)",y.rgba=-1o.mod/2?i+=o.mod:i-r>o.mod/2&&(i-=o.mod)),u[n]=H((r-i)*s+i,t)))}),this[t](u)},blend:function(e){if(1===this._rgba[3])return this;var t=this._rgba.slice(),n=t.pop(),i=g(e)._rgba;return g(c.map(t,function(e,t){return(1-n)*i[t]+n*e}))},toRgbaString:function(){var e="rgba(",t=c.map(this._rgba,function(e,t){return null==e?2").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),t={width:n.width(),height:n.height()},r=document.activeElement;try{r.id}catch(e){r=document.body}return n.wrap(e),n[0]!==r&&!D.contains(n[0],r)||D(r).focus(),e=n.parent(),"static"===n.css("position")?(e.css({position:"relative"}),n.css({position:"relative"})):(D.extend(i,{position:n.css("position"),zIndex:n.css("z-index")}),D.each(["top","left","bottom","right"],function(e,t){i[t]=n.css(t),isNaN(parseInt(i[t],10))&&(i[t]="auto")}),n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),n.css(t),e.css(i).show()},removeWrapper:function(e){var t=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),e[0]!==t&&!D.contains(e[0],t)||D(t).focus()),e},setTransition:function(i,e,r,o){return o=o||{},D.each(e,function(e,t){var n=i.cssUnit(t);0r&&0!==r||!1===i.call(e,o))&&jQuery.timer.remove(e,n,i)}a.timerID=i.timerID,s[n][i.timerID]||(s[n][i.timerID]=window.setInterval(a,t)),this.global.push(e)}},remove:function(e,t,n){var i,r=jQuery.data(e,this.dataKey);if(r){if(t){if(r[t]){if(n)n.timerID&&(window.clearInterval(r[t][n.timerID]),delete r[t][n.timerID]);else for(var n in r[t])window.clearInterval(r[t][n]),delete r[t][n];for(i in r[t])break;i||(i=null,delete r[t])}}else for(t in r)this.remove(e,t,n);for(i in r)break;i||jQuery.removeData(e,this.dataKey)}}}}),jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(e,t){jQuery.timer.remove(t)})}),function(){"use strict";var a={version:"1.0.1-nanoui",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{:([\s\S]+?)\}\}/g,encode:/\{\{>([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\/?if\s*([\s\S]*?)\s*\}\}/g,conditionalElse:/\{\{else\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{\/?for\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,props:/\{\{\/?props\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,empty:/\{\{empty\}\}/g,varname:"data, config, helper",strip:!0,append:!0,selfcontained:!1},template:void 0,compile:void 0};function l(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(e,function(e){return t[e]||e}):this}}"undefined"!=typeof module&&module.exports?module.exports=a:"function"==typeof define&&define.amd?define(function(){return a}):function(){return this||(0,eval)("this")}().doT=a,String.prototype.encodeHTML=l();var u={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},c=/$^/;function f(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}a.template=function(e,t,n){var i,r=(t=t||a.templateSettings).append?u.append:u.split,o=0,s=t.use||t.define?function i(r,e,o){return("string"==typeof e?e:e.toString()).replace(r.define||c,function(e,i,t,n){return 0===i.indexOf("def.")&&(i=i.substring(4)),i in o||(":"===t?(r.defineParams&&n.replace(r.defineParams,function(e,t,n){o[i]={arg:t,text:n}}),i in o||(o[i]=n)):new Function("def","def['"+i+"']="+n)(o)),""}).replace(r.use||c,function(e,t){r.useParams&&(t=t.replace(r.useParams,function(e,t,n,i){if(o[n]&&o[n].arg&&i){var r=(n+":"+i).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[r]=o[n].text.replace(new RegExp("(^|[^\\w$])"+o[n].arg+"([^\\w$])","g"),"$1"+i+"$2"),t+"def.__exp['"+r+"']"}}));var n=new Function("def","return "+t)(o);return n?i(r,n,o):n})}(t,e,n||{}):e;s=("var out='"+(t.strip?s.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):s).replace(/'|\\/g,"\\$&").replace(t.interpolate||c,function(e,t){return r.start+f(t)+r.end}).replace(t.encode||c,function(e,t){return i=!0,r.start+f(t)+r.endencode}).replace(t.conditional||c,function(e,t){return t?"';if("+f(t)+"){out+='":"';}out+='"}).replace(t.conditionalElse||c,function(e,t){return t?"';}else if("+f(t)+"){out+='":"';}else{out+='"}).replace(t.iterate||c,function(e,t,n,i){if(!t)return"';} } out+='";o+=1,n=n||"value",i=i||"index",t=f(t);var r="arr"+o;return"';var "+r+"="+t+";if("+r+" && "+r+".length > 0){var "+n+","+i+"=-1,l"+o+"="+r+".length-1;while("+i+" 0){var "+n+";for( var "+i+" in "+r+"){ if (!"+r+".hasOwnProperty("+i+")) continue; "+n+"="+r+"["+i+"];out+='"}).replace(t.empty||c,function(e){return"';}}else{if(true){out+='"}).replace(t.evaluate||c,function(e,t){return"';"+f(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|\}|^|\{)out\+=''\+/g,"$1out+="),i&&t.selfcontained&&(s="String.prototype.encodeHTML=("+l.toString()+"());"+s);try{return new Function(t.varname,s)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+s),e}},a.compile=function(e,t){return a.template(e,null,t)}}(),function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){function n(e){try{var t=S.call(e).replace(/\/\/.*\n/g,"").replace(/\/\*[.\s\S]*\*\//g,"").replace(/\n/gm," ").replace(/ {2}/g," ");return N.test(t)}catch(e){return!1}}function p(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(E)return function(e){try{return!n(e)&&(S.call(e),!0)}catch(e){return!1}}(e);if(n(e))return!1;var t=_.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}var h,d,l=Array,e=l.prototype,a=Object,t=a.prototype,u=Function,i=u.prototype,v=String,r=v.prototype,y=Number,o=y.prototype,c=e.slice,s=e.splice,g=e.push,f=e.unshift,m=e.concat,b=e.join,x=i.call,w=i.apply,T=Math.max,C=Math.min,_=t.toString,E="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,N=/^\s*class /,D=RegExp.prototype.exec;h=function(e){return"object"==typeof e&&(E?function(e){try{return D.call(e),!0}catch(e){return!1}}(e):"[object RegExp]"===_.call(e))};var k=String.prototype.valueOf;d=function(e){return"string"==typeof e||"object"==typeof e&&(E?function(e){try{return k.call(e),!0}catch(e){return!1}}(e):"[object String]"===_.call(e))};function j(e){var t=typeof e;return null===e||"object"!=t&&"function"!=t}function A(){}var P,H,M=a.defineProperty&&function(){try{var e={};for(var t in a.defineProperty(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}(),L=(P=t.hasOwnProperty,H=M?function(e,t,n,i){!i&&t in e||a.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,i){!i&&t in e||(e[t]=n)},function(e,t,n){for(var i in t)P.call(t,i)&&H(e,i,t[i],n)}),O=y.isNaN||function(e){return e!=e},I=function(e){var t=+e;return O(t)?t=0:0!==t&&t!==1/0&&t!==-1/0&&(t=(0>>0};L(i,{bind:function(t){var n=this;if(!p(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var i,r=c.call(arguments,1),e=T(0,n.length-r.length),o=[],s=0;s=r)throw new TypeError("reduce of empty array with no initial value")}for(;s>10|55296,1023&i|56320)}function i(){v()}var e,d,x,o,r,g,p,m,w,u,c,v,T,s,y,b,a,h,C,_="sizzle"+ +new Date,E=n.document,S=0,N=0,l=oe(),D=oe(),k=oe(),j=function(e,t){return e===t&&(c=!0),0},A={}.hasOwnProperty,t=[],P=t.pop,H=t.push,M=t.push,L=t.slice,O=function(e,t){for(var n=0,i=e.length;n+~]|"+F+")"+F+"*"),Y=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),Q=new RegExp($),J=new RegExp("^"+q+"$"),V={ID:new RegExp("^#("+W+")"),CLASS:new RegExp("^\\.("+W+")"),TAG:new RegExp("^("+W.replace("w","w*")+")"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,ee=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,te=/[+~]/,ne=/'|\\/g,ie=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig");try{M.apply(t=L.call(E.childNodes),E.childNodes),t[E.childNodes.length].nodeType}catch(e){M={apply:t.length?function(e,t){H.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function re(e,t,n,i){var r,o,s,a,l,u,c,f,p,h;if((t?t.ownerDocument||t:E)!==T&&v(t),n=n||[],a=(t=t||T).nodeType,"string"!=typeof e||!e||1!==a&&9!==a&&11!==a)return n;if(!i&&y){if(11!==a&&(r=ee.exec(e)))if(s=r[1]){if(9===a){if(!(o=t.getElementById(s))||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&C(t,o)&&o.id===s)return n.push(o),n}else{if(r[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=r[3])&&d.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(d.qsa&&(!b||!b.test(e))){if(f=c=_,p=t,h=1!==a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){for(u=g(e),(c=t.getAttribute("id"))?f=c.replace(ne,"\\$&"):t.setAttribute("id",f),f="[id='"+f+"'] ",l=u.length;l--;)u[l]=f+ge(u[l]);p=te.test(e)&&he(t.parentNode)||t,h=u.join(",")}if(h)try{return M.apply(n,p.querySelectorAll(h)),n}catch(e){}finally{c||t.removeAttribute("id")}}}return m(e.replace(z,"$1"),t,n,i)}function oe(){var i=[];return function e(t,n){return i.push(t+" ")>x.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function se(e){return e[_]=!0,e}function ae(e){var t=T.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),i=e.length;i--;)x.attrHandle[n[i]]=t}function ue(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||1<<31)-(~e.sourceIndex||1<<31);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function ce(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function fe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function pe(s){return se(function(o){return o=+o,se(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function he(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=re.support={},r=re.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},v=re.setDocument=function(e){var t,n,l=e?e.ownerDocument||e:E;return l!==T&&9===l.nodeType&&l.documentElement?(s=(T=l).documentElement,(n=l.defaultView)&&n!==n.top&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),y=!r(l),d.attributes=ae(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ae(function(e){return e.appendChild(l.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=Z.test(l.getElementsByClassName),d.getById=ae(function(e){return s.appendChild(e).id=_,!l.getElementsByName||!l.getElementsByName(_).length}),d.getById?(x.find.ID=function(e,t){if(void 0!==t.getElementById&&y){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},x.filter.ID=function(e){var t=e.replace(ie,f);return function(e){return e.getAttribute("id")===t}}):(delete x.find.ID,x.filter.ID=function(e){var n=e.replace(ie,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}}),x.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},x.find.CLASS=d.getElementsByClassName&&function(e,t){if(y)return t.getElementsByClassName(e)},a=[],b=[],(d.qsa=Z.test(l.querySelectorAll))&&(ae(function(e){s.appendChild(e).innerHTML="
",e.querySelectorAll("[msallowcapture^='']").length&&b.push("[*^$]="+F+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||b.push("\\["+F+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+_+"-]").length||b.push("~="),e.querySelectorAll(":checked").length||b.push(":checked"),e.querySelectorAll("a#"+_+"+*").length||b.push(".#.+[+~]")}),ae(function(e){var t=l.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&b.push("name"+F+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||b.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),b.push(",.*:")})),(d.matchesSelector=Z.test(h=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ae(function(e){d.disconnectedMatch=h.call(e,"div"),h.call(e,"[s!='']:x"),a.push("!=",$)}),b=b.length&&new RegExp(b.join("|")),a=a.length&&new RegExp(a.join("|")),t=Z.test(s.compareDocumentPosition),C=t||Z.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===l||e.ownerDocument===E&&C(E,e)?-1:t===l||t.ownerDocument===E&&C(E,t)?1:u?O(u,e)-O(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===l?-1:t===l?1:r?-1:o?1:u?O(u,e)-O(u,t):0;if(r===o)return ue(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?ue(s[i],a[i]):s[i]===E?-1:a[i]===E?1:0},l):T},re.matches=function(e,t){return re(e,null,null,t)},re.matchesSelector=function(e,t){if((e.ownerDocument||e)!==T&&v(e),t=t.replace(Y,"='$1']"),d.matchesSelector&&y&&(!a||!a.test(t))&&(!b||!b.test(t)))try{var n=h.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,f),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=g(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=l[e+" "];return t||(t=new RegExp("(^|"+F+")"+e+"("+F+"|$)"))&&l(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=re.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1(?:<\/\1>|)$/,x=/^.[^:#\[\.,]*$/;function w(e,n,i){if(C.isFunction(n))return C.grep(e,function(e,t){return!!n.call(e,t,e)!==i});if(n.nodeType)return C.grep(e,function(e){return e===n!==i});if("string"==typeof n){if(x.test(n))return C.filter(n,e,i);n=C.filter(n,e)}return C.grep(e,function(e){return 0<=C.inArray(e,n)!==i})}C.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?C.find.matchesSelector(i,e)?[i]:[]:C.find.matches(e,C.grep(t,function(e){return 1===e.nodeType}))},C.fn.extend({find:function(e){var t,n=[],i=this,r=i.length;if("string"!=typeof e)return this.pushStack(C(e).filter(function(){for(t=0;t)[^>]*|#([\w-]*))$/;(C.fn.init=function(e,t){var n,i;if(!e)return this;if("string"!=typeof e)return e.nodeType?(this.context=this[0]=e,this.length=1,this):C.isFunction(e)?void 0!==T.ready?T.ready(e):e(C):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),C.makeArray(e,this));if(!(n="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&3<=e.length?[null,e,null]:E.exec(e))||!n[1]&&t)return!t||t.jquery?(t||T).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof C?t[0]:t,C.merge(this,C.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:_,!0)),b.test(n[1])&&C.isPlainObject(t))for(n in t)C.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}if((i=_.getElementById(n[2]))&&i.parentNode){if(i.id!==n[2])return T.find(e);this.length=1,this[0]=i}return this.context=_,this.selector=e,this}).prototype=C.fn,T=C(_);var S=/^(?:parents|prev(?:Until|All))/,N={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}C.extend({dir:function(e,t,n){for(var i=[],r=e[t];r&&9!==r.nodeType&&(void 0===n||1!==r.nodeType||!C(r).is(n));)1===r.nodeType&&i.push(r),r=r[t];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),C.fn.extend({has:function(e){var t,n=C(e,this),i=n.length;return this.filter(function(){for(t=0;t
a",v.leadingWhitespace=3===t.firstChild.nodeType,v.tbody=!t.getElementsByTagName("tbody").length,v.htmlSerialize=!!t.getElementsByTagName("link").length,v.html5Clone="<:nav>"!==_.createElement("nav").cloneNode(!0).outerHTML,e.type="checkbox",e.checked=!0,n.appendChild(e),v.appendChecked=e.checked,t.innerHTML="",v.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,n.appendChild(t),t.innerHTML="",v.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,v.noCloneEvent=!0,t.attachEvent&&(t.attachEvent("onclick",function(){v.noCloneEvent=!1}),t.cloneNode(!0).click()),null==v.deleteExpando){v.deleteExpando=!0;try{delete t.test}catch(e){v.deleteExpando=!1}}}(),function(){var e,t,n=_.createElement("div");for(e in{submit:!0,change:!0,focusin:!0})t="on"+e,(v[e+"Bubbles"]=t in d)||(n.setAttribute(t,"t"),v[e+"Bubbles"]=!1===n.attributes[t].expando);n=null}();var Y=/^(?:input|select|textarea)$/i,Q=/^key/,J=/^(?:mouse|pointer|contextmenu)|click/,V=/^(?:focusinfocus|focusoutblur)$/,G=/^([^.]*)(?:\.(.+)|)$/;function K(){return!0}function Z(){return!1}function ee(){try{return _.activeElement}catch(e){}}function te(e){var t=ne.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}C.event={global:{},add:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C._data(e);if(m){for(n.handler&&(n=(l=n).handler,r=l.selector),n.guid||(n.guid=C.guid++),(s=m.events)||(s=m.events={}),(c=m.handle)||((c=m.handle=function(e){return typeof C===L||e&&C.event.triggered===e.type?void 0:C.event.dispatch.apply(c.elem,arguments)}).elem=e),a=(t=(t||"").match(j)||[""]).length;a--;)h=g=(o=G.exec(t[a])||[])[1],d=(o[2]||"").split(".").sort(),h&&(u=C.event.special[h]||{},h=(r?u.delegateType:u.bindType)||h,u=C.event.special[h]||{},f=C.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&C.expr.match.needsContext.test(r),namespace:d.join(".")},l),(p=s[h])||((p=s[h]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,i,d,c)||(e.addEventListener?e.addEventListener(h,c,!1):e.attachEvent&&e.attachEvent("on"+h,c))),u.add&&(u.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),r?p.splice(p.delegateCount++,0,f):p.push(f),C.event.global[h]=!0);e=null}},remove:function(e,t,n,i,r){var o,s,a,l,u,c,f,p,h,d,g,m=C.hasData(e)&&C._data(e);if(m&&(c=m.events)){for(u=(t=(t||"").match(j)||[""]).length;u--;)if(h=g=(a=G.exec(t[u])||[])[1],d=(a[2]||"").split(".").sort(),h){for(f=C.event.special[h]||{},p=c[h=(i?f.delegateType:f.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=p.length;o--;)s=p[o],!r&&g!==s.origType||n&&n.guid!==s.guid||a&&!a.test(s.namespace)||i&&i!==s.selector&&("**"!==i||!s.selector)||(p.splice(o,1),s.selector&&p.delegateCount--,f.remove&&f.remove.call(e,s));l&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,d,m.handle)||C.removeEvent(e,h,m.handle),delete c[h])}else for(h in c)C.event.remove(e,h+t[u],n,i,!0);C.isEmptyObject(c)&&(delete m.handle,C._removeData(e,"events"))}},trigger:function(e,t,n,i){var r,o,s,a,l,u,c,f=[n||_],p=m.call(e,"type")?e.type:e,h=m.call(e,"namespace")?e.namespace.split("."):[];if(s=u=n=n||_,3!==n.nodeType&&8!==n.nodeType&&!V.test(p+C.event.triggered)&&(0<=p.indexOf(".")&&(p=(h=p.split(".")).shift(),h.sort()),o=p.indexOf(":")<0&&"on"+p,(e=e[C.expando]?e:new C.Event(p,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=h.join("."),e.namespace_re=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:C.makeArray(t,[e]),l=C.event.special[p]||{},i||!l.trigger||!1!==l.trigger.apply(n,t))){if(!i&&!l.noBubble&&!C.isWindow(n)){for(a=l.delegateType||p,V.test(a+p)||(s=s.parentNode);s;s=s.parentNode)f.push(s),u=s;u===(n.ownerDocument||_)&&f.push(u.defaultView||u.parentWindow||d)}for(c=0;(s=f[c++])&&!e.isPropagationStopped();)e.type=1]","i"),oe=/^\s+/,se=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ae=/<([\w:]+)/,le=/\s*$/g,ge={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:v.htmlSerialize?[0,"",""]:[1,"X
","
"]},me=te(_).appendChild(_.createElement("div"));function ve(e,t){var n,i,r=0,o=typeof e.getElementsByTagName!==L?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==L?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(i=n[r]);r++)!t||C.nodeName(i,t)?o.push(i):C.merge(o,ve(i,t));return void 0===t||t&&C.nodeName(e,t)?C.merge([e],o):o}function ye(e){X.test(e.type)&&(e.defaultChecked=e.checked)}function be(e,t){return C.nodeName(e,"table")&&C.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function xe(e){return e.type=(null!==C.find.attr(e,"type"))+"/"+e.type,e}function we(e){var t=he.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Te(e,t){for(var n,i=0;null!=(n=e[i]);i++)C._data(n,"globalEval",!t||C._data(t[i],"globalEval"))}function Ce(e,t){if(1===t.nodeType&&C.hasData(e)){var n,i,r,o=C._data(e),s=C._data(t,o),a=o.events;if(a)for(n in delete s.handle,s.events={},a)for(i=0,r=a[n].length;i")?o=e.cloneNode(!0):(me.innerHTML=e.outerHTML,me.removeChild(o=me.firstChild)),!(v.noCloneEvent&&v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||C.isXMLDoc(e)))for(i=ve(o),a=ve(e),s=0;null!=(r=a[s]);++s)i[s]&&_e(r,i[s]);if(t)if(n)for(a=a||ve(e),i=i||ve(o),s=0;null!=(r=a[s]);s++)Ce(r,i[s]);else Ce(e,o);return 0<(i=ve(o,"script")).length&&Te(i,!l&&ve(e,"script")),i=a=r=null,o},buildFragment:function(e,t,n,i){for(var r,o,s,a,l,u,c,f=e.length,p=te(t),h=[],d=0;d")+c[2],r=c[0];r--;)a=a.lastChild;if(!v.leadingWhitespace&&oe.test(o)&&h.push(t.createTextNode(oe.exec(o)[0])),!v.tbody)for(r=(o="table"!==l||le.test(o)?""!==c[1]||le.test(o)?0:a:a.firstChild)&&o.childNodes.length;r--;)C.nodeName(u=o.childNodes[r],"tbody")&&!u.childNodes.length&&o.removeChild(u);for(C.merge(h,a.childNodes),a.textContent="";a.firstChild;)a.removeChild(a.firstChild);a=p.lastChild}else h.push(t.createTextNode(o));for(a&&p.removeChild(a),v.appendChecked||C.grep(ve(h,"input"),ye),d=0;o=h[d++];)if((!i||-1===C.inArray(o,i))&&(s=C.contains(o.ownerDocument,o),a=ve(p.appendChild(o),"script"),s&&Te(a),n))for(r=0;o=a[r++];)pe.test(o.type||"")&&n.push(o);return a=null,p},cleanData:function(e,t){for(var n,i,r,o,s=0,a=C.expando,l=C.cache,u=v.deleteExpando,c=C.event.special;null!=(n=e[s]);s++)if((t||C.acceptData(n))&&(o=(r=n[a])&&l[r])){if(o.events)for(i in o.events)c[i]?C.event.remove(n,i):C.removeEvent(n,i,o.handle);l[r]&&(delete l[r],u?delete n[a]:typeof n.removeAttribute!==L?n.removeAttribute(a):n[a]=null,f.push(r))}}}),C.fn.extend({text:function(e){return U(this,function(e){return void 0===e?C.text(this):this.empty().append((this[0]&&this[0].ownerDocument||_).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||be(this,e).appendChild(e)})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=be(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?C.filter(e,this):this,r=0;null!=(n=i[r]);r++)t||1!==n.nodeType||C.cleanData(ve(n)),n.parentNode&&(t&&C.contains(n.ownerDocument,n)&&Te(ve(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&C.cleanData(ve(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&C.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return C.clone(this,e,t)})},html:function(e){return U(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(ie,""):void 0;if("string"==typeof e&&!ce.test(e)&&(v.htmlSerialize||!re.test(e))&&(v.leadingWhitespace||!oe.test(e))&&!ge[(ae.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(se,"<$1>");try{for(;n")).appendTo(t.documentElement))[0].contentWindow||Ee[0].contentDocument).document).write(),t.close(),n=De(e,t),Ee.detach()),Ne[e]=n),n}v.shrinkWrapBlocks=function(){return null!=Se?Se:(Se=!1,(t=_.getElementsByTagName("body")[0])&&t.style?(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),typeof e.style.zoom!==L&&(e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",e.appendChild(_.createElement("div")).style.width="5px",Se=3!==e.offsetWidth),t.removeChild(n),Se):void 0);var e,t,n};var je,Ae,Pe,He,Me,Le,Oe,Ie,Fe,We=/^margin/,qe=new RegExp("^("+B+")(?!px)[a-z%]+$","i"),Re=/^(top|right|bottom|left)$/;function $e(t,n){return{get:function(){var e=t();if(null!=e){if(!e)return(this.get=n).apply(this,arguments);delete this.get}}}}function Be(){var e,t,n,i;(t=_.getElementsByTagName("body")[0])&&t.style&&(e=_.createElement("div"),(n=_.createElement("div")).style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",t.appendChild(n).appendChild(e),e.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",Le=Oe=!1,Fe=!0,d.getComputedStyle&&(Le="1%"!==(d.getComputedStyle(e,null)||{}).top,Oe="4px"===(d.getComputedStyle(e,null)||{width:"4px"}).width,(i=e.appendChild(_.createElement("div"))).style.cssText=e.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",e.style.width="1px",Fe=!parseFloat((d.getComputedStyle(i,null)||{}).marginRight),e.removeChild(i)),e.innerHTML="
t
",(i=e.getElementsByTagName("td"))[0].style.cssText="margin:0;border:0;padding:0;display:none",(Ie=0===i[0].offsetHeight)&&(i[0].style.display="",i[1].style.display="none",Ie=0===i[0].offsetHeight),t.removeChild(n))}d.getComputedStyle?(je=function(e){return e.ownerDocument.defaultView.opener?e.ownerDocument.defaultView.getComputedStyle(e,null):d.getComputedStyle(e,null)},Ae=function(e,t,n){var i,r,o,s,a=e.style;return s=(n=n||je(e))?n.getPropertyValue(t)||n[t]:void 0,n&&(""!==s||C.contains(e.ownerDocument,e)||(s=C.style(e,t)),qe.test(s)&&We.test(t)&&(i=a.width,r=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=i,a.minWidth=r,a.maxWidth=o)),void 0===s?s:s+""}):_.documentElement.currentStyle&&(je=function(e){return e.currentStyle},Ae=function(e,t,n){var i,r,o,s,a=e.style;return null==(s=(n=n||je(e))?n[t]:void 0)&&a&&a[t]&&(s=a[t]),qe.test(s)&&!Re.test(t)&&(i=a.left,(o=(r=e.runtimeStyle)&&r.left)&&(r.left=e.currentStyle.left),a.left="fontSize"===t?"1em":s,s=a.pixelLeft+"px",a.left=i,o&&(r.left=o)),void 0===s?s:s+""||"auto"}),(Pe=_.createElement("div")).innerHTML="
a",(He=(Me=Pe.getElementsByTagName("a")[0])&&Me.style)&&(He.cssText="float:left;opacity:.5",v.opacity="0.5"===He.opacity,v.cssFloat=!!He.cssFloat,Pe.style.backgroundClip="content-box",Pe.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===Pe.style.backgroundClip,v.boxSizing=""===He.boxSizing||""===He.MozBoxSizing||""===He.WebkitBoxSizing,C.extend(v,{reliableHiddenOffsets:function(){return null==Ie&&Be(),Ie},boxSizingReliable:function(){return null==Oe&&Be(),Oe},pixelPosition:function(){return null==Le&&Be(),Le},reliableMarginRight:function(){return null==Fe&&Be(),Fe}})),C.swap=function(e,t,n,i){var r,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];for(o in r=n.apply(e,i||[]),t)e.style[o]=s[o];return r};var ze=/alpha\([^)]*\)/i,Ue=/opacity\s*=\s*([^)]*)/,Xe=/^(none|table(?!-c[ea]).+)/,Ye=new RegExp("^("+B+")(.*)$","i"),Qe=new RegExp("^([+-])=("+B+")","i"),Je={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","O","Moz","ms"];function Ke(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),i=t,r=Ge.length;r--;)if((t=Ge[r]+n)in e)return t;return i}function Ze(e,t){for(var n,i,r,o=[],s=0,a=e.length;s
a",ut=at.getElementsByTagName("a")[0],ct=(lt=_.createElement("select")).appendChild(_.createElement("option")),st=at.getElementsByTagName("input")[0],ut.style.cssText="top:1px",v.getSetAttribute="t"!==at.className,v.style=/top/.test(ut.getAttribute("style")),v.hrefNormalized="/a"===ut.getAttribute("href"),v.checkOn=!!st.value,v.optSelected=ct.selected,v.enctype=!!_.createElement("form").enctype,lt.disabled=!0,v.optDisabled=!ct.disabled,(st=_.createElement("input")).setAttribute("value",""),v.input=""===st.getAttribute("value"),st.value="t",st.setAttribute("type","radio"),v.radioValue="t"===st.value;var xt=/\r/g;C.fn.extend({val:function(n){var i,e,r,t=this[0];return arguments.length?(r=C.isFunction(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=r?n.call(this,e,C(this).val()):n)?t="":"number"==typeof t?t+="":C.isArray(t)&&(t=C.map(t,function(e){return null==e?"":e+""})),(i=C.valHooks[this.type]||C.valHooks[this.nodeName.toLowerCase()])&&"set"in i&&void 0!==i.set(this,t,"value")||(this.value=t))})):t?(i=C.valHooks[t.type]||C.valHooks[t.nodeName.toLowerCase()])&&"get"in i&&void 0!==(e=i.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),C.extend({valHooks:{option:{get:function(e){var t=C.find.attr(e,"value");return null!=t?t:C.trim(C.text(e))}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,s=o?null:[],a=o?r+1:i.length,l=r<0?a:o?r:0;l").append(C.parseHTML(e)).find(i):e)}).complete(n&&function(e,t){s.each(n,r||[e.responseText,t,e])}),this},C.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){C.fn[t]=function(e){return this.on(t,e)}}),C.expr.filters.animated=function(t){return C.grep(C.timers,function(e){return t===e.elem}).length};var cn=d.document.documentElement;function fn(e){return C.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}C.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,u=C.css(e,"position"),c=C(e),f={};"static"===u&&(e.style.position="relative"),a=c.offset(),o=C.css(e,"top"),l=C.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1").outerWidth(1).jquery||D.each(["Width","Height"],function(e,n){var r="Width"===n?["Left","Right"]:["Top","Bottom"],i=n.toLowerCase(),o={innerWidth:D.fn.innerWidth,innerHeight:D.fn.innerHeight,outerWidth:D.fn.outerWidth,outerHeight:D.fn.outerHeight};function s(e,t,n,i){return D.each(r,function(){t-=parseFloat(D.css(e,"padding"+this))||0,n&&(t-=parseFloat(D.css(e,"border"+this+"Width"))||0),i&&(t-=parseFloat(D.css(e,"margin"+this))||0)}),t}D.fn["inner"+n]=function(e){return void 0===e?o["inner"+n].call(this):this.each(function(){D(this).css(i,s(this,e)+"px")})},D.fn["outer"+n]=function(e,t){return"number"!=typeof e?o["outer"+n].call(this,e):this.each(function(){D(this).css(i,s(this,e,!0,t)+"px")})}}),D.fn.addBack||(D.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),D("").data("a-b","a").removeData("a-b").data("a-b")&&(D.fn.removeData=(t=D.fn.removeData,function(e){return arguments.length?t.call(this,D.camelCase(e)):t.call(this)})),D.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),D.fn.extend({focus:(i=D.fn.focus,function(t,n){return"number"==typeof t?this.each(function(){var e=this;setTimeout(function(){D(e).focus(),n&&n.call(e)},t)}):i.apply(this,arguments)}),disableSelection:(n="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.bind(n+".ui-disableSelection",function(e){e.preventDefault()})}),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(e){if(void 0!==e)return this.css("zIndex",e);if(this.length)for(var t,n,i=D(this[0]);i.length&&i[0]!==document;){if(("absolute"===(t=i.css("position"))||"relative"===t||"fixed"===t)&&(n=parseInt(i.css("zIndex"),10),!isNaN(n)&&0!==n))return n;i=i.parent()}return 0}}),D.ui.plugin={add:function(e,t,n){var i,r=D.ui[e].prototype;for(i in n)r.plugins[i]=r.plugins[i]||[],r.plugins[i].push([t,n[i]])},call:function(e,t,n,i){var r,o=e.plugins[t];if(o&&(i||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(r=0;r",options:{disabled:!1,create:null},_createWidget:function(e,t){t=D(t||this.defaultElement||this)[0],this.element=D(t),this.uuid=a++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=D(),this.hoverable=D(),this.focusable=D(),t!==this&&(D.data(t,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===t&&this.destroy()}}),this.document=D(t.style?t.ownerDocument:t.document||t),this.window=D(this.document[0].defaultView||this.document[0].parentWindow)),this.options=D.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:D.noop,_getCreateEventData:D.noop,_create:D.noop,_init:D.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(D.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:D.noop,widget:function(){return this.element},option:function(e,t){var n,i,r,o=e;if(0===arguments.length)return D.widget.extend({},this.options);if("string"==typeof e)if(o={},e=(n=e.split(".")).shift(),n.length){for(i=o[e]=D.widget.extend({},this.options[e]),r=0;r=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){D.ui=D.ui||{};var r,T,C=Math.max,_=Math.abs,E=Math.round,i=/left|center|right/,o=/top|center|bottom/,s=/[\+\-]\d+(\.[\d]+)?%?/,a=/^\w+/,l=/%$/,u=D.fn.position;function S(e,t,n){return[parseFloat(e[0])*(l.test(e[0])?t/100:1),parseFloat(e[1])*(l.test(e[1])?n/100:1)]}function N(e,t){return parseInt(D.css(e,t),10)||0}D.position={scrollbarWidth:function(){if(void 0!==r)return r;var e,t,n=D("
"),i=n.children()[0];return D("body").append(n),e=i.offsetWidth,n.css("overflow","scroll"),e===(t=i.offsetWidth)&&(t=n[0].clientWidth),n.remove(),r=e-t},getScrollInfo:function(e){var t=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),n=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),i="scroll"===t||"auto"===t&&e.widthC(_(i),_(r))?o.important="horizontal":o.important="vertical",f.using.call(this,e,o)}),s.offset(D.extend(u,{using:e}))})},D.ui.position={fit:{left:function(e,t){var n,i=t.within,r=i.isWindow?i.scrollLeft:i.offset.left,o=i.width,s=e.left-t.collisionPosition.marginLeft,a=r-s,l=s+t.collisionWidth-o-r;t.collisionWidth>o?0o?0").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var t=this.document[0];if(this.handleElement.is(e.target))try{t.activeElement&&"body"!==t.activeElement.nodeName.toLowerCase()&&D(t.activeElement).blur()}catch(e){}},_mouseStart:function(e){var t=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),D.ui.ddmanager&&(D.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0n[2]&&(l=n[2]+this.offset.click.left),e.pageY-this.offset.click.top>n[3]&&(u=n[3]+this.offset.click.top)),s.grid&&(r=s.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,u=!n||r-this.offset.click.top>=n[1]||r-this.offset.click.top>n[3]?r:r-this.offset.click.top>=n[1]?r-s.grid[1]:r+s.grid[1],o=s.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,l=!n||o-this.offset.click.left>=n[0]||o-this.offset.click.left>n[2]?o:o-this.offset.click.left>=n[0]?o-s.grid[0]:o+s.grid[0]),"y"===s.axis&&(l=this.originalPageX),"x"===s.axis&&(u=this.originalPageY)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(e,t,n){return n=n||this._uiHash(),D.ui.plugin.call(this,e,[t,n,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),n.offset=this.positionAbs),D.Widget.prototype._trigger.call(this,e,t,n)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),D.ui.plugin.add("draggable","connectToSortable",{start:function(t,e,n){var i=D.extend({},e,{item:n.element});n.sortables=[],D(n.options.connectToSortable).each(function(){var e=D(this).sortable("instance");e&&!e.options.disabled&&(n.sortables.push(e),e.refreshPositions(),e._trigger("activate",t,i))})},stop:function(t,e,n){var i=D.extend({},e,{item:n.element});n.cancelHelperRemoval=!1,D.each(n.sortables,function(){var e=this;e.isOver?(e.isOver=0,n.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,i))})},drag:function(n,i,r){D.each(r.sortables,function(){var e=!1,t=this;t.positionAbs=r.positionAbs,t.helperProportions=r.helperProportions,t.offset.click=r.offset.click,t._intersectsWith(t.containerCache)&&(e=!0,D.each(r.sortables,function(){return this.positionAbs=r.positionAbs,this.helperProportions=r.helperProportions,this.offset.click=r.offset.click,this!==t&&this._intersectsWith(this.containerCache)&&D.contains(t.element[0],this.element[0])&&(e=!1),e})),e?(t.isOver||(t.isOver=1,r._parent=i.helper.parent(),t.currentItem=i.helper.appendTo(t.element).data("ui-sortable-item",!0),t.options._helper=t.options.helper,t.options.helper=function(){return i.helper[0]},n.target=t.currentItem[0],t._mouseCapture(n,!0),t._mouseStart(n,!0,!0),t.offset.click.top=r.offset.click.top,t.offset.click.left=r.offset.click.left,t.offset.parent.left-=r.offset.parent.left-t.offset.parent.left,t.offset.parent.top-=r.offset.parent.top-t.offset.parent.top,r._trigger("toSortable",n),r.dropped=t.element,D.each(r.sortables,function(){this.refreshPositions()}),r.currentItem=r.element,t.fromOutside=r),t.currentItem&&(t._mouseDrag(n),i.position=t.position)):t.isOver&&(t.isOver=0,t.cancelHelperRemoval=!0,t.options._revert=t.options.revert,t.options.revert=!1,t._trigger("out",n,t._uiHash(t)),t._mouseStop(n,!0),t.options.revert=t.options._revert,t.options.helper=t.options._helper,t.placeholder&&t.placeholder.remove(),i.helper.appendTo(r._parent),r._refreshOffsets(n),i.position=r._generatePosition(n,!0),r._trigger("fromSortable",n),r.dropped=!1,D.each(r.sortables,function(){this.refreshPositions()}))})}}),D.ui.plugin.add("draggable","cursor",{start:function(e,t,n){var i=D("body"),r=n.options;i.css("cursor")&&(r._cursor=i.css("cursor")),i.css("cursor",r.cursor)},stop:function(e,t,n){var i=n.options;i._cursor&&D("body").css("cursor",i._cursor)}}),D.ui.plugin.add("draggable","opacity",{start:function(e,t,n){var i=D(t.helper),r=n.options;i.css("opacity")&&(r._opacity=i.css("opacity")),i.css("opacity",r.opacity)},stop:function(e,t,n){var i=n.options;i._opacity&&D(t.helper).css("opacity",i._opacity)}}),D.ui.plugin.add("draggable","scroll",{start:function(e,t,n){n.scrollParentNotHidden||(n.scrollParentNotHidden=n.helper.scrollParent(!1)),n.scrollParentNotHidden[0]!==n.document[0]&&"HTML"!==n.scrollParentNotHidden[0].tagName&&(n.overflowOffset=n.scrollParentNotHidden.offset())},drag:function(e,t,n){var i=n.options,r=!1,o=n.scrollParentNotHidden[0],s=n.document[0];o!==s&&"HTML"!==o.tagName?(i.axis&&"x"===i.axis||(n.overflowOffset.top+o.offsetHeight-e.pageY")[0],x=c.each,b.style.cssText="background-color:rgba(1,1,1,.5)",y.rgba=-1").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),t={width:n.width(),height:n.height()},r=document.activeElement;try{r.id}catch(e){r=document.body}return n.wrap(e),n[0]!==r&&!D.contains(n[0],r)||D(r).focus(),e=n.parent(),"static"===n.css("position")?(e.css({position:"relative"}),n.css({position:"relative"})):(D.extend(i,{position:n.css("position"),zIndex:n.css("z-index")}),D.each(["top","left","bottom","right"],function(e,t){i[t]=n.css(t),isNaN(parseInt(i[t],10))&&(i[t]="auto")}),n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),n.css(t),e.css(i).show()},removeWrapper:function(e){var t=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),e[0]!==t&&!D.contains(e[0],t)||D(t).focus()),e},setTransition:function(i,e,r,o){return o=o||{},D.each(e,function(e,t){var n=i.cssUnit(t);0r&&0!==r||!1===i.call(e,o))&&jQuery.timer.remove(e,n,i)}a.timerID=i.timerID,s[n][i.timerID]||(s[n][i.timerID]=window.setInterval(a,t)),this.global.push(e)}},remove:function(e,t,n){var i,r=jQuery.data(e,this.dataKey);if(r){if(t){if(r[t]){if(n)n.timerID&&(window.clearInterval(r[t][n.timerID]),delete r[t][n.timerID]);else for(var n in r[t])window.clearInterval(r[t][n]),delete r[t][n];for(i in r[t])break;i||(i=null,delete r[t])}}else for(t in r)this.remove(e,t,n);for(i in r)break;i||jQuery.removeData(e,this.dataKey)}}}}),jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(e,t){jQuery.timer.remove(t)})}),function(){"use strict";var a={version:"1.0.1-nanoui",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{:([\s\S]+?)\}\}/g,encode:/\{\{>([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\/?if\s*([\s\S]*?)\s*\}\}/g,conditionalElse:/\{\{else\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{\/?for\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,props:/\{\{\/?props\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,empty:/\{\{empty\}\}/g,varname:"data, config, helper",strip:!0,append:!0,selfcontained:!1},template:void 0,compile:void 0};function l(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(e,function(e){return t[e]||e}):this}}"undefined"!=typeof module&&module.exports?module.exports=a:"function"==typeof define&&define.amd?define(function(){return a}):function(){return this||(0,eval)("this")}().doT=a,String.prototype.encodeHTML=l();var u={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},c=/$^/;function f(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}a.template=function(e,t,n){var i,r=(t=t||a.templateSettings).append?u.append:u.split,o=0,s=t.use||t.define?function i(r,e,o){return("string"==typeof e?e:e.toString()).replace(r.define||c,function(e,i,t,n){return 0===i.indexOf("def.")&&(i=i.substring(4)),i in o||(":"===t?(r.defineParams&&n.replace(r.defineParams,function(e,t,n){o[i]={arg:t,text:n}}),i in o||(o[i]=n)):new Function("def","def['"+i+"']="+n)(o)),""}).replace(r.use||c,function(e,t){r.useParams&&(t=t.replace(r.useParams,function(e,t,n,i){if(o[n]&&o[n].arg&&i){var r=(n+":"+i).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[r]=o[n].text.replace(new RegExp("(^|[^\\w$])"+o[n].arg+"([^\\w$])","g"),"$1"+i+"$2"),t+"def.__exp['"+r+"']"}}));var n=new Function("def","return "+t)(o);return n?i(r,n,o):n})}(t,e,n||{}):e;s=("var out='"+(t.strip?s.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):s).replace(/'|\\/g,"\\$&").replace(t.interpolate||c,function(e,t){return r.start+f(t)+r.end}).replace(t.encode||c,function(e,t){return i=!0,r.start+f(t)+r.endencode}).replace(t.conditional||c,function(e,t){return t?"';if("+f(t)+"){out+='":"';}out+='"}).replace(t.conditionalElse||c,function(e,t){return t?"';}else if("+f(t)+"){out+='":"';}else{out+='"}).replace(t.iterate||c,function(e,t,n,i){if(!t)return"';} } out+='";o+=1,n=n||"value",i=i||"index",t=f(t);var r="arr"+o;return"';var "+r+"="+t+";if("+r+" && "+r+".length > 0){var "+n+","+i+"=-1,l"+o+"="+r+".length-1;while("+i+" 0){var "+n+";for( var "+i+" in "+r+"){ if (!"+r+".hasOwnProperty("+i+")) continue; "+n+"="+r+"["+i+"];out+='"}).replace(t.empty||c,function(e){return"';}}else{if(true){out+='"}).replace(t.evaluate||c,function(e,t){return"';"+f(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|\}|^|\{)out\+=''\+/g,"$1out+="),i&&t.selfcontained&&(s="String.prototype.encodeHTML=("+l.toString()+"());"+s);try{return new Function(t.varname,s)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+s),e}},a.compile=function(e,t){return a.template(e,null,t)}}(),function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){function n(e){try{var t=S.call(e).replace(/\/\/.*\n/g,"").replace(/\/\*[.\s\S]*\*\//g,"").replace(/\n/gm," ").replace(/ {2}/g," ");return N.test(t)}catch(e){return}}function p(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(E)return function(e){try{return n(e)?!1:(S.call(e),!0)}catch(e){return!1}}(e);if(n(e))return!1;var t=_.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}var h,d,l=Array,e=l.prototype,a=Object,t=a.prototype,u=Function,i=u.prototype,v=String,r=v.prototype,y=Number,o=y.prototype,c=e.slice,s=e.splice,g=e.push,f=e.unshift,m=e.concat,b=e.join,x=i.call,w=i.apply,T=Math.max,C=Math.min,_=t.toString,E="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,N=/^\s*class /,D=RegExp.prototype.exec;h=function(e){return"object"==typeof e&&(E?function(e){try{return D.call(e),!0}catch(e){return!1}}(e):"[object RegExp]"===_.call(e))};var k=String.prototype.valueOf;d=function(e){return"string"==typeof e||"object"==typeof e&&(E?function(e){try{return k.call(e),!0}catch(e){return!1}}(e):"[object String]"===_.call(e))};function j(e){var t=typeof e;return null===e||"object"!=t&&"function"!=t}function A(){}var P,H,M=a.defineProperty&&function(){try{var e={};for(var t in a.defineProperty(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}(),L=(P=t.hasOwnProperty,H=M?function(e,t,n,i){!i&&t in e||a.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,i){!i&&t in e||(e[t]=n)},function(e,t,n){for(var i in t)P.call(t,i)&&H(e,i,t[i],n)}),O=y.isNaN||function(e){return e!=e},I=function(e){var t=+e;return O(t)?t=0:0!==t&&t!==1/0&&t!==-1/0&&(t=(0>>0};L(i,{bind:function(t){var n=this;if(!p(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var i,r=c.call(arguments,1),e=T(0,n.length-r.length),o=[],s=0;s=r)throw new TypeError("reduce of empty array with no initial value")}for(;sError name: "+e.name+"
Error Message: "+e.message)}t.hasOwnProperty("data")||(a&&a.hasOwnProperty("data")?t.data=a.data:t.data={}),n?l(t):a=t}(e)},addBeforeUpdateCallback:function(e,t){r[e]=t},addBeforeUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addBeforeUpdateCallback(t,e[t])},removeBeforeUpdateCallback:function(e){r.hasOwnProperty(e)&&delete r[e]},executeBeforeUpdateCallbacks:function(e){return t(r,e)},addAfterUpdateCallback:function(e,t){o[e]=t},addAfterUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addAfterUpdateCallback(t,e[t])},removeAfterUpdateCallback:function(e){o.hasOwnProperty(e)&&delete o[e]},executeAfterUpdateCallbacks:function(e){return t(o,e)},addState:function(e){e instanceof NanoStateClass?e.key?i[e.key]=e:reportError("ERROR: Attempted to add a state with an invalid stateKey"):reportError("ERROR: Attempted to add a state which is not instanceof NanoStateClass")},setCurrentState:function(e){if(void 0===e||!e)return reportError("ERROR: No state key was passed!"),!1;if(!i.hasOwnProperty(e))return reportError("ERROR: Attempted to set a current state which does not exist: "+e),!1;var t=s;return s=i[e],null!=t&&t.onRemove(s),s.onAdd(t),!0},getCurrentState:function(){return s},getData:function(){return a}}}(),NanoBaseCallbacks=function(){var a=!0,t={},n={status:function(n){var e;return 2==n.config.status?(e="good",$(".linkActive").removeClass("inactive")):(e=1==n.config.status?"average":"bad",$(".linkActive").addClass("inactive")),$(".statusicon").removeClass("good bad average").addClass(e),$(".linkActive").stopTime("linkPending"),$(".linkActive").removeClass("linkPending"),$(".linkActive").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("href");null!=t&&a&&(a=!1,$("body").oneTime(300,"enableClick",function(){a=!0}),2==n.config.status&&$(this).oneTime(300,"linkPending",function(){$(this).addClass("linkPending")}),window.location.href=t)}),n},nanomap:function(e){return $(".mapIcon").off("mouseenter mouseleave").on("mouseenter",function(e){$("#uiMapTooltip").html($(this).children(".tooltip").html()).show().stopTime().oneTime(5e3,"hideTooltip",function(){$(this).fadeOut(500)})}),$(".zoomLink").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("zoomLevel"),n=$("#uiMap"),a=n.width()*t,r=n.height()*t;n.css({zoom:t,left:"50%",top:"50%",marginLeft:"-"+Math.floor(a/2)+"px",marginTop:"-"+Math.floor(r/2)+"px"})}),$("#uiMapImage").attr("src",e.config.map+"_nanomap_z"+e.config.mapZLevel+".png"),e}};return{addCallbacks:function(){NanoStateManager.addBeforeUpdateCallbacks(t),NanoStateManager.addAfterUpdateCallbacks(n)},removeCallbacks:function(){for(var e in t)t.hasOwnProperty(e)&&NanoStateManager.removeBeforeUpdateCallback(e);for(var e in n)n.hasOwnProperty(e)&&NanoStateManager.removeAfterUpdateCallback(e)}}}(),NanoBaseHelpers=function(){var t={syndicateMode:function(){return $(".mainBG").css("background","url('syndicate.png') no-repeat fixed center/50% 50%, linear-gradient(to bottom, #8f1414 0%, #4B0A0A 100%) no-repeat fixed center;"),$("#uiTitleFluff").css("background-image","url('uiTitleFluff-Syndicate.png')"),$("#uiTitleFluff").css("background-position","50% 50%"),$("#uiTitleFluff").css("background-repeat","no-repeat"),""},combine:function(e,t){return e&&t?e.concat(t):e||t},dump:function(e){return JSON.stringify(e)},link:function(e,t,n,a,r,o){var i="",s="noIcon";void 0!==t&&t&&(i='
',s="hasIcon"),void 0!==r&&r||(r="link");var l="";void 0!==o&&o&&(l='id="'+o+'"');var c=NanoTransition.allocID(l+"_"+e.toString().replace(/[^a-z0-9_]/gi,"_")+"_"+t);return void 0!==a&&a?'