From 52d77eefc8e42ff04fa77b42eeea8c389b536486 Mon Sep 17 00:00:00 2001 From: Jack Edge Date: Thu, 16 Jun 2016 20:45:01 +0100 Subject: [PATCH 01/19] Drones can hear robotic talk :cl: coiax rscadd: Drones can hear robotic talk, but cannot communicate on it. AIs and cyborgs are encouraged to share information with station repair drones. /:cl: --- .../mob/living/simple_animal/friendly/drone/say.dm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm index 8a11b4e86cf..0e607056ccf 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm @@ -1,4 +1,3 @@ - ///////////// //DRONE SAY// ///////////// @@ -31,5 +30,10 @@ /mob/living/simple_animal/drone/proc/drone_chat(msg) - var/rendered = "DRONE CHAT: [name]: [msg]" + var/rendered = "Drone Chat: \ + [name]: \ + [msg]" alert_drones(rendered, 1) + +/mob/living/simple_animal/drone/binarycheck() + return TRUE From 7d0d4d374034abdadfbcd0daa08cea14c31816a4 Mon Sep 17 00:00:00 2001 From: Leo Date: Thu, 16 Jun 2016 17:08:19 -0300 Subject: [PATCH 02/19] Admin message for BZ gas --- code/modules/atmospherics/machinery/portable/canister.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 6c664f7280b..0a6efae2095 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -307,9 +307,10 @@ if(!holding) var/plasma = air_contents.gases["plasma"] var/n2o = air_contents.gases["n2o"] - if(n2o || plasma) - message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""]! (JMP)") - log_admin("[key_name(usr)] opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [x], [y], [z]") + var/bz = air_contents.gases["bz"] + if(n2o || plasma || bz) + message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma && bz ? " & " : ""][plasma ? "Plasma" : ""][bz ? "BZ" : ""]! (JMP)") + log_admin("[key_name(usr)] opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][bz ? "BZ" : ""] at [x], [y], [z]") else logmsg = "Valve was closed by [key_name(usr)], stopping the transfer into \the [holding || "air"].
" investigate_log(logmsg, "atmos") From 2366eb1a20950f50aa1e888a58f7d8b81a5b797c Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Sat, 23 Apr 2016 09:53:29 -0700 Subject: [PATCH 03/19] PUTS NIKNAK OUT OF A JOB! --- SQL/tgstation_schema.sql | 11 +++- SQL/tgstation_schema_prefixed.sql | 9 +++ code/controllers/configuration.dm | 15 +++++ code/modules/admin/IsBanned.dm | 22 ++++++++ code/modules/admin/ipintel.dm | 91 +++++++++++++++++++++++++++++++ config/config.txt | 12 ++++ tgstation.dme | 1 + 7 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 code/modules/admin/ipintel.dm diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 34d83537256..7fb896d93a6 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -364,5 +364,14 @@ CREATE TABLE `notes` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; - +DROP TABLE IF EXISTS `ipintel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `ipintel` ( +`ip` INT UNSIGNED NOT NULL , +`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`intel` REAL NOT NULL DEFAULT '0', +PRIMARY KEY ( `ip` ) +) ENGINE = INNODB; +/*!40101 SET character_set_client = @saved_cs_client */; -- Dump completed on 2013-03-24 18:02:35 diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index fe40d2f72cf..c5bbd407125 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -359,5 +359,14 @@ CREATE TABLE `SS13_notes` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `SS13_ipintel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SS13_ipintel` ( +`ip` INT UNSIGNED NOT NULL , +`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`intel` REAL NOT NULL DEFAULT '0', +PRIMARY KEY ( `ip` ) +) ENGINE = INNODB; -- Dump completed on 2013-03-24 18:02:35 diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 67e4e70422e..f141715dbbd 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -70,6 +70,12 @@ var/forbid_singulo_possession = 0 var/useircbot = 0 + //IP Intel vars + var/ipintel_email + var/ipintel_rating_max = 1 + var/ipintel_save_good = 3 + var/ipintel_save_bad = 1 + var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database @@ -389,6 +395,15 @@ config.notify_new_player_age = text2num(value) if("irc_first_connection_alert") config.irc_first_connection_alert = 1 + if("ipintel_email") + if (value != "ch@nge.me") + config.ipintel_email = value + if("ipintel_rating_max") + config.ipintel_rating_max = text2num(value) + if("ipintel_save_good") + config.ipintel_save_good = text2num(value) + if("ipintel_save_bad") + config.ipintel_save_bad = text2num(value) if("aggressive_changelog") config.aggressive_changelog = 1 if("log_runtimes") diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 0d1c1c2370b..a1515f0c86b 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -99,6 +99,28 @@ log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . + if (config.ipintel_email) + world.log << "checking [ckey] [address]" + var/datum/ipintel/res = get_ip_intel(address) + world.log << "got res: [res.ip], [res.intel], [res.cache], [res.cachedate], [res.cacheminutesago]" + world.log << "checking [res.intel] vs [config.ipintel_rating_max]" + if (res.intel > config.ipintel_rating_max) + world.log << "match" + if (admin) + world.log << "admin" + log_admin("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") + message_admins("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") + addclientmessage(ckey,"You have been allowed to bypass an IP intel ban. Your IP [address] was rated [res.intel*100]% likely to be a bad ip.") + else + world.log << "not admin, banning" + if (!res.cache) + world.log << "first ban" + log_admin("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") + message_admins("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") + + . = list("reason"="IP_INTEL", "desc"="\nYour IP [address] was rated [res.intel*100]% likely to be a bad IP (spammer/proxy). The highest allowed to connect is [config.ipintel_rating_max*100]%.\nThis rating was retrieved [res.cacheminutesago] minutes ago on [res.cachedate] and refreshes in [(config.ipintel_save_bad*60)-res.cacheminutesago] minutes.") + log_access("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") + return . = ..() //default pager ban stuff if (.) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm new file mode 100644 index 00000000000..cab6d96a996 --- /dev/null +++ b/code/modules/admin/ipintel.dm @@ -0,0 +1,91 @@ +/datum/ipintel + var/ip + var/intel = 0 + var/cache = FALSE + var/cacheminutesago = 0 + var/cachedate = "" +/datum/ipintel/New() + cachedate = SQLtime() + +proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) + var/datum/ipintel/res = new() + res.ip = ip + . = res + if (!ip || !config.ipintel_email) + return + if (!bypasscache && establish_db_connection()) + var/DBQuery/query = dbcon.NewQuery("SELECT date,intel,TIMESTAMPDIFF(MINUTE,date,NOW()) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") + query.Execute() + if (query.NextRow()) + res.cache = TRUE + res.cachedate = query.item[1] + res.intel = query.item[2] + res.cacheminutesago = query.item[3] + return + res.intel = ip_intel_query(ip) + if (updatecache && res.intel >= 0 && establish_db_connection()) + //if you're wondering, we don't add or update the date as its a TIMESTAMP field, and as such, automatically updates at any insert or update + var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel)") + query.Execute() + return + + +var/ip_intel_throttle = 0 +var/ip_intel_errors = 0 +/proc/ip_intel_query(ip, var/retry=0) + . = -1 //default + if (!ip) + return + if (ip_intel_throttle > world.timeofday) + return + + var/http[] = world.Export("http://check.getipintel.net/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json") + + if(http) + var/status = text2num(http["STATUS"]) + + if(status == 200) + var/response = json_decode(file2text(http["CONTENT"])) + if(response) + if(response["status"] == "success") + return text2num(response["result"]) + else + ipintel_handle_error("Bad response from server: [response["status"]].", ip, retry) + if (!retry) + sleep(25) + return .(ip, 1) + + else if(status == 429) + ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip) + return + + else + ipintel_handle_error("Unknown status code: [status].", ip, retry) + if (!retry) + sleep(25) + return .(ip, 1) + + else + ipintel_handle_error("Unable to connect to API.", ip, retry) + if (!retry) + sleep(25) + return .(ip, 1) + + + +proc/ipintel_handle_error(error, ip, retry) + if (retry) + ip_intel_errors++ + error += " Could not check [ip]. Disabling IPINTEL for [ip_intel_errors] minute[( ip_intel_errors == 1 ? "" : "s" )]" + ip_intel_throttle = world.timeofday + (10 * 60 * ip_intel_errors) + else + error += " Attempting retry on [ip]." + log_ipintel(error) + +proc/log_ipintel(text) + log_game("IPINTEL: [text]") + + + + + diff --git a/config/config.txt b/config/config.txt index 5cbfcd0c5b0..f371a024b59 100644 --- a/config/config.txt +++ b/config/config.txt @@ -111,6 +111,18 @@ HOSTEDBY Yournamehere ## Uncomment this to stop people connecting to your server without a registered ckey. (i.e. guest-* are all blocked from connecting) GUEST_BAN +### IPINTEL: +### This allows you to block likely proxies by checking ips against getipintel.net +## Maximum rating: (0.90 is good, 1 is 100% likely to be a spammer/proxy, 0.8 is 80%, etc) anything higher then this number is rejected +#IPINTEL_RATING_MAX 0.90 +## Contact email, (required to use the service, leaving blank or default disables IPINTEL) +#IPINTEL_EMAIL ch@nge.me +## How long to save good matches (ipintel rate limits to 15 per minute and 500 per day. so this shouldn't be too low, getipintel.net suggests 6 hours, time is in hours) +#IPINTEL_SAVE_GOOD 6 +## How long to save bad matches (these numbers can change as ips change hands, best not to save these for too long in case somebody gets a new ip used by a spammer/proxy before.) +#IPINTEL_SAVE_BAD 1 + + ## Uncomment to allow web client connections #ALLOW_WEBCLIENT diff --git a/tgstation.dme b/tgstation.dme index 94ba8781c4a..b7142475ca6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -833,6 +833,7 @@ #include "code\modules\admin\create_poll.dm" #include "code\modules\admin\create_turf.dm" #include "code\modules\admin\holder2.dm" +#include "code\modules\admin\ipintel.dm" #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" #include "code\modules\admin\player_panel.dm" From d67b9cbe0c9ff2407b95213568a625f266643d4f Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Sat, 23 Apr 2016 10:03:10 -0700 Subject: [PATCH 04/19] Removes debugging messages --- code/modules/admin/IsBanned.dm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index a1515f0c86b..fb320a66c02 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -100,21 +100,14 @@ return . if (config.ipintel_email) - world.log << "checking [ckey] [address]" var/datum/ipintel/res = get_ip_intel(address) - world.log << "got res: [res.ip], [res.intel], [res.cache], [res.cachedate], [res.cacheminutesago]" - world.log << "checking [res.intel] vs [config.ipintel_rating_max]" if (res.intel > config.ipintel_rating_max) - world.log << "match" if (admin) - world.log << "admin" log_admin("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") message_admins("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") addclientmessage(ckey,"You have been allowed to bypass an IP intel ban. Your IP [address] was rated [res.intel*100]% likely to be a bad ip.") else - world.log << "not admin, banning" if (!res.cache) - world.log << "first ban" log_admin("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") message_admins("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") From 2523a0d604cd5bea6a7f4bde2bef4475583bd932 Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Sat, 23 Apr 2016 15:31:36 -0700 Subject: [PATCH 05/19] whitespace and code formatting changes. --- code/modules/admin/ipintel.dm | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index cab6d96a996..58a69267a54 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -7,7 +7,7 @@ /datum/ipintel/New() cachedate = SQLtime() -proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) +/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip . = res @@ -41,13 +41,13 @@ var/ip_intel_errors = 0 var/http[] = world.Export("http://check.getipintel.net/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json") - if(http) + if (http) var/status = text2num(http["STATUS"]) - if(status == 200) + if (status == 200) var/response = json_decode(file2text(http["CONTENT"])) - if(response) - if(response["status"] == "success") + if (response) + if (response["status"] == "success") return text2num(response["result"]) else ipintel_handle_error("Bad response from server: [response["status"]].", ip, retry) @@ -55,16 +55,14 @@ var/ip_intel_errors = 0 sleep(25) return .(ip, 1) - else if(status == 429) - ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip) + else if (status == 429) + ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip, 1) return - else ipintel_handle_error("Unknown status code: [status].", ip, retry) if (!retry) sleep(25) return .(ip, 1) - else ipintel_handle_error("Unable to connect to API.", ip, retry) if (!retry) @@ -72,8 +70,7 @@ var/ip_intel_errors = 0 return .(ip, 1) - -proc/ipintel_handle_error(error, ip, retry) +/proc/ipintel_handle_error(error, ip, retry) if (retry) ip_intel_errors++ error += " Could not check [ip]. Disabling IPINTEL for [ip_intel_errors] minute[( ip_intel_errors == 1 ? "" : "s" )]" @@ -82,7 +79,7 @@ proc/ipintel_handle_error(error, ip, retry) error += " Attempting retry on [ip]." log_ipintel(error) -proc/log_ipintel(text) +/proc/log_ipintel(text) log_game("IPINTEL: [text]") From c37ae784e7a68ee502da57f7295c055bb4020900 Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Wed, 11 May 2016 23:40:37 -0700 Subject: [PATCH 06/19] Adds local cache, doesn't check reconnects, fixes bugs --- SQL/database_changelog.txt | 13 ++++++ SQL/tgstation_schema.sql | 2 +- SQL/tgstation_schema_prefixed.sql | 4 +- code/controllers/subsystem/ipintel.dm | 18 +++++++++ code/modules/admin/IsBanned.dm | 2 +- code/modules/admin/ipintel.dm | 58 ++++++++++++++++++--------- tgstation.dme | 1 + 7 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 code/controllers/subsystem/ipintel.dm diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index e142f20cfab..9835d792f6e 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,3 +1,16 @@ +16th April 2016 + +Added ipintel table, only required if ip intel is enabled in the config + +CREATE TABLE `ipintel` ( +`ip` INT UNSIGNED NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`intel` REAL NOT NULL DEFAULT '0', +PRIMARY KEY ( `ip` ) +) ENGINE = INNODB; + +--------------------------------------------------- + 21 September 2015, by Jordie0608 Modified table 'poll_question', adding columns 'createdby_ckey', 'createdby_ip' and 'for_trialmin' to bring it inline with the schema used by the tg servers. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 7fb896d93a6..72d08af90f7 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -369,7 +369,7 @@ DROP TABLE IF EXISTS `ipintel`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `ipintel` ( `ip` INT UNSIGNED NOT NULL , -`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , `intel` REAL NOT NULL DEFAULT '0', PRIMARY KEY ( `ip` ) ) ENGINE = INNODB; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index c5bbd407125..ab49b337cf3 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -364,9 +364,9 @@ DROP TABLE IF EXISTS `SS13_ipintel`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `SS13_ipintel` ( `ip` INT UNSIGNED NOT NULL , -`date` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , +`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , `intel` REAL NOT NULL DEFAULT '0', PRIMARY KEY ( `ip` ) ) ENGINE = INNODB; - +/*!40101 SET character_set_client = @saved_cs_client */; -- Dump completed on 2013-03-24 18:02:35 diff --git a/code/controllers/subsystem/ipintel.dm b/code/controllers/subsystem/ipintel.dm new file mode 100644 index 00000000000..ecfb6c928f5 --- /dev/null +++ b/code/controllers/subsystem/ipintel.dm @@ -0,0 +1,18 @@ +var/datum/subsystem/ipintel/SSipintel + +/datum/subsystem/ipintel + name = "IP Intel" + priority = -3 + var/enabled = 0 //disable at round start to avoid checking reconnects + var/throttle = 0 + var/errors = 0 + + var/list/cache = list() + +/datum/subsystem/ipintel/New() + NEW_SS_GLOBAL(SSipintel) + +/datum/subsystem/ipintel/Initialize(timeofday, zlevel) + enabled = 1 + . = ..() + diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index fb320a66c02..6b7f75a81df 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -99,7 +99,7 @@ log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . - if (config.ipintel_email) + if (config.ipintel_email && SSipintel.enabled) var/datum/ipintel/res = get_ip_intel(address) if (res.intel > config.ipintel_rating_max) if (admin) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index 58a69267a54..8b6a1566866 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -4,39 +4,61 @@ var/cache = FALSE var/cacheminutesago = 0 var/cachedate = "" + var/cacherealtime = 0 + /datum/ipintel/New() cachedate = SQLtime() + cacherealtime = world.realtime + +/datum/ipintel/proc/is_valid() + . = FALSE + if (intel < 0) + return + if (intel <= config.ipintel_rating_max) + if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10)) + return TRUE + else + if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10)) + return TRUE + /proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip . = res - if (!ip || !config.ipintel_email) + if (!ip || !config.ipintel_email || !SSipintel.enabled) return - if (!bypasscache && establish_db_connection()) - var/DBQuery/query = dbcon.NewQuery("SELECT date,intel,TIMESTAMPDIFF(MINUTE,date,NOW()) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") - query.Execute() - if (query.NextRow()) - res.cache = TRUE - res.cachedate = query.item[1] - res.intel = query.item[2] - res.cacheminutesago = query.item[3] - return + if (!bypasscache) + var/datum/ipintel/cachedintel = SSipintel.cache[ip] + if (cachedintel && cachedintel.is_valid()) + cachedintel.cache = TRUE + return cachedintel + + if (establish_db_connection()) + var/DBQuery/query = dbcon.NewQuery("SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()), UNIX_TIMESTAMP(date) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") + query.Execute() + if (query.NextRow()) + res.cache = TRUE + res.cachedate = query.item[1] + res.intel = query.item[2] + res.cacheminutesago = query.item[3] + res.cacherealtime = query.item[4]*10 + SSipintel.cache[ip] = res + return res.intel = ip_intel_query(ip) if (updatecache && res.intel >= 0 && establish_db_connection()) - //if you're wondering, we don't add or update the date as its a TIMESTAMP field, and as such, automatically updates at any insert or update - var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel)") + SSipintel.cache[ip] = res + var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NULL") query.Execute() return -var/ip_intel_throttle = 0 -var/ip_intel_errors = 0 + /proc/ip_intel_query(ip, var/retry=0) . = -1 //default if (!ip) return - if (ip_intel_throttle > world.timeofday) + if (SSipintel.throttle > world.timeofday) return var/http[] = world.Export("http://check.getipintel.net/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json") @@ -72,9 +94,9 @@ var/ip_intel_errors = 0 /proc/ipintel_handle_error(error, ip, retry) if (retry) - ip_intel_errors++ - error += " Could not check [ip]. Disabling IPINTEL for [ip_intel_errors] minute[( ip_intel_errors == 1 ? "" : "s" )]" - ip_intel_throttle = world.timeofday + (10 * 60 * ip_intel_errors) + SSipintel.errors++ + error += " Could not check [ip]. Disabling IPINTEL for [SSipintel.errors] minute[( SSipintel.errors == 1 ? "" : "s" )]" + SSipintel.throttle = world.timeofday + (10 * 60 * SSipintel.errors) else error += " Attempting retry on [ip]." log_ipintel(error) diff --git a/tgstation.dme b/tgstation.dme index b7142475ca6..301e7c4f1bd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -136,6 +136,7 @@ #include "code\controllers\subsystem\fastprocess.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\icon_smooth.dm" +#include "code\controllers\subsystem\ipintel.dm" #include "code\controllers\subsystem\jobs.dm" #include "code\controllers\subsystem\lighting.dm" #include "code\controllers\subsystem\machines.dm" From 43193e8e4c5a30f22f3aa0b210ab947dd097338d Mon Sep 17 00:00:00 2001 From: NikNakFlak Date: Fri, 17 Jun 2016 01:10:50 -0700 Subject: [PATCH 07/19] Cat ghost cat ghost does whatever a cat ghost does --- code/modules/client/preferences_toggles.dm | 2 +- icons/mob/mob.dmi | Bin 258349 -> 258466 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 965e60ddc1f..3b61fb2dedb 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -235,7 +235,7 @@ var/global/list/ghost_forms = list("ghost","ghostking","ghostian2","skeleghost", "ghost_blue","ghost_yellow","ghost_green","ghost_pink", \ "ghost_cyan","ghost_dblue","ghost_dred","ghost_dgreen", \ "ghost_dcyan","ghost_grey","ghost_dyellow","ghost_dpink", "ghost_purpleswirl","ghost_funkypurp","ghost_pinksherbert","ghost_blazeit",\ - "ghost_mellow","ghost_rainbow","ghost_camo","ghost_fire") + "ghost_mellow","ghost_rainbow","ghost_camo","ghost_fire", "catghost") /client/proc/pick_form() if(!is_content_unlocked()) alert("This setting is for accounts with BYOND premium only.") diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index d0d7817736909a9289df7c35fe89576d1ef6e1a8..16d3103afd91853b3884e752c9efa75f6e62c22b 100644 GIT binary patch delta 9797 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 P`g)5arzTq^4GH=mUjzG$ From d220416ed3fcbcdc122a31309c90e9257bd5b6a1 Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Fri, 17 Jun 2016 03:54:42 -0700 Subject: [PATCH 08/19] Makes ipintel only warn, fixes some cache things. --- code/controllers/configuration.dm | 11 +++-- code/controllers/subsystem/ipintel.dm | 5 ++- code/modules/admin/IsBanned.dm | 16 ------- code/modules/admin/ipintel.dm | 62 +++++++++++++++++++-------- code/modules/client/client_defines.dm | 1 + code/modules/client/client_procs.dm | 11 +++++ config/config.txt | 15 ++++--- 7 files changed, 73 insertions(+), 48 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index f141715dbbd..f8aec416e19 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -72,9 +72,10 @@ //IP Intel vars var/ipintel_email - var/ipintel_rating_max = 1 - var/ipintel_save_good = 3 + var/ipintel_rating_bad = 1 + var/ipintel_save_good = 12 var/ipintel_save_bad = 1 + var/ipintel_domain = "check.getipintel.net" var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt @@ -398,8 +399,10 @@ if("ipintel_email") if (value != "ch@nge.me") config.ipintel_email = value - if("ipintel_rating_max") - config.ipintel_rating_max = text2num(value) + if("ipintel_rating_bad") + config.ipintel_rating_bad = text2num(value) + if("ipintel_domain") + config.ipintel_domain = value if("ipintel_save_good") config.ipintel_save_good = text2num(value) if("ipintel_save_bad") diff --git a/code/controllers/subsystem/ipintel.dm b/code/controllers/subsystem/ipintel.dm index ecfb6c928f5..b1b99d59392 100644 --- a/code/controllers/subsystem/ipintel.dm +++ b/code/controllers/subsystem/ipintel.dm @@ -1,8 +1,9 @@ var/datum/subsystem/ipintel/SSipintel /datum/subsystem/ipintel - name = "IP Intel" - priority = -3 + name = "XKeyScore" + init_order = -10 + flags = SS_NO_FIRE var/enabled = 0 //disable at round start to avoid checking reconnects var/throttle = 0 var/errors = 0 diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 6b7f75a81df..75eaeab65fb 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -99,22 +99,6 @@ log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . - if (config.ipintel_email && SSipintel.enabled) - var/datum/ipintel/res = get_ip_intel(address) - if (res.intel > config.ipintel_rating_max) - if (admin) - log_admin("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") - message_admins("The admin [key] has been allowed to bypass an IP intel ban. [address] was rated [res.intel*100]% likely to be a bad ip.") - addclientmessage(ckey,"You have been allowed to bypass an IP intel ban. Your IP [address] was rated [res.intel*100]% likely to be a bad ip.") - else - if (!res.cache) - log_admin("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") - message_admins("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") - - . = list("reason"="IP_INTEL", "desc"="\nYour IP [address] was rated [res.intel*100]% likely to be a bad IP (spammer/proxy). The highest allowed to connect is [config.ipintel_rating_max*100]%.\nThis rating was retrieved [res.cacheminutesago] minutes ago on [res.cachedate] and refreshes in [(config.ipintel_save_bad*60)-res.cacheminutesago] minutes.") - log_access("Failed Login: [key] [computer_id] [address] - IP intel rated [res.intel*100]% likely to be a bad ip.") - return - . = ..() //default pager ban stuff if (.) //byond will not trigger isbanned() for "global" host bans, diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index 8b6a1566866..d176de32bb5 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -14,14 +14,13 @@ . = FALSE if (intel < 0) return - if (intel <= config.ipintel_rating_max) + if (intel <= config.ipintel_rating_bad) if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10)) return TRUE else if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10)) return TRUE - /proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip @@ -35,33 +34,50 @@ return cachedintel if (establish_db_connection()) - var/DBQuery/query = dbcon.NewQuery("SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()), UNIX_TIMESTAMP(date) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND ((intel <= [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_good] HOUR > NOW()) OR (intel > [config.ipintel_rating_max] AND date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()))") + var/DBQuery/query = dbcon.NewQuery({" + SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()) + FROM [format_table_name("ipintel")] + WHERE + ip = INET_ATON('[ip]') + AND (( + intel < [config.ipintel_rating_bad] + AND + date + INTERVAL [config.ipintel_save_good] HOUR > NOW() + ) OR ( + intel >= [config.ipintel_rating_bad] + AND + date + INTERVAL [config.ipintel_save_bad] HOUR > NOW() + )) + "}) query.Execute() if (query.NextRow()) res.cache = TRUE res.cachedate = query.item[1] res.intel = query.item[2] res.cacheminutesago = query.item[3] - res.cacherealtime = query.item[4]*10 + res.cacherealtime = world.realtime - (query.item[3]*10*60) SSipintel.cache[ip] = res return res.intel = ip_intel_query(ip) - if (updatecache && res.intel >= 0 && establish_db_connection()) + if (updatecache && res.intel >= 0) SSipintel.cache[ip] = res - var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NULL") - query.Execute() + if (establish_db_connection()) + var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()") + query.Execute() return -/proc/ip_intel_query(ip, var/retry=0) +/proc/ip_intel_query(ip, var/retryed=0) . = -1 //default if (!ip) return if (SSipintel.throttle > world.timeofday) return + if (!SSipintel.enabled) + return - var/http[] = world.Export("http://check.getipintel.net/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json") + var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags=f") if (http) var/status = text2num(http["STATUS"]) @@ -70,10 +86,17 @@ var/response = json_decode(file2text(http["CONTENT"])) if (response) if (response["status"] == "success") - return text2num(response["result"]) + var/intelnum = text2num(response["result"]) + if (isnum(intelnum)) + return text2num(response["result"]) + else + ipintel_handle_error("Bad intel from server: [response["result"]].", ip, retryed) + if (!retryed) + sleep(25) + return .(ip, 1) else - ipintel_handle_error("Bad response from server: [response["status"]].", ip, retry) - if (!retry) + ipintel_handle_error("Bad response from server: [response["status"]].", ip, retryed) + if (!retryed) sleep(25) return .(ip, 1) @@ -81,28 +104,29 @@ ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip, 1) return else - ipintel_handle_error("Unknown status code: [status].", ip, retry) - if (!retry) + ipintel_handle_error("Unknown status code: [status].", ip, retryed) + if (!retryed) sleep(25) return .(ip, 1) else - ipintel_handle_error("Unable to connect to API.", ip, retry) - if (!retry) + ipintel_handle_error("Unable to connect to API.", ip, retryed) + if (!retryed) sleep(25) return .(ip, 1) -/proc/ipintel_handle_error(error, ip, retry) - if (retry) +/proc/ipintel_handle_error(error, ip, retryed) + if (retryed) SSipintel.errors++ error += " Could not check [ip]. Disabling IPINTEL for [SSipintel.errors] minute[( SSipintel.errors == 1 ? "" : "s" )]" - SSipintel.throttle = world.timeofday + (10 * 60 * SSipintel.errors) + SSipintel.throttle = world.timeofday + (10 * 120 * SSipintel.errors) else error += " Attempting retry on [ip]." log_ipintel(error) /proc/log_ipintel(text) log_game("IPINTEL: [text]") + debug_admins("IPINTEL: [text]") diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 78b19cb7198..7443a4a17ed 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -45,6 +45,7 @@ // Used by html_interface module. var/hi_last_pos + var/ip_intel = "Disabled" //datum that controls the displaying and hiding of tooltips var/datum/tooltip/tooltips diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index a888c025b7e..c9fa33716bf 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -210,6 +210,8 @@ var/next_external_rsc = 0 sync_client_with_db() + check_ip_intel() + send_resources() if(!void) @@ -322,6 +324,15 @@ var/next_external_rsc = 0 var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');") query_accesslog.Execute() +/client/proc/check_ip_intel() + set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep + if (config.ipintel_email) + var/datum/ipintel/res = get_ip_intel(address) + if (res.intel >= config.ipintel_rating_bad) + message_admins("Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.") + ip_intel = res.intel + + /client/proc/add_verbs_from_config() if(config.see_own_notes) verbs += /client/proc/self_notes diff --git a/config/config.txt b/config/config.txt index f371a024b59..d04cd64cd3d 100644 --- a/config/config.txt +++ b/config/config.txt @@ -112,16 +112,17 @@ HOSTEDBY Yournamehere GUEST_BAN ### IPINTEL: -### This allows you to block likely proxies by checking ips against getipintel.net -## Maximum rating: (0.90 is good, 1 is 100% likely to be a spammer/proxy, 0.8 is 80%, etc) anything higher then this number is rejected -#IPINTEL_RATING_MAX 0.90 +### This allows you to detect likely proxies by checking ips against getipintel.net +## Rating to warn at: (0.90 is good, 1 is 100% likely to be a spammer/proxy, 0.8 is 80%, etc) anything equal to or higher then this number triggers an admin warning +#IPINTEL_RATING_BAD 0.90 ## Contact email, (required to use the service, leaving blank or default disables IPINTEL) #IPINTEL_EMAIL ch@nge.me -## How long to save good matches (ipintel rate limits to 15 per minute and 500 per day. so this shouldn't be too low, getipintel.net suggests 6 hours, time is in hours) -#IPINTEL_SAVE_GOOD 6 +## How long to save good matches (ipintel rate limits to 15 per minute and 500 per day. so this shouldn't be too low, getipintel.net suggests 6 hours, time is in hours) (Your ip will get banned if you go over 500 a day too many times) +#IPINTEL_SAVE_GOOD 12 ## How long to save bad matches (these numbers can change as ips change hands, best not to save these for too long in case somebody gets a new ip used by a spammer/proxy before.) -#IPINTEL_SAVE_BAD 1 - +#IPINTEL_SAVE_BAD 3 +## Domain name to query (leave commented out for the default, only needed if you pay getipintel.net for more querys) +#IPINTEL_DOMAIN check.getipintel.net ## Uncomment to allow web client connections #ALLOW_WEBCLIENT From e40bfc74550045684c621e0693413bfce036e44b Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Fri, 17 Jun 2016 06:58:46 -0400 Subject: [PATCH 09/19] Fixes invoking Inath-Neq permanently coloring people --- code/game/gamemodes/clock_cult/clock_scripture.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 48228105716..4f062d92311 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -1151,7 +1151,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed L.fully_heal() L.stun_absorption = TRUE L.status_flags |= GODMODE - animate(invoker, color = initial(invoker.color), time = 150, easing = EASE_IN) + animate(L, color = initial(L.color), time = 150, easing = EASE_IN) affected_servants += L sleep(150) for(var/mob/living/L in affected_servants) From f716d6d70d15248645ba4127db60406f6c8d1768 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Fri, 17 Jun 2016 10:24:41 -0400 Subject: [PATCH 10/19] Drones don't get hacked by ratvar conversion unless they're actually converted --- code/game/gamemodes/clock_cult/clock_cult.dm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 70b4d58be49..9a8fe324974 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -83,8 +83,14 @@ This file's folder contains: M << "You must not involve yourself in other affairs, but... this one... you see it all. Your world glows a brilliant yellow, and all it once it comes to you. \ Ratvar, the Clockwork Justiciar, lies derelict and forgotten in an unseen realm." var/mob/living/simple_animal/drone/D = M - D.update_drone_hack(TRUE, TRUE) - D.languages |= HUMAN + if(!is_eligible_servant(M)) + if(!silent && !M.stat) + D.visible_message("[M] whirs as it resists an outside influence!") + M << "Corrupt data purged. Resetting repair processor to factory defaults... complete." + return 0 + else + D.update_drone_hack(TRUE, TRUE) + D.languages |= HUMAN else if(!silent) M << "Your world glows a brilliant yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm." From 7c28194f6615385a04bb07f987a46aa91018c55e Mon Sep 17 00:00:00 2001 From: Jack Edge Date: Fri, 17 Jun 2016 15:40:27 +0100 Subject: [PATCH 11/19] Drones have the silicon faction by default :cl: rscdel: AI turrets no longer fire at drones. /:cl: - Also cleaned up some stuff in portable_turret.dm while I was there --- code/game/machinery/porta_turret/portable_turret.dm | 9 +-------- .../mob/living/simple_animal/friendly/drone/_drone.dm | 1 + 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 0927ef42271..8036ba00401 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -706,7 +706,6 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 power_change() //Checks power and initial settings - return /obj/machinery/turretid/initialize() //map-placed turrets autolink turrets if(control_area && istext(control_area)) @@ -779,13 +778,7 @@ return user.set_machine(src) - var/loc = src.loc - if (istype(loc, /turf)) - loc = loc:loc - if (!istype(loc, /area)) - user << text("Turret badly positioned - loc.loc is [].", loc) - return - var/area/area = loc + var/area/area = get_area(src) var/t = "" if(src.locked && (!(istype(user, /mob/living/silicon) || IsAdminGhost(user)))) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 1b41366bdf6..23d3c82da27 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -44,6 +44,7 @@ staticOverlays = list() hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD) unique_name = TRUE + faction = list("silicon") var/staticChoice = "static" var/list/staticChoices = list("static", "blank", "letter", "animal") var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable) From 6289801964cd26e6708759bb4bab8ab020e7d972 Mon Sep 17 00:00:00 2001 From: Xhuis Date: Fri, 17 Jun 2016 10:46:55 -0400 Subject: [PATCH 12/19] Hydroponics changes --- code/modules/hydroponics/grown/ambrosia.dm | 14 +++--- code/modules/hydroponics/grown/berries.dm | 44 ------------------ code/modules/hydroponics/grown/misc.dm | 38 +++++++++++++++ code/modules/hydroponics/hydroponics.dm | 40 ++++++++-------- code/modules/hydroponics/seeds.dm | 3 ++ .../chemistry/reagents/medicine_reagents.dm | 6 +-- icons/mob/head.dmi | Bin 146541 -> 148650 bytes 7 files changed, 73 insertions(+), 72 deletions(-) diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm index dc810aba585..ef576982bed 100644 --- a/code/modules/hydroponics/grown/ambrosia.dm +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -53,21 +53,23 @@ //Ambrosia Gaia /obj/item/seeds/ambrosia/gaia name = "pack of ambrosia gaia seeds" - desc = "These seeds grow into ambrosia gaia, incredibly rare but imbued with breathtaking potential." + desc = "These seeds grow into ambrosia gaia, filled with infinite potential." icon_state = "seed-ambrosia_gaia" species = "ambrosia_gaia" plantname = "Ambrosia Gaia" product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia mutatelist = list() - reagents_add = list("earthsblood" = 0.4, "nutriment" = 0.2, "vitamin" = 0.1) - rarity = 100 //These are some pretty good plants right here + reagents_add = list("earthsblood" = 0.05, "nutriment" = 0.06, "vitamin" = 0.05) + rarity = 30 //These are some pretty good plants right here oneharvest = TRUE + weed_rate = 4 + weed_chance = 100 /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia - name = "ambrosia gaia" - desc = "The bringer of light." + name = "ambrosia gaia branch" + desc = "Eating this makes you immortal." icon_state = "ambrosia_gaia" filling_color = rgb(255, 175, 0) - origin_tech = "biotech=7" + origin_tech = "biotech=6;materials=5" luminosity = 3 seed = /obj/item/seeds/ambrosia/gaia diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index d3eaac3ea7c..3ac1d6c11e8 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -136,50 +136,6 @@ filling_color = "#6495ED" bitesize_mod = 2 -//Cherry Bombs -/obj/item/seeds/cherry/bomb - name = "pack of cherry bomb pits" - desc = "They give you vibes of dread and frustration." - icon_state = "seed-cherry_bomb" - species = "cherry_bomb" - plantname = "Cherry Bomb Tree" - product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb - mutatelist = list() - reagents_add = list("nutriment" = 0.1, "sugar" = 0.1, "blackpowder" = 0.1) - rarity = 25 - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb - name = "cherry bombs" - desc = "You think you can hear the hissing of a tiny fuse." - icon_state = "cherry_bomb" - filling_color = rgb(20, 20, 20) - seed = /obj/item/seeds/cherry/bomb - bitesize_mod = 2 - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/attack_self(mob/living/user) - var/area/A = get_area(user) - user.visible_message("[user] plucks the stem from [src]!", "You pluck the stem from [src], which begins to hiss loudly!") - message_admins("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x], [user.y], [user.z]) (JMP)") - log_game("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x],[user.y],[user.z]).") - prime() - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/burn() - prime() - ..() - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime() - icon_state = "cherry_bomb_lit" - playsound(src, 'sound/effects/fuse.ogg', seed.potency, 0) - sleep(30) - if(!src) - return - var/d_strength = round(seed.potency / 100) - var/h_strength = round(seed.potency / 50) - var/l_strength = round(seed.potency / 20) - var/f_strength = l_strength - explosion(get_turf(src), d_strength, h_strength, l_strength, f_strength) - qdel(src) - // Grapes /obj/item/seeds/grape name = "pack of grape seeds" diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 34bb0d6a5d3..561723fa878 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -94,3 +94,41 @@ origin_tech = "combat=6" trash = /obj/item/weapon/gun/projectile/revolver bitesize_mod = 2 + +//Cherry Bombs +/obj/item/seeds/cherry/bomb + name = "pack of cherry bomb pits" + desc = "They give you vibes of dread and frustration." + icon_state = "seed-cherry_bomb" + species = "cherry_bomb" + plantname = "Cherry Bomb Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb + mutatelist = list() + reagents_add = list("nutriment" = 0.1, "sugar" = 0.1, "blackpowder" = 0.7) + rarity = 60 //See above + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb + name = "cherry bombs" + desc = "You think you can hear the hissing of a tiny fuse." + icon_state = "cherry_bomb" + filling_color = rgb(20, 20, 20) + seed = /obj/item/seeds/cherry/bomb + bitesize_mod = 2 + volume = 125 //Gives enough room for the black powder at max potency + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/attack_self(mob/living/user) + var/area/A = get_area(user) + user.visible_message("[user] plucks the stem from [src]!", "You pluck the stem from [src], which begins to hiss loudly!") + message_admins("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x], [user.y], [user.z]) (JMP)") + log_game("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x],[user.y],[user.z]).") + prime() + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/burn() + prime() + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime() + icon_state = "cherry_bomb_lit" + playsound(src, 'sound/effects/fuse.ogg', seed.potency, 0) + reagents.chem_temp = 1000 //Sets off the black powder + reagents.handle_reactions() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index ef3645353b8..f3ede6629ea 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -80,7 +80,7 @@ if(istype(I, /obj/item/weapon/crowbar)) if(using_irrigation) - user << "Unscrew the hoses first!" + user << "Disconnect the hoses first!" else if(default_deconstruction_crowbar(I, 1)) return else @@ -168,10 +168,12 @@ if(waterlevel <= 0) adjustHealth(-rand(0,2) / rating) - // Sufficient water level and nutrient level = plant healthy + // Sufficient water level and nutrient level = plant healthy but also spawns weeds else if(waterlevel > 10 && nutrilevel > 0) adjustHealth(rand(1,2) / rating) - if(prob(5)) //5 percent chance the weed population will increase + if(myseed && prob(myseed.weed_chance)) + adjustWeeds(myseed.weed_rate) + else if(prob(5)) //5 percent chance the weed population will increase adjustWeeds(1 / rating) //Toxins///////////////////////////////////////////////////////////////// @@ -316,9 +318,9 @@ if(myseed) user << "It has [myseed.plantname] planted." if (dead) - user << "It's dead." + user << "It's dead!" else if (harvest) - user << "It's ready to harvest." + user << "It's ready to harvest." else if (health <= (myseed.endurance / 2)) user << "It looks unhealthy." else @@ -328,7 +330,7 @@ user << "Water: [waterlevel]/[maxwater]" user << "Nutrient: [nutrilevel]/[maxnutri]" else - user << "It doesn't require any maintenance." + user << "It doesn't require any water or nutrients." if(weedlevel >= 5) user << "[src] is filled with weeds!" @@ -345,7 +347,7 @@ qdel(myseed) myseed = null else - oldPlantName = "Empty tray" + oldPlantName = "empty tray" switch(rand(1,18)) // randomly pick predominative weed if(16 to 18) myseed = new /obj/item/seeds/reishi(src) @@ -370,7 +372,7 @@ weedlevel = 0 // Reset pestlevel = 0 // Reset update_icon() - visible_message("[oldPlantName] overtaken by [myseed.plantname].") + visible_message("The [oldPlantName] is overtaken by some [myseed.plantname]!") /obj/machinery/hydroponics/proc/mutate(lifemut = 2, endmut = 5, productmut = 1, yieldmut = 2, potmut = 25) // Mutates the current seed @@ -404,7 +406,7 @@ sleep(5) // Wait a while update_icon() - visible_message("[oldPlantName] suddenly mutated into [myseed.plantname]!") + visible_message("[oldPlantName] suddenly mutates into [myseed.plantname]!") /obj/machinery/hydroponics/proc/mutateweed() // If the weeds gets the mutagent instead. Mind you, this pretty much destroys the old plant @@ -424,9 +426,9 @@ sleep(5) // Wait a while update_icon() - visible_message("The mutated weeds in [src] spawned a [myseed.plantname]!") + visible_message("The mutated weeds in [src] spawn some [myseed.plantname]!") else - usr << "The few weeds in [src] seem to react, but only for a moment..." + usr << "The few weeds in [src] seem to react, but only for a moment..." /obj/machinery/hydroponics/proc/plantdies() // OH NOES!!!!! I put this all in one function to make things easier @@ -440,12 +442,12 @@ /obj/machinery/hydroponics/proc/mutatepest() if(pestlevel > 5) - visible_message("The pests seem to behave oddly...") + visible_message("The pests seem to behave oddly...") for(var/i=0, i<3, i++) var/obj/effect/spider/spiderling/S = new(src.loc) S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter else - usr << "The pests seem to behave oddly, but quickly settle down..." + usr << "The pests seem to behave oddly, but quickly settle down..." /obj/machinery/hydroponics/proc/applyChemicals(datum/reagents/S) if(myseed) @@ -463,13 +465,13 @@ if(41 to 65) mutate() if(21 to 41) - usr << "The plants don't seem to react..." + usr << "The plants don't seem to react..." if(11 to 20) mutateweed() if(1 to 10) mutatepest() else - usr << "Nothing happens..." + usr << "Nothing happens..." // 2 or 1 units is enough to change the yield and other stats.// Can change the yield and other stats, but requires more than mutagen else if(S.has_reagent("mutagen", 2) || S.has_reagent("radium", 5) || S.has_reagent("uranium", 5)) @@ -667,7 +669,7 @@ if(1 to 32) mutatepest() else - usr << "Nothing happens..." + usr << "Nothing happens..." /obj/machinery/hydroponics/attackby(obj/item/O, mob/user, params) //Called when mob user "attacks" it with object O @@ -803,7 +805,7 @@ else if(istype(O, /obj/item/weapon/wrench) && unwrenchable) if(using_irrigation) - user << "Unscrew the hoses first!" + user << "Disconnect the hoses first!" return if(!anchored && !isinspace()) @@ -848,7 +850,7 @@ if(myseed) //Could be that they're just using it as a de-weeder qdel(myseed) myseed = null - weedlevel = 0 //Side-effect of cleaning up those nasty weeds + weedlevel = 0 //Has a side effect of cleaning up those nasty weeds update_icon() else @@ -929,7 +931,7 @@ return // Has no lights /obj/machinery/hydroponics/soil/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/weapon/shovel) && !istype(O, /obj/item/weapon/shovel/spade)) + if(istype(O, /obj/item/weapon/shovel) && !istype(O, /obj/item/weapon/shovel/spade)) //Doesn't include spades because of uprooting plants user << "You clear up [src]!" qdel(src) else diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index aa7f785b152..e85418941d0 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -37,6 +37,9 @@ var/innate_yieldmod = 1 //modifier for yield, seperate to the one in Hydro trays, as that one is SPECIFICALLY for nutriment/chems (which means it's constantly reset) //This is added onto the yield mod of the hydro tray, yield *= (parent.yieldmod+innate_yieldmod) + var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth + var/weed_chance = 5 //Percentage chance per tray update to grow weeds + /obj/item/seeds/New(loc, nogenes = 0) ..() pixel_x = rand(-8, 8) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 7d5fe115568..46bc5472217 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1003,7 +1003,7 @@ datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/M) ..() . = 1 -/datum/reagent/medicine/earthsblood +/datum/reagent/medicine/earthsblood //Created by ambrosia gaia plants name = "Earthsblood" id = "earthsblood" description = "Ichor from an extremely powerful plant. Great for restoring wounds, but it's a little heavy on the brain." @@ -1015,11 +1015,11 @@ datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/M) M.adjustFireLoss(-3 * REM, 0) M.adjustOxyLoss(-15 * REM, 0) M.adjustToxLoss(-3 * REM, 0) - M.adjustBrainLoss(0.5 * REM) //This does, after all, come from ambrosia + M.adjustBrainLoss(2 * REM) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) M.adjustStaminaLoss(-30 * REM, 0) M.jitteriness = min(max(0, M.jitteriness + 3), 30) - M.druggy = min(max(0, M.druggy + 3), 15) //See above + M.druggy = min(max(0, M.druggy + 10), 15) //See above ..() . = 1 diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 3d7dd56ecec32c991d2d85e554b4aabddd2a0208..35204a7ea8f8343f292701a1aae8932c79d7ffa3 100644 GIT binary patch delta 50156 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

f6aG$fMCOme5< zM~>5)3_Xu>-xo!R#$u+2AN;1R=@JZ4HczRQaQw4^^3*C@%0fKr7<0Cj%v$>|~b1=re=IHhQ?We6+6V+(Y-4W&QkwP^_c zE_pt3Yh{^eq`eky3RGY1m=xjK|9-Ui$vk6+(3?-0s;sy87KFIA(Y+>wGUDa!{X0#) zGf%FZs^ZcE7g>8R4f9l8w|jq29%q8I`^wmMNz5C4qMTmhlYUr5;(>mA8niaX1`w?4 z4@w6R9lyCwJQzYy(AR`F)D6%j<_0LY z@6y`Z{eqM&8?Fa#7GE;y%Qtyx0ZgbkmmEy(asE##jIXWlJljA4?XFEF-PjjBqM;H9 zT-Jo()3@K~TVCbENi2(3<002rx{k=T$J!y+krFOF>f*^01U4RBUOGK^q5srR6Q7m( zJA)L&X54aHTn$GwA(F=dO2@K*8n)gfa9zV>f5{ei!>;!x4V0_{1%gSReYc{LWY#NS zwiB_^+82HU6{p?}#9?IBND=;@i2SOp)zhSdjZI{+QxNL|L0o3V^aKwm4&9l$(RGzN zZvXn5Djs791!KPzWnSt2eo!?{IU}!{wF~9ZYtu&o0L_mkWh=~@M7Ja0AVvGanNM%u zko%L49%`_x<%JK)(D{x!P4|xo8xEGgh*~{U1%PoJ>0OhbKUZtE7dn!J%OsH;6|a

>y`biNY7M9YBY&@XZpDw)%3pk4~XcX~;4_1A89*x%Ts2&ef526Ab8nQd_(IE8Er8 zVn~KuL|0b_ewYw}Q@Z!5`TYq4n0(Jud_xsd&;0^~@y%O2k~okvcDaAF!@tc0^R42r zpF@|0JMYu0*&%6?)P0;gO$CSv_fWv2FTz8R4yzBzeP5?&<{vb_?qGwwTi?I)PcXru z$n|W8V))0zVOABYqM1dk)dcNAdw|g7Vge(Kx9+WYwWhl8dT|+fesniLqxr!|jh@a5 zU_8wOg9MyyY)C563a3a_9NCKFp4PjeaV}BEB`kQ|_w1t>q0T(_i-kK;I@KfaD4wmW z8Eyd`?jMo|-i%MvAVM;PYRd!Dh%B;xhHfy^4NuQ!t)TaAiUF>A0UXjMhWog(A-v z3TEZ48YF&S9L6eQ>`$iYl`@Gz; zeA~?6VgfnHG}SqRg(8lr9A^*hQ68Dp+?VP@f5}6ud(t}Il5h}C4*2>?J~XQlp7x6O zyCSvMhYTslTj@2GcQMjYR`^_F)uOW`5Z6b}6sX@1#*fWeAhtVOI(anJiDM$L-Q zZ&eZ#e+u@WGSr1mwE4yF+?$Tm1+KII5}_}A(hI)2&;E*P?w`t>=Wy8uBhD=1n2Z7T z&{dH^23kOS?g~VM{B^Bt3Far&gwlrk3(q4P%e0)NbybFvg2A%JTmqSJxi73=FXkmKSXHsI_f|!d=PwX<^P2%DTOI z{f>a*>>BqPSo9BlJmQGp(__p_YXMS_w#ppv<_21$g-jLci798>pp(Cw2mI4MMJxT6 z%5GJE6JTbo)i~K%Ia2LnWfOhvU)^XYf|K7)cPQQuS8J-PgS5>Gi;BY^E}z2RFcJvz z;D&;rKcc7^c3npPtj|v#ISyz5Z!B&9{Lu}Zb>$fTHIEqVDDQCXvBrc90VJ}T zRK4H4d>m#gC1gK&>+qPig=!Hp$q;v?G;7$X@6kM4$fBo!F*k;8m3$92w#V_3iq$fA zRrbrosAy9)h%kQCG<7k-YwAqX0n7>{8?I*Kn4~cHP(6`7a}ZcDV@IyYI4MR#!+3V% zWu)(A`#{{SQJQW^R%82%{0+av%H2{7$0r{N_eUt~`eYM7l8jVOEzq3R~cyAZ~e0xfdeV+IGxO5lxl+(V|O}bmY z%FL!mP+h^^>nlc&J>H?Gul7h^v}b^NJ-6Wlaiu36YXm_#|0>kir@5!0{ebq{2^Z>) zWyXSOsBr^RXbo3)?$8dJgze$@nq^QiTdyY2Vvm!4_P4th`){v;5hIItm$05ypnyHx zeIbc6nPp%Z293uHh&d6)A5-hKUE=YJ=mIjdiZ$5`;tl%J_cN3A7TLW8UpB*b*Z+7J$B~du|yFTjho-=Cmcbj(;Y;+L97F~ zP(JPfN=r%QBlrt`%fsf^+oLv<`;BaGan+Zg|zQ_sui*)yctstfbS{nrg z?ZjEND^m3@&>_x5@39XSfcXA_<(Dp`g#US=7IJWaF1;nBb{nAM*`T*Iop(Rn!_o~? z5;$=wrk%Cv>RatwJP=P8wW1x;sd-QJ$4E8RRe1Fub3QxB-GkacAk_hU>&xI?O zIKW!ksBM)P(rk9jbpiMm9B?FHk;0rJ-ORA@D-TX~WCuVhYT70!J|!tMMXRF>;eMrm za_I07)QXnBV zs}XGx?hyv^|*aku4;JdQtoCw(03z6Gtsm1>2k0pr! z)}F?cScVZ?6+L2kt$01lcGDiV5_stH) z_5_%i$NMB4+eHgx4yM-}*SUoCR$VW-cH1@0U3Kj#t>{T=fl7bTSLem)uBujRh!M{4 z@t0qnEfMIaQtm5Z%3lZ5%h^9vRq)lCl$tno(YE;lVjUHTk&r`+gN(cOiyJ(do!Y<#{M$^HK=i z-wU=QQs}))`uJs#gdb$+Tk00Z8ABc8wkmMnY~D8=IPpnEE1z%0^XD-f09sQ?teM7z zKD)mDgZ{Oo4X(Z=H-!olsC+&VTz^gkxAO=KJ*BlRZPq+KU9xmYhAjC6BDR}M&%^Z) zsS%PhpCQsIc)znRS`n!=nf~?TZR2jW`eI~hMq1ILHspV!1V35Wl1VoX?$rqZUFgA zK0?iZ{RwWt#Lt+f6i3l)BP%iMziEWSj)3#?Wpl^tOVF?Mkm-RqPFToPhMFzI{cyxZ z3`dU$<06~Y*2miJl8toYuORfC{AWVV&kH^`6L&^|&G9*{`p(Pr*yI0tFF4BP!w4fk z_i?WrY=S34>vnR7ZcqLGZG6~NjxLQU`HmIQkg{}kn_Xsc?yh($w0K{=v*Rm9o7z4f<6b|aVIsl2odwDc+C+S;~?=l69fBDmqsj+s&`uj0a1kJPC{<7mBCaJ8xSmRr=(x(jz>V@J z9ox#E>J*O`tvv^J%R}$k1OsQCxj*;uIM~b#>yL(~Ac@0&*uM|P?uPA}HsS#uuKsz= z4oDVMgT%qc5g_baX%CA0ph6eemR+A$uG1b}G|rk&r}oD~6C{=VU{g;$6Uzn}JSunx zRk^dq0nuHEQ+ZYisVm*@K+2Yhaw_8vB5x||FdqdcM40tT$N&1O)+ zX?p6y&!X40>{Wb*!SsON=`oGzAu!+y@h2i-8T4oW^_YSYrGGE*LHFlBObfOPrVFU1 zFoH4^S=|nlbfDaI{~*{f!7ewk?kmThI!*Jru>{o`SH(4Ao>z=-zncrid_j)_f1cIz zHj?E4u2uWbzD+ai!!vP-$E*0}z9tu1&)Yr@+k4MEWLs{D4&zQ!_ie^D*Rt(M`hi$= zF`obs`)_^g=uX!+7=_Aku&Zh6=WdhL)Y%8hgDc*4xY3m0p2FLIcW5pBB4>UiR}-cP zsBE0xp`R&z_oq{khFvo`My=|Zugu78>`Z1j{+1?Op~|w3D1s-MO+1`W8U01+YiV3R zq@xEVf=g;>v9CDjNnua%ro4*}@0K&Z|R9Y#YZ|$|YpX;X2 zqZ^DCADN#ZibZ{(?;m3jCw4X>frAJA>%t2xs*t-D5H9k?2Z;tu-cZ7~*Vz<6mPEU> z;IDZ813BWEFWICSKE|8XHPmhdmG=hdG@qDI(gr%`AEZYN@CC%}Tb$;ZI=Ke2)F-`P z+1!x+YUEZ7p<`0zYqXgx`O7F@5S)8`A1dTd=RDW0MAH`NSH7mcc2actWO*5r$|J>h z2~q`DxR!lsj)33%a?;^nhbf?q7*i3_BY%nH<_L|6)eNoc3vXB+e**<{-}~!N$E8g* zMzpt_le7{!ElO=#i!da>p?@u}1lY`s(m4grTbOM<*-CY9p9BgEI$O|z#Tz+xw)gE^ z&+q(hSO?6AyWNeW7R&8JVOr;enIxS(zeyv>yQXpgtCYTZ*ndP-6?0bq*&^XjFcob_ z=3nsa|D)J|z3=~f$N!`1|El~y*KSc0MT;ywb#(#JZN>}~+I`p>D?nCrm1e~{&3Zjp zNq#OXWG{8#Ck6T_VwRry?MEvPBP)3~0bKFOCg+XW*tt$*MvBUf7B8fsAgFba(CPXp zhHy${yLchN=SY=JkeOW&>_*k15(DfEuE5EQ04ddiBDcrt&VPk*;l`iip3peCL-yd6 zaNs$s1lW2Y9QudAFbf0Rhae>J2!tbU$C~Vn2)(Ae9uHW(A8Ch5jPo-G7g-Lz7vpkxZmC17w>irR5tnxWO&($0% zZvoaCWphxI8=hAi3{}{xEWxM=zry^Ljgia-c+v`%UF^g&CP72cpA#^ilUtb5Mf*Cf5g@zUSBB?VQq z{*LTVoViG4klCVhL#XRb|Da=3K}RGemj-R%V|9GO=Vb!koGj-dYwqx_jG@BZ=5<^9&_OjPd2T%%fc8~f854~1tILyn zN?6%%9M$1%Vu-Ec5&>cnZ5XfEKSX%xo+VsIIf`wy*ASjb7mqv()`w&TyB6H|r-! zV**mwcW0Y&>ZsaZKxb*p0aYOINc)=TsX8trtlP?LH!Xd3?Itjb{FDqfD^io)*Q652 zwmPcxIHcnKHx~|O=dQQ8bVbU>D;``Z9pRl@*WwA<C&*Tu!2VkYsd#MbZu#@s+X+OzFeaoaJ#8SG2-s%`usYthxV|~ zunHX=BZ{yxm8t_3=^`MvmDPwXb)eQ}st%l>zsLErTa5sHd{U~X%l%jlBZX`54X7}uMCz$o28-8TQCvUAH*`l^Jp!4u?OHoB6f6X@mjeL{tw+V=B}jr~(?sp0Sub8u$bMgqI%>Nv^4W zu$t$N2AOVfkQnth+V~RQ9Rt1|O?Ga)K37y^a?f8lBvBBw?}kBceM#&?uim76#L2sk z!4}VZdel13rtNcWI{9d%O;{R|Vxz@djs%afTOL}|TAEUO81EnS&WLmm*%{q-%5Z3C z=tVM+es{3vxveHfm{ zz*P<9^BS9l61QIUO?FFa2gsvjR;b|2Ol^w!`z-8B$-;QUteYYL)@+QFJ%Qp!dp4F5 zPOP8{3;n66TjPw>PDH24!wZA%?5T&&RwPVq4{O~~bUpLYck_&auKBBeTe#!4jYifd z`q&+aRh5Q-sj{prKdjiNTQoB(tI^2d#j|i_edr07>k)V9r(_&mN{adUKR+40d+7N1 zK1d|)-n;h=Dh#ay>6Et}++&?on8WL}8$n7Bc{1=@K!_n@8Dto2Ld?6~#z<3udOZVU zap(o6BO|TVklu5d{P0{}srmDH%pH3_7$i@C_~Zg_RHu2rQ28;a+^M|$%t5(0aIVmC z_@1S0IAX5NuD4BIQdzjA;=pol(S=6%*6c-DSvquijxr-T^84Fz6cXx+;}fb~UmNk) z>Jut&ajz(yc^JaUW=kr!=%9L+=9SVlyX4;tunc;!wq!A*+D+`Me)r<4k&eMKX-RZjlhD} z%h@1f4ED`6+fd0i;c^I=n^%2p1KHBdu^F7O?bu~Yn~(d#w@Y^_EEPpbcFFI^D`VyA z*v11cie7TU_1!QstiA%c=WwC2`1s5%_mFqhU85C_spcOQ1B`CEIt0ZT-uDRh5DE!| z;g2U#GU?vGX1=t%7mN2TPTB74s^4%cD35_`@cPSiNC;lbT{`t(ify0v=(O&vTR7rX z8ywhbO9bAXsQ$3;xK7};&!;u_jTZVc$x2SbU;|ea8%ex-Iu{@)UEbLD@-qatNV`s- z?&utvWPm-KZMWiMJpI}V4nto#!d*`noPDDs-4cKG<&E37Wyu-{m0Qn~=2YWO-J+$X zrba{Di{@R>F;@s#J_!ctD7X(YGY9T+FroulawpVz?-;NPhxD1lweHLb<(7ALu+h(^ zp0j!AAPQ(^cd5dbD8C8?cdTE)PnQSRCqe5R$&Hg0$TXL9zY|*--39YMW-FD- zgbzQ)aY7PUgr*)?9xG>p$?R_G#G86q+!Tgo7*E>F?hO1m2!o|;FV)wdKN|YB&Ess4 zz~?}vPsZkA(4rS;8X2*(V-ftr@8k5$N^VgDN_g3;6=>Fw_?dk$-secN;i;a3YTf6L zejOb0s_o!W%T8mGWk20*`-f8o<`)g&0B!7NO5-WfAz^Xe+sUt@{)a zE~Y94u|l%P0!uAVe{+wC(twkGqmz;jR***l%@l(v5^8k=iG4(6DEqmAbofD1M%_&K z_3L3Yq)YX#>>jfEK)JG~Wr@&^Po}iSahJ~B;2TKx6IhrGmRpzo5P8v>?0BJM@l%{C zXOoe^a1P?(H%Mm;)xdbD9&a`n0@vduc|{JrsH)+N4!b(y3JaO!gJPQ?ouKUm_$)1l z9UL@V7#Lx@I-%YJnM(MfqN^+VZK|&qA@W@yQ#8EzHDk3eT45&TOuY?Kn|os|W3V5R z(e01A_00S4=PR5ktf=CG9(Lc}@9s5rkFp zDDO=n`wBrh8Ntmhojt7V+jcsWJ2s~^PTG>wf-vtC_e_YjSh2p-1={WkoT&Bj zuy(AUh&%OYdBuO?qE6xO#v)h8`Tb@OyU~i+ErB_E=ZH5B7=?aH)9&YYdCL=}TBZPr zY1rB=kWs_q1x+0=@|JrR#;ETic{Q*LNQlAslUdCp%yM|5TMv@~ffmrYX%Pc}+hJ!hY^}(e+ch^OkLq6vk5+U&c9UMek zzrQ&CMekuBCBQO^K*8+NtO;}^(lcoTO9Twpz}qXJfD*lvJERr&Ix}s}yy9Unf34LY z085amN4}Pcdv4&!ze6>()SnW#jT>(aH&eHxbms+tVP5tC(j{lU%cjuxh_c+ZiJz~2 zq6l7S%RsF%{p|~7C1mD6WuGTiR$nzsVGrTd`(;&ol#GX6@cqueH?Ix@ zM$e>De#5DXsD?n^jFJjZ5NY~4??lY)!_Y8j_^!W+V1vF$MT1`6gNH{5owG<(TiynW zL9OLxEO5~EZ72oN2AQ$GAnFRelYUsHo-SoDU;TY!R}?Ilqu1U$R3v&okgH~79`D3^ z(LcM)ZR%o*%D!tnsn^th2jQ{1E&$apyJu{@3BfiHiP+q~3_sHtd$g_kZ8qJ^RDZV` zJ&B51`*KXVB0U{jDCxbdEKw(I5d=-T&~|IW!-&35!4Dl-(5Im-=7cMyGE)=|OeqNJ zdE-2(D`s1yHQ)Qff%D<=Lg3G2#Vxkr_@1+EKpWH8ub?gCdsb%;c3~~<0=-0ykXf)X zj|y8Y+6MQn4vc7-0nLz!2PuW~2x@-ohEMZ`+k^tWaLmnzdVMR&t{wZrdaF`PD$2Pf z>$Y-40@80}Q}#iBRvKfJb3*xaMf~GNES7j_OUc?A*Zr6ipLJmTpICy$A^%o%u;3Aa zGpw!GIV7zpu7LPNxRte+Wh{U{3Q)gv{3gx9?FzlAQhqDo=~8=YmHTvK#2&m*Nv#lQ z7hX5F{)n@mU~`XhqL9g|{zVjvD*@Ax{*0LI{;Swt`F1zYs*HQ}f2SC{SU_n__{<;p z11UfmS||QJD+~A^$>RDykI(}CJ4s^yo9YK#9*o@W{eU;0VD<5(X=rSZ4Xi!@Z6K#? zHm>^vf38{k<$08;wU=^1fy!L<1xA>X*HZZ7iRw=}N#}u{HOxAdvv2IaS5S$hqR|7F zu+Ry{1fnwD+&umCbsfGl5-laJ-AiO6RKw5FnI|un$|uCnNA^^x`w2s+f|v04G{HCl zc~CX@nA8}AGw{H^^8c2|h)O@Y1^csvh}OZbp?$oXJZkp0QeGulo5R#x*$+V$ z)81@o73|7jKn%-Ar(bYAyJuVP!2riY1eKnihD|MA=$-*-)Qi>LE3XO)&e<`ky`$p_XJ`eX;kzLF4+lBLuP62O^_?ggbb^Du{gN~D@>Sr@Sd?!b zCxz{%?b|&A5AvvTzCDI~^gWmECi@pQG5>WNw4pvugbq3Ij|#99b$jKG>F#PS2xLh? zWu4&+9X|tOTo%7`=T3Yd?9r%gzs0I7QdgB-YR5d+m3LA8Romemuias1B>H6e&g+6> zGtdsvQ0FfUK?@grCjnJKl${sLN6!>;6)mNV*%$`Z@fZxUO_gw!;PG=j5#Lp0Cn|CI zv@2Avx79o_BP_JM!4&be2c|6WbBUaZVU7Jz$5yb}f=obcnYW20MsX$H5@+e0{|Ew2 zQu?{~01DY5qh3}B`N=*is!S&^^qhD}Yo3JGQ+WT32bKgJ-)@>LW9p+=A=eJUrr(4I zI}o#uK9W>9)Gv16;KA34iO+QokQrdxJE!-B-kOfH!lCk|bq(1wzkW@t>)~B^rpHjq z&o3b>JIH=?Pbwg{Nq~G=pc8VWPJImIfC)|Hl{{`b3AxLVcP;dMzjpJUYqLjN*Pzye zurEMGVNQ=Y?;E=gFWcr4L0l86pV(TxC|_6(y32-S)6YMAE@N9Hd~9ZR_UOqk?(P{Ru+Ss^C>x)_upo4# zAQPRQ4v$SbG`mi(<6WtZ-f3=b7L%0J@u%&oi?8Y$7!ki{{_XSv{IvbK2PBY}HD~lUfL8g4miq+r5#b zFI*fcjkXM8sAs>wEz^j~M^XiE3Wcxzuh!lJs;Q^z7fwKmbVTVzu#13H=^as25TtkM z(t8glNbf~d1nEeV-g}TP9Vwv~X-eo2N+8L1c>d4(KI{9|x7K^_x;JYjr)1`onLT@E z@7eSF-8cD6eddXFaC>fssPc1>#dwU`DtFxaNE22!~pb8N91NxZ6ZZyjqBnM4(^b<6!h%k?!*u`W%8kK}$n zcujrho!J{b0!SukJN?UP^|vC95q51{D!0oTdf9`6mOu_-w!}L}oh20G)FELPd<0ql zsACL;e4U0=vpE7=^IpJWS1as1cSwE|h02Qh^7%7^y-4bj-oNS`I$ zb34$-KSQVwoLeQ)Vv^TZS8ww1QCAXVUh0cBb|IUT&>#|O=4A!%XE$BRUO=W4Xqocm zzo1ZZ%DW3KP>7zMUia|BO%4f93dl%_!ILCH}e=BjG2tv!PO+{-9HSQ!JAD7;LIbc?$I{%QL) z<05mcu&R9qKlhWe7_@Jy1v>C7<;}*el@v{FBqH9kw`g~##PJX|Pe6 z0M8^OT`p2TT#sg#V*ajE_DO*Jsa;M)Z|}3icWSR_f2l(49QC>QA-@1tDc|Z*2344= zTp9ko739(jWR{dUANl0<8xGk^gVs9{^i**Q21lqpyAHYs{NIr)gLQXI1-Z#$avVt` z8*zkz?5+K9h8zdAyx?uQu0VW;OBfKI_(O+1ddzgG*3%!OyWLYsq*3lG*g`vq%z1arW|5tIerAHdkw&;eq4V{ zd4L$gDq|d|^F;bq&8I35IVUEP(IqIo*vw^dI z1XAL1KObclKg=w7@)!`EGCmx|iyxC@b6SMRK2ctLw6p0|r;vdN=tABXg|4#K)V=y7 z=C+=xmH|?*wRD706PEcJW7lgHtYBWHJWZF*R7VL>9Ow*2Y)pW=lCBqNR_Wmq5JTdd zw6e_bdH69?E*QgjGuS5e%NL)gPReFx+5G4Cd3Xj-#U26=Rr<#ThWp3@yW=?GEc-tR zkE0j@2MDLBU|cA|KhtHVM_#GJIxHx3?Reex`#zKLI{2M?_sm!Kvb=x)%)fLUSAhDp z8UG`U;ZT#I%O_7AtaSQc-10wl%u?(~?p-0nj+cR!HWl(pq7pUi=*wT5OBTN)85Q5ka5_u?>Z!&Sy~i{w1!UGi_Cc-jX*>j4gE#K?*?^_e`=k%FRQ() z*$*DVW71@{AO(SUh8VC-qP7{Oe1+@*5rcjP&t=)a(93FrNR+$vWw>M>!4n%BdAizU zcr(Hf4jHk4p)|GA7PK3!{idnJOJVTGk7JK@T)ad6V8t-Gs^~GvWDAIaok{o@(KNC3gsm#vnpwDrZbD4@mx{JHgom6$erq;ER491YQt8J0jg* ztETikm=^a(E?kkoCV5*!TRXJ6I<&u3bRaaroAyt2wa_0VbYG3hz65leN?xy4HCKAR4W(;!*QTH7Fr`R|nuDreK7B{bCLk4W$hO0m?l+MY^NeZ?#B6R(vHu zywRr~9>S_=;@@%u6cvMA7SDWTeX%7U=(;jPc%IOy1Auf(z#E3;PvE*hCeb)t-Tnj9 zGLwDb*1kkP=E;jJnxLTVz@GYrHXS|6I*czEU&0<0=6$5mlM-i0HrMzR_s(>E4AJ@$ zGeeqng!6_`?``r%A#Q|#V}HpgVwbf7InnZ4gy5*_J~wv|h#xE96-uxK5|Hp$HOCYN04<{agHCu?%B8 zM#yOWu$`lYveHf{>`Yt|^C&mTi9=BSCZIR49QWN0`m@&kuZE!xkn%yyU$@5g1_q7F z&%=2jIVB`mK*MFK!R>NUb<%_h_+M$$jyU8M0{4jm_?qD~QKa>%_Qf%3xTtbi^zYc2 zT{SvAR4(f~-$Mz1FOwU7-5ic>!05I#gORjem zfbUs5jDIshgR{^QtG!&gRM16ggRn6mfMaYmG9=)1it&py|=>LmUe_ z&)AX)%RxSBh^(wE0N+1tZd&*tPH2PqCBt-rezSaVa1iZLNmyC85YX?9wH^lbe)T)^ z441P#6ZTK7l+Ea419`;G;B=MsrMkWquC8T*pDse~7S%>#;<{$>`q6O&0-MqTtwfJz z?6^Kn;3;ii3BDe{Ry?A6Mtc5iQ>PMTf^X$<%2ubdF#=$!;Ck%IJ?cFM5Hr0STUjaa zuF80>rd66yrEC|(wI7InIb9W3jbB`t4^z@w2hrj(p#HyqLKQV!t}Buey;P|(swu73 z=how?5%|9ScCflpWOlnr4+a?M&8BSE{Tg`neXw${lE-aU#N)*v`y$R2tnwGUHN4u#SrP_N>|bs)aVNkxtY5y>VGV4BC-GfLHrXr-nm7>Ot=2eDlTUm{>2C9tITmg#gt*^Y~=`%=*n~ zGC?vAGOvaQ=6k+t8uBzv*JoYKX)Qz5JP(4yCnp*G`8i716@o-S;)#t?qox!DB|S3v zIy3*=Ls0f*jeNY2wT=-dq0AtM8#ST978sp`^rwKy^o}NUIB%C`V+(#~+ zBEa_uWS#8Pjm_cDV!xA`%18h@Fa!=WG8TVpt!$B4rylRB79dYf7%#9F3N5XOo~7Ll zj!iUHiWrc=zb@PD=dVT(_A)-Up?UD&K|WO?JMU}w{sC&;z0;cWwHr<14uH{6kW*11 zE7s;NDk^$ieB+7SO$ufq$Saz=UuUdH0Syfe@FaQM&6lwZ1oAc`o?fea?88ji4Tgu! z;vYVI7-faL8(F%tB)PKji>iAs-{7}8^0@I}=Z~B8V>8jFW9W@STAL>%2@wn1O`S22;y?vt8LD|aK4g+34fSj`y_W?QV>R`a{8~FEdcNfF+ zH3zl0{HBd~EjNnozO0K2KUicmAmcg6LHWqI(q`hQ$x8ALVi*K>;v{7vh6K3{0ptC3 zdSLn|+cZRgz!eSUpx&Q9<&2Hli76)zzpxpQMT4=Tx`rFb5Y2r{I$Pw$@1T1*oXrJ97h%6qocuxAiXVN)E?*VxtLd! z$V3X<~zb-rjI|b9pIG2hlCEK)CpgZ}Ue( zy);1}_e-etaaY|jOqMwKiq_+s^2!zSn>Y)Wv(n^^o<`c|9-!HdbDACVWBGiW8S2@S8yMZ@c}j)sqPk zNOAp-e7BJ-)h}{lf4Rg(nBfcP#I&>+0OWHppDKU*>=he4hUJMg*-c7cn*>M6kiRdz zgJs^OGqp7L9n{A%MZ)4NQO*1Csa06aAvH=ynvGjE@ z{mkah#dE^P=)(MTePQ1t8?Y^rw)mZN$MO(OReWm`z57kZzez;sW~oyWvS%o*26*^_ z5YBz^z>Zf-o4ii;Ps;P3eaL`~A^l4gz{I3pS}{JsrmR;Y&HfQO1?nOpJ!NUIX1m+e zY42nImOrpF-SUlJO?6)Dg5JI}+dQeJQu{^2L>liHag{VGwsUd4vW-=qoq>=br20=1igsl4^`?DU!?iVui$*a|r4M4za^ zrW4$!BUzG45R$bO=Re;lZ)7U4$qLv*;J<&HU1wk*gj|k$F3r@>hKWI7U8ypOxvst` zVOx2r_vjO--X5H;AMP5VV^ZquUNb?2Gmh_U$i*rhu+kkZkQbs7!`nZf6S3V;5C?Qp&p^%iH>PUEX?i-FU2oMMZWoAfxYFY=7H;_>8&56 zs6^#U*D@4QvD$k`Ywj0cW=V+8%plg*@nVg2tzna$zeX3IILXl=cuoL@Vnk*5hgfWc z?b``5N~lG**6g|s2I*aHV7xu%PoGdAW!#Y_p#Yx*NHGMz)&T2?Wvi77B8Eb2GkGBi zXz0>Zg?Z_AMMXvFHYkE`bacWJ6R$yf2_dP2pWe9I+WPldRb}Po-lm2GTivh!l zzvcs}PpB9DKZGURQf@_!(QanN0+S;n5Ls1Ks=KdJg1>%cg*ZE?J%65n>{K`V zmHT`L{mTI|x6!#|-@#F5{*tMY1@R~?%p^dJy2@H+hirLOH>GF&kOBYkdw#F!y>SwpSeqoTFhZO3IbGmS*e?E8=aFn>SQ;FVeta*+{t`|h2F_ZdG? z)*)M%ez7lfPmInm!x5=F+GB5&k(n?ySpsmi>LZBM-iY?6KP8XFAY1U-Yr1;}y2U04 z_FKxabClS|Cq&kMls747c%fNPcvrTyR%L%)Q4twP(^$IuaW*O{D(ir21U!mILK5`{ zt^(z(J4gt@j2Oq@Fw=+{;q070D@--cF+IEFf^kM=X~%CzQKgZxi|EdMUS3E3yC&jB zr?>txaFp)(V2{T|ZbiE!A+spv;reb(u`>#uiiKN{O|X;V5P^mLSSeNdydE3IOFbl8 z0^Wyyq@bGPOpfFt(ktw>eM|nl$ zLD}u{!m}GgHfuG_$<4NRw4)L1WpQj_2bBUk_xe_~xYc!ay;Edh!0~F-g?XqWpP;(y~-F2|NLL zX^7`;wigTn>d>F_+l?x+6wfdw6{3 z+mQXFYOo(eg9}MmgKsb--Mn*$h-fx49+19$1Kb*BC9#&hylXWc(;=X_?O6 zh&3afEXElk&UNMX3oB?JjBAsGGTBC|=)3zRPhiz+5sEKVYOfB@XuOG0ct^^K@|zSA zyt0f5JI1^KN54_48>9TAIRga`)I318XFJes?ZKP`dQ3MKh%BC-nipH@S_%RL<=`Bd z{bDN{+>i7&g7?v*PB7SXbjGO9ALMHIz1upEZg6R0LX%K1E*;-(J8f^;kEshJ`AG3& z8zYnMq{!M6$8AKoa`+@v_Q0+RiPzc45T6%{pEOw$_Kog2-oSLw5I}uT&5tooyN**# z5EP$Z2H+*6Jvs~28{vC00F)C&;40Fp4DZ3XjPds?#3M}(&|qFL^9080RAi54q}WCK zZH>NBDrlgTe>eS{cR;mON~0vJz^VvxB1O48;NFoVeyyeDOQQLsmP@xpTT?5&@w9?Z z{xM%qIe0i|TO(4UhZS38UR_V|5^r}D`+h6e{1f~`KQ6@!*A9+kVqy9#c&TI<^8Vp z@u7!Gl&@FXpp_drpt(rAaHv$Di|Im)r_auo>NP!`7OsyTUi5w_4~jP<=AvrqV5wse z`G@IyF3?&Lx`CHZtspkUPa^TlKgGN~mDt(SzvgUljdU~PjDeN2RzrNL?vuVyZjq$= z($Spv6;DL~e9HmyQa8tflE{D0v9U5rmc{OL^Tgy0Fy;>SH{zeMzds{r2Khil?ZVOq zW5>AI2;-}!W`>5Wn#Nbo-ba&Pfn3xd_5k$4Gc);-B^m6UACr=j7h&J!rtC4Plpoz3 zZ<`p_-Drzp6BMy&il6nx!KF!xGVm!ic8UgQsE1t}dILjf2$aeo7gOC_uuPXR{OYL` z&=EpV_W1g?LD@SY^p^90Tz_VdwdZ=B{(ah9ugWvVd*kG!v9 zPyMbbX?pb~NP_nz-IGDThAz*lNjPd4yhqat#tl0>h-UEL`$3Xs7+?W`uzq>2D5uGB zc>;w0*mzqt9eio|R?P9=<}qDwTcj4;;Cj6-^}3sul)4nKkpZkc{|`oCfzeL=<5!F_8a7}95&?6qU`R;*@mY*JS{WU}3Fts!aKS3D zAn|km!7seu`ycp1GS`2@9S*_2p5Uhqonaozk#pGiqsS!?5fw z=?|NH82{~jc@L~-<*{3>XyyA<@AFBIc#8IVG)I;3hO}o z3>7O$cA~D*VfMW9gxZMyXl2+f}~GCA<&WTgP1+1As|_tk!+I zDzN@Air2-{)6at$eg2Y0H~SZ(cE9K_@VPHY!ScRGSj^{t@2c}L*z5h;1H*ZZj=5zx z$2PkMudAEPfeFCLYRvBhvAFZ%inWhjd>QrDm=>d%bF5p2k4k4x*M!&VFu367#>bCo z8yEYdp2H4)-Rujafdc>#&KTM#*3dyvxS5&a{FN-)x&Fih#K~$D8 zZgPgyV}jc>s8lgxU@|TyM#)e!pMI9Rqr+uuihp8_uvQwf#or9oc~If^q-=IDIY>4Q z0FWf|=Gbou=3x=4!VD`GM_yC)R#ktUqzV81#={r^z`tQ?ujUI>@#Z+9%Pl9ue9sF8 z>5V}e$^aZ%q+V^L^g`cfKrz^MA?w4(!DKOBnZ5zLNBXNZfJ^$pi9#?7U6b}3Ntz?G~4*Q0| zrC*f-Xl~qy=$4KV)qXSPvm>ZBF?6<)qu$EcGiRM%CK%lVnzdB`N_fA@KOgbG9zy?x=Ci;z^}&T}kWf zSstGG^@30O0WX`Q0$?Ds^r)M19l=~H3K@Aa07ZL;RS&SL%eCKx~k(^D@EV$ zfnVO9qxN?mg@n8ZIE0|IhUO{E=p-x~LOIp^j;PT+QchDd*KNJnud|(~?0#yH^15W{ zAa=2*6Sk}B)W@3mE&`NQd4JXgnDrM?&n?ES*{z|EF&s;4cV2vqUQQ4L;tT@(W=no2 z;4kEC=*cSuNE$YGr_OE_QRytjL?SD;T25e-*f(zsP{(LcB(6cq5jNDH7_e+kJgszs z3$xMWd~8$@UHl?nxt9*7S@AqSrii};@p|i~-N{Y@3SUJ(p`|?Pv;d*eHhf|5N24JJ^2KySd&cH?zR&XGElMsV>2 zu%}~;P@Z7zE&Tu`ByMx8>u{`V+U9s{3P<^A2Gbl&(cOJ%L)#1zhMBboUu}DN|2tog zDFxzF3pQ^y;G>%U~Nhn&~QzSXS3$`u1K7oW1oXdw9gIy)AZGYFELyQv=eL@RWpx(!Ho* zDv73d>g>pT#Y>bms|>xDegai65wN6c4O)O5(jP6YG}R)EA_zKqqGmBqIRrvw4#Z6C zPxS#0(p#whvnR2HcgIOoLu8)E)?;=cDM_6rRZ2>;3LXh?pQm~cXiSyh3KASsCC}Zi8-7W1uU>d zw{AF(k7wIy-d-4-jeJn|stZi6go%HoOZVG3w|F2Qy=_qUb}!x@#Aj^6@ENAGV*7_D zm%C&PBc9jsv=L3~ogT=bmfS_Mya0m^1QN(X$e!2GB)in!8Y#gKGdG_vD>FmpJp2|v za4+h!zpV()GQmJzHabA*WzvDDbNm5Qw;}8fq`uqlel6>9$?S}zXBarSsT#tDB>_UD zWDIAlZqnMe4rE+4wIwrUZ9z3;I6iZ7B(AoIC!^;sL^zMW zXM!*6|H>xp-Ge>ce9@BVOE}Vz@x9x4-i)`D`8#lgX0#egp4e>W^8?NY!DzRIP3F{x zl^vOf!f{Z@CLWzTyHVnC_p}lBWk*MAQIw=e$um|K--PA}kt(abV0gO5>Wn2c$Icez z`-0&WS=P64=V$Z~1NgkG%2U=N?#+)#BKT$>9Vn{Nx58LuhwIRBgR_IKqBu<>$lx&c zMW#H=!JG#v36TYc>jD*Q?fOwe{=Y65NtVBIr zu=0zV`4Fn+{mH`2l~%tUdZnhw!TZ$aZ3n+DtUFt;VGlF7qxPma=rcbLP8JkI)H^qL%9Msz*Hh6g{2LIle9iF8f{T`pcO6|{H({*P=^AG^=$r1BsATCT?~1DU0h zfk^sC@)nv&Hm)KO<$I(rkdE_v>oT~}by4x_5YRakKALwaP@p^K(mIvTw9VRy@w(Yt zH=B_5W!kKXqO+*WY#?2V-uv|{Ea=oVA50Mjv(zy+uKBsIpK2H^tN9(DN7hkg23Z0m z1NUD+e9@b0Xg4xSaIAW}$tluHyS-#A*QaTd_bU$jOX;N{gQm`SQwYbz4Rm+}>OFX_ zE4_uNZ_}E3kp2Oa3r~9nC~U9wkk5vk@Bx1bMifA>N7vrKq-asuW#;R0)V={Ncq9bk zcM#^7!BBXAb6KK3>}Gddkx%FgAmh$#r@=_aXVp-j*AJ>1hJLP6t3#wt8-GzVzLOL!d7+v;U4~y}A z^}WP%sdJxBRBu-iUBT=g6R8Mm`Ayy?G+Waz1p;V&HulkK!hSM%i6Be@_`Q8BhB&@L zgucFgqa^XuJnGyEKUyu}EhDhuvi-L~E&Q(czqH`= zT`qBtb{H@pUYw<{x5v8ZY4#J-Mbwm#Jja5PHl#eqUE6l^Cy~5jad)=!jKM0$&f<2X zvhsO#t2O*!q}Wf%>-&v;K#H!y3+ZV1ICGaCq6^B$*QUF%fY(ow?@1mukIqad+QDOv zn$;k!H#;e!(!1}WFfjd2mI7bPl^bDwqu)<_yd8h^vtb%upLJ}yl@LAd#$KP>0!L@4 z-K5W->qPIo`WR$MqHlbDPd53+dnO6BW{<33WlcvTy*wMxBD5AXQGRDKT#H-Jo~o^W$hNx|Qh z^!IL&%MtqSaW!SD-UY&=pkFnG=zTCco?v~my~dFN#rIS_m_K>)^Ia4=RcFuS^yf7` z&ukqfo0xwBtf7683H+pBhX|jE;_o;2BM*#Tc~f{~Dwa1FAmxj;m(@D+@?KSYV)r;jF9ww=FM>Ay5XQ+NyQ>#5cbt1x-Ap{h?{yA zeU7nrQqb*XT@wvRP8p}D$b-{AIn>M@SK3>vFBq8NX+8#{GGfo^x$So@zGUat%ekEj z(#dkdp;ArC4%1)iJZv;F7D(%K%P}3)iXTGr=H?={`#i-jf|8OOslb^ht|lOQR;#~m z)&RI7wNP95TQs1#OJq8NF6UJb$Qt-@B3%Y(H6YRU>t26x%(3OrIx8_BU?QgLc^SD} zO40-jEEhPLVymWr(l|NxbCZmXCWn&?eGeG$uB6o;XH^Q=xs|$7_#M;Rd~0e!wDHWt zUivT$fQ>eVLbQlmt)BhBPO#D0q9+cR_K@;PBd2>`m_6pNSyE%#Wl|^i*<(#OLDM*{ zw<;8oUWHb?@<~V2_Ta4)ZJ>1a(43sjOkvpbp%4j&LiQCr7Ohm0olRAS-F{)eI1NYQ zj_*8txVZ-aF#e^Dr^3n}C4!uVag{6gZleQp8nt148%pl(NyoU#HT}a~gHhmI>s~j) z#KR1CxkCsMqU2r-P?q@n`tU>+On16E|1o=F(W^yTb7FWfjWJ-m?4B(U-~z(;%HRu) zq<0=_>aenrWjccmCa+-YV!s+}DdedgdF`8#ISPCnUN;tS8!|OAhJ=h;owZzEpG1bL2CIcXb(Zk3@5L1>4{6%7reLB z$ml%!M^vBP5o6r;Wov+2AtsCaOtY3Y~uq5aGCEJU&u))bs#F8FW= z46aRk`*aZ_kNxh&5zsWEcEvbOV^YNN#=yg)1UJW8DL--{A54OU6)6|0r_+PKrL~yH z4!!%C7n9pX5UD10_;gZ)*r`Y@kno5%gByC0-Ec^>r^cXi^NYDRu8whCDdY*L%AC@1 zvw*+q0<3S86~}n;Gxqufn4kwPj`wq4`F_QuCB^Nr*p~+=5vsKWC@Da)(uU-o<9*;u@qx7h9&yphq2e z0D<^SeJct`J#2jYB0aCNHD4KjluHaj0w!YGlHNTIA2NXL-8|g2%l+)!D zp=07kset(^kzmYsY64bjzI;a&Qz z%2xhh0YQKM$(gD;S%pJDbfEbL?0CdpJ%)~_v2@@o3D&*rT2)_~pk~Nh99clLN{yrJ zXX3fbUM{O=aNi}n=mjAJ&G7!%iy^kSjKu71fsR*0n&(w&Y6YK`v2h=tg9vLO$SH*h zBu*H({YbZ3_b(eG=v863>j1S{v$m_Ab*wjj+}Falo;SI^irv$VOVlP z=;j?I360~b+6D}F@rC`M9$wOhXHlh2HI#cNO;nsoGWyaR2t51$cmo5MjDuwFDDbbb zJ-a)xpHycW3W0ysi>huW5>&LXxIKg)bemBtlex`G6=v6Tk#1TBG!Daz78lJ)tAVo< zFYFj>2Zad~Am$>IO80_{l{Msyb#P>kMd%|)gsd8ybdsINd$=kO`9(L)p|U>?>jUn%9m3*A6^}3<+!ljF` z_mKb`0`I>Lo`TVa0YyDpezG`p=sNq9Ww?1?b zK>%F|F?A1(VVWm9PUG_5aInvvk%=9`<>>J47mKW8(!RW}9vNu{YbmL|>3%Fd!L{=> zA#yIv(=Ofo@7|A>slxxfdsfqWPjJ0s(M?)F%#h+Q+f}=J z_rRQF;3o7a);&bPY8?0zh;u}90KS=scW9{TER>{3RX_d{Tf}}L{r()epYukvW>w$H z5L2P|PKXp^hAr*8>4XCDcRy+gsm3<{DZ|kQWz@5;j~%XeR#J|*3brf0l&90cbY|Bd zF&4!IFXyDaN|`IOE$_yppAQr`-QLK=JY$5kiEA(-NGH`l81C8eBRf<#nWSH`5b^J)7(?Jm3;Ymx1oFsr zw#+QEdqu|U8$dK{^iB?Z?$wPV6id%riZ-)rDNAA;51BURL__DIA7^12Seoo(2V)gy zGOU-Uww{%pYfT{Bo)&T2Clsk}LX((`WVP<`=r$IRzF@ckh5V{SZy=hhX`}MowT;-p z-|mB7PwQq}CDRY(|BFoa?pvm)e#7>D{oX=PTFVf`!Hpm?u8o zN>pqL@)~8y;{pYnk>XSI{s!EY}nxE&)nz^q?b|J z@Va)`#3DJ5la8=9z*imBzL`XF(;hL%|Jl}Pq{h>8hcp}B;U4|Sb`T} zet{VwaD^KfVXvo@ahvOV{RZu=VR-jDG944s4@|PzDh{HYUQV9x#)*0ioIWOJMp9N|Yg~*9Jp@hHT+`ger?Hmm}&)@h_UY`yWmZkm`)#F=N<-8>He}6KJuTgN2phMx@Mr}&vv|8HS_=r z*ZTV1L|t`{U+)v=sgkxl+h%~D5#a8e*sUA0RHCLR+LG*Q7K1n&dx=b>P;8b(U4V7v zId8-bNy_Mdid3@jmA(H~IpLHMG`9;CNKF%~`MuT2E2Py#m`UJ5+$$oBkJbvpndvh

A#~TFx?$3SPbdsAdYYH93 z3T*+BTb=t)>)9o!CHNaNLIdU}5GPn0>kqXJ;}L9Yn7_{!);lP=#TM0fI@dMwk#>Ur z)p>Xn5dLYjq@3v)<7y6NlhKkr>xxH6WPY9uqB?n#HbC*#VnpB%bB)(m@wAMGM^puO z7Wq#vBZ|RKc5Qg9j4K~0odb*wu#JmzilDI?lG`DA`+LQJOWt?rY;QE^pU0P%4|60` zQas5TzyE{q<^SpO|Kru!{#Bkt4S4D*#LL+E TQ<6pq_<63Rs#q#-`u_g`piR5o delta 47385 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 AMgRZ+ From 7bd5dd5168ef5540e93535847718a8f5a97e119d Mon Sep 17 00:00:00 2001 From: Xhuis Date: Fri, 17 Jun 2016 10:51:51 -0400 Subject: [PATCH 13/19] Makes cherry bombs auto-delete on explosion --- code/modules/hydroponics/grown/misc.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 561723fa878..4504d1740ba 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -127,6 +127,9 @@ prime() ..() +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity) + qdel(src) //Ensuring that it's deleted by its own explosion + /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime() icon_state = "cherry_bomb_lit" playsound(src, 'sound/effects/fuse.ogg', seed.potency, 0) From aa0899eb06e89bc8bfa6f1243edaac3f48be38c7 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Fri, 17 Jun 2016 22:57:56 +0000 Subject: [PATCH 14/19] Automatic changelog generation for PR #18636 [ci skip] --- html/changelogs/AutoChangeLog-pr-18636.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18636.yml diff --git a/html/changelogs/AutoChangeLog-pr-18636.yml b/html/changelogs/AutoChangeLog-pr-18636.yml new file mode 100644 index 00000000000..63b7219dad5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18636.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Drones can hear robotic talk, but cannot communicate on it. AIs and cyborgs are encouraged to share information with station repair drones." From cbf976affda93da6bfe657816853a2e345ce2e31 Mon Sep 17 00:00:00 2001 From: Leo Date: Fri, 17 Jun 2016 20:10:14 -0300 Subject: [PATCH 15/19] fix it --- code/modules/atmospherics/machinery/portable/canister.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 0a6efae2095..904f76b8a0a 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -309,8 +309,8 @@ var/n2o = air_contents.gases["n2o"] var/bz = air_contents.gases["bz"] if(n2o || plasma || bz) - message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma && bz ? " & " : ""][plasma ? "Plasma" : ""][bz ? "BZ" : ""]! (JMP)") - log_admin("[key_name(usr)] opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][bz ? "BZ" : ""] at [x], [y], [z]") + message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][(n2o || plasma) && bz ? " & " : ""][bz ? "BZ" : ""]! (JMP)") + log_admin("[key_name(usr)] opened a canister that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""][(n2o || plasma) && bz ? " & " : ""][bz ? "BZ" : ""] at [x], [y], [z]") else logmsg = "Valve was closed by [key_name(usr)], stopping the transfer into \the [holding || "air"].
" investigate_log(logmsg, "atmos") From c082b7df5ac6cd1953af969ced586292ff98d687 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Fri, 17 Jun 2016 19:08:41 -0500 Subject: [PATCH 16/19] Missing return added to fultons --- code/modules/mining/fulton.dm | 1 + .../mob/living/simple_animal/hostile/megafauna/megafauna.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 09c612b4f18..08da1d69739 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -58,6 +58,7 @@ var/list/total_extraction_beacons = list() else if(!safe_for_living_creatures && check_for_living_mobs(A)) user << "[src] is not safe for use with living creatures, they wouldn't survive the trip back!" + return if(A.loc == user || A == user) // no extracting stuff you're holding in your hands/yourself return if(A.anchored) 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 2c2a48a2d61..bc6dd31cdd4 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -12,6 +12,7 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = INFINITY + anchored = TRUE layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise /mob/living/simple_animal/hostile/megafauna/death(gibbed) From d91812d3ad80ba12430b3ee3f321e677fc974561 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Sat, 18 Jun 2016 07:15:12 -0400 Subject: [PATCH 17/19] Clock cult scripture unlock now counts humans and silicons only (#18669) * Clock cult scripture unlock now requires non-brain mobs * switch * brains don't count dave * humies and silicons only * i blame everything on how inattentive i am --- code/game/gamemodes/clock_cult/clock_items.dm | 20 +++--- .../gamemodes/clock_cult/clock_unsorted.dm | 68 +++++++++++++------ 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_items.dm b/code/game/gamemodes/clock_cult/clock_items.dm index c3f7db74900..75051b889f6 100644 --- a/code/game/gamemodes/clock_cult/clock_items.dm +++ b/code/game/gamemodes/clock_cult/clock_items.dm @@ -132,19 +132,11 @@ return 1 /obj/item/clockwork/slab/proc/recite_scripture(mob/living/user) - var/servants = 0 - var/unconverted_ai_exists = FALSE - for(var/mob/living/M in living_mob_list) - if(is_servant_of_ratvar(M)) - servants++ - for(var/mob/living/silicon/ai/ai in living_mob_list) - if(!is_servant_of_ratvar(ai) && ai.client) - unconverted_ai_exists = TRUE var/list/tiers_of_scripture = list("Drivers") - tiers_of_scripture += "Scripts[ratvar_awakens || (servants >= 5 && clockwork_caches >= 1) || no_cost ? "" : " \[LOCKED\]"]" - tiers_of_scripture += "Applications[ratvar_awakens || (servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 50) || no_cost ? "" : " \[LOCKED\]"]" - tiers_of_scripture += "Revenant[ratvar_awakens || (servants >= 10 && clockwork_construction_value >= 100) || no_cost ? "" : " \[LOCKED\]"]" - tiers_of_scripture += "Judgement[ratvar_awakens || (servants >= 10 && clockwork_construction_value >= 100 && !unconverted_ai_exists) || no_cost ? "" : " \[LOCKED\]"]" + tiers_of_scripture += "Scripts[ratvar_awakens || scripture_unlock_check(SCRIPTURE_SCRIPT) || no_cost ? "" : " \[LOCKED\]"]" + tiers_of_scripture += "Applications[ratvar_awakens || scripture_unlock_check(SCRIPTURE_APPLICATION) || no_cost ? "" : " \[LOCKED\]"]" + tiers_of_scripture += "Revenant[ratvar_awakens || scripture_unlock_check(SCRIPTURE_REVENANT) || no_cost ? "" : " \[LOCKED\]"]" + tiers_of_scripture += "Judgement[ratvar_awakens || scripture_unlock_check(SCRIPTURE_JUDGEMENT) || no_cost ? "" : " \[LOCKED\]"]" var/scripture_tier = input(user, "Choose a category of scripture to recite.", "[src]") as null|anything in tiers_of_scripture if(!scripture_tier || !user.canUseTopic(src)) return 0 @@ -187,11 +179,15 @@ /obj/item/clockwork/slab/proc/show_stats(mob/living/user) //A bit barebones, but there really isn't any more needed var/servants = 0 + var/validservants = 0 for(var/mob/living/L in living_mob_list) if(is_servant_of_ratvar(L)) servants++ + if(ishuman(L) || issilicon(L)) + validservants++ user << "State of the Enlightened" user << "Total servants: [servants]" + user << "Servants valid for scripture unlock: [validservants]" user << "Total construction value: [clockwork_construction_value]" user << "Total tinkerer's caches: [clockwork_caches]" user << "Total tinkerer's daemons: [clockwork_daemons] ([servants / 5 < clockwork_daemons ? "DISABLED: Too few servants (5 servants per daemon)!" : "Functioning Normally"])" diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm index b688ac714cd..e8fc69c171b 100644 --- a/code/game/gamemodes/clock_cult/clock_unsorted.dm +++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm @@ -20,27 +20,6 @@ qdel(F) return 1 -/proc/generate_cache_component(specific_component_id) //generates a component in the global component cache, either random based on lowest or a specific component - if(specific_component_id) - clockwork_component_cache[specific_component_id]++ - else - var/component_to_generate = get_weighted_component_id() - clockwork_component_cache[component_to_generate]++ - -/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab) //returns a chosen component id based on the lowest amount of that component - if(storage_slab) - return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["belligerent_eye"] + storage_slab.stored_components["belligerent_eye"]), 1), \ - "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["vanguard_cogwheel"] + storage_slab.stored_components["vanguard_cogwheel"]), 1), \ - "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["guvax_capacitor"] + storage_slab.stored_components["guvax_capacitor"]), 1), \ - "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["replicant_alloy"] + storage_slab.stored_components["replicant_alloy"]), 1), \ - "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["hierophant_ansible"] + storage_slab.stored_components["hierophant_ansible"]), 1))) - - return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["belligerent_eye"], 1), \ - "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["vanguard_cogwheel"], 1), \ - "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["guvax_capacitor"], 1), \ - "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["replicant_alloy"], 1), \ - "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["hierophant_ansible"], 1))) - //allows a mob to select a target to gate to /atom/movable/proc/procure_gateway(mob/living/invoker, time_duration, gateway_uses, two_way) var/list/possible_targets = list() @@ -92,6 +71,53 @@ S2.visible_message("The air in front of [target] ripples before suddenly tearing open!") return 1 +/proc/scripture_unlock_check(scripture_tier) //check if the selected scripture tier is unlocked + var/servants = 0 + var/unconverted_ai_exists = FALSE + for(var/mob/living/M in living_mob_list) + if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M))) + servants++ + for(var/mob/living/silicon/ai/ai in living_mob_list) + if(!is_servant_of_ratvar(ai) && ai.client) + unconverted_ai_exists = TRUE + switch(scripture_tier) + if(SCRIPTURE_DRIVER) + return 1 + if(SCRIPTURE_SCRIPT) + if(servants >= 5 && clockwork_caches) + return 1 //5 or more non-brain servants and any number of clockwork caches + if(SCRIPTURE_APPLICATION) + if(servants >= 8 && clockwork_caches >= 3 && clockwork_construction_value >= 50) + return 1 //8 or more non-brain servants, 3+ clockwork caches, and at least 50 CV + if(SCRIPTURE_REVENANT) + if(servants >= 10 && clockwork_caches >= 3 && clockwork_construction_value >= 100) + return 1 //10 or more non-brain servants, 3+ clockwork caches, and at least 100 CV + if(SCRIPTURE_JUDGEMENT) + if(servants >= 10 && clockwork_caches >= 3 && clockwork_construction_value >= 100 && !unconverted_ai_exists) + return 1 //10 or more non-brain servants, 3+ clockwork caches, at least 100 CV, and there are no living, non-servant ais + return 0 + +/proc/generate_cache_component(specific_component_id) //generates a component in the global component cache, either random based on lowest or a specific component + if(specific_component_id) + clockwork_component_cache[specific_component_id]++ + else + var/component_to_generate = get_weighted_component_id() + clockwork_component_cache[component_to_generate]++ + +/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab) //returns a chosen component id based on the lowest amount of that component + if(storage_slab) + return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["belligerent_eye"] + storage_slab.stored_components["belligerent_eye"]), 1), \ + "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["vanguard_cogwheel"] + storage_slab.stored_components["vanguard_cogwheel"]), 1), \ + "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["guvax_capacitor"] + storage_slab.stored_components["guvax_capacitor"]), 1), \ + "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["replicant_alloy"] + storage_slab.stored_components["replicant_alloy"]), 1), \ + "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["hierophant_ansible"] + storage_slab.stored_components["hierophant_ansible"]), 1))) + + return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["belligerent_eye"], 1), \ + "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["vanguard_cogwheel"], 1), \ + "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["guvax_capacitor"], 1), \ + "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["replicant_alloy"], 1), \ + "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["hierophant_ansible"], 1))) + /* The Ratvarian Language From e8175c9f8ba78fd9d66e5b0db753a3c0b66167c3 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sat, 18 Jun 2016 11:15:14 +0000 Subject: [PATCH 18/19] Automatic changelog generation for PR #18669 [ci skip] --- html/changelogs/AutoChangeLog-pr-18669.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18669.yml diff --git a/html/changelogs/AutoChangeLog-pr-18669.yml b/html/changelogs/AutoChangeLog-pr-18669.yml new file mode 100644 index 00000000000..c47fea8e108 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18669.yml @@ -0,0 +1,4 @@ +author: "Joan" +delete-after: True +changes: + - rscdel: "Clock cult scripture unlock now only counts humans and silicons." From 7187b893d952b58005aa8938531b54457e66fde5 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sat, 18 Jun 2016 16:09:33 +0000 Subject: [PATCH 19/19] Automatic changelog generation for PR #18675 [ci skip] --- html/changelogs/AutoChangeLog-pr-18675.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-18675.yml diff --git a/html/changelogs/AutoChangeLog-pr-18675.yml b/html/changelogs/AutoChangeLog-pr-18675.yml new file mode 100644 index 00000000000..a397fba7d15 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-18675.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - rscdel: "AI turrets no longer fire at drones."