From fb751312ace43d5fa40716e92aa33dac4efc2b7c Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 25 Nov 2017 17:34:45 -0500 Subject: [PATCH 001/213] Merge pull request #33037 from Jordie0608/nextupweaddsupportformongodb Conversion script MariaDB note --- SQL/feedback_conversion_2017-11-12.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/SQL/feedback_conversion_2017-11-12.py b/SQL/feedback_conversion_2017-11-12.py index b8577460b3..8a60e10b7e 100644 --- a/SQL/feedback_conversion_2017-11-12.py +++ b/SQL/feedback_conversion_2017-11-12.py @@ -5,6 +5,10 @@ #It can be downloaded from command line with pip: #pip install mysqlclient # +#tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement. +#Before running this script you will need to migrate to MariaDB. +#Migrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/ +# #You will also have to create a new feedback table for inserting converted data to per the schema: #CREATE TABLE `feedback_new` ( # `id` int(11) unsigned NOT NULL AUTO_INCREMENT, @@ -476,11 +480,25 @@ parser.add_argument("newtable", help="Name of the new table to insert to, can't args = parser.parse_args() db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database) cursor=db.cursor() +cursor.execute("SELECT @@GLOBAL.version_comment") +db_version = "".join([x for x in cursor.fetchone()]) +database_mysql = False +if 'MySQL' in db_version: + database_mysql = True +elif 'mariadb' not in db_version: + choice = input("Unable to determine database version installed, are you using MySQL? Type Yes or No and press enter...").lower() + if choice == "yes": + database_mysql = True +if database_mysql == True: + print("WARNING Database detected to be MySQL: tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement.\nBefore running this script you will need to migrate to MariaDB.\nMigrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/") + input("Press enter to quit...") + quit() current_table = args.curtable new_table = args.newtable -cursor.execute("SELECT max(id) FROM {0}".format(current_table)) +cursor.execute("SELECT max(id), max(round_id) FROM {0}".format(current_table)) query_id = cursor.fetchone() max_id = query_id[0] +max_round_id = query_id[1] start_time = datetime.now() print("Beginning conversion at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S"))) try: @@ -493,7 +511,7 @@ try: if not query_row: continue else: - if current_round != query_row[2]: + if current_round != query_row[2] or current_round == max_round_id: multirows_completed.clear() if query_values: query_values = query_values[:-1] @@ -524,8 +542,11 @@ try: print("Conversion completed at {0}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) print("Script duration: {0}".format(end_time - start_time)) except Exception as e: + cursor.execute("SELECT round_id FROM {0} WHERE id = {1}".format(current_table, current_id-1)) + query_round_id = cursor.fetchone() end_time = datetime.now() print("Error encountered on row ID {0} at {1}".format(current_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) + print("Note SQL insertion errors will be due to data from round ID {0}".format(query_round_id[0])) #since data is inserted when the round id changes on a new row print("Script duration: {0}".format(end_time - start_time)) cursor.execute("TRUNCATE {0} ".format(new_table)) raise e From 6bfca33a78662b2db9017e60f76535463d388379 Mon Sep 17 00:00:00 2001 From: AnturK Date: Mon, 11 Dec 2017 17:57:20 +0100 Subject: [PATCH 003/213] Roundend report refactor --- code/__DEFINES/clockcult.dm | 1 - code/__HELPERS/roundend.dm | 412 ++++++++++++++++++ code/_globalvars/game_modes.dm | 18 +- code/_globalvars/misc.dm | 2 + code/_onclick/hud/alert.dm | 31 +- code/controllers/subsystem/blackbox.dm | 8 +- code/controllers/subsystem/ticker.dm | 3 + code/controllers/subsystem/vote.dm | 11 + code/datums/ai_laws.dm | 29 +- code/datums/antagonists/abductor.dm | 63 +++ code/datums/antagonists/antag_datum.dm | 58 ++- code/datums/antagonists/brother.dm | 68 +++ code/datums/antagonists/changeling.dm | 33 +- code/datums/antagonists/clockcult.dm | 53 ++- code/datums/antagonists/cult.dm | 259 ++++++++--- code/datums/antagonists/datum_traitor.dm | 60 ++- code/datums/antagonists/devil.dm | 30 ++ code/datums/antagonists/ninja.dm | 21 +- code/datums/antagonists/nukeop.dm | 322 ++++++++++++++ code/datums/antagonists/pirate.dm | 57 ++- code/datums/antagonists/revolution.dm | 55 ++- code/datums/antagonists/wizard.dm | 48 +- code/datums/mind.dm | 62 ++- code/game/gamemodes/antag_spawner.dm | 1 + code/game/gamemodes/brother/traitor_bro.dm | 43 +- code/game/gamemodes/changeling/changeling.dm | 3 + code/game/gamemodes/clock_cult/clock_cult.dm | 46 +- .../clock_items/construct_chassis.dm | 3 +- .../clock_cult/clock_mobs/_eminence.dm | 22 +- .../clock_structures/eminence_spire.dm | 10 +- code/game/gamemodes/cult/cult.dm | 210 ++------- code/game/gamemodes/cult/cult_comms.dm | 68 +-- code/game/gamemodes/cult/ritual.dm | 23 +- code/game/gamemodes/cult/runes.dm | 25 +- code/game/gamemodes/devil/game_mode.dm | 38 -- code/game/gamemodes/game_mode.dm | 97 +---- code/game/gamemodes/meteor/meteor.dm | 19 +- .../miniantags/abduction/abduction.dm | 43 -- .../abduction/machinery/experiment.dm | 20 +- .../gamemodes/miniantags/monkey/monkey.dm | 11 +- code/game/gamemodes/miniantags/morph/morph.dm | 1 + .../gamemodes/miniantags/revenant/revenant.dm | 1 + .../miniantags/slaughter/slaughterevent.dm | 1 + code/game/gamemodes/nuclear/nuclear.dm | 40 ++ code/game/gamemodes/objective_team.dm | 14 +- code/game/gamemodes/revolution/revolution.dm | 58 +-- code/game/gamemodes/traitor/traitor.dm | 7 +- code/game/gamemodes/wizard/soulstone.dm | 3 +- code/game/gamemodes/wizard/wizard.dm | 20 +- code/game/machinery/wishgranter.dm | 1 + code/modules/admin/admin.dm | 8 +- code/modules/admin/verbs/one_click_antag.dm | 9 + code/modules/admin/verbs/onlyone.dm | 3 + .../awaymissions/mission_code/wildwest.dm | 2 + code/modules/client/client_defines.dm | 6 + code/modules/client/client_procs.dm | 7 + code/modules/client/player_details.dm | 2 + code/modules/clothing/under/accessories.dm | 2 +- code/modules/events/holiday/vday.dm | 7 + code/modules/events/nightmare.dm | 1 + .../modules/events/wizard/departmentrevolt.dm | 1 + code/modules/events/wizard/greentext.dm | 1 + code/modules/mob/living/silicon/robot/life.dm | 1 + .../mob/living/simple_animal/constructs.dm | 10 +- .../friendly/drone/extra_drone_types.dm | 2 +- code/modules/mob/login.dm | 4 + code/modules/ninja/ninja_event.dm | 2 +- code/modules/power/singularity/narsie.dm | 11 +- .../spells/spell_types/rightandwrong.dm | 2 + code/modules/station_goals/station_goal.dm | 6 +- html/browser/roundend.css | 67 +++ tgstation.dme | 2 + 72 files changed, 1928 insertions(+), 760 deletions(-) create mode 100644 code/__HELPERS/roundend.dm create mode 100644 code/datums/antagonists/nukeop.dm create mode 100644 code/modules/client/player_details.dm create mode 100644 html/browser/roundend.css diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index d51dbfd047..7451c42cab 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -6,7 +6,6 @@ #define HIEROPHANT_ANSIBLE "hierophant_ansible" //Use this for construction-related scripture! GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult -GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual) GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm new file mode 100644 index 0000000000..7bd08167e6 --- /dev/null +++ b/code/__HELPERS/roundend.dm @@ -0,0 +1,412 @@ +/datum/controller/subsystem/ticker/proc/gather_roundend_feedback() + var/clients = GLOB.player_list.len + var/surviving_humans = 0 + var/surviving_total = 0 + var/ghosts = 0 + var/escaped_humans = 0 + var/escaped_total = 0 + + for(var/mob/M in GLOB.player_list) + if(ishuman(M)) + if(!M.stat) + surviving_humans++ + if(M.z == ZLEVEL_CENTCOM) + escaped_humans++ + if(!M.stat) + surviving_total++ + if(M.z == ZLEVEL_CENTCOM) + escaped_total++ + + if(isobserver(M)) + ghosts++ + + if(clients) + SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) + if(ghosts) + SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) + if(surviving_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) + if(surviving_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) + if(escaped_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) + if(escaped_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) + + gather_antag_success_rate() + +/datum/controller/subsystem/ticker/proc/gather_antag_success_rate() + var/team_gid = 1 + var/list/team_ids = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + var/list/antag_info = list() + antag_info["key"] = A.owner.key + antag_info["name"] = A.owner.name + antag_info["antagonist_type"] = A.type + antag_info["antagonist_name"] = A.name //For auto and custom roles + antag_info["objectives"] = list() + antag_info["team"] = list() + var/datum/objective_team/T = A.get_team() + if(T) + antag_info["team"]["type"] = T.type + antag_info["team"]["name"] = T.name + if(!team_ids[T]) + team_ids[T] = team_gid++ + antag_info["team"]["id"] = team_ids[T] + + if(!A.owner) + continue + if(A.objectives.len) + for(var/datum/objective/O in A.objectives) + var/result = O.check_completion() ? "SUCCESS" : "FAIL" + antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) + SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) + + +/datum/controller/subsystem/ticker/proc/declare_completion() + set waitfor = FALSE + + to_chat(world, "


The round has ended.") + if(LAZYLEN(GLOB.round_end_notifiees)) + send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") + + for(var/client/C in GLOB.clients) + if(!C.credits) + C.RollCredits() + C.playtitlemusic(40) + + display_report() + + gather_roundend_feedback() + + CHECK_TICK + + //Set news report and mode result + mode.set_round_result() + + send2irc("Server", "Round just ended.") + + if(CONFIG_GET(string/cross_server_address)) + send_news_report() + + CHECK_TICK + + //These need update to actually reflect the real antagonists + //Print a list of antagonists to the server log + var/list/total_antagonists = list() + //Look into all mobs in world, dead or alive + for(var/datum/mind/Mind in minds) + var/temprole = Mind.special_role + if(temprole) //if they are an antagonist of some sort. + if(temprole in total_antagonists) //If the role exists already, add the name to it + total_antagonists[temprole] += ", [Mind.name]([Mind.key])" + else + total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob + total_antagonists[temprole] += ": [Mind.name]([Mind.key])" + + CHECK_TICK + + //Now print them all into the log! + log_game("Antagonists at round end were...") + for(var/i in total_antagonists) + log_game("[i]s[total_antagonists[i]].") + + CHECK_TICK + + //Collects persistence features + if(mode.allow_persistence_save) + SSpersistence.CollectData() + + //stop collecting feedback during grifftime + SSblackbox.Seal() + + sleep(50) + ready_for_reboot = TRUE + standard_reboot() + +/datum/controller/subsystem/ticker/proc/standard_reboot() + if(ready_for_reboot) + if(mode.station_was_nuked) + Reboot("Station destroyed by Nuclear Device.", "nuke") + else + Reboot("Round ended.", "proper completion") + else + CRASH("Attempted standard reboot without ticker roundend completion") + +//Common part of the report +/datum/controller/subsystem/ticker/proc/build_roundend_report() + var/list/parts = list() + + //Gamemode specific things. Should be empty most of the time. + parts += mode.special_report() + + CHECK_TICK + + //AI laws + parts += law_report() + + CHECK_TICK + + //Antagonists + parts += antag_report() + + CHECK_TICK + //Medals + parts += medal_report() + //Station Goals + parts += goal_report() + + listclearnulls(parts) + + return parts.Join() + + +/datum/controller/subsystem/ticker/proc/survivor_report() + var/list/parts = list() + var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED + var/num_survivors = 0 + var/num_escapees = 0 + var/num_shuttle_escapees = 0 + + //Player status report + for(var/i in GLOB.mob_list) + var/mob/Player = i + if(Player.mind && !isnewplayer(Player)) + if(Player.stat != DEAD && !isbrain(Player)) + num_survivors++ + if(station_evacuated) //If the shuttle has already left the station + var/list/area/shuttle_areas + if(SSshuttle && SSshuttle.emergency) + shuttle_areas = SSshuttle.emergency.shuttle_areas + if(Player.onCentCom() || Player.onSyndieBase()) + num_escapees++ + if(shuttle_areas[get_area(Player)]) + num_shuttle_escapees++ + + //Round statistics report + var/datum/station_state/end_state = new /datum/station_state() + end_state.count() + var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) + + parts += "[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" + parts += "[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]" + var/total_players = GLOB.joined_player_list.len + if(total_players) + parts+= "[GLOB.TAB]Total Population: [total_players]" + if(station_evacuated) + parts += "
[GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)" + parts += "[GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)" + parts += "[GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)" + return parts.Join("
") + +/datum/controller/subsystem/ticker/proc/show_roundend_report(client/C,common_report) + var/list/report_parts = list() + + report_parts += personal_report(C) + report_parts += common_report + + var/datum/browser/roundend_report = new(C, "roundend") + roundend_report.width = 800 + roundend_report.height = 600 + roundend_report.set_content(report_parts.Join()) + roundend_report.stylesheets = list() + roundend_report.add_stylesheet("roundend",'html/browser/roundend.css') + + roundend_report.open(0) + +/datum/controller/subsystem/ticker/proc/personal_report(client/C) + var/list/parts = list() + var/mob/M = C.mob + if(M.mind && !isnewplayer(M)) + if(M.stat != DEAD && !isbrain(M)) + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + if(!M.onCentCom() || !M.onSyndieBase()) + parts += "
" + parts += "You managed to survive, but were marooned on [station_name()]..." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + + else + parts += "
" + parts += "You did not survive the events on [station_name()]..." + else + parts += "
" + parts += "
" + if(GLOB.survivor_report) + parts += GLOB.survivor_report + else + parts += survivor_report() + + parts += "
" + + return parts.Join() + +/datum/controller/subsystem/ticker/proc/display_report() + GLOB.common_report = build_roundend_report() + for(var/client/C in GLOB.clients) + show_roundend_report(C,GLOB.common_report) + give_show_report_button(C) + CHECK_TICK + +/datum/controller/subsystem/ticker/proc/law_report() + var/list/parts = list() + //Silicon laws report + for (var/i in GLOB.ai_list) + var/mob/living/silicon/ai/aiPlayer = i + if(aiPlayer.mind) + parts += "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was deactivated"] were:" + parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE) + + parts += "Total law changes: [aiPlayer.law_change_counter]" + + if (aiPlayer.connected_robots.len) + var/robolist = "[aiPlayer.real_name]'s minions were: " + for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) + if(robo.mind) + robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" + parts += "[robolist]" + + for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) + if (!robo.connected_ai && robo.mind) + if (robo.stat != DEAD) + parts += "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:" + else + parts += "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:" + + if(robo) //How the hell do we lose robo between here and the world messages directly above this? + parts += robo.laws.get_law_list(include_zeroth=TRUE) + if(parts.len) + return "
[parts.Join("
")]
" + else + return "" + +/datum/controller/subsystem/ticker/proc/goal_report() + var/list/parts = list() + if(mode.station_goals.len) + for(var/V in mode.station_goals) + var/datum/station_goal/G = V + parts += G.get_result() + return "
    [parts.Join()]
" + +/datum/controller/subsystem/ticker/proc/medal_report() + if(GLOB.commendations.len) + var/list/parts = list() + parts += "Medal Commendations:" + for (var/com in GLOB.commendations) + parts += com + return "
[parts.Join("
")]
" + return "" + +/datum/controller/subsystem/ticker/proc/antag_report() + var/list/result = list() + var/list/all_teams = list() + var/list/all_antagonists = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + all_teams |= A.get_team() + all_antagonists += A + + for(var/datum/objective_team/T in all_teams) + result += T.roundend_report() + for(var/datum/antagonist/X in all_antagonists) + if(X.get_team() == T) + all_antagonists -= X + result += " "//newline between teams + + var/currrent_category + var/datum/antagonist/previous_category + + sortTim(all_antagonists, /proc/cmp_antag_category) + + for(var/datum/antagonist/A in all_antagonists) + if(!A.show_in_roundend) + continue + if(A.roundend_category != currrent_category) + if(previous_category) + result += previous_category.roundend_report_footer() + result += "
" + result += "
" + result += A.roundend_report_header() + currrent_category = A.roundend_category + previous_category = A + result += A.roundend_report() + result += "
" + + if(all_antagonists.len) + var/datum/antagonist/last = all_antagonists[all_antagonists.len] + result += last.roundend_report_footer() + result += "
" + + return result.Join() + +/proc/cmp_antag_category(datum/antagonist/A,datum/antagonist/B) + return sorttext(B.roundend_category,A.roundend_category) + + +/datum/controller/subsystem/ticker/proc/give_show_report_button(client/C) + var/datum/action/report/R = new + C.player_details.player_actions += R + R.Grant(C.mob) + to_chat(C,"Show roundend report again") + +/datum/action/report + name = "Show roundend report" + button_icon_state = "vote" + +/datum/action/report/Trigger() + if(owner && GLOB.common_report && SSticker.current_state == GAME_STATE_FINISHED) + SSticker.show_roundend_report(owner.client,GLOB.common_report) + +/datum/action/report/IsAvailable() + return 1 + +/datum/action/report/Topic(href,href_list) + if(usr != owner) + return + if(href_list["report"]) + Trigger() + return + + +/proc/printplayer(datum/mind/ply, fleecheck) + var/text = "[ply.key] was [ply.name] the [ply.assigned_role] and" + if(ply.current) + if(ply.current.stat == DEAD) + text += " died" + else + text += " survived" + if(fleecheck) + var/turf/T = get_turf(ply.current) + if(!T || !(T.z in GLOB.station_z_levels)) + text += " while fleeing the station" + if(ply.current.real_name != ply.name) + text += " as [ply.current.real_name]" + else + text += " had their body destroyed" + return text + +/proc/printplayerlist(list/players,fleecheck) + var/list/parts = list() + + parts += "
    " + for(var/datum/mind/M in players) + parts += "
  • [printplayer(M,fleecheck)]
  • " + parts += "
" + return parts.Join() + + +/proc/printobjectives(datum/mind/ply) + var/list/objective_parts = list() + var/count = 1 + for(var/datum/objective/objective in ply.objectives) + if(objective.check_completion()) + objective_parts += "Objective #[count]: [objective.explanation_text] Success!" + else + objective_parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + return objective_parts.Join("
") \ No newline at end of file diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm index 9c3af923f1..3822f7077d 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -1,18 +1,12 @@ GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode +GLOBAL_VAR(common_report) //Contains commmon part of roundend report +GLOBAL_VAR(survivor_report) //Contains shared surivor report for roundend report (part of personal report) + GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report -// Cult, needs to be global so admin cultists are functional -GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master -GLOBAL_DATUM(blood_target_image, /image) -GLOBAL_VAR_INIT(blood_target_reset_timer, null) -GLOBAL_DATUM(sac_mind, /datum/mind) -GLOBAL_VAR_INIT(sac_image, null) -GLOBAL_VAR_INIT(cult_vote_called, FALSE) -GLOBAL_VAR_INIT(cult_mastered, FALSE) -GLOBAL_VAR_INIT(reckoning_complete, FALSE) -GLOBAL_VAR_INIT(sac_complete, FALSE) -GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) -GLOBAL_LIST_EMPTY(summon_spots) \ No newline at end of file + +//TODO clear this one up too +GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) \ No newline at end of file diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index bb86b4cbb0..8b8b817586 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -16,3 +16,5 @@ GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a perce GLOBAL_LIST_EMPTY(powernets) GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes + +GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details \ No newline at end of file diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 0006d72d3b..2ad2eb76f5 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -302,32 +302,41 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /obj/screen/alert/bloodsense/process() var/atom/blood_target - if(GLOB.blood_target) - if(!get_turf(GLOB.blood_target)) - GLOB.blood_target = null + + var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return + var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives + + if(antag.cult_team.blood_target) + if(!get_turf(antag.cult_team.blood_target)) + antag.cult_team.blood_target = null else - blood_target = GLOB.blood_target + blood_target = antag.cult_team.blood_target if(Cviewer && Cviewer.seeking && Cviewer.master) blood_target = Cviewer.master desc = "Your blood sense is leading you to [Cviewer.master]" if(!blood_target) - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) if(icon_state == "runed_sense0") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense0" - desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin." - add_overlay(GLOB.sac_image) + desc = "Nar-Sie demands that [sac_objective.target] be sacrificed before the summoning ritual can begin." + add_overlay(sac_objective.sac_image) else + var/datum/objective/eldergod/summon_objective = locate() in antag.cult_team.objectives + if(!summon_objective) + return if(icon_state == "runed_sense1") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense1" - desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(GLOB.summon_spots)]!" + desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(summon_objective.summon_spots)]!" add_overlay(narnar) return var/turf/P = get_turf(blood_target) @@ -388,11 +397,13 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "CHETR
NYY
HAGEHUGF-NAQ-UBABE
RATVAR.
" else var/servants = 0 - var/list/textlist + var/list/textlist = list() for(var/mob/living/L in GLOB.alive_mob_list) if(is_servant_of_ratvar(L)) servants++ - textlist = list("[SSticker.mode.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
") + var/datum/antagonist/clockcult/C = mob_viewer.mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + textlist += "[C.clock_team.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
" textlist += "There are currently [servants] servant[servants > 1 ? "s" : ""] of Ratvar.
" for(var/i in SSticker.scripture_states) if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 941fcbbcd6..e638de668e 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -10,7 +10,8 @@ SUBSYSTEM_DEF(blackbox) var/sealed = FALSE //time to stop tracking stats? var/list/research_levels = list() //list of highest tech levels attained that isn't lost lost by destruction of RD computers var/list/versions = list("time_dilation_current" = 2, - "science_techweb_unlock" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this + "science_techweb_unlock" = 2, + "antagonists" = 3) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this /datum/controller/subsystem/blackbox/Initialize() @@ -225,7 +226,10 @@ Versioning var/pos = length(FV.json["data"]) + 1 FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]" for(var/i in data) - FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" //and here with "[FV.json["data"].len]" + if(islist(data[i])) + FV.json["data"]["[pos]"]["[i]"] = data[i] //and here with "[FV.json["data"].len]" + else + FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" else CRASH("Invalid feedback key_type: [key_type]") diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 881bb7fcb7..f178a1bd24 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -398,6 +398,7 @@ SUBSYSTEM_DEF(ticker) var/mob/living/L = I L.notransform = FALSE +<<<<<<< HEAD /datum/controller/subsystem/ticker/proc/declare_completion() set waitfor = FALSE var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED @@ -596,6 +597,8 @@ SUBSYSTEM_DEF(ticker) else CRASH("Attempted standard reboot without ticker roundend completion") +======= +>>>>>>> 3d81385... Roundend report refactor (#33246) /datum/controller/subsystem/ticker/proc/send_tip_of_the_round() var/m if(selected_tip) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 55624a866c..0ce136f83b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -206,6 +206,7 @@ SUBSYSTEM_DEF(vote) var/datum/action/vote/V = new if(question) V.name = "Vote: [question]" + C.player_details.player_actions += V V.Grant(C.mob) generated_actions += V return 1 @@ -299,6 +300,7 @@ SUBSYSTEM_DEF(vote) for(var/v in generated_actions) var/datum/action/vote/V = v if(!QDELETED(V)) + V.remove_from_client() V.Remove(V.owner) generated_actions = list() @@ -318,7 +320,16 @@ SUBSYSTEM_DEF(vote) /datum/action/vote/Trigger() if(owner) owner.vote() + remove_from_client() Remove(owner) /datum/action/vote/IsAvailable() return 1 + +/datum/action/vote/proc/remove_from_client() + if(owner.client) + owner.client.player_details.player_actions -= src + else if(owner.ckey) + var/datum/player_details/P = GLOB.player_details[owner.ckey] + if(P) + P.player_actions -= src \ No newline at end of file diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 8d86507271..c12a08a792 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -373,32 +373,9 @@ ion = list() /datum/ai_laws/proc/show_laws(who) - - if (devillaws && devillaws.len) //Yes, devil laws go in FRONT of zeroth laws, as the devil must still obey it's ban/obligation. - for(var/i in devillaws) - to_chat(who, "666. [i]") - - if (zeroth) - to_chat(who, "0. [zeroth]") - - for (var/index = 1, index <= ion.len, index++) - var/law = ion[index] - var/num = ionnum() - to_chat(who, "[num]. [law]") - - var/number = 1 - for (var/index = 1, index <= inherent.len, index++) - var/law = inherent[index] - - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ - - for (var/index = 1, index <= supplied.len, index++) - var/law = supplied[index] - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ + var/list/printable_laws = get_law_list(include_zeroth = TRUE) + for(var/law in printable_laws) + to_chat(who,law) /datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 if(force) diff --git a/code/datums/antagonists/abductor.dm b/code/datums/antagonists/abductor.dm index 8d13c48e7c..3b8935d9fa 100644 --- a/code/datums/antagonists/abductor.dm +++ b/code/datums/antagonists/abductor.dm @@ -1,5 +1,6 @@ /datum/antagonist/abductor name = "Abductor" + roundend_category = "abductors" job_rank = ROLE_ABDUCTOR var/datum/objective_team/abductor_team/team var/sub_role @@ -70,3 +71,65 @@ var/mob/living/carbon/human/H = owner.current var/datum/species/abductor/A = H.dna.species A.scientist = TRUE + + +/datum/objective_team/abductor_team + member_name = "abductor" + var/team_number + var/list/datum/mind/abductees = list() + +/datum/objective_team/abductor_team/is_solo() + return FALSE + +/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) + O.team = src + O.update_explanation_text() + objectives += O + +/datum/objective_team/abductor_team/roundend_report() + var/list/result = list() + + var/won = TRUE + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + won = FALSE + if(won) + result += "[name] team fulfilled its mission!" + else + result += "[name] team failed its mission." + + result += "The abductors of [name] were:" + for(var/datum/mind/abductor_mind in members) + result += printplayer(abductor_mind) + result += printobjectives(abductor_mind) + + return result.Join("
") + + +/datum/antagonist/abductee + name = "Abductee" + roundend_category = "abductees" + +/datum/antagonist/abductee/on_gain() + give_objective() + . = ..() + +/datum/antagonist/abductee/greet() + to_chat(owner, "Your mind snaps!") + to_chat(owner, "You can't remember how you got here...") + owner.announce_objectives() + +/datum/antagonist/abductee/proc/give_objective() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + H.gain_trauma_type(BRAIN_TRAUMA_MILD) + var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) + var/datum/objective/abductee/O = new objtype() + objectives += O + owner.objectives += objectives + +/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner) + +/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_removed(mob_override ? mob_override.mind : owner) \ No newline at end of file diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 0a7b2aa22f..6b5a573eff 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -2,6 +2,8 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist var/name = "Antagonist" + var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section + var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report var/datum/mind/owner //Mind that owns this datum var/silent = FALSE //Silent will prevent the gain/lose texts to show var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum @@ -9,6 +11,7 @@ GLOBAL_LIST_EMPTY(antagonists) var/delete_on_mind_deletion = TRUE var/job_rank var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. + var/list/objectives = list() /datum/antagonist/New(datum/mind/new_owner) GLOB.antagonists += src @@ -96,9 +99,62 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/get_team() return +//Individual roundend report +/datum/antagonist/proc/roundend_report() + var/list/report = list() + + if(!owner) + CRASH("antagonist datum without owner") + + report += printplayer(owner) + + var/objectives_complete = TRUE + if(owner.objectives.len) + report += printobjectives(owner) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(owner.objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +//Displayed at the start of roundend_category section, default to roundend_category header +/datum/antagonist/proc/roundend_report_header() + return "The [roundend_category] were:
" + +//Displayed at the end of roundend_category section +/datum/antagonist/proc/roundend_report_footer() + return + //Should probably be on ticker or job ss ? /proc/get_antagonists(antag_type,specific = FALSE) . = list() for(var/datum/antagonist/A in GLOB.antagonists) if(!specific && istype(A,antag_type) || specific && A.type == antag_type) - . += A.owner \ No newline at end of file + . += A.owner + + + +//This datum will autofill the name with special_role +//Used as placeholder for minor antagonists, please create proper datums for these +/datum/antagonist/auto_custom + +/datum/antagonist/auto_custom/on_gain() + ..() + name = owner.special_role + //Add all objectives not already owned by other datums to this one. + var/list/already_registered_objectives = list() + for(var/datum/antagonist/A in owner.antag_datums) + if(A == src) + continue + else + already_registered_objectives |= A.objectives + objectives = owner.objectives - already_registered_objectives + +//This one is created by admin tools for custom objectives +/datum/antagonist/custom \ No newline at end of file diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm index 6458e6da09..dd3bdef9d2 100644 --- a/code/datums/antagonists/brother.dm +++ b/code/datums/antagonists/brother.dm @@ -55,3 +55,71 @@ /datum/antagonist/brother/proc/finalize_brother() SSticker.mode.update_brother_icons_added(owner) + + +/datum/objective_team/brother_team + name = "brotherhood" + member_name = "blood brother" + var/meeting_area + +/datum/objective_team/brother_team/is_solo() + return FALSE + +/datum/objective_team/brother_team/proc/update_name() + var/list/last_names = list() + for(var/datum/mind/M in members) + var/list/split_name = splittext(M.name," ") + last_names += split_name[split_name.len] + + name = last_names.Join(" & ") + +/datum/objective_team/brother_team/roundend_report() + var/list/parts = list() + + parts += "The blood brothers of [name] were:" + for(var/datum/mind/M in members) + parts += printplayer(M) + var/win = TRUE + var/objective_count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[objective_count]: [objective.explanation_text] Success!" + else + parts += "Objective #[objective_count]: [objective.explanation_text] Fail." + win = FALSE + objective_count++ + if(win) + parts += "The blood brothers were successful!" + else + parts += "The blood brothers have failed!" + + return "
[parts.Join("
")]
" + +/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) + O.team = src + if(needs_target) + O.find_target() + O.update_explanation_text() + objectives += O + +/datum/objective_team/brother_team/proc/forge_brother_objectives() + objectives = list() + var/is_hijacker = prob(10) + for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) + forge_single_objective() + if(is_hijacker) + if(!locate(/datum/objective/hijack) in objectives) + add_objective(new/datum/objective/hijack) + else if(!locate(/datum/objective/escape) in objectives) + add_objective(new/datum/objective/escape) + +/datum/objective_team/brother_team/proc/forge_single_objective() + if(prob(50)) + if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) + add_objective(new/datum/objective/destroy, TRUE) + else if(prob(30)) + add_objective(new/datum/objective/maroon, TRUE) + else + add_objective(new/datum/objective/assassinate, TRUE) + else + add_objective(new/datum/objective/steal, TRUE) \ No newline at end of file diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm index e98bfed782..4f8af2dc8a 100644 --- a/code/datums/antagonists/changeling.dm +++ b/code/datums/antagonists/changeling.dm @@ -4,11 +4,11 @@ /datum/antagonist/changeling name = "Changeling" + roundend_category = "changelings" job_rank = ROLE_CHANGELING var/you_are_greet = TRUE var/give_objectives = TRUE - var/list/objectives = list() var/team_mode = FALSE //Should assign team objectives ? //Changeling Stuff @@ -478,4 +478,35 @@ /datum/antagonist/changeling/xenobio name = "Xenobio Changeling" give_objectives = FALSE + show_in_roundend = FALSE //These are here for admin tracking purposes only you_are_greet = FALSE + +/datum/antagonist/changeling/roundend_report() + var/list/parts = list() + + var/changelingwin = 1 + if(!owner.current) + changelingwin = 0 + + parts += printplayer(owner) + + //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. + parts += "Changeling ID: [changelingID]." + parts += "Genomes Extracted: [absorbedcount]" + parts += " " + if(objectives.len) + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!
" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + changelingwin = 0 + count++ + + if(changelingwin) + parts += "The changeling was successful!" + else + parts += "The changeling has failed." + + return parts.Join("
") \ No newline at end of file diff --git a/code/datums/antagonists/clockcult.dm b/code/datums/antagonists/clockcult.dm index 8cc1c9e9a7..5f99ccc5dd 100644 --- a/code/datums/antagonists/clockcult.dm +++ b/code/datums/antagonists/clockcult.dm @@ -1,8 +1,11 @@ //CLOCKCULT PROOF OF CONCEPT /datum/antagonist/clockcult name = "Clock Cultist" - var/datum/action/innate/hierophant/hierophant_network = new() + roundend_category = "clock cultists" job_rank = ROLE_SERVANT_OF_RATVAR + var/datum/action/innate/hierophant/hierophant_network = new() + var/datum/objective_team/clockcult/clock_team + var/make_team = TRUE //This should be only false for tutorial scarabs /datum/antagonist/clockcult/silent silent = TRUE @@ -11,6 +14,22 @@ qdel(hierophant_network) return ..() +/datum/antagonist/clockcult/get_team() + return clock_team + +/datum/antagonist/clockcult/create_team(datum/objective_team/clockcult/new_team) + if(!new_team && make_team) + //TODO blah blah same as the others, allow multiple + for(var/datum/antagonist/clockcult/H in GLOB.antagonists) + if(H.clock_team) + clock_team = H.clock_team + return + clock_team = new /datum/objective_team/clockcult + return + if(make_team && !istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + clock_team = new_team + /datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -164,3 +183,35 @@ if(iscyborg(owner.current)) to_chat(owner.current, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.") . = ..() + + +/datum/objective_team/clockcult + name = "Clockcult" + var/list/objective + var/datum/mind/eminence + +/datum/objective_team/clockcult/proc/check_clockwork_victory() + if(GLOB.clockwork_gateway_activated) + return TRUE + return FALSE + +/datum/objective_team/clockcult/roundend_report() + var/list/parts = list() + + if(check_clockwork_victory()) + parts += "Ratvar's servants defended the Ark until its activation!" + else + parts += "The Ark was destroyed! Ratvar will rust away for all eternity!" + parts += " " + parts += "The servants' objective was: [CLOCKCULT_OBJECTIVE]." + parts += "Construction Value(CV) was: [GLOB.clockwork_construction_value]" + for(var/i in SSticker.scripture_states) + if(i != SCRIPTURE_DRIVER) + parts += "[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" + if(eminence) + parts += "The Eminence was: [printplayer(eminence)]" + if(members.len) + parts += "Ratvar's servants were:" + parts += printplayerlist(members - eminence) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm index c26b0f8108..bce9123fb3 100644 --- a/code/datums/antagonists/cult.dm +++ b/code/datums/antagonists/cult.dm @@ -2,84 +2,103 @@ /datum/antagonist/cult name = "Cultist" + roundend_category = "cultists" var/datum/action/innate/cult/comm/communion = new var/datum/action/innate/cult/mastervote/vote = new job_rank = ROLE_CULTIST var/ignore_implant = FALSE + var/give_equipment = FALSE + + var/datum/objective_team/cult/cult_team + +/datum/antagonist/cult/get_team() + return cult_team + +/datum/antagonist/cult/create_team(datum/objective_team/cult/new_team) + if(!new_team) + //todo remove this and allow admin buttons to create more than one cult + for(var/datum/antagonist/cult/H in GLOB.antagonists) + if(H.cult_team) + cult_team = H.cult_team + return + cult_team = new /datum/objective_team/cult + cult_team.setup_objectives() + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + cult_team = new_team + +/datum/antagonist/cult/proc/add_objectives() + objectives |= cult_team.objectives + owner.objectives |= objectives + +/datum/antagonist/cult/proc/remove_objectives() + owner.objectives -= objectives /datum/antagonist/cult/Destroy() QDEL_NULL(communion) QDEL_NULL(vote) return ..() -/datum/antagonist/cult/proc/add_objectives() - var/list/target_candidates = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - GLOB.sac_mind = pick(target_candidates) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - GLOB.sac_complete = TRUE - SSticker.mode.cult_objectives += "sacrifice" - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - SSticker.mode.cult_objectives += "eldergod" - -/datum/antagonist/cult/proc/cult_memorization(datum/mind/cult_mind) - var/mob/living/current = cult_mind.current - for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++) - var/explanation - switch(SSticker.mode.cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." - else - explanation = "The veil has already been weakened here, proceed to the final objective." - GLOB.sac_complete = TRUE - if("eldergod") - explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(GLOB.summon_spots)] - where the veil is weak enough for the ritual to begin." - if(!silent) - to_chat(current, "Objective #[obj_count]: [explanation]") - cult_mind.memory += "Objective #[obj_count]: [explanation]
" - /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() if(. && !ignore_implant) - . = is_convertable_to_cult(new_owner.current) + . = is_convertable_to_cult(new_owner.current,cult_team) + +/datum/antagonist/cult/greet() + to_chat(owner, "You are a member of the cult!") + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change + owner.announce_objectives() /datum/antagonist/cult/on_gain() . = ..() var/mob/living/current = owner.current - if(!LAZYLEN(SSticker.mode.cult_objectives)) - add_objectives() + add_objectives() + if(give_equipment) + equip_cultist() SSticker.mode.cult += owner // Only add after they've been given objectives - cult_memorization(owner) SSticker.mode.update_cult_icons_added(owner) current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && current.client) - current.client.images += GLOB.blood_target_image + + if(cult_team.blood_target && cult_team.blood_target_image && current.client) + current.client.images += cult_team.blood_target_image + + +/datum/antagonist/cult/proc/equip_cultist(tome=FALSE) + var/mob/living/carbon/H = owner.current + if(!istype(H)) + return + if (owner.assigned_role == "Clown") + to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + H.dna.remove_mutation(CLOWNMUT) + + if(tome) + . += cult_give_item(/obj/item/tome, H) + else + . += cult_give_item(/obj/item/paper/talisman/supply, H) + to_chat(owner, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") + + +/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) + var/list/slots = list( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store + ) + + var/T = new item_path(mob) + var/item_name = initial(item_path.name) + var/where = mob.equip_in_one_of_slots(T, slots) + if(!where) + to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") + return 0 + else + to_chat(mob, "You have a [item_name] in your [where].") + if(where == "backpack") + var/obj/item/storage/B = mob.back + B.orient2hud(mob) + B.show_to(mob) + return 1 /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() @@ -89,7 +108,7 @@ current.faction |= "cult" current.grant_language(/datum/language/narsie) current.verbs += /mob/living/proc/cult_help - if(!GLOB.cult_mastered) + if(!cult_team.cult_mastered) vote.Grant(current) communion.Grant(current) current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) @@ -107,6 +126,7 @@ current.clear_alert("bloodsense") /datum/antagonist/cult/on_removal() + remove_objectives() owner.wipe_memory() SSticker.mode.cult -= owner SSticker.mode.update_cult_icons_removed(owner) @@ -114,8 +134,8 @@ owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!", ignored_mob = owner.current) to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && owner.current.client) - owner.current.client.images -= GLOB.blood_target_image + if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) + owner.current.client.images -= cult_team.blood_target_image . = ..() /datum/antagonist/cult/master @@ -145,7 +165,7 @@ var/mob/living/current = owner.current if(mob_override) current = mob_override - if(!GLOB.reckoning_complete) + if(!cult_team.reckoning_complete) reckoning.Grant(current) bloodmark.Grant(current) throwing.Grant(current) @@ -162,3 +182,118 @@ throwing.Remove(current) current.update_action_buttons_icon() current.remove_status_effect(/datum/status_effect/cult_master) + +/datum/objective_team/cult + name = "Cult" + + var/blood_target + var/image/blood_target_image + var/blood_target_reset_timer + + var/cult_vote_called = FALSE + var/cult_mastered = FALSE + var/reckoning_complete = FALSE + + +/datum/objective_team/cult/proc/setup_objectives() + //SAC OBJECTIVE , todo: move this to objective internals + var/list/target_candidates = list() + var/datum/objective/sacrifice/sac_objective = new + sac_objective.team = src + + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && player.stat != DEAD) + target_candidates += player.mind + + if(target_candidates.len == 0) + message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && player.stat != DEAD) + target_candidates += player.mind + listclearnulls(target_candidates) + if(LAZYLEN(target_candidates)) + sac_objective.target = pick(target_candidates) + sac_objective.update_explanation_text() + + var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) + var/datum/preferences/sacface = sac_objective.target.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) + sac_objective.sac_image = reshape + + objectives += sac_objective + else + message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") + + + //SUMMON OBJECTIVE + + var/datum/objective/eldergod/summon_objective = new() + summon_objective.team = src + objectives += summon_objective + +/datum/objective/sacrifice + var/sacced = FALSE + var/sac_image + +/datum/objective/sacrifice/check_completion() + return sacced || completed + +/datum/objective/sacrifice/update_explanation_text() + if(target && !sacced) + explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." + else + explanation_text = "The veil has already been weakened here, proceed to the final objective." + +/datum/objective/eldergod + var/summoned = FALSE + var/list/summon_spots = list() + +/datum/objective/eldergod/New() + ..() + var/sanity = 0 + while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100) + var/area/summon = pick(GLOB.sortedAreas - summon_spots) + if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) + summon_spots += summon + sanity++ + update_explanation_text() + +/datum/objective/eldergod/update_explanation_text() + explanation_text = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin." + +/datum/objective/eldergod/check_completion() + return summoned || completed + +/datum/objective_team/cult/proc/check_cult_victory() + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + return FALSE + return TRUE + +/datum/objective_team/cult/roundend_report() + var/list/parts = list() + + if(check_cult_victory()) + parts += "The cult has succeeded! Nar-sie has snuffed out another torch in the void!" + else + parts += "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!" + + if(objectives.len) + parts += "The cultists' objectives were:" + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + + if(members.len) + parts += "The cultists were:" + parts += printplayerlist(members) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index d386c79c25..3ccdc7ddfb 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -1,5 +1,6 @@ /datum/antagonist/traitor name = "Traitor" + roundend_category = "traitors" job_rank = ROLE_TRAITOR var/should_specialise = FALSE //do we split into AI and human, set to true on inital assignment only var/ai_datum = ANTAG_DATUM_TRAITOR_AI @@ -8,7 +9,6 @@ var/employer = "The Syndicate" var/give_objectives = TRUE var/should_give_codewords = TRUE - var/list/objectives_given = list() /datum/antagonist/traitor/human var/should_equip = TRUE @@ -52,9 +52,9 @@ if(should_specialise) return ..()//we never did any of this anyway SSticker.mode.traitors -= owner - for(var/O in objectives_given) + for(var/O in objectives) owner.objectives -= O - objectives_given = list() + objectives = list() if(!silent && owner.current) to_chat(owner.current," You are no longer the [special_role]! ") owner.special_role = null @@ -71,11 +71,11 @@ /datum/antagonist/traitor/proc/add_objective(var/datum/objective/O) owner.objectives += O - objectives_given += O + objectives += O /datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O) owner.objectives -= O - objectives_given -= O + objectives -= O /datum/antagonist/traitor/proc/forge_traitor_objectives() return @@ -294,3 +294,53 @@ where = "In your [equipped_slot]" to_chat(mob, "

[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
") +//TODO Collate +/datum/antagonist/traitor/roundend_report() + var/list/result = list() + + var/traitorwin = TRUE + + result += printplayer(owner) + + var/TC_uses = 0 + var/uplink_true = FALSE + var/purchases = "" + for(var/datum/component/uplink/H in GLOB.uplinks) + if(H && H.owner && H.owner == owner.key) + TC_uses += H.spent_telecrystals + uplink_true = TRUE + purchases += H.purchase_log.generate_render(FALSE) + + var/objectives_text = "" + if(objectives.len)//If the traitor had no objectives, don't need to process this. + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + objectives_text += "
Objective #[count]: [objective.explanation_text] Success!" + else + objectives_text += "
Objective #[count]: [objective.explanation_text] Fail." + traitorwin = FALSE + count++ + + if(uplink_true) + var/uplink_text = "(used [TC_uses] TC) [purchases]" + if(TC_uses==0 && traitorwin) + var/static/icon/badass = icon('icons/badass.dmi', "badass") + uplink_text += "[icon2html(badass, world)]" + result += uplink_text + + result += objectives_text + + var/special_role_text = lowertext(name) + + if(traitorwin) + result += "The [special_role_text] was successful!" + else + result += "The [special_role_text] has failed!" + SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg') + + return result.Join("
") + +/datum/antagonist/traitor/roundend_report_footer() + return "
The code phrases were: [GLOB.syndicate_code_phrase]
\ + The code responses were: [GLOB.syndicate_code_response]
" \ No newline at end of file diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index 416a8f3752..97e0d8c18a 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -86,6 +86,7 @@ GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) /datum/antagonist/devil name = "Devil" + roundend_category = "devils" job_rank = ROLE_DEVIL //Don't delete upon mind destruction, otherwise soul re-selling will break. delete_on_mind_deletion = FALSE @@ -508,6 +509,35 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", owner.RemoveSpell(S) .=..() +/datum/antagonist/devil/proc/printdevilinfo() + var/list/parts = list() + parts += "The devil's true name is: [truename]" + parts += "The devil's bans were:" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]" + return parts.Join("
") + +/datum/antagonist/devil/roundend_report() + var/list/parts = list() + parts += printplayer(owner) + parts += printdevilinfo() + parts += printobjectives(owner) + return parts.Join("
") + +/datum/antagonist/devil/roundend_report_footer() + //sintouched go here for now as a hack , TODO proper antag datum for these + var/list/parts = list() + if(SSticker.mode.sintouched.len) + parts += "The sintouched were:" + var/list/sintouchedUnique = uniqueList(SSticker.mode.sintouched) + for(var/S in sintouchedUnique) + var/datum/mind/sintouched_mind = S + parts += printplayer(sintouched_mind) + parts += printobjectives(sintouched_mind) + return parts.Join("
") + //A simple super light weight datum for the codex gigas. /datum/fakeDevil var/truename diff --git a/code/datums/antagonists/ninja.dm b/code/datums/antagonists/ninja.dm index ab4822dd79..8201cd879d 100644 --- a/code/datums/antagonists/ninja.dm +++ b/code/datums/antagonists/ninja.dm @@ -37,19 +37,20 @@ else if(M.assigned_role in GLOB.command_positions) possible_targets[M] = 1 //good-guy - var/list/objectives = list(1,2,3,4) - while(owner.objectives.len < quantity) - switch(pick_n_take(objectives)) + var/list/possible_objectives = list(1,2,3,4) + + while(objectives.len < quantity) + switch(pick_n_take(possible_objectives)) if(1) //research var/datum/objective/download/O = new /datum/objective/download() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O if(2) //steal var/datum/objective/steal/special/O = new /datum/objective/steal/special() O.owner = owner - owner.objectives += O + objectives += O if(3) //protect/kill if(!possible_targets.len) continue @@ -63,13 +64,13 @@ O.owner = owner O.target = M O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - owner.objectives += O + objectives += O else //protect var/datum/objective/protect/O = new /datum/objective/protect() O.owner = owner O.target = M O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - owner.objectives += O + objectives += O if(4) //debrain/capture if(!possible_targets.len) continue var/selected = rand(1,possible_targets.len) @@ -82,17 +83,17 @@ O.owner = owner O.target = M O.explanation_text = "Steal the brain of [M.current.real_name]." - owner.objectives += O + objectives += O else //capture var/datum/objective/capture/O = new /datum/objective/capture() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O else break var/datum/objective/O = new /datum/objective/survive() O.owner = owner - owner.objectives += O + owner.objectives |= objectives /proc/remove_ninja(mob/living/L) diff --git a/code/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm new file mode 100644 index 0000000000..d0f24e7d7b --- /dev/null +++ b/code/datums/antagonists/nukeop.dm @@ -0,0 +1,322 @@ +#define NUKE_RESULT_FLUKE 0 +#define NUKE_RESULT_NUKE_WIN 1 +#define NUKE_RESULT_CREW_WIN 2 +#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 +#define NUKE_RESULT_DISK_LOST 4 +#define NUKE_RESULT_DISK_STOLEN 5 +#define NUKE_RESULT_NOSURVIVORS 6 +#define NUKE_RESULT_WRONG_STATION 7 +#define NUKE_RESULT_WRONG_STATION_DEAD 8 + +/datum/antagonist/nukeop + name = "Nuclear Operative" + roundend_category = "syndicate operatives" //just in case + job_rank = ROLE_OPERATIVE + var/datum/objective_team/nuclear/nuke_team + var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/nukeop_outfit = /datum/outfit/syndicate + +/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(M) + set_antag_hud(M, "synd") + +/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_added(M) + +/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_removed(M) + +/datum/antagonist/nukeop/proc/equip_op() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/H = owner.current + + H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + H.equipOutfit(nukeop_outfit) + return TRUE + +/datum/antagonist/nukeop/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") + owner.announce_objectives() + return + +/datum/antagonist/nukeop/on_gain() + give_alias() + forge_objectives() + . = ..() + equip_op() + memorize_code() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/nukeop/get_team() + return nuke_team + +/datum/antagonist/nukeop/proc/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Syndicate nuke not found during nuke team creation.") + nuke_team.memorized_code = null + +/datum/antagonist/nukeop/proc/give_alias() + if(nuke_team && nuke_team.syndicate_name) + var/number = 1 + number = nuke_team.members.Find(owner) + owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" + +/datum/antagonist/nukeop/proc/memorize_code() + if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) + owner.store_memory("[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]", 0, 0) + to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") + else + to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") + +/datum/antagonist/nukeop/proc/forge_objectives() + if(nuke_team) + owner.objectives |= nuke_team.objectives + +/datum/antagonist/nukeop/proc/move_to_spawnpoint() + var/team_number = 1 + if(nuke_team) + team_number = nuke_team.members.Find(owner) + owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) + +/datum/antagonist/nukeop/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.nukeop_leader_start)) + +/datum/antagonist/nukeop/create_team(datum/objective_team/nuclear/new_team) + if(!new_team) + if(!always_new_team) + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) + if(N.nuke_team) + nuke_team = N.nuke_team + return + nuke_team = new /datum/objective_team/nuclear + nuke_team.update_objectives() + assign_nuke() //This is bit ugly + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + nuke_team = new_team + +/datum/antagonist/nukeop/leader + name = "Nuclear Operative Leader" + nukeop_outfit = /datum/outfit/syndicate/leader + always_new_team = TRUE + var/title + +/datum/antagonist/nukeop/leader/memorize_code() + ..() + if(nuke_team && nuke_team.memorized_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + P.forceMove(get_turf(H)) + else + H.put_in_hands(P, TRUE) + H.update_icons() + +/datum/antagonist/nukeop/leader/give_alias() + title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + if(nuke_team && nuke_team.syndicate_name) + owner.current.real_name = "[nuke_team.syndicate_name] [title]" + else + owner.current.real_name = "Syndicate [title]" + +/datum/antagonist/nukeop/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) + + +/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() + if(!nuke_team) + return + nuke_team.rename_team(ask_name()) + +/datum/objective_team/nuclear/proc/rename_team(new_name) + syndicate_name = new_name + name = "[syndicate_name] Team" + for(var/I in members) + var/datum/mind/synd_mind = I + var/mob/living/carbon/human/H = synd_mind.current + if(!istype(H)) + continue + var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) + H.fully_replace_character_name(H.real_name,chosen_name) + +/datum/antagonist/nukeop/leader/proc/ask_name() + var/randomname = pick(GLOB.last_names) + var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) + if (!newname) + newname = randomname + else + newname = reject_bad_name(newname) + if(!newname) + newname = randomname + + return capitalize(newname) + +/datum/antagonist/nukeop/lone + name = "Lone Operative" + always_new_team = TRUE + send_to_spawnpoint = FALSE //Handled by event + nukeop_outfit = /datum/outfit/syndicate/full + +/datum/antagonist/nukeop/lone/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Station self destruct ot found during lone op team creation.") + nuke_team.memorized_code = null + +/datum/objective_team/nuclear + var/syndicate_name + var/obj/machinery/nuclearbomb/tracked_nuke + var/core_objective = /datum/objective/nuclear + var/memorized_code + +/datum/objective_team/nuclear/New() + ..() + syndicate_name = syndicate_name() + +/datum/objective_team/nuclear/proc/update_objectives() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + +/datum/objective_team/nuclear/proc/disk_rescued() + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/operatives_dead() + for(var/I in members) + var/datum/mind/operative_mind = I + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/syndies_escaped() + var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") + return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT)) + +/datum/objective_team/nuclear/proc/get_result() + var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME + var/disk_rescued = disk_rescued() + var/syndies_didnt_escape = !syndies_escaped() + var/station_was_nuked = SSticker.mode.station_was_nuked + var/nuke_off_station = SSticker.mode.nuke_off_station + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + return NUKE_RESULT_FLUKE + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + return NUKE_RESULT_NUKE_WIN + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + return NUKE_RESULT_NOSURVIVORS + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION_DEAD + else if ((disk_rescued || evacuation) && operatives_dead()) + return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD + else if (disk_rescued) + return NUKE_RESULT_CREW_WIN + else if (!disk_rescued && operatives_dead()) + return NUKE_RESULT_DISK_LOST + else if (!disk_rescued && evacuation) + return NUKE_RESULT_DISK_STOLEN + else + return //Undefined result + +/datum/objective_team/nuclear/roundend_report() + var/list/parts = list() + parts += "[syndicate_name] Operatives:" + + switch(get_result()) + if(NUKE_RESULT_FLUKE) + parts += "Humiliating Syndicate Defeat" + parts += "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!" + if(NUKE_RESULT_NUKE_WIN) + parts += "Syndicate Major Victory!" + parts += "[syndicate_name] operatives have destroyed [station_name()]!" + if(NUKE_RESULT_NOSURVIVORS) + parts += "Total Annihilation" + parts += "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!" + if(NUKE_RESULT_WRONG_STATION) + parts += "Crew Minor Victory" + parts += "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!" + if(NUKE_RESULT_WRONG_STATION_DEAD) + parts += "[syndicate_name] operatives have earned Darwin Award!" + parts += "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!" + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + parts += "Crew Major Victory!" + parts += "The Research Staff has saved the disk and killed the [syndicate_name] Operatives" + if(NUKE_RESULT_CREW_WIN) + parts += "Crew Major Victory" + parts += "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_LOST) + parts += "Neutral Victory!" + parts += "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_STOLEN) + parts += "Syndicate Minor Victory!" + parts += "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!" + else + parts += "Neutral Victory" + parts += "Mission aborted!" + + var/text = "
The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/I in members) + var/datum/mind/syndicate = I + for(var/U in GLOB.uplinks) + var/datum/component/uplink/H = U + if(H.owner == syndicate.key) + TC_uses += H.spent_telecrystals + if(H.purchase_log) + purchases += H.purchase_log.generate_render(show_key = FALSE) + else + stack_trace("WARNING: Nuke Op uplink with no purchase_log Owner: [H.owner]") + text += printplayerlist(members) + text += "
" + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + + parts += text + + return "
[parts.Join("
")]
" diff --git a/code/datums/antagonists/pirate.dm b/code/datums/antagonists/pirate.dm index ad32e09151..e0ce38c1e4 100644 --- a/code/datums/antagonists/pirate.dm +++ b/code/datums/antagonists/pirate.dm @@ -1,6 +1,7 @@ /datum/antagonist/pirate name = "Space Pirate" job_rank = ROLE_TRAITOR + roundend_category = "space pirates" var/datum/objective_team/pirate/crew /datum/antagonist/pirate/greet() @@ -36,7 +37,6 @@ /datum/objective_team/pirate name = "Pirate crew" - var/list/objectives = list() /datum/objective_team/pirate/proc/forge_objectives() var/datum/objective/loot/getbooty = new() @@ -84,11 +84,11 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( loot_table[lootname] = count else loot_table[lootname] += count - var/text = "" + var/list/loot_texts = list() for(var/key in loot_table) var/amount = loot_table[key] - text += "[amount] [key][amount > 1 ? "s":""], " - return text + loot_texts += "[amount] [key][amount > 1 ? "s":""]" + return loot_texts.Join(", ") /datum/objective/loot/proc/get_loot_value() if(!storage_area) @@ -105,31 +105,26 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( return ..() || get_loot_value() >= target_value -//These need removal ASAP as everything is converted to datum antags. -/datum/game_mode/proc/auto_declare_completion_pirates() - var/list/datum/mind/pirates = get_antagonists(/datum/antagonist/pirate) - var/datum/objective_team/pirate/crew - var/text = "" - if(pirates.len) - text += "
Space Pirates were:" - for(var/datum/mind/M in pirates) - text += printplayer(M) - if(!crew) - var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate) - crew = P.crew - if(crew) - text += "
Loot stolen: " - var/datum/objective/loot/L = locate() in crew.objectives - text += L.loot_listing() - text += "
Total loot value : [L.get_loot_value()]/[L.target_value] credits" - var/all_dead = TRUE - for(var/datum/mind/M in crew.members) - if(considered_alive(M)) - all_dead = FALSE - break - if(L.check_completion() && !all_dead) - text += "
The pirate crew was successful!" - else - text += "
The pirate crew has failed." - to_chat(world, text) \ No newline at end of file +/datum/objective_team/pirate/roundend_report() + var/list/parts = list() + + parts += "Space Pirates were:" + + var/all_dead = TRUE + for(var/datum/mind/M in members) + if(considered_alive(M)) + all_dead = FALSE + parts += printplayerlist(members) + + parts += "Loot stolen: " + var/datum/objective/loot/L = locate() in objectives + parts += L.loot_listing() + parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits" + + if(L.check_completion() && !all_dead) + parts += "The pirate crew was successful!" + else + parts += "The pirate crew has failed." + + return parts.Join("
") \ No newline at end of file diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm index 9db86bdf08..14c6d1ab0e 100644 --- a/code/datums/antagonists/revolution.dm +++ b/code/datums/antagonists/revolution.dm @@ -3,6 +3,7 @@ /datum/antagonist/rev name = "Revolutionary" + roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen job_rank = ROLE_REV var/hud_type = "rev" var/datum/objective_team/revolution/rev_team @@ -184,7 +185,6 @@ /datum/objective_team/revolution name = "Revolution" - var/list/objectives = list() var/max_headrevs = 3 /datum/objective_team/revolution/proc/update_objectives(initial = FALSE) @@ -227,3 +227,56 @@ rev.promote() addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) + + +/datum/objective_team/revolution/roundend_report() + if(!members.len) + return + + var/list/result = list() + + result += "
" + + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors++ + if(survivor.mind) + if(is_revolutionary(survivor)) + num_revs++ + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" + + + var/list/targets = list() + var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) + var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) + if(headrevs.len) + var/list/headrev_part = list() + headrev_part += "The head revolutionaries were:" + headrev_part += printplayerlist(headrevs,TRUE) + result += headrev_part.Join("
") + + if(revs.len) + var/list/rev_part = list() + rev_part += "The revolutionaries were:" + rev_part += printplayerlist(revs,TRUE) + result += rev_part.Join("
") + + var/list/heads = SSjob.get_all_heads() + if(heads.len) + var/head_text = "The heads of staff were:" + head_text += "
    " + for(var/datum/mind/head in heads) + var/target = (head in targets) + head_text += "
  • " + if(target) + head_text += "Target" + head_text += "[printplayer(head, 1)]
  • " + head_text += "

" + result += head_text + + result += "
" + + return result.Join() \ No newline at end of file diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm index e1e6dc09c8..7f23215d6c 100644 --- a/code/datums/antagonists/wizard.dm +++ b/code/datums/antagonists/wizard.dm @@ -5,13 +5,13 @@ /datum/antagonist/wizard name = "Space Wizard" + roundend_category = "wizards/witches" job_rank = ROLE_WIZARD var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE var/hud_version = "wizard" var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices - var/list/objectives = list() //this should be base datum antag proc and list, todo make lazy var/move_to_lair = TRUE var/outfit_type = /datum/outfit/wizard var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ @@ -45,10 +45,12 @@ /datum/objective_team/wizard name = "wizard team" + var/datum/antagonist/wizard/master_wizard /datum/antagonist/wizard/proc/create_wiz_team() wiz_team = new(owner) wiz_team.name = "[owner.current.real_name] team" + wiz_team.master_wizard = src update_wiz_icons_added(owner.current) /datum/antagonist/wizard/proc/send_to_lair() @@ -283,4 +285,46 @@ var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders") new_objective.owner = owner owner.objectives += new_objective - objectives += new_objective \ No newline at end of file + objectives += new_objective + +//Solo wizard report +/datum/antagonist/wizard/roundend_report() + var/list/parts = list() + + parts += printplayer(owner) + + var/count = 1 + var/wizardwin = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + wizardwin = 0 + count++ + + if(wizardwin) + parts += "The wizard was successful!" + else + parts += "The wizard has failed!" + + if(owner.spell_list.len>0) + parts += "[owner.name] used the following spells: " + var/list/spell_names = list() + for(var/obj/effect/proc_holder/spell/S in owner.spell_list) + spell_names += S.name + parts += spell_names.Join(", ") + + return parts.Join("
") + +//Wizard with apprentices report +/datum/objective_team/wizard/roundend_report() + var/list/parts = list() + + parts += "Wizards/witches of [master_wizard.owner.name] team were:" + parts += master_wizard.roundend_report() + parts += " " + parts += "[master_wizard.owner.name] apprentices were:" + parts += printplayerlist(members - master_wizard.owner) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c0ab1dc015..14d619c917 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -185,12 +185,6 @@ objectives, uplinks, powers etc are all handled. */ -/datum/mind/proc/remove_objectives() - if(objectives.len) - for(var/datum/objective/O in objectives) - objectives -= O - qdel(O) - /datum/mind/proc/remove_changeling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(C) @@ -223,7 +217,6 @@ if(src in SSticker.mode.cult) SSticker.mode.remove_cultist(src, 0, 0) special_role = null - remove_objectives() remove_antag_equip() /datum/mind/proc/remove_rev() @@ -769,17 +762,44 @@ var/objective_pos var/def_value + + + var/datum/antagonist/target_antag + if (href_list["obj_edit"]) objective = locate(href_list["obj_edit"]) if (!objective) return - objective_pos = objectives.Find(objective) + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + target_antag = A + objective_pos = A.objectives.Find(objective) + break + + if(!target_antag) //Shouldn't happen + stack_trace("objective without antagonist found") + objective_pos = objectives.Find(objective) //Text strings are easy to manipulate. Revised for simplicity. var/temp_obj_type = "[objective.type]"//Convert path into a text string. def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword. if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" + else + switch(antag_datums.len) + if(0) + target_antag = add_antag_datum(/datum/antagonist/custom) + if(1) + target_antag = antag_datums[1] + else + var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)" + if (QDELETED(target)) + return + else if(target == "(new custom antag)") + target_antag = add_antag_datum(/datum/antagonist/custom) + else + target_antag = target var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "late-assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom") if (!new_obj_type) @@ -901,11 +921,15 @@ return if (objective) + if(target_antag) + target_antag.objectives -= objective objectives -= objective - objectives.Insert(objective_pos, new_objective) + target_antag.objectives.Insert(objective_pos, new_objective) message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") else + if(target_antag) + target_antag.objectives += new_objective objectives += new_objective message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]") log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]") @@ -914,6 +938,11 @@ var/datum/objective/objective = locate(href_list["obj_delete"]) if(!istype(objective)) return + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + A.objectives -= objective + break objectives -= objective message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]") log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]") @@ -996,11 +1025,13 @@ message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") if("tome") - if (!SSticker.mode.equip_cultist(current,1)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current,1)) to_chat(usr, "Spawning tome failed!") if("amulet") - if (!SSticker.mode.equip_cultist(current)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current)) to_chat(usr, "Spawning amulet failed!") else if(href_list["clockcult"]) @@ -1407,16 +1438,11 @@ /datum/mind/proc/make_Cultist() - if(!(src in SSticker.mode.cult)) - SSticker.mode.add_cultist(src,FALSE) + if(!has_antag_datum(/datum/antagonist/cult,TRUE)) + SSticker.mode.add_cultist(src,FALSE,equip=TRUE) special_role = "Cultist" to_chat(current, "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar-Sie.") to_chat(current, "Assist your new bretheren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - var/datum/antagonist/cult/C - C.cult_memorization(src) - var/mob/living/carbon/human/H = current - if (!SSticker.mode.equip_cultist(current)) - to_chat(H, "Spawning an amulet from your Master failed.") /datum/mind/proc/make_Rev() var/datum/antagonist/rev/head/head = new(src) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 7456b8f5eb..d0ab4347ff 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -242,6 +242,7 @@ new_objective2.owner = S.mind new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]." S.mind.objectives += new_objective2 + S.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ Ctrl+Click a blood pool to manifest.") diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index c1af1601ce..34373da5c8 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -1,41 +1,3 @@ -/datum/objective_team/brother_team - name = "brotherhood" - member_name = "blood brother" - var/list/objectives = list() - var/meeting_area - -/datum/objective_team/brother_team/is_solo() - return FALSE - -/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) - O.team = src - if(needs_target) - O.find_target() - O.update_explanation_text() - objectives += O - -/datum/objective_team/brother_team/proc/forge_brother_objectives() - objectives = list() - var/is_hijacker = prob(10) - for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) - forge_single_objective() - if(is_hijacker) - if(!locate(/datum/objective/hijack) in objectives) - add_objective(new/datum/objective/hijack) - else if(!locate(/datum/objective/escape) in objectives) - add_objective(new/datum/objective/escape) - -/datum/objective_team/brother_team/proc/forge_single_objective() - if(prob(50)) - if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) - add_objective(new/datum/objective/destroy, TRUE) - else if(prob(30)) - add_objective(new/datum/objective/maroon, TRUE) - else - add_objective(new/datum/objective/assassinate, TRUE) - else - add_objective(new/datum/objective/steal, TRUE) - /datum/game_mode var/list/datum/mind/brothers = list() var/list/datum/objective_team/brother_team/brother_teams = list() @@ -54,6 +16,7 @@ var/list/datum/objective_team/brother_team/pre_brother_teams = list() var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 + traitors_required = FALSE //Only teams are possible var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library") @@ -92,12 +55,14 @@ team.forge_brother_objectives() for(var/datum/mind/M in team.members) M.add_antag_datum(ANTAG_DATUM_BROTHER, team) + team.update_name() brother_teams += pre_brother_teams return ..() /datum/game_mode/traitor/bros/generate_report() return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." +<<<<<<< HEAD /datum/game_mode/proc/auto_declare_completion_brother() if(!LAZYLEN(brother_teams)) return @@ -130,6 +95,8 @@ text += "
" to_chat(world, text) +======= +>>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] brotherhud.join_hud(brother_mind.current) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index a70f392d4f..6fc06f7bca 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -94,6 +94,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ as paranoia may spread and inhibit workplace efficiency." +<<<<<<< HEAD /datum/game_mode/proc/auto_declare_completion_changeling() var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention if(changelings.len) @@ -135,6 +136,8 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th return 1 +======= +>>>>>>> 3d81385... Roundend report refactor (#33246) /proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 61bd9bb496..778cf41022 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -65,13 +65,16 @@ Credit where due: return TRUE return FALSE -/proc/add_servant_of_ratvar(mob/L, silent = FALSE) +/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE) if(!L || !L.mind) return var/update_type = ANTAG_DATUM_CLOCKCULT if(silent) update_type = ANTAG_DATUM_CLOCKCULT_SILENT - . = L.mind.add_antag_datum(update_type) + var/datum/antagonist/clockcult/C = new update_type(L.mind) + C.make_team = create_team + C.show_in_roundend = create_team //tutorial scarabs begone + . = L.mind.add_antag_datum(C) /proc/remove_servant_of_ratvar(mob/L, silent = FALSE) if(!L || !L.mind) @@ -88,7 +91,6 @@ Credit where due: /////////////// /datum/game_mode - var/datum/mind/eminence //The clockwork Eminence var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar var/clockwork_explanation = "Defend the Ark of the Clockwork Justiciar and free Ratvar." //The description of the current objective @@ -110,6 +112,8 @@ Credit where due: var/servants_to_serve = list() var/roundstart_player_count var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.) + + var/datum/objective_team/clockcult/main_clockcult /datum/game_mode/clockwork_cult/pre_setup() if(CONFIG_GET(flag/protect_roles_from_antagonist)) @@ -191,16 +195,16 @@ Credit where due: . = ..() /datum/game_mode/clockwork_cult/proc/check_clockwork_victory() + return main_clockcult.check_clockwork_victory() + +/datum/game_mode/clock_cult/set_round_result() + ..() if(GLOB.clockwork_gateway_activated) SSticker.news_report = CLOCK_SUMMON - return TRUE + SSticker.mode_result = "win - servants completed their objective (summon ratvar)" else SSticker.news_report = CULT_FAILURE - return FALSE - -/datum/game_mode/clockwork_cult/declare_completion() - ..() - return //Doesn't end until the round does + SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" /datum/game_mode/clockwork_cult/generate_report() return "Bluespace monitors near your sector have detected a continuous stream of patterned fluctuations since the station was completed. It is most probable that a powerful entity \ @@ -210,30 +214,6 @@ Credit where due: working for this entity and utilizing highly-advanced technology to cross the great distance at will. If they should turn out to be a credible threat, the task falls on you and \ your crew to dispatch it in a timely manner." -/datum/game_mode/proc/auto_declare_completion_clockwork_cult() - var/text = "" - if(istype(SSticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky? - var/datum/game_mode/clockwork_cult/C = SSticker.mode - if(C.check_clockwork_victory()) - text += "Ratvar's servants defended the Ark until its activation!" - SSticker.mode_result = "win - servants completed their objective (summon ratvar)" - else - text += "The Ark was destroyed! Ratvar will rust away for all eternity!" - SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" - text += "
The servants' objective was: [CLOCKCULT_OBJECTIVE]." - text += "
Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches." - text += "
Construction Value(CV) was: [GLOB.clockwork_construction_value]" - for(var/i in SSticker.scripture_states) - if(i != SCRIPTURE_DRIVER) - text += "
[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" - if(SSticker.mode.eminence) - text += "
The Eminence was: [printplayer(SSticker.mode.eminence)]" - if(servants_of_ratvar.len) - text += "
Ratvar's servants were:" - for(var/datum/mind/M in servants_of_ratvar - SSticker.mode.eminence) - text += printplayer(M) - to_chat(world, text) - /datum/game_mode/proc/update_servant_icons_added(datum/mind/M) var/datum/atom_hud/antag/A = GLOB.huds[ANTAG_HUD_CLOCKWORK] A.join_hud(M.current) diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm index acf6e43974..1b2b867aa5 100644 --- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm +++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm @@ -91,7 +91,8 @@ /obj/item/clockwork/construct_chassis/cogscarab/pre_spawn() if(infinite_resources) - construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar //During rounds where they can't interact with the station, let them experiment with builds + //During rounds where they can't interact with the station, let them experiment with builds + construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar /obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct) if(infinite_resources) //Allow them to build stuff and recite scripture diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm index cc91feeb98..8416e4651d 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm @@ -14,16 +14,6 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/static/superheated_walls = 0 -/mob/camera/eminence/Initialize() - if(SSticker.mode.eminence) - return INITIALIZE_HINT_QDEL - . = ..() - -/mob/camera/eminence/Destroy(force) - if(!force && mind && SSticker.mode.eminence == mind) - return QDEL_HINT_LETMELIVE - return ..() - /mob/camera/eminence/CanPass(atom/movable/mover, turf/target) return TRUE @@ -39,12 +29,20 @@ /mob/camera/eminence/Login() ..() - add_servant_of_ratvar(src, TRUE) + var/datum/antagonist/clockcult/C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(!C) + add_servant_of_ratvar(src, TRUE) + C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + if(C.clock_team.eminence) + remove_servant_of_ratvar(src,TRUE) + qdel(src) + else + C.clock_team.eminence = src to_chat(src, "You have been selected as the Eminence!") to_chat(src, "As the Eminence, you lead the servants. Anything you say will be heard by the entire cult.") to_chat(src, "Though you can move through walls, you're also incorporeal, and largely can't interact with the world except for a few ways.") to_chat(src, "Additionally, unless the herald's beacon is activated, you can't understand any speech while away from Reebe.") - SSticker.mode.eminence = mind eminence_help() for(var/V in actions) var/datum/action/A = V diff --git a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm index 8d4e936658..495bfaeaa8 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm @@ -17,7 +17,11 @@ return if(kingmaking) return - if(SSticker.mode.eminence) + + var/datum/antagonist/clockcult/C = user.mind.has_antag_datum(/datum/antagonist/clockcult) + if(!C || !C.clock_team) + return + if(C.clock_team.eminence) to_chat(user, "There's already an Eminence!") return if(!GLOB.servants_active) @@ -34,7 +38,9 @@ /obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user) if(!IsAdminGhost(user)) return - if(SSticker.mode.eminence) + + var/datum/antagonist/clockcult/random_cultist = locate() in GLOB.antagonists //if theres no cultists new team without eminence will be created anyway. + if(random_cultist && random_cultist.clock_team && random_cultist.clock_team.eminence) to_chat(user, "There's already an Eminence - too late!") return if(!GLOB.servants_active) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index f20dd25802..67e2225772 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,24 +2,23 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/cult_objectives = list() - var/eldergod = 1 //for the summon god objective /proc/iscultist(mob/living/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) -/proc/is_sacrifice_target(datum/mind/mind) - if(mind == GLOB.sac_mind) - return TRUE +/datum/objective_team/cult/proc/is_sacrifice_target(datum/mind/mind) + for(var/datum/objective/sacrifice/sac_objective in objectives) + if(mind == sac_objective.target) + return TRUE return FALSE - -/proc/is_convertable_to_cult(mob/living/M) + +/proc/is_convertable_to_cult(mob/living/M,datum/objective_team/cult/specific_cult) if(!istype(M)) return FALSE if(M.mind) if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) return FALSE - if(is_sacrifice_target(M.mind)) + if(specific_cult && specific_cult.is_sacrifice_target(M.mind)) return FALSE if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to)) return FALSE @@ -55,10 +54,10 @@ var/list/cultists_to_cult = list() //the cultists we'll convert + var/datum/objective_team/cult/main_cult + /datum/game_mode/cult/pre_setup() - cult_objectives += "sacrifice" - if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs @@ -86,82 +85,19 @@ /datum/game_mode/cult/post_setup() - if("sacrifice" in cult_objectives) - var/list/possible_targets = get_unconvertables() - if(!possible_targets.len) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !(player.mind in cultists_to_cult)) - possible_targets += player.mind - if(possible_targets.len > 0) - GLOB.sac_mind = pick(possible_targets) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if((summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - cult_objectives += "eldergod" - for(var/datum/mind/cult_mind in cultists_to_cult) - equip_cultist(cult_mind.current) - update_cult_icons_added(cult_mind) - to_chat(cult_mind.current, "You are a member of the cult!") - cult_mind.current.playsound_local(get_turf(cult_mind.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change - add_cultist(cult_mind, 0) + add_cultist(cult_mind, 0, equip=TRUE) ..() -/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob,tome = 0) - if(!istype(mob)) - return - if (mob.mind) - if (mob.mind.assigned_role == "Clown") - to_chat(mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - mob.dna.remove_mutation(CLOWNMUT) - if(tome) - . += cult_give_item(/obj/item/tome, mob) - else - . += cult_give_item(/obj/item/paper/talisman/supply, mob) - to_chat(mob, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") - -/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) - var/list/slots = list( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - - var/T = new item_path(mob) - var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) - if(!where) - to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") - return 0 - else - to_chat(mob, "You have a [item_name] in your [where].") - if(where == "backpack") - var/obj/item/storage/B = mob.back - B.orient2hud(mob) - B.show_to(mob) - return 1 - -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE +/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun , equip = FALSE) //BASE if (!istype(cult_mind)) return 0 - if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT)) + + var/datum/antagonist/cult/new_cultist = new(cult_mind) + new_cultist.give_equipment = equip + + if(cult_mind.add_antag_datum(new_cultist)) if(stun) cult_mind.current.Unconscious(100) return 1 @@ -187,25 +123,19 @@ culthud.leave_hud(cult_mind.current) set_antag_hud(cult_mind.current, null) -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !is_convertable_to_cult(player) && !(player.mind in cultists_to_cult)) - ucs += player.mind - return ucs - /datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(cult_objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(cult_objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(cult_objectives.Find("sacrifice")) - if(GLOB.sac_mind && !GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - return cult_fail //if any objectives aren't met, failure + return main_cult.check_cult_victory() +/datum/game_mode/cult/set_round_result() + ..() + if(check_cult_victory()) + SSticker.mode_result = "win - cult win" + SSticker.news_report = CULT_SUMMON + else + SSticker.mode_result = "loss - staff stopped the cult" + SSticker.news_report = CULT_FAILURE + /datum/game_mode/cult/proc/check_survive() var/acolytes_survived = 0 for(var/datum/mind/cult_mind in cult) @@ -218,57 +148,6 @@ return 1 -/datum/game_mode/cult/declare_completion() - - if(!check_cult_victory()) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - - var/text = "" - - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "SUCCESS")) - SSticker.news_report = CULT_ESCAPE - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "FAIL")) - SSticker.news_report = CULT_FAILURE - if("sacrifice") - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)].Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)]Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - - text += "
Objective #[obj_count]: [explanation]" - if(cult.len) - text += "
The cultists were:" - for(var/datum/mind/M in cult) - text += printplayer(M) - to_chat(world, text) - ..() - return 1 - /datum/game_mode/cult/generate_report() return "Some stations in your sector have reported evidence of blood sacrifice and strange magic. Ties to the Wizards' Federation have been proven not to exist, and many employees \ have disappeared; even Central Command employees light-years away have felt strange presences and at times hysterical compulsions. Interrogations point towards this being the work of \ @@ -276,41 +155,4 @@ devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will prevent conversion \ altogether." -/datum/game_mode/proc/datum_cult_completion() - var/text = "" - var/cult_fail = 0 - cult_fail += eldergod - if(!GLOB.sac_complete) - cult_fail++ - if(!cult_fail) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count in 1 to 2) - var/explanation - switch(cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - text += "
Objective #[obj_count]: [explanation]" - to_chat(world, text) - #undef CULT_SCALING_COEFFICIENT diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 530b6ebb20..2938f5abf4 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -88,19 +88,21 @@ button_icon_state = "cultvote" /datum/action/innate/cult/mastervote/IsAvailable() - if(GLOB.cult_vote_called || !ishuman(owner)) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C || C.cult_team.cult_vote_called || !ishuman(owner)) return FALSE return ..() /datum/action/innate/cult/mastervote/Activate() - pollCultists(owner) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + pollCultists(owner,C.cult_team) -/proc/pollCultists(var/mob/living/Nominee) //Cult Master Poll +/proc/pollCultists(var/mob/living/Nominee,datum/objective_team/cult/team) //Cult Master Poll if(world.time < CULT_POLL_WAIT) to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].") return - GLOB.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) @@ -108,39 +110,39 @@ to_chat(B.current, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") sleep(100) var/list/asked_cultists = list() - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current && B.current != Nominee && !B.current.incapacitated()) SEND_SOUND(B.current, 'sound/magic/exit_blood.ogg') asked_cultists += B.current var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 300, group = asked_cultists) if(QDELETED(Nominee) || Nominee.incapacitated()) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has died in the process of attempting to win the cult's support!") return FALSE if(!Nominee.mind) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has gone catatonic in the process of attempting to win the cult's support!") return FALSE if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") return FALSE - GLOB.cult_mastered = TRUE + team.cult_mastered = TRUE SSticker.mode.remove_cultist(Nominee.mind, TRUE) Nominee.mind.add_antag_datum(ANTAG_DATUM_CULT_MASTER) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current) for(var/datum/action/innate/cult/mastervote/vote in B.current.actions) vote.Remove(B.current) @@ -159,6 +161,9 @@ button_icon_state = "sintouch" /datum/action/innate/cult/master/finalreck/Activate() + var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return for(var/i in 1 to 4) chant(i) var/list/destinations = list() @@ -169,7 +174,7 @@ to_chat(owner, "You need more space to summon the cult!") return if(do_after(owner, 30, target = owner)) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in antag.cult_team.members) if(B.current && B.current.stat != DEAD) var/turf/mobloc = get_turf(B.current) switch(i) @@ -194,7 +199,7 @@ addtimer(CALLBACK(B.current, /mob/.proc/reckon, final), 10) else return - GLOB.reckoning_complete = TRUE + antag.cult_team.reckoning_complete = TRUE Remove(owner) /mob/proc/reckon(turf/final) @@ -269,34 +274,37 @@ var/turf/T = get_turf(ranged_ability_user) if(!isturf(T)) return FALSE + + var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(target in view(7, get_turf(ranged_ability_user))) - GLOB.blood_target = target + C.cult_team.blood_target = target var/area/A = get_area(target) attached_action.cooldown = world.time + attached_action.base_cooldown addtimer(CALLBACK(attached_action.owner, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown) - GLOB.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) - GLOB.blood_target_image.appearance_flags = RESET_COLOR - GLOB.blood_target_image.pixel_x = -target.pixel_x - GLOB.blood_target_image.pixel_y = -target.pixel_y + C.cult_team.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) + C.cult_team.blood_target_image.appearance_flags = RESET_COLOR + C.cult_team.blood_target_image.pixel_x = -target.pixel_x + C.cult_team.blood_target_image.pixel_y = -target.pixel_y for(var/datum/mind/B in SSticker.mode.cult) if(B.current && B.current.stat != DEAD && B.current.client) - to_chat(B.current, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!") + to_chat(B.current, "Master [ranged_ability_user] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!") SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - B.current.client.images += GLOB.blood_target_image + B.current.client.images += C.cult_team.blood_target_image attached_action.owner.update_action_buttons_icon() remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.") - GLOB.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target), 900, TIMER_STOPPABLE) + C.cult_team.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target,C.cult_team), 900, TIMER_STOPPABLE) return TRUE return FALSE -/proc/reset_blood_target() - for(var/datum/mind/B in SSticker.mode.cult) +/proc/reset_blood_target(datum/objective_team/cult/team) + for(var/datum/mind/B in team.members) if(B.current && B.current.stat != DEAD && B.current.client) - if(GLOB.blood_target) + if(team.blood_target) to_chat(B.current,"The blood mark has expired!") - B.current.client.images -= GLOB.blood_target_image - QDEL_NULL(GLOB.blood_target_image) - GLOB.blood_target = null + B.current.client.images -= team.blood_target_image + QDEL_NULL(team.blood_target_image) + team.blood_target = null diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2adaa57a2f..f0934b524f 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -179,6 +179,13 @@ This file contains the arcane tome files. var/list/shields = list() var/area/A = get_area(src) + var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!user_antag) + return + + var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives + var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team.objectives + if(!check_rune_turf(Turf, user)) return entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in GLOB.rune_types @@ -196,18 +203,20 @@ This file contains the arcane tome files. A = get_area(src) if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user)) return + + //AAAAAAAAAAAAAAAH, i'm rewriting enough for now so TODO: remove this shit if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) - if(!("eldergod" in SSticker.mode.cult_objectives)) + if(!summon_objective) to_chat(user, "Nar-Sie does not wish to be summoned!") return - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!") return - if(!SSticker.mode.eldergod) + if(summon_objective.check_completion()) to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") return - if(!(A in GLOB.summon_spots)) - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") if(confirm_final == "No") @@ -215,8 +224,8 @@ This file contains the arcane tome files. return Turf = get_turf(user) A = get_area(src) - if(!(A in GLOB.summon_spots)) // Check again to make sure they didn't move - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg') for(var/B in spiral_range_turfs(1, user, 1)) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index be1c2ccaff..1bab1d90f4 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -349,7 +349,11 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_DARKRED var/mob/living/L = pick(myriad_targets) var/is_clock = is_servant_of_ratvar(L) - var/is_convertable = is_convertable_to_cult(L) + + var/mob/living/F = invokers[1] + var/datum/antagonist/cult/C = F.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + + var/is_convertable = is_convertable_to_cult(L,C.cult_team) if(L.stat != DEAD && (is_clock || is_convertable)) invocation = "Mah'weyh pleggh at e'ntrath!" ..() @@ -397,17 +401,27 @@ structure_check() searches for nearby cultist structures required for the invoca return 1 /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) + var/mob/living/first_invoker = invokers[1] + if(!first_invoker) + return FALSE + var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C) + return + + var/big_sac = FALSE - if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) + if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") log_game("Offer rune failed - not enough acolytes and target is living or sac target") return FALSE if(sacrificial.mind) GLOB.sacrificed += sacrificial.mind - if(is_sacrifice_target(sacrificial.mind)) - GLOB.sac_complete = TRUE - big_sac = TRUE + for(var/datum/objective/sacrifice/sac_objective in C.cult_team.objectives) + if(sac_objective.target == sacrificial.mind) + sac_objective.sacced = TRUE + sac_objective.update_explanation_text() + big_sac = TRUE else GLOB.sacrificed += sacrificial @@ -481,7 +495,6 @@ structure_check() searches for nearby cultist structures required for the invoca sleep(40) if(src) color = RUNE_COLOR_RED - SSticker.mode.eldergod = FALSE new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn even if the rune has been removed /obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. diff --git a/code/game/gamemodes/devil/game_mode.dm b/code/game/gamemodes/devil/game_mode.dm index 957e261933..44f3368feb 100644 --- a/code/game/gamemodes/devil/game_mode.dm +++ b/code/game/gamemodes/devil/game_mode.dm @@ -3,32 +3,6 @@ var/list/datum/mind/devils = list() var/devil_ascended = 0 // Number of arch devils on station -/datum/game_mode/proc/auto_declare_completion_sintouched() - var/text = "" - if(sintouched.len) - text += "
The sintouched were:" - var/list/sintouchedUnique = uniqueList(sintouched) - for(var/S in sintouchedUnique) - var/datum/mind/sintouched_mind = S - text += printplayer(sintouched_mind) - text += printobjectives(sintouched_mind) - text += "
" - text += "
" - to_chat(world, text) - -/datum/game_mode/proc/auto_declare_completion_devils() - /var/text = "" - if(devils.len) - text += "
The devils were:" - for(var/D in devils) - var/datum/mind/devil = D - text += printplayer(devil) - text += printdevilinfo(devil.current) - text += printobjectives(devil) - text += "
" - text += "
" - to_chat(world, text) - /datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity) var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) for(var/i = 1 to quantity) @@ -41,18 +15,6 @@ else objective.find_target() -/datum/game_mode/proc/printdevilinfo(mob/living/ply) - var/datum/antagonist/devil/devilinfo = is_devil(ply) - if(!devilinfo) - return "Target is not a devil." - var/text = "
The devil's true name is: [devilinfo.truename]
" - text += "The devil's bans were:
" - text += " [GLOB.lawlorify[LORE][devilinfo.ban]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.bane]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.obligation]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.banish]]

" - return text - /datum/game_mode/proc/update_devil_icons_added(datum/mind/devil_mind) var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_DEVIL] hud.join_hud(devil_mind.current) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 803e73b9e0..0c6a8fd1e0 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -73,7 +73,6 @@ /datum/game_mode/proc/pre_setup() return 1 - ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) @@ -241,55 +240,9 @@ return 0 -/datum/game_mode/proc/declare_completion() - var/clients = 0 - var/surviving_humans = 0 - var/surviving_total = 0 - var/ghosts = 0 - var/escaped_humans = 0 - var/escaped_total = 0 - - for(var/mob/M in GLOB.player_list) - if(M.client) - clients++ - if(ishuman(M)) - if(!M.stat) - surviving_humans++ - if(M.z == ZLEVEL_CENTCOM) - escaped_humans++ - if(!M.stat) - surviving_total++ - if(M.z == ZLEVEL_CENTCOM) - escaped_total++ - - - if(isobserver(M)) - ghosts++ - - if(clients) - SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) - if(ghosts) - SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) - if(surviving_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) - if(surviving_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) - if(escaped_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) - if(escaped_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) - - send2irc("Server", "Round just ended.") - if(cult.len && !istype(SSticker.mode, /datum/game_mode/cult)) - datum_cult_completion() - - return 0 - - /datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. return 0 - /datum/game_mode/proc/send_intercept() var/intercepttext = "Central Command Status Summary
" intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ @@ -451,34 +404,6 @@ for (var/C in GLOB.admins) to_chat(C, msg) -/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) - var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and" - if(ply.current) - if(ply.current.stat == DEAD) - text += " died" - else - text += " survived" - if(fleecheck) - var/turf/T = get_turf(ply.current) - if(!T || !(T.z in GLOB.station_z_levels)) - text += " while fleeing the station" - if(ply.current.real_name != ply.name) - text += " as [ply.current.real_name]" - else - text += " had their body destroyed" - return text - -/datum/game_mode/proc/printobjectives(datum/mind/ply) - var/text = "" - var/count = 1 - for(var/datum/objective/objective in ply.objectives) - if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success!" - else - text += "
Objective #[count]: [objective.explanation_text] Fail." - count++ - return text - //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/game_mode/proc/age_check(client/C) if(get_remaining_days(C) == 0) @@ -518,11 +443,6 @@ station_goals += new picked -/datum/game_mode/proc/declare_station_goal_completion() - for(var/V in station_goals) - var/datum/station_goal/G = V - G.print_result() - /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." @@ -530,3 +450,20 @@ /datum/game_mode/proc/OnNukeExplosion(off_station) if(off_station < 2) station_was_nuked = TRUE //Will end the round on next check. +<<<<<<< HEAD +======= + +//Additional report section in roundend report +/datum/game_mode/proc/special_report() + return + +//Set result and news report here +/datum/game_mode/proc/set_round_result() + SSticker.mode_result = "undefined" + if(station_was_nuked) + SSticker.news_report = STATION_DESTROYED_NUKE + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + SSticker.news_report = STATION_EVACUATED + if(SSshuttle.emergency.is_hijacked()) + SSticker.news_report = SHUTTLE_HIJACK +>>>>>>> 3d81385... Roundend report refactor (#33246) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index b7a6580570..f8e0666015 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -30,30 +30,29 @@ spawn_meteors(ramp_up_final, wavetype) -/datum/game_mode/meteor/declare_completion() - var/text +/datum/game_mode/meteor/special_report() var/survivors = 0 + var/list/survivor_list = list() for(var/mob/living/player in GLOB.player_list) if(player.stat != DEAD) ++survivors if(player.onCentCom()) - text += "
[player.real_name] escaped to the safety of CentCom." + survivor_list += "[player.real_name] escaped to the safety of CentCom." else if(player.onSyndieBase()) - text += "
[player.real_name] escaped to the (relative) safety of Syndicate Space." + survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." else - text += "
[player.real_name] survived but is stranded without any hope of rescue." - + survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." if(survivors) - to_chat(world, "The following survived the meteor storm:[text]") + return "The following survived the meteor storm:
[survivor_list.Join("
")]" else - to_chat(world, "Nobody survived the meteor storm!") + return "Nobody survived the meteor storm!" - SSticker.mode_result = "end - evacuation" +/datum/game_mode/meteor/set_round_result() ..() - return 1 + SSticker.mode_result = "end - evacuation" /datum/game_mode/meteor/generate_report() return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 4eb8642c02..050cac443d 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -1,19 +1,5 @@ -/datum/objective_team/abductor_team - member_name = "abductor" - var/list/objectives = list() - var/team_number - -/datum/objective_team/abductor_team/is_solo() - return FALSE - -/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) - O.team = src - O.update_explanation_text() - objectives += O - /datum/game_mode var/list/datum/mind/abductors = list() - var/list/datum/mind/abductees = list() /datum/game_mode/abduction name = "abduction" @@ -99,35 +85,6 @@ return ..() return ..() -/datum/game_mode/abduction/declare_completion() - for(var/datum/objective_team/abductor_team/team in abductor_teams) - var/won = TRUE - for(var/datum/objective/O in team.objectives) - if(!O.check_completion()) - won = FALSE - if(won) - to_chat(world, "[team.name] team fulfilled its mission!") - else - to_chat(world, "[team.name] team failed its mission.") - ..() - return TRUE - -/datum/game_mode/proc/auto_declare_completion_abduction() - var/text = "" - if(abductors.len) - text += "
The abductors were:" - for(var/datum/mind/abductor_mind in abductors) - text += printplayer(abductor_mind) - text += printobjectives(abductor_mind) - text += "
" - if(abductees.len) - text += "
The abductees were:" - for(var/datum/mind/abductee_mind in abductees) - text += printplayer(abductee_mind) - text += printobjectives(abductee_mind) - text += "
" - to_chat(world, text) - // LANDMARKS /obj/effect/landmark/abductor var/team_number = 1 diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index c3a591a278..cf1329aec9 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -151,13 +151,18 @@ var/mob/living/mob_occupant = occupant if(mob_occupant.stat != DEAD) if(href_list["experiment"]) - flash = Experiment(occupant,href_list["experiment"]) + flash = Experiment(occupant,href_list["experiment"],usr) updateUsrDialog() add_fingerprint(usr) -/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type) +/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user) LAZYINITLIST(history) var/mob/living/carbon/human/H = occupant + + var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor) + if(!user_abductor) + return "Authorization failure. Contact mothership immidiately." + var/point_reward = 0 if(H in history) return "Specimen already in database." @@ -182,15 +187,8 @@ if(3) to_chat(H, "You feel intensely watched.") sleep(5) - to_chat(H, "Your mind snaps!") - H.gain_trauma_type(BRAIN_TRAUMA_MILD) - to_chat(H, "You can't remember how you got here...") - var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) - var/datum/objective/abductee/O = new objtype() - SSticker.mode.abductees += H.mind - H.mind.objectives += O - H.mind.announce_objectives() - SSticker.mode.update_abductor_icons_added(H.mind) + user_abductor.team.abductees += H.mind + H.mind.add_antag_datum(/datum/antagonist/abductee) for(var/obj/item/organ/heart/gland/G in H.internal_organs) G.Start() diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm index 379031dce9..8e02d41441 100644 --- a/code/game/gamemodes/miniantags/monkey/monkey.dm +++ b/code/game/gamemodes/miniantags/monkey/monkey.dm @@ -105,13 +105,18 @@ monkey_mind.special_role = null -/datum/game_mode/monkey/declare_completion() +/datum/game_mode/monkey/set_round_result() + ..() if(check_monkey_victory()) SSticker.mode_result = "win - monkey win" - to_chat(world, "The monkeys have overthrown their captors! Eeek eeeek!!") else SSticker.mode_result = "loss - staff stopped the monkeys" - to_chat(world, "The staff managed to contain the monkey infestation!") + +/datum/game_mode/monkey/special_report() + if(check_monkey_victory()) + return "The monkeys have overthrown their captors! Eeek eeeek!!" + else + return "The staff managed to contain the monkey infestation!" /datum/game_mode/monkey/generate_report() return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "banana blight")] outbreak that turn humans into monkeys has been reported in your quadrant. Any such infections may be treated with banana juice. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at CentCom." diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 5e1a97675b..2ebc21adac 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -227,6 +227,7 @@ player_mind.assigned_role = "Morph" player_mind.special_role = "Morph" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) SEND_SOUND(S, sound('sound/magic/mutate.ogg')) message_admins("[key_name_admin(S)] has been made into a morph by an event.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 727203b150..78d39673eb 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -87,6 +87,7 @@ mind.assigned_role = "revenant" mind.special_role = "Revenant" SSticker.mode.traitors |= mind //Necessary for announcing + mind.add_antag_datum(/datum/antagonist/auto_custom) AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null)) AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null)) AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null)) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm index f1f9624380..e62665f21b 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm @@ -38,6 +38,7 @@ player_mind.assigned_role = "Slaughter Demon" player_mind.special_role = "Slaughter Demon" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.") SEND_SOUND(S, 'sound/magic/demon_dies.ogg') diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 94c372ef23..c7fc1bfdc8 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -171,6 +171,7 @@ return FALSE //its a static var btw ..() +<<<<<<< HEAD /datum/game_mode/nuclear/declare_completion() var/disk_rescued = 1 for(var/obj/item/disk/nuclear/D in GLOB.poi_list) @@ -251,12 +252,49 @@ ..() return +======= +/datum/game_mode/nuclear/set_round_result() + var result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH + return ..() +>>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." +<<<<<<< HEAD /datum/game_mode/proc/auto_declare_completion_nuclear() if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) var/text = "
The syndicate operatives were:" @@ -298,6 +336,8 @@ synd_mind.current.real_name = synd_mind.name return +======= +>>>>>>> 3d81385... Roundend report refactor (#33246) /proc/is_nuclear_operative(mob/M) return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates diff --git a/code/game/gamemodes/objective_team.dm b/code/game/gamemodes/objective_team.dm index 7789a167c7..1483f356d2 100644 --- a/code/game/gamemodes/objective_team.dm +++ b/code/game/gamemodes/objective_team.dm @@ -3,6 +3,7 @@ var/list/datum/mind/members = list() var/name = "team" var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. /datum/objective_team/New(starting_members) . = ..() @@ -12,7 +13,6 @@ add_member(M) else add_member(starting_members) - members += starting_members /datum/objective_team/proc/is_solo() return members.len == 1 @@ -21,4 +21,14 @@ members |= new_member /datum/objective_team/proc/remove_member(datum/mind/member) - members -= member \ No newline at end of file + members -= member + +//Display members/victory/failure/objectives for the team +/datum/objective_team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
") \ No newline at end of file diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 4fa9532b42..cbfdb98c69 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -169,62 +169,22 @@ return FALSE return TRUE -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/declare_completion() + +/datum/game_mode/revolution/set_round_result() + ..() if(finished == 1) SSticker.mode_result = "win - heads killed" - to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!") - SSticker.news_report = REVS_WIN - else if(finished == 2) SSticker.mode_result = "loss - rev heads killed" - to_chat(world, "The heads of staff managed to stop the revolution!") - SSticker.news_report = REVS_LOSE - ..() - return TRUE -/datum/game_mode/proc/auto_declare_completion_revolution() - var/list/targets = list() - var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) - var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) - if(headrevs.len) - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - to_chat(world, "[GLOB.TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" ) - var/text = "
The head revolutionaries were:" - for(var/datum/mind/headrev in headrevs) - text += printplayer(headrev, 1) - text += "
" - to_chat(world, text) - - if(revs.len) - var/text = "
The revolutionaries were:" - for(var/datum/mind/rev in revs) - text += printplayer(rev, 1) - text += "
" - to_chat(world, text) - - if(revs.len || headrevs.len) - var/text = "
The heads of staff were:" - var/list/heads = SSjob.get_all_heads() - for(var/datum/mind/head in heads) - var/target = (head in targets) - if(target) - text += "Target" - text += printplayer(head, 1) - text += "
" - to_chat(world, text) +//TODO What should be displayed for revs in non-rev rounds +/datum/game_mode/revolution/special_report() + if(finished == 1) + return "The heads of staff were killed or exiled! The revolutionaries win!" + else if(finished == 2) + return "The heads of staff managed to stop the revolution!" /datum/game_mode/revolution/generate_report() return "Employee unrest has spiked in recent weeks, with several attempted mutinies on heads of staff. Some crew have been observed using flashbulb devices to blind their colleagues, \ diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 7c93a89a36..468725074d 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -27,6 +27,7 @@ var/traitors_possible = 4 //hard limit on traitors if scaling is turned off var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. var/antag_datum = ANTAG_DATUM_TRAITOR //what type of antag to create + var/traitors_required = TRUE //Will allow no traitors /datum/game_mode/traitor/pre_setup() @@ -55,7 +56,7 @@ log_game("[traitor.key] (ckey) has been selected as a [traitor_name]") antag_candidates.Remove(traitor) - return pre_traitors.len > 0 + return !traitors_required || pre_traitors.len > 0 /datum/game_mode/traitor/post_setup() @@ -85,6 +86,7 @@ new_antag.should_specialise = TRUE character.add_antag_datum(new_antag) +<<<<<<< HEAD /datum/game_mode/traitor/declare_completion() @@ -154,11 +156,12 @@ return TRUE +======= +>>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/traitor/generate_report() return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." - /datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind) var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR] traitorhud.join_hud(traitor_mind.current) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 484961b6f8..e0b83f4d0a 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -143,7 +143,8 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(is_sacrifice_target(T.mind)) + var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(C && C.cult_team.is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 5302ebd39b..6dd38e9d58 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -58,20 +58,13 @@ return TRUE -/datum/game_mode/wizard/declare_completion() +/datum/game_mode/wizard/set_round_result() + ..() if(finished) SSticker.mode_result = "loss - wizard killed" - to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!") - SSticker.news_report = WIZARD_KILLED - ..() - return 1 - - -/datum/game_mode/proc/auto_declare_completion_wizard() - if(wizards.len) - var/text = "
the wizards/witches were:" +<<<<<<< HEAD for(var/datum/mind/wizard in wizards) text += "
[wizard.key] was [wizard.name] (" @@ -114,9 +107,12 @@ text += ", " i++ text += "
" +======= +/datum/game_mode/wizard/special_report() + if(finished) + return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" +>>>>>>> 3d81385... Roundend report refactor (#33246) - to_chat(world, text) - return 1 //returns whether the mob is a wizard (or apprentice) /proc/iswizard(mob/living/M) return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index fdb481401e..59465cf5b2 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -45,6 +45,7 @@ var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) user.mind.announce_objectives() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 22365c4584..c0859cc318 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -705,15 +705,17 @@ /datum/admins/proc/output_all_devil_info() var/devil_number = 0 - for(var/D in SSticker.mode.devils) + for(var/datum/mind/D in SSticker.mode.devils) devil_number++ - to_chat(usr, "Devil #[devil_number]:

" + SSticker.mode.printdevilinfo(D)) + var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, "Devil #[devil_number]:

" + devil.printdevilinfo()) if(!devil_number) to_chat(usr, "No Devils located" ) /datum/admins/proc/output_devil_info(mob/living/M) if(is_devil(M)) - to_chat(usr, SSticker.mode.printdevilinfo(M)) + var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, devil.printdevilinfo()) else to_chat(usr, "[M] is not a devil.") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 8a18dc9ac5..75e43adf51 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -317,11 +317,14 @@ //Assign antag status and the mission SSticker.mode.traitors += Commando.mind Commando.mind.special_role = "deathsquad" + var/datum/objective/missionobj = new missionobj.owner = Commando.mind missionobj.explanation_text = mission missionobj.completed = 1 Commando.mind.objectives += missionobj + + Commando.mind.add_antag_datum(/datum/antagonist/auto_custom) //Greet the commando to_chat(Commando, "You are the [numagents==1?"Deathsquad Officer":"Death Commando"].") @@ -369,11 +372,14 @@ //Assign antag status and the mission SSticker.mode.traitors += newmob.mind newmob.mind.special_role = "official" + var/datum/objective/missionobj = new missionobj.owner = newmob.mind missionobj.explanation_text = mission missionobj.completed = 1 newmob.mind.objectives += missionobj + + newmob.mind.add_antag_datum(/datum/antagonist/auto_custom) if(CONFIG_GET(flag/enforce_human_authority)) newmob.set_species(/datum/species/human) @@ -474,12 +480,15 @@ //Assign antag status and the mission SSticker.mode.traitors += ERTOperative.mind ERTOperative.mind.special_role = "ERT" + var/datum/objective/missionobj = new missionobj.owner = ERTOperative.mind missionobj.explanation_text = mission missionobj.completed = 1 ERTOperative.mind.objectives += missionobj + ERTOperative.mind.add_antag_datum(/datum/antagonist/auto_custom) + //Greet the commando to_chat(ERTOperative, "You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"].") var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division." diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index b675815602..d09041aaf3 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(highlander, FALSE) /mob/living/carbon/human/proc/make_scottish() SSticker.mode.traitors += mind mind.special_role = "highlander" + dna.species.species_traits |= NOGUNS //nice try jackass var/datum/objective/steal/steal_objective = new @@ -40,6 +41,8 @@ GLOBAL_VAR_INIT(highlander, FALSE) hijack_objective.owner = mind mind.objectives += hijack_objective + mind.add_antag_datum(/datum/antagonist/auto_custom) + mind.announce_objectives() for(var/obj/item/I in get_equipped_items()) diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 3031936d43..1fe8baba01 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -115,9 +115,11 @@ to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.") SSticker.mode.traitors += user.mind user.mind.special_role = "traitor" + var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(user, "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!") user.mind.announce_objectives() user.set_species(/datum/species/shadow) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index dbbe6ea512..a7e3b20e7a 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -68,3 +68,9 @@ var/datum/chatOutput/chatOutput +<<<<<<< HEAD +======= + var/list/credits //lazy list of all credit object bound to this client + + var/datum/player_details/player_details //these persist between logins/logouts during the same round. +>>>>>>> 3d81385... Roundend report refactor (#33246) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 43ae694b84..fc00ae3828 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -222,6 +222,13 @@ GLOBAL_LIST(external_rsc_urls) message_admins("Notice: [key_name_admin(src)] has the same [matches] as [key_name_admin(C)] (no longer logged in). ") log_access("Notice: [key_name(src)] has the same [matches] as [key_name(C)] (no longer logged in).") + if(GLOB.player_details[ckey]) + player_details = GLOB.player_details[ckey] + else + player_details = new + GLOB.player_details[ckey] = player_details + + . = ..() //calls mob.Login() chatOutput.start() // Starts the chat diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm new file mode 100644 index 0000000000..a842607235 --- /dev/null +++ b/code/modules/client/player_details.dm @@ -0,0 +1,2 @@ +/datum/player_details + var/list/player_actions = list() \ No newline at end of file diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index f983ca2563..7ec7d75bac 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -135,7 +135,7 @@ "You pin \the [src] on [M]'s chest.") if(input) SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[user.real_name]", "commendee" = "[M.real_name]", "medal" = "[src]", "reason" = input)) - GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" + GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" commended = TRUE log_game("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") message_admins("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index 41ff90407d..abb5a0639d 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -45,19 +45,26 @@ to_chat(L, "You didn't get a date! They're all having fun without you! you'll show them though...") var/datum/objective/martyr/normiesgetout = new normiesgetout.owner = L.mind + L.mind.special_role = "heartbreaker" SSticker.mode.traitors |= L.mind L.mind.objectives += normiesgetout + L.mind.add_antag_datum(/datum/antagonist/auto_custom) + /proc/forge_valentines_objective(mob/living/lover,mob/living/date) SSticker.mode.traitors |= lover.mind lover.mind.special_role = "valentine" + var/datum/objective/protect/protect_objective = new /datum/objective/protect protect_objective.owner = lover.mind protect_objective.target = date.mind protect_objective.explanation_text = "Protect [date.real_name], your date." lover.mind.objectives += protect_objective + + lover.mind.add_antag_datum(/datum/antagonist/auto_custom) + to_chat(lover, "You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.") diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 073ef8aea3..76188cb5b7 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -35,6 +35,7 @@ player_mind.assigned_role = "Nightmare" player_mind.special_role = "Nightmare" SSticker.mode.traitors += player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) S.set_species(/datum/species/shadow/nightmare) playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1) message_admins("[key_name_admin(S)] has been made into a Nightmare by an event.") diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index 618c746a65..3227f81d58 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -44,6 +44,7 @@ citizens += H SSticker.mode.traitors += M M.special_role = "separatist" + M.add_antag_datum(/datum/antagonist/auto_custom) H.log_message("Was made into a separatist, long live [nation]!", INDIVIDUAL_ATTACK_LOG) to_chat(H, "You are a separatist! [nation] forever! Protect the sovereignty of your newfound land with your comrades in arms!") if(citizens.len) diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 6ee000249b..1cf4858ce7 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -67,6 +67,7 @@ O.completed = 1 //YES! O.owner = new_holder.mind new_holder.mind.objectives += O + new_holder.mind.add_antag_datum(/datum/antagonist/auto_custom) new_holder.log_message("Won with greentext!!!", INDIVIDUAL_ATTACK_LOG) color_altered_mobs -= new_holder resistance_flags |= ON_FIRE diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index aab1f204f6..d09f8cd4a2 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -50,6 +50,7 @@ if(!mind.special_role) mind.special_role = "traitor" SSticker.mode.traitors += mind + mind.add_antag_datum(/datum/antagonist/auto_custom) // ???? /mob/living/silicon/robot/update_health_hud() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0e6ecf1672..8046daf55d 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -360,8 +360,14 @@ ..() /datum/action/innate/seek_master/Activate() - if(!SSticker.mode.eldergod) - the_construct.master = GLOB.blood_target + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult) + if(!C) + return + var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives + + if(summon_objective.check_completion()) + the_construct.master = C.cult_team.blood_target + if(!the_construct.master) to_chat(the_construct, "You have no master to seek!") the_construct.seeking = FALSE diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 3aa1153133..65ef28baee 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -153,7 +153,7 @@ /mob/living/simple_animal/drone/cogscarab/Login() ..() - add_servant_of_ratvar(src, TRUE) + add_servant_of_ratvar(src, TRUE, GLOB.servants_active) to_chat(src,"You yourself are one of these servants, and will be able to utilize almost anything they can[GLOB.ratvar_awakens ? "":", excluding a clockwork slab"].") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd /mob/living/simple_animal/drone/cogscarab/binarycheck() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index e7608f524b..5a10b3183b 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -48,6 +48,10 @@ client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed. + if(client.player_details.player_actions.len) + for(var/datum/action/A in client.player_details.player_actions) + A.Grant(src) + if(!GLOB.individual_log_list[ckey]) GLOB.individual_log_list[ckey] = logging else diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 1656a43505..b26d01d880 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -95,7 +95,7 @@ Contents: var/datum/mind/Mind = new /datum/mind(key) Mind.assigned_role = "Space Ninja" Mind.special_role = "Space Ninja" - SSticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. + SSticker.mode.traitors |= Mind //Adds them to current traitor list. TODO : Remove this in admin tools refeactor. return Mind diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 22712e970d..9801e98614 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -47,8 +47,15 @@ /obj/singularity/narsie/large/cult/Initialize() . = ..() GLOB.cult_narsie = src - deltimer(GLOB.blood_target_reset_timer) - GLOB.blood_target = src + var/list/all_cults = list() + for(var/datum/antagonist/cult/C in GLOB.antagonists) + all_cults |= C.cult_team + for(var/datum/objective_team/cult/T in all_cults) + deltimer(T.blood_target_reset_timer) + T.blood_target = src + var/datum/objective/eldergod/summon_objective = locate() in T.objectives + if(summon_objective) + summon_objective.summoned = TRUE for(var/datum/mind/cult_mind in SSticker.mode.cult) if(isliving(cult_mind.current)) var/mob/living/L = cult_mind.current diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index b992871004..7ab3121a3a 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -22,12 +22,14 @@ guns.owner = H.mind H.mind.objectives += guns H.mind.special_role = "survivalist" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.") else var/datum/objective/steal_five_of_type/summon_magic/magic = new magic.owner = H.mind H.mind.objectives += magic H.mind.special_role = "amateur magician" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.") var/datum/objective/survive/survive = new survive.owner = H.mind diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index 98ec01f641..88377455c6 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -26,11 +26,11 @@ /datum/station_goal/proc/check_completion() return completed -/datum/station_goal/proc/print_result() +/datum/station_goal/proc/get_result() if(check_completion()) - to_chat(world, "Station Goal : [name] : Completed!") + return "
  • [name] : Completed!
  • " else - to_chat(world, "Station Goal : [name] : Failed!") + return "
  • [name] : Failed!
  • " /datum/station_goal/Destroy() SSticker.mode.station_goals -= src diff --git a/html/browser/roundend.css b/html/browser/roundend.css new file mode 100644 index 0000000000..82235f1273 --- /dev/null +++ b/html/browser/roundend.css @@ -0,0 +1,67 @@ +.greentext { + color: #90ee90; + font-weight: bold; +} + +.greentext_alt { + color: green; +} +.redtext { + color: #ef2f3c; + font-weight: bold; +} +.neutraltext { + font-weight: bold; /* If you feel these should have some color feel free to change */ +} + +.marooned { + color: rgb(109, 109, 255); font-weight: bold; +} + +.header { + font-size: 24px; font-weight: bold; +} + +.big { + font-size: 24px; +} + +.medaltext { + color: #add8e6; +} + +.codephrase { + color : #ef2f3c; +} + +.redborder { + border-bottom: 2px solid #ef2f3c; +} + +.greenborder { + border-bottom: 2px solid #90ee90; +} + +.clockborder { + border-bottom: 2px solid #B18B25; +} + +.stationborder { + border-bottom: 2px solid #add8e6; +} + +li { + margin-bottom: 0.2rem; +} + +.panel { + background-color: #313131; + padding: 10px; + border-radius: 10px; + margin-bottom: 5px; +} + +body { + background-color: #272727; + color: #efefef; +} \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 79e277a91b..44c5e2dd93 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -107,6 +107,7 @@ #include "code\__HELPERS\pronouns.dm" #include "code\__HELPERS\radiation.dm" #include "code\__HELPERS\radio.dm" +#include "code\__HELPERS\roundend.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" #include "code\__HELPERS\stat_tracking.dm" @@ -1301,6 +1302,7 @@ #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" +#include "code\modules\client\player_details.dm" #include "code\modules\client\message.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" From 2aef00daf0713b4c0cbff7f663dcff335b832c02 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Thu, 14 Dec 2017 16:48:25 -0500 Subject: [PATCH 004/213] All-In-One grinder results are now defined by type, not by huge lists --- code/game/objects/items.dm | 15 + code/game/objects/items/apc_frame.dm | 3 +- code/game/objects/items/cigs_lighters.dm | 4 + .../items/circuitboards/circuitboard.dm | 1 + code/game/objects/items/clown_items.dm | 1 + code/game/objects/items/crayons.dm | 1 + code/game/objects/items/devices/flashlight.dm | 2 + code/game/objects/items/devices/scanners.dm | 1 + code/game/objects/items/stacks/bscrystal.dm | 3 + code/game/objects/items/stacks/medical.dm | 2 + .../game/objects/items/stacks/sheets/glass.dm | 4 + .../game/objects/items/stacks/sheets/light.dm | 8 + .../objects/items/stacks/sheets/mineral.dm | 6 + .../items/stacks/sheets/sheet_types.dm | 6 + code/game/objects/items/stacks/stack.dm | 11 + code/game/objects/items/trash.dm | 2 + code/modules/food_and_drinks/drinks/drinks.dm | 1 + code/modules/food_and_drinks/food/snacks.dm | 1 + .../food_and_drinks/food/snacks_egg.dm | 1 + .../food_and_drinks/food/snacks_other.dm | 1 + .../hydroponics/beekeeping/honeycomb.dm | 1 + code/modules/hydroponics/grown.dm | 23 ++ code/modules/hydroponics/grown/apple.dm | 1 + code/modules/hydroponics/grown/banana.dm | 1 + code/modules/hydroponics/grown/beans.dm | 1 + code/modules/hydroponics/grown/berries.dm | 5 + code/modules/hydroponics/grown/cereals.dm | 4 + code/modules/hydroponics/grown/citrus.dm | 3 + code/modules/hydroponics/grown/corn.dm | 1 + code/modules/hydroponics/grown/flowers.dm | 1 + code/modules/hydroponics/grown/melon.dm | 1 + code/modules/hydroponics/grown/nettle.dm | 2 + code/modules/hydroponics/grown/potato.dm | 1 + code/modules/hydroponics/grown/pumpkin.dm | 4 +- code/modules/hydroponics/grown/root.dm | 1 + code/modules/hydroponics/grown/tea_coffee.dm | 9 +- code/modules/hydroponics/grown/tomato.dm | 3 + code/modules/hydroponics/growninedible.dm | 4 + .../living/simple_animal/friendly/mouse.dm | 4 + code/modules/paperwork/pen.dm | 6 + code/modules/paperwork/photocopier.dm | 1 + code/modules/paperwork/photography.dm | 1 + code/modules/power/cable.dm | 1 + code/modules/power/cell.dm | 2 + code/modules/power/lighting.dm | 1 + .../chemistry/machinery/reagentgrinder.dm | 272 +++--------------- .../reagents/reagent_containers/pill.dm | 158 ++++++++++ .../research/xenobiology/xenobiology.dm | 5 + 48 files changed, 356 insertions(+), 235 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f4dd741695..d4fd9c710a 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -117,7 +117,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/trigger_guard = TRIGGER_GUARD_NONE +<<<<<<< HEAD var/icon_override = null +======= + //Grinder vars + var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only + var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) /obj/item/Initialize() if (!materials) @@ -678,6 +684,15 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/proc/on_mob_death(mob/living/L, gibbed) +/obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object + return TRUE + + //Called BEFORE the object is ground up - use this to change grind results based on conditions + //Use "return -1" to prevent the grinding from occurring +/obj/item/proc/on_grind() + +/obj/item/proc/on_juice() + /obj/item/proc/set_force_string() switch(force) if(0 to 4) diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 4c8d342c16..5048f6ed2d 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -120,4 +120,5 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50, MAT_GLASS=50) \ No newline at end of file + materials = list(MAT_METAL=50, MAT_GLASS=50) + grind_results = list("iron" = 10, "silicon" = 10) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 491feb91ce..9c7c34510c 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -25,6 +25,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/smoketime = 5 w_class = WEIGHT_CLASS_TINY heat = 1000 + grind_results = list("phosphorus" = 2) /obj/item/match/process() smoketime-- @@ -104,6 +105,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM container_type = INJECTABLE_1 w_class = WEIGHT_CLASS_TINY body_parts_covered = null + grind_results = list() var/lit = FALSE var/starts_lit = FALSE var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi @@ -363,6 +365,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigbutt" w_class = WEIGHT_CLASS_TINY throwforce = 0 + grind_results = list("carbon" = 2) /obj/item/cigbutt/cigarbutt name = "cigar butt" @@ -484,6 +487,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM heat = 1500 resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE + grind_results = list("iron" = 1, "welding_fuel" = 5, "oil" = 5) /obj/item/lighter/update_icon() if(lit) diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index 82350e37f9..12b54a3751 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -12,6 +12,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_GLASS=1000) w_class = WEIGHT_CLASS_SMALL + grind_results = list("silicon" = 20, "sacid" = 0.5) //Retrieving acid this way is extremely inefficient var/build_path = null /obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M) diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index c96ec4167a..f2a804e9e9 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -21,6 +21,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 + grind_results = list("lye" = 10) var/cleanspeed = 50 //slower than mop force_string = "robust... against germs" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2d730daf..56bad47963 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -26,6 +26,7 @@ item_color = "red" w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "coloured") + grind_results = list() var/paint_color = "#FF0000" //RGB var/drawtype diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 08c570a786..f656d55afd 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -256,6 +256,7 @@ var/produce_heat = 1500 heat = 1000 light_color = LIGHT_COLOR_FLARE + grind_results = list("sulfur" = 15) /obj/item/device/flashlight/flare/New() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. @@ -404,6 +405,7 @@ color = LIGHT_COLOR_GREEN icon_state = "glowstick" item_state = "glowstick" + grind_results = list("phenol" = 15, "hydrogen" = 10, "oxygen" = 5) //Meth-in-a-stick var/fuel = 0 /obj/item/device/flashlight/glowstick/Initialize() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3f17485550..9a60bb0edb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -335,6 +335,7 @@ GAS ANALYZER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) + grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5) /obj/item/device/analyzer/attack_self(mob/user) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 5276050b03..978966706e 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -9,6 +9,7 @@ points = 50 var/blink_range = 8 // The teleport range when crushed/thrown at someone. refined_type = /obj/item/stack/sheet/bluespace_crystal + grind_results = list("bluespace" = 2) /obj/item/ore/bluespace_crystal/refined name = "refined bluespace crystal" @@ -48,6 +49,7 @@ blink_range = 4 // Not as good as the organic stuff! points = 0 //nice try refined_type = null + grind_results = list("bluespace" = 1, "silicon" = 2) //Polycrystals, aka stacks /obj/item/stack/sheet/bluespace_crystal @@ -58,6 +60,7 @@ materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE + grind_results = list("bluespace" = 2) var/crystal_type = /obj/item/ore/bluespace_crystal/refined /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 560182d9c7..7a0f85a8f2 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -111,6 +111,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 self_delay = 20 + grind_results = list("styptic_powder" = 1) /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -147,3 +148,4 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_burn = 40 self_delay = 20 + grind_results = list("silver_sulfadiazine" = 1) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 0544598246..8cc6a60efa 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass + grind_results = list("silicon" = 1) /obj/item/stack/sheet/glass/cyborg materials = list() @@ -79,6 +80,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list("silicon" = 1, "plasma" = 1) /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -128,6 +130,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass + grind_results = list("silicon" = 1, "iron" = 1) /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -168,6 +171,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list("silicon" = 1, "plasma" = 1, "iron" = 1) /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index a02d182f1c..e0dcfa3184 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -10,10 +10,18 @@ throw_speed = 3 throw_range = 7 flags_1 = CONDUCT_1 +<<<<<<< HEAD max_amount = 60 /obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) +======= + max_amount = 60 + grind_results = list("silicon" = 1, "copper" = 1) + +/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) + +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) if(istype(O, /obj/item/wirecutters)) var/obj/item/stack/cable_coil/CC = new (user.loc) CC.amount = 5 diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index e2ae00d06c..e44366daec 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -126,6 +126,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("uranium" = 20) GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ @@ -149,6 +150,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ resistance_flags = FLAMMABLE max_integrity = 100 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) + grind_results = list("plasma" = 20) GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ @@ -182,6 +184,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ singular_name = "gold bar" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) + grind_results = list("gold" = 20) GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ @@ -207,6 +210,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ singular_name = "silver bar" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) + grind_results = list("silver" = 20) GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ @@ -232,6 +236,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ sheettype = "clown" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("banana" = 20) GLOBAL_LIST_INIT(clown_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ @@ -302,6 +307,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ singular_name = "snow block" force = 1 throwforce = 2 + grind_results = list("ice" = 20) GLOBAL_LIST_INIT(snow_recipes, list ( \ new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index d8019d98a3..36b9cf210a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -99,6 +99,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ flags_1 = CONDUCT_1 resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal + grind_results = list("iron" = 20) /obj/item/stack/sheet/metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -151,6 +152,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel + grind_results = list("iron" = 20, "plasma" = 20) /obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plasteel_recipes @@ -202,6 +204,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE + grind_results = list("carbon" = 20) /obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.wood_recipes @@ -322,6 +325,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ sheettype = "runed" merge_type = /obj/item/stack/sheet/runed_metal novariants = TRUE + grind_results = list("iron" = 0.5, "blood" = 1.5) /obj/item/stack/sheet/runed_metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -385,6 +389,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE + grind_results = list("iron" = 0.5, "teslium" = 1.5) /obj/item/stack/tile/brass/narsie_act() new /obj/item/stack/sheet/runed_metal(loc, amount) @@ -435,6 +440,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 + grind_results = list("carbon" = 1) GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1faad3462b..d50239f79d 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -21,6 +21,17 @@ var/merge_type = null // This path and its children should merge with this stack, defaults to src.type var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount var/novariants = TRUE //Determines whether the item should update it's sprites based on amount. + //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() + +/obj/item/stack/on_grind() + for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists + grind_results[grind_results[i]] *= amount //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size + +/obj/item/stack/grind_requirements() + if(is_cyborg) + to_chat(usr, "[src] is electronically synthesized in your chassis and can't be ground up!") + return + return TRUE /obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE) . = ..() diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index c9552a3d39..b1313ef84f 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -66,6 +66,7 @@ name = "crushed can" icon_state = "cola" resistance_flags = NONE + grind_results = list("aluminum" = 10) /obj/item/trash/attack(mob/M, mob/living/user) return @@ -75,6 +76,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "slag" desc = "Someone's gotten on the naughty list." + grind_results = list("carbon" = 20) /obj/item/trash/coal/burn() visible_message("[src] fuses into a diamond! Someone wasn't so naughty after all...") diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 7217fe0b28..6fb712ea41 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -393,6 +393,7 @@ container_type = NONE spillable = FALSE isGlass = FALSE + grind_results = list("aluminum" = 10) /obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/user) if(M == user && !src.reagents.total_volume && user.a_intent == INTENT_HARM && user.zone_selected == "head") diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 49f85a882d..7f574e0313 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -6,6 +6,7 @@ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' unique_rename = 1 + grind_results = list() //To let them be ground up to transfer their reagents var/bitesize = 2 var/bitecount = 0 var/trash = null diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index bfe181b419..10039f7a8b 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -20,6 +20,7 @@ filling_color = "#F0E68C" tastes = list("egg" = 1) foodtype = MEAT + grind_results = list("eggyolk" = 5) /obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) if(!..()) //was it caught by a mob? diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index c32ebfb765..c7681fe807 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -28,6 +28,7 @@ filling_color = "#FF1493" tastes = list("watermelon" = 1) foodtype = FRUIT + juice_results = list("watermelonjuice" = 5) /obj/item/reagent_containers/food/snacks/candy_corn name = "candy corn" diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 737736efc5..8b9d641eac 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -10,6 +10,7 @@ volume = 10 amount_per_transfer_from_this = 0 list_reagents = list("honey" = 5) + grind_results = list() var/honey_color = "" /obj/item/reagent_containers/honeycomb/New() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d003f40d4a..643ac056e4 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,6 +15,7 @@ // Saves us from having to define each stupid grown's dried_type as itself. // If you don't want a plant to be driable (watermelons) set this to null in the time definition. resistance_flags = FLAMMABLE + var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up /obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() @@ -137,6 +138,28 @@ return return ..() +/obj/item/reagent_containers/food/snacks/grown/grind_requirements() + if(dry_grind && !dry) + to_chat(usr, "[src] needs to be dry before it can be ground up!") + return + return TRUE + +/obj/item/reagent_containers/food/snacks/grown/on_grind() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(grind_results.len) + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + +/obj/item/reagent_containers/food/snacks/grown/on_juice() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(juice_results.len) + for(var/i in 1 to juice_results.len) + juice_results[juice_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + // For item-containing growns such as eggy or gatfruit /obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user) var/obj/item/T diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index 7ec9a730ed..8b35fee872 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -15,6 +15,7 @@ genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/apple/gold) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("applejuice" = 0) /obj/item/reagent_containers/food/snacks/grown/apple seed = /obj/item/seeds/apple diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index bf71856323..72517e87bc 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -13,6 +13,7 @@ genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace) reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02) + juice_results = list("banana" = 0) /obj/item/reagent_containers/food/snacks/grown/banana seed = /obj/item/seeds/banana diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm index 8ca2a5961a..46a7e7979f 100644 --- a/code/modules/hydroponics/grown/beans.dm +++ b/code/modules/hydroponics/grown/beans.dm @@ -26,6 +26,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("soymilk" = 0) // Koibean /obj/item/seeds/soya/koi diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 0d8c5d5a9a..541fb1b2a5 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -26,6 +26,7 @@ filling_color = "#FF00FF" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("berryjuice" = 0) // Poison Berries /obj/item/seeds/berry/poison @@ -46,6 +47,7 @@ icon_state = "poisonberrypile" filling_color = "#C71585" foodtype = FRUIT | TOXIC + juice_results = list("poisonberryjuice" = 0) // Death Berries /obj/item/seeds/berry/death @@ -121,6 +123,7 @@ filling_color = "#FF0000" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("cherryjelly" = 0) // Blue Cherries /obj/item/seeds/cherry/blue @@ -142,6 +145,7 @@ filling_color = "#6495ED" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("bluecherryjelly" = 0) // Grapes /obj/item/seeds/grape @@ -173,6 +177,7 @@ filling_color = "#FF1493" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("grapejuice" = 0) // Green Grapes /obj/item/seeds/grape/green diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index 7834ed15e8..d9b724d052 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -22,6 +22,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Oat /obj/item/seeds/wheat/oat @@ -42,6 +43,7 @@ filling_color = "#556B2F" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Rice /obj/item/seeds/wheat/rice @@ -63,6 +65,7 @@ filling_color = "#FAFAD2" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("rice" = 0) //Meatwheat - grows into synthetic meat /obj/item/seeds/wheat/meat @@ -83,6 +86,7 @@ bitesize_mod = 2 seed = /obj/item/seeds/wheat/meat foodtype = MEAT | GRAIN + grind_results = list("flour" = 0, "blood" = 0) /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 1b0cdc00d2..38f8a40ec3 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -30,6 +30,7 @@ desc = "It's so sour, your face will twist." icon_state = "lime" filling_color = "#00FF00" + juice_results = list("limejuice" = 0) // Orange /obj/item/seeds/orange @@ -56,6 +57,7 @@ desc = "It's a tangy fruit." icon_state = "orange" filling_color = "#FFA500" + juice_results = list("orangejuice" = 0) // Lemon /obj/item/seeds/lemon @@ -81,6 +83,7 @@ desc = "When life gives you lemons, make lemonade." icon_state = "lemon" filling_color = "#FFD700" + juice_results = list("lemonjuice" = 0) // Combustible lemon /obj/item/seeds/firelemon //combustible lemon is too long so firelemon diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index 827deaea47..4454c3c52a 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -25,6 +25,7 @@ trash = /obj/item/grown/corncob bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("corn_starch" = 0) /obj/item/grown/corncob name = "corn cob" diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index e0845ffb2a..18eae2f4fd 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -182,6 +182,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("roasted", "scorched", "burned") + grind_results = list("capsaicin" = 0, "condensedcapsaicin" = 0) /obj/item/grown/novaflower/add_juice() ..() diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 5e64d716ec..a64fc4b156 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -33,6 +33,7 @@ filling_color = "#008000" bitesize_mod = 3 foodtype = FRUIT + juice_results = list("watermelonjuice" = 0) // Holymelon /obj/item/seeds/watermelon/holy diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 284f962e45..9ec936c1f2 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -43,6 +43,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("stung") + grind_results = list("sacid" = 0) /obj/item/grown/nettle/suicide_act(mob/user) user.visible_message("[user] is eating some of [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -91,6 +92,7 @@ icon_state = "deathnettle" force = 30 throwforce = 15 + grind_results = list("facid" = 1, "sacid" = 1) /obj/item/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm index 0a3cbc060c..e127b166ea 100644 --- a/code/modules/hydroponics/grown/potato.dm +++ b/code/modules/hydroponics/grown/potato.dm @@ -17,6 +17,7 @@ genes = list(/datum/plant_gene/trait/battery) mutatelist = list(/obj/item/seeds/potato/sweet) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("potato" = 0) /obj/item/reagent_containers/food/snacks/grown/potato seed = /obj/item/seeds/potato diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm index d5257aeee7..7113a8feab 100644 --- a/code/modules/hydroponics/grown/pumpkin.dm +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -24,6 +24,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("pumpkinjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params) if(W.is_sharp()) @@ -53,4 +54,5 @@ icon_state = "blumpkin" filling_color = "#87CEFA" bitesize_mod = 2 - foodtype = VEGETABLES \ No newline at end of file + foodtype = VEGETABLES + juice_results = list("blumpkinjuice" = 0) diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 8666db45a8..fd78fa6ffa 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -22,6 +22,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("carrotjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params) if(I.is_sharp()) diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index bd3b182c13..fc2ed221c5 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -14,7 +14,6 @@ icon_dead = "tea-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/tea/astra) - reagents_add = list("vitamin" = 0.04, "teapowder" = 0.1) /obj/item/reagent_containers/food/snacks/grown/tea seed = /obj/item/seeds/tea @@ -22,6 +21,8 @@ desc = "These aromatic tips of the tea plant can be dried to make tea." icon_state = "tea_aspera_leaves" filling_color = "#008000" + grind_results = list("teapowder" = 0) + dry_grind = TRUE // Tea Astra /obj/item/seeds/tea/astra @@ -39,6 +40,7 @@ name = "Tea Astra tips" icon_state = "tea_astra_leaves" filling_color = "#4582B4" + grind_results = list("teapowder" = 0, "salglu_solution" = 0) // Coffee @@ -67,6 +69,8 @@ icon_state = "coffee_arabica" filling_color = "#DC143C" bitesize_mod = 2 + dry_grind = TRUE + grind_results = list("coffeepowder" = 0) // Coffee Robusta /obj/item/seeds/coffee/robusta @@ -84,4 +88,5 @@ seed = /obj/item/seeds/coffee/robusta name = "coffee robusta beans" desc = "Increases robustness by 37 percent!" - icon_state = "coffee_robusta" \ No newline at end of file + icon_state = "coffee_robusta" + grind_results = list("coffeepowder" = 0, "morphine" = 0) diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 1bc42b45c0..4d066e769e 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -23,6 +23,8 @@ filling_color = "#FF6347" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("ketchup" = 0) + juice_results = list("tomatojuice" = 0) // Blood Tomato /obj/item/seeds/tomato/blood @@ -44,6 +46,7 @@ splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" foodtype = VEGETABLES | GROSS + grind_results = list("ketchup" = 0, "blood" = 0) // Blue Tomato diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index a77808f006..3b80fae6c0 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -62,3 +62,7 @@ /obj/item/grown/microwave_act(obj/machine/microwave/M) return + +/obj/item/grown/on_grind() + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = round(seed.potency) diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 85ec19bfb9..809681ed6b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -110,3 +110,7 @@ eatverb = "devours" list_reagents = list("nutriment" = 3, "vitamin" = 2) foodtype = GROSS | MEAT | RAW + grind_results = list("blood" = 20, "liquidgibs" = 5) + +/obj/item/reagent_containers/food/snacks/deadmouse/on_grind() + reagents.clear_reagents() diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 0826a49c7c..1cd6b889c8 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -23,6 +23,7 @@ throw_range = 7 materials = list(MAT_METAL=10) pressure_resistance = 2 + grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! var/traitor_unlock_degrees = 0 var/degrees = 0 @@ -174,7 +175,12 @@ reagents.trans_to(M, reagents.total_volume) +<<<<<<< HEAD /obj/item/pen/sleepy/New() +======= +/obj/item/pen/sleepy/Initialize() + . = ..() +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 20038f5745..65babd7e00 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -391,5 +391,6 @@ /obj/item/device/toner name = "toner cartridge" icon_state = "tonercartridge" + grind_results = list("iodine" = 40, "iron" = 10) var/charges = 5 var/max_charges = 5 diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 48b045f680..6e908c0f6a 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,6 +33,7 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE max_integrity = 50 + grind_results = list("iodine" = 4) var/icon/img //Big photo image var/scribble //Scribble on the back. var/blueprints = 0 //Does it include the blueprints? diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 9e4e29ceb5..c1a4181666 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -472,6 +472,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai attack_verb = list("whipped", "lashed", "disciplined", "flogged") singular_name = "cable piece" full_w_class = WEIGHT_CLASS_SMALL + grind_results = list("copper" = 2) //2 copper per cable in the coil /obj/item/stack/cable_coil/cyborg is_cyborg = 1 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 1e1407e852..8258d7ce0d 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -14,6 +14,7 @@ var/charge = 0 // note %age conveted to actual charge in New var/maxcharge = 1000 materials = list(MAT_METAL=700, MAT_GLASS=50) + grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5) var/rigged = 0 // true if rigged to explode var/chargerate = 100 //how much power is given every tick in a recharger var/self_recharge = 0 //does it self recharge, over time, or not? @@ -107,6 +108,7 @@ to_chat(user, "You inject the solution into the power cell.") if(S.reagents.has_reagent("plasma", 5)) rigged = 1 + grind_results["plasma"] = 5 S.reagents.clear_reagents() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 3acac6cee5..749dcb463e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -680,6 +680,7 @@ var/base_state var/switchcount = 0 // number of times switched materials = list(MAT_GLASS=100) + grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs var/rigged = 0 // true if rigged to explode var/brightness = 2 //how much light it gives off diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 77fcd50306..223259f6f3 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -2,7 +2,7 @@ #define MILK_TO_BUTTER_COEFF 15 /obj/machinery/reagentgrinder - name = "All-In-One Grinder" + name = "\improper All-In-One Grinder" desc = "From BlenderTech. Will It Blend? Let's test it out!" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" @@ -16,97 +16,6 @@ var/operating = FALSE var/obj/item/reagent_containers/beaker = null var/limit = 10 - - var/static/list/blend_items = list( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), - /obj/item/stack/sheet/metal = list("iron" = 20), - /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), - /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), - /obj/item/stack/sheet/glass = list("silicon" = 20), - /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), - /obj/item/stack/cable_coil = list ("copper" = 5), - /obj/item/ore/bluespace_crystal = list("bluespace" = 20), - /obj/item/grown/nettle/basic = list("sacid" = 0), - /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), - /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //Blender Stuff - /obj/item/reagent_containers/food/snacks/donkpocket/warm = list("omnizine" = 3), - /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), - /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), - /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster - //Grinder stuff, but only if dry - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //Stuff that doesn't quite fit in the other categories - /obj/item/electronics = list ("iron" = 10, "silicon" = 10), - /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient - /obj/item/match = list ("phosphorus" = 2), - /obj/item/device/toner = list ("iodine" = 40, "iron" = 10), - /obj/item/photo = list ("iodine" = 4), - /obj/item/pen = list ("iodine" = 2, "iron" = 1), - /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10), - /obj/item/trash/can = list ("aluminium" = 10), - /obj/item/device/flashlight/flare = list ("sulfur" = 15), - /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5), - /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5), - /obj/item/soap = list ("lye" = 10), - /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5), - /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5), - /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs - /obj/item/cigbutt/ = list ("carbon" = 2), - /obj/item/trash/coal = list ("carbon" = 20), - /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5), - /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/slime_extract = list(), - /obj/item/reagent_containers/pill = list(), - /obj/item/reagent_containers/food = list(), - /obj/item/reagent_containers/honeycomb = list(), - /obj/item/toy/crayon = list(), - /obj/item/clothing/mask/cigarette = list()) - - var/static/list/juice_items = list( - //Juicer Stuff - /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) - - var/static/list/dried_items = list( - //Grinder stuff, but only if dry, - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) - var/list/holdingitems /obj/machinery/reagentgrinder/Initialize() @@ -158,6 +67,7 @@ if(!user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return TRUE + to_chat(user, "You slide [I] into [src].") beaker = I update_icon() updateUsrDialog() @@ -165,15 +75,8 @@ to_chat(user, "There's already a container inside [src].") return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry [G] first!") - return TRUE - - if(length(holdingitems) >= limit) - to_chat(user, "The machine cannot hold anymore items.") + if(holdingitems.len >= limit) + to_chat(user, "[src] is filled to capacity!") return TRUE //Fill machine with a bag! @@ -192,14 +95,18 @@ updateUsrDialog() return TRUE - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(!I.grind_results && !I.juice_results) if(user.a_intent == INTENT_HARM) return ..() else - to_chat(user, "Cannot refine into a reagent!") + to_chat(user, "You cannot grind [I] into reagents!") return TRUE + if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions + return + if(user.transferItemToLoc(I, src)) + to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE updateUsrDialog() return FALSE @@ -214,7 +121,7 @@ user.set_machine(src) interact(user) -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu +/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave var/is_chamber_empty = FALSE var/is_beaker_ready = FALSE var/processing_chamber = "" @@ -307,60 +214,10 @@ holdingitems -= O updateUsrDialog() -/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(O.seed.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) - /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O qdel(O) -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) - return - operate_for(50, juicing = TRUE) - - //Snacks - for(var/obj/item/i in holdingitems) - var/obj/item/I = i - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/list/allowed = get_allowed_juice_by_obj(O) - if(isnull(allowed)) - break - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - beaker.reagents.add_reagent(r_id, min(amount, space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - /obj/machinery/reagentgrinder/proc/shake_for(duration) var/offset = prob(50) ? -2 : 2 var/old_pixel_x = pixel_x @@ -386,8 +243,26 @@ operating = FALSE updateUsrDialog() -/obj/machinery/reagentgrinder/proc/grind() +/obj/machinery/reagentgrinder/proc/juice() + power_change() + if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + return + operate_for(50, juicing = TRUE) + for(var/obj/item/i in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/obj/item/I = i + if(I.juice_results) + juice_item(I) +/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions + if(I.on_juice(src) == -1) + to_chat(usr, "[src] shorts out as it tries to juice up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.juice_results) + remove_object(I) + +/obj/machinery/reagentgrinder/proc/grind() power_change() if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return @@ -396,82 +271,17 @@ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break var/obj/item/I = i - //Snacks - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - var/list/allowed = get_allowed_by_obj(O) - if(isnull(allowed)) - continue - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - if(O.reagents.reagent_list.len == 0) - remove_object(O) - //Sheets - else if(istype(I, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/O = I - var/list/allowed = get_allowed_by_obj(O) - for(var/t in 1 to round(O.amount, 1)) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if(t == round(O.amount, 1)) - remove_object(O) - break - //Plants - else if(istype(I, /obj/item/grown)) - var/obj/item/grown/O = I - var/list/allowed = get_allowed_by_obj(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - else if(istype(I, /obj/item/slime_extract)) - var/obj/item/slime_extract/O = I - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (O.reagents != null) - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, min(amount, space)) - if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) - remove_object(O) - if(istype(I, /obj/item/reagent_containers)) - var/obj/item/reagent_containers/O = I - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) - else if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/O = I - for (var/r_id in O.reagent_contents) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(!space) - break - beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) - remove_object(O) + if(I.grind_results) + grind_item(i) + +/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I) //Grind results can be found in respective object definitions + if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1 + to_chat(usr, "[src] shorts out as it tries to grind up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.grind_results) + if(I.reagents) + I.reagents.trans_to(beaker, I.reagents.total_volume) + remove_object(I) /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 324623edbd..b1a126ba62 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/reagent_containers/pill name = "pill" desc = "A tablet or capsule." @@ -152,3 +153,160 @@ icon_state = "pill9" color = "#454545" list_reagents = list("shadowmutationtoxin" = 1) +======= +/obj/item/reagent_containers/pill + name = "pill" + desc = "A tablet or capsule." + icon = 'icons/obj/chemical.dmi' + icon_state = "pill" + item_state = "pill" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + possible_transfer_amounts = list() + volume = 50 + grind_results = list() + var/apply_type = INGEST + var/apply_method = "swallow" + var/roundstart = 0 + var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills + +/obj/item/reagent_containers/pill/Initialize() + . = ..() + if(!icon_state) + icon_state = "pill[rand(1,20)]" + if(reagents.total_volume && roundstart) + name += " ([reagents.total_volume]u)" + + +/obj/item/reagent_containers/pill/attack_self(mob/user) + return + + +/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) + if(!canconsume(M, user)) + return 0 + + if(M == user) + M.visible_message("[user] attempts to [apply_method] [src].") + if(self_delay) + if(!do_mob(user, M, self_delay)) + return 0 + to_chat(M, "You [apply_method] [src].") + + else + M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ + "[user] attempts to force [M] to [apply_method] [src].") + if(!do_mob(user, M)) + return 0 + M.visible_message("[user] forces [M] to [apply_method] [src].", \ + "[user] forces [M] to [apply_method] [src].") + + + add_logs(user, M, "fed", reagentlist(src)) + if(reagents.total_volume) + reagents.reaction(M, apply_type) + reagents.trans_to(M, reagents.total_volume) + qdel(src) + return 1 + + +/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) + if(!proximity) + return + if(target.is_open_container() != 0 && target.reagents) + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") + return + to_chat(user, "You dissolve [src] in [target].") + for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius + to_chat(O, "[user] slips something into [target]!") + reagents.trans_to(target, reagents.total_volume) + qdel(src) + +/obj/item/reagent_containers/pill/tox + name = "toxins pill" + desc = "Highly toxic." + icon_state = "pill5" + list_reagents = list("toxin" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/cyanide + name = "cyanide pill" + desc = "Don't swallow this." + icon_state = "pill5" + list_reagents = list("cyanide" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/adminordrazine + name = "adminordrazine pill" + desc = "It's magic. We don't have to explain it." + icon_state = "pill16" + list_reagents = list("adminordrazine" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/morphine + name = "morphine pill" + desc = "Commonly used to treat insomnia." + icon_state = "pill8" + list_reagents = list("morphine" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/stimulant + name = "stimulant pill" + desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" + icon_state = "pill19" + list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/salbutamol + name = "salbutamol pill" + desc = "Used to treat oxygen deprivation." + icon_state = "pill16" + list_reagents = list("salbutamol" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/charcoal + name = "charcoal pill" + desc = "Neutralizes many common toxins." + icon_state = "pill17" + list_reagents = list("charcoal" = 10) + roundstart = 1 +/obj/item/reagent_containers/pill/epinephrine + name = "epinephrine pill" + desc = "Used to stabilize patients." + icon_state = "pill5" + list_reagents = list("epinephrine" = 15) + roundstart = 1 +/obj/item/reagent_containers/pill/mannitol + name = "mannitol pill" + desc = "Used to treat brain damage." + icon_state = "pill17" + list_reagents = list("mannitol" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/mutadone + name = "mutadone pill" + desc = "Used to treat genetic damage." + icon_state = "pill20" + list_reagents = list("mutadone" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/salicyclic + name = "salicylic acid pill" + desc = "Used to dull pain." + icon_state = "pill9" + list_reagents = list("sal_acid" = 24) + roundstart = 1 +/obj/item/reagent_containers/pill/oxandrolone + name = "oxandrolone pill" + desc = "Used to stimulate burn healing." + icon_state = "pill11" + list_reagents = list("oxandrolone" = 24) + roundstart = 1 + +/obj/item/reagent_containers/pill/insulin + name = "insulin pill" + desc = "Handles hyperglycaemic coma." + icon_state = "pill18" + list_reagents = list("insulin" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/shadowtoxin + name = "black pill" + desc = "I wouldn't eat this if I were you." + icon_state = "pill9" + color = "#454545" + list_reagents = list("shadowmutationtoxin" = 1) +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index cf250f50f1..7d8ff00e91 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -12,6 +12,7 @@ throw_speed = 3 throw_range = 6 container_type = INJECTABLE_1 + grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -29,6 +30,10 @@ . = ..() create_reagents(100) +/obj/item/slime_extract/on_grind() + if(Uses) + grind_results["slimejelly"] = 20 + /obj/item/slime_extract/grey name = "grey slime extract" icon_state = "grey slime extract" From 8beeeefa44cc755c53df1d1490e938a03787ea19 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:23:09 -0500 Subject: [PATCH 005/213] Update items.dm --- code/game/objects/items.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d4fd9c710a..497ad4faf8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -117,13 +117,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/trigger_guard = TRIGGER_GUARD_NONE -<<<<<<< HEAD var/icon_override = null -======= + //Grinder vars var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) /obj/item/Initialize() if (!materials) From ba928eae5ea57e024ac0896423c6925aae0955c3 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:23:42 -0500 Subject: [PATCH 006/213] Update light.dm --- .../game/objects/items/stacks/sheets/light.dm | 69 +++++++++---------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index e0dcfa3184..051d8326b8 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -1,45 +1,38 @@ -/obj/item/stack/light_w - name = "wired glass tile" - singular_name = "wired glass floor tile" - desc = "A glass tile, which is wired, somehow." - icon = 'icons/obj/tiles.dmi' - icon_state = "glass_wire" - w_class = WEIGHT_CLASS_NORMAL - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 7 +/obj/item/stack/light_w + name = "wired glass tile" + singular_name = "wired glass floor tile" + desc = "A glass tile, which is wired, somehow." + icon = 'icons/obj/tiles.dmi' + icon_state = "glass_wire" + w_class = WEIGHT_CLASS_NORMAL + force = 3 + throwforce = 5 + throw_speed = 3 + throw_range = 7 flags_1 = CONDUCT_1 -<<<<<<< HEAD - max_amount = 60 - -/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) - -======= max_amount = 60 grind_results = list("silicon" = 1, "copper" = 1) /obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) if(istype(O, /obj/item/wirecutters)) - var/obj/item/stack/cable_coil/CC = new (user.loc) - CC.amount = 5 - CC.add_fingerprint(user) - amount-- - var/obj/item/stack/sheet/glass/G = new (user.loc) - G.add_fingerprint(user) - if(amount <= 0) - qdel(src) - - else if(istype(O, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = O - if (M.use(1)) - use(1) - var/obj/item/L = new /obj/item/stack/tile/light(user.loc) - to_chat(user, "You make a light tile.") - L.add_fingerprint(user) - else - to_chat(user, "You need one metal sheet to finish the light tile!") - else - return ..() + var/obj/item/stack/cable_coil/CC = new (user.loc) + CC.amount = 5 + CC.add_fingerprint(user) + amount-- + var/obj/item/stack/sheet/glass/G = new (user.loc) + G.add_fingerprint(user) + if(amount <= 0) + qdel(src) + + else if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + if (M.use(1)) + use(1) + var/obj/item/L = new /obj/item/stack/tile/light(user.loc) + to_chat(user, "You make a light tile.") + L.add_fingerprint(user) + else + to_chat(user, "You need one metal sheet to finish the light tile!") + else + return ..() From ede6f432bc712e1457d77f724ae57e56e1be40df Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:24:19 -0500 Subject: [PATCH 007/213] Update pen.dm --- code/modules/paperwork/pen.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 1cd6b889c8..fd52d8f0ac 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -175,12 +175,8 @@ reagents.trans_to(M, reagents.total_volume) -<<<<<<< HEAD -/obj/item/pen/sleepy/New() -======= /obj/item/pen/sleepy/Initialize() . = ..() ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) From d45b668a390ca0c97cf4df7315cf51a892731414 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 18:23:10 -0500 Subject: [PATCH 008/213] Adds config inclusion system --- code/__DEFINES/configuration.dm | 2 - .../controllers/configuration/config_entry.dm | 4 +- .../configuration/configuration.dm | 44 +- .../configuration/entries/comms.dm | 14 +- .../configuration/entries/config.dm | 390 ------------------ .../configuration/entries/dbconfig.dm | 16 +- .../configuration/entries/game_options.dm | 176 ++++---- .../configuration/entries/general.dm | 388 +++++++++++++++++ config/config.txt | 6 + tgstation.dme | 2 +- 10 files changed, 527 insertions(+), 515 deletions(-) delete mode 100644 code/controllers/configuration/entries/config.dm create mode 100644 code/controllers/configuration/entries/general.dm diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3db0ca24c2..c4ef8e6606 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,8 +1,6 @@ //config files -#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) -#define CONFIG_TWEAK(X) /datum/config_entry/##X #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 92dcb9baf0..7e6f481392 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -9,7 +9,7 @@ var/value var/default //read-only, just set value directly - var/resident_file //the file which this belongs to, must be set + var/resident_file //the file which this was loaded from, if any var/modified = FALSE //set to TRUE if the default has been overridden by a config entry var/protection = NONE @@ -18,8 +18,6 @@ var/dupes_allowed = FALSE /datum/config_entry/New() - if(!resident_file) - CRASH("Config entry [type] has no resident_file set") if(type == abstract_type) CRASH("Abstract config entry [type] instatiated!") name = lowertext(type2top(type)) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index e9c0aa71b8..f411bd65d3 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -20,10 +20,13 @@ GLOBAL_PROTECT(config_dir) /datum/controller/configuration/New() config = src - var/list/config_files = InitEntries() + InitEntries() LoadModes() - for(var/I in config_files) - LoadEntries(I) + if(!LoadEntries("config.txt")) + log_config("No $include directives found in config.txt! Loading legacy game_options/dbconfig/comms files...") + LoadEntries("game_options.txt") + LoadEntries("dbconfig.txt") + LoadEntries("comms.txt") loadmaplist(CONFIG_MAPS_FILE) /datum/controller/configuration/Destroy() @@ -42,8 +45,6 @@ GLOBAL_PROTECT(config_dir) var/list/_entries_by_type = list() entries_by_type = _entries_by_type - . = list() - for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case var/datum/config_entry/E = I if(initial(E.abstract_type) == I) @@ -57,24 +58,30 @@ GLOBAL_PROTECT(config_dir) continue _entries[esname] = E _entries_by_type[I] = E - .[E.resident_file] = TRUE /datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) entries -= CE.name entries_by_type -= CE.type -/datum/controller/configuration/proc/LoadEntries(filename) +/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) + var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename + if(filename_to_test in stack) + log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") + return + stack = stack + filename_to_test + log_config("Loading config file [filename]...") var/list/lines = world.file2list("[GLOB.config_dir][filename]") var/list/_entries = entries for(var/L in lines) if(!L) continue - - if(copytext(L, 1, 2) == "#") + + var/firstchar = copytext(L, 1, 2) + if(firstchar == "#") continue - var/lockthis = copytext(L, 1, 2) == "@" + var/lockthis = firstchar == "@" if(lockthis) L = copytext(L, 2) @@ -91,14 +98,17 @@ GLOBAL_PROTECT(config_dir) if(!entry) continue + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + continue + var/datum/config_entry/E = _entries[entry] if(!E) log_config("Unknown setting in configuration: '[entry]'") continue - - if(filename != E.resident_file) - log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") - continue if(lockthis) E.protection |= CONFIG_ENTRY_LOCKED @@ -107,10 +117,14 @@ GLOBAL_PROTECT(config_dir) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") else if(E.modified && !E.dupes_allowed) - log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") + log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + + E.resident_file = filename if(validated) E.modified = TRUE + + . = TRUE /datum/controller/configuration/can_vv_get(var_name) return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index bf099f6cb6..70197b6fd4 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -1,22 +1,24 @@ -#define CURRENT_RESIDENT_FILE "comms.txt" - -CONFIG_DEF(string/comms_key) +/datum/config_entry/string/comms_key protection = CONFIG_ENTRY_HIDDEN /datum/config_entry/string/comms_key/ValidateAndSet(str_val) return str_val != "default_pwd" && length(str_val) > 6 && ..() +<<<<<<< HEAD CONFIG_DEF(string/cross_server_address) +======= +/datum/config_entry/keyed_string_list/cross_server +>>>>>>> 8c537ea... Adds config inclusion system (#33307) protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) return str_val != "byond:\\address:port" && ..() -CONFIG_DEF(string/cross_comms_name) +/datum/config_entry/string/cross_comms_name GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. -CONFIG_DEF(string/medal_hub_address) +/datum/config_entry/string/medal_hub_address -CONFIG_DEF(string/medal_hub_password) +/datum/config_entry/string/medal_hub_password protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm deleted file mode 100644 index 37081c15dd..0000000000 --- a/code/controllers/configuration/entries/config.dm +++ /dev/null @@ -1,390 +0,0 @@ -#define CURRENT_RESIDENT_FILE "config.txt" - -CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins - value = "Game Master" - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/servername) // server name (the name of the game window) - -CONFIG_DEF(string/serversqlname) // short form server name used for the DB - -CONFIG_DEF(string/stationname) // station name (the name of the station in-game) - -CONFIG_DEF(number/lobby_countdown) // In between round countdown. - value = 120 - min_val = 0 - -CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown - value = 25 - min_val = 0 - -CONFIG_DEF(flag/hub) // if the game appears on the hub or not - -CONFIG_DEF(flag/log_ooc) // log OOC channel - -CONFIG_DEF(flag/log_access) // log login/logout - -CONFIG_DEF(flag/log_say) // log client say - -CONFIG_DEF(flag/log_admin) // log admin actions - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/log_prayer) // log prayers - -CONFIG_DEF(flag/log_law) // log lawchanges - -CONFIG_DEF(flag/log_game) // log game events - -CONFIG_DEF(flag/log_vote) // log voting - -CONFIG_DEF(flag/log_whisper) // log client whisper - -CONFIG_DEF(flag/log_attack) // log attack messages - -CONFIG_DEF(flag/log_emote) // log emotes - -CONFIG_DEF(flag/log_adminchat) // log admin chat messages - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/log_pda) // log pda messages - -CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - -CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls - -CONFIG_DEF(flag/log_manifest) // log crew manifest to seperate file - -CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour - -CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart - -CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode - -CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default) - value = 6000 - min_val = 0 - -CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute) - value = 600 - min_val = 0 - -CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart - -CONFIG_DEF(flag/no_dead_vote) // dead people can't vote - -CONFIG_DEF(flag/allow_metadata) // Metadata is supported. - -CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set - -CONFIG_DEF(number/fps) - value = 20 - min_val = 1 - max_val = 100 //byond will start crapping out at 50, so this is just ridic - var/sync_validate = FALSE - -/datum/config_entry/number/fps/ValidateAndSet(str_val) - . = ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] - if(!TL.sync_validate) - TL.ValidateAndSet(10 / value) - sync_validate = FALSE - -CONFIG_DEF(number/ticklag) - integer = FALSE - var/sync_validate = FALSE - -/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps - var/datum/config_entry/CE = /datum/config_entry/number/fps - value = 10 / initial(CE.value) - ..() - -/datum/config_entry/number/ticklag/ValidateAndSet(str_val) - . = text2num(str_val) > 0 && ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] - if(!FPS.sync_validate) - FPS.ValidateAndSet(10 / value) - sync_validate = FALSE - -CONFIG_DEF(flag/allow_holidays) - -CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling - value = TICK_LIMIT_MC_INIT_DEFAULT - min_val = 0 //oranges warned us - integer = FALSE - -CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/hostedby) - -CONFIG_DEF(flag/norespawn) - -CONFIG_DEF(flag/guest_jobban) - -CONFIG_DEF(flag/usewhitelist) - -CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database - -CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. - -CONFIG_DEF(flag/use_exp_tracking) - -CONFIG_DEF(flag/use_exp_restrictions_heads) - -CONFIG_DEF(number/use_exp_restrictions_heads_hours) - value = 0 - min_val = 0 - -CONFIG_DEF(flag/use_exp_restrictions_heads_department) - -CONFIG_DEF(flag/use_exp_restrictions_other) - -CONFIG_DEF(flag/use_exp_restrictions_admin_bypass) - -CONFIG_DEF(string/server) - -CONFIG_DEF(string/banappeals) - -CONFIG_DEF(string/wikiurl) - value = "http://www.tgstation13.org/wiki" - -CONFIG_DEF(string/forumurl) - value = "http://tgstation13.org/phpBB/index.php" - -CONFIG_DEF(string/rulesurl) - value = "http://www.tgstation13.org/wiki/Rules" - -CONFIG_DEF(string/githuburl) - value = "https://www.github.com/tgstation/-tg-station" - -CONFIG_DEF(number/githubrepoid) - value = null - min_val = 0 - -CONFIG_DEF(flag/guest_ban) - -CONFIG_DEF(number/id_console_jobslot_delay) - value = 30 - min_val = 0 - -CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive) - value = 3000 - min_val = 0 - -/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) - . = ..() - if(.) - value *= 10 //documented as seconds in config.txt - -CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive) - value = 3000 - min_val = 0 - -/datum/config_entry/number/afk_period/ValidateAndSet(str_val) - . = ..() - if(.) - value *= 10 //documented as seconds in config.txt - -CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players - -CONFIG_DEF(flag/load_jobs_from_txt) - -CONFIG_DEF(flag/forbid_singulo_possession) - -CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention - -CONFIG_DEF(string/panic_server_name) - -/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) - return str_val != "\[Put the name here\]" && ..() - -CONFIG_DEF(string/panic_server_address) //Reconnect a player this linked server if this server isn't accepting new players - -/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) - return str_val != "byond://address:port" && ..() - -CONFIG_DEF(string/invoke_youtubedl) - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -CONFIG_DEF(flag/show_irc_name) - -CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)? - -CONFIG_DEF(number/note_fresh_days) - value = null - min_val = 0 - integer = FALSE - -CONFIG_DEF(number/note_stale_days) - value = null - min_val = 0 - integer = FALSE - -CONFIG_DEF(flag/maprotation) - -CONFIG_DEF(number/maprotatechancedelta) - value = 0.75 - min_val = 0 - max_val = 1 - integer = FALSE - -CONFIG_DEF(number/soft_popcap) - value = null - min_val = 0 - -CONFIG_DEF(number/hard_popcap) - value = null - min_val = 0 - -CONFIG_DEF(number/extreme_popcap) - value = null - min_val = 0 - -CONFIG_DEF(string/soft_popcap_message) - value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." - -CONFIG_DEF(string/hard_popcap_message) - value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." - -CONFIG_DEF(string/extreme_popcap_message) - value = "The server is currently serving a high number of users, find alternative servers." - -CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting - -CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player - min_val = -1 - -CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account - min_val = 0 - -CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time? - -CONFIG_DEF(flag/check_randomizer) - -CONFIG_DEF(string/ipintel_email) - -/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) - return str_val != "ch@nge.me" && ..() - -CONFIG_DEF(number/ipintel_rating_bad) - value = 1 - integer = FALSE - min_val = 0 - max_val = 1 - -CONFIG_DEF(number/ipintel_save_good) - value = 12 - min_val = 0 - -CONFIG_DEF(number/ipintel_save_bad) - value = 1 - min_val = 0 - -CONFIG_DEF(string/ipintel_domain) - value = "check.getipintel.net" - -CONFIG_DEF(flag/aggressive_changelog) - -CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/allow_webclient) - -CONFIG_DEF(flag/webclient_only_byond_members) - -CONFIG_DEF(flag/announce_admin_logout) - -CONFIG_DEF(flag/announce_admin_login) - -CONFIG_DEF(flag/allow_map_voting) - -CONFIG_DEF(flag/generate_minimaps) - -CONFIG_DEF(number/client_warn_version) - value = null - min_val = 500 - max_val = DM_VERSION - 1 - -CONFIG_DEF(string/client_warn_message) - value = "Your version of byond may have issues or be blocked from accessing this server in the future." - -CONFIG_DEF(flag/client_warn_popup) - -CONFIG_DEF(number/client_error_version) - value = null - min_val = 500 - max_val = DM_VERSION - 1 - -CONFIG_DEF(string/client_error_message) - value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." - -CONFIG_DEF(number/minute_topic_limit) - value = null - min_val = 0 - -CONFIG_DEF(number/second_topic_limit) - value = null - min_val = 0 - -CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error) - value = 600 - min_val = 0 - -CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them - value = 50 - -CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for - value = 6000 - -CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error - value = 50 - -CONFIG_DEF(flag/irc_announce_new_game) - -CONFIG_DEF(flag/debug_admin_hrefs) - -CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) - integer = FALSE - value = 1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate) - integer = FALSE - value = 1.1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount) - value = 65 - -CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount) - value = 60 - -CONFIG_TWEAK(number/mc_tick_rate) - abstract_type = /datum/config_entry/number/mc_tick_rate - -CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) - . = ..() - if (.) - Master.UpdateTickRate() - -CONFIG_DEF(flag/resume_after_initializations) - -CONFIG_TWEAK(flag/resume_after_initializations/ValidateAndSet(str_val)) - . = ..() - if(. && Master.current_runlevel) - world.sleep_offline = !value - -CONFIG_DEF(number/rounds_until_hard_restart) - value = -1 - min_val = 0 - -CONFIG_DEF(string/default_view) - value = "15x15" diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index c46880686a..1ac4d85419 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -1,28 +1,26 @@ -#define CURRENT_RESIDENT_FILE "dbconfig.txt" - -CONFIG_DEF(flag/sql_enabled) // for sql switching +/datum/config_entry/flag/sql_enabled // for sql switching protection = CONFIG_ENTRY_LOCKED -CONFIG_DEF(string/address) +/datum/config_entry/string/address value = "localhost" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(number/port) +/datum/config_entry/number/port value = 3306 min_val = 0 max_val = 65535 protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_database) +/datum/config_entry/string/feedback_database value = "test" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_login) +/datum/config_entry/string/feedback_login value = "root" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_password) +/datum/config_entry/string/feedback_password protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_tableprefix) +/datum/config_entry/string/feedback_tableprefix protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index b04d7845f5..4fa6133883 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -1,247 +1,245 @@ -#define CURRENT_RESIDENT_FILE "game_options.txt" +/datum/config_entry/number_list/repeated_mode_adjust -CONFIG_DEF(number_list/repeated_mode_adjust) - -CONFIG_DEF(keyed_number_list/probability) +/datum/config_entry/keyed_number_list/probability /datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/max_pop) +/datum/config_entry/keyed_number_list/max_pop /datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/min_pop) +/datum/config_entry/keyed_number_list/min_pop /datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die +/datum/config_entry/keyed_flag_list/continuous // which roundtypes continue if all antagonists die /datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system +/datum/config_entry/keyed_flag_list/midround_antag // which roundtypes use the midround antagonist system /datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_string_list/policy) +/datum/config_entry/keyed_string_list/policy -CONFIG_DEF(number/damage_multiplier) +/datum/config_entry/number/damage_multiplier value = 1 integer = FALSE -CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on. +/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. min_val = 0 -CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access. +/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. -CONFIG_DEF(flag/assistants_have_maint_access) +/datum/config_entry/flag/assistants_have_maint_access -CONFIG_DEF(flag/security_has_maint_access) +/datum/config_entry/flag/security_has_maint_access -CONFIG_DEF(flag/everyone_has_maint_access) +/datum/config_entry/flag/everyone_has_maint_access -CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts +/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts -CONFIG_DEF(flag/force_random_names) +/datum/config_entry/flag/force_random_names -CONFIG_DEF(flag/humans_need_surnames) +/datum/config_entry/flag/humans_need_surnames -CONFIG_DEF(flag/allow_ai) // allow ai job +/datum/config_entry/flag/allow_ai // allow ai job -CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. +/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. -CONFIG_DEF(flag/disable_peaceborg) +/datum/config_entry/flag/disable_peaceborg -CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors +/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors value = 6 min_val = 1 -CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team +/datum/config_entry/number/brother_scaling_coeff //how many players per brother team value = 25 min_val = 1 -CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings +/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings value = 6 min_val = 1 -CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions +/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions value = 8 min_val = 1 -CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team +/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team value = 15 min_val = 1 -CONFIG_DEF(number/traitor_objectives_amount) +/datum/config_entry/number/traitor_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(number/brother_objectives_amount) +/datum/config_entry/number/brother_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors +/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors -CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other +/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other -CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other +/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other -CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff +/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff -CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling +/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling -CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system +/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) value = 60 min_val = 0 -CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist +/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist value = 0.7 integer = FALSE min_val = 0 max_val = 1 -CONFIG_DEF(number/shuttle_refuel_delay) +/datum/config_entry/number/shuttle_refuel_delay value = 12000 min_val = 0 -CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen +/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen -CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. +/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go. -CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game +/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game -CONFIG_DEF(flag/no_summon_guns) //No +/datum/config_entry/flag/no_summon_guns //No -CONFIG_DEF(flag/no_summon_magic) //Fun +/datum/config_entry/flag/no_summon_magic //Fun -CONFIG_DEF(flag/no_summon_events) //Allowed +/datum/config_entry/flag/no_summon_events //Allowed -CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. +/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. -CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station +/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station value = 55 min_val = 30 -CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join +/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join -CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join +/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join -CONFIG_DEF(string/alert_green) +/datum/config_entry/string/alert_green value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." -CONFIG_DEF(string/alert_blue_upto) +/datum/config_entry/string/alert_blue_upto value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." -CONFIG_DEF(string/alert_blue_downto) +/datum/config_entry/string/alert_blue_downto value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." -CONFIG_DEF(string/alert_red_upto) +/datum/config_entry/string/alert_red_upto value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." -CONFIG_DEF(string/alert_red_downto) +/datum/config_entry/string/alert_red_downto value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." -CONFIG_DEF(string/alert_delta) +/datum/config_entry/string/alert_delta value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." -CONFIG_DEF(flag/revival_pod_plants) +/datum/config_entry/flag/revival_pod_plants -CONFIG_DEF(flag/revival_cloning) +/datum/config_entry/flag/revival_cloning -CONFIG_DEF(number/revival_brain_life) +/datum/config_entry/number/revival_brain_life value = -1 min_val = -1 -CONFIG_DEF(flag/rename_cyborg) +/datum/config_entry/flag/rename_cyborg -CONFIG_DEF(flag/ooc_during_round) +/datum/config_entry/flag/ooc_during_round -CONFIG_DEF(flag/emojis) +/datum/config_entry/flag/emojis -CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. +/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs. var/static/value_cache = 0 -CONFIG_TWEAK(number/run_delay/ValidateAndSet()) +/datum/config_entry/number/run_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/walk_delay) +/datum/config_entry/number/walk_delay var/static/value_cache = 0 -CONFIG_TWEAK(number/walk_delay/ValidateAndSet()) +/datum/config_entry/number/walk_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways -CONFIG_DEF(number/robot_delay) -CONFIG_DEF(number/monkey_delay) -CONFIG_DEF(number/alien_delay) -CONFIG_DEF(number/slime_delay) -CONFIG_DEF(number/animal_delay) +/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways +/datum/config_entry/number/robot_delay +/datum/config_entry/number/monkey_delay +/datum/config_entry/number/alien_delay +/datum/config_entry/number/slime_delay +/datum/config_entry/number/animal_delay -CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. +/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. value = 18000 min_val = 0 -CONFIG_DEF(flag/ghost_interaction) +/datum/config_entry/flag/ghost_interaction -CONFIG_DEF(flag/silent_ai) -CONFIG_DEF(flag/silent_borg) +/datum/config_entry/flag/silent_ai +/datum/config_entry/flag/silent_borg -CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff +/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff -CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with. +/datum/config_entry/number/default_laws //Controls what laws the AI spawns with. value = 0 min_val = 0 max_val = 3 -CONFIG_DEF(number/silicon_max_law_amount) +/datum/config_entry/number/silicon_max_law_amount value = 12 min_val = 0 -CONFIG_DEF(keyed_flag_list/random_laws) +/datum/config_entry/keyed_flag_list/random_laws -CONFIG_DEF(keyed_number_list/law_weight) +/datum/config_entry/keyed_number_list/law_weight splitter = "," -CONFIG_DEF(number/assistant_cap) +/datum/config_entry/number/assistant_cap value = -1 min_val = -1 -CONFIG_DEF(flag/starlight) -CONFIG_DEF(flag/grey_assistants) +/datum/config_entry/flag/starlight +/datum/config_entry/flag/grey_assistants -CONFIG_DEF(number/lavaland_budget) +/datum/config_entry/number/lavaland_budget value = 60 min_val = 0 -CONFIG_DEF(number/space_budget) +/datum/config_entry/number/space_budget value = 16 min_val = 0 -CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set +/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set -CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts +/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/events_min_players_mul) +/datum/config_entry/number/events_min_players_mul value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/mice_roundstart) +/datum/config_entry/number/mice_roundstart value = 10 min_val = 0 -CONFIG_DEF(number/bombcap) +/datum/config_entry/number/bombcap value = 14 min_val = 4 @@ -258,9 +256,9 @@ CONFIG_DEF(flag/allow_extended_miscreants) GLOB.MAX_EX_FLASH_RANGE = value GLOB.MAX_EX_FLAME_RANGE = value -CONFIG_DEF(number/emergency_shuttle_autocall_threshold) +/datum/config_entry/number/emergency_shuttle_autocall_threshold min_val = 0 max_val = 1 integer = FALSE -CONFIG_DEF(flag/ic_printing) +/datum/config_entry/flag/ic_printing diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm new file mode 100644 index 0000000000..637e65c46f --- /dev/null +++ b/code/controllers/configuration/entries/general.dm @@ -0,0 +1,388 @@ +/datum/config_entry/flag/autoadmin // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/autoadmin_rank // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/servername // server name (the name of the game window) + +/datum/config_entry/string/serversqlname // short form server name used for the DB + +/datum/config_entry/string/stationname // station name (the name of the station in-game) + +/datum/config_entry/number/lobby_countdown // In between round countdown. + value = 120 + min_val = 0 + +/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown + value = 25 + min_val = 0 + +/datum/config_entry/flag/hub // if the game appears on the hub or not + +/datum/config_entry/flag/log_ooc // log OOC channel + +/datum/config_entry/flag/log_access // log login/logout + +/datum/config_entry/flag/log_say // log client say + +/datum/config_entry/flag/log_admin // log admin actions + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_prayer // log prayers + +/datum/config_entry/flag/log_law // log lawchanges + +/datum/config_entry/flag/log_game // log game events + +/datum/config_entry/flag/log_vote // log voting + +/datum/config_entry/flag/log_whisper // log client whisper + +/datum/config_entry/flag/log_attack // log attack messages + +/datum/config_entry/flag/log_emote // log emotes + +/datum/config_entry/flag/log_adminchat // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_pda // log pda messages + +/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + +/datum/config_entry/flag/log_world_topic // log all world.Topic() calls + +/datum/config_entry/flag/log_manifest // log crew manifest to seperate file + +/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour + +/datum/config_entry/flag/allow_vote_restart // allow votes to restart + +/datum/config_entry/flag/allow_vote_mode // allow votes to change mode + +/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart + +/datum/config_entry/flag/no_dead_vote // dead people can't vote + +/datum/config_entry/flag/allow_metadata // Metadata is supported. + +/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set + +/datum/config_entry/number/fps + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/number/ticklag + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/flag/allow_holidays + +/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/hostedby + +/datum/config_entry/flag/norespawn + +/datum/config_entry/flag/guest_jobban + +/datum/config_entry/flag/usewhitelist + +/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database + +/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +/datum/config_entry/flag/use_exp_tracking + +/datum/config_entry/flag/use_exp_restrictions_heads + +/datum/config_entry/number/use_exp_restrictions_heads_hours + value = 0 + min_val = 0 + +/datum/config_entry/flag/use_exp_restrictions_heads_department + +/datum/config_entry/flag/use_exp_restrictions_other + +/datum/config_entry/flag/use_exp_restrictions_admin_bypass + +/datum/config_entry/string/server + +/datum/config_entry/string/banappeals + +/datum/config_entry/string/wikiurl + value = "http://www.tgstation13.org/wiki" + +/datum/config_entry/string/forumurl + value = "http://tgstation13.org/phpBB/index.php" + +/datum/config_entry/string/rulesurl + value = "http://www.tgstation13.org/wiki/Rules" + +/datum/config_entry/string/githuburl + value = "https://www.github.com/tgstation/-tg-station" + +/datum/config_entry/number/githubrepoid + value = null + min_val = 0 + +/datum/config_entry/flag/guest_ban + +/datum/config_entry/number/id_console_jobslot_delay + value = 30 + min_val = 0 + +/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/number/afk_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/flag/kick_inactive //force disconnect for inactive players + +/datum/config_entry/flag/load_jobs_from_txt + +/datum/config_entry/flag/forbid_singulo_possession + +/datum/config_entry/flag/automute_on //enables automuting/spam prevention + +/datum/config_entry/string/panic_server_name + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +/datum/config_entry/string/invoke_youtubedl + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/show_irc_name + +/datum/config_entry/flag/see_own_notes //Can players see their own admin notes + +/datum/config_entry/number/note_fresh_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/number/note_stale_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/flag/maprotation + +/datum/config_entry/number/maprotatechancedelta + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/number/soft_popcap + value = null + min_val = 0 + +/datum/config_entry/number/hard_popcap + value = null + min_val = 0 + +/datum/config_entry/number/extreme_popcap + value = null + min_val = 0 + +/datum/config_entry/string/soft_popcap_message + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +/datum/config_entry/string/hard_popcap_message + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +/datum/config_entry/string/extreme_popcap_message + value = "The server is currently serving a high number of users, find alternative servers." + +/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting + +/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player + min_val = -1 + +/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account + min_val = 0 + +/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? + +/datum/config_entry/flag/check_randomizer + +/datum/config_entry/string/ipintel_email + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +/datum/config_entry/number/ipintel_rating_bad + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/ipintel_save_good + value = 12 + min_val = 0 + +/datum/config_entry/number/ipintel_save_bad + value = 1 + min_val = 0 + +/datum/config_entry/string/ipintel_domain + value = "check.getipintel.net" + +/datum/config_entry/flag/aggressive_changelog + +/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/allow_webclient + +/datum/config_entry/flag/webclient_only_byond_members + +/datum/config_entry/flag/announce_admin_logout + +/datum/config_entry/flag/announce_admin_login + +/datum/config_entry/flag/allow_map_voting + +/datum/config_entry/flag/generate_minimaps + +/datum/config_entry/number/client_warn_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_warn_message + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +/datum/config_entry/flag/client_warn_popup + +/datum/config_entry/number/client_error_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_error_message + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +/datum/config_entry/number/minute_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/second_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error + value = 600 + min_val = 0 + +/datum/config_entry/number/error_limit // How many occurrences before the next will silence them + value = 50 + +/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for + value = 6000 + +/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +/datum/config_entry/flag/irc_announce_new_game + +/datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate + integer = FALSE + value = 1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate + integer = FALSE + value = 1.1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount + value = 65 + +/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount + value = 60 + +/datum/config_entry/number/mc_tick_rate + abstract_type = /datum/config_entry/number/mc_tick_rate + +/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) + . = ..() + if (.) + Master.UpdateTickRate() + +/datum/config_entry/flag/resume_after_initializations + +/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) + . = ..() + if(. && Master.current_runlevel) + world.sleep_offline = !value + +/datum/config_entry/number/rounds_until_hard_restart + value = -1 + min_val = 0 + +/datum/config_entry/string/default_view + value = "15x15" diff --git a/config/config.txt b/config/config.txt index fb648a5fa9..e43b38b568 100644 --- a/config/config.txt +++ b/config/config.txt @@ -1,3 +1,9 @@ +# You can use the "$include" directive to split your configs however you want + +$include game_options.txt +$include dbconfig.txt +$include comms.txt + # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: # @SERVERNAME tgstation diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..cfe9e0d0c5 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -224,9 +224,9 @@ #include "code\controllers\configuration\config_entry.dm" #include "code\controllers\configuration\configuration.dm" #include "code\controllers\configuration\entries\comms.dm" -#include "code\controllers\configuration\entries\config.dm" #include "code\controllers\configuration\entries\dbconfig.dm" #include "code\controllers\configuration\entries\game_options.dm" +#include "code\controllers\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" From e77c1a8a074fa829e117bd0e3653c19f99dd3df5 Mon Sep 17 00:00:00 2001 From: Michiyamenotehifunana <31995558+Michiyamenotehifunana@users.noreply.github.com> Date: Fri, 15 Dec 2017 16:57:22 +0800 Subject: [PATCH 009/213] Consolidates NEB code into a modular package --- code/citadel/cit_weapons.dm | 240 ------------- .../objects/items/melee/eutactic_blades.dm} | 335 ++++++++++++------ .../code/modules/crafting/recipes.dm | 5 + .../item/hypereutactic.dmi | Bin .../icons/eutactic/item/noneutactic.dmi | Bin .../mob/hypereutactic_left.dmi | Bin .../mob/hypereutactic_right.dmi | Bin .../icons/eutactic/mob/noneutactic_left.dmi | Bin .../icons/eutactic/mob/noneutactic_right.dmi | Bin tgstation.dme | 4 +- 10 files changed, 238 insertions(+), 346 deletions(-) delete mode 100644 code/citadel/cit_weapons.dm rename modular_citadel/{hypereutactic_blade.dm => code/game/objects/items/melee/eutactic_blades.dm} (52%) create mode 100644 modular_citadel/code/modules/crafting/recipes.dm rename modular_citadel/icons/{hypereutactic => eutactic}/item/hypereutactic.dmi (100%) rename icons/obj/cit_weapons.dmi => modular_citadel/icons/eutactic/item/noneutactic.dmi (100%) rename modular_citadel/icons/{hypereutactic => eutactic}/mob/hypereutactic_left.dmi (100%) rename modular_citadel/icons/{hypereutactic => eutactic}/mob/hypereutactic_right.dmi (100%) rename icons/mob/citadel/melee_lefthand.dmi => modular_citadel/icons/eutactic/mob/noneutactic_left.dmi (100%) rename icons/mob/citadel/melee_righthand.dmi => modular_citadel/icons/eutactic/mob/noneutactic_right.dmi (100%) diff --git a/code/citadel/cit_weapons.dm b/code/citadel/cit_weapons.dm deleted file mode 100644 index dbf0448240..0000000000 --- a/code/citadel/cit_weapons.dm +++ /dev/null @@ -1,240 +0,0 @@ -/obj/item/toy/sword/cx - name = "\improper DX Non-Euplastic LightSword" - desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." - icon = 'icons/obj/cit_weapons.dmi' - icon_state = "cxsword_hilt" - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - active = FALSE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - light_color = "#37FFF7" - var/light_brightness = 3 - actions_types = list() - -/obj/item/toy/sword/cx/attack_self(mob/user) - active = !( active ) - - if (active) - to_chat(user, "You activate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/nebon.ogg', 50, 1) - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("slashed", "stabbed", "ravaged") - set_light(light_brightness) - update_icon() - - else - to_chat(user, "You deactivate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/neboff.ogg', 50, 1) - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - set_light(0) - update_icon() - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - add_fingerprint(user) - -/obj/item/toy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/toy/sword/cx/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) - if(istype(W, /obj/item/toy/sword/cx)) - if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1)) - to_chat(user, "\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!") - return - else - to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") - new /obj/item/twohanded/hypereutactic/toy(user.loc) - qdel(W) - qdel(src) - else - return ..() - -/obj/item/toy/sword/cx/examine(mob/user) - ..() - to_chat(user, "Alt-click to recolor it.") - -/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys - -/datum/design/toyneb - name = "Non-Euplastic Blade" - id = "toyneb" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) - build_path = /obj/item/toy/sword/cx - category = list("hacked", "Misc") -*/ // There, I stopped doing it - -/datum/crafting_recipe/toyneb - name = "Non-Euplastic Blade" - reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/toy/sword = 1) - result = /obj/item/toy/sword/cx - category = CAT_MISC - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/obj/item/melee/transforming/energy/sword/cx - name = "non-eutactic blade" - desc = "The CX Armories Type-69 Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." - icon_state = "cxsword_hilt" - icon = 'icons/obj/cit_weapons.dmi' - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - force = 3 - throwforce = 5 - hitsound = "swing_hit" //it starts deactivated - hitsound_on = 'sound/weapons/nebhit.ogg' - attack_verb_off = list("tapped", "poked") - throw_speed = 3 - throw_range = 5 - sharpness = IS_SHARP - embed_chance = 40 - embedded_impact_pain_multiplier = 10 - armour_penetration = 0 - block_chance = 60 - light_color = "#37FFF7" - actions_types = list() - -/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) - active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE - if(active) //also I need to rip out the iconstate changing bits - force = force_on - throwforce = throwforce_on - hitsound = hitsound_on - throw_speed = 4 - if(attack_verb_on.len) - attack_verb = attack_verb_on - w_class = w_class_on - START_PROCESSING(SSobj, src) - set_light(brightness_on) - update_icon() - else - force = initial(force) - throwforce = initial(throwforce) - hitsound = initial(hitsound) - throw_speed = initial(throw_speed) - if(attack_verb_off.len) - attack_verb = attack_verb_off - w_class = initial(w_class) - STOP_PROCESSING(SSobj, src) - set_light(0) - update_icon() - transform_messages(user, supress_message_text) - add_fingerprint(user) - return TRUE - -/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") - -/obj/item/melee/transforming/energy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/melee/transforming/energy/sword/cx/examine(mob/user) - ..() - to_chat(user, "Alt-click to recolor it.") - -/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/melee/transforming/energy/sword/cx/traitor - name = "\improper Dragon's Tooth Sword" - desc = "The Dragon's Tooth sword is a blackmarket modification of the CX Armouries Type-69 NEB, \ - which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ - It appears to have a wooden grip and a shaved down guard." - icon_state = "cxsword_hilt_traitor" - armour_penetration = 35 - embed_chance = 75 - block_chance = 50 - hitsound_on = 'sound/weapons/blade1.ogg' - light_color = "#37F0FF" - -/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/modular_citadel/hypereutactic_blade.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm similarity index 52% rename from modular_citadel/hypereutactic_blade.dm rename to modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index f0cfa55109..d324c95511 100644 --- a/modular_citadel/hypereutactic_blade.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -1,10 +1,211 @@ -/* fuckhuge esword thingy */ +/*///////////////////////////////////////////////////////////////////////// +///////////// The TRUE Energy Sword /////////////////////////// +*////////////////////////////////////////////////////////////////////////// + +/obj/item/melee/transforming/energy/sword/cx + name = "non-eutactic blade" + desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." + icon_state = "cxsword_hilt" + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + force = 3 + throwforce = 5 + hitsound = "swing_hit" //it starts deactivated + hitsound_on = 'sound/weapons/nebhit.ogg' + attack_verb_off = list("tapped", "poked") + throw_speed = 3 + throw_range = 5 + sharpness = IS_SHARP + embed_chance = 40 + embedded_impact_pain_multiplier = 10 + armour_penetration = 0 + block_chance = 60 + light_color = "#37FFF7" + actions_types = list() + +/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) + active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE + if(active) //also I'd need to rip out the iconstate changing bits + force = force_on + throwforce = throwforce_on + hitsound = hitsound_on + throw_speed = 4 + if(attack_verb_on.len) + attack_verb = attack_verb_on + w_class = w_class_on + START_PROCESSING(SSobj, src) + set_light(brightness_on) + update_icon() + else + force = initial(force) + throwforce = initial(throwforce) + hitsound = initial(hitsound) + throw_speed = initial(throw_speed) + if(attack_verb_off.len) + attack_verb = attack_verb_off + w_class = initial(w_class) + STOP_PROCESSING(SSobj, src) + set_light(0) + update_icon() + transform_messages(user, supress_message_text) + add_fingerprint(user) + return TRUE + +/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") + +/obj/item/melee/transforming/energy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/melee/transforming/energy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +//OBLIGATORY TOY MEMES ///////////////////////////////////// + +/obj/item/toy/sword/cx + name = "\improper DX Non-Euplastic LightSword" + desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + icon_state = "cxsword_hilt" + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + active = FALSE + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + light_color = "#37FFF7" + var/light_brightness = 3 + actions_types = list() + +/obj/item/toy/sword/cx/attack_self(mob/user) + active = !( active ) + + if (active) + to_chat(user, "You activate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/nebon.ogg', 50, 1) + w_class = WEIGHT_CLASS_BULKY + attack_verb = list("slashed", "stabbed", "ravaged") + set_light(light_brightness) + update_icon() + + else + to_chat(user, "You deactivate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/neboff.ogg', 50, 1) + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + set_light(0) + update_icon() + + add_fingerprint(user) + +/obj/item/toy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/toy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) + if(istype(W, /obj/item/toy/sword/cx)) + if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1)) + to_chat(user, "\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!") + return + else + to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") + new /obj/item/twohanded/hypereutactic/toy(user.loc) + qdel(W) + qdel(src) + else + return ..() + +/obj/item/toy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +///////////////////////////////////////////////////// +// HYPEREUTACTIC Blades ///////////////////////// +///////////////////////////////////////////////////// /obj/item/twohanded/hypereutactic - icon = 'modular_citadel/icons/hypereutactic/item/hypereutactic.dmi' + icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi' icon_state = "hypereutactic" - lefthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi' - righthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi' + lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi' item_state = "hypereutactic" inhand_x_dimension = 64 inhand_y_dimension = 64 @@ -55,8 +256,8 @@ slowdown = initial(slowdown) /obj/item/twohanded/hypereutactic/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_gem") + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem") if(light_color) blade_overlay.color = light_color @@ -68,7 +269,6 @@ if(wielded) add_overlay(blade_overlay) - if(ismob(loc)) var/mob/M = loc M.update_inv_hands() @@ -76,13 +276,11 @@ clean_blood()//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) /obj/item/twohanded/hypereutactic/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return if(user.incapacitated() || !istype(user)) to_chat(user, "You can't do that right now!") return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") var/energy_color_input = input(usr,"Choose Energy Color") as color|null @@ -108,7 +306,7 @@ -////////// stuff beneath this is all taken from the desword //////////// +////////// stuff beneath this is all taken from the desword //////////// wow very professional such OOP wow @@ -137,12 +335,12 @@ /obj/item/twohanded/hypereutactic/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) if(wielded) return ..() - return 0 + return FALSE /obj/item/twohanded/hypereutactic/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up if(wielded) to_chat(user, "You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!") - return 1 + return TRUE /obj/item/twohanded/hypereutactic/process() if(wielded) @@ -152,7 +350,7 @@ /obj/item/twohanded/hypereutactic/IsReflect() if(wielded) - return 1 + return TRUE /obj/item/twohanded/hypereutactic/ignition_effect(atom/A, mob/user) // same as /obj/item/melee/transforming/energy, mostly @@ -167,7 +365,6 @@ playsound(loc, hitsound, get_clamped_volume(), 1, -1) add_fingerprint(user) - ////////////////// TOY VERSION ///////////////////////////// /obj/item/twohanded/hypereutactic/toy @@ -182,95 +379,25 @@ attack_verb = list("attacked", "struck", "hit") /obj/item/twohanded/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - return 0 + return FALSE /obj/item/twohanded/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles - return 0 + return FALSE -/* old code that don't work no more -/obj/item/toy/sword/cx/hyper - name = "\improper DX Hyper-Euplastic LightSword" - desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up." - icon = 'modular_citadel/icons/hypereutactic/item/hypereutactic.dmi' - icon_state = "hypereutactic" - lefthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi' - righthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi' - item_state = "hypereutactic" - inhand_x_dimension = 64 - inhand_y_dimension = 64 - active = FALSE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "devastated", "jabbed") - light_color = "#37FFF7" - light_brightness = 3 - actions_types = list() +//////// Tatortot NEB /////////////// (same stats as regular esword) +/obj/item/melee/transforming/energy/sword/cx/traitor + name = "\improper Dragon's Tooth Sword" + desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \ + which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ + It appears to have a wooden grip and a shaved down guard." + icon_state = "cxsword_hilt_traitor" + armour_penetration = 35 + embed_chance = 75 + block_chance = 50 + hitsound_on = 'sound/weapons/blade1.ogg' + light_color = "#37F0FF" -/obj/item/toy/sword/cx/hyper/attack_self(mob/user) - active = !( active ) - - if (active) - to_chat(user, "You activate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/nebon.ogg', 50, 1) - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("slashed", "stabbed", "ravaged") - set_light(light_brightness) - update_icon() - - else - to_chat(user, "You deactivate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/neboff.ogg', 50, 1) - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - set_light(0) - update_icon() - - add_fingerprint(user) - -/obj/item/toy/sword/cx/hyper/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/toy/sword/cx/hyper/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/toy/sword/cx/hyper/worn_overlays(isinhands, icon_file) - if(isinhands) - var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem") - gem_inhand.color = light_color - . += gem_inhand - if(active) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/toy/sword/cx/hyper/attackby(obj/item/W, mob/living/user, params) - return -*/ \ No newline at end of file +/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/modular_citadel/code/modules/crafting/recipes.dm b/modular_citadel/code/modules/crafting/recipes.dm new file mode 100644 index 0000000000..6ed749e7c6 --- /dev/null +++ b/modular_citadel/code/modules/crafting/recipes.dm @@ -0,0 +1,5 @@ +/datum/crafting_recipe/toyneb + name = "Non-Euplastic Blade" + reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4) + result = /obj/item/toy/sword/cx + category = CAT_MISC \ No newline at end of file diff --git a/modular_citadel/icons/hypereutactic/item/hypereutactic.dmi b/modular_citadel/icons/eutactic/item/hypereutactic.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/item/hypereutactic.dmi rename to modular_citadel/icons/eutactic/item/hypereutactic.dmi diff --git a/icons/obj/cit_weapons.dmi b/modular_citadel/icons/eutactic/item/noneutactic.dmi similarity index 100% rename from icons/obj/cit_weapons.dmi rename to modular_citadel/icons/eutactic/item/noneutactic.dmi diff --git a/modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi rename to modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi diff --git a/modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi rename to modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi diff --git a/icons/mob/citadel/melee_lefthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi similarity index 100% rename from icons/mob/citadel/melee_lefthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_left.dmi diff --git a/icons/mob/citadel/melee_righthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi similarity index 100% rename from icons/mob/citadel/melee_righthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_right.dmi diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..384b574883 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -190,7 +190,6 @@ #include "code\citadel\cit_spawners.dm" #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" -#include "code\citadel\cit_weapons.dm" #include "code\citadel\dogborgstuff.dm" #include "code\citadel\plasmacases.dm" #include "code\citadel\crew_objectives\cit_crewobjectives_cargo.dm" @@ -2449,7 +2448,8 @@ #include "modular_citadel\cit_screenshake.dm" #include "modular_citadel\citadel_ghostrole_spawners.dm" #include "modular_citadel\cydonian_armor.dm" -#include "modular_citadel\hypereutactic_blade.dm" #include "modular_citadel\polychromic_clothes.dm" #include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" +#include "modular_citadel\code\modules\crafting\recipes.dm" // END_INCLUDE From 2152bc7121b7882ba137c6d62aa7b23777063d4a Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Fri, 15 Dec 2017 01:27:20 -0800 Subject: [PATCH 010/213] Adds some permission checks to admin/topic (#33527) --- code/modules/admin/admin_investigate.dm | 2 + code/modules/admin/topic.dm | 113 +++++++++++++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 6e327db6b5..f259e9b1e9 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,6 +11,8 @@ return switch(subject) if("notes, memos, watchlist") + if(!check_rights(R_ADMIN)) + return browse_messages() else var/F = file("[GLOB.log_directory]/[subject].html") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index de8dff1518..da8077cfdd 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -58,6 +58,8 @@ toggle_exempt_status(C) else if(href_list["makeAntag"]) + if(!check_rights(R_ADMIN)) + return if (!SSticker.mode) to_chat(usr, "Not until the round starts!") return @@ -201,7 +203,8 @@ return else if(href_list["dbbanaddtype"]) - + if(!check_rights(R_BAN)) + return var/bantype = text2num(href_list["dbbanaddtype"]) var/banckey = href_list["dbbanaddckey"] var/banip = href_list["dbbanaddip"] @@ -599,6 +602,8 @@ return else if(href_list["jobban2"]) + if(!check_rights(R_BAN)) + return var/mob/M = locate(href_list["jobban2"]) if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") @@ -1029,6 +1034,8 @@ return 0 //we didn't do anything! else if(href_list["boot2"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) @@ -1041,72 +1048,110 @@ qdel(M.client) else if(href_list["addmessage"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addmessage"] create_message("message", target_ckey, secret = 0) else if(href_list["addnote"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addnote"] create_message("note", target_ckey) else if(href_list["addwatch"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addwatch"] create_message("watchlist entry", target_ckey, secret = 1) else if(href_list["addmemo"]) + if(!check_rights(R_ADMIN)) + return create_message("memo", secret = 0, browse = 1) else if(href_list["addmessageempty"]) + if(!check_rights(R_ADMIN)) + return create_message("message", secret = 0) else if(href_list["addnoteempty"]) + if(!check_rights(R_ADMIN)) + return create_message("note") else if(href_list["addwatchempty"]) + if(!check_rights(R_ADMIN)) + return create_message("watchlist entry", secret = 1) else if(href_list["deletemessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessage"] delete_message(message_id) else if(href_list["deletemessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessageempty"] delete_message(message_id, browse = 1) else if(href_list["editmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessage"] edit_message(message_id) else if(href_list["editmessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessageempty"] edit_message(message_id, browse = 1) else if(href_list["secretmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["secretmessage"] toggle_message_secrecy(message_id) else if(href_list["searchmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["searchmessages"] browse_messages(index = target) else if(href_list["nonalpha"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["nonalpha"] target = text2num(target) browse_messages(index = target) else if(href_list["showmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessages"] browse_messages(index = target) else if(href_list["showmemo"]) + if(!check_rights(R_ADMIN)) + return browse_messages("memo") else if(href_list["showwatch"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry") else if(href_list["showwatchfilter"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry", filter = 1) else if(href_list["showmessageckey"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessageckey"] var/agegate = TRUE if (href_list["showall"]) @@ -1118,6 +1163,8 @@ browse_messages(target_ckey = target, linkless = 1) else if(href_list["messageedits"]) + if(!check_rights(R_ADMIN)) + return var/message_id = sanitizeSQL("[href_list["messageedits"]]") var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'") if(!query_get_message_edits.warn_execute()) @@ -1568,9 +1615,13 @@ C.jumptocoord(x,y,z) else if(href_list["adminchecklaws"]) + if(!check_rights(R_ADMIN)) + return output_ai_laws() else if(href_list["admincheckdevilinfo"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["admincheckdevilinfo"]) output_devil_info(M) @@ -1979,20 +2030,28 @@ Secrets_topic(href_list["secrets"],href_list) else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster. src.access_news_network() else if(href_list["ac_set_channel_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked src.access_news_network() else if(href_list["ac_submit_new_channel"]) + if(!check_rights(R_ADMIN)) + return var/check = 0 for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels) if(FC.channel_name == src.admincaster_feed_channel.channel_name) @@ -2010,6 +2069,8 @@ src.access_news_network() else if(href_list["ac_set_channel_receiving"]) + if(!check_rights(R_ADMIN)) + return var/list/available_channels = list() for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels) available_channels += F.channel_name @@ -2017,12 +2078,16 @@ src.access_news_network() else if(href_list["ac_set_new_message"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) + if(!check_rights(R_ADMIN)) + return if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" ) src.admincaster_screen = 6 else @@ -2037,22 +2102,32 @@ src.access_news_network() else if(href_list["ac_create_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=2 src.access_news_network() else if(href_list["ac_create_feed_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=3 src.access_news_network() else if(href_list["ac_menu_censor_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=10 src.access_news_network() else if(href_list["ac_menu_censor_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=11 src.access_news_network() else if(href_list["ac_menu_wanted"]) + if(!check_rights(R_ADMIN)) + return var/already_wanted = 0 if(GLOB.news_network.wanted_issue.active) already_wanted = 1 @@ -2064,18 +2139,24 @@ src.access_news_network() else if(href_list["ac_set_wanted_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) while(findtext(src.admincaster_wanted_message.criminal," ") == 1) src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) while (findtext(src.admincaster_wanted_message.body," ") == 1) src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) + if(!check_rights(R_ADMIN)) + return var/input_param = text2num(href_list["ac_submit_wanted"]) if(src.admincaster_wanted_message.criminal == "" || src.admincaster_wanted_message.body == "") src.admincaster_screen = 16 @@ -2092,6 +2173,8 @@ src.access_news_network() else if(href_list["ac_cancel_wanted"]) + if(!check_rights(R_ADMIN)) + return var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel") if(choice=="Confirm") GLOB.news_network.deleteWanted() @@ -2099,36 +2182,50 @@ src.access_news_network() else if(href_list["ac_censor_channel_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"]) FC.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"]) MSG.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_body"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"]) MSG.toggleCensorBody() src.access_news_network() else if(href_list["ac_pick_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"]) src.admincaster_feed_channel = FC src.admincaster_screen=13 src.access_news_network() else if(href_list["ac_toggle_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"]) FC.toggleCensorDclass() src.access_news_network() else if(href_list["ac_view"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=1 src.access_news_network() else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~ + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = text2num(href_list["ac_setScreen"]) if (src.admincaster_screen == 0) if(src.admincaster_feed_channel) @@ -2140,25 +2237,35 @@ src.access_news_network() else if(href_list["ac_show_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 9 src.access_news_network() else if(href_list["ac_pick_censor_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 12 src.access_news_network() else if(href_list["ac_refresh"]) + if(!check_rights(R_ADMIN)) + return src.access_news_network() else if(href_list["ac_set_signature"]) + if(!check_rights(R_ADMIN)) + return src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", "")) src.access_news_network() else if(href_list["ac_del_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"]) var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"]) FM.comments -= FC @@ -2166,6 +2273,8 @@ src.access_news_network() else if(href_list["ac_lock_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"]) FM.locked ^= 1 src.access_news_network() @@ -2262,6 +2371,8 @@ error_viewer.show_to(owner, null, href_list["viewruntime_linear"]) else if(href_list["showrelatedacc"]) + if(!check_rights(R_ADMIN)) + return var/client/C = locate(href_list["client"]) in GLOB.clients var/thing_to_check if(href_list["showrelatedacc"] == "cid") From 533c716e56a23748f6d0f9a8aebe68db6b59ec90 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 Dec 2017 15:07:07 -0500 Subject: [PATCH 012/213] Further emphasises the importance of round ID in issue template (#33538) * Further emphasises the importance of round ID in issue template * Update statbus url. Add server note --- .github/ISSUE_TEMPLATE.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 699ab8ffa2..10f60767bb 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,9 @@ -[Directions]: # (INCLUDE THE ROUND ID from the Status panel or retrieve it from https://atlantaned.space/newSS13tools/round.php ! If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.) +[Directions]: # (If you discovered this issue from playing tgstation hosted servers + + +INCLUDE THE ROUND ID + + +from the Status panel or retrieve it from https://atlantaned.space/statbus/round.php ! If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.) [For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.) From 9adb77c5e3067b5ea839902a93d4832c79eaf1f5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 Dec 2017 15:53:12 -0500 Subject: [PATCH 014/213] Merge pull request #33530 from AutomaticFrenzy/patch/autocall Fix shuttle autocalls when the round is already over --- code/controllers/subsystem/shuttle.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index c80bc17047..35208d4137 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -307,6 +307,9 @@ SUBSYSTEM_DEF(shuttle) return 1 /datum/controller/subsystem/shuttle/proc/autoEvac() + if (!SSticker.IsRoundInProgress()) + return + var/callShuttle = 1 for(var/thing in GLOB.shuttle_caller_list) From b1ca28ef3c49f7ad04f73b25c9c317f1b375111a Mon Sep 17 00:00:00 2001 From: oranges Date: Sat, 16 Dec 2017 11:59:47 +1300 Subject: [PATCH 016/213] Merge pull request #33513 from tgstation/Cyberboss-patch-2 ahelp chat command is silent on success --- code/modules/admin/chat_commands.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index 9a54d094e5..744455bb9a 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -47,7 +47,9 @@ target = AH.initiator_ckey else return "Ticket #[id] not found!" - return IrcPm(target, all_params.Join(" "), sender) + var/res = IrcPm(target, all_params.Join(" "), sender) + if(res != "Message Successful") + return res /datum/server_tools_command/namecheck name = "namecheck" From 1cd746ba67198459ba3d35a28add3c8e13790bd5 Mon Sep 17 00:00:00 2001 From: KomradeSpectre Date: Fri, 15 Dec 2017 18:12:43 -0500 Subject: [PATCH 018/213] Adds two new Integrated Circuit components: hsv2hex converter and rgb2hex converter. (#33433) * Added two new components, HSV to Hex RGB and RGB to Hex RGB, along with icons. * Added valid input ranges to the extended_desc of the new converter components. --- .../subtypes/converters.dm | 52 ++++++++++++++++++ .../obj/assemblies/electronic_components.dmi | Bin 21381 -> 21775 bytes 2 files changed, 52 insertions(+) diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 272dbef071..e2046fd456 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -320,3 +320,55 @@ push_data() activate_pin(2) + +/obj/item/integrated_circuit/converter/hsv2hex + name = "hsv to hexadecimal" + desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color." + extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)." + icon_state = "hsv-hex" + inputs = list( + "hue" = IC_PINTYPE_NUMBER, + "saturation" = IC_PINTYPE_NUMBER, + "value" = IC_PINTYPE_NUMBER + ) + outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/hsv2hex/do_work() + var/result = null + pull_data() + var/hue = get_pin_data(IC_INPUT, 1) + var/saturation = get_pin_data(IC_INPUT, 2) + var/value = get_pin_data(IC_INPUT, 3) + if(isnum(hue)&&isnum(saturation)&&isnum(value)) + result = HSVtoRGB(hsv(AngleToHue(hue),saturation,value)) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/converter/rgb2hex + name = "rgb to hexadecimal" + desc = "This circuit can convert a RGB (Red, Green, Blue) color to a Hexadecimal RGB color." + extended_desc = "The first pin controls red amount, the second pin controls green amount, and the third controls blue amount. All go from 0-255." + icon_state = "rgb-hex" + inputs = list( + "red" = IC_PINTYPE_NUMBER, + "green" = IC_PINTYPE_NUMBER, + "blue" = IC_PINTYPE_NUMBER + ) + outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/rgb2hex/do_work() + var/result = null + pull_data() + var/red = get_pin_data(IC_INPUT, 1) + var/green = get_pin_data(IC_INPUT, 2) + var/blue = get_pin_data(IC_INPUT, 3) + if(isnum(red)&&isnum(green)&&isnum(blue)) + result = rgb(red,green,blue) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi index cc0367b682fad3367eca4d817488780b78d48409..1852079e7392745c0a3911bf1ea557f74b052e0d 100644 GIT binary patch literal 21775 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 From ce22210b47487177c0ca55c7722bfb91109e45cf Mon Sep 17 00:00:00 2001 From: AnturK Date: Sat, 16 Dec 2017 11:07:52 +0100 Subject: [PATCH 020/213] Fixes mecha drifting. (#33542) * Fixes mecha drifting. --- code/game/mecha/mecha.dm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index e50da70c5d..799344fe54 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -24,7 +24,7 @@ infra_luminosity = 15 //byond implementation is bugged. force = 5 flags_1 = HEAR_1 - var/can_move = 1 + var/can_move = 0 //time of next allowed movement var/mob/living/carbon/occupant = null var/step_in = 10 //make a step in step_in/10 sec. var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. @@ -502,7 +502,7 @@ return domove(direction) /obj/mecha/proc/domove(direction) - if(!can_move) + if(can_move >= world.time) return 0 if(!Process_Spacemove(direction)) return 0 @@ -520,21 +520,19 @@ return 0 var/move_result = 0 + var/oldloc = loc if(internal_damage & MECHA_INT_CONTROL_LOST) move_result = mechsteprand() else if(dir != direction && !strafe) move_result = mechturn(direction) else move_result = mechstep(direction) - if(move_result) + if(move_result || loc != oldloc)// halfway done diagonal move still returns false use_power(step_energy_drain) - can_move = 0 - spawn(step_in) - can_move = 1 + can_move = world.time + step_in return 1 return 0 - /obj/mecha/proc/mechturn(direction) setDir(direction) if(turnsound) From 6a09d5c981abf923013aa6533ba82e14697bc2bb Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 17 Dec 2017 00:52:00 -0500 Subject: [PATCH 022/213] Merge pull request #33578 from lzimann/job Changes manage job slots to use a browser datum, also lets it be used before roundstart --- code/modules/admin/admin.dm | 46 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 22365c4584..0b0957e072 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -720,41 +720,43 @@ /datum/admins/proc/manage_free_slots() if(!check_rights()) return - var/dat = "Manage Free Slots" + var/datum/browser/browser = new(usr, "jobmanagement", "Manage Free Slots", 520) + var/list/dat = list() var/count = 0 - if(!SSticker.HasRoundStarted()) - alert(usr, "You cannot manage jobs before the round starts!") + if(!SSjob.initialized) + alert(usr, "You cannot manage jobs before the job subsystem is initialized!") return - for(var/datum/job/job in SSjob.occupations) + dat += "" + + for(var/j in SSjob.occupations) + var/datum/job/job = j count++ var/J_title = html_encode(job.title) var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) var/J_totPos = html_encode(job.total_positions) - if(job.total_positions < 0) - dat += "[J_title]: [J_opPos] (unlimited)" - else - dat += "[J_title]: [J_opPos]/[J_totPos]" + dat += "" continue - if(job.total_positions >= 0) - dat += " Add | " - if(job.total_positions > job.current_positions) - dat += "Remove | " - else - dat += "Remove | " - dat += "Unlimit" else - dat += " Limit" - dat += "
    " + dat += "" + dat += "" + else + dat += "Limit" - dat += "" - var/winheight = 100 + (count * 20) - winheight = min(winheight, 690) - usr << browse(dat, "window=players;size=375x[winheight]") + browser.height = min(100 + count * 20, 650) + browser.set_content(dat.Join()) + browser.open() /datum/admins/proc/create_or_modify_area() set category = "Debug" From 0a4c557336dd41e79565c600949c2b633eaedee5 Mon Sep 17 00:00:00 2001 From: Jordie Date: Sun, 17 Dec 2017 15:23:23 +1100 Subject: [PATCH 024/213] Db schema version check by simplification (#33582) * db schema version check by concatenation * lets just use actual floats * simplifies schema check and some more logging --- code/game/world.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/world.dm b/code/game/world.dm index 2853bb2ef6..6c49e37456 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -62,15 +62,15 @@ GLOBAL_PROTECT(security_mode) var/db_major = text2num(query_db_version.item[1]) var/db_minor = text2num(query_db_version.item[2]) if(db_major != DB_MAJOR_VERSION || db_minor != DB_MINOR_VERSION) - var/which = "behind" - if(db_major < DB_MAJOR_VERSION || db_minor < DB_MINOR_VERSION) - which = "ahead of" - message_admins("Database schema ([db_major].[db_minor]) is [which] the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") - log_sql("Database schema ([db_major].[db_minor]) is [which] the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") + message_admins("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") + log_sql("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") else message_admins("Could not get schema version from database") + log_sql("Could not get schema version from database") else - log_world("Your server failed to establish a connection with the database.") + log_sql("Your server failed to establish a connection with the database.") + else + log_sql("Database is not enabled in configuration.") /world/proc/SetRoundID() if(CONFIG_GET(flag/sql_enabled)) From e038319ba2c7e534bb34ac2456831e677157f712 Mon Sep 17 00:00:00 2001 From: Emmett Gaines Date: Sat, 16 Dec 2017 23:17:39 -0500 Subject: [PATCH 026/213] Quick access hotkeys for backpack and belt --- code/modules/keybindings/bindings_human.dm | 69 ++++++++++++++++++++++ interface/interface.dm | 2 + 2 files changed, 71 insertions(+) create mode 100644 code/modules/keybindings/bindings_human.dm diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm new file mode 100644 index 0000000000..85aeba5f10 --- /dev/null +++ b/code/modules/keybindings/bindings_human.dm @@ -0,0 +1,69 @@ +/mob/living/carbon/human/key_down(_key, client/user) + if(client.keys_held["Shift"]) + switch(_key) + if("E") // Put held thing in belt or take out most recent thing from belt + var/obj/item/thing = get_active_held_item() + var/obj/item/storage/equipped_belt = get_item_by_slot(slot_belt) + if(!equipped_belt) // We also let you equip a belt like this + if(!thing) + to_chat(user, "You have no belt to take something out of.") + return + equip_to_slot_if_possible(thing, slot_belt) + return + if(!istype(equipped_belt)) // not a storage item + if(!thing) + to_chat(user, "You have no belt to take something out of.") + else + to_chat(user, "You can't fit anything in.") + return + if(thing) // put thing in belt + if(equipped_belt.can_be_inserted(thing)) + equipped_belt.handle_item_insertion(thing) + else + to_chat(user, "You can't fit anything in.") + return + if(!equipped_belt.contents.len) // nothing to take out + to_chat(user, "There's nothing in your belt to take out.") + return + var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from belt + return + + if("B") // Put held thing in backpack or take out most recent thing from backpack + var/obj/item/thing = get_active_held_item() + var/obj/item/storage/equipped_backpack = get_item_by_slot(slot_back) + if(!equipped_backpack) // We also let you equip a backpack like this + if(!thing) + to_chat(user, "You have no backpack to take something out of.") + return + equip_to_slot_if_possible(thing, slot_back) + return + if(!istype(equipped_backpack)) // not a storage item + if(!thing) + to_chat(user, "You have no backpack to take something out of.") + else + to_chat(user, "You can't fit anything in.") + return + if(thing) // put thing in backpack + if(equipped_backpack.can_be_inserted(thing)) + equipped_backpack.handle_item_insertion(thing) + else + to_chat(user, "You can't fit anything in.") + return + if(!equipped_backpack.contents.len) // nothing to take out + to_chat(user, "There's nothing in your backpack to take out.") + return + var/obj/item/stored = equipped_backpack.contents[equipped_backpack.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from backpack + return + + switch(_key) + if("E") + quick_equip() + return + + return ..() \ No newline at end of file diff --git a/interface/interface.dm b/interface/interface.dm index 9c5984cdd9..9b87479a33 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -119,6 +119,8 @@ Hotkey-Mode: (hotkey-mode must be on) \th = stop pulling \tx = swap-hand \tz = activate held object (or y) +\tShift+e = Put held item into belt or take out most recent item added to belt. +\tShift+b = Put held item into backpack or take out most recent item added to backpack. \tf = cycle-intents-left \tg = cycle-intents-right \t1 = help-intent From 67ad41729127954b7053c3a9753978cce37dd60f Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 16 Dec 2017 15:53:10 -0500 Subject: [PATCH 027/213] Pings maintainers to review PRs in areas they are familiar with (#33572) * Pings maintainers to review PRs in areas they are familiar with * Add ShizCalev to _maps * air.dm * Forgot this * Fix ShizCalev * Added more --- .github/CODEOWNERS | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..2df370e6ea --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,66 @@ +# This list auto requests reviews from the specified org members +# when a PR that modifies the file in question is opened +# This list is alphabetized by User -> Filename KEEP IT THAT WAY + +# ChangelingRain + +/code/__DEFINES/clockcult.dm @ChangelingRain +/code/datums/antagonists/datum_clockcult.dm @ChangelingRain +/code/game/gamemodes/blob/* @ChangelingRain +/code/game/gamemodes/clock_cult/* @ChangelingRain +/code/game/gamemodes/miniantags/revenant* @ChangelingRain +/code/game/objects/effects/temporary_visuals/* @ChangelingRain +/code/modules/reagents/chemistry/reagents/blob_reagents.dm @ChangelingRain + +# Cyberboss + +/code/__DATASTRUCTURES/globals.dm @Cyberboss +/code/__DEFINES/components.dm @Cyberboss +/code/__DEFINES/server_tools.config.dm @Cyberboss +/code/__DEFINES/server_tools.dm @Cyberboss +/code/controllers/subsystem/atoms.dm @Cyberboss +/code/controllers/subsystem/mapping.dm @Cyberboss +/code/controllers/globals.dm @Cyberboss +/code/datums/helper_datums/getrev.dm @Cyberboss +/code/datums/components/* @Cyberboss +/code/datums/map_config.dm @Cyberboss +/code/datums/forced_movement.dm @Cyberboss +/code/datums/holocall.dm @Cyberboss +/code/modules/admin/verbs/adminhelp.dm @Cyberboss +/code/modules/admin/verbs/adminpm.dm @Cyberboss +/code/modules/server_tools/* @Cyberboss +/code/modules/mapping/* @Cyberboss + +# duncathan + +/code/__DEFINES/atmospherics.dm @duncathan +/code/controllers/subsystem/air.dm @duncathan +/code/modules/atmospherics/* @duncathan + +# Jordie0608 + +/SQL/* @Jordie0608 +/code/controllers/subsystem/dbcore.dm @Jordie0608 +/tools/SQLAlertEmail/* @Jordie0608 + +# MrStonedOne + +/code/__DEFINES/MC.dm @MrStonedOne +/code/__DEFINES/tick.dm @MrStonedOne +/code/controllers/admin.dm @MrStonedOne +/code/controllers/master.dm @MrStonedOne +/code/controllers/failsafe.dm @MrStonedOne +/code/controllers/subsystem.dm @MrStonedOne +/code/controllers/subsystem/air.dm @MrStonedOne +/code/controllers/subsystem/timer.dm @MrStonedOne + +# ninjanomnom + +/code/controllers/subsystem/shuttle.dm @ninjanomnom +/code/modules/shuttle/* @ninjanomnom + +# ShizCalev + +/_maps/* @ShizCalev +/icons/* @ShizCalev +/sound/* @ShizCalev From 8a0aa3233595051bee91e0380bfd89b38841eaa2 Mon Sep 17 00:00:00 2001 From: Armhulen Date: Sat, 16 Dec 2017 12:19:27 -0800 Subject: [PATCH 029/213] Mi-go --- _maps/RandomRuins/SpaceRuins/bigderelict1.dmm | 8 +- _maps/RandomZLevels/Academy.dmm | 2 +- _maps/RandomZLevels/research.dmm | 2 +- _maps/RandomZLevels/wildwest.dmm | 10 +- _maps/map_files/generic/CentCom.dmm | 2 +- .../awaymissions/mission_code/Academy.dm | 2 +- .../simple_animal/hostile/netherworld.dm | 103 ++++++++++++++++++ code/modules/spells/spell_types/conjure.dm | 12 ++ code/modules/spells/spell_types/wizard.dm | 2 +- icons/mob/animal.dmi | Bin 192019 -> 197914 bytes icons/mob/nest.dmi | Bin 13209 -> 12839 bytes tgstation.dme | 2 +- 12 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 code/modules/mob/living/simple_animal/hostile/netherworld.dm diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index 04e9d6ba68..1da57dc70a 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -990,7 +990,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; @@ -1010,7 +1010,7 @@ icon_state = "trails_1"; dir = 10 }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; @@ -1378,7 +1378,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ name = "Miss Tiggles" }, /turf/open/floor/plasteel, @@ -1888,7 +1888,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm index 4e943346f2..535cb1377c 100644 --- a/_maps/RandomZLevels/Academy.dmm +++ b/_maps/RandomZLevels/Academy.dmm @@ -3738,7 +3738,7 @@ /turf/open/floor/vault, /area/awaymission/academy/academyengine) "ml" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/vault, /area/awaymission/academy/academyengine) "mm" = ( diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index 39ffb0c913..5693bd14ff 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -4347,7 +4347,7 @@ /turf/open/floor/mineral/plasma, /area/space/nearstation) "nc" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/mineral/plasma, /area/space/nearstation) "nd" = ( diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/wildwest.dmm index 426e68e015..e24d9dcb85 100644 --- a/_maps/RandomZLevels/wildwest.dmm +++ b/_maps/RandomZLevels/wildwest.dmm @@ -726,7 +726,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cG" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/plasteel/stage_bleft, /area/awaymission/wildwest/gov) "cH" = ( @@ -761,7 +761,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cN" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cO" = ( @@ -771,7 +771,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cP" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/carpet, /area/awaymission/wildwest/gov) "cQ" = ( @@ -1024,7 +1024,7 @@ /area/awaymission/wildwest/gov) "dB" = ( /obj/structure/toilet, -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/plasteel/white, /area/awaymission/wildwest/gov) "dC" = ( @@ -1941,7 +1941,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/mines) "gn" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/grass, /area/awaymission/wildwest/gov) "go" = ( diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 82243073f3..27198fe072 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -9835,7 +9835,7 @@ /area/wizard_station) "zQ" = ( /obj/effect/decal/cleanable/blood/splatter, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ name = "Experiment 35b" }, /turf/open/floor/grass, diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 5af834955f..bf256fecbd 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -207,7 +207,7 @@ //Swarm of creatures for(var/direction in GLOB.alldirs) var/turf/T = get_turf(src) - new /mob/living/simple_animal/hostile/creature(get_step(T,direction)) + new /mob/living/simple_animal/hostile/netherworld(get_step(T,direction)) if(4) //Destroy Equipment for (var/obj/item/I in user) diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm new file mode 100644 index 0000000000..67a565f945 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -0,0 +1,103 @@ +/mob/living/simple_animal/hostile/netherworld + name = "creature" + desc = "A sanity-destroying otherthing from the netherworld." + icon_state = "otherthing" + icon_living = "otherthing" + icon_dead = "otherthing-dead" + health = 80 + maxHealth = 80 + obj_damage = 100 + melee_damage_lower = 25 + melee_damage_upper = 50 + attacktext = "slashes" + attack_sound = 'sound/weapons/bladeslice.ogg' + faction = list("creature") + speak_emote = list("screams") + gold_core_spawnable = HOSTILE_SPAWN + 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 + faction = list("nether") + +/mob/living/simple_animal/hostile/netherworld/migo + name = "mi-go" + desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae." + speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes") + icon_state = "mi-go" + icon_living = "mi-go" + icon_dead = "mi-go-dead" + attacktext = "lacerates" + speed = -0.5 + var/static/list/migo_sounds + deathmessage = "wails as its form turns into a pulpy mush." + death_sound = 'sound/voice/hiss6.ogg' + +/mob/living/simple_animal/hostile/netherworld/migo/Initialize() + . = ..() + migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg', 'sound/misc/disco.ogg', 'sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers + +/mob/living/simple_animal/hostile/netherworld/migo/say(message) + ..() + if(stat) + return + var/chosen_sound = pick(migo_sounds) + playsound(src, chosen_sound, 100, TRUE) + +/mob/living/simple_animal/hostile/netherworld/migo/Life() + ..() + if(stat) + return + if(prob(10)) + var/chosen_sound = pick(migo_sounds) + playsound(src, chosen_sound, 100, TRUE) + +/mob/living/simple_animal/hostile/netherworld/blankbody + name = "blank body" + desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile." + icon_state = "blank-body" + icon_living = "blank-body" + icon_dead = "blank-dead" + gold_core_spawnable = NO_SPAWN + health = 100 + maxHealth = 100 + melee_damage_lower = 5 + melee_damage_upper = 10 + attacktext = "punches" + deathmessage = "falls apart into a fine dust." + +/mob/living/simple_animal/hostile/spawner/nether + name = "netherworld link" + desc = "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea." + icon_state = "nether" + icon_living = "nether" + health = 50 + maxHealth = 50 + spawn_time = 50 //5 seconds + max_mobs = 15 + icon = 'icons/mob/nest.dmi' + spawn_text = "crawls through" + mob_type = /mob/living/simple_animal/hostile/netherworld/migo + 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) + faction = list("nether") + deathmessage = "shatters into oblivion." + del_on_death = TRUE + +/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user) + user.visible_message("[user] is violently pulled into the link!", \ + "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") + contents.Add(user) + +/mob/living/simple_animal/hostile/spawner/nether/Life() + ..() + var/list/C = src.get_contents() + for(var/mob/living/M in C) + if(M) + playsound(src, 'sound/magic/demon_consume.ogg', 50, 1) + M.adjustBruteLoss(60) + new /obj/effect/gibspawner/human(get_turf(M)) + if(M.stat == DEAD) + var/mob/living/simple_animal/hostile/netherworld/blankbody/blank + blank = new(loc) + blank.name = "[M]" + blank.desc = "It's [M], but their flesh has an ashy texture, and their face is featureless save an eerie smile." + src.visible_message("[M] reemerges from the link!") + qdel(M) diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm index 87c1b8de44..306c3fcef6 100644 --- a/code/modules/spells/spell_types/conjure.dm +++ b/code/modules/spells/spell_types/conjure.dm @@ -56,6 +56,18 @@ range = 3 newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/item/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot") +/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds + name = "Link Worlds" + desc = "A whole new dimension for you to play with! They won't be happy about it, though." + invocation = "WTF" + clothes_req = FALSE + charge_max = 600 + cooldown_min = 200 + summon_type = list(/mob/living/simple_animal/hostile/spawner/nether) + summon_amt = 1 + range = 1 + cast_sound = 'sound/weapons/marauder.ogg' + /obj/effect/proc_holder/spell/targeted/conjure_item name = "Summon weapon" desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it. Summons into hand if possible." diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index 9b120c2e7f..ab4be6bafc 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -209,7 +209,7 @@ summon_amt = 10 range = 3 - summon_type = list(/mob/living/simple_animal/hostile/creature) + summon_type = list(/mob/living/simple_animal/hostile/netherworld) cast_sound = 'sound/magic/summonitems_generic.ogg' /obj/effect/proc_holder/spell/targeted/trigger/blind diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index b860bd8426060bef34188c2b7a4d1118ce21ee7a..8504b18a4a5f94f9722e535daca7c7f7889f9ba7 100644 GIT binary patch literal 197914 zcmYg%1yqz>*zM5W(lrdFD3a1JbSNpHDAEW>cXuNV9|BSm(k&%5bW1DU-7v%u1KfB1 z|K7DOYrU`-W|()*6K6kr?-Qk|u0(`ShYtdQh*Xs2--19G(x?j;8+ZiWj7S#vrOR7K z&sF}ji<$EmN7pY7_8^dFW_?&RUxU5lBc-jTL z1ur~v{7D*YOIdoI78TTq+ixyOUS;N9zq)zY*tt8|Jes+K4~*khBpK9tc^kgO*3!>D zOmb`g7m-SZ)&IS8b2vlv_J*X#9`f+Y7SZUlb6mxwxp#GG#aiXvwvm-vg=QNEz7bp)kCev z-!@GK2oP2NBrZy{%dfhG_~~1{EXB}Pi1OAv+o%76_cutDccqF@Au-EmP6|cN8J7yKG6^4iR(rkV*7}g2|}aU>Wvrcvpc`!C5w~L6e|o>zAw-- z38^kWmD(V5lATbOvIm)^pu5 zhNHw=@GQK@Td;@998G4 z@m4nn8mAG_7ZX1yjK%Q2(M*6dBkk!zrz9{f z(JwpZ2R}?w&iRu5RpDBqylZ(_X-#O^_?+JM|8>>3kownVJvv=Un zOD-ja`t#8DQ==%(qP{h+&VN^5Fi*9evd!>LsVB^ek390$fqd>!FUNd_XUYA}+`m4+ zqPar{9H3)-U)-_H614m=ywhDoKiTZ*nR)MzO48Ru52epT;c+c!0=x*nmfbhTw2SGX zj0hYJd-Q*u8K783PNCO@-rA?_Sh{+Ic1?r5YHrd*l!)Zfx}ltgFAsHYx8K>az3O8G z`o8Xu2g5_Aa&HEU70TkvKM&pJs1AQFAk*na_Z&H5tZ~VO_{*_+cB-I{nn2MNq8NiS$QFMhNk;lz zf?yTfnLLM#WPj{y%@3L61Cid;Nk5*I&^t`CQ7w;vPYqrr_oIp9t9<8YRZf)z6Bso3 zVt%Q0Ny`2liGTM^eScrmk%l|_(PBaol8j&{|&*|YlCoS1&BlF%?A9+Y!o;3Cf1 zW}&tbjI1<`Pl{<%Jkm-mdoLK%XD_&>U8j;K2xlqZ!>&R@C!_gVS8ZQ=!d$eh-Qs?9 z{-LN8UXxRAt^2pc<*H@O3sG_|b$35IvWhJTe1$`XGKx-Xg_o5KYL0CCoBF?5$nb9-r-!%o zP3@kS46-aukjZ(yM(^D}@ z3Cm`^^k@zO{*JV=A|xWz|1io^VKaefRy5u;Z^59Wqm!cs-sAj$( zb;#}-&M0ye`!)~%8u7lo_SO25rvB340^LIS$p!&|;}xl`%UzS%A$VQ96A@ADLs<2(k6IwGn&hORk(dgX zC6tF9i5nsle~CH-S8d9~C5K;TJc5R{p@FeH5*Q%h53v|ZaoskL{nS*TK%Vr_=5WZ> z^`T)5?VTIy0-Y+fzf}MN;&Z0V629`A>QU@URLEmTvi$P{i~FM`)Z%Z^yK2?MAZ}k4 z*4h+q^t`CC@emFu-JIgVy00YmuTb9OM;LxSD_sb+dN|vTgyn~s{KYYUx@9s8t2E|x z^PamD<~kVap8#ufQ%u&42L9>G0Q=3UaX6&*VLM&hNH3>?wC+dj4Q3+A#Daj1igLr2 zjX9Gk?teoxS%}H7@qWxf6{Q6_It)B@HnzW~@dR{0 zi<4oDO$+0nQ_8k9E!k+h7#(FA70N>f&UcdZ%0D&cc$*>Aud!X+YQY&3+39dOhI8F_3IVLCDt{9i{bHtS}~ANH@K|ScL}t z>%Bq7ojHwZ6b@=|Oc=Ftcfb4Q!ny8Jyd!AQe(j}r3)v5-P9A@A@Nss5UCC>$&e>++ zzt%Dk2&<+hF^UhoZ^R}!vFrjG@!@4eEC*ky#3*ZybrNr?aTBXOW=l%vktqvQ{O9?C z-WYWYe{tC%EOk{#xh8-3-x&WfDm-!(4O@z6S_?lQ=Qq7=Lz4M8Aq(ck*C~8{tV*#a zmN1Ff7G_^e1v7&2nVHn{)4l#CYp7#ft@!g~2?d#iKW9qt&kiG33M*l$*Vh97pgXd<;UCh$my`W-0sBaF+c?mU-D`nX)z)8%Htn2V77P z8dfZ@)Dt9(L3ig#UEnLp&0*S0gM82FKT$Hgf)-}c`%RVFW|qzc+6|h)N*>^W2L4v{#-+Y zpHmc0z8+HMA?Zs4w|`>RX&dP<5pmwQ`+Z~ai9Ea|*O5B1MCdnzho-Z^v8vKS{%BLz z&okU$mu)-7N*~KyjtuyNPJnATXDVtS+?`{zIeIrPTgl_X_hae$L^+J{Ms(U`9s=FO zQ|3IpIFTov3bKs}!a7RUn|Yv;_ZefE_Ze-zittu1vLlQ{wS|5l*OCmS^Kkx^aGz}{ zwA0_9y`6&bb z=k4O`d<(j$m`BQGi}NwB4C@CjM&0BhSTZ&=LYL|hX)%c+C6O%zs z(NbQX7Wf$d2hLimy7DWk_JoqnleAyyE01&WbEo1n=)6RZTxd&PV}3&otrrUaar$%8 z=J~eNJ1EC}y&m@vCqG~_3VnZ*x5$eZZFG|^4|Mhd93c55`2AV@4Fd?|^AC3}8^Qek zCW^`lS-BZ_7&OX+l1Vbyj-`s#Rs};W8hJ=L$s&pvV=$jlcgYg?-gzpZP+7B~9|V$j zR^srbj>xh3qo1)MasbKKZj<&nxAulm7P^u|ADBjRRo8IKKy}x@I3=ZE+NX#Cj z9H;NA+yS;)4i-e{X-87TO?MG9LGK;Kd5NcD^QrEu~YcEr^;9jc{bOU)^eUbez*S9 zf$cHM;CF);zblchpU&V9v(^Eek@F`izn1(B$JB^n+DEMR$z#w%P06D3iQJ$N3ZNaH z=gh32gVJ=7ayEBLjE`ubYu!H$b=$IsK%zU`9L4jUbb15J3juQ1+rjTQHYM~{?W0@= zstHV-Qbt9@1P|ao&g4~oqsQ(Z+HYj=U|r9jufz{~8#a!$XVh>>(xVbr>~qF=%8dOq znXN|7Nv#3O}KGFWV1CH8XJ3Lojc5>NRj~BnpK!GPI zDeEaS-vjlmGGl-gR_3+X`rrorwVRh)RL#|iw#)61Ez4G1)#~+{c;wTwvHQX8Yi;&@ z@j;FE(1B_nUw58Ne9-he4>)$giFZ>JoiG+S%W$1de`SG?9VeXiq-Z~5ANiR)6<=iz z2s;j}zky`k0}`ChChu;p#fmlk7oIbd(KmM$FSOQnGzNLA9b)AtY0oWS84&;!RE+Pa zmOk}uJ@sHb{y9^5|F@L~nhpm~F6`7^foySZV`vvWXa=uOD{1w7|RAyg*Daybk+fc%yiz3 zqGn@B4G+dF0v81t19(dmK+i4P^H1k3H^ZJ~JW6+A9UdHX55PvvfY%tKt{IJXu{8xR zW#H#`wJgC-v2U_7l{vnzP}lA4t)`a)RwYk%H-M-!dT9cRfdQb^t9$m+w?FewD^-1~)wzwQuX~jlu3o8$5!YPchYM+>I*X&UFPb|1 z>GZ27HN4LKbU=q8Ab7+S3%IqV_UA}qwl-UcBPo}7#zRWvmf|Z0n=F0%yzUJ#C50r5 z>4N_q1kq1y_-`XI)*o&x);Ua5d(J!O_YE&yyQTD0j>i$g;BLrTWj95GaE?*M+)Hx} z?;oUKqbmW10%v=gZAX?3PUs3@&FI)zzt2KW{Z}vz_M0~^V{rMMw-De2mlrx~Z@9Xt zH7QumJZcO=Xc^qwUPVf^1Nm8gv`HqlcBwS@@;O<(fNm0J{|F zAmf)Xxxr1#JEaU?&T@qCJ;qur8edgJAVqe8x}}Z0Zt}1;(J$p@?s02cyI>E!M8G*9%wM@145q-Etq!0)kZrUr`;CQ!4&fDj>IIs}M*Z(UaR=%;PJfvh zzbM}YKUi;;)+{C$zWg=x9M%MkNF8kzE<+-d0hXV+cSEX8Ax9 z0cO&swfV9MV7IG;cSD%-Y(aSNK@684W<{?om~xhEXpxlVQ4xva+pZ66NPEUhCdSL^MD%oPenRFQ6IgjKd@sWIy4G#>Aq< z;JU{cH0y|dAi2!!1AyYw$Qay$$Nwatd<6#&2>C#BR?NUj5Nkocbvn)M6)>`=`Sjn< zUX3cEhAyDq^m=xIVC0|c2m_;848k|vqw-fPRD5|UwDyK%wL!FZHFM*t_U-eC2tMp@ z$ss@($(2E5{QNro2CwLVXlU?0>9v{m+9yP{0UMf@_IL^U^^^4-VAwSSY90^s4c1?G z2(4)*LBoU>`_N3>dOLP^gb`485V2BWUpjLA!B*5W>xe_e(s|(f6wN^B!=7*v1kaG{>i$F& zQ$-N{OIxDR!#N!i*m3l1@)J4}D@#9{j|-&2hfpvvli{SE^y9I_$gpYXeh@nes-8EX zTwl2d*mm0tm^TpO^A+uOOLHvm3g37}F){VPje6|h4^Kup$Qj@lkt<7%KoiJ^=WbEq z!M_4zMR()THHcFqAnGg(iwf_*v%4d^p(E2Rk&ir_S0OwbFZDO#Z(n#XE^cZEXtOhO z&9Malt6Z)rF}KROF;unFOU%VXGDy8OM;7lon5qSkEpN(RZyd<=wwBtX=$HWSeNNx0 zde~Y<|0!m;ye*6z;cop?xf{I8n7dJ`QE{qf*mjZ97yDHI zBFT1*AieZ;_DmO%Jxn~Y{Kw2ZNgbjeN_?5AI9GnhjX?v-t4TNJ4;;2wI?-eQL$aCF z_KSd%9a)JljE@cvePNaJpM3C;#Zr9wO)`b~fa1?<^-U$iGKK7kB3=kBy#Cj7hYI}0 zq+t_}BL|t8hi`0h{Lihre3qxzH7~1zKk1I!6Jl0K6+>kF`=w>f zG2Pu5)tZS7`vQ|6dihqB9t8_6w>8vpW6#}8658)pw8=tI{dc9^@0~JrASOwKt)nfF z=jq^BxpuLQ&?(MGBgfI?0g|0Xd`gUw>iYMFE5X1E^7l8#J}m$M$aFh@#L{;;n0Ygf zhhd4+n@8vGb|4Mj{G}7JWt``>)vg~WP0CNq=-;K4x^0k-JHWr3?d53uSz}RKe(Vjs zMA1GCjLdqvedeAlQv4scnN2@~cz}ouio{*UZtDA`BSzhPtp{x{E-y_MMkR}p%qxwN zOfnbf_x?Wg_B_wAFi&QWT;5nQ7GT;2cu)+jRp5VW=x46K+q3Ks+PD6(#i(>69pf9y zJN(AZevM$RsCdh8t4OT-6TtKs8A;$Yj@%OqsbL$&B%+sI2wC?yjx2eRECe^n?4){n zCK7=tpVoa9)$3z5O8jqi1$%W}yiD_|?@k2Z2aSPEtF9*9G2hI6gTUb7mYc3&x+p9x zfPb(iVWTKGH8b~zU$xE3UegbFTV{lER}ZPUR;n9Xf0cfKg2M=k$NW^#zfeR*JfJ5O zEBos<<<-KY1+vZY<8Ml9x&EJT$y8IC9?QPlc_Mn2(_)%rUi0rr>N&g%C8!qJu1?u% zwSA}3C8V2{Y|zz0IR7#NGjUCynNMKZChryUAOHF7ApcR)y>4GqlY?pT)Xr>+IXZQ$ z`|D9e9`lFC#Kpvp>Ggtp$ZuA;zc50`tLgS7njZ+TSx4n~SY&m-^z9`{t3hp4>Yrw# z4{V)VNd@;0h(it)UUakB>n?$B6D|OZLT$FORSqh1pw~(F}rmN4?q4`#S5WSUMjQA?XRLF{w%gL%d> zdw^sJ*!&2tY-O4{}>_!=gJ3sGusw)27P%%byUhAr=hug&&H1(tCg%`4raHUGc{a>e<(IqYbAD5RjqDF*0=`v zl~YC+p>yzk^|^0ikS9Qbs-IGgyX!)`lDK#BBMs5#rGV{VwtcrnWW0vL&bH7az3ZB* zf~$W1!n;)&{IdNQKEO0fc;(BFQPfiu>;`_q(h%Cc-^3~5YVbNM7x6<(2Jjue+`YM* zi-^=qE9lo4O}oMr4Z+83^)clE1t#?p6s2&sS^c90Elbu2Zz-_o62!YJjcvr8Z3ld% zv5?0*mBbM*e-99_$A2ln?_cN7xqesR%vYy;#}+P2)^o2=Y|%gHBl`=v{-zIr3Q4k= zRz_!wpS#_+qjLmGW0d;6*r8naO27c!*7Xk-+4hFR@eCQ*G&;CYNQdG74~txG$zodr z+n78BY$iROvp{p2AE4FFd>_56_FFl4>eXP+{Ye?2(AwOkO>zU{?rb{gN8OuoXPumn zWCdROi&Bl4u$2ko(ckH1E|%;7t@)KmqY48w($=loynk?R`1k|hmJNpkf{tW$e`6>~ zY49J4?noOk1GV0J(wL#R3y{LbBePW*zh!HJ@iJW&`FA+rvZw#VNjMW!C%V^j9SHwa zTXX{xBU>WTe?k*8=t*oW{ePd&nWYK#K|eIg>6DmCf!5PW^UGpQ;e_6=-OnD+ z(}}g^eGm5^zV}Zwu>`fG?8JqR z?Ty_%{YbZF;KULO$kKe@4#CQ}+-E=iizSSlom(YZcn}!8vB)8x=cmyDACEqqaLv`W z0v!9hiCK#r;cjYgF%(5clOkLtmo>L-e%bDBNH$T-=)W^Ri#T!SS$+za0Mw0kbLUir zm-n7wnK7QCb+NMJ<{B{u;{MS@k$yUq?-I76?tr!J493))znqAtejeFBYy*9}G(&NMylmz|c%Lm?Kbv_U?x$iRoEFX70GjlEE+4#!1=+Y4h;0T4-+_#e zhx>S%+(LNcANeh2mloI=KV5h;d^G?S@wPUhWj1A5jIS&_yr_zw7MRj&BTdd1Ql|Dp zFiSV@&aVVZ zQ2yuYUhn$m#@1V9oeFf4UO(?Blt6Z%*N{PY_jOTe_ z>~5#cGzpM8XUmoG8$Fzg!NpI5lQ8)#wlt5RzJw@1`rBhM{^(CtUZzn$0Cx`42`zk( zgK%ANHyj{d3Y}=r+d~s0Scf=+0p|Vd5!Vg6DBe5?=UZuP8$jM!c^KvTPdKCzkP-$2 z?l9MvbHMT=>J7Hi4!};;>+udvWYem{M+N|qav?V>H2{C90~;vQDoFZ*>_^T?lHSxkqW5nhyZ9(lzcp;U(B2Qq!YX@ypFB*r`I!}BjIDzne1YSBa($C7k zH*T24v9!G@5zMn0VeUR^0*SOE z`GSyK5xy|1sw#2AfokU6C!eD8{#2o57`;i-2-hpU*YwJ6=y84DIl@0pWR|M^K(fLz zSfv~k85N4jD|b8~fRg&Y+y>3Rr5&%;+W$-Ob12_wm<-PvY2Ri-h4jpB9e7W>0leRA zlNDuPkE28iVz82kvuThTQC4xhIZb`0ryCTkgHO~%#+M?@mBmzSn_OT!OoBc!`^{uj z%t-U$pG!4{;G3M%Pn3A*s`+Df?m5Z{6s?}Pf$}^AfuWz$fI7EeCKFcIjiirB{tp(N zAb0+BTGdu5`)}$UBeqNpJ%;bp8{rilwO{$|<^Xd>^3Ur*@$qMLg@_V}Dh&y+)UYjZR3YVUZz=b_=qs_neG z%$F;897y*3G4tXnI^o8#SIHEEZ@Or@`(_$fr>+ zA^2UHNcE#}0J7V7P~2so0LURcE#W*)O8}hMFsJ)QhVO=V6?s2i_d~altL@gKQ92erzACu|2{56=kjH+gh!rK?+OCw z+LqMnUBLXVVkRTOp)7;>n_CM8B5zeNjWjJiI1&kx$j@u!I&{J|zd}v*AOW3VLPK$k zgqSVfSSV;#^IC`4tUUD}`t5BKdMg|$kmmMY`)ChxS|f_rgLF zZ7+B3#fh8g=4vp{7!NbsGIqb>C1qHlAvR6=*6CQ{Lo(v57n9_1=i{`v`?9=8P0vyJEI zSeLTJTYqu~_%N!}=4mbaI?ADf%9ZD~(>yncZ=9q3 z3Kz40UKJnPLLXT7v>MbL=TBtHSrxvB!&%GLjvS!=jFoait-NPFS zUkn0K-bC42S>DGYL4}-F?rUu0rWGbB0snSangBSVAXN7Y&`5;<0Jw#w+NkRN(?Ab< z6&MuQQy)u@oj@H3I28!wKXcwtA3xKB1Ot;E0dL8kx>iac({YLhP;A( zicQS#8?VfLK)YaS30%2sjXh!153ENZapWlVfZR+Q9PlnV6sjQTIeb0v6D=8`aR+K%)8;N2$zZ0l16}C5@mf9BO!$cna3*$B^;gYa6NVgkhGDY=GHLR#7>Ae zIv%Xlhr!75aWoqLF?2NCp6MI)5I0*%LvylRqO=je|F|SC%EemC8~i;42OE$O|4nV~+B#^0oR+Dcfu|YT*x%)PYsi+_)^%A8|u4 zOK#s77BjkVk#~VUlf+U(SdLrFovAwl4nMT((rR3*eLLyZ->N5ZCc{fn8nU@I;0pZ- z_42uW1HEN^Sz%+6XzS61gB>kXy2dQ;S&tZlqDOq;_Bo{XTtB9sqws(Ye3QJ2=Dpj* z@1rSYzK7nR9?G`19x=F@<#}E#9RKG#DU;Fw7 z3vw27R8bQ0e~){T0nx6*E7#tcum5|Ovi{yJ-V9YK0k4jGfvdhXSpQm<>KnB+s@FF9 z-I4*&Y6#w3OgI2wD-(c?J1uMOr-&H>e#@n*527;B^~x?bNK&gs89xB!nG$dg3@eu9 z(Ap=u>MrZ&vc+@B%~np*BpgOTO!a^fU~I`NzCw6tFnJwwfA%Qc-83QJ8ixJ$s>!_NK*%g>D7bQD`%=J#enSoMat(|=$A203et`@hsVy#QF~ zL`|=o#e5eO?Ob1Ayqd@%8g+ifIJyu(nA8mSo$v>JnyILf1GN6%=zD_|fIqG1 zb{c=%l5EBmGPNNM%j82d0D3iM3yM0&iD_)UIE6soNp^pobFp64L?risQS8( z%#8p|CHmvEGkz8U|F@pfKxY~zzVsGInNoOaA1$9^ko&w%vNP3dPXCEC%#9L!e2PA#1r9zBa@H z1~VP0I*Dg0;*^naTC;2TrzepW3vvZJfCOtClj!@8*WJ&k)S1?7_jq4^E-S@zHFt~V zmAC3B3cB^Kpq*zr{QgDmq5HBQ;|-JgJddtmjKP=^u#Uhuw^7NAe1aMgT}>K|G~sf) z8U;nrSSaU>AVyA{6e*V;1!pZQIoiJV7u^!w5^mju9TmZWr_8ECQd{@9{{26O&NsK3 zfMFr2l@A#I<({n&q~jJ#Hxmdbg+=C1Ng2Atw|YX%c_Pv*>wsEbp1vfCrb(iH&0$y~ z%TWxOW4Upy@EDoP+^qj4&P=)ZI=xIeZKk0OY(>BK6n70vY*S56PL7p$jOm9KYq)+C zLh#@XYyyG0Z$RAmmiUB2@xhG=MTr3qodbo)zwa|5J+_v)BUQa=0#GQSn>Y`@9Dq2& z8g8I2MH)GA`rH0Ejbq%MfX_>DOAgvgG^0N91yDZTFPv~I=I zB9w-LlB=`?8^A28O7$z;F0c?_gNiUDiV=Oj7z5NmA&hOB``y8P1CYWp>lQ*1~*N+#Ur3t zs0-2V#DQrh;_(s2M@H?2!QWnV##<^#Il%3s0L4xJVln`#xn)`6Y~K@wmooEJswJy& z2{QsvVg7CgEu8^IN;{1#B-qK^7d$Cc#)@=v`= zXW?zdfLbsL9JOS6#!EVgN$=6QDkh2i0fk6|3rbkA58qATYHsiTx=Hd%|2 zz#O_OI-3aJA2Gik#xz!YFhx0N0eRvb6X#Hc%~MnU8$dV=G)c?IB-{dM$Wy?TR~`n6 z!iq%dMH0qjJk1V#gpSFeVIfR<1Nyr)c?ylXqxjjOt0RZzHx z6|0_{*{;kAA_N2Q3}Y$=utWLZvNHp5mv|||ciuae{xy(v;It8gjFdL@Up;RKeaw4Z z(QqqKFF7j(>kdLR4Al@LOfOl$B0048)4D47)!A+>xgjYnnxQThXjNCYTHImo95O`R z#%<`T3Ha7J2}kMZm)z^I22%$Ml#_J&e||^E^e=?Tmkv}ZT8}FxC^poHYs7cj%B(zM zFz1r~a2>0)xiE^vPCax}=}*%P3yOm8x#(q6^T4-w1-%hwuBEaQt)VYVx<<`s6PZEa z^fEn#x47>T#!HTv?Ye-8@uu-{JRjKxXn`sV%IW|q#Z$qh0D$DKJbQaXGN*g`BofeN zqW2Zx4>8nV`r;J{fas(F>Or1YRKf3cKlBWf3}DE~$K0ycDz~R00mV`M!;hRb%kPdvvN-A=TUb_2pQ7hkU*s}{=*~9a zj>)Uc9e`^l`jVCDg*}4_y%U2K59k(ZGs};=fo}{i{=?hV?d}d60{#BY>DOG?P`{R+ zo5)mryz<}<(+ZfpF%n2ibf#9)(?m<<1Pe8Cx_Rq3xN&#G+HgG>ehw(z@|E;XskHI!eOYlq(8T~}j39iIOk+mMmp z8oNzPvQi-cGnEbw$Vy7iK3&G(rl*F*!+y|b^vUIdVn&T8a+Fr3x+n2DP`$Htt z;j~Bz1A0fkd;Ev^2CdcsgfS-&{A-R!>v6_lARF!bGmPs?6YLy!1>~Jt%~&++wohR{ zXz$@?@r~cu*0sYOPecI85L+>rnuhC^c?9to2$l}~a|j^WMOkIXvcamSwL$I5J{$DN@p85<)u!yRxJEVDV#rJ}JL0BwW?Py6RIb zj5X%>jr1K7naD6CFP(gxJ3gcdO1}WjCW65(00$r?eLFaIED;h-!2pfw8B4w8pS^s% z}Jf7S!taSs+yREvZdr zLIizVnjiOA{YQa? z|8n`tQj58yQJF~B&4rZ}#aA)=KPLey(&5InDvC+!31#jdD|~jrxX6g98yhPT86khX zbPkz_b2ZiqF#Z>vnL2O6)+DBy)D_i&>3b3aG_N!QH5#6z9~G*MZ=B(6Hxf)6ZCL3tfJ z#Oi5+vh2Heu+MfzGmg}RA*|kc&+OQgulmYODPP|Jwb2DQG-TKqg6`HyzbWQ=x-(HY zwR95N(=ZfQ5cEc-Ziyzc*5nvUJd-yL^i+@2`#nc#GKsn0O2K!y>o1@vs=<<>d(>U0o`~7 zzQAm@9C8WdOdYOf9fIMbQKd|8ynnI~xqROX+B@~rB#~^)&Q-TyW#7#sE^;=ywNUVy zGnZ)tqKmAot?SDcAPyzT2LgGeZv8wmPM(|}uqXYyiWhsp0Fg&3HG}Df@_hM6@`qoG zkmd2>M!fddH>2-K_+=?Z9Na4Hj~7AhB@J2QOY8K~rPMPs>&naL;u%DdoqL?cGx-g~ zXZT-U78_%)KnC#S+QStCI#?-)q_&%GZZgpEuFVcReYW>6#sZl}g|DA$t@;=V5Rvf* zHv0sv++$tKu=y#D19ekoaj%OzMX@S$K#1@W9$pajxm=|%4e^Ak z3*vN7W)3ZQ0_)$$pq}d-VCui9LMJ^EiXWAzjK_2Q~zYRw?QJd86Pj zKkH>KKTErVD)8EVdE#?&l?2r~omvHQwunQwBZr#EL`Jk4R>^6hAY4)qs+zD8$viji z1LT0>S~wsr&y%Y{ z5r8R!AIw;<@}?oITsNiU(Pj8Z;U29Ay>E>D{dKR4gGaoX>04sZGKdRmz9TXomt1;UsogwBPq64@y9V{~v=9oZ?8*GLadaxH=eJ3^)Pu0XW~%9Jj7H zwiilGidao}0fCm1F9BUY?M65ten|Xb89q62SrPTm({S1buz8}q-oDor67ts8ppK6P z{QtjKkof}R?0fTI5helvu0{p@DjX&NP%kg{Cm4<{5*soylz8QosD&oDeE7O~!Rvsk zPQ%m&PHje678%h*Nom3{Umhk~0(A$!ElzUaY?K|iqeX3;B_|DieW78pZKU*^H|c$V zon=v7Nv?uD`WdE3#1*e&TsMN$&C zKgG0s`(kK;5uL=g5Q|Ea^#c_Ri!TbHF+o8DkWg^4GxxSV*ulO3}my6$A2kI_5;X zX$!ykZwOfu9zj;B@*yq&lrjg1+jeIw@3~QWc{=R=4s)(HB4R)T*l(YcC>s`B7VC71 z|F5x2&&ysNu=}mW|F7MTFu{cCNHXI8&S0!3k<>Rbgm1J8BY8K)6Zum<4eeSnL! zryIA*%yar(lKX+_+bDQ0v7~*nMB%|*1szTO=U+2e=Z)xxokPo}5+k_&t^zr^* zIO3qM<^_odNuNP!9jcJ#zT!v1Ra+FpyI#+%8&p-ZJqTaKvC(Cy12%EQG>Mo7tT{DySu$0-?4J@Qvt0Mj8$k`Q3%$_VR?$!(Ab{spu=8B5 zr`YkMS65d-Mb14>o&Ob#_hdexM}rE<>P_s?_~5HMIEsIUSOMk6B_K?U!%2^7!40Sl+kUhhi|EnOy#sImae0Xz$UKtu=m3 zVfQw*Mx4iqn?wA5_|8j##?08MXF6puZi(hJ?@luHj}XvL4-D-&t%3q=7a#4bryi&B zlOM$o=Sfe(?o%mT22p!~ECWWnbD)kuoxnL~KA0aJb+X`9t$5#<>X1I#;u{{HXHMJ{ zETT9{z>aY$0fGJ}phZ!!*7!}bd?bSmub*+lk}H~}So!TZm*e^?6h?o#P|j5d4sM02 z@1Q~>2)%y#RvL4CiNYuOt4Jhx4(M`CW=K^~$r!JGv}xaR39>l@`QvBf)+b8QBFmE` zyiX%`$%vwrtcI#VBSP@meA6J7D$gj87Vqq{KHo>UEyrY@M!CO> zZ~v?~4Mo!doomJLF&^CYO(i~Z1<4zmi^tEzB$2f%lORJN?~Xv{>1Prz*+wg-Vm4sl zyF*VS@%(Q0I0j>5J}IJ0DxFNyE{^76`5+Xi(-RZJENWT9@v(a_@;{k-Pj5lqZBL02 z<-a((FokRG)bdG~^_lKjWAz1(tb%pdG?a9d28>=Xp979Z<7viGy%%TiX}L_j-BIG1 zYkgGk{QEfkzC^BVvDMJ<^(T_)yOl45P2Q+;dFQ~`mf4EEDGD}g68B!l57AC!hC7N3 zY9=yIgvctk?tUhd9yLI%q)kcj z-y}*3x=Lg*U&arB!rCW*yI4ECeqisHIao(x%C);WNyT4fccYw*K)D!v zoaxfp46#^O_#N8#CJsLDwqUZRYU-=Qbpf63;6`4v02E7zq4eyE5M^$2?Bq^(&WgVxSOb$8%O0T znm1+c#=_ipXcwb}rG#5>Yk+M#6dFU2(M|vx z82$43n#~Q>LCeYk*%SGJcQs!-qR}GeQe*$te>hSaFAbAJGe-{mAHv=ODvm8!7arW* zT>}XaNN^t@UB5fTah7EDXA$Wf?# z@$=-K-u1xz9Tz{ZUt-34MnAbu3w&HMMM%1LpUciy_^_+iDLPbR@194g>UE; zbD$sreI!;#e>>0f#=>5k3OWMEUir%m8VXEB@3sr&@RB&J;T2$%rC+b6O`zFLuiDa6 z0}zwoK^TpdUkn=|neahY&D3PE6jdwofF#rTIIYL?`u``$Rmot^5NG zF3P9QY$*p9<3+z~O@>&^^Njp%g>mlEK-X_`MBTp zKk*jUsGF`ol&NZWp)9=3SR$`(Ei&1qRokJA;)d#@lJ@w1p!}wC2wJX;I*?4-N^rTY z$i2xb#HMK`sDp2 z+(;}p)I%zoodF~!@9aTod>Qdr?W#PZ+I#ry=7{BA;xd-#+suK@Twa0}!RxGR%h6Zz zn)MP>s0Pt+jK~Np>m4mcSHT7gn1NXJq;l}=4}|gHZUXAN*ST-o1wiZq{`J(#Mt9Xl zp`A9zuVE;opqxYg9_3*2(f5nRh#_c~h-y?-cszm>AjZr=JPN}1zT>rHrr(pXYh05A z*{S7rQ_#KSXcc(7H^(Vla&mW`4`1@&c8`mg08q2jQB;IMi6}@ljz20W3+-h2HEMxJ zFjP7-FQq3ZJDP>^n}4*@^yjZvVWxQ&kv7lh@BRVA|v$G)uelHJ*Ju$ zyVKwBNiAWb3^H)kx=@D`6b`E=#@bgsP}|RDS)HU*akn#+;8U}HH_%JF2mN^>A;FE| z+HL%+ec{1gKKM;DEWG>SI1S__DXb7r7AZ>sz<9rrEdr&O>F45Ah1iIvQ3Z*pxR^(x zyPk(XAV_#!2&)R2!#Smj8f6Oa9qo=4pMLg)lQ-)N(KF99<5@orJC^w$s~XOBeR?yap%DRKrD$@P*xMlcOhN=jGKzvWau<`I zFT`+=X#UVk8or1>hN)rTGqjX52PIepBinGr%9Y|pPhQ!iz*vdBd#0RVz$m*hS@Mk0IPx!cwnU!AqvsG+FCl> z@H$Hj*_0O_LT&TOM$boMi%A@IG>P!1Pm-Up^{dg()7TP*z8aL@i|bXAmNqla1LM>G z5*#het9TVJS2~WYAk8#-k_g@zI4>NI#iA^gx2Wn1##50cmBAw(`byna-A3ssOWSrZ zVdUy(9(kiM7Y>!NvBtK)Ktn9dd#RR?bchQq6XS7xTI@OZLGq4S?k*}PWRUeZPRDVv zgqJ5dh$~aeu_6eVs=i2c%3LQPO4B1dNowskOJp9y# zzIpr(O1H-O_BbWKmqdF0Ro0#-4ET%|=*|VnB)I`d(=~}CI-J#Ll>k^D z%tHkDY0(3NG=AiQz4G2;*#G4!?WKw6V0B7XEg%nEjCfB<{#RbW zuajs5)j;!tHpt+A&D($QH8;=?R31-&oDND|aRz7qo@(xAz=|e+-cigcKemEPyDxUACMb`#EKIl=O&zmSUP#qH zy&tX=`-QH3`3)d14GI>j1rdpVRMj@NR=i>&WKE<45VagWBfz!iMDc@IqRzcD(VNa^ z$VF2>*z=(UPDk0*XGhT2KSuEX^L#rHcm;}*YXa!Xh#grHRF>gyVl|8UOwN4^VKfGzn6a%3)}h)EJ2Pz|jsPEilE zb$F%x^7AC&2_SYV0zN2 zk`R~2%%go%7xZ~WcY6x9oN&gYFOzLP-z!?8=~?vYVwN|Iy^6-JKSu$?witkMWRw&- zA}_1@HfOr+zx`jtq@>tu6DB>wg)Yn~q#@6ZF`MT8$s=PgbX<*b>=*Gu8}eULR46Ea zj^EDE@4{flF#H8+-=M1L{5#b zLGmQz_szvObE-MP;RUk)Lp|yOp67YO306&N&|(}wGPW7}YX+yVByDJxGp5+gao0W% zpf_8tnQC)ir~EP$VH6xAI|Crpztp7njo|7g_{cUW>F7nA)(P0P+51JR#AjzrU#>}F z^&qrlRkhm>;pnY0fF|8((v?_QpB%~7 zd?NV-a0qWtzeI*%U|XI5#7X-L?zA5lV$8#1{5Np=6cbQ|w#%U(KkqHD)|Hwt=P;3m zEg|)f8{{pwRlRKk{4B693=dWxL3R(U()-{~8kKccc=2yhz5zfLM-mFgAiI?3Guv%L z{QjMyZzqAfu>|d$wZ1N+Bw$nsoSMyawe!?m7v?;B_rjI2BWs{WBWgx;fevl zScr@5in4z^3YBaX(N_1YmuuS~9MfxXU)?EVTKOzXz`G@1hVyJYu^ma5<=#*d;H(Z!GlyhX8qXYiwbN49K&Qdtuql6qEj8S zVe0CGx;C0N!3iDKD~!wU#CtB#`)<>12a~8M@~i6reD84|@`zRIi)jMa?nlo#ak8+% zNkF5uQ22!9JF{Zi#DA>bebF*`u#4^30(1Y;f30wFl2?rGAouoZo{NlV=1(K(9*o*k z>A^yRi>Zv)LZEW54wABzpGY8mud8z#x-p~n=Ff4|Rxsyg8~xkZT(1EwH`bn=#i1md zcG7n+_`}xv;q{&ELuU!arL=Phr}eBm>>M`$MaPj%pI z-6KG^t;YUw3N`H=Im;YOSgHN-A6=&e4IKgs4xDQ)>a}k!TA@nT7uw{}m23U6$uGp0 zt;IY+=aMoDNuMxo7!>fpiR@6OB|OQ*LnuCSw?JsykK1e!o5$43{oKo{e;;(&kA4L7 zLI+r&$8)ajyC}mXfNQXo`c#c{+j*+<|;MykV0*7uIi>@d2Q$p9b6LS39S#2N{9vLR?pDUOYe6Iau$>=VLBx4`|mNv4adqwTx^ z6{4MJ3ls%F-}$mpcun2T0FN9iznR;(p_yCNVC{$2FJ1oT`MMsd z-66XTJGHvP&Ge*%^0f2>KAdGkV~-<0g=E<{0DF%U!WHG4X9fd!y)i%s92|87IvJWc z(zz`zj;Xf#Z%%mg0ja`wjvNWvr) zFos%yv+E>x?4o0*u*swSA}WSX7uB!mvG{gxva$--=D`klAORlw7EcwXh!;ORA&rkQ zI#Cdm<7eaF@dq;rKRJhYD4wRp=OHEfix|BB^k6XEX4rSK1eBzisN$_2H}}97Vp%*v zX9qbkxpjeO2c>MGLA3rrkKg{hO(0mGg;}oF40LoSF=f9$STNh6+fWtvdQzEryyzs7 zwxg2Wo4%tr>W{_KRfnrter&Act0sKqioga1i^3vQz+vcS=T_4viV56& zUKKCxr2FHN_-fbDu@_*9RHKvbA+7n(hwNnN-`F)p7AtZZ6HXm%%asRIyrf;%(g;nn zt|P_#`Zyb;kf+#@wTRgzeKsf)GGSWo5F3ku73R&ruX4r{E6_+S>4u)|JgF0^+QAnEK?nYW$k7z<&-QT>!C)wslGq< zV2$Cd4(2L~rywqei$RrxwWuF|yp_&O58OBqK$o=l9-0JV*Bu#7_?+yUq5d!Ik3^ou zKhzKG!g_UV;B`fx`5#YAi=-{5HPmw=LV5a|Qh$wV7S3T+R)0T^8*dAwhdjEpr)l8X z+)~hHy;zpQRuJcUnNyWX*$lJzPA4!=Jn+cyW~0~FJ@DLZ~t&ZIKHnH^jC2bf~p} z6aWfg{M*BCB~glAz#eC#mcI)`RKsdtdCQF95fs>HGjn3!wpXQ90W`f%>kd)o?j^)| zH(SRgECcK8xfz)9TvTR%-^EQ*+@G-K>ZvD+S0}BggFl&cMcXhiX4aP0d8KWAvG_=T zLsCAJbPt5aa%ZxP=JLZb&84QO%sHYSu7k`Gr%_a`eO-(h9QLhlXvw&7|~i`r}P0bn7FEc{j6!{^=+^FaLtR}P~8hXC1e z?&#{<^E!LHXq|u_S@PKbbR^JB*6+MnKWL_|T4p80vA{UWXUwf50?_&5xcV;TjzwHe zx7U0D1JAhj5~5IH=cjM*O-2gkd!77K`^S-+_nsk;29lU@O5MlO#+391m66i6+35Rj zmtPJk+I>;>cSd*|sVZfAE)*s_US0-3>R^y2o|X6Y5KpzX|M&Ef@Px&<8-Y*K`{&hX zNE&|5`vR*~QpwW+)bC*DAnS(-r+2V!FPjIn-w@eA^Rogr4f;g-&P8ozaZ~inHe>$HC48SO)oR$G zxI~ut+U}@05~SH4JvqawVgB~HT8qfos=!rhZy4s2#nT13v9or4cJ&V57{v}>@paRd z$#1zR%=h{Kq(F#OVP9Xqm%u~0K`=`RO+WE-w;29vtcf-DOIpnr^f3y;-6o2@6+tI< z-OHafoby{co;EPQh91m2Bf7F@4H{Y_H8pydQ(livuen~KkE?yu`W-^HWc@I(FnJpX z1kC$J;nM*x9(Y2ifV$gWjObGHOHUMx__e0_40J}Y4<{=j_qVgT3y~}=5-Wu;WSXA> zp8Q)#KQ({s3UIGlNc#g=7y#;X7~MO14ec2dQWOj^z9CMRfAV{2^DRTv(h?ayP*A9` zO22k3?5yh#c-YO@J;0k*#ZlO61a)aIYFqeS`G^Gvqi@{KP}Zpg-Xal<5dWc$%#8rn z7a1(+Exi^I8w?Rg&SE=WC(HXi#01x_25W!BdINGhu-58 z$I?x8ApZgp=6M?;zWT?9{TzzL>NaG@WlD(MRj9JR z#zV~lEhz@PdJ*#f3#CWX=EK2{HfHYH_Q4eC!?y0Sdmsl}>q?>e|KR9@**!`TFoM%x zTSHUTKG#Ec6hJuUu@JP1Cpm>Qz&U-lIJ8;&&7Uqf-^Ey4N^`2{-nqanxr})(=yuaw zBQjT4Rft!b@6P5!hv84n{grmrNiKqSu+zi9X$V#Q;}p5#EsVX>CpG>0A29o1RfD5z z2+KWRo2GOdmC=a(s7wlo9WK*aGw%;|2usB-lUn%vi_Yr76bokK&KnPgs9(! zGh2GXvpHtE+~Ke_O($ymYAp6aUh6(5&0R@y_JGy~2J!I{@Vbb}A>ZsRj_+;DI^8&&@AXi<2bttL3pH%0Uwi z$CISvwXK%BW9_T~n`zFei0s)<8^>?Zqp7KA0ciK5 zdP>imHmDoD)L+G4xi7zTGJWyKh=?A65n(9YcUV2In!ht`){{Zk5Zm$P0Uqe++M(bZ zBB_SWXwW9zDazV;MPe)G zSJ=3_6dfV|Bxl+yF-o#X?1@V9QE)CmQseE6og2)H5S@rP@`lrD;6ZZBQmhc`4N)2F znVv2kUI|z~ST#O8qE^6uG_I_?(733=Py+`qNfnhy{FHy=)dZi_zDa+RpjwM?oXr}% z8-!U$)mMuy!iuuUdpE2+J4P^^JJ~!|+>dF)c^F3)WnL$hT zwPmG&=W}~Tz-_j9Y4om_|1JD8=sE@R*;2M6{O{I39u9@i5J=^@mK=#i6Y76PJ+3MO z&vgN#2mRp7yDbywiI#u;7kvZJR)*G|3z2<>=ozlTHybP z1Xy7m8}&VUrv9CtnYHA8fVK4BCmfuSW_pUs`xm7JkWBJ-| zR4(ZM91i~)*k@esWITKtHZDhg3oCmeoc|9Nn@2#ZvH2T-q_9EnSSw8)`anhgZ&rA_ zgWyN9TvUkxc>Le(0h2AH7UH#7f0`j~{eb6SE(M!M;svetzSm=|9NLSW$+_d#8PBP5 z2{>9XmJI0Ve`t0JL3y~L{MPE!PZeNU`^$`@CH#stqz-&(Q4Q}4)6%VK6i}$2`}=0c z9@y6;J_mCQf1eA0QI^2RDnsG1d43=>19gg~3J+d{#J`8^6y7`lsKK<8UAB|*T~07O z;`;l5tb$2Kum}YS1Y}x+hUJ`DVvWj-;OQB{rZ;ZT+tK?$d>HWr%0?`>PODtq9x3_8Vs;#@orr|%FZ}%^eg`G zu{Y};g#i5{7trd~sej2-_wr)r+k7?#6S~6VdEHUF%SO2mUpZL%*HlHzfHqf_l?V|r z3xKeV0~mqB%q?B!t+rOs?_1U1VtGJtoSIV%_C5rL; z?Q?;WfVVK->nzmVoO6vXdmkKZ5aZ1qY|iKInr)Z|2ICR(3Pwf`jZnZR(2yd=K*dQW zO+q2iyPuQ@amY;BmY;v8{YTADnwV_Et7rE0_;+ z311S%pq8WLAhL*3ya-B4%3OqiS!OoHuhN9#c-(L|y&;BPTbVp=+bvd=LOe4&9Y=SR z8@>f&OY%^sJ>=?!QExK)VgKRwes3Bs8Rv(08|zjNcPr-ikI#kWGkZ&SRQ+=Xm0$c? z37a}LdaTgOmlJ%rYpSKN8_=$W1V96xYPZ0qd|qwdK|VZ=Ij{vUo705etSRH$e>i3} z5?b?-5=T2YX!&(B`q&ila2x}37%|rN*J0XKRrVPXS@<;_9-N;ak3>|Wk=3^J{oOmO z1K-gzMPd#Z&GaO>O*J3ih+6gihhkmBsNv*{K;bL9o`q*iGQ`z}Vy_NtZF?$<_^GXV zRE%5A%%1pb7!AT~^iFAyJ$>=W!I&-Nvp3m|?zyA8va?f@q(-lLS}60hRS6$yM#6xv zZ}Lxu-hUfgf`aD~97=Qg>cnn81q`?*ET}QLQXTj`S;%#-Ff3b8?1v>ZR&*3W=N#S| z&Rl4hpBx8_!ye~g2QZCWBV7NA@eF>3rjkK^X=5}40VW!}Dqq#_F1X{h)_1lTcR3Ho z!LXifP=zSuO}Rlv^kP^7M4@|N&#lZpa0X70+57FjIjec=^0J0yg z6JFrb5KW>@Wa3TDxxB){2LwJoWu2tDky<~#C9J-5K8sIx%Mi2X_$&4=_5?jIusdf0 zTHVbnH}?Ztu2(9ra$eMdENaF=8nKYK%r-tBYgb;F9Y!_~ENp4rla2V#cRgCcTDM?I z+!A!`vlx;DB-e=AGU2=R8*+4IcV#8RC97>Cm^~!`h3N1?ICW_c4@$ z=2@nd5d}?w6rch52>AFy=pXxFY+8?3$J~$FoK24^52zau@6$Sw6!hljrEznxny$w< zY$F)j@g<#t5sZt2y*87KfNM__Q`kT1dKofu9b5Kj)XGnmJc4E_)*{zJ1JflriWJZr zhWBd?rZf-oOYk^LAOtI5&|350KBYmP*S!Si(T4Kz<;mGiUufGa(DQvOg;?jbjvg=? zry%vv9XbZ{@$aqdT~7pDhRcct*r}r$8&jZsE(%&>^8nCZ^%Bj2-3&vox!JxiL`{1F`9tzF~M?mp^^| z&2h$6kI+@ml|Yz|<7ycveW_Mvbp_I8eETp`m;p;VoJASDy3DuqvQP-Lo;jx*y0Sfa zEe2D)GEz2QnYf%hypDqg<-Ymjf)|2#M`sKZ`4gZ_ChSUOD>Is|%&-^bjrAw+eSHIk z1(ZMZ3ZJm1a9!z?2u;JgDz_MY@@G0<#*eI`D?8gSIQ0`@w8rf)A?!0{#g3PQD8Rg= z!GSlM^uJxQ4S3Z`LZ;RIFfQ)$ew;Kd6E9r_{#r1(3W=L6GI#PnfT_&_n%}h(!8qu609it=kH5nGiBkP~YKS#@={{74#$oE5$_7&L zN$gT#BJS7T_qR^vQ#daYkAs5fK8SXpNjYtw-h%*f1wdh-kWm4!Sj6<`I zw?H}u+AMF-BBxqpxKEARG&|wl;JUB+BNf+73t2>ZYL=W>yYNyMUG`1C2O52^TtG6$ zB~RxP9q9R6r@%Ar*5kRk$oJ>bleCwG20B`s^X8qm4I|xb*}Z#rK%(@w4Pb8{_*v7~ z`{1HcF>Qt-P0s|}Qb!)r#+NuQs$dVT4^)O`z3b{ObukouGQ)1osKv46br@d;8_Wr- zuoA$Qr^qI(U^XjnPtY2d;VlEShRP&p2#QyqzNhSR8B-*35OC*E4KoXQ2)OBfY+8}y ze*C}&LL{Wa1ZE8+kN6UKynK_t<5NyE>Dpbb})?AL;6U-EjuH=VjX zaa-MkYP7s}Chk(<IDFkvYk02jMoXI#*wkk)Wqw~J z3E`f-Dk%d0VWA#DVWKG4XwVn`#fFn^Pc;k6TR@zJ)zl{eH^2&J)bXg=d#rV+3>A&s z4(Mh>FWN{dhgJBh&MKpRFx~y8RDaF&ru7XCGLI5-J|_JQLy^bULH@Hz_DgyEKd8Hf zu?i!HpPTgrBu+UTSLWK#>fpY z5)_vF2bRh$fjqT=8vov7N0Ff^Pfmv2WtVhs=nwR}ZQ1Fb3Y6F2)4yj6V6(4-O<)NG zuj-7Kp|NbWUSd-RZa}Q7VO(HtGlPUZ7cLGS>P#P$gZnL&2R=JqZ>hU(JUirDy6#;T zz7ck5fAgbvW{h2rbc@w6G=T%y1tZ-1(S<)P8pEweNG>LDMD4l-Zrd5f z24ok0_Vr=V%eBH5H;YCIA@vq=87@a&7p3_B zb9P{NjtM!7zaUcY3v6I)?0NAcmw{;t$Cy0a|-)B(Nx_XCf$F~a|R zB?tw-N55$BiA`D;+JD!3MNKM^^33<#?4MJmUYj7ir|4mfe8uN|$t;eB_VRDza!gW3 zNaSfl70D$1?$GYzdC_WGn#W&OLM&sya3V%NjQ!IreNN^qg!R=KvGPwgEtlVGU=)Ab zmpX!B#VtV%;K&^hNXjH)z?l1AW-rP-_=VY zi4O3%W!tf}9ZyQdoZ7MXH_%`IK-UI{n8l0NVE2_nXBk%Y(s)(+Rp-mtXe3dnv`NS~=h3*z2N5f?l-3zAo$p zQeJ~fF#X}d(<6Tk3@sVxvrBj=N<0vFA&`STTb^z$w{~4(LGBGZ$PqicYZ+BJ16$MQ zrNrNc7<2W-&2h#7&I5+9cmerHd7pYniTsErHHJ`TZ0(WYBdN9(!Pi|mFk_!H&{Z|Z z4+R4wO-7@|EUe@d-1FjR0#Iq*a@}{^JTb{pg^lHpP$1uN)pZ|s*af8EeKV0``XA;oem5@ta-F{)J_rDcPk>W zvdJpG;2e!RI`qSvu&;axUnE%~D zKoa{L;9&({>r>DRT{lQM&4(@)<$w1HzSw&e{K!~=MBe`VJwYOu=tcS?oi){N^Q%Gu zg~!TtXk)FOnuhr@e*U3+yVFu}?YNw@w39Gi#)`2wBtFi+D$weVa5aV?;H$bIJdRqoBVOqi_}Bg68N%fy=rW2> zyZ^xYgF`}B@5e^aAt$0Mv}doIb>i2wsLBE`SRG=%H$pGj}3Ni39T<& zTMz9$>T#4}nxb^5W((&+Xum?yKlfPqH;kAW#nzRBy!9o>tc2n|;$xnmoL2#r|w zn}>q#xRaB-CdxlKN1#*hxrl+tRp`hE_GwFMnXAkla8g#VIv83NTrndG=|UArz9-6N z$(x89^C(u~;b(t=9#a-$GSzuFR9eKv-_OlAG@Gns7?|7hB#tVyOYZfK%JgHuRiz7z z&&atqJfgV3go35!d1vqGp6^DYU?KwsgD3Rq^DCuI>gqEvs9g6g>AKU6(`Y*P$Z_$) z$AK#q6!2dM9&mCCc(I*V??5!x(H$zh7l(A#?@i*7WLgb#fRw5FGw;LIF(O+EUi}CJ z%d@aIZZS;aND8}f?rVm^*0A#SPW>{|6Mvpvv2jcLq-DK1tp%$FybE3KuiO=EAlchR zhgn$20?Z>wu5A`YGAa|PE?R2rHH_2PLN{qk$aw26*+Q8i_)21-)4zY;=UWIJ6#T>D z0JfXcigUN32P;#eol2}Vd0$fR5Ru_PX@8gTv+*#pN%<89{jE!xZeW;&tVuhE$3kv2 z0!o)FeOr-b+OP8`2F9Dw1-CiDMh$OL=F5!g`is-e8uRQaY^Uu%US}C7J6Ph|Tj)7b z`NhY0vRG7U%wjK-c~_I_I)#1(kTWMwt5B;j!|6-XuULD?vTYNJ{Ee> zI(U-oO+C46AdFV-TUEL6%Q9vz$AB1eY@=J-h4MNxIzY+YEER8W>Bq z?ZLt=QpQ*6s-kkpcPM&0KK6+Bga9@miZ-~HF9$xElSLBS158lY66KyGVSsr=Ow6O0 zOmYt;e{2dg%O>W83TaUE*|QB@=5=;U$ctV8T-Kyhppe{bDbCrg7BlxF)r(J6)Cv)Y zDfKaqF)E*s;OaFsHa*F~7@}ZI5883MblKoj81FltQPZgFhoz%(|AZL!4K+yjOm03 zGIugCwTlQg5{N@Pa_1c4gF-n1sIDPF;{n|*qLC3s$1{vZc+w)ve?Uj%?gS~lK?j2M< zuL_&7FOK_zF|Q#M&YA7%AtT!;-yWp$8NmXE=Lkbe@OfX+TY2BE;{?@`Hkiz1n|6~B zS2@i@O7O+&ya;IP__l1khw!u(}?yL(hPo57}UJ9Qt3Q{xY!kGoUI zDw_duKtUVqvhL?X)$cw7tTF_BC;yAzi51<7O2}XANoMZPF9p3hsH}eaMcOa!S-*|s zIS0!u7gMQoKM5=#n0KA2n6%u08KT`YMF)A^ZQEoNIS^WWNJbzJFS5z#tz{Y!y@Ubp zWagISiY9UH;Jc$qpJU$Gk1dLID&Aw(Zj67sFi~mNuro+SO?l=OGD9e zQ!?sGNs-M)dq6vaWp?e(8JlhH6R&R&goyQ<=8+Ct{*EiwoCt(s&>cts#U$b#ceA zNb*Uwd0Fa9aWvUJA_Nd{Z1-By(x*9A0?E7AFoe~wA;)2}dG2wvBmF)50vlF%Vu5&L z?HkuM=p1uwl@#s;HU;L2osG{y-Sd@|RCvs&@AULunsg%rfbVKtz`a={40002CG#U* za0t*X85ftAEJ~>$khOzDUlb85bsfa&h*n))-Q{C?+U1*~R{ z(G{RtEdQ-5*DxZIn+V4%KX$!StRR#+oi^u~Gcc!BWGL z`d$4B7mY8T$sOc~cH(C}$ru))ynLJmAQO<=Lk=Qn&z7CWM%BTf9Te!-%%n^OvR`0~ zrk#(F>5EGyx3;zIUI{Rfi-f@*;v&{GNe9_P>fClzle6FU|CumQ|V@{s}F=~XmxL9{`zZJ?{?5kl+Nq`|j6PZyhW5y(NPgp)H zVHmH}VAFqKRxCn3S!>RSr*SaDm2`8R9LucdI&R8Dz^rLDFYCOfJ{QACI_Ar9;YHHW z)+?b1wlB1ib_}tNmQkx+M|-i|K4_Zz{X4l?e@vGTQ)NGx|DuW)k(_7SJfCGfe0x*o zj)P+J;R}xh_va|aWhxgwknvHr@fig@i@Vx!4v=?!8T2$UUS-S#fI7lMltPDb<*rH^ ztu*?USL0Vi?Q z=@QcRoZfdA3&o_yTq&um)XJc8(1MScWsbiZCf$SrM13}_cd+3T2sVz0h;J>`-U$!p z_blpg(h{1|r!O6H{1)aoG?F=sl)0LyQPDtJJ)?`FsAuC4odvhT=3fbBQeBUL{^#O? z3w}f<^^7w%NRvD4}RKv*Md)`?IvI1=*%unKa(Q82y%ZT?OFxZNC4BqTiXiBEmBi;ofh z=Jv;Fu)Draz{INw>4$#uM3J~>N6*uKi|Ec%Bn#@!=nn5Hxl{S>g)N0e-C0Y+(BZ6x zpGYp~vW{Gij6RBUrU*(fXb@Au3tQlINFwL4RGNJu=)Mx=8HZpMNFM$wbupZhprW@~ zuXug3V%ezMwj($xt$&2zpG%KEmi3`&yh%oIaqWgYd058_{CbkGgCUgc5;ckIEwh=L@mlkJX?#;|5 zlAVQrf4vujtUP?4KJV+t?2jKY2Y4hpJMS553vdxc{ch`<9org#T!Ox7+EU$-U)CDy6(?)2k}zgSq`>mW+R zgC5O0)>jziHv3_33ccjE4HIlC?NYyN$`bh?^?XE`g1m`a%@rE84N5r4Yh4|Fiqz@*s%0#SaE_tcD(%DR$TAHafpbYPK}c>efn1pLHU7s66ZG?2zk z>?14F{eOvc(viZsiALLxKsCM=joGIA#WE}Uuit6Te91`!>cFLbrE)2lcUn2DwkbgB z{5S93k|>pxC_U`)6tppL_$mi$ug$=9aDIoZ?+8WM`Q#U#6l?lVCarH;RXL@lMHwvZ zFQ#(<9A83>>|;ZvPyy2OFi-O^*CqHuqgymog%<7CDFkyvjr=E*H%XO5g6rfzpD1{% zLI0kQ+;Y4V@&7sqi~iqZOi*z+{+BPvnIu5lcE(Z@4vU66Y(lq5AK-H4G#a_)|qQ4hrtmtW$Sm`Zv}s<8PNx|4HoeZ4nSa z?h=aJ_{8sziLb2B?6?lR9VUi5ZiPvp6#dWtm9x@2bu4t{i6H1hvBOGEEjBjFx=5c` zy0&C9n}1t2k-1flb1RJ&KSjUIztBaJM`R;P=L7;TX;vTOq1T$bT4pInXiHAX&(31# zl4G20Ks64`tPKum!0(EBiNgw)ErO)Ty5n&N))iSe5qP~cUe60LB?B48029qs3UHrY=m;5OZ>@mKXj;0p zl1tL$V&oxhI7V3OfiwegNZ&l*Pb)~Dw3YT+S>-fyN9uxbxCEaDUSI}CkWmu@5r5Ia z`ultR61jmVH1sRqe-*vI0I&h<4H{$P#I|Nov=}Z(-=fZ^U?? zPC$4NoRT`v>kzXv7BG5JrqdeQ=(oW0U9=5Try^o$LFg z(P*%<+;3!ku`>?D?2kK`zL>@v?)%hD5cok0jSdVsQ(7}0YY#0N@!eTe(@;;x3Z`ni=z#2q@b{}0MR_GHugZ055R;RWi_6P_wZF*iCagx}tJgI>TUI?DE^r>53+ zUxNqW@$b<~p-Sp#Kx8ggsnqc6f9kk6k90^_&^I!Qb69Bf+M@#uTHuuhY5%?yGFwO< zt8j8J58BXkBkV?r)JP4lpAO|RpO(}F1@5zPA$C=9UP_3?jg^K689P1jh-Zw}8+07| zof4#`uTNb|+wKI!$)OlTKuv`4W79BcUoZzM8#}u?aIx)eOMCx4bzi$6x)nCZf$eX! zvTkl}j2Wttz#a`Pt@LAdc6OQuqsDfnvWf~>3yUYaV2qEYrKR!ifBc3FR=R<2^c@Uj zcS37%C#R=GJh*43r=kxnXi^_$iDvI73!XOb>k%wSbtGPOvFUw&8uUa@7Dyz6*!)(< z%r;H3FLvCitc&yRcajfTDLo?L&oHW{DB#tzf( z#jWwDTnDqGl4qum1Vj(lEiSZ!x~%MXt|pNhvvC(UTZ&53t3bre$JC1S_8#AdBfMKV z^#wq=^Yi5WR|`;4QCwWCpm+~@FwJeznw*--YiuOd)YOFkgD=ISThe93K&n7O(8N`a z!lcZiQjWM-(O9D7vJ)XO8(?fwqzueTr5TviB)~tJOnwKLU2z$0HA9nRgKTiD@3xE{ z;_JqAa2v&jo0^6wLFeW6SvzwubgyzLcay{NpWFq%HWLU|d&HO+qB8+$R-flLwrGKz zCt+-=ya)KY6a57{gRd4{L-2sN8&Tmj>q8%X#4vD49T!;!IYEoTNuB);rZXYYVtA+} z&q1qGk4dY(=VOwEra5nwOCy31N=CaUV_OaMLU&|K0jc#!Gosmr2gmOWeXn_#hd$)j zzyeydy4-wpQs1HcEOYzmxSJ&`Ffs})yuGq$3Q#%z@I!ia`!M4hA1`kxwnN4XlVBlY zM<7uRMwEItJwN|(;+rb#lEQGLhNh;;@p3yu8k!K#x-6a`&N*YND;2+C(=YYA(a}+c zG_Fp3vdIM_ZEdpJ@{W$>Q+q5)@puPKK(nOR0CPe{*|2ToBnSsw=jT5dKr#sA0$m18 zhHKf9QxmIf&79vFfK?=Sp#P?SfU&Bns}r#JgN%RW%j(oy6J-8C1spMX z;#x^*sT5$VgI8?zKmNF>Z;yh}@?x*WYKvm!r|VD0BeBCsnf?DVYpg-7AL(68wlWF~5_HAQ3# zO{`0(^SAjE!aGa8*BsaSwJODvomZKQIKuij{PEdP{F$9Wx%v6suGe~R-zJ&0ues7! zU?R3+M`gqtP;LXt76w?l5T&R1bqZR8`~I{pZb;J3{CJ0t3%0r5*&=hZUU%8O+Kya}Bx0r4UuWKPw)}eLJc1(*H+$m`EGNeXa5K&2h$PdQJNw;X z&to_5$#M6{+}0jI2*~Wi``r>nAoCnd=cjc#&Iz?x5jgN_Uukf^G+pa=*v|RZfA`X- zkZy=y+!_ca_zStQk}z8X{qWpN7r4n!_BU-z`e5*PTNZ(LlTj)w$zsU_8c_o%5mA2{MgHP!134UULcX>5g4P*qxO#l<4C|ruOhUv8 z+?vKWcC)87Hywb{yItpLn--d!3Bj$OP(&}=3?NeDdU52D8bB+39yi=4R*WJ8 zgi5L*)fx+2PVC5|5XL*hIm1FRrz5B4?`T`=v|}SONq$}cO%1VK89J0_@0Nh>UZ*sX z2-}FWndf|Jo`4ouq?!MEk`t#g7dz8&zk+e+;ZRd|JQ+W$a7W|dsFBaVK`2q1o6v`E z5n`^+3&id+3&aTuy0}%`^p}^HmhmMj*G6rgH5=07*8T)@2`CY4-isUp&zU_G=!IZqUT;|YSo^&j-Ds*80i}cgfg^wrwF1tBCUon*_2si)kj@t@FfA`%bqxk#P zUVJA65T3@OPXlXD&E^f58D!0wxBz{&ukLa@wOuVzyW+N4$a?PLA@*H|$;Xvy_qx>! zd$L)Z7dbIBUeCjfVG1wif(^aCbq!fRLLl*bc4)isW06?& z!-wA;1_a>>(5zYemrTl83ct=J>1Xm(9!G65$baiLaL`|=>FV0Hdo+_E8;y1>w0KmI4xX;G5ZBe! zX}5ZE|NEnh@hhppVMS=bz6>~ieAMlaZo{)^Vov^=XKuKV)0NCh%vOL5ras9nf4gqa z|7^NH$#}Kd&^Km-nJFX%2tKWSK%&c_eUr#PnbqLEA)rjV4(l6-Sxr1My-;~3gdx+C!m0pE-=4XR|8zH)3a9ED7FUP*a5IIwIDld7@S?PZ>0??Z!_!O|z6L zUS_{W1zBc)dsM5yi``96+X)mEodw*cYn2LqkKQ|HIz&-|G26)6MF z;J`HLh1M9K1JUXez~8!EGLm72EjI}zx;$!XterZ}{u^8~vvZj}YYGoU0FHdbSd)hQ zW5BA5T+Gu9sM%~_uurcq9iw=Z+hkh!d_IF-hn)42Rcs~hh~LldnSb)$px`HJ=`myi zQF&$W&navvklEvDAlPU_;P3YZUH;Z!JE7urEnSO?cY;6GjPW;l;TDOt%T7KH4;cDY z03qv{h-=N!o+N<2Tzeo;G)wU-?ZhcfPj2K^clNS$5%J`R`Z$=iXBaup(yt!6 z!#0{cA2eV@%OkMeA~5er2|iAh%H-W#iGSE-z0?Rq&^-5nWvS>ZttcCRhO6Xb?9g7F zP0yk5#bSIZZv8NzQ}eZa&~iuxaV!}W{b_N?)~+%MHIJ`fqLrvukzW67yk?W3wHa>b zH5J#)!21?Nv$<1AA67ll9=kaF0T?cnl$1^b{SkDhA00220fp!d3;#cqRQg$Toz_8< zeL$LeSN$7vn!gT-L3Z~}r6Zn@N!h471na$q^bh{QO>@T^gBm=5IY38(wYHjLsZ9HV zwKB!1sZLf}=6p3ZNPi1+nC!rNBms2fq~HH(*9i*`?hJl!FJ?jJ?rZl7G zzOq}6L2NtUsI-i1>VKyD-5#4pz0pAo)ihV-JM1JBVg^^|sQKSOv6JwwW zC!BwC@h{l_sFmaQC~L#?94uQ;5>Cnr3@9NMKwdPj@&-jFK`J@rJMp~6mn$BWqz^EO z!#Hqry(C-&5ZW7${vB0$%((-#m=EtzzA2K&SXycr?Tu#xT3U>4#*~76p34CM0R6yl zQx1*K0+c)_bZ@L1rD1tp`d|6;oSUGc#mAX}hLDHHHTcxuZ&|QX8w@e1M7jp7A99z&wds#2ZznoxH;>_pQd-{{IAR72Y15+GX{tv z2N9I+b47G@b*1ljb%k-79=Wvlt>r~T_&g`)Te0JVXI1`ZS(*A(YwwP9E;=cBKe=q- zz4JXrwNNDWBfiaD-%zCgFWmk6rbvPVA`x&Q(PYn#2Rl*%ogQC=sJ7&u;pj}@!P-4h@m+5!Du%)$rEeA3TBO`_Hx(n1A zW<&Km{5)y+S^u-`d)M+qzSrHpu;13&t(~6tmz!uW8^Ql-6LuW_5@Lp6=HiaQrVMIx z4V$bf9Nsj&{@9@&`P1-M@67kn<=*4C_FS-Euq%R_)-D*VR{~C0D z26NhroV@y_fivd<++2xqmn{ZNRtk z3Q}_{C;1SOr01Vwfz8hz@m_jJx3@tWC`K zIE1PG{lg%tx3_+s&SO7(F**qoIp9-I_;=)9`we+jET<;qQctBt@yvsy zhMft&r9^3A!maNs`u?a@$T?`fl6yvutTa8kB}~gn43fe&to3jUqexb##A%42*UJj} zpVFxKoi;i*CI&a=wSEAvrO@b3p*->WOsVUxPqD13EuzL>sD&fUEC68oq4i=k6qMNV z(rep?jvy}g<2MxWk7aj{ThqDTub>U%{*rp47C-LVx0|tO23~W;$+Im`lYPbj-Gcql z#ad=!TeH~AEba;R58l>DfF>#T`!cTd2S-OcH@2AA(KaGl^^Sdxw0lh@fgOX4zwUT7 zTOI$c)9xe05BzT@*L&&Ty($-VYO22M>t_$Rpvk3aJdg#onCXWqQ+!MY*e@tj46drX zCgc6~1TPQQ&0&@2+)s>eag@T?h0#%}v|z}^fl4+%VPet|V|s-=G3kW(XIa(XgFU3- zcte2%$YTSs!!90v4$Vy`r$(Hp_fAmHOlCiY^JShJGE^TQ=k}5KCIOW$v4i=MotF4| zV4HZ63#DWKy62f6`6EUoQTtdd+E+ib`^}=^fn2_4g6!g(?fwHgm|TFfD}x4j?5% zU=*=YCZw{N{BV)Z{d1l`-2a`MtVKYC0Hh7~o19_%|92c3mBw3hivnSS-pJc{Qd)&h zB5|TOBbx(}YzcZdO5jx$>iKX$`MEPF$J|qYr9gQv2b13%*t?>cCk)_ZC70J#F%FuQ zqu91ODkaEl3w&*6VY#8GtDAnVzU0vNP&o3|i$rfIq^bx?!>A`ricI#9oog%<&@-U& z{VJy2?{;tW2G`hklt}XOfu3b{1m?yHZ$t=YcUnrUkqT(= zJYQfkSgm**uU16}aww)v6P@@3URjECY`1qj`Q}ik(i%eP%d5mpaokX{^ZB`U%qf36 z-WuHeZ@@d90hqMh^>_H;=Ri>7HXlYk_TR$Pbo4@-cz|n3g$@4X{RsX_Tik>tZ%Q)G zI6eQEsT7g|3u^;q$iXpqHC^>IYGqat5`axBiCJN2f_QiNti9n`Q!M+`Weq|aJJy|^UpNr5WyW#K)oyR`RJNILq7k{C;$qT#*g3O{jUg= z&KD9UoPBm_daz6iosF)@SfJ`0Br>xw-_+u45BuqAnSK?z@1s1QE4(EH!X!uEJHw+T zz@4}r%@!kteUE1{_W)?f;z;;vUlR_o^J%v%s*g9p@j;i?-ddRd-9ilkZNx)j;rhsM zKLS4X%=hb~{riRJ(2DU6JjAVlFz~+IP@hYw4mkWW5_V%H8P(qr^k^2ki{ zfCz55XM|EJ8Sr_j+D z^g!@j2I`x!e{>|xHIFluo1MQSY+&0DeDLG-F!Ry`xrs=4kqTxEg-$@?om@SWz%(&G zeuPuESY%!rew(d@pOwODf-zbnbU~tsE>%!qh;|8h?S)IKNpN`w*aW#wV9JZX&BA?X z@Y2j;C%r%+4 zTsH>LN5t(p91}fwaCBVi_9w?aVvBXs|6Ui=navw}IRixXzEcvG&IK9}YH-`rusNy- z@YJ}B8hen686v8wfq831`eiVoajFnUYB%HrfMvBJMTx1B4d_y?~}e=P9?x5V<9MK)!-V!Xc)E_H7>y=^8ob;9vr(4)d+Eo0^<9*xw$cb zz98JdPcAE{R&dvZ(GO0NXHnFk{$;9PpyE58^M;Rm8~cV|#@z3#tGUXl#f$7qHP%7Y zlS?>wau(q-1R#KEIF}aoxCql>%dPtkc-4TqH%ysEEpaKIxD{Qv@$BEbIC1(p_5x8@ zv4{$>ZV=?j$l6>ubR3EM^jR)6B+5FR0r z@3{&$x{eT0Z1cAJD~mKJW@P61n@5~JC;|X&9duz*n0k=zYj-(hlz=;2>H@QF?QQs2 zX8B9WL0F~$8WvF*|DZh%0pCk|F8IG&yRM^G~JDk zNtjR&zVXH3k;{spab_XX$Pq-qmGgc&mw{we+;D)($w4{ho`U+Wj?J&+a~7d_C7nh> za;Q8PNyx;Ww2wSfkwNmeq4dQc7Fp^vMdef{3o=_c^0;=a^WlGOqn_>u6d)`vKpAlH zP>7TEP~?b2J#RaDcX5+8mfAM~*ylW2wBiVKuC!c4g&qJQe7ES0jkxF)Kmz@TBpi52 zI2f@8e11zDu}2NqDMY$^z+YNSoF&arMqVa@gO z(Uf67Ymwj8{OZFH`o$kkzwxYEF(8hExccxxm^29)DZ#5b4%as~G~#O{?q3gQ1h*|L zjSpu{tLVBU(vCgQgHo@2M#FPHO!lbq@{NrmGuW)fr5W1x|K-&9F4entCE1xx^W+goV(vO&$NzSl(+vcjZlT)0BD8V#{+v@B?O7vLFH3ODG2?(k)Gi5Riy;NJ za&?*cOH{S`z|FtY`@M<@o^{BN-VVnA{gW~qKkOz*lpRUJf}He*+lc>#GbO>T);w5s ziBw>uay!0hRF4w)E;ThEP$4#s^F_Cp6)B1i&{#oAN{R`=Gh^I7WB6c6ZKbQvEe!2bSAhF|ILCnX zm6eSza^Sa5$DQ>z!4hVAoUm{*=Iq~~MNQ=`Mxygw}MEra+kDI78-Rzd)8Je+2XllD;IGBcbtcWp>p9${8^;t^hen z9TJPxco4a1G3_4qYhIp)zV`M?$hSVn@TLxta8I4m0#7-PUI7p7b`c)q(N36uZCCXV?ggFsnTuo}ax1j~_}+mwQimeVx@A zU3uMsSrZJ|DqW)_L|pGMbB~F8+xV28xCjz{!`6P#6T=-E>b~O;ul5z&#vhV9cq{8^ zd?x8zb*Q;*X3g-tyf%!@=v_}N?OxwlX7ek+lL3ReV;U?g5J9gN+U|bH;0KH;P!`XTf~_5i)?SzyI|xi}GI24aQg z##k_|(7uq~<`Y1gKOL^$VhOhYdhyLsY$z&Ofp|}Ww8YHLVEkzYg)X&?AJ`e%hcBj@ zEfHI19#pQCGHMJ+&bdvs*)%LnueI5DNcHr-kR0pwOa$MZ-a5<;D$n^l)au8l_OVLP zN|HWmX=US$2qj`BrX|`lm5=;d0nf6hFL82MrITY}4@-@$7(@Z@#Jxrl8X&fwh%WZ? zV6*G6GR(bS;Z7`po5iK+Plda+2^873{EeM>3)T?6{3QG!D!PAo8dzivBv2%r$D$D@ zoE>4rh{*`z+qav*tQ+efXVOPgnx33pLGf3?kMo_015SOLzlO9R?wXGSnw+z2JXwiX z$v;^}dw2+)1Eyln;<$b%fIw1)xmGfN;b$ZP#+G&DWpGJ);`gFUOK0UtAdt&C27F<)G0VGOhn zQ-j{iNUG1d;5SnI_*CILeu(DWa275;&)KYX^6W^dp=PK5v1~JFR}tFL0s&K+@DE^bwSqj6hW5~Tr z7#FC7d4M2OVG6Nc`i7RoD|)@03oxQ1QtBqkZ;^-h;tf`pdp59Tsk!SfS2r)&`~rG^ zwM^YI!s;SiL)b=)%91~prYSvEaA+Covd5<=EXA1hFvHSN1j~riMcbRoh<`M`U48zC zsFH0MRH)T{BrZ^J>eDb_K7d$jNn}D>(1dJHWU)!&g6gi^F4X-K$bE}faD|vbsVCEW zJjxC73@LlLcA4h|cx&+0lSO?0O2h5PS!AdN%)bugR7Dq1pUDE-eR~Z|judD@XgDDq z(zg8|OgUG!rsK*7Whu%XUp4$^X;*6sTy~b7CYvx3BA($xZJzabFrrrbLl_1G-Ru<1#E3 ziQ90ZYwlyV#B%9G0V-J{MBu*xT+3`d+uc>OIAyTXMxHjg$o{yn#oKhSl4YSi3n_wr zeEIz2uL*Gw&B8OlRYr{_>=jUT7H&-t(|uy*#Og45k>zSUTq3!MKEL0t4kk?#jpjgo zJrUe|ngIO|aO`#x2w$o;P?dA^Dm%x&sy&2izXT&rWCGbbfB!4yPXK%6?zb4|k)w}D zJHq)HN=^0snwA<&2Fe_fBxW$;g!-m53(t{Uy$G05%mh*6-W#f4NT&a^)Nh~iG#5{8 zV$eKs`o;dlbMIQfQ+Bd+fi#|E1dnb4WcQ5tfzdCSe0jCU#p}gAPvpx!5LdvpgIv8R zzk&rb%NG5=&MqVvMAD)XZh?#r8IWjdj9Q&t}!WJ+4dmfAHrA^xXGD8{e z%+8xs1Lg&z*AogEaoT`9e^Q(@k{_%1hAjYHuxds}#f+SCr$t6`OR6S>CWTk=->Xjm zjk84Vj1_GzT&km^lP3nR$T7aJR~l)vLg~S^(6s#Xs?1wc79QKzyt-pW1zMi3Cv044 zcYF6(T91!wfGGa14incbmw{DS9&B>1p|~`x;exb%J*!S2TEMwLAIE%)hvSSZcR7nw zg{7C8_4}V9oXh32mIm`b16Ie|2~SuiruzU6q0sBssyeB>#Lz-2=p6x%yVRF5P%*H0 z2_@#^m=PNGcoI}&Q<+!@wuR2Gn~&D~P}@{$fWG&U?N98qQ$m++6d)su-OhURCDc0O zr5Jk}d!_z%+`8b!o489|w;D~co*!h*rJoY&?ECriA9enC{G4Y3T8p~vT8x=q&A0=d zI!zX=vjgI@kjSn>gnBZ^V=;-yONhpjjqq}{Auvigzl0N8;1-Hm@16riIowF`*)>U^ z#i6_nvY1{^Sp#~y4|~ykSLRj%ngBTcn}*OSvyQNz?Ltc+&3cXKFG!$p?=5_}*&8O< z+i&PFrxJn7+Zl=U#k{CutCPeU;-e9kNkHzoy|JMgXv=dpPRBQcRqumvyZFxb1G!)` z952*0m(*qd-B)9)fmDU##r~F3PP{Z;$`$z~JGu9i{a(2K{Qki8$7(>T9v}4WhNd3X zwyrSV%?9|4tWL!MaS{KK%j+ArRM8$M!TjZ%IgM{}$*lJ68G5hn38zgk2-KqK``kJJ|DZ&`chgGXW#!G-D=RCFo)@$ae&Qhn1X4!V`%~o$OsoC~Fz@>D;bAw> zzJ7 z5e)j9uSZ{K&9B}lq@5%aB%U~6{j*_E*^Az4LY8;PHjat~Uhpk{d`4iMITfTTXjKdr z&0$r1PCX$>1M^z*TGq4tSov=>f&egHP;YuRxcdFk%6y?M)2fh>MXni)mp9hb#N2Qd zUy!T#L@dp^Huhh`3t}L0$UPR0qJia>Y$>W{h}gg@&F<7b)R|8m#O_aB#6gN`i&)(Kl`)@5wNW~pwcW7gVU~r zi|{va(A1x)F&dS!c}X|n-=>yDS&&1Lgvw|w%r1b576k0}QTWHI(Vba?m!NCIf5 z1zx|bURDa~q7LCw_EMUbLN>0*gFjiU)_Pi1M<)_Eu(r0g(W2((&%Rn-`$az9^{dTv z!h=o3{oey%@edbWbd*vtgc(iV;>6u{dKm!dL*=Gs ze#Fpx{729yBjtx*Za(vzhWbp;)oG-@?HvRmUu`wfI>4%~Wz=5DzoG>Il?FM4huntx zy-N1aGaWqfXd>Js%zOzwN@PoO|DsEJCP8RiF{R77N(RSbs$JUR-9{?q{^MmpWfOGO z_!wC1ngX2(2mb}8CMn7t3FIre$riNf^PeVss2rrzgAw-j;qXwP((0JBib1;!+-NSZ z0NKiB)33eG;b~xZOsjV`Rq=FBSQVeSPXL%$8=HdF+FYBZ2y}GZ@8ielKj4K`Aff_T z$M74K+6c1}z%gwsF2UgX87-!ymqzZ|V>h4B(!U25xPv;!)e3>J@58ptK*tal7Nr24 zPv<@op`oE!SzAj=N+S8)Pv?fQ-6E6S%lLQY3E)ejqC=7)xsS_o^|D?3b$!ur6=KBN z#kg+HeMegxV!<8Gk6wmQ!#g=jq?4B#@1T>93t{W{dz_3(vm_r!(Z!pY>)O|@@qkc0 zl3o<=xMLc;@Nb3uF+pA8nXgK{X*;mx#AcFFp{K3u!-G|evMya(R)fj9WsX1>8e)ZP zgjf`vm=ETX`Kif8cFD`=FHAJg{^Z&944zs_qYeq{G*80Nk98x9Tm{C^Q(98(e_i=+ zpS35Oqe3n(>?o>;0=Pq>+bbTmz~_2JAWBYZx52#Db{qfF3gzFNWn7`8>`&pe1Omk9 z$#c=+psD-nj?F5S0jrfPVH%teg_6B(H8scnI`&zbf$JRO+pQL9!#?Rh_@N6?Z;$BC zgaaz!3!;_{+UJKs3HG0cu4Im7Z86#!gu|wefhV?UhbJ62*k)dK-(wx2;c+jvcyN|1 zGi&78SX*NWBeKl^+OqkptehuU6sYamsdAC@F4S1krCKR{yCM7+oxy9lx!D(ee&U-Lv2+_SMZ%s@MoEW1YuXJ47|g6rSs$yVnA94tEKnM&MzmdvUhXh%XVhBHM^I$ z9~+{9zs#j1SrEaOE+q~Ryb$!CnwyruAQP>L2%D{u%d?@?b$xhHgxC%aVsVZsL98A% zes6AhmP-KCl-)MuqOx6K)AnPfCTufez{#+}qDi#6!)5g$9S}uZQ<^}o?h{x;!-)hb zd#LO{z>T5M7fEB5;^C==A_c_#5(b_xFNFa9MMGK$@UQ%ww8VrOgX{b0EZEqUMOPUP zpOCy2%$@X2*~!3n_@~g=S?*f0AYzO7zKNGOXl*X%M`)U&D-O4QPxH%tf0725Qi!O_ zh^yDY+M4;p$B&|3kHf!mG{_c`FQgtyencY-z3$BC;2pm#Q|fK!IHnOiT1g0h-WvfE zAYwOegprTJzYDrD{!`KBoH=wUtI>=Gj1xM`)4iZmxUHS3qlJv6;7@DY>o?{4=>C!F*IqvW=NH{~RHhb;-G1aUKXAV- zKgv|WD3jL)AD<{{N}D$CqT;=jPQvM_1E|w77mtXFl;1A>Zt;(SHVe|xEo{t-s;#XJ z=pW##0fE8bcdolJg*u>SFI}bb;v9d0>Su|0L+6@=Im`skix>dZ7o3Sj;@_Nso|fc7 z;LSM@0ME7}fnrFwk-ryZ45US|QV6*X>H+XXd07*_EOdrhc6Amju-f@sr$$c@G2^4z z3Yi0plVlx!53V>K(a9+m7e#ve2sBWSryrxB(AgjRZZ?9Vh%g7DSNM;2*R>bo8z|k6 z)H-t_PRv50HP*EN(pc^fdmbnDm-G{`GF7m4`0kL2f&-mV1i?c4!|(4;A3poNM#j&k zydp=xR-%Jkhex!Ymb(_T)zm$T3fyV$Q0AOpi0*1`#O0OlgA{x}){IH`0mRULy4%)O`OH)=Xd5k99Fn}uB_cf!RHu{x<>zpvmzyDv??eTj*r z*xLSAJ|uKd1&61`q*J?gSdiQc*~?pvD)#8FFQzXqbon4L)P{XF@$db&Gb@U$2S-MD zKb|A^o1Kr3D_^xuOLB?Aezvp-|G>xzQI(TJzrVj9ZK77j3;i7Yj8h{#Kb@&u87gm!1v=_Mg+v11~R}!4E*6=wM9MOzG^Y!&56sy zz@GB&l`Cw`@yuK&VYBC(b>QkY_X$>uW$Govmc5r06EC3?6PyuNxh9Iou)Zw#_(H9NjnAy}x=uWTWw-9ca2 zW7OoE8>jf#(`t@fkYtPgDw^ z%sYDx=`d#eF>F%rf4Q@H`CdSp8Y@g)mg5!7rCwzf z;U$lszPb0Sb)Y+^qXvlRkM}=MX!_6;(jV*;og=_swW;i-U!eg++j#S-cql#o*ek*T zq?Nm3!wl7X$2q1srk$Nm?N4+Mtb?X*mC2(?`)Q2tmn_M)YmiLbEP;r|b||Uk-&bXs zj>g6`jLKON1qHN3z#iX&2{gN|Z$O0&%caKLGglQ+K;a&wI?1XP#>&R#cCx^BcX#)O zjZMbDAm?uHZS_facXxv68K353h2JHN`2vAahcJqwqW=1y|Ekehss6 zi}^NkN5W@H)!z9)*e%@L|*(37*h4Z}-lz=`~G~bRu zYcB{MAu25wclRsx5N7`L8lSlO&Dk{eQ0=1oK(*GYGjr-l7bp?EfSfkdU#D82H6})c zS&i^$vaX^*J=zfMd1^LPj$gw5lTTvXTf&4ixk!*2BvAB#>$|F3!PIa#$A`KBKnGux9L)cfH74k-+f^PB!r*c z1EX72gc3-v!mhiQ7PR)5|8RPtm>G)oSA*{*0WTwQ&mm*SlEw>napV4>g`yfA)F1jq zE{=oo_Ji~o?R*-V4&5tc(Cd-uKC?B4E9fw+@R=H&Kb|0r&}wSejqh+Gp8RPW!4<-5Hc0)0XFsF!R7Kh3qv{;vM`X8ZLlpZ7mZKk* zn7)Pncg2FYSNVxM^EsC>26skk3HMu!eiu&0-_fdh zFNgI8kJ9r`e2{4J7lKnl-qE9+1Y~=69VDlQ$8Szv#-_KH;>6cfbZ^>nl!tpuI91JtWpA=V4vqV&3wbk%DZN1 zX_;w{gdW#M5g{~1Sbp!n)&ZwCe?;U#s6L+}zz9fk?JZ)+AA#nFh?V{XUz?gj>LlQm z4#SlMQobVP?5N+r*`U5+SM!>j1~KlXAQ@%lXYMD9pRJ94UGXZ){bsw4j7>i&( z;k*ko7AL5zrTU2bS`EGAjtN1gR=86=1Ek0lhK{AmhcppHgC#&Gd~`P48UugeEfOmb zW>=<1R4?7yb#|hUKRH2^|8-ueZ1WHIOl{U>Cl*E@#6K1a)+()NdH=D*G~3<}vKyLh z-oCkNziJd@i%w1UWCqN8@%!8a87&s4j?j@3Q_y((^&NmdwP(3*@cAs2+N&8WKvP0r zPcEm@T`azxLBAsr1GZ(UR`LG@_Ev%*(T!Z|6=5=eR?V@*%}nAotcEMJ=M|s;`MEn_ z*DF!;$Za+(EUZOFjh}_!dw{cnNL-!7#+t-Ob5ZSE0FkBXEFOOGlR!5yVGsM$zvCuF z>37AwIPc`}j zc|RB5Gi*DumQq2Ob=UNeQ0Di^$P03;<0`n~3l^i|&~GMs;rnh1r%V%`l!*2`pc2DW zC=pFHTgrj2xQ*x#5moGpw2)PM4Xgo)h{1vp+UL{2Pp`&!WA$Son z0W8+`4T{JZLZs9pv~GU?eMTu10#NIX&Oj8JO<)<1xX{p05`eP^?pXoP_s!SY5}!8h zy?)|}V!0EeQ8wSh0B$qbM^+-@0{GVA(vs;baR8qJ0-*xm;r@C*Ga-O^-aXzfQgv}$ zZKS~Kd<@>tx04}~;XeLXIEucz#Gg(EUIfd(lmKwN`!KLLG0$L?u3;S0=iIDSd!g7^ zzG|@n8~P_N&+EPr5dpB=i&^P#C7)|Vf6lxeP`r(15mIjfMzm=BsH&P>SmPyCGMtR8 z#ZAd?pW%<=GuET2I`+Wx096hpcKm}QAX9vHLpEY*(M=J@(7-@9Fo>H-=`9yy*YVVS zQjvjV6Kv=IM91YI61rwE8(<%s!3imE4z+cFnH0f+{Bkg`!!9?E#mS5c1Vrd~nD<-P zj*@qw8fap?wlj_@qMQI~{jmo`BftmWeh;s?`A)j4lz3d$!(qKvdPxqBdoxIy0EAL< zpiG=_GR<8HYiH@)*NZY!6P??CSF$;#JUO^eiUKPerzv0wIlTQne$!tbh%q!Qz5njY z)$0n_r7K^U`k#d5ut-=i{YAv8qG`0fi&MiAD9H8nNdcJo{!=bb2x03bLc;J2ppmBvp#k`Y*t zABY;+Z9QF-Usi_0&d#3x&e=q&d*^csnMuT_%J-~cN^(_b z+%b7PqN10{udROQ+WYX)y(B+z|3YNF-~Ya0A_hlD<`vbHuZ4 zW%)*59>OPLg2jCk16Ifyvex$UiJ}R1)cg5Q`{;eAl9}U~923QncU5{PZbVdNb2OrI zFcd4^bQfZcfOk27uid4e%xDy<<};yHVt-t3N&1#zrA5}pmqMw1VHs4@@ zlBLW9EJL#4CglA1;Pn6<5J%5@F$X9R;Xg-q+7Uc>at|guJ!@pXAW!fqEnBNM^1q$Y z-sY?f;{}5JP2!b0?O+739=UcSm@r0;?&-7P1KvtLW7OAFu6SY-&95Ji{l^*_J06F^ zFNp++9wboZM*AiSMS~4{@k7`*cS&*hltj$!F09?&2o27A^&>k}Mr~P*q6QyE<`+N6 z`1aap4}@T7nmE#Y*L_Ac!}|g6RZCH|ru<(XMXqa4QX9Y#*8T)2sHS42pJ}odQC|H5 z+YFLR9MK&nKo^isooQ7f1RXkx^msSce0GIY-;sGC+hnsW(E3)4loL2Vd553c1#=OV zcxRhHh~F`7TryKQT_e1&D)+xDkTv(+Ts)ysE=NAcxiqIbY~TIJkT4Y#b1GmIk(t z^*M+QgOxI8{2@^Vokm=Ft*s(~^m+ta+1jFLy!pZ6esOV8GL~Ih79IvV(7-riXFiBU?IxBk z*yirS)O;g!XneF0we!Q=Zfb>zDFfrmCDM!Dq#RwetGH>mMT4`aF_wGOsERl7SY2n9 zf~LulU`+Pq{PysdZONhf1wo|rv(wTabz9v849&(U4zar9(kl_335kkfJ1t{Jf>l#E z`AJ^~0o&Lvw?G}8;a1?jC}W}^`L`R6vAX5f5+4n44vFbsj20bdk5WBmZF`r?8-Jl; z$~W=+p0ginmbhoGKdzXdwV(a|tWv@UWQCQkZO=iZC;GgtAiz6!%zkN1oOj^FQpRTg z(fcN<#}6xAuZex~Hf}c=OS|%d-egPPpP>^TNfD&At@G23o_%_mY2!tz(drg${9?2M ziHV8jV;+2UA^sP+Ga{jni~e7< z)>}FdGSGb=hSYA0n69H6mrMBYews64)YQ{-`G_oj>g$|-_+C5T=INNZ=W*45)76-O zt7wl-@yJ)i6rxxH3ba=Nz@XN9eq*;@Xn-%{dpNL-?|-#B*2ZWYc<#vdX+-yEqeIN& z`5H!EF{UiA41|lTYgK`p0B0>tbUc;TwS?+rlR+0!l2h|2#tZHkMSQ~vqi+{*2Jtk( zlc;nzDi(f*>7#5lV2}pq1OIjBJ_}LW&~q^zxpR<}{=I*2ABjQLufZuYGKBt;f#4>^ z@r@{D1Y1IvCyOaLt3X+pzjtwW&n7mLvYcBFx><($*~irPH|>*Ze%N=zJf$+hQk9q} zs`0Ko7N<1sx!)~}qu(>Ic|(C~C;{QBmFBQz?C{7gGg}~eMfeoGRggtZZ6y|Wnx}Yi zM84m@!Alf~Mh^q?wp=^Dbr$|RUvalz7TDf29}h?UU1{a&=47qdp5xq%-b<2yLvoQM zn&fSY{G1Cr8|OY&qH1$PV2&?a zHzxpKX1=2N9dws!zw9!?Z2;1C12&1P@p8xD@sIRh?_*KKOd z931_B?{$*XueI|cj^hL1aRC@`uGI8)E!iF=O~pNk`T zD3y1c!RsiGwV^&P5?rU2mC6M>5)n@>JAU%dpFckp-;h+LiF}Synr3dP;1$F53kxV; zXPcn`HVC;Fh7*r|dF9{zm3zY!N@F7NMQI75ZW;9Q1$+A9Lpbt{lBa&pk)*^8nM(IPGjob2 zA;j(Et{}sLPd|=xv=^`>@%JN48bUVkzyH{1f z3vTZFJhOX!P$I1jW%Fyq5u?d5r3XrwX1|TpX1Ah)9d&yl^EiX)A66IzY;a9Ss@4#W*m02yU+wzsLVwjVw)5z~aCy?8{G#uv+0K_?HLjm(!fv3hYJ zpR)7DFxaUCn=BM6BVe~aXJ~F->GP5;?z1SDi&c7r^qlIh`iR%`&Co^)ZF{RbR{5Ay zBj-662XMFHI8j9c-EEQlGP%noML<+@FPjnkl`=GL_>*|&3L*_+%YJqn1MagCP_M~IlQ;%Xn^76wH!k}hp+m733fbu zjIXYkB6@=*TMUJI_6`hO$rS)nR@YE66R^~4m#cdT;`xpNQv00<&s}MGdA*jF))M72 zjMr>}IN?2ko0}$jUOOp+V`H;e-1AA6st$6y+E84KLl2(%qqyAk88T0tsf9SuYrFJTCFJ%XrZ&*en}6xCtv<2`Bs!iuJ7^9n4M5REzPvj16*C_ zA74RxCC{mUW}hN8$wam%{y(lN_wQV2k#GfaMBtcDv8O|Mo{EIy5u3Tc_Ik;6*a3NBAjXS=SG`N1 zTBiUZ;)0*7b@5N+1wcZiReLm$Ey#EGC}L^a;?FMFjXkxSIo_sb%_RE?_zCoX6i4geD z!2MrvuDdNtGgSn?I`3R3mtYD)F%e!H7_0(?yUf{ixVX5)OSXcf6X62=B`PX<)P5}k zfe0;#0yn}`{`Ku@+rRN9sknf@o z{?RMz#G}-WK5TzGJav z0UhdsvV?WSxIMu9WqXSjI~zys)5FNn$i+bLUO)-txN%0;c#*H(zD~*9aLYSE6!)z_;4LJx$!O8viY%Qe+jw;7{pD?1s-GN_o0EV1*tUm6Ar=qc#q~$(Z;dgB!nP_2MEUj|m7k z)|4Lqx4|>nLQd%ao09*DHtd$;;nqmbbfs|$*n(fa2;Qx;1lq=4y;Rmp9tZ``v(s3k z1~>k?vrx3$rpf8}fbsBFCe+@ji@n7mGdSf1YWpWVvYxpXIfokm7g24E5@Cd&nPG(f zKsndV9lUSapPZb0&;EWwH}zjavu2Elfq}tM4!S$oK3|DoaXV4!i^LxzwTQC1`JXTW zKbti2k{>PV1Y`4592^9srKPLE-XiaVzum@v@V+s8#R3(JomJ?hm%Lp-nyA zVpUG0a=-c*&HnUi#LcWH4MSVM#WEzFz2LN5eM`^t_?jx`L$vBd9FfuoD~3A+6HPd; za#U$X$&Ixc=K}!J5QdR3y)EzSFEDWa@u-FjV@D6%D&o3_5ex0;qHYK*EbGx6#!r!4 zIgIN*dZtf(O7i(C6xOg-u;fyv-QI8Tnx?&?bAEZRljZn0V0}r1hOXGU(38Jk^ju8x zc6CvRc1Q#HES665nHBD#+8Nj&=oe_76ektX^xXAPSHa|_Z(4tcZ+P#c@;~JHXI*T)W)cwAkatsAd#ZI5zeoN_`%0 zsrMG@1jip68)G|cQ`c&}IeF^q?*0h!&M6*xRb^a@qSe`iB7kVtzVpv;4m2J>N^5pC z?{2b@M_r`kgf(oeV1i*SdF1A-`2gzrJm%jg5OmoMkIx=@$CbLiD&d^`2t;Q8~m zWy*hB({|yp@%}OvzS|Zz8^d(M+8@_wI9M?#TCh&+4D!D~2Vl86XYBHHKTc@3GVPSu znS)$!>2lfS&wCQzv5v&5!Dny#gWw}aeJoOc#v&zyAZ^Vh?a$hA)<`Sbh_~j3QqoY5LK@yhj@X;UGm41 z{jaV?R@t>Zg%kyjFJT#LafLQFehn=8*?JGJAFL*K2(2a`tHVZJSehZ_OMixa*FJ#C z1BmQudb)+rPLrE49_-h|1eP<+_m!LSgj@Tb9G&e2Yd#ire#aj3{p*3Z`(||Wl z$@D;Oj68Lk&tzvrSoX>eCbB{GSBdLwi>VM?6NX|8Vz!!ae0;&j5^|)nX1MnsOp2h8 zNCWPLt)7{gx$G)AIyTnP1s7Dg!_xp&Y~TL&c3{`a(VSgD)$g=hl-p#L(A?cciJ#HM z((oP*80}R(Jw07eTT21_qn#*0Bp%5zI(rRR*S6KLG6<#-2~G6`i%^SR5*P_i-x{Ht zoW{TWvXV~HQwIx_R5>vy^+it@f;pcN>eh_UpLMy~JUJ}pwNNolsG+=X7D;(O%3Ww?cGOmauk9z z%8TDb;u-+IX`lAEeMyYDAjL z;F{^>pFe*Pui6|@yDRS37sE~HJMyn12Lz1jBov8yCuV8~?l+qtB|X_W+b!7KCx`4X zTIc(K2w4|22S{G(S#E!f5xDp} z)vRhLdnU-fUF zjdK;Neg4Nn)`R~zek&lq*|FSM(>wq1Oe_1<=er_x4)Idn#&Y${P8*)-Y4S!H*l&ujmXBgA%MGUu)uwvOtVs0d1rZ5MRO{* zs$B^4AS!T35s7PhF@U3 zr|s|OatH(rCBw=!J=IUiQT&GL>bbB33o4#T#?ajvoJoKSZPD)-sjb3-OiWL&<$S&y zP>auPEpsJ#T*FTnW*X)zFUL38m6kJw*I897s?BT6npgd>rdxdZWpCyY*u!7Xl<|B= z-UTz58v65*UBLH++&iB%4f0rT8>4*Io8uq1) zM4m{K{qw6^RSHl(jPklIOpYNf&5mIo;om6x3A=2JoGz#%&12-?NMDSe?Atbl1QHxR z&hP)KNe7mhZM{1tz_nFj`U{V8 zMPT-*YDmv;KbGn=SGaMcg&Al9+f@cJO)EtP*P$?Nlc!hr^aV-6(#Kjn0K!Y@3yExy zN^GZz76uS{2m-oPxopt;Bir7~dBK43FDaS_3%_vJbDRDU|?L4F2BQg++EvU?iyJYD+B>|1&b` zLtX0i4}DTQG+1Ye=)y=F#0lvLoS88Ola$W~kT?@1ixKyjR(q=uIiTnwq7h^T0DcH; zVTHruCh1;2O<>GY>o5b~0HANW=abdx+pw-tLklQa@jQMm{K5>@t%!T85fC`&iz0s< zSbaQw=Oyh(Di`CFVip=JaKLk$^Si60xgs@{8UT6iV6_9}FqpJt7#mzmG)_3{p6q_S z{B0)zoD^oJ*T?{S77!&9zgRXgH5Dup{^!pN@Ws`#(Q`WHt4k<|#Lv@iAZ&&~yV~g= zX`?1St{cl?1)1Xgj))=d1o190K|Ni)8FPbd6E|vGoniIa28| z*lnme6xIHL5!pra4x9utej##6OD-&Tn9Ph(u*Tj{Q@i3y7RcYQAs9%Pkjg1YPv^4#_hytU3 zsLRtW@0lD&6y;s=T2&v&>jQT&q;|Y>buN8DSa`0>?HJZJHY;Oos2p5)XRR7$QZ?cq zMv@Bg3ce?$&)3%~CNQ`B~HRi9k z*OxD%*Yy|MKo)X}&lu>cQDi$?y%LgYQjT<<355Oe#DF;0*OQCht$If3zI?eGf*LOL zoI$_+LOAP??AUD{c9mMqn3!@`h0RYu_0Aztyi{gfmXh1>Yz$NE0?GtHl{ z{Sb0tpNG3ep8Km=p|G69F(;5H+Zbd7iS=r=K1V2Wny)O6O9QUjxYE6a+d2h*zK$uU zHwvEiGwW}S0#eyLpW!hp2;1Zm)pEAn>_KMhJ7vSPQK2t&8mczZZX-=D1?EStmEsts z@?S<)wso(#o;iFMk-Pk{hkC~XpAf2t2){)|H1@TTUc(zU+?L?}9fwXc{w~L_9qa$K zZF^JnRXwh<1p_fMM`6c|KJaTjaRXt{tO5M?oxY4UK_=GOt0dhMva6&La-A=*!kUnk zEjpr^8WK3M6i@lQqupB5tyy%s&=ae{q4z%|H67N)Z4Ry7hIQ(v6M&WlpxqH;N5!<;-HQ*gF9Ao4{H{(M6#?KiN zFzC<^W&&EwGyv@$%xBDGHl)NdN>PAbcY+g+^=9=yO-(|8%2kWI3yd5BT(l>}$aGeq zsJrmS9O)yyJ;b+bWp`ENO_1hB1WCEkdPH&(EyQpK@S+OY*TTgaxUV&}#}9u$FS3Zh z`u&c))qUtI0Ht5~X>X5CbJ=%waOAy%_@FGk>2=?r>#CHG-z`iM z+i4RpE{iq$Tx4d_MXc%*nXdgFB*V{o{f&+^dSmF;LKavg^AHt%;D>@~{8*x_=m$kH zHmAbQCqmEwb+ypC1-}G&cyMF?&vzmb5fNEWEQqPkPEkTL)UDYJ6ivkOFScatjN;t3 z#$-}@dsY3;CynHh8@6Ul;Ls=YtAvYu;mU;jI$1G*KoeP7NN)EfzqfX0Vg=uh-n7zF` znH%u-5X)<$F*>uk*j)L^utg%}VYKXnyg>IT@X|mP_KG+q%UKfhaB{M;v31}<<>Xq-jd{g@EWzZAz!V0;1rSa)ibycWR2m4_c;fh zS#v<=2p~2=(QWRqX=rF;W3Qp51OKG!f;+HXmi z#ZO_bVr;2}l~O?tQ?<=kslD?)ySdvl3b<(<*a~+E+fZczP=;XU{+mT^!SC#bwl0?7 zP{1ESmPhlH$Vs~>j;*Y$R*tCbhJw*EBN0zT17=Ad| zJ++# z+&@ccN-X(3f|zfbO~1~REb`=^v9$C8c%@^rG1Gs~k3pe4=q$MElN@04*1MU&B4hl^ z-p#SjdnFpNp(i~_U75l8k^B4hm(QLmAA{v>{N~MP*!?fyqgGZ? z$@~62g(X_-ain@JE-CY`8WkY@C@m}7Njqmjhq}X@iW>PI=D&U>#}|uBHBXCRrP2YE zDwLQ!TV0^h#Yz2>3~3)A%?&q;WNLS5y|mqHh2t=LyK{h05<*j4oF`nVE1||cntZ}9 z(DmgHy{xetHPCQ03z3|!@M;NI7k$;tK)|e&neewxn|LfhKf2`>ip$#7r%vnJI%?e01j0gj}@q4K~&?JW50b98``?%Gp(Yr{Yn?8>4&&6 z(ahV8iHcHma}z~h0Is}vd1SIBP^2$s`5dnv5~@IjhX7CKPW$l zt+i+O0hAj4T;_MmLepy8=BxAxx-KaIzek2b!poIPMahCMZWE##F0de*BRQnylTk}I zn-bM8D$}9x*3HwqRIme>uT-I?Rdq{8{as459-p43J_wq8vjM$*$Uc?C^;E1e!8u>z zjRL#SKj>V>?MNbuL7H_*)*IZD$M2P8d*cvW-L`uOuXWq_(VPC9@$1%AN{ocqYj|c_ z7(D&`{X2_4&yXeF&l3m~IPv@Gcl8}_O4(-okHmW8={vWeKFy}5rm&@qWVO61PUY-A zmPMqVlIxk5zrv@svQ7fBu;%;4_fLio(ObcE-i)yQqU`c_D7n|wPRVg^u%qnl+4%es zo`GU*`H%4U4IEtTssv_1I)t(xLS1*8nw*S$N!+tG{+_b@P2xShG*DFRUF=ICgPbrV zw9FW#G12VY9_~Z=Pw4hhh{Dme*_#XiiqCf{{2)I)8jjnz~NFV^jLTDOoGpMZ$NfnuMPW2p=E1dO@tp;Yf=sQ_`f|O;)96C>v zTYJ+!M$tcb|D&hdYy7E#Qw%+!Jft5P_&1UtMqklT)$PXu$94p%j|+rq9UI4SucJ=% zjctCP2_?fAKUJ8Np57g1io?@1Rgw#)ETv%6D2!4d?%$xfSaV(syA^_85;-^RKOS<) zMRhJg#J^P(72)72jkrG=yY8ahO*^Vn_|MoF@zS{=40UEl@E4u6*bOZ#EZUZh@60WV zOSCd`0x+%~5B_(a#!Od>njOx*sScEzl|Ax2oO_^b{x?%vSFe(KnO=sSxva}k-bz1W zRv0V+aP~|i!8>iHOer4@>t7>TvQcej8JQsy6Ut^c6Ur4@Lo2wbUjqf~nvkEc@036QTv?XMoaO{m?*+DY7S_F(xJ^Flz5}y;m5Kb;`c$wzPunw=@6i^vy{Oj-%=x8RsY2t}S*yelxk& zycFoZ3|Ubt&q8-IS<506?7YXTnG9lV!62!b;I;VC{>2nZ-Q;G=uXnp5Mr=iT)xOnQ z?_#XWA(zjk7EU;hmM#APFk!2^>BlLi$z86;7~ie@hQBbz8pU-k0zDc%9KbQQ!^QI% zrEh+r_cPeVKG?r<0N-qC_U%C+6qC9it4IP~y2z5jxl@^Eil0rosBkytX^1#OtZ)5? z*xLa#^^VaYX>L+HIM6YD$d;u7xOrqR=G~i1wc$~pW>dDZeTO4%bdAkbR8(@*XL6zU zEFXU)0m251@9)*MwZoXn|0136c9BkfTs#_SU06!#IPlu9rS62k4tbGl4sBNd;Lk4R z@4&#P+cxMxKn{xY>mOp_LM&MK`N&d>OD5i5x1HZPyGM$@9>vJY#OkDNe$8~($vHl$ zQ7s`_=le@S@WRSJimPu{H=vPOd@CypJH_nn)S=YbELaV??!%EMVxv$F7mNhd+rq~|B(yMP+%B*`EWH`FHZab?uTuZA_3m054Ei>thMhbFdo^z9 zJ3gSt#%O(gkk)%YeMaX)l^PAiZFwyRc0q#9PWAZ)e@hkJHtd4Fdb4RVX&HjnF8{i- z|FH^~g_W*|0??;`0t$C@ZJ)JP%)yIa$Xgq^p%Ego;U_+=G4Z5|7P1n}S@`qkGPpj? zIRg)3tk?L__cKsLsam5^y0yGq5%3=`32ULi|UZ* zaK9j{!bNYEEW|2|aoRZX9jxXXMv=mpBNZ3w6~I&wKS$g|t_sbIc6}g*17#E`Rap1H zE<@b*&gQ#wv5tol7ZnW%o~?6|{yL*lGDzg$#wrw2-!X62E1a^FE$b~ha(nD0JJSY- z660clhvVay-2%0VK~Qj>wwEk(EZ%1zXsE2LOqIA3?xV-RX%j9tu|at0vNHRktkdp7PfdD5))F zw=5FyovBY8CS?wPm$xV*S^rbXiEa}TlVM9L)+In>_hZLwvin;*vPb8Cp~?J|DM!F* zr3NOA+dj!3qDUN7d2WjE4j;Q&=ff`KcMUwGyzcy_n3|Fjw*5)Q+_V}$zU^2V2oT{{ z0}le?hHRByzGMK)q8I4+=bv(JEn@pnR7QMEOzaTo*l)9eew}sfpU*6_p4UC{wp$@pyPr8bBs zx4~c@)qv~j0TK`({S6WFnXr!ovLV?DmkhGPsD`wpOt!Hoea@55WX-lpc3k+xRC#y=Q?q{1%@Mq4Oj=y?e}(s z;CbU`0m-yUu6kJKW%(Vq*mauJwejjizmYThW!s%fHv zvHm`wgZ1$ARMMkD_ur!q&GdwV7U64U>;*>0kWFcvJs;N3J%MTmm!4trUnl4xxV%v8 z`A5cW2?@I;ErY+_hE$KXu;^9ddXW%E(U=poC(pgI*N?G3zw_;WE3|c9^+nLUSdMUp z213;?ZsNb}fHG=2>6;GdYqV_9y@#=&M3-I@k$x62gL1SpCY&L8Z!?tKX0<0~&g>L; zoP`lii}j+n(fm)z@=Duz04Z;L$(OPaUpR#m_0VqK@mQvNaBO9%b7zQCe0U+HH(XGx zJewtPl(TPESWNy84{>~drn=X*Nv6QWXM1*eNNfq70?VIpcbaR z*yJ|d*%NZe33KRF)+JbX9lW<2rndo987%M{5sC2VgBQf{eIb3OOWgzms6Bp_moGo! z=ES@b^*jG5YB#s%Snnj2-B6$H>#vOU!*$h~Mal25o6J-=dk#^|07Z_ST3n8{vQ}yVD3pLSoZH&ZX8{OD^x*mD5{tnshc`9s!>@Kts$Txr zT!rMk!#7Szu>h}Pjb+MdZt3j+_=(c>`cjwbYu!c44B<-w4#9Y?;1>W4hJ5DH7M$FV zKf}4s?zidh`ETvpUB}P(i(+DApo#n#2UNdArzcM-0x2RIcO8PAxYf6N-nn~jd9pqr z>2<`~2TrkoNRmfk6a3~-@VMpT;<_YSofL(3kY!*N$Y zvu^S81D_Z0q`d`RNu2;-&jAcQ83V)M)1<+fe4|njFsIGna)PGK2yiC$k@~3F9&sBa z$vHCkf*-etXq$N@%n{qncmbn{?F4Sde4`?D+I>$|Y0_xh*}miKUxBcZfa}6$&oB!2 zZgDn@T7@g-Rxw!c^c;0rW0zhxL^L8S)Clv*i^2RgiCfLv?yA@!wB%c{q<9B0JE1w1 zNG84X+pPPHF&@xbKFx`UnFP7`VqP9YTs)RnuzV_pyhRb>*SYTYRSg7e@~Rg97|MLz zm^WibB?*FZ?73>~XZ^vlYP`y!vb;h4)VW-=8EfCxL)2du;**6zk{IPo50yrP6FbeN z&u9ov)B+$(m>yMD%)a7Q3=+D09~@M6oOSERN0#P_*;rue z*+c$*+-9vICg0~2V?kOOzzm9LD*!GKGdv~+EH$vHgmkU6XWp1yE?=MifPAjw6WSnz zw4bfvNxr7k2(-s0t$WzVq&HW6Y$*SOaYh_z zSo^U3>b^|1$z)-LWROl|w-9IB=J_kq;$m+d299z(}FpdY0r#?@{s`SIiN!7Un=C@pOV zM2V7o>Jb5ht`Y}j6zX#s8Li+YTZ0L6`u*`A!bVf#?VRG@S}t3ZBo9hEg_`(}+Kw|y zZ_kLje|%f{Hcgb)7eaJf*tgLbKz=RnhrPkxP8`@#p6gIe13TRQYvd?*BC-97gC~b) zh@VYrd}@)0sUQDKsk5TDZVc+pGQQABa9k|0?Di*3}v5V#ZLYW3zrN3gbbx5Q{Z|EmG+?e zLO`jc+0JcpvVP;V>r2)ZY3&HSXCH?7Z9rXI?>px}fAZwnQe1ryVC&Y|Jj6f@e~00% z_s6vYr0~bUI#Rr22ip5o?wIA2A^e;uaWYi^MWDTd2X9%cLSuw>6BaAENZrQu=vcPP z2=Np`#LbW_45gQ4P^_0{SLBfyfGz_Bg?)dDsUBWua@Y55w5Z_iepwE`Z`9@fZS6X%pW&h7ZB{>IdY{jWm2jZ(k=QkSzVtToURKRMTzCh%YTvT z0aPk0;RisX;T3?Ge52y&DPba*2IDm}(;!P^shS=fxR*=8`gN8#q@$f6p~rGeOntwc zM!osH9s-*j}L`ZP4VpI!AFWCreZuvM#bO#6%Ss;D^ z3S7Q|X;1a-)gNp>0-mNeAIO`5BhWJ3Q#j1*iDFKVUxbFL!Dq^j+m(Ofr*2F`k&hfQ zB(QoJdJFcuVD0G`3uaTn?>ssasG{STuFYvvL$9WEO!nLg%Dyv=A!G>%-{0Qu1SQq5 z4D1GOFkv;S2{-$GIB&WjI^u#CQ-`BsN0jXbEWBcR5ecxdYo)?4Ywr_l7Aq4f(W_}Q z$^Q5;#yp>(vlE+c;d%vJXd>n%qh2Q)v=(`aJ+Q9!Av7cetS2$v9~F2I&|!A;4D2^r zA+T|NKc#|ms{gw1uHM(ByCm z(DF}%){p)1%&qA>s?U~6moX~!cr|X;3HU%q)GXLUu~3b{E?*hcc8XRy7$7V!BMy&! z`N(Vm*o)Yxe9Z(pYOQ!=lmpL*jl`KrRhE)+kBr|Hg$6QIfci68A8unR#-;7kr%#D4 zyb_LGfbR+P8;j{w2tO8jc5zPSfNqKzAeg6zsc>c%{G5IghS%8Gh?EAUUku$NTm9C6pdy&VITLK9-#>dcYk*1Eu$;imK>9ee9x2$okngP>L z#Iq&;KKqcB6+^=CczL?*P8<*+U4jNRmVcwWy~z4xe-XaN&6`$+ud1Pn*)4ZGiQRKz$Fh7evoexLKo+0HP2dBXJctT1H{yiHDQ#t z#*J}klIBFo{bv{p(k@^slz%*o5>w4;uu5{*b5Zx4JO!X&nc=yz!aZ*rsG0r)gd)>rNA9ta=ae(R< z$l^)j>hlOtm=mr+3{T&?zXB?HaISbDuxLzd4tIl{m#LC}Cka3xuip-eXlmfYhvm+C z58x8!l_<~C{eQjh&nQmjrcH4m&2tt1;3CF*5B_=G*NLYeJ|1AuO-@Ch!@KSkeTh%)?6swW1P-b|!8*oFG0i?c8M?@Rj^jR8*G=~na!INYF z8E%M%bAc2T&1;ul(O1U%1f6#?e0)ITk@cEra1(~VL=xS_3* z-~&|l8&hJBFZucU4nG};NNJ`mq9ZMU=5VC45o}kwDkG{DV5yRKN26BmNxKa+JP8u7 z!Osf_y}up0*+|wTy^<8wRXI38*emq)^{qtIlFd`CF@%5{|`)%SE1s=kohn7hJ z-wsy)T>KD|3=@yqip~p&%6D~B_I|!jBI~hD2DYTwVmr9=n7ZY-t!KZVTI`j?=>v3idRz3;fy`_TgnYzP!aJEq}MH5xaGZR$xdsk6%Z3VL)w8-WT? z)z_%-(jv-+nuO#WIIT=h2Q(VV8Oj!i#g{w$ZC`22>5!{~DZG6y&SQ{hpFpokchHJ3 zk$R{*hV{0>B*l4W>o4Vwt3ZbyjwHnRs$sy+6z+rjdv<9CZ;tsH{U<@<*!aytPH}NP zB}_8_1K7mvmZ|elaA%B8h`(cXpC=n)CIwe8i=N;ndPYXH53oH3$^kma`sU`z-#1_+ zf#l!w<+3Ikw+(9NrBI2@1uT#emRkSupB$z~r>E0q$#}*YJrNKTRCRV1gye#m1eXh! z0ZO_3qn~R<Pc5H6t;_&5DxR*N4b+N~2-pOT*2~U=HMy z08e>RI{r`3euB0ue`331Uyby*WXoE%b*`DY@9;$^+S3U+gehl}eop`QtLL0{$;oKF zuQKwv006*Cui3pjw7_0gl`coACSBcB#ft?>57F%8DruoLfwzf7H z5JF39B}^YH>9&rrUBF052h*&={PzJBc(RR~VIAe5FzqBvYySA-*zD}UQr(XqmIFy# zUhavRMn2QUA+l$&_%BL#&x||i-^=@oy;!BNsIE6}bYqlFv0Eu~2ra3+&$Ph&?UN*q zX9Uf;aQ>s8F*@-y+;t3rO)zi1wuTevbN`nz!{6&Vt-rUE-H+WAd0Y?s6j3xuqNF98 zIo}@EXy^s;PcLn1VbLd6AuGeqh(XUu@<|! zEef2LT+&xDnGr-HDw>}`XfA&qIH@{fx%e;HJfVp>eM?^8 zSVb3fr4=NC8{gLz+YA~T)2Ph;5n$f7fAc0dJK-%_jb6I46Ft6}TUJH@qn$^WY9$Az z2+E5rb6{WUZD}9?V>rX!x;S@=2nmBON$ZpJ{bz=_03?{N8&Lw(&0XR3!0~hesO`X{ z6K3XjbA5Gu%H93yCP1SHU|KzW{gBIpY}-_H$Odb8d8&Q`4T=Cm3!XQ;|7ne&9XFaP z2SW>Z~FrUx+s{If%=7J5*muGQD^`~)_m1(RetpQRafyPZ*#J&Qb%vHBl#b1qyWYN zY@Mtb&>}?u*;Br8m6N`cwa8Z+G!x3l*l9tRM0CIw&hscgQTtNDCp#Eq1!88|`VlFS zF*w2yNOZiI39X0$B@3J_yXL~Q!Val_sGo@a(f{v1_FyxxdB88^h_hlUvZwt#ASD+8 zUy*Y>d)77lk}iocbB ztnMfQ7AS}@1xCLVZXS$!`%t`r zW<^M|7%7{uQ>evHpEApO#F!={q|_W7G(`d?$bMzX5}v-)!98QWOgK`By9!$x5{svC)*HFV z!Va~pXCe(M7^NLMTJ)-+hxust19lj3yZ{`^m!7{=z@P<6cN*uVZjuN5;R=>D#?@fu z26(I|#9u^I0~rU9WW>@$#I=LX1^U7)gu!zcfla#JsAJ(L&e-@kv+ zMVjfojLqWWN>C1%MDTxg!DkNZPm$W!{5wmO?$$~VST)W6?_h@svTqNPUtq6XKBuv$ zo_UVGPWl~xtyX*K_;+XvK)yItE@e* z@&evytethhub3H{MgmojRxiy6*NB$zDi{6QT`xAfIiOG8cUP`P7IM>KB+H5U)YoQ< zVo;7Gf2@f*+-kb7(|*A|h7B_k;EW!N6*qi6~B88WxYOHh>}7M-)T!;O9s7!-&0 zLIP!dv-MS=vJRLZRK|u8mo9z7e3|G#k zZfD*unYq>!-zVvF81uejZx*ytjx~S&rfFf@<6Qwm`*U9VH?P%{{CP4>2>&z&`qTyA ziw}MeF@*@yw&&7|e|lwVTxrW29!SRa3O+Q(pEYX|e9)G5-Eya|D^zn{m4gKV+fTXg zg^&Mj=)&cW#*g5%q)iHJ9dlV7$Zl+}zR42nr{@rImo_M{}@| z3rcNHCpi!%N)u&;};7u+}qvT9Y{9w9#N8)z2+q zEg9qHbgGiE?f5T)@cYqLOj)h!Bo4Pwjn+#2>C-OICIUxg9zi1e znpbBi0hsi~`TO^8KSCO1&3=5ErR0EHwh&yB;4%Bq$v0sDGkfuZ9<+*JnhM4lRY?7W zqPGMDJVBc>feh(O$(a4bhuwReXu$Q1V;HtEq#~3vy&E>Tp$Nb>;2B?e-!wKg)r)Ey zuo)#HBEo>6r|j0+3?9w9kA%&OrOFC-WiV(z+)rQl6Z9jBTlp((^SVJj9yf(*bvEq- z?(|=(9uVQ+yhyrHVywp8Tyk8=yj&*2dEI4Pg=o7d5ez+CuV!LFqr(=~NhU#qZ%w)N z&B8J=m_E4`y3q-RhSTn(fV*r0+wI#whF63a0k8BHV#0B8Ih6Vrt9XkpmPk$%E;-tm zm~n=5g%=0SL+PeyDf2D0Aheo-??biZH;#D5t~n^~*IdNgFGpAPh$vU|6DhB22$8Da z^T*01fG5XZfDJbk&#P>Skc7yY=IUyYt+2?MR%Pfwvn38S?_{ zKrl;TVV*_7;f!JhSykJG*59-uSBdsMw#GY&h};CMQVI8xwb+YnHr?NY(FMKwE-twl zhKmAIB_1^ytz?t_#?W2McDY7Aj=hH){ptAwYVC|I0FR~VKQ`WTTJx> zW=j=Ez&IU8NF<(gm+bmDc7&AJ!QRN>s%k!6WY>PCt7J_Lm!$6CAt-rLjO9}yPoGg{&01uv20O0pG z^v53{76}!^|CZsa3Ln!%aZ^-dPun7io^XU@6W^L+YsrqVU{I=Xn|B;(DEqy2vLbH~MPM%dxvBeb-2F2PR z!$DICATq!iXd`KIDe}P6MVKuZe(3*CQFoCDa$u35;vBBI?g+RFe|}Ac8O#1DaP$Mx zLF$75m{1W3*W8oH|AZ`2&Z(Ub@*pbuLw}AzFJg(U8cUD!aVQ+%BsyY|#uO{Bot;&| zILN9{o;$>P#2J`pOwa>Y0ppEDuKTFkUB zKj1hCPVtax)eVN}RN)a5(n3fLU@(b5Wv@hhp$F!|5Z%_^BDIPiPq@8giE+Q`!B2FL z7MQ(E1na4=-Vm$4A~h&b>)=!2Vo^=E2+Z)!b*5vU+ubes-Zrwfxmcy_CH2q9SxJ4d zN^nXBNBJ-ZdNPO8P84?NtM-vn;{t_=Dx+;zck=JY$GbX4WhLX9O-011QLu76Xe+i6Padxv9a&Xo${PWtv0jQ zoOtfLNty|>QHTK{l+cS~kbYbjz8h_)VZ*d1Zu&*V1wJrR zvr`7S1%V?-+0FBo@jACjTC+x!Pmj*Y@o5%Zc0NUM3w;J68n#c7XS#H*iH>2b4|mJ` zrscG7Lolu{4)Gw`X0%cd2z9$A)|(SsqqO`=SuuB16>-Se$?r`s9?XRVPbmzC<@c7~ zJ_MRz`CV-waXdkqQvjTQd)wahXO_C|t5;0(&Jy4OP_EI%#bNgK=-FzHy5}}ROU}P_tF{-6Yq0F2wK+C-$(T+ z;y#Uvxfx@Se=X^np!A?gny4L)>c$g8e$F7LtZWfNtZZZYB2PnE;^MaCG(WfU)oXoT zq;MbU0+qH(jXXq6<&oR+PCMK?Ve?*V(oOS`Z@)tuDcXqyV!%Uo4uzP#s)HS^;JxJS zU5079$9lh!Ukjc*4G_i#KRm;7$1FLP^|>@rM$qv@3Cu_Czmq6QGYv0K5!bR4Tx)9q|kj3Jrpc2^jU&q2L%-8<+ zrRF21(4H}mUtIjO$i*s9R1?$m;KU+XJL-9j?5N^INJO|?zSF^Yw;5<{xO~tz%y;_M zkBGc7ayGoybcD+iRmCZ#!NjDj*5{tl6cR%0m=s&resd(9ei($nrmjFNU<;`lJS8llE2 z>x~|JQP46FA+sRic!Gi0+)X@thvMCt)=*$AkKr-PO2$Mjn<-apQoa-*_;Z>5IyHQ2 zf`*xMtX2_XCBjy3v^`zoQ7IoyB94Uu@GY>d*^k;xpknr3yXFR0x9#6pLpYn)%}TKe z2{tK5X<9hGC9aS}3kwTeZ|XZa!191#y}i5Mz_C#gI;ps?MCm=19$$Wu)iO0rn3>Td zTSf=f*VorA`~y+~%=;tQj3It~y}eeDC^ngvl?BuVxFa%A(ekoMY<&DWz?aMV`*)0u z%bj+Iz3Dp%G3#09eF&%Pi3xo4qekZssrXo(Yle!VfXyqr%4o1u98{-m#=IC}ZeSKy z#{dOMtSSoi5{C2T?z=FqY{=`nbEC$RFd%|RFI?P(oWTL*9|=2{Ea}9mo++Urm2}Uk zQSUjS23bvnINOUY_p)zyo`U}_O$xrZJ^FcUEsDnM>-8Sfv8$B?j2gRm&E);nM33$Fi$wcXxl z>sI@bi3ujk2OqQZZE!{SW`%X;*(^#4+UM#Y82VVRBPFa%DDw|1dRBxM{n+2mSL2de z^$Y53I=E;m50A8vi88%Fqdaj4AT<3#OoBPymWqpuhi7hO73Pgs=3k$Y$L6XKCs1?g zzjdR3JlZU}R#f#h9s9WfG9We(C)$C)!6<=9esf@~e)O#0R!?Dz*gP%ybu{phQ{&}- zQS9C72a)yg5YEoY0l;}g&6{r)TbJr{|DKaa`2iEr%i$sq^edWzfzngPw1omlc)jx6 zHoPjIkN#GzLyV+Ct7iSjk!$t0+Rvgx_v#yFl#B$-R# zKHM8}mC>Y;&?2G-UQPRc)fisOd~P3nI86sG*EgrrH_}P9x{mt%yd(u5awM^vG?`-& z=)iXtKrZuxOCpunpn`U0{W$&Qge5hNfFwm*V54m<6H#3OO@7Tj%i3B@&^TPlo`3S` zHyYx0XD-kj7zq_Uyy#sII5TG7vS#aGnm%@($+j6aV z$KAN_4Wnkv zIdtq$qR@y#1%nCy(IP>W7@?TTn2o*Y3}ivHV04g`&rNW>vzTVr6niTMbbMx8zS>u@ zo4b6)?k8-*h1iA`h?+x`Z)ReYsVJae)VtFg>N<_{^>{XV%Q5yu(#1EvM?~o|*AyQ} zQ5R1(Ee)7rS2Jc;f*_bc`v~&B!p{lQ?WSuJM91d@Og`&P_Li&59qgYdP|e7>DUcJ{ z!qzN^S}7*exx#vIkTRHXyKV+Goy*u61VjYbPrci_QwVr;6qX6|uimF^?2ue5AUAE( z*``U&9J5s!^O-P2G7-fKQJ>8LmaNd?Bgy5AJFMl?lKOAmsV%x>VkR+Sj}Dn2DCT0y z8xcSqu))0>V>CNBDTzo(NT~ZDZ3d~$^`5JBr#7&sva2JWTJ%A|(;tw3IX;Q3Te>gc zc7JyrF>=g4bi$w+J8fr;g#{YCHT!WZlXdrqsO7B(48rR55o_)@N0R)-2FkIIs^VR> zxW2NB?LW{#$K$W{H{udnG#MT`>;!IjJ}bnu1D4rXe+{`hv)x!$sR@;<#;z!XLbqww?UEM3Vb8gxF$x+rR8UwX1< zEk~p63ETWq%je6yr3-q6i{N6LnaK4@O@U0gmBbe)qWS?5wSlL?OpK}Q-~a@%`L77d zSkex+f9m5Y1hJZ7Y}b1&&ls*L3*g=Rsu{(w>`%ay6s+06$xZe%3KFr=>hAdpUNh4t z%AwFa_5QyJwGn50DsiO}sjlTyyi1|}YZh##BDL#-eKE;o=5xWJaNHzmX2cxR(6W~{ zYc%y5&*;>9T)x`QtuV@=VtUOUe{zcnx%fpv5=&9xwW6dK0W*VUZ}*J$sUTM9kpdP! zD;I78^!oZcW00h=fQ(^hVr?Cks8l=J-7Vj@s0DUol-JfGvaoa5Sb?-B z2f5ja32mTXT2udvXP!rkfCMPMp+OEnRsiS8t&0GucXhx7`$bsK=-qjgA;|~ArS4JT zm92vw*O5oL`0~-1D>k7KGJt<`^)g{b#V58fO?d8IQ9L_Frr6KGE!*A=3)&owx$W?J z=YUGw+fES@6%dbV$Pho$N;Gh!BO9`-NQsJzY`~8E1>5`>*?`~2w41=}=dOPUxsEZ8 zq8Xv=d}cMf=QoN!peWK(spZ?P6J$f(05~EcDG;GrTsM1yyolE1|y(wDm9 zYY5|e>prl=9vZarxangx-^+h~=>z!%6_C<6Ij2hA8NMaKoobi0+iH?uX)InFut`+3Crgz!e1=EJa1qYzP`4W_Os zEIa~L{?E0%9b|xIp@}7)ZxhStykwiF!UL=db&!>E^uj~5Z|5DVP`!!f^EiXChO`)Z zUW2ID-Zo%yamrfwO5~mXS@_dbI=Pv&=l_G9b@#LeKXn2u-v&k!Z_=Wk>;~+hmzqcD zMrv5^`3DY3@~YEO$lhZ*HZ$VMi0nzgOT2rpg$o2u6(zK!toluXcPJOV6|5mPuTW_a zBuLHnlNI3Ptv3zN;gaby)tnFaAG<>W)qSr;aWYgarFoyof`80>A7ZRI0L(M1Q$#Fm zYh{}gok8?3%&U~>T=h`jeB^~wW3!9rkKypehz_-fp7Ik#!)tL(mFtPTu^{@29cw!x zJ{1wU3r;B{NH=D?%_m81NcW^87a#E5+N^@dKuXY$g{ThcHE%Z+j;~5VD&sCJNV>Pb zGj`x_G2>@a9*X=&ho z&&0$uVD&&?Ze|uVNJ~ct1*GsK^H<~00Ic?Ogec&KNxXP5F+Cmram8OB>gUk)4GXYD zHnhvwfQZpiL(W`rV??_|K#(L~JO$Tw*qdV%fKNc8U1!%I?`Y)|MzVe>@>>=aDC`m| zCE+6NVCj|ig}~-ug;IRNv|VIA>r6!3Nto(Qn7ByFxEMMS5s3mqVYr$y_(}_Fw8Q8& z;pAjdoYZX+$3*_HMu_M`;xD+dzN3qxx%T-+d_XrHYoR z!;iFA=y3Dz)I|J}7y>1Ep=-5l5FW}ro>GGKfPAS8|GnT42m}x zQ4QVKM(1RpFxUFGx zaYVo2yMz!%MeCpNvRY|07G?%o!0~yr^GN;B+ANQlPwEVYJr1=gr=!K=wz@BT!iou` zO4BTD-p-~<+9ZGM@RIiiX8_ja*LJE_hYIrLlP9*Hf~&PVb#q90Rr|O0IQ=zb_S}uA z%Qw3FKn^vbHUq&NkDrEP2RHE!Y+qApu#My3L|kZgl5vQmnPN!UNaJe1Bs>qmc=fP8 zg?|#d+}v<1ELA>Ov{S)d#aa+(B2+GmsAbhO{Fd#fS_)y^lNm(%HOp8GXMAkm^|_Hw zW=r_0oBjo%$yn`vpPzJsM58&$Yk*7w=xq7beezu!yzOC6BJu@QVv%G2FBjnOBeYHQ z$87P7Q_j8X^Ugsl>NLvhAIcN&QY+YcOJuy;l= z0mR=e5VrLOgd`-PGcz-VE*+kAI zi8&v_;?W*$bYKKUeAgd~JKPBGCz3MHP6iBQ5R$)r_a6Jo4r&Jo=zK5>9=4@(U2bXT zZl`o%-;X4wx^Ad6x{j#M?=M~h1^^u*KgGv${c-)cn;ndb1BDdYjK|on^L3K;n#qYl z`K9Lz+NB?c)a&l_P=i{dw1seS#AuNvLBzdKeoP!m69x%n3b*I=zukoL0#KQD$x4IQ zDZj16|NW9L+w<>Z@%~Bovg(QPhot?d&j$tNIwL7X25W0Sf3b}1o`4xe41q)<83U#t zjc5YY84* zL-$+qtMWYEsyFa9S*yK497sA@{wM!e+&O7THZeKjEl9F*5vfV9vhZ_~-?9%&Ogfa$ zEm`G)PH69PmT$Anugy*jqhewJty}ZwkJi2!Sma+kqo$c0#SZ`VP=9GzUAw8ZT1Mw# z(!y!)sZ8}E+nW8>yfhq z^yConJRM!+p@--^}-DIUJ0dN6N zz1N$~hLJ~Xeo{9`Dn9@yi_vcgKPiKr9Z63>`vH{F|21mQXa6Q@5_*5}JNjJ|Stf)iD{vB#D4Q zRmCD}`^5TIVeHNo4B_-%;h=*IVZ)^eC zK43tQ9}f?&@O+$^KCu`LI6Iw2h~wn$FB2IlDIYvzU_(wZm6zw z>IheruxIs#o_;1f1ty-u3f1y8BlJ@l`Qp}MbdVZm`2i_t%c??I zn~|%-INeNI1ZoWIpKfZdyfdZP4S_pl;hu>$XioNupwd@qvNwRM?WfB}-U-c)Ta1uE zbcjS5G@R1s5@beF{r;qKMM-1K0F@H99T1rC9($x5qR~60dvm?V|5facfsKO$oKSJRnLd(f zj)gK9IAanHWZ(&0i-#h=Gw59TNEsI=8k8}o2e+3OcvXE z7Y0NhcN;V*#~AP&bQjS9j=7o1*e^ zOhIn*-@Bc+zp5q{7Py#XROThGTg_)2?yAm_7y0Z(J^+NZS-rvdpFg4Bs*BYga>d=O zPLa%jV<}p9hBbjm#z<@&uuh-!tT!G5ci2mO$9f)x`+h}-ar>N7;JS-fj0EqyV5XnV zJI<8AdF`s-w@r^j_ZHATb0JaDMpR5ApIyqwyAvs2p?+8j_XF?aV9`OCcRr8Z{=^B?4LmC-$#q@aJxI#|; zU|%GAb1>K?a2SjQmHC{+nv4=;eY;*udz3e`6y+z@rgZ zSBm`QvFhOmFcDfl@;39E2P_;HIzK*kY9wp!xT2#OfQNq`bG(4~h{Bs$a0F|TgEdIt zfY`r<2St+R*vU{GM*lm6QPx02GJ)U9mad_6Qs0Mf?rNISH8xM*59r~LGO1mpDDklj z5zxbajkGG5=UTTF*E{={|Nj0y1xyYC4()xFASx_e@y;TL8}M7~-sSw6oPg|3c)Y@` z$QTs9p$;ZElbA3|rYBiZVxM(bpLNlB^Jj3DN>kDRb20l^c>Q;l;K|O?4=cJt;Wc}M zP~gsAgsEJgJw{RV024uWU}~sJPW|%Mri&N3J73Dz{h-JmX|=PGH#1mq*7W>ZF?Q;S zjcJ8PKlU^?&)!T`akjs`19;Bt)9a)FPT&1}-s48h?@6*2?;U?(sGmFRQ@gc7uQ8Thyh*c zuFUfMk3H|dle~U7=|{*7kl@*-EA^*O_>R~(0$CVcMLB4rVOS)rYMFfIK$(P9gSq^9 znB9Mu|EpsIt07zce>Kr5=&VQr|JVG#HvKPAQb1Wx9Ta$pT-zqC#D9}c!P>g7Sc2F4 zp+h$dcH#YD(Hr69v~T*qSkR|A@=CO1c8QX#yvRg_J$E2z!v2*UySA zV=}XHLl^J-=F_us`$oBHb8sceF6v-TDJ+p0U%mxOo*2*k`+={3y1Un!(f?(`MBq;A zp6Ag&=1-*dubO};fgw>f33CgV-7@5AT<@Ar;K;pIH(zOCb*tR;)Fs} zV5n%QT#(Ja@a~y4KRA`dsqZefHIZV~4%I9GO4E6ayB<=_{xK!XJN-iE_xl zbJ1$AkfpEu1M5_gYETsHHwTA;i5|aT^jAFH|hj6{=!n7V_G7;O&m&vsXOvZSEqQNYSG1};u4ae8V3gKR=3G6#UkCm zS3P}Q>IU$XbhszKu-c_-7Gz@r*Z7yMYwo_*9;lpwhHIphNUbbKYF=gi8$GH!mSP9) zxHft57`%A|W2s(?#2?FIgTg{Uet(}Y-9}`ah$UMffvD|#Cbo&Q;zP}mMTGHt=}53Z z&dfj8w~X^*Q&CZDa;SOX`&JGA_><u8M`KnSsNDSrOG~EQ5grgo$%hKa1WY6{ z3CiwQvf2{t#Ys#{Lj!6--SdkfzkdBnJnyr+SC=zqd||3(AZF`-Y^hBUg9d~&&Kt+H zwO;k_zdoW*c*vMl*VGRz60Y-WKgh;?{}lxi;qI$Xy-!_b7Bdp@=&3?ZP;`20IfTO ztQD6>xl^^g{9DfCb=|q0qfU`=@#NY0Kk>j-B7X4li@`Dp5a0E=q*sSBIj{(ad`E2H z*@bb5I6<4F@agpFi~qS)Gj7Y_38$U3-pI~U89y_?n~Hi{XN4u=f5o^fxB^0vbySZ# zl=ScPb$+ciRzM|eN{Y}U-&=W%g&Qz;1Az8i>23lDBM8?Q<`~bxUp)#)|k>X_7P<#z$T%4)b zDYSGCJkNSqumrDBQDi$Wn$D{LxMcN$(HIyPbxM&KpZh){S*g|1C6R5;2z*W3v3I4 zjWP*_mC0H8B=nqjop;!lSK$od=Wv%3GYH(|{J2TVr-<498en{?pq0$fCL+Z@<79aU zEMk!5x}BHfpR*De+RIh+0$STB;511AVUpKH5+RI?uP_*r2tf`0fLGXkiR1PO1uO>% zu*28mpHw_eWmePV4J;7%#}{_NF8#1YpdE8Zn99sPM^Co`dPe%JK4K??MfKJ2pYMPu z;*_2~#u6wQA4(;`19k=e6^v4prQ0tB{$F3VvsNLYhd70WI{I-;RaaUPg2tuXNv*UF zf-x23tx!RQV&d2ZLKkQdSubR?SdvPGbdJhdtAxuTOlr;55Jocn^rfbAevTCUi?XC(DpiYZ$&dW9#&_~SVj*DyR- zxu!D%Gm$C^6kbWNEyX_ku9M+~zVJCJs4n2d>%5B@1N4aro@(4>J~ndbR>&NM=}?Et zo+-gftye>095ba>tQEWOk#GbDnV5Alm+pV0* zz~pMgu<_%^7aU;z-4%M_cUJ$6rkpXLfki20k$bt_IDljoe&ApTtn-&(y{9;m>#_ZF zVm+-<%JL$Suz;eDEesQr^6u3b)dAJXWym+JtX49R)?_oXeRW2o8;F7tYX+w;1-o)Z zcr}FQ7d|2g=WD&2%4tgap=`++Av?{8DedmHZn?2)q%O2qSyUGMLM8dv0TH(5R6R1D zr1q2|V1ty1`$K)#*`CLTtdz8Mve?3FT>Q5&^kmezSsf}#|+ z##mSSptHKas;4y0B!h#?X5QTSKPiC_f%$un0`b%UY{{Htz!{76NJ1*jOL1f~4ef zAEDCiIL|yTH+S67js5spkyCf;4sZnPn6HVKz|{Po4_BROh4yJCw13&gQvQ0pir@Y~ z`TZj{<8R<&1RE6OLsB;fl>MhL18?Scr+21SaEe8;}>`LD}X^FvUqjkQ>o zy;+nujn$SoN{8=mIk&?IJ)rCc|5@R%Yjbh*FCBL`G?Yprfv9#UB7mDKHv~_(uSPgX7S!a zqO=Z@k695czwMP!Kn%h5my$8vddCd8IfoIQymzOQ2L{U;mGjzgWu5_9UUWl~5KT8j zJ|10D?@u^c>Gqx07~Cv0E)iJ%YgS?Ka`df98s5~j2k4Tl?g$mc#$vZdpCf! zsxQ7OZCasR(xzud{k~>k8l&?fxt;D~aovH5-&A1LVYXuZm>`@WxE`VIhl^@K9AbPqe(H)J#lw$AeVWmbC?pYEkZDAbN!(UQ;31WVx+Qmn+l(lja}x^2_nBh1&|0NdMxZbrsl0F7h2wK^awQzE|Z zVt>w3%A_62_pBv|Yy~Srfjmubh-B0qO@s1TO70FcNMM>Wt?Gh?y)W-<5%US30+vm= z87DJ|FW))%d}1;!KPDgln@2UNwC%ovyF-6iLn%SQ(OaGkI&b{uuL<#Sd^GXOzb-Rg zztDF6>kjJ1Utp*66nDuH#ZF*}M|dQ#l&y+5kpflqeInSP-#D9e&V$NfGOKu3C>OWp zG4+l2Etj72(7K;<)@~MeEJy%+bL98rjv4Kz&GL5Ej1Kly!A)1RX}DRUTBgt^JT-p1 zwCS;K{T<_NGQQ=_Vp3M5^+Z;~&L-WD(f2y2fc2DN&nKB=#> zCm^D*d#sAcm;K{h!@XH4cB(;nUDN=eLf5l1BFBVKqaQWsO#V(#ub!}jD`woD^B%u0 zRm3}|4jT2o=J!Y*4WwT^H z2%V5BdTeg*+;*N=f~L8hhc=P)x!dsfqBqviAnsnr1Cu0{Eb}Aw%IdjNrjDsV^G2>n3z|c*osvv!q7OxbFsfk!V zs%;WMO|19bEue@hK*A81|FC2ItdA^*=f&9UXSS3`Bc|Ua_4V2<97Qu%Hz=RjzSewA z7w+!t7VUO-tSfT%L13vd%lU0kt0`3LCGehZsOs}v*@a!Vx|`)59+$%OXBbQ3oW3bh zSxAeC4Pjyu6~FosMBu7)5{PJO;C6WYsL3S_qgAXlHVccyg!S}j8|L}6)>wY-_T>b| zNgv<}f__N~s1P?<1cxTEfw;4RXD+PDNwVMkm@8u$OCpT{x?8LMvj(GaN+AApcCz~U z>_lJHPPWJy0J(S5$)5l(DIskA1hEBE`{_Kh2aL!z!|N$`QI-Cw^AQ=3%HJD`9{jyx zmy5Z1_b{MbByo`l7`?q*0kz?jDBOfdV-2CE1nNt?f6pZklT&het2`}?mfcfFITVZ< z`grFz?~$0D@QH{7wh5--15IUgG*a%UN(8h$z$G*>ie|i>1{6R9LWX}XycT-lPy$o0 z-}s!1%-qkmUM8q9K(Cn-2aLNziEk?GMhwfTPpH~j>h7UoSMBbkX})zY_D>RFK~#n- zc47{A?|nkOCWG7qtor_4AWWGsso<~ECAANkH4gdupE2o-c9{_#hvTHnyb+#qH~rNO zCf>&TgoO53iH~RtUmhg>(hXe7+#kC2-Pf6{s76S`!zmG{FL&f8FvyjbIhed(D`@ha z&I-Ma>HX?E|BFOEy97dM5&AE%BHwLHJm&%q5lfRG#MGCr@Gho8^*^-hdA%@1`#^`g?eygBPr8S4f|2!c>iB z8dob*L2<42JUHa*#W$i&CA(Ba74-R)zpp&_igXF^`}>?au>5ENpA38^P_b7i`Rm}T z=uO!y<{2c0bql(%VbuWGj;w(MnNd^w(v#0bcSl7fnXgmP09TAXPY6`{7p+vRaSfJ= z>((2ZF&fDv_>5!JfeanGSCyA{4>Sx1+Dilbkm(a8sYwIK*#UQ~8X#~?Z3=Dcr!mnU z=e;3zfhsK?uy{vU25w;B_LSB<-nBxtN#}=$OdWcu-ZJ!MU$-{{Dn0Y_1OZEI**{XG zIKyR$iMDnWC!~`K4<}5RA<()5TVr-~2T}o#2f*shCL~k?N5Bxz4jk14J0}<7b z$z)nN@8DDu9B{xU(y)5HAQ%!Bqr_KaWjCuaoHH7w`Qejs8IGok_mX}>HCgO_5wnTp z6KUWB*Mhh6o+>y3{6GnJD7CdNTKCONc4*+hZ^Qc5hns@6n}fiJtVRoMw_|vN05FCd z4l178<@jIp8Ts>4p4z>n*v*`rBPb;p)i4Z^_$KsE{w4daAQArZSy~==a9waJuf?w3 z{JYBWtWF+tD4XSGmd^gmTaP1b&pfK~$Jg>af1WE&ABRQ>Dc2kZPVa+|b26&>XL@Uj zU2#h3UK1n&&WB)j&fn6B0xmLRwqewd?@Zzym_lck0;9YGcmF=I2<|n!iEk?t1lo`` z=>0!f-aWXemAkfk8m&@_sD-@E9Z;#j(G+-_Zw^3Bz=Q4eF2$qYjMwmzejw(}$3)&3%h)e-_*hy( zwYTQsd41e@LPskLZVNTvFy*{E?*CsdK+^6UrU*uC6an13c+C9+KtB~*GR<8BoD`Ae z=K*Cr(q2V$E^ilh(inkGDeqD`O}dJK<)naDO-*$NFke)_`~`=FoG_Z9f@Or@n2FmA zL|EW3FsgdR@Y`=zUxk`}IDee=GF79i17JedY)re&*YzwUU+uR)1r@FR0s2DoxO-`7 zdh~Lqjfe634zQpOU)ml$ORC)2_||w^Jk~<-Vrqs#XXZ1SicxncG119AoCA?7V@{i| zdn9f;^Qh;rEZMWM;qYPNqVwRQ1LBbCmf$rmo{x(52gB*+lJ1@5@jY)6PQH}`Pyl5n z79D{RLZ#Czw@Z&@(<~c6Vcw-O$EsovDHhQ+x=p61M*zi$*!v*|Pns zZ@;GJaveTg|6xg@dZm>PNL1`Q#mQhIBo+z=oh;K!BO%FTeDMN~xt2P%*-kU?Ssi1i z>%hNTWRx9R{N*b+R2ouG_XKOJv=cI1 zm&b-Wslx#WULd(IrTVkY>TasXmr;!1x>5MxH1qjgy^tPr@gSP^vn? zn+|!~DSsRi?AieSe7Q+2vSpJUgr#f`26g{sE9k#%K`F1PnD{+Y776j^@Z)ZB&zM4kndl(-^>2b42Miky_{|1Q*<*3F+)AW(pO_EgfF4v9W z#LoYyvf1v$u|rEqV1#d@xp`iy4x;{wpRkc$*Xwa#v9oR9S|h zo^09}8Z&$9i>_DivV*!0nNDDI|I)%)D)&mK3<*d*VZP1)Avc5>-+&MG5(Agu{@kd2 zS&%KJQTR(z*={Xr^L`ESWlMdaCGS}SUsIesFStR_dI4IbPZrSPX!8@*QjCz75VUQm z%_M`$f>mrEa`I5VhpfyP1o%`Wl4dFdT6QYfoFudBO0!Gwk2#Me2S?;wB(q>)MLHJ& z9;X{rg0}$c!;Q+HxQXGjOfAi{l;{5qXKcWU+|BY`H4omWK1-f0=xf#vL|lUP(Fk6-H21CfLE zWW`3gqSsbUTrL1m2*$N|xLf|9cw<8wYT_N=l|FjnI^~}DxruH#M2T{X9c39n)|Xjz z07(Tz3bd^s$$nH(8)B|#LKjvK4-qk5+SdiKE%k(*fVC)Z2plH!+46X`56L>)r7+d| zx6E-KXWE4YViFZ32G6_L*mT*ko4MJO{}>2^VWyV`BhCRh!bepVGqsmsOKa&KPy~i-5TZ!P(CxEoJDd3iRZc|vKw&zwB7OC=A&iKUq3OO>o8n*KwEM(%@KgB@Gt1BSZ>MWywFEKsUIug=$6u#_c%9uMFnZLc`|BL~t!42dlgcE9J z0*SwobK0yTU}-m%A%n{o`B6_xe*xY1xnrEiy`-3M--rh5{+NanZDod}ys*|+hF1ly zH4K3-3j}cS6T4o3Wk6aw1|iA4#2_NvRoY7$r-W@2!Oa4&e z{e2A1kY+y!PZYk(k-kezqBSZAYB(QnWYsC1S}=tZ2saHK1~!@2dkaz%p_ESW8}X_f zP<32{dG!@cGQ3D=Dmq%w0})>rZ2&a<+8<9|X-9;G?gj%8CTs8qtG=cUjYXaIUl`i1 z)}l3vXcah*iFB>W!`k_7X+&}q=ViWYs6`8qCAlAXfwde6tPR2xHQLohzC~?w`cF;` z%uE$oz8Zx|GH@!)iY+Yuwug?*&Tpp=jz)juPkxsW{S;&qTQXrSI8suTF1RZaGdvX$ z7XVTbLp8H+=1u_4MNE_hcc(0@9yh2-6P`=fg;u(Wl}Zz`e=N$i46wIJxF^75GRbYm zU@_*Jy9P$Lm&**Dm3Zl;$HM5R#CJp+_1e4Eza9Yo#B&Zx$-#I^Vt0IS;&4pUgFZ$C zv9f6x<5@F-O2Dqz2pCz#Cy-62 zKveAq+jsdH{+e+4Z7!V!C^}!b5D=oD(O(L~BR3T5y zdYi)_V9hmkJA(==CxC2awV5x_)*4(zFK@~y2~o){+qxC0(OzwEH1nr| zol+0A1M%Aw{2ZsS;1hbSyGrxidRGzZU&yVBWT6PbTk6e9(|~-#>yYD@;k)v$05V z093|imn~wtzvO5RT?8#4jNTZ&iw)N*?u)?K zJ>Tv_AY%oil=4YW<|(V>sHTqCOU!Mgr*!}vjC0*UoO)bn#2|S%AVK1bC^3Hj;a{@% z89UA@<1p!TTm$ITq;GrXdHe0ebLi?6SvuM;r2`y|oY7cafo*TgW*}DKn_cPbG1%2; zU;F&}1KrcOCR5{&Phbc3>q);ZmQQK=D z^qpAxgZ3siZzK+!psO00!eR>CF+`m6;$OkBIwT+aF-h|y>NSCNkHP?%VFx7$JI_24 z(0qxlCZ|8Lo3g_uA9X?)>m-_FztGZdb*y5#NHHKb{+I5LMJ@fvtJi(+%c~R=jA_fb z)vf)TlGG|xvN~@}mJ4g$^kD*{Cs}*!F2Sc%EV1W35DJa3hgtUPiGANRk-0PbSq+LH zzkq*#v05_p=nn~^`boFQ7$u~s5Yn!^NB)~84pj>x<|S?uCll;LJjuqjXgGXHUgLN4 z`PIi989?-MVtM+PKv(m}=DqaS@8orvz<#^b-h8RIL008wz-~_IcJmPul&#J#X5|Ef zlbB@UdF`+BB-~dwQKTmgXSbuHtDqSA5 zH@`<@`H6BGMP{O-zMkk=j%W#>Vwv@0Q6HsRgdpl;mu}x6d_}5NMe7Xq-hX>ocLTD6 zj1|5?E!sBUp?*qG^`#lJrRZR%g`$%I-I>BOWhWw<+& zH`UL!x8XDlozj10#KbC9j@Xw(AJyjgX_L!1Q@CpNd29QYj~M4&w$3I|!n-+0Xt=rJ zElbfsOfo^6jO(JHSX3l4D_cXC+-eP9_p2~MvHUwf!)7;RthF8VW_Pg@t&xP|vn4_8 zTMr()uCG7GK92P(2+JVDSr||<+31_f5|f&y?9L3XEP+5;>#yGZs|z1L;~m~87-)kz z*mO5FpGb4^syQes_lg=BBi7gNN;t^NupJ-LAN7{d1sm;(5C+|0oNrSN1Ni34Tz1sS z_xDErwMI~0qpv}tRuvs1BV+m_G-aqO7`OYr-de1J&Eh=nYFYodN&TJ6Z%j+X=wqHT6RHFU!@Hda?;X%LLbs>Q?N+; zs?%}*+r|Dp{sOA%MckhNJ3fF@eD7>&`+HoDD;xo-+!foC8}RbKn&4_%ULh1qt`YeJ zY1pM$nLG7CZ@?B&@03L3Hd4;7Ny+%2X0XWtg!+OEP~*X7$*EBK_bs@%eM3Fv%j2$C zur{;Gs?4A7*5SIVd-MoqMQ_DzJne`~BCp9_-#{;gEYbbz?=0trRg&HTsjlZhf|6jW ztZYS$>vNJb>1%_~_aURX-4##8@= zaa2+day6YH4-hJIm@>^m`tXEw$&_A)CVO%8j18_~A=NyVkQ+TKCs)3vNnIspVQDCN z+lcYM36}&mX(8^hTHcr?EEa$3hgs^|{ZpB+OIU({-=7^dc{>ql!=8hqXclo==$SRv zIvAOu`%a_7Q?G{LavE_O8qKp5_kNF#jS}@nZRc7}x%uX9FH~Xv5eNo}<=@xVcFrc{ zM?7UnS(%Jol3ST10M`q%2calEZjXNWSo~NHE6)ykZ>ww#-6sG`@u$}yFbf*nX{7-GpW%SF|Tb9a};7@UWTvg^B2v z4@wj>rwYmAzm)0g_*76lwO^&qHEAA*Z&^QU^vGvV6YiRD z`S{4VY5gp8CILu8@L6+8HC|Nc`W(1Y@6K)AEd;B`ro>jwBNcN&SEj&WDB$ZCT z;6tBkgmBH6e31(2r3c_O75VP6Q(x~0CJ7wpy*-omMLnX)rT$Wt$A;Wca46-$;t5}~TXc$f-^sjS2sP9TfA z>ornmVE`gKYy%!zn{D!sfl3R&ePYoVuT<3}qwoFcYm_=m!m%1nV9ExkEb?F0-NYG+ z^)h0}l4LBgl*~F4Ma2(N3*73h9nj@o;)=ET77(i zvv^L2JgDem@DOo7M7t}R^YSAQlgYKw?aR0@DM%>{SHODgmV zfQ^Nredx64R?3G`hvyMNqywtNKXHPmhdMFA-AtUItyO9%@l*}~2itc6KcMLZpWsNv zAM`&y`$A%2%r?9~&dEd^>kzIP`sVtTXt4EZ3VHPDhi#sM`>{T>PZy91`fTODSE_F^ zd-EqHEsf#gHtDU#FC6iCi`PuvHU}LJC>4ZqyZxEladv<&o=R?h`4n;LMbPE%deU~{ z*Pf5dbaZpj<6Olug4c8!*?3W`qoV0}q`}$Dm|}+4{B*ni-4Ndy_d-7>$%BW5p@RgR zj8~O$zt@)ku-Ldo%`b`n+d;5e@(WhD%g(S5vO=iqlQUP4q1QbA!fz7wYl@kfBEH%e z$hAs7*(R-?w}Qm^;k>Y11@qBExzI?jB=@XpdPc{G!^Q_Z9ea0YYzeQRkvM2H;A4b9VF)n-kR_ z;-e4ZRfs-ndsW~h1a@k940gM?AiZ-bDk(4<2J&l_FrMLCG7LVfk%@f)3_}RZ13=m` zaqM@oH$AXXI4xe3kJokU>m=&%x@OSl`P~~GB;pDm+>B{M^F2XHTFmV9-M>F~<$h(q zS4ZZO)PQ1CVM^xpGt-Xyq6XtdOHDaFD5Dp68F7n@1L?884e^x}#rlAQT>i_3e(Sb{ z@=Z&VF-!Dif2%fZ-lws(Y7-_P_4rdgpH5KululUTt%V|PF%FFWGY#@VFh&@Aix=1< zAHN5%Sc$GF5GE=Jl;W8DyII&O=>d*br`wnZMgUBo1!pH#3QF;8~dKf34?NyhpYk-VTu1v^57 zwMaZ$A8;y7$OmlSTym4$xZ#I&kF|EmU;^}2%q?8f@pIVTOaYPOE5-SoTpZuudo8B! zYkXZ38^4fWE8w8DM3LubF0h`>U~eau^`(Kv=^uyJ5N6ca2YSv)B#VN_na)=Y$9oZyw(~@y7Kr!a{O=G>D)M{gT+I$+T?(!c%LhWwT@^GFGoL}X?melP z1*)GJnidzjR$erMR@r-7Kjv!&IWwL@HiU&VI!ziPE8mBfL9OoZ_ClCyp$xZ6XnDg= zT+|1O0adllVLqPp>IoF?<)8O31Wr|HoeK=Hh(Og+=b)$CaKVLM>KinfX5CRwZ&zR* z-G6OXKGV7vq*AN4``&Qt`Pu<~z>+UTPUSLXmim$8*6ly9X%$R~(U$$qyPOO1FQ}6O zi@|2Q1p$vm(cCNbhLb*h9PV7y9Ns|<0n%^ILm|8fnxqN85{ftYWrA*>254v$wn(tm zF+ZY-leWeC3v=KSh0T?YAWe$ys=VcJ(#`k%xst*~d3%+|9M;UmE9;AI_Wez8tS@-a z?dRLWxLI*hksGz5kjVecf8!zWs47U`&2Caw)7-=d# zI;=7`kg(zJ1Llo~V}uv-kV7XU$PMi9p|X=;`sVzJmEkMkPDA`ADxvx};1WqdE&Xh? z^BQQhyHRwTiki&F@Qh zT>$}j1hBMxy;TT3A-@qc%UqPh+6#VoO)Az$5fY~MRQ!Lv-hfvWO2kiCYI{G7IX!;z zr`9Yab9Ooe(AkyS>;FaqPJAs&JgS-FUw%UwH2;pFAkrgF^BWGeNs8&cV7OzU-sIng zMiXFY2KD2D04IHPs;v(jQHjQ`C=wym_|zhSSTh1HU!*zC!gz~hj*I9v^{*PZ$kwiqmU8O(LM!Py8(jU-s$v{JYFFpI&O4^)Wm? zi;9MjHmq|!ppTVe{5c+gk?`e^RfT+m!rORZ)$B zJ3l;Z*;)1Uj`WV@?5ZE!#L2AHX#_?E)qZ-p_WjM9|BX@jf3HZLveHSN*|RWEZ{E|HW3QW(wJw5&-D)e|@s~xiJ#|d-#9F zUy%KGOvL~6VZ#33IsPX`5mqre*xR^MvKQ`qWfn8(b+o(CP$Vwd9ha__8iNss~#gp&&G?)+e{1A ztgWdh+)J$d^J8T(EI?igxt~8Mp$eg`-uYM4|Jgmpft#{I zD*w5Kjj6TZxI;mSsT^Q9VC>7fype(io?yFueJnaEvUr`fRb|kKb60$)>Z$6F1){is z2AyXr1*ykFI{$m_uZ3>af>e=iZ%Ml>FVD9ka-|0*3E2Bw#dL17(L+~BcC3(0Z`Av_ zM&7P8hydC(R}bb9F8Q+!^93(l5U;i6Z)lh00BVrO;ViA2!jB_EO;3VoAp5Gj7fZt{ zM{!1obP6cXzZ3l5aFeq!6~g!ftj}vwy!Vn6Jprdr zYOE`i7kE|OMn}qA@5`vfp}>s^rY`ahF;rhvpm#j!l(p);my}Xq^6!*q*!bO~JUt15 z;eER|aHH-Cw%M4sRk~Ha3BJ3k*~oZ<@(nrp^S@1Fnyk8C%{)wrT5r&IDV;u5wUuj@ z13y==%h3QG+SHhB2}~C3HIzp7Ow%AxG7s#mC4uLNwDlsWUfU6%qny9$}mptQlpozC_WdJyMJGvSAJD7 zF6gu*S~5%(Ety)JfeiHg`ltQQAX8U_uBpvu5HGt9anL5U19oEV4x^|&ZzWD>00|XY zZ?&~<^3tK%4OR5R#{-0Z3~o3Muv{9A74OcG)&4joSY~y?E#MFE%C$YB!=4`N930Tk z+f!;O`R05vK@pK?wN`Sx8dx;p2}~_kR>_@ib+O7=gI&_B1I^%-J^q;RE(NH|5856< zO?_MQUn96WZV`9E{xA$T2qUA6lKU8Zu5%hQR|*0L{C9iMsJua-YWoG=$E7_ymjCeu zsDqV!IbZJYN2l`LqfLD*-12jQNMIz|f~ZZ9G6f|HHw({h4-+2Rb}H>ozLfM4641E= zmhrQL1s#jt@1&rhjh>#!EHX4H-<`|ReV@zv>w?b~L?Bb>Tfej3N=xm>*I9%B8y;)Gc3khn3Ov$g-VY1 zYt{MNp1EWy3VadYyUWA_1%(o_=5bMC)&(CQA5c(H5j};7JNg4q6dP1jR7AtUfxWP> zaOy3#cXT9YWmOzYLy1WdW6k~b3hg`Qy6(Y0LbE^Cc>#?3-S`C@yE(*~EB&qC6*w

    !*ktBO~LW!iG{%SdN4?vJ1hFOw4L7dK#kFg(c8eN?FA zC8+u)`s%fl_CXFN(d$_gT7S{+>AAE-4{^dxClV4+D}W?u zYF|!GZN!CE@_F3zL$ip*h|jH`N1TPF4b|La9j9E!K269gNlpLXGaIB{OB;-e;uiQ* zr)7MIo*Nzkf!YG~iu=j$e0OESlEJCyPKMXvP44@e+B!NGv*mj8)n-Vdkco+4AQzMU zN()g{`}HF5RA6LR?9|TsT*lMNDId4of6Eon>9Sqo+g0^5&+R2z$^a(H^mO(flLI)SUnk|*(}nQzxF6ESk6zjeZtMs) zT#I~bkcYvcj3*QskV(s(;MFGLu)p&U3v#$!UxoGX1Zr&D3xXU z!E>p<4Ze}BI|?H;*ZMBp#U*won0Axje0L`4(jgQBT|Sw(3~VLmcd9*Pp@YK0!hV*P zn(f{`S*QW7@$K!D&v0vp*!KzVW`}Ul`lDK2PTh322dFTYVJj0ekRXt@LNy3vV68t= z1Gf6{+0PXUL`1*lKoIX9&|kH=aJ`5)yN_pN-d&7sgfB6rA&aNpB%*`njQu!_{f^&w z#zQ1$x6nY>$4e0qBQK)sz*lwg_?YBg8rB-ITjcg zNeww=oWA@TYu!<2$+BAMPYzNK+8rD`N6zG;j^^g>dVHd;f=Gh$%MG)y3r%Porc3pT zdN#UN#~LWJoPY8JfPf}pvv(RlowY;ye})I8rNvl}ehcCLMFcQqJb8TT<1*Y^ABuMK z_9h!oDr9LXbuY9wI=b7>H}CSl8*&qT`BCgg<2!Es1~EB3i9xjCET#&7qM2F})?=64 z#~KMmUXi^AQ{Z8`C44U~#rMmR&0LTCH;Wze`?vLocnp3)oQXe2QUQ-qJmVAmD96X2 z&4P3o zHxf#!#d{4-jxblEVhzl&Nm21hx-n=1_Y}RFFQY@6Pp5I44P(lk7$4;8*27omh1gW9 z((d*>)uH^PxP_4OK;OOy(qiiQ*qGM0V$o@!z2`XzId|5`n_lGR7uE{B?}@9g#Ajoq zLr@DQY|yc><h)VhsuNoTxYyk@QMiTU$V(poK;!YQBWA)PpIMkq?aJoJg)C zZyHi2kCqw}j*jdFo}O$~dde_%L)&nZ+!A8yx@-cUu5@_$_@bhtU*9g#2^`{(@JjK> z0Aj@gNV=_T@aON}EO+C|!{6`3ydXj?5bn8s5vGR9jga=QBfPLrMj0L(fcQblFDonS z&7{#uI{G)fK;9J^hcVg0dH7FDT|DevNul*vE;=nx2e6(h!IzYV^bLX|47n-1BYw>PU@$K!e^0U!QmHrr2 zRFIh(JpH=5w@#H#jkw+kN2pmo1MGVNrjh5Jyr`SX$@^tnOZcuH-K(+9f02b3ao^sb z!*CDrgRAm7T@A_XzLbw7v{jf};6o_K5bfh4`8M~XNv1zZfg-7}H0WMca?{KnCuI8> zW{;>bbmYWG{=8NeJrAt*XSl?0lvQ43_#`o(28`|qoPkVT?|!n-gIKhq(zEX z$R>8)Pd5l3B#C8H`oYFVb8SyuV`S)eTn`ky&)PoWmX5#vo7B+;Z}+|WGd89!%o+Da zdUogSYWjo?{hJxyj=9B18-B75IP8IptTIyC0Tnqvz%S;mF(Hf%E7IeEZkLJ}F6@%~ z^Cxp<^A1@tWjlBPrEClgS?aamCp){isI|r9Z)aNtR$tE0kOHU)Y#*CoJ-GgN5FSI! zg<96vDa40UN#mpZTlcpm#)l6d1cp}3zEB)T&;|Iwq3t)u-wO-VHZ?OaJ|`k*60W5y z1vxC9T6zhg#FA*bg{}A%usObwibfb(G;j-J8(OJ!s%Z49I<9d}>1e-0E~~GI4{N<% zc~7p5>b5z@LJFQ%=nnOf-?8&d&! zGh9^=9mfC?3%i=9_FH!Nax{_i)}h(7#9ZXOI0T8toU%)y%_G<*i`a_+9J8w`qj)jKwZ+nHhf=XS3UptrGN zLfU1|B?ot?aSmFJkjocbiQ9aIWGD_{UFDF7nfP@dl~)#x-$kw69OrYHmU5u(I)aqD zd);qUFV-}9Xu#e$@|#=fpB@ZdS(_XfnXS5={DYp|Y4p<~2=3&1ejE?Xc19Bojwzxy zM(fIdoN~M?z}5mD%KD|G`QX62Ox;DC z#M;}q)6&cZvRL|uYP87=%UKd^Cw3^p##aTP1E0Dixk-Sv_kVh15qPzrZC8h>uC%y+ zMO|C?m!@J6s zOMQxq#mJVQrN*FGX*lpOt)aHvWDp?GS&n(sW`4>L5(%!Bj2QUg@Q#%-T>gCJEJO~k zAd|XUd&pD37WxY)&9n`q0mCBWkDQ;^1xjzs*IFm2$)KP70)<6HTpU()61;pF`mW^f z&``|eq-H1{PyvsCit6OEk`*FqbFx{SJ?fV)U)Yrz^QaXHCw}N}-h9vF|8$>;x?i#T z@&Q((9#mY0JhRhh!=Id&X9B#2w$A^&MqB|JlcOlDWy(U%iSkWTem)H%BBDL3wClF= zYDxI#!M>II+QLVa6{`?7Qn~5juWjm#3uzxB%~pVPbHzF~Ts@CcBaVJ*w49vr0KPmQ zBE#$o}rMs(YK>(B2(_c3r9ji6`+voz+4 zBVYh$az7xlGnJhDQ|J>xa2$Q=Ox_ys>Piz`*Ygv0zO}5~7u8=)zR$`#I{Em76rnC6 zs5@d6*wqUff|q9qVjf&Uj^@C3mkIJq{Wcp*`}4ju*a0@8o{kHOee+axaj^}tM5I=D zCr7X!07kgqwnaTb0zxKqrL5#pGPsP^B371!{8zUc&fYF2l&HAQbT0@oFWheJeyWAH zI*kX48GTmv+ZuzyPsq>RYSWHIWo)P3$)@lhUmf?6>0v2)gmHA_;0RN}!kE%NzhWN);>j`O6$>LeaxRfGC(B*V3$oG>Uji| z2b^-)Oz1tLq8s>t_Hbg%`}+(i>ufexX%xF4uJB(I2L@$lQ&>I3Cob_{+zvC^E*>r= zydm4>vS+miipT2q$yQ#2qVH^@5o#dB4;SFnPSfE=2=B!|jQfw<2zWKF3>rp0EnXU( zWEKr%vgfImJg!@cK&^|Ojh-0cyE8N(Gi%zCV{04$?qo3ry>dWkH`P8E{OLuu-5t#t z&Js-EvmVvZ*B=B*Uihp9qs=$Fl`QpAGuW#pZVe^}%!!gN+){{o#`;|B=*6m29@{n{ zxO(0YPa`*xYMgLeABUB}SZ>GDVXk;+grlY%jli>O**a>^wK@H(NzXmdLiF!9xS4W^@ow+;K(P zh{SY)&FwfHx=FRJGaKL*ot@n88ve-0%2H8OL_c1vw>Z}tOH51z*f4){b9xO)rD|8s zS;@(9rjP%R%cmQNmaZ;fC42jyuR!xM3#Kl?IiL}d;h{6}KYK3V3)Ia@{`Rd*ETSiE z<@6I(9t)+gYbXGAc_uzS!UxYLyB+bvIUMYMBDbF;iF0&C0T0*B%RxeaV2_OwXubXq z9M4;?QOR!-gujL-3g7OpvKy`HQri6MagvI{u3!UH;f!AR3S{sV^*XVgBHb#+kX9bt(d1yMa{@!eFO|5L2Fmej7 zJ5z+Oy9F;x=rC<^R5(Fi>6u7CumqJHMNJycg9h7cRM`{mnU*tE)jZy>Ox`A zyZa25JXlSnQ%S9u&E*U6jr-R6drh`NtnUmz+CQaA%k}D04O{2D9Iz-lA}s##I-$Ep zq8HemVg_N_!X1)IJ1OynZve!jkl|9_F@B(?DS5HS|sJFv>Q{n|VFe9umuhiVtfH`@dLc|L=2*%b!g{pXWq!JY@N3iNA|{{iz1 zeY$gU@LzTf`ioz=r7T?2jgv$u5p=%pSG^N6jeD2mDWs_B4z*s%>3x%CU;YEq?gm2Jpd|VQLos$Qe5E7 z;O?E9upr*+unQ+)+J&pOZgWIE-9bIImWOxYx6YIlD|Qy1ZM!G+^iP!prAUXIo+l(1 zTGRmYZJ&y%&u5P3Uv$2&?GpaG;srmP^s*LYK5XsuU=TiOLo&)zFoMEouk5DmI7iZF zE2`GrtclJ)Pdn{HJ7&WT^=y*LQlgbH>2zM{e?KVtJ~`Pxwr(3$mcnM6h)@={qa0{A zl>~8XL~!|W_|Acd$mY(i;?3c&xz6bSe3S#6zanS?4D^3Kw#WQ|WcEb=_eq10l>NVZ zG=J8>P6Wovroa7x5ky4!C-l@rugdm16s}zJT{g2C_UM%M#zH+h@9%81x2;~zgW2g* zBlo{-!te(2m4-3kHwUmouhgP5)@KaFF<_gG6~D`hmsT;Sgx_Z)RiHGte}4R+t*xD1 zNJc|Mlt#v$ph_6rKHT<3xYztsIA<{@A^oFH^tNmU;_2)b3I6=hGCkpRGU`!r;+(wM zBDW_K)=tVe`e&6O>_9dYv*Z2o;+KDWSRAvEyPaL4fviO=q4kY6BDBEMB{1Slz5bZK zm_618B3OPoWljwrmmoNs!MbhhGMH+t@hWuD$zu72ibG_K9v7xsb9Bu`hn? z$8d&zIQF^s;Q$8FRq>|0b)&XPWJ$rc4p1wh1J?ZPpozrHK{3k!UP*3T!gH^|2kVAr zoGRHM*A(mF%y~6pR3_ZTag1yLi}D4+Wvlu4A-^NdE5g!Ck~;FHfO(SuH;9>^Cg$d49wKe57PUz8Cj;XOL2&Ku-jC)BJ^Dng`y}_TeixC&61D3R@AI| zDWL*bdF*<`qVM0$Ln1qKv*{ojwyVA8$64r?F8*^%q`?w;?2wKqj<{CtV^N zAIop!B#nr8i%#w#$)=@yfh-GLKxNiK1fW%*lr4MxcjwDYlDD1SF*V)*&RDfSC9+8$ zTcE9P(&D>WBd9>w`;1r zi>6W5iuE9>e)Er-eOD^=M`rd*X=s|h|M!-;2MS%j>!SXp_QYQ8K>#(*D8mHSSU%R> z)RJb=A42M#N(@>L+h3ly=xWdw2z!!RTNGlw-&UUM1K`igbnv<$fIfbY(yP?J73%e; zPj&;q5l7WYzRdx`;oH`#p(Tk;XveVkIkF(*zHp)^6*X>D<3pfMp*TRxE^@fQ=p8wu zEr9BjbrfZ_oAoh1gIur58yu^6D=H9w&Q(?1+|K+WodE%Ly5{k;n~7NYk-ezZCfo{H znB#udK75TmHDP(7Ovmi&$lty4RyM5ncRT9%OC-j|3#i45GpN4OXo4vEk(Fa&hxmsF zVpgToiRRsBEL&Ny@ll_2ep*J;W!=u7u$gyp=5m=Z%JdmqQJbv$v?K0CNW2n8iFWgS z!UpK^-0^2Jy9s0>Cr-{bT3F;JJNfbBvB^A5+#RtwLoEb*rm9cXQ)y{8;j3!#J~_a= zX7z(@Z3C>ek4+TKs!Eb(Z(Ud19DHmKekmUncs#?QOGV3MyJdIrb;Vh6_1x5z2-@m5 z3c43l_Zy|;DpE&O#!;}JN=CRj?@6om#XR=j{S=W3JCg^lv#uCeJpuG@E*+)~g?`Kh0`HZ2|YCv(RM22<(*Ok#RL=sp9Gb_Yy!p@pbW~-_AyMX8#=O zWx9PL=q>t4@GwW7R+$*C>JXz7^f4C7O!0M@Xj3#=r?00;T+i!=Q=Hh{08;_}a8!$; zz3r=d4?4qH#}tzBMoGS0q3&4g041aPkz$4ZanC|UfKd#4&t{OSXPZhvVC;5{1N+xt zoLX(rE&yVH&rJ_#{Fn3~3L`pxlItj8z&CpOXT5Bgh&rDC0;_8T#kM?fgAa5r?qn+O z*XavJ5bOzRmVx8~%r)^S#S~hoaCu+(JBQ(>gzo_+g*=W9?%QKz>z$hJ!`BF1T7s|Ka63iV zu%1cfP6#!ElXj!oH8&?PkH9Y|Jzg?D8)@uaXF}xeAO?<+`PB7dW;=@!?~RRYu@AWq zlNS2PY=l%Ed&W0B;D(obrmvMUq!`e;hE%1F)RpJ7-4X;MZx07Vzy7J15?}ry>1h7) zL%RaY{V2EP=VDDq=}H)O&Ui$BryQTZ90Pzima3$^1BJfW5vJI5GJS6xmFSKar|L)IZcY^2^R2 ztl;?W6z73*dIrxaxEU4z zMDhk<^{7$DHe#6*Sh!3)+oGGY>&x7Q@IJVgLIr5{%jY0K`rD(IEl2ltSz)c>kKh*a zDRRG>R#f!lf@$;vr{y6F=RlGi>1khefG68&p!9!5_{F6*Fhr6b-^+HJ&r%;WE)UB>K-8uu2ZUFWl&g)WXR!B~2HXLe*24|~atG6z}03)bk| z?$hlFU-Gqx#v&DfpKQ{uj5Ke)4}B{q)V5Pm$^qm311?6lvB0b08FxxdH|N25&#*pm zBcFA~{LLZ*gZb$N?!IGX`>B2VNoN#^oHW{XTTlI32QGvD(Uf;#dDlFx*4w2@4#u2j$-0|i6>%5vuP_I#A zP=k6-iG9Bk0riXZnuV{bk>vtik`W&uAUhT$_N-h$SgJdIc2+R46=0`vhdE=Ea<{m01Xr%t4S*cXKSy2d;;6lRYr0erj@bsKj)gmqX^89WyFQheMQR$jb@6p)PjSaZ$! zsvi8}+5|L`<#3B5^dR5Ex!%HNTt%x6H+0<(tDiTitIM)^A;NKGFe{2>Wq{Ly?r(0M zU)5YjL`B6R-p%NY$vKV2IW1D~72bqEc2sAE-v9Ul1V&L^KK7$Qli%3fi+!{}{Nl44 zn_O<&em)oXtGmUBg<^wN$_-p%)Ca zV3Cl$lb_&Y=O#UyDMr-sE|bJ;qbdf2aUF9`5P}LfO@1MCxIR)pq!jGy*A z(sWlF1-oRKE~O#zcVC%R)=XiSWX=txKIv zrHSv{>9Ov2sE@cYkj@a`eW4xpmZ$MHzvJUgrIe}p`#4)wO&nzp4jeYpo)Xx=L(pbr z2-P97cheb@L}o{5W4*(k9V=ap76PUD7sauGAJuyjjZfn*U#&0|?^;gLGDiM;hXUZh zSwjOhwW`S<=S_7r<)Gc1cJ^(*)gXZNsAiFZx)QNb{;3RwKGjrlz^>&gZsaQWW@fP` zjNuUzq+;h_gg2Ml0zxsJZyX+=KN|xBPT2x5tBeKf7jONpS}-~%8_DXA*T$L7NSd%9 zlOC6gp5z5w8mNAIt2tpob=ezxDT2bKPT@tu8GlRLMRn_c}Bqql_@rL2OFq zzPERbtwilLYRZ~8hSc5~96mUPDg9Oc>T9c!bAQ#XRakm;-&tH9%Jbunps5d(z%!EJ z$ifCR-c0ke7iR&2WU#93-(Q2t;;wh?M1)w0E(VRs zbKJG1R#8xbaozBDAwR8_X_5fax2R18_w|(I%`cdLYyKPp33{P4aU!t;|Npwzq0auW zc2EvNt8`WJYE{qy9hO#+<$oNe_LQ4N{|=p0HiJWN06e_1jVTQH$yH$s?}Y#Ltg*Pw z*f<^W>xo}CnH?A74$K&FwLYAQc;^lVskTB^TR={oSNP@H0RSqpvSNHB1 z+Yo^$QDVw#p{(37Od>{|{^>#B&*+ccl$6(sN80)9xDwzFB@Axeme&I-)P)c@Ca92D zVNSQI@)i@GX5Jru&|t>-*6qkO$EA8U&jrd0NS%VcA<0mW9uomoS%H__z?5XiIzKu+ zwRrR2Ag~AuHqP`)0>3B59>02xG7t1g2uS1@K(hw{8HOHM5i2yNa>>G}JzK#6qrBjp zn%d+gbYwMy%wqvCFkg*6)5dTb3}6z83vP$4aD{8Qx?5sDwQO)5MznoY7??J{dIDcd(CMrgUkdAfrbfjsR5S<9sK#E!O1Gg0?CFjaWmqh=}B0PP0aM<_r4mY9wpoiP?_l{q*U&IyrF7=&P6)e{856wT1{xyd1ISdP~ z&D7@Z>lr(w_0C*)B3H;oELb|7;Maimi>~klNlgiZw*J}yVq=xVx$ye+Oo0GYkVsDP zl9F_wK$al*Lm_2hBXZ0OEey!2eVNXZ{wB<%>86QU@B?0e8Ztw1v1M+jTq7=;;x#nm ztE&5hbC4zMkm0?izOv^#3Cg)1!6vmTSV0c+{Dsi_sKVRb5vx5vs5z8hC8J31mn7bq z`WEXURiHqq$IU9^K$JDGppV;HPRgTLJ~PV3;q;xUOie8ioC$p~q={ocbPMDAL+^f#V3NTrtYsxfLb6w`G4J@G`( z|HUn7;jxODO7{LrZ4&HZ7;E$E?n_J>*mUd-W`DNcz^ZMq)D<$}=mzf0jy1s3JnQz$ z{}psZm9)dKB@?#u1T&J_=6P+}D{n)#3z~Ncati~_A*XClb<+3sXHe1bXq8s%x}Dob zQnR%&=!va1xiKX%9o1?wXZxgt+{+y?2e;!V>)p-ex+8}8uhee7PdC$T%pI^HB=*wB z(5(StZ_6I$z&kTs>Pce6y z^NnJs#N%oe{CPVqH7C0Ta7dw#ie~XWQjRM&-%Yc_6F&A_%n;gA++DG|%(-j8sNweP zd^=P-hn-?wm*nuCCQ)dKb!W=(yjZn#U%S9l`xK(^^=GDV3IFghDvXa3eEVr)*KLbQ z|Iqk^#jO=mF6}m-&*1`}XoO`OUESvGkUJVuh2IkoDAg3vkC1|^RXt#zJ{i2AGW=JP zK~3*IhMighb-Gl;TX06cx5THy503b0zVXi#pxAC;wJ%vYHwr(T4IiE%g4>`7u=*n( znA5t64>WF0&*jmjMcfsqf=RVg@0mYNP=|s}Aql_s$h3M&-4pa%`9&vj0~RLZChi3l z1q=Z`6RKcP8De|`lO}+%g#k&!zvG@BUuuZSF&M?(WnW{K6+E-T-ma@{bGT{+|D#sU z?e(V=dZty^-_Tv^qH+V5ZJ9*Ev)`J9=Ad$0Ma|X8`&pr~O4V#3Dko}{JcET>Z(EPS zhu+siInoQMFS*XOujN-87x@jQU`tvJ+;6>od|9i+bFu3d9A^ko{`fY()ruCG%3cC*{9=w6w77w46+f0zXI z=g1?;Z^I#?JTC=dXx(37{}kz33TL$NvwR=)?#%$(4V5s$j`<7Y9mRCp7?NLt7amdJ zYTLz*@UxVKN&`+tyMQKRr=2VUY|Npj(s9F}hJbIWprJOO6|?ur5~u;go(u?a`cOUV zN8)!a!wEHXO%?-Q$SBK-W)sAjVbg0Qx`#;E(eNt-w5)Qc1lpbKbMcq+0mvwDzv>UY zlBX?m%tAG-Ei3!S(V`X8uy&ohi>U)W#P?<&G~TFdqx z#y-@Otw}DIxkPpF1y-Tz3Q$9_$a-`p(xG?@a&ln2KWFtmV*HP&;lnL^(;zTEl%!n& zXZ;99XgPYl1?(O`b?|ZX(A9_WN&c}ves*;e`rw((tkmrgFS!(-n#@hRi}|`!oF+rmYz;QLlM0oM{v!bbsS=%pC^JEE1Z}1V z5Luj@S+~{Wqiot7Rj&TI>*(h3aZG{}4bk=wGNR~v`VEc>+?n3KmOq=tGw<~crS$Z8 zx(kkfma+HQH*7KVey2c0{F^$b;h@~{@TeE)(^O*F=~UqZ&v}0(7u?hU7VMC8C#aYm z`h67Le5S~Xzr9UF-`kVu%Byv!3U7KxA#$!#s5;J;L{_j)e-~zQdXn;YFQXyL0-DJa z#o7?2ki1OyEp(Igk#-jm!52Hn>8e^OXvBRp33EpQ>gI4CsO>Zx=^WGX=1uZiJG@v8 z?&7}GN|L{jO#St^WgBsAE0La)a#3b2(ZDGA@e2dOOg1|c^gKnG;Bk~NeY5kZmK&Dn zR-o|M7^ZOEJcq}s2Eh~iEDRj=Z7$EM)H*9~aaW6+es{bnDFVmbh%PJ6HyaL$C}xh9 zXcinUf3L}?kwj}#l`OQI!-Up;89J72dO9L@CjvWaFRiwnR5Odr5FZ{w&)p;u@f?SL z;lu4ERb(bl&Wzc0172F}o0jpfKf zF`Z-y>TU0mYm-@Pm2AKQ){4NxEAoIDP&2`RMow@{?@jm7|bT777yMtYL#l{{8T3ZEZ`j~Y+;7mHL$jK zyM^{kD!&TLep7&I^_U%!lCE$9YY`8h65}-NR>9WZ^l6bWmmEd$D>ll-`}Otxff^Ie z_w~A5cbpY3jV%6@mjCRU8j8`{UvQ7Z=u`Pc$J+uJ5}Vs6KICsF+5Q3d$88;Fk6kjT zzrVU1QjO)GoY@$kXM5u;-lNVK7Pr_X0hW~V&hF7r%IqzIkwGZQ`+;r519FOr^HD~!(AV}jKV#6 z(w4JI-^aJZ6Uo1}uNSFY^~Da9^1+rGBU9QgR=)a3)IaUl3_ zRTVfVWcW~~60!gOss)zkJF8%_s-U&#Qg00By*~5uMEW;#);Q;+`e;;u+v$X4Zxp~H zHk0>aGloQs@zGtR?U71W`!UpMjzFP=5lQG6q5A!NZy=!7ehs-mna(N3%UG&G_9CiLciobraWIa za26fMEd#)~C&z09A^-cIe-F@hOkLL35)$cL1%JK_dHX$xtb~8uwa}t1E#sXNMF5O? z3m_kF8+%svZJjcfcxE;>MjCFcpvg&s;tkgaYG~Kc(4@HIv8a>4PsEwzJ_!CSs-l2k zX-QzQcT$NZVu$`94bCkZllLY%0QkM7MkNLelOflv#}H)0q8Kje3{)VnI$X zQ#4JUlHd84irbn6U0t1bC;GddT0PsAUDh8u@i^hP`h{OJGxyGxvcM+Ppre9a5``(Vt^ZZ2^DnfU7EvoU}(R{Iv6sPay z!W7vx1bb9Seb2jjjE%*QA(`}<@TU$eWXhE#kYM8m7jnuCBXq2n9h%k)g) zqKjvvp9mSpQv&XOTU2CeQPmC>V0~+ue$+km>hLddS0GfBQ!PH<^a79|GE*5OV$z}I zS`2f3?akv(FJCNgiuL2bofo|Nl`T%JG1@F70-p`WUT=vgwz-GJ^6^oROu(CjZmeQs zOw_HoY-#}L{27OB)s@Q|3m8FYd?JbtjIkl_?YQj-e1iRq zzViVGac#qGlfx^ga@S)cFTbbze*l^tT$zl_kbpr>Px@y*)mFOaip@3O8_Nu&vBd^B#3Xq**0su`9^RvQdWbLBnB2DGDKXwc5#dW1WORT` zrk&C&1xM!fyk_xx#6`5<1aJK6*3?`B|J(Q?+5G4wJsYtT2VU(zLC^ET5a!QS>4hSI z^F8{g*CsOz(60|=95+4|O^OB;a!%+Oo-(ntrXPY`k`67L)Q!%(7_R5Qw+R=)I29r= z{NRT(l6ndqK$ZY%3N0CGE2B{r#~8^Vsr;*U1kS*J3>MXzC=xqUO4*dl@uZ$}#%{a- zk?d!!Lm~}u?k6rRzh3HJ4zSHY62`;T-liUx&v~A}eq>!9GzrL@@E+KU>->X!w_4(; z@3>bgSa|Jxz<4eQ#_1B_p`y?9S(o_oV^uD2Pv5M+G$6LIJ+Pfs%5@TaJ5049in9&) z4_)158vGmyqGw=W`N0IZ;x;)bzEpvGtAzaGj_2P7UoQe)XB*?mIu46TVm`cp4jLn0`kkrt^skLpW6e_V{A(7YoGZTCe|N8n#l1}^gv~$LM?5LxPvhO9S=V| zm0=6laI{$_HXNPN^7E&5Fb+ASa`^eDQqy?Rcg-T-bOTSi-ePoQ zxYZTN=vdx37-@}DF>#~?zBWf043ICZSS_Vl95TaZp{*%9v7M(r84VraU=?BhtKcsq zQGj{)UopkvJq%_2qEe;NXzmK?_~j9TcX4%tG;@|$)!C_637^$C`xQg_)>`qT1%^Py zBRP;RJ4Zl9R>r<`zF99;o^`BAY0cj0)|Oe7^QSz~58wmCFPbCn7FnJf4IJARbb?2y zkbtbncn{>b9NqIyeahl094Y>p;;57J2UYgypUJsy`UcQ?_=uhq_b&+w3JS_EnlOW? z7wOGTW497gaA(Ov7Woef!JlvSZjTTaS42|s%ebUp(EdD7`NFu0oF^`|ccls=;{?%CYF+1=DMaATr&+hAK2DIcim)YqXq5dOVKz`F3BsBF7@av4joqO(E zY1FFQ=FJ13iurcvlJMCdR-7a8u0f1OHU(xDmZ+vCAyp&4v+h;ZcnV=nsD&ACnr33& zNH{ii&7F!$V`-k|WdFb@BKxM2Wmy?}X^^2=|KRP{Javj6MNJxdJH`JGS#JRqSIjl+ z4pOAJL-FEHu@?8@PLU#m)8g({O7Q}vxND)si|gR7#ogUq24?=l`+nd3@4ELaR?l>1 zpG+p%Np^OgolLVO2CcCb4$YKuRhYB#ZUApAaFnsyW5Q;n{90ghWJN)DRU+M=mAi?wjUCHeAK$ z13DfHE*TfOQsk~~o3~N*RDvk&psW#)dKl&T025fN3QDq*s136+`PmM$6e1``OAM?bqkj!#t*XlfQ#!#=}3i|XcOS{y%k_kyu4&ofDakU0I5oD zXKQL}cYg_n@QOReU#d86A|^j zp=W20ZfIzDWp0whuD`)ky;)2-irEin1u3r;CKVNxKsEr9Iu~$2j9a{_{`v=DAekk) zLy_y(+l`g7`vDBtlCqKGIv21%0k;kTQ?&I)$ob&fHJ}#>f8=Dn(Jd`|QU;?F2uboT zZ=`pR`+i^9ZO`-Z5N$K;`6B^S_u?|Bf$ey*O4!QVocD=Ec}v}Zglt7Y1Flx;kH3G- z((49xik?$H4YLdRcnKTYjNQ6%fL*Zl)Lb1Cl#ohsl~Dm>q1#FTkRC89y-6fX9Kb6* z|93#dE8r|O$trn)vsPe>Q{{VG0W_|t<>o-ke{0esH%QEI5U`40Nd4Ekz#t%K8o7Z{ zSL<;|@g!aqDib%$JNzNt&f~%-)Omp^n1@6;7*xgvliZ=!W9lWafOT-3!#TiEo|#pI z^0le6YHb~D?$4iIHhaQfnnb|I34?@A+nW_3%VoUw8`ON~jQ^?7$mAl3k^gTXaK;pfL69~t9tt{IYW#V;$bmCdEg<=w zpQhH?^aGB9!}E#O1HQ~^ia^^pBE?n8UK1$TGRjkPB2PbYBH!FhgdF;^1LkZ;&F7@u zRlm7i+w?Juf^1D#`5zuv+D%Lno>3>U%^FS1;?iREKSVAJQsvrH){K<^Z#WA~Ulz4B zfo2SR24bJiy(B9l@;_vab0;sm?eKvB)pqD6hK%x!j-0kKg}U(%-B>g#b0X!uiL8w0 zFV|bI!V4r~Bu3q^3&3P-gxAuFEUN2kbadEeRqMA2_g|FKi!2I!hF(uQdLAl+3X!?s zpe9YQN|3D!e-F49SUz4=-Y}0XS>$BO8QoaTK51`Whud|9)+2U zZQEtWyWI>?Q|&3TiY9xb(+?=ny+x)ZFwZ3mSM~A1ht>ULgOA`}&vQL-+mGJ*ED(#G z$$B+*!Fhc`k{xsQex~cGipcwh4EMHB0lnzq<|=ZA%=%cK2?^UJ_=arOKj^7J6TAC? zji4tr^bjBDLut9+A&SFkhNN}*>(Vd&9ZWz`a0%_+$XyiRUUcJLoDVdnC}_zy-$?vi zab)Gltzc}QHnczI;`lso{n&u0dm{ZE`AQLS$;`-PsT6L|c4N6zg;U;wwEFQnHvHSa z(;g5t9!B8hZdG&ftZUFS0(;VYD&})jng!k3%?>O#4I<_;KKe&Cn`1@9>~i7^XzDee zcLyAe7{H9T028NFuPS)DMA!ASb^0sBVzRDk?EP#ua=fI>Xk+3tgZ-~gu>Rshoq{)` z`o-1&Ui^S2H18>0U@Y0{%3cwgmlH8Uks)B|G?Fm!k#?t2iic8 zMSp+434mX7z7Zibg8dBs+w=NfL^!u`d-?dw6!I1AHt+cv08ldZo{SlsdytJNesqOR*?r>7mGzJV+cNeZm+?| z00k`HJ2o9LtTubz8S`~|xigK-R@x2dsXjk0ZEhe=_kO-km_8v-VZp?Ym(+u_fhq@s zS`5okXfZj3#eQiSZEJLu;%5 z`PIdH*Fxcpu%e_$7lK#cL+06;IXEcn2}QO`z5%LQo6K+E=g=@ZfJ zt9ksJWS!6Cg+7)gf9I6&_I}~AD3XQc7DeV5^AziQ82^rE@q)WTwStPE%i%93cU?eS z$$Pqax380*=tV?ox3)8Y$sq~#ss!tx%3#eZxmcZY$?<{17XT#r&jpdyM!F);vono3 zyC^NEpJRIXphk#xxcyfU=*2#x`$NYT9aoJ>a`OJ-pIYWRC|sqR!%@q*NTAj>h3nY| z-SuzN>AjC8YW9;-_a7g>Cb)02)LZ6j>DY7!T%f6ckNqz|9T~}Aen?Wdp~Jc4YnYJE z8s5ej9RE*~XAGQ2j%3pUw&I!ij*tTPQ6N=P8Ww{W$c_>D-Ta!Ix{k<@9BmE!^^Qvv3lLv8TmO z@8Jh%NH42B$0_I)5taH#%>U#@(Wn?@@2%8B<7GlpT0a+G{Ll2UJx8WF`X-2#aY4Uc z9=o{9QBBu%fYJl7V5%e>8pt9g9UNYSwJb(Kb4&^=JiDDFP{6Si_4fWGk1N=Ce|NWM zx8nI?q!A9R$;P*L0}K3-_W4}$>h^X5Tu(sUs=)NsbCZ6)rl@N%GXA$%A|nSsNVop# z(D`4o9Jt?$<~&2)|9d5tptxf`v*iD|6!R7QUDG8HhsSMCs11cU`Q4`lzM$Za+s4?| zmudcd=E(tuh=Lg7(7hC^4Ne@gidGl~5UYA#0e_XuYf6_HH9j)57l~U0e#yNXyIu%r zsZsXBeVdt0*}t3Px9mQ*IJIdxKptK;j$kQld|)pn^VN)&he>*i@-s#8Wuqx7 zQuM6?a3U%0Vhlji#$lb2gyI8^Jj-K&2y!eR3#1I-AXTK#yKf9LHk_b7Pap9N(s}^i zaq#al`qxHix&!}=ZgV?8pB5MMrB1!AkC>WXlsWig&u_(QcTuNnG=Gy`zFHS)tG)?` zcHn;Ce1_Lmr)15PssV&f2EdA+S$cq46nJwtfy_?E%01s zHAh690Nsx7#3w%XL>EBr^CZe)ok}<#K9HA;;wYfBzR><@8Fk$$8+bF~V*E_wN@qTU z(E!lj)cPL^+L&_J4~(U;oyToY+Dw3Qd3E^_0Bh-MV!QELdvF&k;2x`|A+cdH!D&-L#G=EmOgG&%vKNqtfLn-KdXKD@n~(N`PR$!laLO-stu$(u_#(5Wx3=8-qKZ~ z@LLVK&tiBK6VeOq6T@S7(Fm7P?|hDZMchhy?zSwf&-Z%Zt^>}2zmFj@pBlCuVB)am z(3MsA4eBX5|ykCrDikp`Id0j5e z{_2n6t3X~V3c>Wy-Y%reg*K7LLpq8FJ0#Ztir13v(~eF@vLGM~AQ#+{6q$p1zAmlk zUJcM&wl#f)DDo;nodO1z!b- zZLdjjQ3}R(4!l4Bxw-)Vv5Q|NDL+K3DR)q3>-8igf>Krd*eVBpYs$B^b&h=p`yyU{ zTL9>OJ;xjQccV~1fxDec_}7`v$-7VvgO}~quwaD``1J{iXSwxRS9v0BSO*f&O4d=M z8>a=8-)+xy{Y72qZZ<=&xZcFWu=JVC56jC{4#V!FI1aa0t$6K>_t!T@GRBs_x{&Vx z?d`mqWRSTxMf6R5Mq|6~1p#8PnGZV=p+q+Pwt{_PS;709xaE;#ZMGh(`fZ^So6z33 z(!klaOwdT4_^DmQr7KOTJThZ1Z43mlJ(o#^AJa);AT$2@Hc*Ll%^Cb&>EinrJ~~1Qkzl~L(p5LL@In=6iyMWOW^RuduK~So>Uk=8e^0=U9=C+5&H07FLDfxP zkPE=>D>=Uuwl%8EB};7IcmN>@D(RH9x;?c(ghC0QxB;U@IKUn&xO#qR@bCI*ml~Iw zg)|}q^l0~Di4d*LLd%W2++(}8HPru0CpQdTcXf43xo3PLr|OUA*9giJ4^B$@=)Eyk4{3ub z+6-^nFY$qz<=tHqS&iDz+DZOoL0n~B zxsBNW2Q&s`5)Q#Ij*sSgF##vsF)QHFb_N{UznWeEue%R4m3ZDuq+0EuDPaj#o|&&N zx2Y)_4J2(Fk=Vg#F64)=YJUIY-YVc3>AT2$jyxgc;vn#>{XA5_ir%GZU%i6B!_K

    Us+|b@&*bUX0_OZrt8_nuwXuNUFVL{k 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 XKUa!TG?^gj00000NkvXXu0mjfNH`CO literal 192019 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

    fv>m)R#hM7k#UGu%~~E?FDkJ4`0+; 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 z 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 N$cXxLgoCFCFEV#Q27Mz(S-|p7# z)=KT4t^Lt`tGfD}KHcZu)Av4acg&}ca+qjjXaE2JQ$b$(^J^RYZ$m|X-4BYHj=wgA zei}L+(w6S#ZniESw$4rffKPVBWCPj&7YX9#d*9e1Lz(7QC*5Khq2{_zv=99Kd?CA| z+bhBZ9%{Sa$$NJcvpe0z3n~2`@>2{kK9#o#GZR_=k=pvCVES{7?ZcMN_(bL#G^Ejo zr1!`y#atYgOs6I7jH0v48^2{?)Z9qP*|2jmW(?n#aH*z>g@96_726r;M_aU%hegd8 zCx;oVo&dOHdg-GsR^?Ox;4MHwT2jL&`z*&dKx6&^wsG+5yYly+xnCo~8Q3HxLxSJh z01)6LaTN%?nQU6xHTyf~oDJ(bFYs4gV_fLtu%qY1MxU zl4vnt5kjAC0%FKpwCBn2hh$HQPF-goh#b7PKF3{JTJqRhjkr?UkRT4y^&stg|AhlV zaCF8Ja3I);u}LA92A92a$P?^NVTkPVrDz=R%Qbp#PUGmM-lQLXW-0u7e^R(Az)(<> zAb4UznTMB`oVkpb%XwYoXzzFcgd*+b<;6SfEjunkPGM*xE^TL5IWaLo4+N%B3VVIc z$WYMI(khD6`>bVO+g&lxvsYSLnv{|v{dzPF_nA2V8;ZP&isk4RN=(J8!ivW3+U}Zz zo{>Fv>Q0e95IUJGTt-I5>7RzM;$nKQ(?610T12|Ky1V=P0B6;aURQ<{k!8*kWC%8Lz0WKE7Oz({w^>x1|1 zZu=SGd}-PK%dg~|9LMv+t0^CzA1lYOMc1PdaYw4pUmYj9U1cE^+J+@Lj?kau&f|fH zSq~Gr;){IjyiJ4Ze;oya|05u1kFD~i=q-5e5e}ZpSh(uqP>q0Q=yb*T;8)kd_Z$^y zAqwzj$wPVgEr!VbZt?`^FsO%a+_??qf@N9wG%h~g;Tm-drcHn7rK+I;yh6W95q8R> zbZbq>pLV=S=cf~H3mTqPeKGPV#%*2!bjRLW!38G1)NPAvHhTS-NqAdOpD(fM`gA%S zA4A##Mud(0UGaUa*occsQ$789o^LNHPtJ7-IdK?SHB9{}>VJK7U@sU%pZMh5GXqK6 z-e|T$kE80X`7n0Q6D+XplE8*`aaW|@hPpof7%EAOwLMmmJf){Sow9+ql4YBb4D!;R zwgfm19i}b*iR5Ggd&` z#Z`&CkQX0^e*44Dj~>eH_ZO`0zBDR1a@ql1fZAjXWdU5yb~rEz~V-jZ-%J#tF13_8Q6Dx85+yy}0X2U<;!Eb2w4f3-p9A->MgCrE$AisooIj0#B zE?R?}AMZ5k=H}*Lwwx{xRrV7C$%u%=2~;sDNtI;p-XuHGj?fCPp=0=n>4#^)rN};S zw`$8@h&S;h)EHi@wld&-hR~16NlW9Zr_v|^eANo5kXI| zm0V~P6-$)M$iG4G^PAdQlTb6W7!b*p8m_Vm^@q7*@buGCOO732Vf6Rz2P8G=)a+C;*hlQ~>v-Xm+qqIJGgM4(NsWj@b75x0dD3G2*6QITgf0a{(>YQjZUUcb^% zmDHmdI`6G|JlEZ~ZYMGriD?4nZ^nfIABF>*qn>@w(2=u9`+gHsr&YWp={#=l@Vq2_ z^Dzb>F?eNCT?eY3rOjPj8SU_w-u6`qsvHX>RxS|~_3tlu=-0FVAtE8MaqkorFdVhw zBXcB*LuwmU(e&hpr>syat_6}v%9-DcpFGBMu8iDI*q6U)X;i8fRGI7tRn@5llmby*L7O~{m<4CV=159$i-Gv2?T^7FQ@+9`9td$@99}u zw*qD%tw>@uUcqzpQWCDZNVj7ww+B@HHFh3}iNhOH@n1e_CLm}oUfPho{p6Xz5|vCA zHM>yUjTHu9VLhEgjI19ka$k%IxJsn7+(Zf!$~;bazWu#z^}L9I;pDB$u6NSn4LonV zJ6-xok|3m)eA@|NNxpg(Z?g}paD@k}Lz=OUsynDcWZcga3O^=&= zQbS9d?rXliO=e{2BIc-Og+Pk?6Fbo9NdAK$O{fH_pRr*2&K52zy{SK#j?2?VPA!{= zpGCgpy?BOpTUYgLC+ky;6q?d0!9CN0|7zR-p73kxF&Ft>etik-n8c_g!~k%SP6`;J z*=2KxWX9fb7a;gP5Tt%r+jGgc7ve~aluK@(?>yH|6@uT=H;VE?N&7;k(9Po7Wq1Qw zNYIXu0_WW}G2CH{nw<>|7y0ot7gv(PlGb`w47I9WQrkA1&&W9SuHerS5Jafv_kU~H zi8|S>Io%NTI@VPe&KbpE`S4Lv#zacbd-54>fA*}T_?R`j*U%Ex#qRSsm{4ud1^+>l z;i2-aG}E&os)N$TaJ~ohX6(88L-*59{mFZEDqj+J;nBBc6iCIlN`=#M4-L39Lo(rC zlakz);mrfPLx>&UAO{*Y>!o2gsJk(^$U&?=|xWsmEj7%>Ecr^x<4*U ze}+GxRkqi6Ck=K5<)`g$KVRcj5TI3^dVLWlTv)xnF0)mQ5ZxKs#SnrI8(*8eH%3OI z_#_BEqYF_V0SMpjB_$<=zDU#f-=4zR+@FdbB%ptOV&Knqj-3lqsD7}s*Y65}130M+ z@63GiBHI^jJ@tlPB zH@g)*Iu4aafHr&p&p#|noG`Q1&)Iv%=sp9(hcBnHl8iv6--gdbgMfhMQ%dKb^_5Y7 z4NQd`?F+JC+7#rS8Bc|Dc9OCcOb>&Pn~5v28J<&+`r+YkE?W@>Vmm_F_#8An1N|*Q zLY&mq$nDn$SM*>$#?ia$66a!eQ&ViZn)Sjj zR40!E@NooTy&Y~Di1zif$)}XZUc-Dly+ANlWo3aaOJ-?7D-Jm-&9nz*4K%x$1GEXT zj>IBE`<0%O+f=2zb69|Yp%On5y_+?;^8RtnNGl?$VcgszoDt6GR~GN3HR&p}OMvf@ z;rGbWQd5wqYy4A{S^3LR7tuqT@LR(OMGWJoHKA5rp56*IeqI3NrjEEQ_A%=gW)vE%e+YiEoQ1v`*n&L7r}}j%^3=VNj`o3b*;^ zPJVXw$-qC%DoQV#XBn!kKa9Oz_Ap4$rc!@=lPzwseXo*GnE|)zJ)_JGQgF9?XbpmV zohB#FX4$+Zld>-Y7?*^jAZgr_Vqyk@or~)htslskskl(dYPmB$j4K|YXfp6Hb|$n8UK# z8SKwm&*=4iLm6R5CV~3tJxr=IDqklr=Y0_>f%$6f$~ara<@CV6zj(yL`q3MM_by>sF(! zSMDb7wbw70)Wm6??jp@wTx_fi&3=$eKNhM~n3UVE^?s0mF!ev3`v*!UI~B0Mfa`E~ zsaY$v&DN+5>$K|uImu4c$C2@$(=ZKXW|2CPX+H5Qq!zWVE%k|?^HWg~;(J_X%TSYK za|Bw&4D(&5=lPbh))DLgpZ;WKjT6wNB>Lep>N%ES9H$TDA6VDR_}sx|OIg9uP@QW)8A>w6`ntZGXLxeNIIRdi&mGBIbCy zps}>JJE5s5YY*vT7TPU~Xl+c^o#_74`c3;C?6wyDLiPnU1Q7!np>TbY)#yc$OQ6GF zrS60!y!x7eF)VZ@-vq}K)1DF-w`||S= zz3)t|V^yt+WZJc3?dAu`DDQ9On}a;O+Y9vo_j!#VSaK#`d)9gMo68^F{wvVga~0mv zj<$^?#yT|Z=Dqn?TS>o614FbKB`OO89g--|^50u5l;OCqZ*^H?@d#oM1Uj*&^ynk+ zCSG^4#h^G>X>1E+Hu_1&_oA!Yp{TK;rqVL)6-5 zRNHqZR?AH_m!QCLlC_8=;pa&QZXwC3gl2zzrcB$n8fcLsY~mNd3Y3v#r2Adsmfwh{ad$cJ0k%j4Lci<_KKx zK{pdqLmM+{H829Drj{JP23Q%MwfgX`10%#f>h+X3%#5Pligr4+b7be^P*bwq%IjJIh$p!NCJ zJaYfL*tY^g;ieyRB9PJ3;z>fmKZjZgjd|?0!(Y%hV1i3&)~<@E2aC&fwYo_!1(3^s zNu}&`YNj1l#cCI=ax&cbursoMlj?UBA9S&4BuGRdUp_B?;VRrlx~T&9;R8(#{CRB5 z!SN*>Dj%6H_+Iq4^L^^UH&FKm6H;dxXSgEKv$g4M0Hi_dr4UGdnDxeCc{^~+|2)e` zk^n>1l_|Uh%qdnIE>E++q|yAvFUe| z3FRyzE?!5nzU7Rg_t3-0H?Y-wX_k>1rFZqa1+M1qMDYsAfyKEZo=oXvbkYoz1TMKUrxkyOk^|KS2P$O{H18YQ*jR=K3Y?|<7wq&rP`}tY9pt9GHY?0 zm$`vhhcrfyDM>L`%F?h4l;_Q3xWVk4Y z{P2WJLL$*p)G9Vs=YH3TDBcuvtY`fJXu`$h!`^QufQyGGrD@4<&y{NzC_XN zGV}BzS`_C&_lA+K^@rQ9QI38vLQ2_`1Tv$7eWb!E<@juLtGlJ<}aGr9~-R zzLn!~+hIIJ2{#1r($P%NCbL3Q7?l(^8z9H$cTO@%Uore|X32xS0~fJ79}lQf)1mGYN+zHl;rUs2PdCzR823WY}^QK zu$k&7OZGMdFPYVnch1+LBVM%WOwTaam6vvwBA2a%E!hCzkcTCFTyRPsr~cMZo7`1k znCwqv{5Io!x3pbo937`bi-aIW;I-npD%1_0l^4K?*d3!OxL3&-jKws@wP+}$`SJCE zfLf$)StO#MUy?pb`}&7uf=k?H8*$!L>7+Q%3>&I~Rt(RHAivAWW)hm}%E@;ZnSILb z?zhA*UHvIK@)%*=JTA8Nhf4P((fC|2Jf^%S9@xDF!&a$;NbI+RxJI2k$W{@xNoDZR zwdpY&t3s*XIu+GmRaT;F&l`sdoE?-FGR!-!t^oOyI4N|c(*TFr`_jdq;lD>))j0#5 zg&n z&nzOS1{c@llBiDh(UW6VU4a(|(m+CvpH1YTVm6WRA&Z;>IC-^kT=4`@79o@8v0%=} zAnN+GG)^yW5Z8nXoLr9$eo;XpA(1}Y&>J6q%GQsWiC;qp{S&w6MB8)bR|&;3s;^7k zWY9#`s!)WT1JbK4P$E9^;`_#^b+RUOcoG?2Dh-le#5!8d(>NrTFx~{lC zaFB?d=k>9FM~wAyw3M?PA6skSY%_fc2CB{F{sn+Q*EMk`J$>ho9}qA?V;_A@5aFX% z9MQ2ZiA zmLk^PzBwORMQyF={a4B7_ID_0vog(dB|WPgi#1F6H@qY|BGZG%cri;lV_9;D`*Z5NjBpi8T~MY zhI;vwc+fm3;Y{K359a)1TY(_xo*~%+!Mc6mhH6>xf(v7lxA?(3Q}Ec2X+U8yM`_op z=J8vYNw5(SkhB4L;d{16CW&F;R3Gbh|;ImpCa&uiy&wYtHaL85!ELxJ`sa{g~n4}ysg?ei{v*nv==MR=v2 zU^gXld^qqn3{1FAij=;k!)?&p!BN#|FST};3!;YaFOoWE29f))>^*$J>pl>cngP@E z@bI`j(+Fvd75>bO;?mqOu+orK(eLUtR7HN-9Ak9{th);pK|DIXBNSbzxyj1PV%7W3 zS867th}r(8Z=2lV9x1QPWTvMP>hOvv{&uo*XE9AZ`o$B04X_i|8PtcWz_MF9C%)zJ zyI8@A+46iWm6iN>eqV0bYYT*LIE5%}F-%0Ih2Mw5FS)L{VE?+xInw zE2MwECGQwD?FeUl|Gp1pxCgJcUrs;e1=g09lu$l0+zabNYsmUa$YIUC@{+CG*CV7o zWk#O!x=ReR#K~zJ-=C&|*BPRqT3bD<73#)mHIlBa7{{V(Et1-fy~pB;+0vZ9kKV1% z`uxGcql>>-MEnS3P`RIOS8N?mZqBDl+8zUzZ}SiPF#`oC)wxj-u*DweDLXv<^i3Xj zmQSwGz7(L!tO|H@c(3^%WQZc%Vaymkv=KYT!r^&zy<@2)e?ambqimbPdcUSZ(c!F8 zHC5)wiMA%2sLR{vexfb%G6xx65(pLS`JC|O%ifO}gT300Hl#KSL|oNUZ$08As(;RS z02?nS=;&xe{~S%Gr>m`~0cWV72`6pWH|k(we9k9eXmU@cGhXyMgZ{BS_h;Jv3?7;EL@U^~{?Q&u4} zn4uLo%OmV;9$6}=^PzzgG}ael;5)zDM11h#WzNJ*)JoRxA z5SpvAxD^QI)Z5qd zh`f1K-ktMT?bR6NSKwzpe-Z0<1&R@>V1t!t@M9}bQ25mIFUb4hUBdlTmv_Hz)ql3C zuOpk9tUV(kAUiXr{;!IKGt&R0SR4m%)|Ziaes{ModR!DV2*081y9OpgZXUfOpI0ma zY2eNg2i|$nFXP^@$8ZH8uKBlwYL^4Zh_}xt!OaH;Tr1>HWS4O(Ml}84qNPmpfsKVs zDZO&gDWUt}LNPQa;2FBe<5tmnoviXER4Q3{=~}lgvtsMF;LX{!ClF+ zQ3RlpjV8d$->*!`)Z~m?Br__;S$rmXBfn4e&cg_}IeC*%y&hK<@wk{Crt3RunPUX| z@*VUauCyy-duvwvwdGW~+)k_j0@X$;SA^hF(5Hj8P&DlBvp1Wb!U^{~`_B>R`k?qN z(!s2wDh}vHtN~ zAxDT~T|dG4Pd(geTcp4?j1im;Ir}PJ=N{G{5S0rwk)Zxa@?W|Bm-(o*6s0q#xP3dLPp!4AB_UJ9%`R5FXhq;tR<`)7a78N6v0*lEsMY% zY!URo5Sxd*nMt(##({MQ*kcGWhEVeMujmaUz14VFW=Owv0=TiT8yEI%ARyAfWPC{k5=B(By?Obou8ILX~7O-~FrsZbKTLaF(Ke{X(>r z8-vATY#w0)8{N)gU(Hs&_paEuNBtW3AISE#uKbu-M*wg}h?# zKyMdGOycj_uDef$3HRbv)w}8HraL{!LN!oIc9<7=UwX@lH4@Tbv>IL3nQ>m#QTiA8 zM--c!1uXRi$3uKPWc@VvI{*N$^xwAtcZ{RJoejGFW^Cm7(NGyxD=!}*znkU1i%2Mg z>9~UmjsqZ_S?)cBN0h@Ht=CM#NFSouk~Y~=CA#IQP!6PFe_?N< zVr%hsT8IsA5C|qwj4bCpXGr`auN75NWC#P+n(qAklZ!TWdXGFe^1Q}o77iI{e|o`-{wg@=zY$?iM$0y&mk(QCOxN^wL8C~4c#^9^=ka%^j<%l3dkvnL zs#`Ot6`Gu@)5ooXjxu_B%QP}y zZvvw8n7nN1BlUC{T9Bc+N9Kq2_4wTAeKlt@p-prx9q&;*RD%?pfgO+8h;B_X?Z->>FPxU&OPaQ`2x&DQkl?<_c zHy*T1cq41ceu_adQr(qJ_3~t|x{`J1$veYVecYS&4(;+%W@Nurk?$h@j^;r!G785L zYR83L%0i1k@&4*P7(y~oN1lIC7_+%nhT*}pr@9jb znm`3Ovd!&5CI```uL+{|l|&odDPEYhYYf`sNpz?Kd=dFX9F7SRt$E&O#xH$PI8&9& z`3)0cy($DY4gWFriHa{!NngTg}s=#r&7(48QZr9{kE*jbFpKN3E4l+ z+PMF5;}}2^!3r{YI*cQ`%p<0X;C~z2j{d|&YjoUG!w5_GsQw{H;3noq3$(fXZg~m# zw(w4@XbG)cno%bHiqlYiUiV7;rSSq~1Zh>oav-U}wY39$OxU|ilxF=9d1+3JB21~l zILfszoe|`)xc*vb(*76FHU08@;b9b#FbH3AFa?fTK$%qHIfEtWQ~XI5V|>@#n7Pd@ z>f^H~E3(q-JOaLol#6+MvjhfGR7HH?J;D31{NK$c((`;^tvRJK27@tU0d~w7*ttsww4dR60f%P#C|(( zYg~-_&Svkep$~=lE7e1WdTG?%t+2x4IFE|nVTiz*uf!c;_oF={gGFYcr~i`W^H6Hr zIAk_JhgjSFIW*4xPi6mqu-WOV;>;?-oY1qbXeuwNZ<$cZ-W9=-B0JZGB(vEgpVwj; zvD|Am&R_aBKgMB^1YMI;lNxooRoxMHGkQX`jA8bK3jN=m zW60h|%d5cnHXKRLv|31%Y<07CaQwISXVgR;^M$$f%+y3JN!SSmDRPZ{mziM-b#=X# zm3ae^i_ieYULw)H!uPZ8ujI2fAsVaEnd4RM;&SbVs;d!h-AytUID_1t;a&VSIK1ar zkUb2XfTBDjm+^e~FArtmqR#{y2K=cTuwq8c^HO0mDG?sXdMm8ie|Ez4{H(3`XVn0q zqi>6u-q&14?KG*IBotC&q7hTdN{@C$6w`3Mwyc>&)h(p8zUV12MzhDY(~0bnmJKtC z83a;%bOra7Tq@|nX%*Is`>p2kVR`V_shjun2hyWQ?01zhJ{JOhjCZEsCF(ReOSc+z z?&##dpwF2xkEiMb2jahgv!!ku;Ff!uhDHHKjZ~RCWqW*ZrCqRiC*LQ{XE+Wys@&)k z!B1MVRu7|WJ{hcWiR-)66wDZmthP{meEU>WyPZ9vvP;e?B(I>5bLou3X@ zeVc#i-APQlCo=z=OX+rz>e%LnSvy)WF(Q>&`8cdi%&-g@MqZS~09S;*q9?u;(>4OB zP*MEtGyO(BYae zuBK)NoJ@d#+!8`b|Du-%?W=NBCKFL0oh!F(Ni*F@f>64l07bSH&LWm;tCFT=NX1f44$b0(HR{Qc%_wFBJ6bbG`5z>-{%B5IL#;x9-jcy|1F0js|p zk$u$rra#G71$UWkclbS{!Y9Zsa0VsbkO%Gg?ova5$9}gr5ubjB!q_HqH>8iEC_3Z$ z=&I%H47M9ASqXx>M$5oiOn*t!-u0uSoE%f@7{ipqHtA%(;t)>AvvLOfUD1xD^^eXFl&?t z{FLg}iF0qi&D?|O60Oy*?8U-o(A^1KaeN25>RC{H5VubyxU|xTy~=q_B9Bgv?5FXo z*z#y5Ua@qp_gqlZ<{^4L*Ep3b{4U=3xi9?E4j9Jct`Qrv>GHk1H7M-I&|u%O9ak39 zCLB&KV%nL|Gz-$$AeQ_$YTM@M(_Pj zzEQiekHZq$-udMbM2t_&FoB3-1CkXX*YLA$WlHDw55 zx<}D#AT#-#kX#oLauPAx!N(#1ZmeW^gir^Wbv+(eS-zqQI@4}`U#>TIFwFq*lScL| zZfyCq^R={*D!N$yp+tR}I&y0l;wnzy~hkhcdh^Ps> zoWEqN=P1tMa=t8MXCtG%IyDCFll+b4<>k2G?ztZ$qYJT|)+&BZO*delY!@e2;tr?P zlGyy*1qt9IO$H*U4uR@ma&?US)WTRT zFR%5c>mt;8CHTEpGi8#qWvXcm3=FSx`%Dk2f@@>kys6G^l`Dv?FjVvTfwTxoXmiA{ zBWe3NFh1*oEVV_C?%{PTYb8b9%KoL0Q=1^E`A}YuWnlr4+$GZBO9J21v5Daj@Xek< zO3M{#`fZB!4KN1>UV(bKR>3NVk0ZE`0WnQ4Ui$X)D^0h|H1j+yHveFssD;gDsf&g#T4lhDcryZcpr zf$fRt;9j5XyDbpm#!COjn_u87I+f_o0w&;lTg?5G9@E?PWl^U!P)9#rL+T z(Tn4Ka|361eU_nn$r{-~(FqP}DPQ0BP|K2=OZOShITgK>d{DGWo#FO^>5&)0$;pYh z=zQc+<;K-gX9A*rbvbHj1qzd3%J}gh8Zi>`wD4H}bC}RKqWiTU1PhMqlNL>Hi|Z6q zWOA#)96l54QOnDEuk+2T`PP}1G^!;b$LEO zlv{MPQ-hAh=kJJQe;z-zNX_V()G(8UufRoqd}OW031y-OkrcX`T@ZYA;cLT5EZue$ z)-4#l@Vxt0Jlgp%U_tA>iuwG0MkPY&>U4yf86BI3Ti4nK@OjQ{NOfn!3P~|X=wn&( z2FmH)UYy|sHHN!-pBlJQl$-2P$FyNsDmz$v*7T(K0hL*>`;O`3TG)#2q~TWbPa$U( z?c%=K9>4nQk*J@FUY`#6cwOz^+#Z_vVMm~cNmNN`t_r?je9}S3iV7nSL-W1q)^j?m z;$dBqF5#mI>BmJ2d_l@%MpKigA}>`>7s909rRL}}G=^bI(`F^f@`|lb%0ZzN*)HfH z6*qJ5{vG490ukEqp^fS*IZ5M-&3i`p`i5oq+*XbmZgA3 zoW-`z<(ew=+V)befL}nimV?LN@Fgfr0!_QSFO(!(YF)x^T<$E|Cvj38Rg@hv@}q}x~8ghNf*FKMAizu3ef z{#y?gU8%$qbm(2B|F(FytOtdgR7FEeBiZ$c zOWummGG~VUz}JZ-Tzc-CM6pWE>lZQH{**dK_{&cK&jsf;G`7{mAyNv<|Lv0fF3p{9y82p_V*b= zf`^xK+)U*kfrJ~{v*uq1P~NXil~}HLDwQO zoy1KeUs3^=pAQ&gZpb46hm?Rp{H?Nqdvb(xyA41)_M1X?T=<9 z?~^}WXLzFA;ymmul|zc}jH}*J!|T?w_t{z>N-Hd!6(1i@0gA>-ZM13Jr%|2N{K3#kjPnBuP=KLimS^jqvS=}KTpS1^#?^?u66 U+#JX2zcv5`nUB)7QYNAQ3FXmCZ2$lO diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..daa00357f1 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1931,7 +1931,6 @@ #include "code\modules\mob\living\simple_animal\hostile\bear.dm" #include "code\modules\mob\living\simple_animal\hostile\bees.dm" #include "code\modules\mob\living\simple_animal\hostile\carp.dm" -#include "code\modules\mob\living\simple_animal\hostile\creature.dm" #include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" @@ -1944,6 +1943,7 @@ #include "code\modules\mob\living\simple_animal\hostile\mimic.dm" #include "code\modules\mob\living\simple_animal\hostile\mushroom.dm" #include "code\modules\mob\living\simple_animal\hostile\nanotrasen.dm" +#include "code\modules\mob\living\simple_animal\hostile\netherworld.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" #include "code\modules\mob\living\simple_animal\hostile\russian.dm" #include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" From cde0266c992eae2da24f2e35961e42f51332177a Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Sat, 16 Dec 2017 12:35:13 -0500 Subject: [PATCH 030/213] Removes the visible messages from vitality matrices (#33549) --- code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index e5a8c9b6f3..920f69cbd5 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -275,7 +275,6 @@ /obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L) if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active) return - visible_message("[src] begins to glow bright blue!") animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay. sleep(10) //as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality @@ -355,5 +354,4 @@ if(sigil_active) animation_number = initial(animation_number) sigil_active = FALSE - visible_message("[src] slowly stops glowing!") animate(src, alpha = initial(alpha), time = 10, flags = ANIMATION_END_NOW) From 3fc98677a06d86fbf843f2832f01cd628990e701 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Sat, 16 Dec 2017 19:20:12 +0200 Subject: [PATCH 032/213] Fixes a brain login runtime (#33569) * Fixes a silly brain meme * better --- code/modules/mob/living/login.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index ffdd37bdca..611d9dbc4c 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -13,8 +13,8 @@ update_damage_hud() update_health_hud() - if (loc) - var/turf/T = get_turf(src) + var/turf/T = get_turf(src) + if (isturf(T)) update_z(T.z) //Vents From e71fa098ae5be0152cc9ec7cfded57f671bd979a Mon Sep 17 00:00:00 2001 From: Robustin Date: Sat, 16 Dec 2017 12:18:08 -0500 Subject: [PATCH 034/213] Shield balance (#33553) Rebalances Marauder shields --- .../clock_cult/clock_mobs/clockwork_marauder.dm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm index a1c3d211fb..562814dfeb 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm @@ -1,13 +1,13 @@ #define MARAUDER_SLOWDOWN_PERCENTAGE 0.40 //Below this percentage of health, marauders will become slower -#define MARAUDER_SHIELD_REGEN_TIME 100 //In deciseconds, how long it takes for shields to regenerate after breaking +#define MARAUDER_SHIELD_REGEN_TIME 200 //In deciseconds, how long it takes for shields to regenerate after breaking //Clockwork marauder: A well-rounded frontline construct. Only one can exist for every two human servants. /mob/living/simple_animal/hostile/clockwork/marauder name = "clockwork marauder" desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield." icon_state = "clockwork_marauder" - health = 150 - maxHealth = 150 + health = 120 + maxHealth = 120 force_threshold = 8 speed = 0 obj_damage = 40 @@ -39,10 +39,11 @@ speed = initial(speed) + 1 //Yes, this slows them down else speed = initial(speed) - if(shield_health != max_shield_health && world.time >= shield_health_regen) - to_chat(src, "Your shield has recovered. [max_shield_health] blocks remaining!") + if(shield_health < max_shield_health && world.time >= shield_health_regen) + shield_health_regen = world.time + MARAUDER_SHIELD_REGEN_TIME + to_chat(src, "Your shield has recovered, [shield_health] blocks remaining!") playsound_local(src, "shatter", 75, TRUE, frequency = -1) - shield_health = max_shield_health + shield_health++ /mob/living/simple_animal/hostile/clockwork/marauder/update_values() if(GLOB.ratvar_awakens) //Massive attack damage bonuses and health increase, because Ratvar From be6a0e82ff760fa49ff5378577396258561f511e Mon Sep 17 00:00:00 2001 From: Robustin Date: Sat, 16 Dec 2017 12:14:54 -0500 Subject: [PATCH 036/213] Slightly faster, more stunnable (#33568) --- code/modules/mob/living/carbon/human/species_types/zombies.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 2fe526368a..792485960e 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -25,7 +25,7 @@ limbs_id = "zombie" mutanthands = /obj/item/zombie_hand armor = 20 // 120 damage to KO a zombie, which kills it - speedmod = 2 + speedmod = 1.6 mutanteyes = /obj/item/organ/eyes/night_vision/zombie var/regen_cooldown = 0 @@ -34,7 +34,7 @@ /datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount) - . = min(2, amount) + . = min(20, amount) /datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H) . = ..() From 7d1485643eb5644b4f935dde30623081d38047d4 Mon Sep 17 00:00:00 2001 From: Robustin Date: Sat, 16 Dec 2017 12:14:18 -0500 Subject: [PATCH 038/213] Fixes race swap (#33566) --- code/modules/events/wizard/race.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 29773d95b2..5adc4bb851 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -12,7 +12,7 @@ for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() - if(!S.dangerous_existence) + if(!S.dangerous_existence && !S.blacklisted) all_species += speciestype var/datum/species/new_species = pick(all_species) From a536831bbb6ca59b751a36bdcfd33c384cb0cf9c Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 17 Dec 2017 11:35:11 -0200 Subject: [PATCH 040/213] Merge pull request #33586 from Xhuis/power_alerts Disables clockcult power alerts to ghosts when it's not clockcult --- .../gamemodes/clock_cult/clock_helpers/power_helpers.dm | 7 +++++-- .../gamemodes/clock_cult/clock_helpers/scripture_checks.dm | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm index 1935eb3e0b..c2479460c7 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm @@ -10,12 +10,15 @@ for(var/obj/effect/clockwork/sigil/transmission/T in GLOB.all_clockwork_objects) T.update_icon() var/power_overwhelming = GLOB.clockwork_power + var/unlock_message if(power_overwhelming >= SCRIPT_UNLOCK_THRESHOLD && !GLOB.script_scripture_unlocked) GLOB.script_scripture_unlocked = TRUE - hierophant_message("The Ark swells as a key power threshold is reached. Script scriptures are now available.") + unlock_message = "The Ark swells as a key power threshold is reached. Script scriptures are now available." if(power_overwhelming >= APPLICATION_UNLOCK_THRESHOLD && !GLOB.application_scripture_unlocked) GLOB.application_scripture_unlocked = TRUE - hierophant_message("The Ark surges as a key power threshold is reached. Application scriptures are now available.") + unlock_message = "The Ark surges as a key power threshold is reached. Application scriptures are now available." + if(GLOB.servants_active) + hierophant_message(unlock_message) return TRUE /proc/can_access_clockwork_power(atom/movable/access_point, amount) //Returns true if the access point has access to clockwork power (and optionally, a number of watts for it) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm index 0b94d34ab1..bfa27cefdb 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm @@ -11,6 +11,8 @@ //reports to servants when scripture is locked or unlocked /proc/scripture_unlock_alert(list/previous_states) + if(!GLOB.servants_active) + return . = scripture_unlock_check() for(var/i in .) if(.[i] != previous_states[i]) From f875d4e17659762ac01a32b239c8e200088d7af8 Mon Sep 17 00:00:00 2001 From: Emmett Gaines Date: Sun, 17 Dec 2017 11:02:11 -0500 Subject: [PATCH 042/213] Defines math, take 2 --- code/__DEFINES/atmospherics.dm | 6 + code/__DEFINES/math.dm | 27 -- code/__DEFINES/maths.dm | 209 +++++++++++ code/__HELPERS/_lists.dm | 4 +- code/__HELPERS/maths.dm | 257 ------------- code/__HELPERS/radio.dm | 17 + code/__HELPERS/time.dm | 6 +- code/__HELPERS/type2type.dm | 2 +- code/__HELPERS/unsorted.dm | 18 +- code/_onclick/hud/parallax.dm | 4 +- code/_onclick/hud/robot.dm | 280 ++++++++++++++ code/_onclick/item_attack.dm | 4 +- .../controllers/configuration/config_entry.dm | 2 +- code/controllers/master.dm | 2 +- code/controllers/subsystem/throwing.dm | 2 +- code/datums/beam.dm | 4 +- code/datums/components/archaeology.dm | 2 +- code/datums/components/decal.dm | 2 +- code/datums/dash_weapon.dm | 2 +- code/datums/diseases/advance/advance.dm | 8 +- code/datums/explosion.dm | 2 +- code/datums/martial/krav_maga.dm | 4 +- code/datums/progressbar.dm | 2 +- code/datums/radiation_wave.dm | 4 +- code/datums/status_effects/buffs.dm | 6 +- code/datums/status_effects/debuffs.dm | 4 +- code/game/gamemodes/blob/blobs/blob_mobs.dm | 2 +- code/game/gamemodes/blob/overmind.dm | 2 +- .../clock_cult/clock_effects/clock_sigils.dm | 2 +- .../clock_helpers/fabrication_helpers.dm | 4 +- .../scripture_applications.dm | 2 +- .../clock_structures/mania_motor.dm | 2 +- .../clock_structures/taunting_trail.dm | 2 +- code/game/gamemodes/meteor/meteor.dm | 2 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 2 +- code/game/machinery/computer/apc_control.dm | 4 +- code/game/machinery/computer/atmos_control.dm | 2 +- code/game/machinery/computer/dna_console.dm | 33 +- .../machinery/computer/gulag_teleporter.dm | 2 +- .../machinery/computer/telecrystalconsoles.dm | 6 + code/game/machinery/deployable.dm | 2 +- code/game/machinery/doors/brigdoors.dm | 2 +- code/game/machinery/pipe/pipe_dispenser.dm | 4 +- code/game/machinery/shieldgen.dm | 2 +- code/game/machinery/spaceheater.dm | 4 +- code/game/machinery/syndicatebomb.dm | 2 +- code/game/machinery/vending.dm | 2 +- code/game/mecha/mech_fabricator.dm | 6 +- code/game/mecha/working/ripley.dm | 2 +- code/game/objects/effects/anomalies.dm | 5 + code/game/objects/items/chrono_eraser.dm | 2 +- code/game/objects/items/defib.dm | 2 +- .../objects/items/devices/lightreplacer.dm | 2 +- .../objects/items/devices/traitordevices.dm | 2 +- code/game/objects/items/dice.dm | 2 +- code/game/objects/items/grenades/plastic.dm | 4 +- code/game/objects/items/his_grace.dm | 6 +- code/game/objects/items/pneumaticCannon.dm | 4 +- code/game/objects/items/robot/robot_items.dm | 4 +- code/game/objects/items/sharpener.dm | 6 +- code/game/objects/items/stacks/stack.dm | 4 +- code/game/objects/items/tanks/tanks.dm | 2 +- code/game/objects/items/tools/weldingtool.dm | 347 ++++++++++++++++++ code/game/objects/obj_defense.dm | 2 +- code/game/objects/structures/fireplace.dm | 2 +- code/game/objects/structures/grille.dm | 2 +- code/game/objects/structures/lattice.dm | 4 +- code/game/objects/structures/musician.dm | 2 +- code/game/objects/structures/reflector.dm | 33 +- code/game/objects/structures/tables_racks.dm | 4 +- code/game/objects/structures/window.dm | 2 +- .../turfs/simulated/floor/plating/asteroid.dm | 2 +- code/game/turfs/simulated/walls.dm | 2 +- code/modules/admin/sound_emitter.dm | 4 +- code/modules/admin/sql_message_system.dm | 2 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 2 +- code/modules/admin/verbs/playsound.dm | 2 +- .../components/binary_devices/dp_vent_pump.dm | 6 +- .../components/binary_devices/passive_gate.dm | 4 +- .../components/binary_devices/pump.dm | 7 +- .../components/binary_devices/volume_pump.dm | 7 +- .../components/trinary_devices/filter.dm | 2 +- .../components/trinary_devices/mixer.dm | 2 +- .../unary_devices/outlet_injector.dm | 4 +- .../components/unary_devices/thermomachine.dm | 2 +- .../components/unary_devices/vent_pump.dm | 8 +- .../machinery/pipes/layermanifold.dm | 4 +- .../machinery/portable/canister.dm | 4 +- .../atmospherics/machinery/portable/pump.dm | 2 +- code/modules/cargo/exports.dm | 6 +- code/modules/client/client_procs.dm | 12 +- code/modules/client/preferences.dm | 4 +- .../modules/clothing/spacesuits/flightsuit.dm | 20 +- code/modules/clothing/spacesuits/hardsuit.dm | 2 +- code/modules/events/_event.dm | 4 +- code/modules/events/brand_intelligence.dm | 4 +- code/modules/events/disease_outbreak.dm | 9 + code/modules/events/meteor_wave.dm | 2 +- code/modules/events/portal_storm.dm | 6 +- .../kitchen_machinery/food_cart.dm | 2 +- code/modules/food_and_drinks/pizzabox.dm | 2 +- code/modules/goonchat/browserOutput.dm | 2 +- code/modules/hydroponics/gene_modder.dm | 2 +- code/modules/hydroponics/grown.dm | 2 +- code/modules/hydroponics/grown/towercap.dm | 4 +- code/modules/hydroponics/growninedible.dm | 2 +- code/modules/hydroponics/hydroponics.dm | 12 +- code/modules/hydroponics/seeds.dm | 28 +- .../core/special_pins/index_pin.dm | 2 +- .../subtypes/converters.dm | 4 +- .../subtypes/data_transfer.dm | 2 +- .../integrated_electronics/subtypes/input.dm | 4 +- .../subtypes/manipulation.dm | 12 +- .../integrated_electronics/subtypes/output.dm | 4 +- .../subtypes/reagents.dm | 8 +- .../integrated_electronics/subtypes/time.dm | 2 +- .../integrated_electronics/subtypes/trig.dm | 8 +- code/modules/language/language.dm | 2 +- code/modules/library/lib_machines.dm | 4 +- code/modules/lighting/lighting_source.dm | 4 +- code/modules/mapping/reader.dm | 10 +- .../mining/lavaland/necropolis_chests.dm | 4 +- code/modules/mining/machine_redemption.dm | 2 +- code/modules/mining/mint.dm | 2 +- .../modules/mob/dead/new_player/new_player.dm | 4 +- code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/living/brain/brain_item.dm | 2 +- .../mob/living/carbon/alien/status_procs.dm | 2 +- .../modules/mob/living/carbon/damage_procs.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 6 +- .../carbon/human/species_types/golems.dm | 2 +- .../carbon/human/species_types/vampire.dm | 4 +- code/modules/mob/living/carbon/life.dm | 2 +- .../modules/mob/living/carbon/status_procs.dm | 4 +- code/modules/mob/living/damage_procs.dm | 10 +- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/living_defense.dm | 4 +- code/modules/mob/living/silicon/pai/pai.dm | 6 +- .../mob/living/silicon/pai/pai_defense.dm | 2 +- code/modules/mob/living/silicon/robot/life.dm | 2 +- .../mob/living/simple_animal/damage_procs.dm | 2 +- .../hostile/megafauna/bubblegum.dm | 4 +- .../hostile/megafauna/colossus.dm | 2 +- .../simple_animal/hostile/megafauna/dragon.dm | 6 +- .../hostile/megafauna/hierophant.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 +- .../mob/living/simple_animal/slime/powers.dm | 2 +- code/modules/power/apc.dm | 4 +- code/modules/power/cell.dm | 4 +- code/modules/power/powernet.dm | 2 +- code/modules/power/smes.dm | 6 +- code/modules/power/solar.dm | 4 +- code/modules/power/supermatter/supermatter.dm | 10 +- code/modules/power/tesla/energy_ball.dm | 4 +- .../boxes_magazines/external_mag.dm | 2 +- .../projectiles/guns/ballistic/automatic.dm | 8 +- code/modules/projectiles/guns/beam_rifle.dm | 6 +- code/modules/projectiles/guns/energy.dm | 2 +- code/modules/projectiles/guns/magic/wand.dm | 4 +- code/modules/projectiles/projectile.dm | 12 +- code/modules/reagents/chemistry/holder.dm | 2 +- .../chemistry/machinery/chem_dispenser.dm | 2 +- .../chemistry/machinery/chem_heater.dm | 2 +- .../chemistry/machinery/chem_master.dm | 4 +- .../chemistry/machinery/reagentgrinder.dm | 2 +- code/modules/reagents/chemistry/reagents.dm | 2 +- .../chemistry/reagents/alcohol_reagents.dm | 2 +- .../chemistry/reagents/toxin_reagents.dm | 4 +- .../chemistry/recipes/pyrotechnics.dm | 8 +- .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/recycling/disposal/bin.dm | 2 +- code/modules/research/protolathe.dm | 2 +- .../research/xenobiology/xenobiology.dm | 4 +- code/modules/shuttle/shuttle.dm | 14 +- code/modules/spells/spell_types/wizard.dm | 2 +- .../surgery/bodyparts/dismemberment.dm | 2 +- code/modules/surgery/organs/eyes.dm | 2 +- code/modules/surgery/organs/lungs.dm | 6 +- tgstation.dme | 3 +- 180 files changed, 1250 insertions(+), 644 deletions(-) delete mode 100644 code/__DEFINES/math.dm create mode 100644 code/__DEFINES/maths.dm delete mode 100644 code/__HELPERS/maths.dm diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index dacd09c995..20d80cb904 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -12,6 +12,12 @@ //ATMOS //stuff you should probably leave well alone! +#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) +#define ONE_ATMOSPHERE 101.325 //kPa +#define T0C 273.15 // 0degC +#define T20C 293.15 // 20degC +#define TCMB 2.7 // -270.3degC + #define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC #define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity #define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm deleted file mode 100644 index 5b3f51b4e3..0000000000 --- a/code/__DEFINES/math.dm +++ /dev/null @@ -1,27 +0,0 @@ -#define PI 3.1415 -#define SPEED_OF_LIGHT 3e8 //not exact but hey! -#define SPEED_OF_LIGHT_SQ 9e+16 -#define INFINITY 1e31 //closer then enough - -//atmos -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -#define TCMB 2.7 // -270.3degC - -#define SHORT_REAL_LIMIT 16777216 - -//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks -//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) -//collapsed to percent_of_tick_used * tick_lag -#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) -#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) - -#define PERCENT(val) (round(val*100, 0.1)) -#define CLAMP01(x) (Clamp(x, 0, 1)) - -//time of day but automatically adjusts to the server going into the next day within the same round. -//for when you need a reliable time number that doesn't depend on byond time. -#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) -#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm new file mode 100644 index 0000000000..0ff3ade369 --- /dev/null +++ b/code/__DEFINES/maths.dm @@ -0,0 +1,209 @@ +// Credits to Nickr5 for the useful procs I've taken from his library resource. +// This file is quadruple wrapped for your pleasure +// ( + +#define NUM_E 2.71828183 +#define NUM_SQRT2 1.41421356 + +#define PI 3.1415 +#define SPEED_OF_LIGHT 3e8 //not exact but hey! +#define SPEED_OF_LIGHT_SQ 9e+16 +#define INFINITY 1e31 //closer then enough + +#define SHORT_REAL_LIMIT 16777216 + +//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks +//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) +//collapsed to percent_of_tick_used * tick_lag +#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) +#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) + +#define PERCENT(val) (round((val)*100, 0.1)) +#define CLAMP01(x) (CLAMP(x, 0, 1)) + +//time of day but automatically adjusts to the server going into the next day within the same round. +//for when you need a reliable time number that doesn't depend on byond time. +#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) +#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) + +#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 ) + +#define CEILING(x, y) ( -round(-(x) / (y)) * (y) ) + +// round() acts like floor(x, 1) by default but can't handle other values +#define FLOOR(x, y) ( round((x) / (y)) * (y) ) + +#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) ) + +// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive +#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) ) + +// Real modulus that handles decimals +#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) ) + +// Tangent +#define TAN(x) (sin(x) / cos(x)) + +// Cotangent +#define COT(x) (1 / TAN(x)) + +// Secant +#define SEC(x) (1 / cos(x)) + +// Cosecant +#define CSC(x) (1 / sin(x)) + +#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) ) + +// Greatest Common Divisor - Euclid's algorithm +/proc/Gcd(a, b) + return b ? Gcd(b, (a) % (b)) : a + +// Least Common Multiple +#define Lcm(a, b) (abs(a) / Gcd(a, b) * abs(b)) + +#define INVERSE(x) ( 1/(x) ) + +// Used for calculating the radioactive strength falloff +#define INVERSE_SQUARE(initial_strength,cur_distance,initial_distance) ( (initial_strength)*((initial_distance)**2/(cur_distance)**2) ) + +#define ISABOUTEQUAL(a, b, deviation) (deviation ? abs((a) - (b)) <= deviation : abs((a) - (b)) <= 0.1) + +#define ISEVEN(x) (x % 2 == 0) + +#define ISODD(x) (x % 2 != 0) + +// Returns true if val is from min to max, inclusive. +#define ISINRANGE(val, min, max) (min <= val && val <= max) + +// Same as above, exclusive. +#define ISINRANGE_EX(val, min, max) (min < val && val > max) + +#define ISINTEGER(x) (round(x) == x) + +#define ISMULTIPLE(x, y) ((x) % (y) == 0) + +// Performs a linear interpolation between a and b. +// Note that amount=0 returns a, amount=1 returns b, and +// amount=0.5 returns the mean of a and b. +#define LERP(a, b, amount) (amount ? ((a) + ((b) - (a)) * (amount)) : ((a) + ((b) - (a)) * 0.5) + +// Returns the nth root of x. +#define ROOT(n, x) ((x) ** (1 / (n))) + +// The quadratic formula. Returns a list with the solutions, or an empty list +// if they are imaginary. +/proc/SolveQuadratic(a, b, c) + ASSERT(a) + . = list() + var/d = b*b - 4 * a * c + var/bottom = 2 * a + if(d < 0) + return + var/root = sqrt(d) + . += (-b + root) / bottom + if(!d) + return + . += (-b - root) / bottom + +#define TODEGREES(radians) ((radians) * 57.2957795) + +#define TORADIANS(degrees) ((degrees) * 0.0174532925) + +// Will filter out extra rotations and negative rotations +// E.g: 540 becomes 180. -180 becomes 180. +#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360)) + +#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360)) + +//A logarithm that converts an integer to a number scaled between 0 and 1. +//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. +#define TRANSFORM_USING_VARIABLE(input, max) ( sin((90*(input))/(max))**2 ) + +//converts a uniform distributed random number into a normal distributed one +//since this method produces two random numbers, one is saved for subsequent calls +//(making the cost negligble for every second call) +//This will return +/- decimals, situated about mean with standard deviation stddev +//68% chance that the number is within 1stddev +//95% chance that the number is within 2stddev +//98% chance that the number is within 3stddev...etc +#define ACCURACY 10000 +/proc/gaussian(mean, stddev) + var/static/gaussian_next + var/R1;var/R2;var/working + if(gaussian_next != null) + R1 = gaussian_next + gaussian_next = null + else + do + R1 = rand(-ACCURACY,ACCURACY)/ACCURACY + R2 = rand(-ACCURACY,ACCURACY)/ACCURACY + working = R1*R1 + R2*R2 + while(working >= 1 || working==0) + working = sqrt(-2 * log(working) / working) + R1 *= working + gaussian_next = R2 * working + return (mean + stddev * R1) +#undef ACCURACY + +/proc/mouse_angle_from_client(client/client) + var/list/mouse_control = params2list(client.mouseParams) + if(mouse_control["screen-loc"] && client) + var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") + var/list/screen_loc_X = splittext(screen_loc_params[1],":") + var/list/screen_loc_Y = splittext(screen_loc_params[2],":") + var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32) + var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32) + var/list/screenview = getviewsize(client.view) + var/screenviewX = screenview[1] * world.icon_size + var/screenviewY = screenview[2] * world.icon_size + var/ox = round(screenviewX/2) - client.pixel_x //"origin" x + var/oy = round(screenviewY/2) - client.pixel_y //"origin" y + var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox)) + return angle + +/proc/get_turf_in_angle(angle, turf/starting, increments) + var/pixel_x = 0 + var/pixel_y = 0 + for(var/i in 1 to increments) + pixel_x += sin(angle)+16*sin(angle)*2 + pixel_y += cos(angle)+16*cos(angle)*2 + var/new_x = starting.x + var/new_y = starting.y + while(pixel_x > 16) + pixel_x -= 32 + new_x++ + while(pixel_x < -16) + pixel_x += 32 + new_x-- + while(pixel_y > 16) + pixel_y -= 32 + new_y++ + while(pixel_y < -16) + pixel_y += 32 + new_y-- + new_x = CLAMP(new_x, 0, world.maxx) + new_y = CLAMP(new_y, 0, world.maxy) + return locate(new_x, new_y, starting.z) + +// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles +/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4) + var/list/region_x1 = list() + var/list/region_y1 = list() + var/list/region_x2 = list() + var/list/region_y2 = list() + + // These loops create loops filled with x/y values that the boundaries inhabit + // ex: list(5, 6, 7, 8, 9) + for(var/i in min(x1, x2) to max(x1, x2)) + region_x1["[i]"] = TRUE + for(var/i in min(y1, y2) to max(y1, y2)) + region_y1["[i]"] = TRUE + for(var/i in min(x3, x4) to max(x3, x4)) + region_x2["[i]"] = TRUE + for(var/i in min(y3, y4) to max(y3, y4)) + region_y2["[i]"] = TRUE + + return list(region_x1 & region_x2, region_y1 & region_y2) + +// ) \ No newline at end of file diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 631214de98..91eee45b4d 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -43,8 +43,8 @@ //Returns list element or null. Should prevent "index out of bounds" error. /proc/listgetindex(list/L, index) if(LAZYLEN(L)) - if(isnum(index) && IsInteger(index)) - if(IsInRange(index,1,L.len)) + if(isnum(index) && ISINTEGER(index)) + if(ISINRANGE(index,1,L.len)) return L[index] else if(index in L) return L[index] diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm deleted file mode 100644 index 0af8b8ae1a..0000000000 --- a/code/__HELPERS/maths.dm +++ /dev/null @@ -1,257 +0,0 @@ -// Credits to Nickr5 for the useful procs I've taken from his library resource. - -GLOBAL_VAR_INIT(E, 2.71828183) -GLOBAL_VAR_INIT(Sqrt2, 1.41421356) - -// List of square roots for the numbers 1-100. -GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)) - -/proc/sign(x) - return x!=0?x/abs(x):0 - -/proc/Atan2(x, y) - if(!x && !y) - return 0 - var/a = arccos(x / sqrt(x*x + y*y)) - return y >= 0 ? a : -a - -/proc/Ceiling(x, y=1) - return -round(-x / y) * y - -/proc/Floor(x, y=1) - return round(x / y) * y - -#define Clamp(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) ) - -/proc/Modulus(x, y) //Byond's modulus doesn't work with decimals. - return x - y * round(x / y) - -// cotangent -/proc/Cot(x) - return 1 / Tan(x) - -// cosecant -/proc/Csc(x) - return 1 / sin(x) - -/proc/Default(a, b) - return a ? a : b - -// Greatest Common Divisor - Euclid's algorithm -/proc/Gcd(a, b) - return b ? Gcd(b, a % b) : a - -/proc/Inverse(x) - return 1 / x - -#define InverseSquareLaw(initial_strength,cur_distance,initial_distance) (initial_strength*(initial_distance**2/cur_distance**2)) - -/proc/IsAboutEqual(a, b, deviation = 0.1) - return abs(a - b) <= deviation - -/proc/IsEven(x) - return x % 2 == 0 - -// Returns true if val is from min to max, inclusive. -/proc/IsInRange(val, min, max) - return min <= val && val <= max - -/proc/IsInteger(x) - return round(x) == x - -/proc/IsOdd(x) - return !IsEven(x) - -/proc/IsMultiple(x, y) - return x % y == 0 - -// Least Common Multiple -/proc/Lcm(a, b) - return abs(a) / Gcd(a, b) * abs(b) - -// Performs a linear interpolation between a and b. -// Note that amount=0 returns a, amount=1 returns b, and -// amount=0.5 returns the mean of a and b. -/proc/Lerp(a, b, amount = 0.5) - return a + (b - a) * amount - -//Calculates the sum of a list of numbers. -/proc/Sum(var/list/data) - . = 0 - for(var/val in data) - .+= val - -//Calculates the mean of a list of numbers. -/proc/Mean(var/list/data) - . = Sum(data) / (data.len) - - -// Returns the nth root of x. -/proc/Root(n, x) - return x ** (1 / n) - -// secant -/proc/Sec(x) - return 1 / cos(x) - -// The quadratic formula. Returns a list with the solutions, or an empty list -// if they are imaginary. -/proc/SolveQuadratic(a, b, c) - ASSERT(a) - . = list() - var/d = b*b - 4 * a * c - var/bottom = 2 * a - if(d < 0) - return - var/root = sqrt(d) - . += (-b + root) / bottom - if(!d) - return - . += (-b - root) / bottom - -// tangent -/proc/Tan(x) - return sin(x) / cos(x) - -/proc/ToDegrees(radians) - // 180 / Pi - return radians * 57.2957795 - -/proc/ToRadians(degrees) - // Pi / 180 - return degrees * 0.0174532925 - -// Will filter out extra rotations and negative rotations -// E.g: 540 becomes 180. -180 becomes 180. -/proc/SimplifyDegrees(degrees) - degrees = degrees % 360 - if(degrees < 0) - degrees += 360 - return degrees - -// min is inclusive, max is exclusive -/proc/Wrap(val, min, max) - var/d = max - min - var/t = round((val - min) / d) - return val - (t * d) - -#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) >= 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360)) - -/proc/get_angle_of_incidence(face_angle, angle_in, auto_normalize = TRUE) - - var/angle_in_s = NORM_ROT(angle_in) - var/face_angle_s = NORM_ROT(face_angle) - var/incidence = face_angle_s - angle_in_s - var/incidence_s = incidence - while(incidence_s < -90) - incidence_s += 180 - while(incidence_s > 90) - incidence_s -= 180 - if(auto_normalize) - return incidence_s - else - return incidence - -//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher). -//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. -/proc/TransformUsingVariable(input, inputmaximum, scaling_modifier = 0) - - var/inputToDegrees = (input/inputmaximum)*180 //Converting from a 0 -> 100 scale to a 0 -> 180 scale. The 0 -> 180 scale corresponds to degrees - var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1 - - return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5 - -//converts a uniform distributed random number into a normal distributed one -//since this method produces two random numbers, one is saved for subsequent calls -//(making the cost negligble for every second call) -//This will return +/- decimals, situated about mean with standard deviation stddev -//68% chance that the number is within 1stddev -//95% chance that the number is within 2stddev -//98% chance that the number is within 3stddev...etc -#define ACCURACY 10000 -/proc/gaussian(mean, stddev) - var/static/gaussian_next - var/R1;var/R2;var/working - if(gaussian_next != null) - R1 = gaussian_next - gaussian_next = null - else - do - R1 = rand(-ACCURACY,ACCURACY)/ACCURACY - R2 = rand(-ACCURACY,ACCURACY)/ACCURACY - working = R1*R1 + R2*R2 - while(working >= 1 || working==0) - working = sqrt(-2 * log(working) / working) - R1 *= working - gaussian_next = R2 * working - return (mean + stddev * R1) -#undef ACCURACY - -/proc/mouse_angle_from_client(client/client) - var/list/mouse_control = params2list(client.mouseParams) - if(mouse_control["screen-loc"] && client) - var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") - var/list/screen_loc_X = splittext(screen_loc_params[1],":") - var/list/screen_loc_Y = splittext(screen_loc_params[2],":") - var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32) - var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32) - var/list/screenview = getviewsize(client.view) - var/screenviewX = screenview[1] * world.icon_size - var/screenviewY = screenview[2] * world.icon_size - var/ox = round(screenviewX/2) - client.pixel_x //"origin" x - var/oy = round(screenviewY/2) - client.pixel_y //"origin" y - var/angle = NORM_ROT(Atan2(y - oy, x - ox)) - return angle - -/proc/get_turf_in_angle(angle, turf/starting, increments) - var/pixel_x = 0 - var/pixel_y = 0 - for(var/i in 1 to increments) - pixel_x += sin(angle)+16*sin(angle)*2 - pixel_y += cos(angle)+16*cos(angle)*2 - var/new_x = starting.x - var/new_y = starting.y - while(pixel_x > 16) - pixel_x -= 32 - new_x++ - while(pixel_x < -16) - pixel_x += 32 - new_x-- - while(pixel_y > 16) - pixel_y -= 32 - new_y++ - while(pixel_y < -16) - pixel_y += 32 - new_y-- - new_x = Clamp(new_x, 0, world.maxx) - new_y = Clamp(new_y, 0, world.maxy) - return locate(new_x, new_y, starting.z) - -/proc/round_down(num) - if(round(num) != num) - return round(num--) - else return num - -//proc/get_overlap() -// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles -/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4) - var/list/region_x1 = list() - var/list/region_y1 = list() - var/list/region_x2 = list() - var/list/region_y2 = list() - - // These loops create loops filled with x/y values that the boundaries inhabit - // ex: list(5, 6, 7, 8, 9) - for(var/i in min(x1, x2) to max(x1, x2)) - region_x1["[i]"] = TRUE - for(var/i in min(y1, y2) to max(y1, y2)) - region_y1["[i]"] = TRUE - for(var/i in min(x3, x4) to max(x3, x4)) - region_x2["[i]"] = TRUE - for(var/i in min(y3, y4) to max(y3, y4)) - region_y2["[i]"] = TRUE - - return list(region_x1 & region_x2, region_y1 & region_y2) \ No newline at end of file diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 1706e8658c..56471142ca 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD // Ensure the frequency is within bounds of what it should be sending/recieving at /proc/sanitize_frequency(frequency, free = FALSE) . = round(frequency) @@ -12,3 +13,19 @@ /proc/format_frequency(frequency) frequency = text2num(frequency) return "[round(frequency / 10)].[frequency % 10]" +======= +// Ensure the frequency is within bounds of what it should be sending/recieving at +/proc/sanitize_frequency(frequency, free = FALSE) + . = round(frequency) + if(free) + . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) + else + . = CLAMP(frequency, MIN_FREQ, MAX_FREQ) + if(!(. % 2)) // Ensure the last digit is an odd number + . += 1 + +// Format frequency by moving the decimal. +/proc/format_frequency(frequency) + frequency = text2num(frequency) + return "[round(frequency / 10)].[frequency % 10]" +>>>>>>> 25080ff... defines math (#33498) diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 74c565da52..68ab173ecd 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -60,7 +60,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!second) return "0 seconds" if(second >= 60) - minute = round_down(second/60) + minute = FLOOR(second/60, 1) second = round(second - (minute*60), 0.1) second_rounded = TRUE if(second) //check if we still have seconds remaining to format, or if everything went into minute. @@ -91,7 +91,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!minute) return "[second]" if(minute >= 60) - hour = round_down(minute/60,1) + hour = FLOOR(minute/60, 1) minute = (minute - (hour*60)) if(minute) //alot simpler from here since you don't have to worry about fractions if(minute != 1) @@ -114,7 +114,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!hour) return "[minute][second]" if(hour >= 24) - day = round_down(hour/24,1) + day = FLOOR(hour/24, 1) hour = (hour - (day*24)) if(hour) if(hour != 1) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index bae773b27e..2ebe24b85b 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -117,7 +117,7 @@ //Converts an angle (degrees) into an ss13 direction /proc/angle2dir(degree) - degree = SimplifyDegrees(degree) + degree = SIMPLIFY_DEGREES(degree) switch(degree) if(0 to 22.5) //north requires two angle ranges return NORTH diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9ec23fa966..207e69fa9b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -147,10 +147,10 @@ Turf and target are separate in case you want to teleport some distance from a t var/line[] = list(locate(px,py,M.z)) var/dx=N.x-px //x distance var/dy=N.y-py - var/dxabs=abs(dx)//Absolute value of x distance - var/dyabs=abs(dy) - var/sdx=sign(dx) //Sign of x distance (+ or -) - var/sdy=sign(dy) + var/dxabs = abs(dx)//Absolute value of x distance + var/dyabs = abs(dy) + var/sdx = SIGN(dx) //Sign of x distance (+ or -) + var/sdy = SIGN(dy) var/x=dxabs>>1 //Counters for steps taken, setting to distance/2 var/y=dyabs>>1 //Bit-shifting makes me l33t. It also makes getline() unnessecarrily fast. var/j //Generic integer for counting @@ -953,8 +953,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list( tY = tY[1] tX = splittext(tX[1], ":") tX = tX[1] - tX = Clamp(origin.x + text2num(tX) - world.view - 1, 1, world.maxx) - tY = Clamp(origin.y + text2num(tY) - world.view - 1, 1, world.maxy) + tX = CLAMP(origin.x + text2num(tX) - world.view - 1, 1, world.maxx) + tY = CLAMP(origin.y + text2num(tY) - world.view - 1, 1, world.maxy) return locate(tX, tY, tZ) /proc/screen_loc2turf(text, turf/origin) @@ -966,8 +966,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list( tX = splittext(tZ[2], "-") tX = text2num(tX[2]) tZ = origin.z - tX = Clamp(origin.x + 7 - tX, 1, world.maxx) - tY = Clamp(origin.y + 7 - tY, 1, world.maxy) + tX = CLAMP(origin.x + 7 - tX, 1, world.maxx) + tY = CLAMP(origin.y + 7 - tY, 1, world.maxy) return locate(tX, tY, tZ) /proc/IsValidSrc(datum/D) @@ -1272,7 +1272,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) . = 0 var/i = DS2TICKS(initial_delay) do - . += Ceiling(i*DELTA_CALC) + . += CEILING(i*DELTA_CALC, 1) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index ff38107bfb..52319b7866 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -257,8 +257,8 @@ view = world.view var/list/viewscales = getviewsize(view) - var/countx = Ceiling((viewscales[1]/2)/(480/world.icon_size))+1 - var/county = Ceiling((viewscales[2]/2)/(480/world.icon_size))+1 + var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 + var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index f1ec409520..e227968f57 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/screen/robot icon = 'icons/mob/screen_cyborg.dmi' @@ -275,3 +276,282 @@ else for(var/obj/item/I in R.held_items) screenmob.client.screen -= I +======= +/obj/screen/robot + icon = 'icons/mob/screen_cyborg.dmi' + +/obj/screen/robot/module + name = "cyborg module" + icon_state = "nomod" + +/obj/screen/robot/Click() + if(isobserver(usr)) + return 1 + +/obj/screen/robot/module/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + if(R.module.type != /obj/item/robot_module) + R.hud_used.toggle_show_robot_modules() + return 1 + R.pick_module() + +/obj/screen/robot/module1 + name = "module1" + icon_state = "inv1" + +/obj/screen/robot/module1/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(1) + +/obj/screen/robot/module2 + name = "module2" + icon_state = "inv2" + +/obj/screen/robot/module2/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(2) + +/obj/screen/robot/module3 + name = "module3" + icon_state = "inv3" + +/obj/screen/robot/module3/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(3) + +/obj/screen/robot/radio + name = "radio" + icon_state = "radio" + +/obj/screen/robot/radio/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.radio.interact(R) + +/obj/screen/robot/store + name = "store" + icon_state = "store" + +/obj/screen/robot/store/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.uneq_active() + +/obj/screen/robot/lamp + name = "headlamp" + icon_state = "lamp0" + +/obj/screen/robot/lamp/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.control_headlamp() + +/obj/screen/robot/thrusters + name = "ion thrusters" + icon_state = "ionpulse0" + +/obj/screen/robot/thrusters/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_ionpulse() + +/datum/hud/robot + ui_style_icon = 'icons/mob/screen_cyborg.dmi' + +/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi') + ..() + var/mob/living/silicon/robot/mymobR = mymob + var/obj/screen/using + + using = new/obj/screen/language_menu + using.screen_loc = ui_borg_language_menu + static_inventory += using + +//Radio + using = new /obj/screen/robot/radio() + using.screen_loc = ui_borg_radio + static_inventory += using + +//Module select + using = new /obj/screen/robot/module1() + using.screen_loc = ui_inv1 + static_inventory += using + mymobR.inv1 = using + + using = new /obj/screen/robot/module2() + using.screen_loc = ui_inv2 + static_inventory += using + mymobR.inv2 = using + + using = new /obj/screen/robot/module3() + using.screen_loc = ui_inv3 + static_inventory += using + mymobR.inv3 = using + +//End of module select + +//Photography stuff + using = new /obj/screen/ai/image_take() + using.screen_loc = ui_borg_camera + static_inventory += using + + using = new /obj/screen/ai/image_view() + using.screen_loc = ui_borg_album + static_inventory += using + +//Sec/Med HUDs + using = new /obj/screen/ai/sensors() + using.screen_loc = ui_borg_sensor + static_inventory += using + +//Headlamp control + using = new /obj/screen/robot/lamp() + using.screen_loc = ui_borg_lamp + static_inventory += using + mymobR.lamp_button = using + +//Thrusters + using = new /obj/screen/robot/thrusters() + using.screen_loc = ui_borg_thrusters + static_inventory += using + mymobR.thruster_button = using + +//Intent + action_intent = new /obj/screen/act_intent/robot() + action_intent.icon_state = mymob.a_intent + static_inventory += action_intent + +//Health + healths = new /obj/screen/healths/robot() + infodisplay += healths + +//Installed Module + mymobR.hands = new /obj/screen/robot/module() + mymobR.hands.screen_loc = ui_borg_module + static_inventory += mymobR.hands + +//Store + module_store_icon = new /obj/screen/robot/store() + module_store_icon.screen_loc = ui_borg_store + + pull_icon = new /obj/screen/pull() + pull_icon.icon = 'icons/mob/screen_cyborg.dmi' + pull_icon.update_icon(mymob) + pull_icon.screen_loc = ui_borg_pull + hotkeybuttons += pull_icon + + + zone_select = new /obj/screen/zone_sel/robot() + zone_select.update_icon(mymob) + static_inventory += zone_select + + +/datum/hud/proc/toggle_show_robot_modules() + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + R.shown_robot_modules = !R.shown_robot_modules + update_robot_modules_display() + +/datum/hud/proc/update_robot_modules_display(mob/viewer) + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(!R.module) + return + + if(!R.client) + return + + if(R.shown_robot_modules && screenmob.hud_used.hud_shown) + //Modules display is shown + screenmob.client.screen += module_store_icon //"store" icon + + if(!R.module.modules) + to_chat(usr, "Selected module has no modules to select") + return + + if(!R.robot_modules_background) + return + + var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1) + R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" + screenmob.client.screen += R.robot_modules_background + + var/x = -4 //Start at CENTER-4,SOUTH+1 + var/y = 1 + + for(var/atom/movable/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen += A + if(x < 0) + A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" + else + A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" + A.layer = ABOVE_HUD_LAYER + A.plane = ABOVE_HUD_PLANE + + x++ + if(x == 4) + x = -4 + y++ + + else + //Modules display is hidden + screenmob.client.screen -= module_store_icon //"store" icon + + for(var/atom/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen -= A + R.shown_robot_modules = 0 + screenmob.client.screen -= R.robot_modules_background + +/mob/living/silicon/robot/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/robot(src) + + +/datum/hud/robot/persistent_inventory_update(mob/viewer) + if(!mymob) + return + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(screenmob.hud_used) + if(screenmob.hud_used.hud_shown) + for(var/i in 1 to R.held_items.len) + var/obj/item/I = R.held_items[i] + if(I) + switch(i) + if(1) + I.screen_loc = ui_inv1 + if(2) + I.screen_loc = ui_inv2 + if(3) + I.screen_loc = ui_inv3 + else + return + screenmob.client.screen += I + else + for(var/obj/item/I in R.held_items) + screenmob.client.screen -= I +>>>>>>> 25080ff... defines math (#33498) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 859c957a43..727e149a97 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -119,9 +119,9 @@ /obj/item/proc/get_clamped_volume() if(w_class) if(force) - return Clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 + return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 else - return Clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 + return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 /mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) var/message_verb = "attacked" diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 92dcb9baf0..804060aaa8 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -110,7 +110,7 @@ /datum/config_entry/number/ValidateAndSet(str_val) var/temp = text2num(trim(str_val)) if(!isnull(temp)) - value = Clamp(integer ? round(temp) : temp, min_val, max_val) + value = CLAMP(integer ? round(temp) : temp, min_val, max_val) if(value != temp && !var_edited) log_config("Changing [name] from [temp] to [value]!") return TRUE diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 568257e10f..b9950da7b9 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -301,7 +301,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new continue //Byond resumed us late. assume it might have to do the same next tick - if (last_run + Ceiling(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time) + if (last_run + CEILING(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time) sleep_delta += 1 sleep_delta = MC_AVERAGE_FAST(sleep_delta, 1) //decay sleep_delta diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 97d84a0d3b..ec21f3bab2 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -80,7 +80,7 @@ SUBSYSTEM_DEF(throwing) last_move = world.time //calculate how many tiles to move, making up for any missed ticks. - var/tilestomove = Ceiling(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait)) + var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1) while (tilestomove-- > 0) if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc)) finalize() diff --git a/code/datums/beam.dm b/code/datums/beam.dm index c1a75c8b7e..dc68de933a 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -128,11 +128,11 @@ //Position the effect so the beam is one continous line var/a if(abs(Pixel_x)>32) - a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32) + a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1) X.x += a Pixel_x %= 32 if(abs(Pixel_y)>32) - a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32) + a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1) X.y += a Pixel_y %= 32 diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm index 6fb2b67051..30bf107ad0 100644 --- a/code/datums/components/archaeology.dm +++ b/code/datums/components/archaeology.dm @@ -6,7 +6,7 @@ var/datum/callback/callback /datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list(), datum/callback/_callback) - prob2drop = Clamp(_prob2drop, 0, 100) + prob2drop = CLAMP(_prob2drop, 0, 100) archdrops = _archdrops callback = _callback RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig) diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm index a28213b0b5..20cc9cd134 100644 --- a/code/datums/components/decal.dm +++ b/code/datums/components/decal.dm @@ -48,7 +48,7 @@ if(old_dir == new_dir) return remove() - var/rotation = SimplifyDegrees(dir2angle(new_dir)-dir2angle(old_dir)) + var/rotation = SIMPLIFY_DEGREES(dir2angle(new_dir)-dir2angle(old_dir)) pic.dir = turn(pic.dir, rotation) apply() diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm index 1637655d18..03badb2069 100644 --- a/code/datums/dash_weapon.dm +++ b/code/datums/dash_weapon.dm @@ -43,7 +43,7 @@ addtimer(CALLBACK(src, .proc/charge), charge_rate) /datum/action/innate/dash/proc/charge() - current_charges = Clamp(current_charges + 1, 0, max_charges) + current_charges = CLAMP(current_charges + 1, 0, max_charges) holder.update_action_buttons_icon() if(recharge_sound) playsound(dashing_item, recharge_sound, 50, 1) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 0c1058a287..60f90d61ad 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -185,10 +185,10 @@ if(properties["stealth"] >= 2) visibility_flags = HIDDEN_SCANNER - SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE)) + SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE)) - permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1) - cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20 + permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1) + cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20 stage_prob = max(properties["stage_rate"], 2) SetSeverity(properties["severity"]) GenerateCure(properties) @@ -243,7 +243,7 @@ // Will generate a random cure, the less resistance the symptoms have, the harder the cure. /datum/disease/advance/proc/GenerateCure() if(properties && properties.len) - var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) + var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) cures = list(advance_cures[res]) // Get the cure name from the cure_id diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index b71c560193..73b76a9155 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -121,7 +121,7 @@ GLOBAL_LIST_EMPTY(explosions) M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound) // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion M.playsound_local(epicenter, null, far_volume, 1, frequency, falloff = 5, S = far_explosion_sound) EX_PREPROCESS_CHECK_TICK diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 5c78a0c321..82497adf45 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -101,7 +101,7 @@ "[A] slams your chest! You can't breathe!") playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) if(D.losebreath <= 10) - D.losebreath = Clamp(D.losebreath + 5, 0, 10) + D.losebreath = CLAMP(D.losebreath + 5, 0, 10) D.adjustOxyLoss(10) add_logs(A, D, "quickchoked") return 1 @@ -112,7 +112,7 @@ playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.apply_damage(5, BRUTE) if(D.silent <= 10) - D.silent = Clamp(D.silent + 10, 0, 10) + D.silent = CLAMP(D.silent + 10, 0, 10) add_logs(A, D, "neck chopped") return 1 diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index f9883cfe50..3599c60f89 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -38,7 +38,7 @@ if (user.client) user.client.images += bar - progress = Clamp(progress, 0, goal) + progress = CLAMP(progress, 0, goal) bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" if (!shown) user.client.images += bar diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm index f065ccfeab..68d8ebc31f 100644 --- a/code/datums/radiation_wave.dm +++ b/code/datums/radiation_wave.dm @@ -34,7 +34,7 @@ var/strength if(steps>1) - strength = InverseSquareLaw(intensity, max(range_modifier*steps, 1), 1) + strength = INVERSE_SQUARE(intensity, max(range_modifier*steps, 1), 1) else strength = intensity @@ -42,7 +42,7 @@ qdel(src) return - radiate(atoms, Floor(strength)) + radiate(atoms, FLOOR(strength, 1)) check_obstructions(atoms) // reduce our overall strength if there are radiation insulators diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 20d218f767..ec4b81acbe 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -60,8 +60,8 @@ if(istype(L)) //this is probably more safety than actually needed var/vanguard = L.stun_absorption["vanguard"] desc = initial(desc) - desc += "
    [Floor(vanguard["stuns_absorbed"] * 0.1)] seconds of stuns held back.\ - [GLOB.ratvar_awakens ? "":"
    [Floor(min(vanguard["stuns_absorbed"] * 0.025, 20))] seconds of stun will affect you."]" + desc += "
    [FLOOR(vanguard["stuns_absorbed"] * 0.1, 1)] seconds of stuns held back.\ + [GLOB.ratvar_awakens ? "":"
    [FLOOR(min(vanguard["stuns_absorbed"] * 0.025, 20), 1)] seconds of stun will affect you."]" ..() /datum/status_effect/vanguard_shield/Destroy() @@ -87,7 +87,7 @@ var/vanguard = owner.stun_absorption["vanguard"] var/stuns_blocked = 0 if(vanguard) - stuns_blocked = Floor(min(vanguard["stuns_absorbed"] * 0.25, 400)) + stuns_blocked = FLOOR(min(vanguard["stuns_absorbed"] * 0.25, 400), 1) vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply if(owner.stat != DEAD) var/message_to_owner = "You feel your Vanguard quietly fade..." diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 2ea1469481..cc64cc2eb8 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -230,7 +230,7 @@ if(prob(severity * 0.15)) to_chat(owner, "\"[text2ratvar(pick(mania_messages))]\"") owner.playsound_local(get_turf(motor), hum, severity, 1) - owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1 + owner.adjust_drugginess(CLAMP(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1 if(owner.hallucination < 50) owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1 if(owner.dizziness < 50) @@ -310,7 +310,7 @@ var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) var/icon_height = I.Height() bleed_overlay.pixel_x = -owner.pixel_x - bleed_overlay.pixel_y = Floor(icon_height * 0.25) + bleed_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size bleed_underlay.pixel_x = -owner.pixel_x bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 3 diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index c5c813ecfc..9e4bf51d41 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -42,7 +42,7 @@ /mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume) ..() if(exposed_temperature) - adjustFireLoss(Clamp(0.01 * exposed_temperature, 1, 5)) + adjustFireLoss(CLAMP(0.01 * exposed_temperature, 1, 5)) else adjustFireLoss(5) diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4f26563da1..c0516fa2dd 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -153,7 +153,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) B.hud_used.blobpwrdisplay.maptext = "

    " /mob/camera/blob/proc/add_points(points) - blob_points = Clamp(blob_points + points, 0, max_blob_points) + blob_points = CLAMP(blob_points + points, 0, max_blob_points) hud_used.blobpwrdisplay.maptext = "
    [round(blob_points)]
    " /mob/camera/blob/say(message) diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index e5a8c9b6f3..19f9e37319 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -207,7 +207,7 @@ to_chat(cyborg, "You start to charge from the [sigil_name]...") if(!do_after(cyborg, 50, target = src, extra_checks = CALLBACK(src, .proc/cyborg_checks, cyborg, TRUE))) return - var/giving_power = min(Floor(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER + var/giving_power = min(FLOOR(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER if(adjust_clockwork_power(-giving_power)) cyborg.visible_message("[cyborg] glows a brilliant orange!") var/previous_color = cyborg.color diff --git a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm index a5af47ff05..74f7119193 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm @@ -90,7 +90,7 @@ if(amount_temp < 2) to_chat(user, "You need at least 2 floor tiles to convert into power.") return TRUE - if(IsOdd(amount_temp)) + if(ISODD(amount_temp)) amount_temp-- no_delete = TRUE use(amount_temp) @@ -239,7 +239,7 @@ if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \ extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE))) break - obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity) + obj_integrity = CLAMP(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity) adjust_clockwork_power(-repair_values["power_required"]) playsound(src, 'sound/machines/click.ogg', 50, 1) diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm index 5aa626bac5..da1f5965bd 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm @@ -97,7 +97,7 @@ if(ishuman(M.current)) human_servants++ construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders - construct_limit = Clamp(construct_limit, 1, 3) + construct_limit = CLAMP(construct_limit, 1, 3) /datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital() channel_time = initial(channel_time) diff --git a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm index b95d9cc0db..447b077d87 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm @@ -60,4 +60,4 @@ break if(!M) M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR, src) - M.severity = Clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY) + M.severity = CLAMP(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY) diff --git a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm index 9d4667ee9f..e417cbbc32 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm @@ -57,5 +57,5 @@ L.confused = min(L.confused + 15, 50) L.dizziness = min(L.dizziness + 15, 50) if(L.confused >= 25) - L.Knockdown(Floor(L.confused * 0.8)) + L.Knockdown(FLOOR(L.confused * 0.8, 1)) take_damage(max_integrity) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index b7a6580570..4918e94131 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -25,7 +25,7 @@ if (prob(meteorminutes/2)) wavetype = GLOB.meteors_catastrophic - var/ramp_up_final = Clamp(round(meteorminutes/rampupdelta), 1, 10) + var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 908ecd797f..e35eaed9f1 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -353,7 +353,7 @@ var/N = text2num(user_input) if(!N) return - timer_set = Clamp(N,minimum_timer_set,maximum_timer_set) + timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set) . = TRUE if("safety") if(auth && yes_code) diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index cbdc28883f..e9390a3cf5 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -161,7 +161,7 @@ return log_activity("changed greater than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = Clamp(new_filter, 0, 100) + new_filter = CLAMP(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Above"] = new_filter if(href_list["below_filter"]) @@ -171,7 +171,7 @@ return log_activity("changed lesser than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = Clamp(new_filter, 0, 100) + new_filter = CLAMP(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Below"] = new_filter if(href_list["access_filter"]) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 2d1d771203..a4881546cf 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -211,7 +211,7 @@ if("pressure") var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null if(!isnull(target) && !..()) - target = Clamp(target, 0, 50 * ONE_ATMOSPHERE) + target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE) signal.data += list("tag" = output_tag, "set_internal_pressure" = target) . = TRUE radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 9fa196bd46..7bbd545981 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -337,12 +337,12 @@ if(!num) num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null) if(num) - radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1) + radduration = WRAP(num, 1, RADIATION_DURATION_MAX+1) if("setstrength") if(!num) num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null) if(num) - radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1) + radstrength = WRAP(num, 1, RADIATION_STRENGTH_MAX+1) if("screen") current_screen = href_list["text"] if("rejuv") @@ -353,13 +353,13 @@ if("setbufferlabel") var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null) if(num && text) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) buffer_slot["label"] = text if("setbuffer") if(num && viable_occupant) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) buffer[num] = list( "label"="Buffer[num]:[viable_occupant.real_name]", "UI"=viable_occupant.dna.uni_identity, @@ -370,7 +370,7 @@ ) if("clearbuffer") if(num) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) buffer_slot.Cut() @@ -387,7 +387,7 @@ apply_buffer(SCANNER_ACTION_MIXED,num) if("injector") if(num && injectorready < world.time) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) var/obj/item/dnainjector/timed/I @@ -436,11 +436,11 @@ injectorready = world.time + INJECTOR_TIMEOUT if("loaddisk") if(num && diskette && diskette.fields) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) buffer[num] = diskette.fields.Copy() if("savedisk") if(num && diskette && !diskette.read_only) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) diskette.name = "data disk \[[buffer_slot["label"]]\]" @@ -454,8 +454,8 @@ delayed_action = list("action"=text2num(href_list["delayaction"]),"buffer"=num) if("pulseui","pulsese") if(num && viable_occupant && connected) - radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1) - radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1) + radduration = WRAP(radduration, 1, RADIATION_DURATION_MAX+1) + radstrength = WRAP(radstrength, 1, RADIATION_STRENGTH_MAX+1) var/locked_state = connected.locked connected.locked = TRUE @@ -471,7 +471,7 @@ switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage if("pulseui") var/len = length(viable_occupant.dna.uni_identity) - num = Wrap(num, 1, len+1) + num = WRAP(num, 1, len+1) num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low var/block = round((num-1)/DNA_BLOCK_SIZE)+1 @@ -487,7 +487,7 @@ viable_occupant.updateappearance(mutations_overlay_update=1) if("pulsese") var/len = length(viable_occupant.dna.struc_enzymes) - num = Wrap(num, 1, len+1) + num = WRAP(num, 1, len+1) num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) var/block = round((num-1)/DNA_BLOCK_SIZE)+1 @@ -518,10 +518,11 @@ ran = round(ran) //negative, so floor it else ran = -round(-ran) //positive, so ceiling it - return num2hex(Wrap(hex2num(input)+ran, 0, 16**length), length) + return num2hex(WRAP(hex2num(input)+ran, 0, 16**length), length) -/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks) - return Wrap(round(position_we_were_supposed_to_hit + gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1) +/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position, radduration, number_of_blocks) + var/val = round(gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration) + position, 1) + return WRAP(val, 1, number_of_blocks+1) /obj/machinery/computer/scan_consolenew/proc/get_viable_occupant() var/mob/living/carbon/viable_occupant = null @@ -532,7 +533,7 @@ return viable_occupant /obj/machinery/computer/scan_consolenew/proc/apply_buffer(action,buffer_num) - buffer_num = Clamp(buffer_num, 1, NUMBER_OF_BUFFERS) + buffer_num = CLAMP(buffer_num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[buffer_num] var/mob/living/carbon/viable_occupant = get_viable_occupant() if(istype(buffer_slot)) diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm index 36da1288a9..2419dd2299 100644 --- a/code/game/machinery/computer/gulag_teleporter.dm +++ b/code/game/machinery/computer/gulag_teleporter.dm @@ -106,7 +106,7 @@ return if(!new_goal) new_goal = default_goal - id.goal = Clamp(new_goal, 0, 1000) //maximum 1000 points + id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points if("toggle_open") if(teleporter.locked) to_chat(usr, "The teleporter is locked") diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 959253036b..6670bfbfa7 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,8 +154,14 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() +<<<<<<< HEAD var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len danger = Ceiling(danger, 10) +======= + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len + danger = CEILING(danger, 10) +>>>>>>> 25080ff... defines math (#33498) scaleTC(danger) /obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index f0e1e8a18a..b9a2a68b34 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -33,7 +33,7 @@ to_chat(user, "You begin repairing [src]...") playsound(loc, WT.usesound, 40, 1) if(do_after(user, 40*I.toolspeed, target = src)) - obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity) + obj_integrity = CLAMP(obj_integrity + 20, 0, max_integrity) else return ..() diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4c0d4a1804..a622f0af3d 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -142,7 +142,7 @@ . /= 10 /obj/machinery/door_timer/proc/set_timer(value) - var/new_time = Clamp(value,0,MAX_TIMER) + var/new_time = CLAMP(value,0,MAX_TIMER) . = new_time == timer_duration //return 1 on no change timer_duration = new_time diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 06cdfcda7d..a67ce24c9c 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -53,9 +53,9 @@ new /obj/item/pipe_meter(loc) wait = world.time + 15 if(href_list["layer_up"]) - piping_layer = Clamp(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = CLAMP(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if(href_list["layer_down"]) - piping_layer = Clamp(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = CLAMP(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) return /obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 9356314973..cdbdb195cc 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -256,7 +256,7 @@ use_stored_power(50) /obj/machinery/shieldwallgen/proc/use_stored_power(amount) - power = Clamp(power - amount, 0, maximum_stored_power) + power = CLAMP(power - amount, 0, maximum_stored_power) update_activity() /obj/machinery/shieldwallgen/proc/update_activity() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index b45b393ab2..f7a18ff246 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -121,7 +121,7 @@ settableTemperatureRange = cap * 30 efficiency = (cap + 1) * 10000 - targetTemperature = Clamp(targetTemperature, + targetTemperature = CLAMP(targetTemperature, max(settableTemperatureMedian - settableTemperatureRange, TCMB), settableTemperatureMedian + settableTemperatureRange) @@ -223,7 +223,7 @@ target= text2num(target) + T0C . = TRUE if(.) - targetTemperature = Clamp(round(target), + targetTemperature = CLAMP(round(target), max(settableTemperatureMedian - settableTemperatureRange, TCMB), settableTemperatureMedian + settableTemperatureRange) if("eject") diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 5b510d965e..528faba57f 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -205,7 +205,7 @@ /obj/machinery/syndicatebomb/proc/settings(mob/user) var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station - timer_set = Clamp(new_timer, minimum_timer, maximum_timer) + timer_set = CLAMP(new_timer, minimum_timer, maximum_timer) loc.visible_message("[icon2html(src, viewers(src))] timer set for [timer_set] seconds.") if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user)) if(defused || active) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index bfa89db368..d3598d4866 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -175,7 +175,7 @@ for(var/datum/data/vending_product/machine_content in machine) if(refill.charges[charge_type] == 0) break - var/restock = Ceiling(((machine_content.max_amount - machine_content.amount)/to_restock)*tmp_charges) + var/restock = CEILING(((machine_content.max_amount - machine_content.amount)/to_restock)*tmp_charges, 1) if(restock > refill.charges[charge_type]) restock = refill.charges[charge_type] machine_content.amount += restock diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 1766a8cc3a..6ef98120f5 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -188,7 +188,7 @@ return queue.len /obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index) - if(!isnum(index) || !IsInteger(index) || !istype(queue) || (index<1 || index>queue.len)) + if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>queue.len)) return FALSE queue.Cut(index,++index) return TRUE @@ -375,8 +375,8 @@ if(href_list["queue_move"] && href_list["index"]) var/index = afilter.getNum("index") var/new_index = index + afilter.getNum("queue_move") - if(isnum(index) && isnum(new_index) && IsInteger(index) && IsInteger(new_index)) - if(IsInRange(new_index,1,queue.len)) + if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index)) + if(ISINRANGE(new_index,1,queue.len)) queue.Swap(index,new_index) return update_queue_on_page() if(href_list["clear_queue"]) diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 5688214044..a7115abd1d 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -94,7 +94,7 @@ /obj/mecha/working/ripley/mining/Initialize() . = ..() if(cell) - cell.charge = Floor(cell.charge * 0.25) //Starts at very low charge + cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge if(prob(70)) //Maybe add a drill if(prob(15)) //Possible diamond drill... Feeling lucky? var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 04737f2e4c..70a6f1bdba 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -27,8 +27,13 @@ aSignal.name = "[name] core" aSignal.code = rand(1,100) +<<<<<<< HEAD aSignal.frequency = rand(1200, 1599) if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven! +======= + aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ) + if(ISMULTIPLE(aSignal.frequency, 2))//signaller frequencies are always uneven! +>>>>>>> 25080ff... defines math (#33498) aSignal.frequency++ if(new_lifespan) diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 8ac9643c39..11336cd06a 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -187,7 +187,7 @@ /obj/effect/chrono_field/update_icon() var/ttk_frame = 1 - (tickstokill / initial(tickstokill)) - ttk_frame = Clamp(Ceiling(ttk_frame * CHRONO_FRAME_COUNT), 1, CHRONO_FRAME_COUNT) + ttk_frame = CLAMP(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) if(ttk_frame != RPpos) RPpos = ttk_frame mob_underlay.icon_state = "frame[RPpos]" diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index bbeed24168..afed9c4b4c 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -69,7 +69,7 @@ if(powered) //so it doesn't show charge if it's unpowered if(cell) var/ratio = cell.charge / cell.maxcharge - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)]-charge[ratio]") /obj/item/defibrillator/CheckParts(list/parts_list) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index cdd95a2f71..4ea91ccccf 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -169,7 +169,7 @@ // Negative numbers will subtract /obj/item/device/lightreplacer/proc/AddUses(amount = 1) - uses = Clamp(uses + amount, 0, max_uses) + uses = CLAMP(uses + amount, 0, max_uses) /obj/item/device/lightreplacer/proc/AddShards(amount = 1, user) bulb_shards += amount diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 338f113afb..5afc8602ff 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -228,7 +228,7 @@ effective or pretty fucking useless. charge = max(0,charge - 25)//Quick decrease in light else charge = min(max_charge,charge + 50) //Charge in the dark - animate(user,alpha = Clamp(255 - charge,0,255),time = 10) + animate(user,alpha = CLAMP(255 - charge,0,255),time = 10) /obj/item/device/jammer diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 334be4a645..e14363a1c1 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -166,7 +166,7 @@ /obj/item/dice/proc/diceroll(mob/user) result = rand(1, sides) if(rigged && result != rigged) - if(prob(Clamp(1/(sides - 1) * 100, 25, 80))) + if(prob(CLAMP(1/(sides - 1) * 100, 25, 80))) result = rigged var/fake_result = rand(1, sides)//Daredevil isn't as good as he used to be var/comment = "" diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index dd0d397e81..0375e5529e 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -87,7 +87,7 @@ return var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_held_item() == src) - newtime = Clamp(newtime, 10, 60000) + newtime = CLAMP(newtime, 10, 60000) det_time = newtime to_chat(user, "Timer set for [det_time] seconds.") @@ -204,7 +204,7 @@ /obj/item/grenade/plastic/c4/attack_self(mob/user) var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_held_item() == src) - newtime = Clamp(newtime, 10, 60000) + newtime = CLAMP(newtime, 10, 60000) timer = newtime to_chat(user, "Timer set for [timer] seconds.") diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index 98121f7772..d13d6cc1dd 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -75,7 +75,7 @@ drowse() return if(bloodthirst < HIS_GRACE_CONSUME_OWNER) - adjust_bloodthirst(1 + Floor(LAZYLEN(contents) * 0.5)) //Maybe adjust this? + adjust_bloodthirst(1 + FLOOR(LAZYLEN(contents) * 0.5, 1)) //Maybe adjust this? else adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all. var/mob/living/master = get_atom_on_turf(src, /mob/living) @@ -164,9 +164,9 @@ /obj/item/his_grace/proc/adjust_bloodthirst(amt) prev_bloodthirst = bloodthirst if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER) - bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) + bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) else - bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) + bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) update_stats() /obj/item/his_grace/proc/update_stats() diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 9bf0b949c0..8baeee3550 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -198,8 +198,8 @@ return target var/x_o = (target.x - starting.x) var/y_o = (target.y - starting.y) - var/new_x = Clamp((starting.x + (x_o * range_multiplier)), 0, world.maxx) - var/new_y = Clamp((starting.y + (y_o * range_multiplier)), 0, world.maxy) + var/new_x = CLAMP((starting.x + (x_o * range_multiplier)), 0, world.maxx) + var/new_y = CLAMP((starting.y + (y_o * range_multiplier)), 0, world.maxy) var/turf/newtarget = locate(new_x, new_y, starting.z) return newtarget diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e4485266b5..97e6752efb 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -616,7 +616,7 @@ continue usage += projectile_tick_speed_ecost usage += (tracked[I] * projectile_damage_tick_ecost_coefficient) - energy = Clamp(energy - usage, 0, maxenergy) + energy = CLAMP(energy - usage, 0, maxenergy) if(energy <= 0) deactivate_field() visible_message("[src] blinks \"ENERGY DEPLETED\".") @@ -626,7 +626,7 @@ if(iscyborg(host.loc)) host = host.loc else - energy = Clamp(energy + energy_recharge, 0, maxenergy) + energy = CLAMP(energy + energy_recharge, 0, maxenergy) return if((host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy)) host.cell.use(energy_recharge*energy_recharge_cyborg_drain_coefficient) diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm index fb25cb1d76..93056adc99 100644 --- a/code/game/objects/items/sharpener.dm +++ b/code/game/objects/items/sharpener.dm @@ -35,14 +35,14 @@ if(TH.force_wielded > initial(TH.force_wielded)) to_chat(user, "[TH] has already been refined before. It cannot be sharpened further!") return - TH.force_wielded = Clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay + TH.force_wielded = CLAMP(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay if(I.force > initial(I.force)) to_chat(user, "[I] has already been refined before. It cannot be sharpened further!") return user.visible_message("[user] sharpens [I] with [src]!", "You sharpen [I], making it much more deadly than before.") I.sharpness = IS_SHARP_ACCURATE - I.force = Clamp(I.force + increment, 0, max) - I.throwforce = Clamp(I.throwforce + increment, 0, max) + I.force = CLAMP(I.force + increment, 0, max) + I.throwforce = CLAMP(I.throwforce + increment, 0, max) I.name = "[prefix] [I.name]" name = "worn out [name]" desc = "[desc] At least, it used to." diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1faad3462b..7cea6d71e8 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -37,9 +37,9 @@ /obj/item/stack/proc/update_weight() if(amount <= (max_amount * (1/3))) - w_class = Clamp(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) + w_class = CLAMP(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) else if (amount <= (max_amount * (2/3))) - w_class = Clamp(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) + w_class = CLAMP(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) else w_class = full_w_class diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 3d1c091a2b..0109b67b00 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -194,7 +194,7 @@ pressure = text2num(pressure) . = TRUE if(.) - distribute_pressure = Clamp(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) + distribute_pressure = CLAMP(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) /obj/item/tank/remove_air(amount) return air_contents.remove(amount) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 1c20c95e93..415cd02585 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD #define WELDER_FUEL_BURN_INTERVAL 13 /obj/item/weldingtool name = "welding tool" @@ -336,4 +337,350 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) +======= +#define WELDER_FUEL_BURN_INTERVAL 13 +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by Nanotrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = CEILING(ratio*4, 1) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + . = ..() + update_icon() + +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) + return + if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) + else + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) + +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) + + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE + else + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER_1 + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + +>>>>>>> 25080ff... defines math (#33498) #undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index ad5f69672b..ff8bcc3e1e 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -198,7 +198,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(T.intact && level == 1) //fire can't damage things hidden below the floor. return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) - take_damage(Clamp(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) + take_damage(CLAMP(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE)) resistance_flags |= ON_FIRE SSfire_burning.processing[src] = src diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index 04d7f983c0..2735bd7e81 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -129,7 +129,7 @@ if(burn_time_remaining() < MAXIMUM_BURN_TIMER) flame_expiry_timer = world.time + MAXIMUM_BURN_TIMER else - fuel_added = Clamp(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) + fuel_added = CLAMP(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) /obj/structure/fireplace/proc/burn_time_remaining() if(lit) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 009bbcd70e..a7bfb92c45 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -30,7 +30,7 @@ return var/ratio = obj_integrity / max_integrity - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 if(smooth) queue_smooth(src) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c0dcd866d8..306d3d0b84 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -67,7 +67,7 @@ resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/clockwork/ratvar_act() - if(IsOdd(x+y)) + if(ISODD(x+y)) icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi' pixel_x = -9 pixel_y = -9 @@ -124,7 +124,7 @@ resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/catwalk/clockwork/ratvar_act() - if(IsOdd(x+y)) + if(ISODD(x+y)) icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi' pixel_x = -9 pixel_y = -9 diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 1265594eff..a73824ca2b 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -119,7 +119,7 @@ else cur_oct[cur_note] = text2num(ni) if(user.dizziness > 0 && prob(user.dizziness / 2)) - cur_note = Clamp(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7) + cur_note = CLAMP(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7) if(user.dizziness > 0 && prob(user.dizziness / 5)) if(prob(30)) cur_acc[cur_note] = "#" diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index e47afd53d4..1ae513f847 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -165,7 +165,7 @@ to_chat(user, "You can't do that right now!") return if(!isnull(new_angle)) - setAngle(NORM_ROT(new_angle)) + setAngle(SIMPLIFY_DEGREES(new_angle)) return TRUE /obj/structure/reflector/AltClick(mob/user) @@ -197,16 +197,12 @@ anchored = TRUE /obj/structure/reflector/single/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) - var/incidence = get_angle_of_incidence(rotation_angle, P.Angle) - var/incidence_norm = get_angle_of_incidence(rotation_angle, P.Angle, FALSE) - if((incidence_norm > -90) && (incidence_norm < 90)) + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, P.Angle) + var/norm_inc = WRAP(incidence, -90, 90) + var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180) + if(ISINRANGE_EX(norm_inc, -90, 90)) return FALSE - var/new_angle_s = rotation_angle + incidence - while(new_angle_s > 180) // Translate to regular projectile degrees - new_angle_s -= 360 - while(new_angle_s < -180) - new_angle_s += 360 - P.Angle = new_angle_s + P.Angle = new_angle return ..() //DOUBLE @@ -228,17 +224,12 @@ anchored = TRUE /obj/structure/reflector/double/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) - var/incidence = get_angle_of_incidence(rotation_angle, P.Angle) - var/incidence_norm = get_angle_of_incidence(rotation_angle, P.Angle, FALSE) - var/invert = ((incidence_norm > -90) && (incidence_norm < 90)) - var/new_angle_s = rotation_angle + incidence - if(invert) - new_angle_s += 180 - while(new_angle_s > 180) // Translate to regular projectile degrees - new_angle_s -= 360 - while(new_angle_s < -180) - new_angle_s += 360 - P.Angle = new_angle_s + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, P.Angle) + var/norm_inc = WRAP(incidence, -90, 90) + var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180) + if(ISINRANGE_EX(norm_inc, -90, 90)) + new_angle += 180 + P.Angle = new_angle return ..() //BOX diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 26582515f8..65d25055f8 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -134,8 +134,8 @@ if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) return 1 else return ..() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2b9494c535..5380f0ca20 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -380,7 +380,7 @@ return var/ratio = obj_integrity / max_integrity - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 if(smooth) queue_smooth(src) diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index b2ab28dcae..1419036d07 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -188,7 +188,7 @@ break var/list/L = list(45) - if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels. + if(ISODD(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels. L += -45 // Expand the edges of our tunnel diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 337bb051a8..00377e4f3f 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -54,7 +54,7 @@ var/turf/p_turf = get_turf(P) var/face_direction = get_dir(src, p_turf) var/face_angle = dir2angle(face_direction) - var/incidence_s = get_angle_of_incidence(face_angle, P.Angle) + var/incidence_s = WRAP(GET_ANGLE_OF_INCIDENCE(face_angle, P.Angle), -90, 90) var/new_angle = face_angle + incidence_s var/new_angle_s = new_angle while(new_angle_s > 180) // Translate to regular projectile degrees diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index b7ec8c36b5..87024f7832 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -92,7 +92,7 @@ var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num if(isnull(new_volume)) return - new_volume = Clamp(new_volume, 0, 100) + new_volume = CLAMP(new_volume, 0, 100) sound_volume = new_volume to_chat(user, "Volume set to [sound_volume]%.") if(href_list["edit_mode"]) @@ -115,7 +115,7 @@ var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num if(isnull(new_radius)) return - new_radius = Clamp(new_radius, 0, 127) + new_radius = CLAMP(new_radius, 0, 127) play_radius = new_radius to_chat(user, "Audible radius set to [play_radius].") if(href_list["play"]) diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 587bd6b26c..38316c904f 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -220,7 +220,7 @@ var/nsd = CONFIG_GET(number/note_stale_days) var/nfd = CONFIG_GET(number/note_fresh_days) if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd) - var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) + var/alpha = CLAMP(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) if (alpha < 100) if (alpha <= 15) if (skipped) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index de8dff1518..0cec1ef3a8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1892,7 +1892,7 @@ return var/list/offset = splittext(href_list["offset"],",") - var/number = Clamp(text2num(href_list["object_count"]), 1, 100) + var/number = CLAMP(text2num(href_list["object_count"]), 1, 100) var/X = offset.len > 0 ? text2num(offset[1]) : 0 var/Y = offset.len > 1 ? text2num(offset[2]) : 0 var/Z = offset.len > 2 ? text2num(offset[3]) : 0 diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 9e9e727b39..0421807abe 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -435,7 +435,7 @@ else if(expression[start + 1] == "\[" && islist(v)) var/list/L = v var/index = SDQL_expression(source, expression[start + 2]) - if(isnum(index) && (!IsInteger(index) || L.len < index)) + if(isnum(index) && (!ISINTEGER(index) || L.len < index)) to_chat(usr, "Invalid list index: [index]") return null return L[index] diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 6b1edf7709..29d95c639f 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -12,7 +12,7 @@ var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num if(!vol) return - vol = Clamp(vol, 1, 100) + vol = CLAMP(vol, 1, 100) var/sound/admin_sound = new() admin_sound.file = S diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index f8204947f1..6f72724e1e 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -185,13 +185,13 @@ Acts like a normal vent, but has an input AND output. pump_direction = 1 if("set_input_pressure" in signal.data) - input_pressure_min = Clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) + input_pressure_min = CLAMP(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) if("set_output_pressure" in signal.data) - output_pressure_max = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + output_pressure_max = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if("set_external_pressure" in signal.data) - external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if("status" in signal.data) spawn(2) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 86c5375d07..ef4e487efd 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -127,7 +127,7 @@ Passive gate is similar to the regular pump except: pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() @@ -149,7 +149,7 @@ Passive gate is similar to the regular pump except: on = !on if("set_output_pressure" in signal.data) - target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 97bba0e534..898a8157ae 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -133,9 +133,14 @@ Thus, the two variables affect pump operation are set in New(): pressure = text2num(pressure) . = TRUE if(.) +<<<<<<< HEAD target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") +======= + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) +>>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/pump/atmosinit() @@ -156,7 +161,7 @@ Thus, the two variables affect pump operation are set in New(): on = !on if("set_output_pressure" in signal.data) - target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index b154c0d3e4..bdc1ae15a3 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -133,9 +133,14 @@ Thus, the two variables affect pump operation are set in New(): rate = text2num(rate) . = TRUE if(.) +<<<<<<< HEAD transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") +======= + transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) + investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) +>>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal) @@ -152,7 +157,7 @@ Thus, the two variables affect pump operation are set in New(): if("set_transfer_rate" in signal.data) var/datum/gas_mixture/air1 = AIR1 - transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume) + transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4baeb3dd3e..9a8034064c 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -162,7 +162,7 @@ pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("filter") filter_type = null diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index b706cd3cd9..b15df59662 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -152,7 +152,7 @@ pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("node1") var/value = text2num(params["concentration"]) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 37bfb5d952..64e6e56504 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -131,7 +131,7 @@ if("set_volume_rate" in signal.data) var/number = text2num(signal.data["set_volume_rate"]) var/datum/gas_mixture/air_contents = AIR1 - volume_rate = Clamp(number, 0, air_contents.volume) + volume_rate = CLAMP(number, 0, air_contents.volume) if("status" in signal.data) spawn(2) @@ -180,7 +180,7 @@ rate = text2num(rate) . = TRUE if(.) - volume_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) + volume_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) investigate_log("was set to [volume_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() broadcast_status() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index fa336c7a34..8d34d5adfa 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -153,7 +153,7 @@ target = text2num(target) . = TRUE if(.) - target_temperature = Clamp(target, min_temperature, max_temperature) + target_temperature = CLAMP(target, min_temperature, max_temperature) investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index a05a13217d..2c9a308ec9 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -244,10 +244,10 @@ pump_direction = text2num(signal.data["direction"]) if("set_internal_pressure" in signal.data) - internal_pressure_bound = Clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = CLAMP(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) if("set_external_pressure" in signal.data) - external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if("reset_external_pressure" in signal.data) external_pressure_bound = ONE_ATMOSPHERE @@ -256,10 +256,10 @@ internal_pressure_bound = 0 if("adjust_internal_pressure" in signal.data) - internal_pressure_bound = Clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = CLAMP(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) if("adjust_external_pressure" in signal.data) - external_pressure_bound = Clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) if("init" in signal.data) name = signal.data["init"] diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index fee00baf50..d2f85c7667 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -121,7 +121,7 @@ if(initialize_directions & dir) return ..() if((NORTH|EAST) & dir) - user.ventcrawl_layer = Clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if((SOUTH|WEST) & dir) - user.ventcrawl_layer = Clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.") diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 585b6e896a..ddc562bbb7 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -411,7 +411,7 @@ pressure = text2num(pressure) . = TRUE if(.) - release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure) + release_pressure = CLAMP(round(pressure), can_min_release_pressure, can_max_release_pressure) investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("valve") var/logmsg @@ -455,7 +455,7 @@ var/N = text2num(user_input) if(!N) return - timer_set = Clamp(N,minimum_timer_set,maximum_timer_set) + timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set) log_admin("[key_name(usr)] has activated a prototype valve timer") . = TRUE if("toggle_timer") diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 3f2bceaa04..807759e43c 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -131,7 +131,7 @@ pressure = text2num(pressure) . = TRUE if(.) - pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) + pump.target_pressure = CLAMP(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("eject") if(holding) diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index 92b953e7b2..b4c0aa350d 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -86,7 +86,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they /datum/export/process() ..() - cost *= GLOB.E**(k_elasticity * (1/30)) + cost *= NUM_E**(k_elasticity * (1/30)) if(cost > init_cost) cost = init_cost @@ -94,7 +94,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they /datum/export/proc/get_cost(obj/O, contr = 0, emag = 0) var/amount = get_amount(O, contr, emag) if(k_elasticity!=0) - return round((cost/k_elasticity) * (1 - GLOB.E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function + return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function else return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0 @@ -131,7 +131,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they else total_amount += amount - cost *= GLOB.E**(-1*k_elasticity*amount) //marginal cost modifier + cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]")) // Total printout for the cargo console. diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index cb1712dff5..f356d6c057 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -152,7 +152,7 @@ GLOBAL_LIST(external_rsc_urls) #if (PRELOAD_RSC == 0) var/static/next_external_rsc = 0 if(external_rsc_urls && external_rsc_urls.len) - next_external_rsc = Wrap(next_external_rsc+1, 1, external_rsc_urls.len+1) + next_external_rsc = WRAP(next_external_rsc+1, 1, external_rsc_urls.len+1) preload_rsc = external_rsc_urls[next_external_rsc] #endif @@ -673,6 +673,16 @@ GLOBAL_LIST(external_rsc_urls) return TRUE . = ..() +<<<<<<< HEAD +======= +/client/proc/rescale_view(change, min, max) + var/viewscale = getviewsize(view) + var/x = viewscale[1] + var/y = viewscale[2] + x = CLAMP(x+change, min, max) + y = CLAMP(y+change, min,max) + change_view("[x]x[y]") +>>>>>>> 25080ff... defines math (#33498) /client/proc/change_view(new_size) if (isnull(new_size)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 175a23c91e..0469f31aba 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1596,12 +1596,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) toggles ^= MIDROUND_ANTAG if("parallaxup") - parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) if("parallaxdown") - parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 7e4b0bad89..681ba3e789 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -164,7 +164,7 @@ assembled = TRUE boost_chargerate *= cap boost_drain -= manip - powersetting_high = Clamp(laser, 0, 3) + powersetting_high = CLAMP(laser, 0, 3) emp_disable_threshold = bin*1.25 stabilizer_decay_amount = scan*3.5 airbrake_decay_amount = manip*8 @@ -194,15 +194,15 @@ /obj/item/device/flightpack/proc/adjust_momentum(amountx, amounty, reduce_amount_total = 0) if(reduce_amount_total != 0) if(momentum_x > 0) - momentum_x = Clamp(momentum_x - reduce_amount_total, 0, momentum_max) + momentum_x = CLAMP(momentum_x - reduce_amount_total, 0, momentum_max) else if(momentum_x < 0) - momentum_x = Clamp(momentum_x + reduce_amount_total, -momentum_max, 0) + momentum_x = CLAMP(momentum_x + reduce_amount_total, -momentum_max, 0) if(momentum_y > 0) - momentum_y = Clamp(momentum_y - reduce_amount_total, 0, momentum_max) + momentum_y = CLAMP(momentum_y - reduce_amount_total, 0, momentum_max) else if(momentum_y < 0) - momentum_y = Clamp(momentum_y + reduce_amount_total, -momentum_max, 0) - momentum_x = Clamp(momentum_x + amountx, -momentum_max, momentum_max) - momentum_y = Clamp(momentum_y + amounty, -momentum_max, momentum_max) + momentum_y = CLAMP(momentum_y + reduce_amount_total, -momentum_max, 0) + momentum_x = CLAMP(momentum_x + amountx, -momentum_max, momentum_max) + momentum_y = CLAMP(momentum_y + amounty, -momentum_max, momentum_max) calculate_momentum_speed() /obj/item/device/flightpack/intercept_user_move(dir, mob, newLoc, oldLoc) @@ -314,7 +314,7 @@ /obj/item/device/flightpack/proc/handle_damage() if(emp_damage) - emp_damage = Clamp(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10) + emp_damage = CLAMP(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10) if(emp_damage >= emp_disable_threshold) emp_disabled = TRUE if(emp_disabled && (emp_damage <= 0.5)) @@ -347,11 +347,11 @@ /obj/item/device/flightpack/proc/handle_boost() if(boost) - boost_charge = Clamp(boost_charge-boost_drain, 0, boost_maxcharge) + boost_charge = CLAMP(boost_charge-boost_drain, 0, boost_maxcharge) if(boost_charge < 1) deactivate_booster() if(boost_charge < boost_maxcharge) - boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge) + boost_charge = CLAMP(boost_charge+boost_chargerate, 0, boost_maxcharge) /obj/item/device/flightpack/proc/cycle_power() powersetting < powersetting_high? (powersetting++) : (powersetting = 1) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index cc1df785b5..73d7ee04e8 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -654,7 +654,7 @@ /obj/item/clothing/suit/space/hardsuit/shielded/process() if(world.time > recharge_cooldown && current_charges < max_charges) - current_charges = Clamp((current_charges + recharge_rate), 0, max_charges) + current_charges = CLAMP((current_charges + recharge_rate), 0, max_charges) playsound(loc, 'sound/magic/charge.ogg', 50, 1) if(current_charges == max_charges) playsound(loc, 'sound/machines/ding.ogg', 50, 1) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a5b23623f2..471dad12d7 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -29,8 +29,8 @@ /datum/round_event_control/New() if(config && !wizardevent) // Magic is unaffected by configs - earliest_start = Ceiling(earliest_start * CONFIG_GET(number/events_min_time_mul)) - min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul)) + earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1) + min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1) /datum/round_event_control/wizard wizardevent = 1 diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index e898729f2d..c2f98be8d5 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -67,12 +67,12 @@ kill() return - if(IsMultiple(activeFor, 4)) + if(ISMULTIPLE(activeFor, 4)) var/obj/machinery/vending/rebel = pick(vendingMachines) vendingMachines.Remove(rebel) infectedMachines.Add(rebel) rebel.shut_up = 0 rebel.shoot_inventory = 1 - if(IsMultiple(activeFor, 8)) + if(ISMULTIPLE(activeFor, 8)) originMachine.speak(pick(rampant_speeches)) \ No newline at end of file diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index eb7625e08c..1ade939ad3 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -18,7 +18,16 @@ announceWhen = rand(15, 30) /datum/round_event/disease_outbreak/start() +<<<<<<< HEAD if(!virus_type) +======= + var/advanced_virus = FALSE + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + if(prob(20 + (10 * max_severity))) + advanced_virus = TRUE + + if(!virus_type && !advanced_virus) +>>>>>>> 25080ff... defines math (#33498) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index 35eb02f082..798bcf82dd 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -49,7 +49,7 @@ priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg') /datum/round_event/meteor_wave/tick() - if(IsMultiple(activeFor, 3)) + if(ISMULTIPLE(activeFor, 3)) spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm /datum/round_event_control/meteor_wave/threatening diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index 7e17124d59..55d9e69f71 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -64,7 +64,7 @@ T = safepick(get_area_turfs(pick(station_areas))) hostiles_spawn += T - next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses) + next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1) /datum/round_event/portal_storm/announce(fake) set waitfor = 0 @@ -117,14 +117,14 @@ /datum/round_event/portal_storm/proc/spawn_hostile() if(!hostile_types || !hostile_types.len) return 0 - return IsMultiple(activeFor, 2) + return ISMULTIPLE(activeFor, 2) /datum/round_event/portal_storm/proc/spawn_boss() if(!boss_types || !boss_types.len) return 0 if(activeFor == next_boss_spawn) - next_boss_spawn += Ceiling(number_of_hostiles / number_of_bosses) + next_boss_spawn += CEILING(number_of_hostiles / number_of_bosses, 1) return 1 /datum/round_event/portal_storm/proc/time_to_end() diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 8573a84c9b..c2be28fb21 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -123,7 +123,7 @@ break if(href_list["portion"]) - portion = Clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50) + portion = CLAMP(input("How much drink do you want to dispense per glass?") as num, 0, 50) if(href_list["pour"] || href_list["m_pour"]) if(glasses-- <= 0) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 82ba8ab405..6ef8e5e4e9 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -124,7 +124,7 @@ return else bomb_timer = input(user, "Set the [bomb] timer from [BOMB_TIMER_MIN] to [BOMB_TIMER_MAX].", bomb, bomb_timer) as num - bomb_timer = Clamp(Ceiling(bomb_timer / 2), BOMB_TIMER_MIN, BOMB_TIMER_MAX) + bomb_timer = CLAMP(CEILING(bomb_timer / 2, 1), BOMB_TIMER_MIN, BOMB_TIMER_MAX) bomb_defused = FALSE var/message = "[ADMIN_LOOKUPFLW(user)] has trapped a [src] with [bomb] set to [bomb_timer * 2] seconds." diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 5bfcb9963d..0832f372c8 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -132,7 +132,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic /datum/chatOutput/proc/setMusicVolume(volume = "") if(volume) - adminMusicVolume = Clamp(text2num(volume), 0, 100) + adminMusicVolume = CLAMP(text2num(volume), 0, 100) //Sends client connection details to the chat to handle and save /datum/chatOutput/proc/sendClientData() diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index bd0215138a..d9c36ae0fd 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -42,7 +42,7 @@ for(var/obj/item/stock_parts/micro_laser/ML in component_parts) var/wratemod = ML.rating * 2.5 - min_wrate = Floor(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low + min_wrate = FLOOR(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low for(var/obj/item/circuitboard/machine/plantgenes/vaultcheck in component_parts) if(istype(vaultcheck, /obj/item/circuitboard/machine/plantgenes/vault)) // DUMB BOTANY TUTS diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d003f40d4a..df2b07113a 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -36,7 +36,7 @@ for(var/datum/plant_gene/trait/T in seed.genes) T.on_new(src, loc) seed.prepare_result(src) - transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency! + transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency! add_juice() diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 59af735b01..1a3db5ef03 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -154,8 +154,8 @@ if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) else return ..() diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index a77808f006..b0bd44ac8a 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -28,7 +28,7 @@ if(istype(src, seed.product)) // no adding reagents if it is just a trash item seed.prepare_result(src) - transform *= TransformUsingVariable(seed.potency, 100, 0.5) + transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 add_juice() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 9eafcec71b..4fd840082b 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -881,26 +881,26 @@ /// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// /obj/machinery/hydroponics/proc/adjustNutri(adjustamt) - nutrilevel = Clamp(nutrilevel + adjustamt, 0, maxnutri) + nutrilevel = CLAMP(nutrilevel + adjustamt, 0, maxnutri) /obj/machinery/hydroponics/proc/adjustWater(adjustamt) - waterlevel = Clamp(waterlevel + adjustamt, 0, maxwater) + waterlevel = CLAMP(waterlevel + adjustamt, 0, maxwater) if(adjustamt>0) adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration. /obj/machinery/hydroponics/proc/adjustHealth(adjustamt) if(myseed && !dead) - plant_health = Clamp(plant_health + adjustamt, 0, myseed.endurance) + plant_health = CLAMP(plant_health + adjustamt, 0, myseed.endurance) /obj/machinery/hydroponics/proc/adjustToxic(adjustamt) - toxic = Clamp(toxic + adjustamt, 0, 100) + toxic = CLAMP(toxic + adjustamt, 0, 100) /obj/machinery/hydroponics/proc/adjustPests(adjustamt) - pestlevel = Clamp(pestlevel + adjustamt, 0, 10) + pestlevel = CLAMP(pestlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/adjustWeeds(adjustamt) - weedlevel = Clamp(weedlevel + adjustamt, 0, 10) + weedlevel = CLAMP(weedlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index aa35b4ae07..56f80c548d 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -170,7 +170,7 @@ /// Setters procs /// /obj/item/seeds/proc/adjust_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = Clamp(yield + adjustamt, 0, 10) + yield = CLAMP(yield + adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -179,39 +179,39 @@ C.value = yield /obj/item/seeds/proc/adjust_lifespan(adjustamt) - lifespan = Clamp(lifespan + adjustamt, 10, 100) + lifespan = CLAMP(lifespan + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/adjust_endurance(adjustamt) - endurance = Clamp(endurance + adjustamt, 10, 100) + endurance = CLAMP(endurance + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/adjust_production(adjustamt) if(yield != -1) - production = Clamp(production + adjustamt, 1, 10) + production = CLAMP(production + adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/adjust_potency(adjustamt) if(potency != -1) - potency = Clamp(potency + adjustamt, 0, 100) + potency = CLAMP(potency + adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/adjust_weed_rate(adjustamt) - weed_rate = Clamp(weed_rate + adjustamt, 0, 10) + weed_rate = CLAMP(weed_rate + adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/adjust_weed_chance(adjustamt) - weed_chance = Clamp(weed_chance + adjustamt, 0, 67) + weed_chance = CLAMP(weed_chance + adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance @@ -220,7 +220,7 @@ /obj/item/seeds/proc/set_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = Clamp(adjustamt, 0, 10) + yield = CLAMP(adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -229,39 +229,39 @@ C.value = yield /obj/item/seeds/proc/set_lifespan(adjustamt) - lifespan = Clamp(adjustamt, 10, 100) + lifespan = CLAMP(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/set_endurance(adjustamt) - endurance = Clamp(adjustamt, 10, 100) + endurance = CLAMP(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/set_production(adjustamt) if(yield != -1) - production = Clamp(adjustamt, 1, 10) + production = CLAMP(adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/set_potency(adjustamt) if(potency != -1) - potency = Clamp(adjustamt, 0, 100) + potency = CLAMP(adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/set_weed_rate(adjustamt) - weed_rate = Clamp(adjustamt, 0, 10) + weed_rate = CLAMP(adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/set_weed_chance(adjustamt) - weed_chance = Clamp(adjustamt, 0, 67) + weed_chance = CLAMP(adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/code/modules/integrated_electronics/core/special_pins/index_pin.dm index 802a2612d3..51b12a0f3a 100644 --- a/code/modules/integrated_electronics/core/special_pins/index_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/index_pin.dm @@ -14,7 +14,7 @@ new_data = 1 if(isnum(new_data)) - data = Clamp(round(new_data), 1, IC_MAX_LIST_LENGTH) + data = CLAMP(round(new_data), 1, IC_MAX_LIST_LENGTH) holder.on_data_written() /datum/integrated_io/index/display_pin_type() diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 272dbef071..4e4e447193 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -265,7 +265,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToDegrees(incoming) + result = TODEGREES(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -283,7 +283,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToRadians(incoming) + result = TORADIANS(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 20b80926c8..a769a16768 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -123,7 +123,7 @@ /obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - if(output_index == Clamp(output_index, 1, number_of_pins)) + if(output_index == CLAMP(output_index, 1, number_of_pins)) activate_pin(round(output_index + 1 ,1)) /obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 276d3d9ca0..c39cfeac44 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -373,7 +373,7 @@ var/rad = get_pin_data(IC_INPUT, 2) if(isnum(rad)) - rad = Clamp(rad, 0, 8) + rad = CLAMP(rad, 0, 8) radius = rad /obj/item/integrated_circuit/input/advanced_locator_list/do_work() @@ -426,7 +426,7 @@ /obj/item/integrated_circuit/input/advanced_locator/on_data_written() var/rad = get_pin_data(IC_INPUT, 2) if(isnum(rad)) - rad = Clamp(rad, 0, 8) + rad = CLAMP(rad, 0, 8) radius = rad /obj/item/integrated_circuit/input/advanced_locator/do_work() diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 42a55f1a1d..f32f414fbb 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -93,8 +93,8 @@ yo.data = round(yo.data, 1) var/turf/T = get_turf(assembly) - var/target_x = Clamp(T.x + xo.data, 0, world.maxx) - var/target_y = Clamp(T.y + yo.data, 0, world.maxy) + var/target_x = CLAMP(T.x + xo.data, 0, world.maxx) + var/target_y = CLAMP(T.y + yo.data, 0, world.maxy) shootAt(locate(target_x, target_y, T.z)) @@ -210,7 +210,7 @@ var/datum/integrated_io/detonation_time = inputs[1] var/dt if(isnum(detonation_time.data) && detonation_time.data > 0) - dt = Clamp(detonation_time.data, 1, 12)*10 + dt = CLAMP(detonation_time.data, 1, 12)*10 else dt = 15 addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt) @@ -389,9 +389,9 @@ if(!M.temporarilyRemoveItemFromInventory(A)) return - var/x_abs = Clamp(T.x + target_x_rel, 0, world.maxx) - var/y_abs = Clamp(T.y + target_y_rel, 0, world.maxy) - var/range = round(Clamp(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) + var/x_abs = CLAMP(T.x + target_x_rel, 0, world.maxx) + var/y_abs = CLAMP(T.y + target_y_rel, 0, world.maxy) + var/range = round(CLAMP(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) A.forceMove(drop_location()) A.throw_at(locate(x_abs, y_abs, T.z), range, 3) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index ef6cc644d8..6a90ff5f2a 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -88,7 +88,7 @@ var/brightness = get_pin_data(IC_INPUT, 2) if(new_color && isnum(brightness)) - brightness = Clamp(brightness, 0, 6) + brightness = CLAMP(brightness, 0, 6) light_rgb = new_color light_brightness = brightness @@ -146,7 +146,7 @@ var/selected_sound = sounds[ID] if(!selected_sound) return - vol = Clamp(vol ,0 , 100) + vol = CLAMP(vol ,0 , 100) playsound(get_turf(src), selected_sound, vol, freq, -1) /obj/item/integrated_circuit/output/sound/on_data_written() diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 564c3a4851..78b1e9682e 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -111,7 +111,7 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, volume) + new_amount = CLAMP(new_amount, 0, volume) transfer_amount = new_amount // Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way. @@ -184,7 +184,7 @@ activate_pin(3) return - var/tramount = Clamp(transfer_amount, 0, reagents.total_volume) + var/tramount = CLAMP(transfer_amount, 0, reagents.total_volume) if(isliving(AM)) var/mob/living/L = AM @@ -235,7 +235,7 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/pump/do_work() @@ -383,7 +383,7 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/filter/do_work() diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index 57fc16ccf9..d93aafef58 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -62,7 +62,7 @@ /obj/item/integrated_circuit/time/delay/custom/do_work() var/delay_input = get_pin_data(IC_INPUT, 1) if(delay_input && isnum(delay_input) ) - var/new_delay = Clamp(delay_input ,1 ,36000) //An hour. + var/new_delay = CLAMP(delay_input ,1 ,36000) //An hour. delay = new_delay ..() diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index 1d7f660bd4..cefa25e945 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -71,7 +71,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Tan(A) + result = TAN(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -91,7 +91,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Csc(A) + result = CSC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -111,7 +111,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Sec(A) + result = SEC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -131,7 +131,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Cot(A) + result = COT(A) set_pin_data(IC_OUTPUT, 1, result) push_data() diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm index 67881f7510..598fb41e6c 100644 --- a/code/modules/language/language.dm +++ b/code/modules/language/language.dm @@ -49,7 +49,7 @@ for(var/i in 0 to name_count) new_name = "" - var/Y = rand(Floor(syllable_count/syllable_divisor), syllable_count) + var/Y = rand(FLOOR(syllable_count/syllable_divisor, 1), syllable_count) for(var/x in Y to 0) new_name += pick(syllables) full_name += " [capitalize(lowertext(new_name))]" diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 52077d2367..d47bb46c63 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -263,7 +263,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums dat += "
    (Order book by SS13BN)

    " dat += "
    [J_title]: [J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]" if(job.title == "AI" || job.title == "Cyborg") - dat += " (Cannot Late Join)
    " + dat += " (Cannot Late Join)
    " + if(job.total_positions >= 0) + dat += "Add | " + if(job.total_positions > job.current_positions) + dat += "Remove | " + else + dat += "Remove | " + dat += "Unlimit
    " dat += "" - dat += libcomp_menu[Clamp(page,1,libcomp_menu.len)] + dat += libcomp_menu[CLAMP(page,1,libcomp_menu.len)] dat += "" dat += "
    AUTHORTITLECATEGORY
    <<<< >>>>
    " dat += "
    (Return to main menu)
    " @@ -444,7 +444,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums else var/orderid = input("Enter your order:") as num|null if(orderid) - if(isnum(orderid) && IsInteger(orderid)) + if(isnum(orderid) && ISINTEGER(orderid)) href_list["targetid"] = num2text(orderid) if(href_list["targetid"]) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 8e56acc2fb..a6c28b4146 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -232,8 +232,8 @@ var/turf/T if (source_turf) var/oldlum = source_turf.luminosity - source_turf.luminosity = Ceiling(light_range) - for(T in view(Ceiling(light_range), source_turf)) + source_turf.luminosity = CEILING(light_range, 1) + for(T in view(CEILING(light_range, 1), source_turf)) for (thing in T.get_corners(source_turf)) C = thing corners[C] = 0 diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 862de852bc..559a93b87f 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -102,7 +102,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) if(!no_changeturf) WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called") - bounds[MAP_MINX] = min(bounds[MAP_MINX], Clamp(xcrdStart, x_lower, x_upper)) + bounds[MAP_MINX] = min(bounds[MAP_MINX], CLAMP(xcrdStart, x_lower, x_upper)) bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd) bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd) @@ -119,15 +119,15 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) if(gridLines.len && gridLines[gridLines.len] == "") gridLines.Cut(gridLines.len) // Remove only one blank line at the end. - bounds[MAP_MINY] = min(bounds[MAP_MINY], Clamp(ycrd, y_lower, y_upper)) + bounds[MAP_MINY] = min(bounds[MAP_MINY], CLAMP(ycrd, y_lower, y_upper)) ycrd += gridLines.len - 1 // Start at the top and work down if(!cropMap && ycrd > world.maxy) if(!measureOnly) world.maxy = ycrd // Expand Y here. X is expanded in the loop below - bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(ycrd, y_lower, y_upper)) + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], CLAMP(ycrd, y_lower, y_upper)) else - bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(min(ycrd, world.maxy), y_lower, y_upper)) + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], CLAMP(min(ycrd, world.maxy), y_lower, y_upper)) var/maxx = xcrdStart if(measureOnly) @@ -166,7 +166,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) ++xcrd --ycrd - bounds[MAP_MAXX] = Clamp(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper) + bounds[MAP_MAXX] = CLAMP(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper) CHECK_TICK diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 7fdecaaeb6..cf290112f4 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -799,13 +799,13 @@ force = 0 var/ghost_counter = ghost_check() - force = Clamp((ghost_counter * 4), 0, 75) + force = CLAMP((ghost_counter * 4), 0, 75) user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") ..() /obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) var/ghost_counter = ghost_check() - final_block_chance += Clamp((ghost_counter * 5), 0, 75) + final_block_chance += CLAMP((ghost_counter * 5), 0, 75) owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") return ..() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 60715ef26a..e16eb0e5b2 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -82,7 +82,7 @@ if(!M || !redemption_mat) return FALSE - var/smeltable_sheets = Floor(redemption_mat.amount / M) + var/smeltable_sheets = FLOOR(redemption_mat.amount / M, 1) if(!smeltable_sheets) return FALSE diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index fe4c2fab84..ca21456163 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -68,7 +68,7 @@ if(materials.materials[href_list["choose"]]) chosen = href_list["choose"] if(href_list["chooseAmt"]) - coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) + coinsToProduce = CLAMP(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) if(href_list["makeCoins"]) var/temp_coins = coinsToProduce processing = TRUE diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 458a54aa48..495b65bfa7 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -185,7 +185,7 @@ var/pollid = href_list["pollid"] if(istext(pollid)) pollid = text2num(pollid) - if(isnum(pollid) && IsInteger(pollid)) + if(isnum(pollid) && ISINTEGER(pollid)) src.poll_player(pollid) return @@ -223,7 +223,7 @@ rating = null else rating = text2num(href_list["o[optionid]"]) - if(!isnum(rating) || !IsInteger(rating)) + if(!isnum(rating) || !ISINTEGER(rating)) return if(!vote_on_numval_poll(pollid, optionid, rating)) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d19f3d4bf8..c838376d28 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -462,7 +462,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp views |= i var/new_view = input("Choose your new view", "Modify view range", 7) as null|anything in views if(new_view) - client.change_view(Clamp(new_view, 7, max_view)) + client.change_view(CLAMP(new_view, 7, max_view)) else client.change_view(CONFIG_GET(string/default_view)) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index db48302f49..aef5489b04 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -154,7 +154,7 @@ var/adjusted_amount if(amount >= 0 && maximum) var/brainloss = get_brain_damage() - var/new_brainloss = Clamp(brainloss + amount, 0, maximum) + var/new_brainloss = CLAMP(brainloss + amount, 0, maximum) if(brainloss > new_brainloss) //brainloss is over the cap already return 0 adjusted_amount = new_brainloss - brainloss diff --git a/code/modules/mob/living/carbon/alien/status_procs.dm b/code/modules/mob/living/carbon/alien/status_procs.dm index 61de87b6cb..33ba8fea1d 100644 --- a/code/modules/mob/living/carbon/alien/status_procs.dm +++ b/code/modules/mob/living/carbon/alien/status_procs.dm @@ -17,4 +17,4 @@ /mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0) . = ..() if(!.) - move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10) + move_delay_add = CLAMP(move_delay_add + round(amount/2), 0, 10) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index aecf966350..a6efaaa967 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -185,7 +185,7 @@ /mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1) if(status_flags & GODMODE) return 0 - staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2) + staminaloss = CLAMP(staminaloss + amount, 0, maxHealth*2) if(updating_stamina) update_stamina() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e8d4baba63..75800dc75f 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -89,15 +89,15 @@ for(var/obj/item/I in held_items) if(!istype(I, /obj/item/clothing)) - var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example + var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 if(wear_suit) - var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier + var/final_block_chance = wear_suit.block_chance - (CLAMP((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 if(w_uniform) - var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier + var/final_block_chance = w_uniform.block_chance - (CLAMP((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 return 0 diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index d2c83fa39f..2b86d2945d 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -369,7 +369,7 @@ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) var/turf/target = get_turf(P.starting) // redirect the projectile - P.preparePixelProjectile(locate(Clamp(target.x + new_x, 1, world.maxx), Clamp(target.y + new_y, 1, world.maxy), H.z), H) + P.preparePixelProjectile(locate(CLAMP(target.x + new_x, 1, world.maxx), CLAMP(target.y + new_y, 1, world.maxy), H.z), H) return -1 return 0 diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 6d1384f12f..aff8440930 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -94,8 +94,8 @@ to_chat(victim, "[H] is draining your blood!") to_chat(H, "You drain some blood!") playsound(H, 'sound/items/drink.ogg', 30, 1, -2) - victim.blood_volume = Clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) - H.blood_volume = Clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + victim.blood_volume = CLAMP(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + H.blood_volume = CLAMP(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) if(!victim.blood_volume) to_chat(H, "You finish off [victim]'s blood supply!") diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 5eb09a8d83..4399607984 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -182,7 +182,7 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10 - adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) + adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else clear_alert("too_much_tox") diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index e46ae2f8e6..7c40b6f144 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -59,10 +59,10 @@ clear_alert("high") /mob/living/carbon/adjust_disgust(amount) - disgust = Clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = CLAMP(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) /mob/living/carbon/set_disgust(amount) - disgust = Clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = CLAMP(amount, 0, DISGUST_LEVEL_MAXEDOUT) /mob/living/carbon/cure_blind() if(disabilities & BLIND) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index dbc8da5a05..9517e1b705 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -157,7 +157,7 @@ /mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = Clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + bruteloss = CLAMP((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -168,7 +168,7 @@ /mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - oxyloss = Clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + oxyloss = CLAMP((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -187,7 +187,7 @@ /mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - toxloss = Clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + toxloss = CLAMP((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -206,7 +206,7 @@ /mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - fireloss = Clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + fireloss = CLAMP((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -217,7 +217,7 @@ /mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - cloneloss = Clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + cloneloss = CLAMP((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f589ecbb20..a5fac98d49 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -918,7 +918,7 @@ update_fire() /mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person - fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20) + fire_stacks = CLAMP(fire_stacks + add_fire_stacks, -20, 20) if(on_fire && fire_stacks <= 0) ExtinguishMob() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f77c65225f..8d4f29a0ee 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -55,9 +55,9 @@ /obj/item/proc/get_volume_by_throwforce_and_or_w_class() if(throwforce && w_class) - return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 + return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 else if(w_class) - return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 + return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 else return 0 diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index b12430d26d..924ab615b8 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -138,7 +138,7 @@ /mob/living/silicon/pai/proc/process_hack() if(cable && cable.machine && istype(cable.machine, /obj/machinery/door) && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) - hackprogress = Clamp(hackprogress + 4, 0, 100) + hackprogress = CLAMP(hackprogress + 4, 0, 100) else temp = "Door Jack: Connection to airlock has been lost. Hack aborted." hackprogress = 0 @@ -283,8 +283,8 @@ /mob/living/silicon/pai/process() - emitterhealth = Clamp((emitterhealth + emitterregen), -50, emittermaxhealth) - hit_slowdown = Clamp((hit_slowdown - 1), 0, 100) + emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth) + hit_slowdown = CLAMP((hit_slowdown - 1), 0, 100) /mob/living/silicon/pai/generateStaticOverlay() return diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 83da7d9087..2c6c42e3bb 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -57,7 +57,7 @@ return FALSE //No we're not flammable /mob/living/silicon/pai/proc/take_holo_damage(amount) - emitterhealth = Clamp((emitterhealth - amount), -50, emittermaxhealth) + emitterhealth = CLAMP((emitterhealth - amount), -50, emittermaxhealth) if(emitterhealth < 0) fold_in(force = TRUE) to_chat(src, "The impact degrades your holochassis!") diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index aab1f204f6..ce0571ca4e 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -23,7 +23,7 @@ if(cell && cell.charge) if(cell.charge <= 100) uneq_all() - var/amt = Clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. + var/amt = CLAMP((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick else uneq_all() diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index 5405ee03c6..bb6794a36a 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -2,7 +2,7 @@ /mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = Clamp(bruteloss + amount, 0, maxHealth) + bruteloss = CLAMP(bruteloss + amount, 0, maxHealth) if(updating_health) updatehealth() return amount 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 a977338008..c6f0f6a91c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -79,10 +79,10 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/Life() ..() - move_to_delay = Clamp((health/maxHealth) * 10, 5, 10) + move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10) /mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/60),0,20) + anger_modifier = CLAMP(((maxHealth - health)/60),0,20) if(charging) return ranged_cooldown = world.time + ranged_cooldown_time diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 58e3e0837b..d47385efc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -57,7 +57,7 @@ Difficulty: Very Hard L.dust() /mob/living/simple_animal/hostile/megafauna/colossus/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/50),0,20) + anger_modifier = CLAMP(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + 120 if(enrage(target)) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index 7f12e684e8..724e4fc5c7 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -101,7 +101,7 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() if(swooping) return - anger_modifier = Clamp(((maxHealth - health)/50),0,20) + anger_modifier = CLAMP(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + ranged_cooldown_time if(prob(15 + anger_modifier) && !client) @@ -227,10 +227,10 @@ Difficulty: Medium //ensure swoop direction continuity. if(negative) - if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) + if(ISINRANGE(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) negative = FALSE else - if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) + if(ISINRANGE(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) negative = TRUE new /obj/effect/temp_visual/dragon_flight/end(loc, negative) new /obj/effect/temp_visual/dragon_swoop(loc) 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 02fb81a1ed..8dc1780e5e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -187,7 +187,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall - anger_modifier = Clamp(((maxHealth - health) / 42),0,50) + anger_modifier = CLAMP(((maxHealth - health) / 42),0,50) burst_range = initial(burst_range) + round(anger_modifier * 0.08) beam_range = initial(beam_range) + round(anger_modifier * 0.12) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index a4851bb432..4c5b94f2e3 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -111,7 +111,7 @@ /mob/living/simple_animal/updatehealth() ..() - health = Clamp(health, 0, maxHealth) + health = CLAMP(health, 0, maxHealth) /mob/living/simple_animal/update_stat() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index e7e71bf091..9654f91b6c 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -166,7 +166,7 @@ step_away(M,src) M.Friends = Friends.Copy() babies += M - M.mutation_chance = Clamp(mutation_chance+(rand(5,-5)),0,100) + M.mutation_chance = CLAMP(mutation_chance+(rand(5,-5)),0,100) SSblackbox.record_feedback("tally", "slime_babies_born", 1, M.colour) var/mob/living/simple_animal/slime/new_slime = pick(babies) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7f3b428978..40401cf0a8 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -153,7 +153,7 @@ GLOB.apcs_list -= src if(malfai && operating) - malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) area.power_light = FALSE area.power_equip = FALSE area.power_environ = FALSE @@ -1253,7 +1253,7 @@ /obj/machinery/power/apc/proc/set_broken() if(malfai && operating) - malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) stat |= BROKEN operating = FALSE if(occupier) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 1e1407e852..2d85612e1b 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -155,7 +155,7 @@ /obj/item/stock_parts/cell/proc/get_electrocute_damage() if(charge >= 1000) - return Clamp(round(charge/10000), 10, 90) + rand(-5,5) + return CLAMP(round(charge/10000), 10, 90) + rand(-5,5) else return 0 @@ -334,7 +334,7 @@ return /obj/item/stock_parts/cell/beam_rifle/emp_act(severity) - charge = Clamp((charge-(10000/severity)),0,maxcharge) + charge = CLAMP((charge-(10000/severity)),0,maxcharge) /obj/item/stock_parts/cell/emergency_light name = "miniature power cell" diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index b6f61103ca..c34edc53f3 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -94,6 +94,6 @@ /datum/powernet/proc/get_electrocute_damage() if(avail >= 1000) - return Clamp(round(avail/10000), 10, 90) + rand(-5,5) + return CLAMP(round(avail/10000), 10, 90) + rand(-5,5) else return 0 \ No newline at end of file diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 70776b5c05..95b78ff0b5 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -227,7 +227,7 @@ /obj/machinery/power/smes/proc/chargedisplay() - return Clamp(round(5.5*charge/capacity),0,5) + return CLAMP(round(5.5*charge/capacity),0,5) /obj/machinery/power/smes/process() if(stat & BROKEN) @@ -382,7 +382,7 @@ target = text2num(target) . = TRUE if(.) - input_level = Clamp(target, 0, input_level_max) + input_level = CLAMP(target, 0, input_level_max) log_smes(usr.ckey) if("output") var/target = params["target"] @@ -404,7 +404,7 @@ target = text2num(target) . = TRUE if(.) - output_level = Clamp(target, 0, output_level_max) + output_level = CLAMP(target, 0, output_level_max) log_smes(usr.ckey) /obj/machinery/power/smes/proc/log_smes(user = "") diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fb530f128f..ab8009df55 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -378,14 +378,14 @@ if("direction") var/adjust = text2num(params["adjust"]) if(adjust) - currentdir = Clamp((360 + adjust + currentdir) % 360, 0, 359) + currentdir = CLAMP((360 + adjust + currentdir) % 360, 0, 359) targetdir = currentdir set_panels(currentdir) . = TRUE if("rate") var/adjust = text2num(params["adjust"]) if(adjust) - trackrate = Clamp(trackrate + adjust, -7200, 7200) + trackrate = CLAMP(trackrate + adjust, -7200, 7200) if(trackrate) nexttime = world.time + 36000 / abs(trackrate) . = TRUE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 02cc80291e..5f9f6042d3 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -317,10 +317,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && co2comp > POWERLOSS_INHIBITION_GAS_THRESHOLD) - powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling + Clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) + powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling + CLAMP(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) else - powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling - 0.05,0, 1) - powerloss_inhibitor = Clamp(1-(powerloss_dynamic_scaling * Clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) + powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling - 0.05,0, 1) + powerloss_inhibitor = CLAMP(1-(powerloss_dynamic_scaling * CLAMP(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) if(matter_power) var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) @@ -368,7 +368,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) var/D = sqrt(1 / max(1, get_dist(l, src))) l.hallucination += power * config_hallucination_power * D - l.hallucination = Clamp(0, 200, l.hallucination) + l.hallucination = CLAMP(0, 200, l.hallucination) for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) @@ -386,7 +386,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) supermatter_zap(src, 5, min(power*2, 20000)) else if (damage > damage_penalty_point && prob(20)) playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10) - supermatter_zap(src, 5, Clamp(power*2, 4000, 20000)) + supermatter_zap(src, 5, CLAMP(power*2, 4000, 20000)) if(prob(15) && power > POWER_PENALTY_THRESHOLD) supermatter_pull(src, power/750) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 4a26950217..51cb99a34f 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -62,7 +62,7 @@ pixel_x = -32 pixel_y = -32 for (var/ball in orbiting_balls) - var/range = rand(1, Clamp(orbiting_balls.len, 3, 7)) + var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7)) tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE) else energy = 0 // ensure we dont have miniballs of miniballs @@ -268,7 +268,7 @@ closest_grounding_rod.tesla_act(power, explosive, stun_mobs) else if(closest_mob) - var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) + var/shock_damage = CLAMP(round(power/400), 10, 90) + rand(-5, 5) closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1, stun = stun_mobs) if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm index 09ae7cb905..b7b3a3e286 100644 --- a/code/modules/projectiles/boxes_magazines/external_mag.dm +++ b/code/modules/projectiles/boxes_magazines/external_mag.dm @@ -176,7 +176,7 @@ /obj/item/ammo_box/magazine/m12g/update_icon() ..() - icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]" + icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]" /obj/item/ammo_box/magazine/m12g/buckshot name = "shotgun magazine (12g buckshot slugs)" diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index eb36608e77..f392fda24e 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -108,7 +108,7 @@ /obj/item/gun/ballistic/automatic/c20r/update_icon() ..() - icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/gun/ballistic/automatic/wt550 name = "security auto rifle" @@ -123,7 +123,7 @@ /obj/item/gun/ballistic/automatic/wt550/update_icon() ..() - icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" + icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]" /obj/item/gun/ballistic/automatic/mini_uzi name = "\improper Type U3 Uzi" @@ -304,7 +304,7 @@ /obj/item/gun/ballistic/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]" + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]" item_state = "l6[cover_open ? "openmag" : "closedmag"]" @@ -415,5 +415,5 @@ /obj/item/gun/ballistic/automatic/laser/update_icon() ..() - icon_state = "oldrifle[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" + icon_state = "oldrifle[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]" return diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm index e1069a6bce..7443286d24 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/beam_rifle.dm @@ -365,7 +365,7 @@ AC.sync_stats() /obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) - aiming_time_left = Clamp(aiming_time_left + amount, 0, aiming_time) + aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time) /obj/item/ammo_casing/energy/beam_rifle name = "particle acceleration lens" @@ -416,11 +416,11 @@ HS_BB.stun = projectile_stun HS_BB.impact_structure_damage = impact_structure_damage HS_BB.aoe_mob_damage = aoe_mob_damage - HS_BB.aoe_mob_range = Clamp(aoe_mob_range, 0, 15) //Badmin safety lock + HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock HS_BB.aoe_fire_chance = aoe_fire_chance HS_BB.aoe_fire_range = aoe_fire_range HS_BB.aoe_structure_damage = aoe_structure_damage - HS_BB.aoe_structure_range = Clamp(aoe_structure_range, 0, 15) //Badmin safety lock + HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock HS_BB.wall_devastate = wall_devastate HS_BB.wall_pierce_amount = wall_pierce_amount HS_BB.structure_pierce_amount = structure_piercing diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3adadb90eb..12b0c57d38 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -130,7 +130,7 @@ ..() if(!automatic_charge_overlays) return - var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections) + var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/iconState = "[icon_state]_charge" var/itemState = null diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 27fb040de4..bf3ade0748 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -12,9 +12,9 @@ /obj/item/gun/magic/wand/Initialize() if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges if(prob(33)) - max_charges = Ceiling(max_charges / 3) + max_charges = CEILING(max_charges / 3, 1) else - max_charges = Ceiling(max_charges / 2) + max_charges = CEILING(max_charges / 2, 1) return ..() /obj/item/gun/magic/wand/examine(mob/user) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0e3bd98c68..79e2fdf903 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -168,7 +168,7 @@ /obj/item/projectile/proc/vol_by_damage() if(src.damage) - return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 + return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume @@ -188,7 +188,7 @@ def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. if(isturf(A) && hitsound_wall) - var/volume = Clamp(vol_by_damage() + 20, 0, 100) + var/volume = CLAMP(vol_by_damage() + 20, 0, 100) if(suppressed) volume = 5 playsound(loc, hitsound_wall, volume, 1, -1) @@ -259,7 +259,7 @@ return var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset time_offset = 0 - var/required_moves = speed > 0? Floor(elapsed_time_deciseconds / speed) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :< + var/required_moves = speed > 0? FLOOR(elapsed_time_deciseconds / speed, 1) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :< if(required_moves == MOVES_HITSCAN) required_moves = SSprojectiles.global_max_tick_moves else @@ -267,7 +267,7 @@ var/overrun = required_moves - SSprojectiles.global_max_tick_moves required_moves = SSprojectiles.global_max_tick_moves time_offset += overrun * speed - time_offset += Modulus(elapsed_time_deciseconds, speed) + time_offset += MODULUS(elapsed_time_deciseconds, speed) for(var/i in 1 to required_moves) pixel_move(required_moves) @@ -287,7 +287,7 @@ setAngle(Angle + ((rand() - 0.5) * spread)) if(isnull(Angle)) //Try to resolve through offsets if there's no angle set. var/turf/starting = get_turf(src) - var/turf/target = locate(Clamp(starting + xo, 1, world.maxx), Clamp(starting + yo, 1, world.maxy), starting.z) + var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z) setAngle(Get_Angle(src, target)) if(!nondirectional_sprite) var/matrix/M = new @@ -403,7 +403,7 @@ var/ox = round(screenviewX/2) - user.client.pixel_x //"origin" x var/oy = round(screenviewY/2) - user.client.pixel_y //"origin" y - angle = Atan2(y - oy, x - ox) + angle = ATAN2(y - oy, x - ox) return list(angle, p_x, p_y) /obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9c4bff72cb..ef609696a2 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -580,7 +580,7 @@ if (R.id == reagent) //clamp the removal amount to be between current reagent amount //and zero, to prevent removing more than the holder has stored - amount = Clamp(amount, 0, R.volume) + amount = CLAMP(amount, 0, R.volume) R.volume -= amount update_total() if(!safety)//So it does not handle reactions when it need not to diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 745843474e..51ddf549e0 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -211,7 +211,7 @@ /obj/machinery/chem_dispenser/emp_act(severity) var/list/datum/reagents/R = list() - var/total = min(rand(7,15), Floor(cell.charge*powerefficiency)) + var/total = min(rand(7,15), FLOOR(cell.charge*powerefficiency, 1)) var/datum/reagents/Q = new(total*10) if(beaker && beaker.reagents) R += beaker.reagents diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index a6d958220a..722ddbf15f 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -126,7 +126,7 @@ target = text2num(target) . = TRUE if(.) - target_temperature = Clamp(target, 0, 1000) + target_temperature = CLAMP(target, 0, 1000) if("eject") on = FALSE eject_beaker() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 3e06449e3a..631a027d9a 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -215,7 +215,7 @@ var/amount = 1 var/vol_each = min(reagents.total_volume, 50) if(text2num(many)) - amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10) + amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 50) @@ -251,7 +251,7 @@ var/amount = 1 var/vol_each = min(reagents.total_volume, 40) if(text2num(many)) - amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10) + amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 40) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 77fcd50306..1369a4e959 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -484,7 +484,7 @@ /obj/machinery/reagentgrinder/proc/mix_complete() if(beaker && beaker.reagents.total_volume) //Recipe to make Butter - var/butter_amt = Floor(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF) + var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1) beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt) for(var/i in 1 to butter_amt) new /obj/item/reagent_containers/food/snacks/butter(drop_location()) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 5f76a87654..9f8e129420 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -41,7 +41,7 @@ return 0 if(method == VAPOR) //smoke, foam, spray if(M.reagents) - var/modifier = Clamp((1 - touch_protection), 0, 1) + var/modifier = CLAMP((1 - touch_protection), 0, 1) var/amount = round(reac_volume*modifier, 0.1) if(amount >= 0.5) M.reagents.add_reagent(id, amount) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 6a3b1a1637..00fd7d56a3 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -961,7 +961,7 @@ All effects don't start immediately, but rather get worse over time; the rate is var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) changeling.chem_charges += metabolization_rate - changeling.chem_charges = Clamp(changeling.chem_charges, 0, changeling.chem_storage) + changeling.chem_charges = CLAMP(changeling.chem_charges, 0, changeling.chem_storage) return ..() /datum/reagent/consumable/ethanol/irishcarbomb diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 711c333896..7bee2ef958 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -850,9 +850,9 @@ /datum/reagent/toxin/peaceborg/confuse/on_mob_life(mob/living/M) if(M.confused < 6) - M.confused = Clamp(M.confused + 3, 0, 5) + M.confused = CLAMP(M.confused + 3, 0, 5) if(M.dizziness < 6) - M.dizziness = Clamp(M.dizziness + 3, 0, 5) + M.dizziness = CLAMP(M.dizziness + 3, 0, 5) if(prob(20)) to_chat(M, "You feel confused and disorientated.") ..() diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 0e645e3798..b77dcc435a 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -168,7 +168,7 @@ return holder.remove_reagent("sorium", created_volume*4) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume*4), 1, 6) + var/range = CLAMP(sqrt(created_volume*4), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/sorium_vortex @@ -179,7 +179,7 @@ /datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume), 1, 6) + var/range = CLAMP(sqrt(created_volume), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/liquid_dark_matter @@ -193,7 +193,7 @@ return holder.remove_reagent("liquid_dark_matter", created_volume*3) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume*3), 1, 6) + var/range = CLAMP(sqrt(created_volume*3), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/ldm_vortex @@ -204,7 +204,7 @@ /datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume/2), 1, 6) + var/range = CLAMP(sqrt(created_volume/2), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/flash_powder diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 87fb2b8a9e..d60d415e9a 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -157,7 +157,7 @@ /obj/item/reagent_containers/syringe/update_icon() - var/rounded_vol = Clamp(round((reagents.total_volume / volume * 15),5), 0, 15) + var/rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 0, 15) cut_overlays() if(ismob(loc)) var/injoverlay diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index ed14ae63c1..c58704de4b 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -297,7 +297,7 @@ data["full_pressure"] = full_pressure data["pressure_charging"] = pressure_charging data["panel_open"] = panel_open - var/per = Clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100) + var/per = CLAMP(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100) data["per"] = round(per, 1) data["isai"] = isAI(user) return data diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 6c52fd4678..521f1d7f29 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -93,7 +93,7 @@ Note: Must be placed west/left of and R&D console to function. return FALSE var/power = 1000 - amount = Clamp(amount, 1, 10) + amount = CLAMP(amount, 1, 10) for(var/M in D.materials) power += round(D.materials[M] * amount / 5) power = max(3000, power) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index cf250f50f1..9c5510a814 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -290,7 +290,7 @@ return ..() to_chat(user, "You feed the slime the stabilizer. It is now less likely to mutate.") - M.mutation_chance = Clamp(M.mutation_chance-15,0,100) + M.mutation_chance = CLAMP(M.mutation_chance-15,0,100) qdel(src) /obj/item/slimepotion/mutator @@ -314,7 +314,7 @@ return ..() to_chat(user, "You feed the slime the mutator. It is now more likely to mutate.") - M.mutation_chance = Clamp(M.mutation_chance+12,0,100) + M.mutation_chance = CLAMP(M.mutation_chance+12,0,100) M.mutator_used = TRUE qdel(src) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index a4303078a5..3811fa0e4a 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -146,13 +146,13 @@ var/y0 = bounds[2] var/x1 = bounds[3] var/y1 = bounds[4] - if(x0 <= x1 && !IsInRange(T.x, x0, x1)) + if(x0 <= x1 && !ISINRANGE(T.x, x0, x1)) return FALSE - else if(!IsInRange(T.x, x1, x0)) + else if(!ISINRANGE(T.x, x1, x0)) return FALSE - if(y0 <= y1 && !IsInRange(T.y, y0, y1)) + if(y0 <= y1 && !ISINRANGE(T.y, y0, y1)) return FALSE - else if(!IsInRange(T.y, y1, y0)) + else if(!ISINRANGE(T.y, y1, y0)) return FALSE return TRUE @@ -534,7 +534,7 @@ rotation = dir2angle(new_dock.dir)-dir2angle(dir) if ((rotation % 90) != 0) rotation += (rotation % 90) //diagonal rotations not allowed, round up - rotation = SimplifyDegrees(rotation) + rotation = SIMPLIFY_DEGREES(rotation) if(!movement_direction) movement_direction = turn(preferred_direction, 180) @@ -888,13 +888,13 @@ var/change_per_engine = (1 - ENGINE_COEFF_MIN) / ENGINE_DEFAULT_MAXSPEED_ENGINES // 5 by default if(initial_engines > 0) change_per_engine = (1 - ENGINE_COEFF_MIN) / initial_engines // or however many it had - return Clamp(1 - delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) + return CLAMP(1 - delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) if(new_value < initial_engines) var/delta = initial_engines - new_value var/change_per_engine = 1 //doesn't really matter should not be happening for 0 engine shuttles if(initial_engines > 0) change_per_engine = (ENGINE_COEFF_MAX - 1) / initial_engines //just linear drop to max delay - return Clamp(1 + delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) + return CLAMP(1 + delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) /obj/docking_port/mobile/proc/in_flight() diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index 9b120c2e7f..39d340927e 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -289,7 +289,7 @@ var/mob/living/M = AM M.Knockdown(stun_amt) to_chat(M, "You're thrown back by [user]!") - AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. + AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?! name = "Tail Sweep" diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index e99455c833..a385d009e5 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -18,7 +18,7 @@ return 0 var/obj/item/bodypart/affecting = C.get_bodypart("chest") - affecting.receive_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage + affecting.receive_damage(CLAMP(brute_dam/2, 15, 50), CLAMP(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] has been violently dismembered!") C.emote("scream") drop_limb() diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 51e39605c4..f8f57c650f 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -199,7 +199,7 @@ return var/range = input(user, "Enter range (0 - [max_light_beam_distance])", "Range Select", 0) as null|num - set_distance(Clamp(range, 0, max_light_beam_distance)) + set_distance(CLAMP(range, 0, max_light_beam_distance)) assume_rgb(C) /obj/item/organ/eyes/robotic/glow/proc/assume_rgb(newcolor) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 02f1ee4ec3..102ac9720f 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -111,7 +111,7 @@ if(safe_oxygen_max) if(O2_pp > safe_oxygen_max) var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10 - H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) + H.apply_damage_type(CLAMP(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) else H.clear_alert("too_much_oxy") @@ -139,7 +139,7 @@ if(safe_nitro_max) if(N2_pp > safe_nitro_max) var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10 - H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) + H.apply_damage_type(CLAMP(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) else H.clear_alert("too_much_nitro") @@ -205,7 +205,7 @@ if(safe_toxins_max) if(Toxins_pp > safe_toxins_max) var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_toxins_max) * 10 - H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) + H.apply_damage_type(CLAMP(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else H.clear_alert("too_much_tox") diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..3ccdf79ee6 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -54,7 +54,7 @@ #include "code\__DEFINES\logging.dm" #include "code\__DEFINES\machines.dm" #include "code\__DEFINES\maps.dm" -#include "code\__DEFINES\math.dm" +#include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" @@ -100,7 +100,6 @@ #include "code\__HELPERS\global_lists.dm" #include "code\__HELPERS\icon_smoothing.dm" #include "code\__HELPERS\icons.dm" -#include "code\__HELPERS\maths.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" #include "code\__HELPERS\names.dm" From 5a50462f10fad8360bd154ef84ec3f3aa6a0bef1 Mon Sep 17 00:00:00 2001 From: Armhulen Date: Sun, 17 Dec 2017 08:41:57 -0800 Subject: [PATCH 043/213] gives credit to people who more than deserve it --- html/changelog.html | 1489 ++++++++++++++++++++++++++++ html/changelogs/.all_changelog.yml | 917 +++++++++++++++++ 2 files changed, 2406 insertions(+) diff --git a/html/changelog.html b/html/changelog.html index 45dfe57b20..d73ebdcd62 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -1279,3 +1279,1492 @@ + + + + /tg/ Station 13 Changelog + + + + + + + +
    + + + + +
    +
    Traditional Games Space Station 13
    + +

    + Visit our IRC channel: #tgstation13 on irc.rizon.net +
    + + + + + +
    + Current Project Maintainers: -Click Here-
    + Currently Active GitHub contributor list: -Click Here-
    + Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor, Polymorph, Carn, Nodrak, Donkie, Sieve, Giacom, Ikarrus, trubble_bass, Aranclanos, Cael_Aislinn, Cheridan, Intigracy, Malkevin, SuperSayu, DumpDavidson, Tastyfish, Yvar, Elo001, Fleure, ManeaterMildred, Miauw, MrPerson
    + Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor, Ricotez, Ausops, TankNut, Pewtershmitz, Firecage, Nienhaus2
    + Sounds: Skie, Lasty/Vinyl
    + Main Testers: Tenebrosity, Anyone who has submitted a bug to the issue tracker
    + Thanks to: Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image.
    Also a thanks to anybody who has contributed who is not listed here :( Ask to be added here on irc.
    +
    Have a bug to report?
    Visit our Issue Tracker.
    + Please ensure that the bug has not already been reported and use the template provided here. +
    + + +
    +

    16 December 2017

    +

    Armhulen and lagnas2000 (+his team of amazing spriters) updated:

    +
      +
    • Mi-go have entered your realm!
    • +
    +

    Robustin updated:

    +
      +
    • Marauder shields now take twice as long to regenerate and only recharge one charge at a time.
    • +
    • Marauders now have 120hp down from 150hp.
    • +
    • The wizard event "race swap" should now stick to "safer" species.
    • +
    • Zombies are now properly stunned for a maximum of 2 seconds instead of 2/10ths of a second.
    • +
    • Zombie slowdown adjusted from -2 to -1.6.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The shuttle will no longer be autocalled if the round has already ended.
    • +
    +

    Xhuis updated:

    +
      +
    • Vitality matrices don't have visible messages when someone crosses them anymore.
    • +
    + +

    15 December 2017

    +

    AverageJoe82 updated:

    +
      +
    • drones now have night vision
    • +
    • drones no longer have lights
    • +
    +

    Cruix updated:

    +
      +
    • Shuttles now place hyperspace ripples where they are about to land again.
    • +
    +

    Cyberboss updated:

    +
      +
    • Added "$include" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it
    • +
    • Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name byond://server.net:1337
    • +
    • CROSS_SERVER_ADDRESS removed
    • +
    +

    Epoc updated:

    +
      +
    • Adds Cybernetic Lungs to the Cyber Organs research node
    • +
    +

    JStheguy updated:

    +
      +
    • Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics.
    • +
    • Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN
    • +
    • Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel.
    • +
    +

    Naksu updated:

    +
      +
    • Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later
    • +
    • Tidied up some loc assignments
    • +
    • fixes the remaining loc assignments
    • +
    +

    ShizCalev updated:

    +
      +
    • Revamped gun dry-firing sounds.
    • +
    • Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Remote signaler and other non-telecomms radio code has been cleaned up.
    • +
    +

    Xhuis updated:

    +
      +
    • Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively.
    • +
    • As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different.
    • +
    • Some grinding recipes that didn't work, like dead mice and glowsticks, now do.
    • +
    • All-In-One grinders now correctly grind up everything, instead of one thing at a time.
    • +
    +

    nicbn updated:

    +
      +
    • Closet sprites changed.
    • +
    + +

    13 December 2017

    +

    Naksu updated:

    +
      +
    • glass shards and bananium floors no longer make a sound when "walked" over by a camera or a ghost
    • +
    +

    SpaceManiac updated:

    +
      +
    • Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description.
    • +
    +

    deathride58 updated:

    +
      +
    • Genetics will no longer have a random block completely disappear each round
    • +
    + +

    12 December 2017

    +

    Mark9013100 updated:

    +
      +
    • Medical Wardrobes now contain an additional standard and EMT labcoat.
    • +
    +

    Robustin updated:

    +
      +
    • The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These "revivals" will not count toward the revive limit.
    • +
    • The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These "revivals" will not drain the rune's energy.
    • +
    +

    Swindly updated:

    +
      +
    • Swarmers can no longer deconstruct objects with living things in them.
    • +
    +

    kevinz000 updated:

    +
      +
    • You can now print telecomms equipment again.
    • +
    + +

    11 December 2017

    +

    Anonmare updated:

    +
      +
    • Booze-o-mats have beer
    • +
    +

    Cruix updated:

    +
      +
    • The white ship navigation computer now takes 10 seconds to designate a landing spot, and users can no longer see the syndicate shuttle or its custom landing location. If the white ship landing location would intersect the syndicate shuttle or its landing location, it will fail after the 10 seconds have elapsed.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Some hardsuits have had their melee, fire and rad armor ratings tweaked.
    • +
    +

    Improvedname updated:

    +
      +
    • cats now drop their ears and tail when butchered.
    • +
    +

    Robustin updated:

    +
      +
    • Modes not in rotation have had their "false report" weights for the Command Report standardized
    • +
    +

    SpaceManiac updated:

    +
      +
    • The MULEbots that the station starts with now show their ID numbers.
    • +
    • The dependency by Advanced Cybernetic Implants and Experimental Flight Equipment on Integrated HUDs has been restored.
    • +
    +

    kevinz000 updated:

    +
      +
    • flightsuits should no longer disappear when you take them off involuntarily
    • +
    • beam rifles actually fire striaght now
    • +
    • click catchers now actually work
    • +
    • you no longer see space in areas you normally can't see, instead of black. in reality you can still see space but it's faint enough that you can't tell so I'll say I fixed it.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Added MANY new types of airlock assembly that can be built with metal. Use metal in hand to see the new airlock assembly recipes.
    • +
    • Added new airlock types to the RCD and airlock painter
    • +
    • Vault door assemblies can be built with 8 plasteel, high security assemblies with 6 plasteel
    • +
    • Glass mineral airlocks are finally constructible. Use glass and mineral sheets on an airlock assembly in any order to make them.
    • +
    • Glass and mineral sheets are now able to be welded out of door assemblies rather than having to deconstruct the whole thing
    • +
    • Airlock painter no longer works on airlock assemblies (still works on airlocks)
    • +
    • Titanium airlocks no longer have any missing overlays
    • +
    + +

    10 December 2017

    +

    SpaceManiac updated:

    +
      +
    • External airlocks of the mining base and gulag are now cycle-linked.
    • +
    • The pAI software interface is now accessible via an action button.
    • +
    +

    Swindly updated:

    +
      +
    • You can kill yourself with a few more items.
    • +
    +

    XDTM updated:

    +
      +
    • Instead of activating randomly on speech, Godwoken Syndrome randomly grants inspiration, causing the next message to be a Voice of God.
    • +
    +

    Xhuis updated:

    +
      +
    • Flickering lights will now actually flicker and not go between emergency lights and normal lighting.
    • +
    • Emergency lights no longer stay on forever in some cases.
    • +
    +

    kevinz000 updated:

    +
      +
    • Nanotrasen would like to remind crewmembers and especially medical personnel to stand clear of cadeavers before applying a defibrillator shock. (You get shocked if you're pulling/grabbing someone being defibbed.)
    • +
    • defib shock/charge sounds upped from 50% to 75%.
    • +
    + +

    08 December 2017

    +

    Dax Dupont updated:

    +
      +
    • Fixed observer chat flavor of silicon chat.
    • +
    • Grilles now no longer revert to a pre-broken icon state when you hit them after they broke.
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Minor fixes to some techweb nodes
    • +
    • Made flight suits, combat implants, and combat modules require more nodes
    • +
    +

    Fox McCloud updated:

    +
      +
    • Slime blueprints can now make an area compatible with Xenobio consoles, regardless of the name of the new area
    • +
    +

    MrDoomBringer updated:

    +
      +
    • All stations have been outfitted with brand new Smoke Machines! They have nicer sprites now!
    • +
    +

    Shadowlight213 updated:

    +
      +
    • You now can get a medal for wasting hours talking to the secret debug tile.
    • +
    • Fixed runtime for the tile when poly's speech file doesn't exist.
    • +
    +

    Xhuis updated:

    +
      +
    • You can now make pet carriers from the autolathe, to carry around chef meat and other small animals without having to drag them. The HoP, captain, and CMO also start with carriers in their lockers for their pets.
    • +
    +

    YPOQ updated:

    +
      +
    • Fixed the camera failure, race swap, cursed items, and imposter wizard random events
    • +
    • The cursed items event no longer nullspaces items
    • +
    +

    jammer312 updated:

    +
      +
    • Action buttons now remember positions where you locked.
    • +
    • Now locking action buttons prevents them from being reset.
    • +
    + +

    07 December 2017

    +

    ShizCalev updated:

    +
      +
    • Games vending machines can now properly be rebuilt.
    • +
    • Games vending machines can now be refilled via supply crates.
    • +
    • Games Supply Crates have been added to the cargo console.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Radio frequency 148.9 is once again serviced by the telecomms system.
    • +
    +

    Xhuis updated:

    +
      +
    • Added the Eminence role to clockcult! Players can elect themselves or ghosts as the Eminence from the eminence spire structure on Reebe.
    • +
    • The Eminence is incorporeal and invisible, and directs the entire cult. Anything they say is heard over the Hierophant network, and they can issue commands by middle-clicking themselves or different turfs.
    • +
    • The Eminence also has a single-use mass recall that warps all servants to the Ark chamber.
    • +
    • Added traps, triggers, and brass filaments to link them. They can all be constructed from brass sheets, and do different things and trigger in different ways. Current traps include the brass skewer and steam vent, and triggers include the pressure sensor, lever, and repeater.
    • +
    • The Eminence can activate trap triggers by clicking on them!
    • +
    • Servants can deconstruct traps instantly with a wrench.
    • +
    • Mending Mantra has been removed.
    • +
    • Clockwork scriptures have been recolored and sorted based on their functions; yellow scriptures are for construction, red for offense, blue for defense, and purple for niche.
    • +
    • Servants now spawn with a PDA and black shoes to make disguise more feasible.
    • +
    • The Eminence can superheat up to 20 clockwork walls at a time. Superheated walls are immune to hulk and mech punches, but can still be broken conventionally.
    • +
    • Clockwork walls are slightly faster to build before the Ark activates, taking an extra second less.
    • +
    • Poly no longer continually undergoes binary fission when Ratvar is in range.
    • +
    • The global records alert for servants will no longer display info that doesn't affect them since the rework.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Box Station has been moved from the Testing Lab to the Morgue/Robotics maintenance tunnel.
    • +
    +

    deathride58 updated:

    +
      +
    • The default view range can now be defined in the config. The default is 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen range is 21x15. Do note that changing this value will affect the title screen. The title screen images and the title screen area on the Centcom z-level will have to be updated if the default view range is changed.
    • +
    + +

    06 December 2017

    +

    Dax Dupont & Alek2ander updated:

    +
      +
    • Binary chat messages been made more visible.
    • +
    +

    Revenant Defile ability updated:

    +
      +
    • Revenant's Defile now removes salt piles
    • +
    +

    XDTM updated:

    +
      +
    • Brain damage has been completely reworked! remove: Brain damage now no longer simply makes you dumb. Although most of its effects have been shifted into a brain trauma.
    • +
    • Every time you take brain damage, there's a chance you'll suffer a brain trauma. There are many variations of brain traumas, split in mild, severe, and special.
    • +
    • Mild brain traumas are the easiest to get, can be lightly to moderately annoying, and can be cured with mannitol and time.
    • +
    • Severe brain traumas are much rarer and require extensive brain damage before you have a chance to get them; they are usually very debilitating. Unlike mild traumas, they require surgery to cure. A new surgery procedure has been added for this, the aptly named Brain Surgery. It can also heal minor traumas.
    • +
    • Special brain traumas are rarely gained in place of Severe traumas: they are either complex or beneficial. However, they are also even easier to cure than mild traumas, which means that keeping these will usually mean keeping a mild trauma along with it.
    • +
    • Mobs can only naturally have one mild trauma and one severe or special trauma.
    • +
    • Brain damage will now kill and ruin the brain if it goes above 200. If it somehow goes above 400, the brain will melt and be destroyed completely.
    • +
    • Many brain-damaging effects have been given a damage cap, making them non-lethal.
    • +
    • The Unintelligible mutation has been removed and made into a brain trauma.
    • +
    • Brain damage no longer makes using machines a living hell.
    • +
    • Abductors give minor traumas to people they experiment on.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Metastation has been moved to the maintenance by Robotics.
    • +
    + +

    05 December 2017

    +

    Cyberboss updated:

    +
      +
    • Reduced the volume of showers
    • +
    +

    Dax Dupont updated:

    +
      +
    • Nanotrasen is happy to announce the pinnacle in plasma research! The Disco Inferno shuttle design is the result of decades of plasma research. Burn, baby, burn!
    • +
    +

    MrPerson & ninjanomnom updated:

    +
      +
    • Completely changed how keyboard input is read.
    • +
    • Holding two directions at the same time will now move you diagonally. This works with the arrow keys, wasd, and the numpad.
    • +
    • Moving diagonally takes twice as long as moving a cardinal direction.
    • +
    • You can use control to turn using wasd and the numpad instead of just the arrow keys.
    • +
    • Some old non-hotkey mode behaviors, especially in relation to chatbox interaction, can't be kept with the new system. Of key note: You can't type while walking. This is due to limitations of byond and the work necessary to overcome it is better done as another overhaul allowing custom controls.
    • +
    +

    Robustin updated:

    +
      +
    • Reverted changes in 3d sound system that tripled the distance that sound would carry.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Energy values are now measured in joules. What was previously 1 unit is now 1 kJ.
    • +
    • Syndicate uplink implants now work again.
    • +
    +

    Xhuis updated:

    +
      +
    • Stethoscopes now inform the user if the target can be defibrillated; the user will hear a "faint, fluttery pulse."
    • +
    +

    coiax updated:

    +
      +
    • Quiet areas of libraries on station have now been equipped with a vending machine containing suitable recreational activities.
    • +
    + +

    04 December 2017

    +

    AnturK updated:

    +
      +
    • You can now record and replay holopad messages using holodisks.
    • +
    • Holodisks are printable in autolathes.
    • +
    +

    Xhuis updated:

    +
      +
    • You now need fuel in your welder to repair mechs.
    • +
    + +

    03 December 2017

    +

    ExcessiveUseOfCobblestone updated:

    +
      +
    • You can now lay (buckle!) yourself to a bed to avoid being burnt to a crisp during "the floor is lava" event.
    • +
    +

    Robustin updated:

    +
      +
    • Igniting plasma statues no longer ignores ignition temperature and only creates as much plasma as was used in its creation.
    • +
    +

    Xhuis updated:

    +
      +
    • Light fixtures now turn an ominous, dim red color when they lose power, and draw from an internal power cell to maintain it until either the cell dies (usually after 10 minutes) or power is restored.
    • +
    • You can override emergency light functionality from an APC. You can also click on individual lights as a cyborg or AI to override them individually. Traitor AIs also have a new ability that disables emergency lights across the entire station.
    • +
    +

    zennerx updated:

    +
      +
    • fixed some typos in the weapon firing mechanism description
    • +
    + +

    02 December 2017

    +

    BeeSting12 updated:

    +
      +
    • Occupand ---> Occupant on opened cryogenic pods.
    • +
    • Cyrogenic ---> Cryogenic on opened cryogenic pods.
    • +
    +

    CosmicScientist updated:

    +
      +
    • You can make plushies kiss one another!
    • +
    +

    Frozenguy5 updated:

    +
      +
    • The Particle Accelerator's wires can no longer be EMP'd
    • +
    +

    Naksu updated:

    +
      +
    • Cleans up some loc assignments
    • +
    +

    Robustin updated:

    +
      +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • Clockwork magicks will now prevent Bags of Holding from being combined on Reebe.
    • +
    • Flashes will now burn out AFTER flashing when they fail instead of being a ticking time bomb that waits to screw you over on your next attempt.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The R&D Console has been given a much prettier interface.
    • +
    • Research scanner goggles now show materials and technology prospects in a nicer way.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Construct shells have a new animated sprite
    • +
    + +

    30 November 2017

    +

    ninjanomnom updated:

    +
      +
    • Reduced the max volume of sm by 1/5th and made the upper bounds only play mid delamination.
    • +
    +

    psykzz updated:

    +
      +
    • Fixing the broken turbine computer
    • +
    + +

    29 November 2017

    +

    MrStonedOne updated:

    +
      +
    • The sloth no longer suspiciously moves fast when gliding between tiles.
    • +
    • The sloth's movespeed when inhabited by a player has been lowered from once every 1/5 of a second to once every second.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The techweb node for mech LMGs no longer claims to be for mech tasers.
    • +
    + +

    28 November 2017

    +

    ACCount updated:

    +
      +
    • "Machine prototype" is removed from the game.
    • +
    • Mass-spectrometers are removed. Would anyone notice if not for this changelog entry?
    • +
    +

    Cruix updated:

    +
      +
    • AI and observer diagnostic huds will now show the astar path of all bots, and Pai bots will be given a visible path to follow when called by the AI.
    • +
    +

    JJRcop updated:

    +
      +
    • Fixed the Make space ninja verb.
    • +
    +

    Naksu updated:

    +
      +
    • rejiggered botcode a little bit
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admin-added "download research" objectives are now consistent with automatic ones.
    • +
    +

    improvedname updated:

    +
      +
    • toolbelts can now carry geiger counters
    • +
    +

    uraniummeltdown updated:

    +
      +
    • You can make many different types of office and comfy chairs with metal
    • +
    • Stack menus use /datum/browser
    • +
    + +

    27 November 2017

    +

    ACCount updated:

    +
      +
    • New integrated circuit components: list constructors/deconstructors. Useful for building lists and taking them apart.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixed cult leaders being de-culted upon election if they had a mindshield implant
    • +
    +

    Naksu updated:

    +
      +
    • Hopefully fixed mesons granting the ability to hear people through walls.
    • +
    +

    Okand37 updated:

    +
      +
    • Re-organized Delta's departmental protolathes for all departments.
    • +
    • Re-organized Delta's ORM placement by connecting it to the mining office, which now has a desk for over handing materials to the outside.
    • +
    • Added a second Nanomed to Deltastation's medical bay.
    • +
    • Nanotrasen has decided to add proper caution signs to most docking ports on Deltastation, warning individuals to be cautious around these areas.
    • +
    • Two health sensors are now placed in Deltastation's robotics area for medibots.
    • +
    • Atmospheric Technicians at Deltastation can now open up their gas storage in the supermatter power area as intended.
    • +
    +

    WJohnston updated:

    +
      +
    • Fixed a case where items would sometimes be placed underneath racks.
    • +
    +

    XDTM updated:

    +
      +
    • Viruses' healing symptoms have been reworked!
    • +
    • All existing healing symptoms have been removed in favour of new ones.
    • +
    • Weight Even and Weight Gain have been removed, so hunger can be used for balancing in symptoms.
    • +
    • Starlight Condensation heals toxin damage if you're in space using starlight as a catalyst. Being up to two tiles away also works, as long as you can still see it, but slower.
    • +
    • Toxolysis (level 7) rapidly cleanses all chemicals from the body, with no exception.
    • +
    • Cellular Molding heals brute damage depending on your body temperature: the higher the temperature, the faster the healing. Requires above-average temperature to activate, and the speed heavily increases while on fire.
    • +
    • Regenerative Coma (level 8) causes the virus to send you into a deep coma when you are heavily damaged (>70 brute+burn damage). While you are unconscious, either from the virus or from other sources, the virus will heal both brute and burn damage fairly quickly. Sleeping also works, but at reduced speed.
    • +
    • Tissue Hydration heals burn damage if you are wet (negative fire stacks) or if you have water in your bloodstream.
    • +
    • Plasma Fixation (level 8) stabilizes temperature and heals burns while plasma is in your body or while standing in a plasma cloud. Does not protect from the poisoning effects of plasma.
    • +
    • Radioactive Resonance gives a mild constant brute and burn healing while irradiated. The healing becomes more intense if you reach higher levels of radiation, but is still less than the alternatives.
    • +
    • Metabolic Boost (level 7) doubles the rate at which you process chemicals, good and bad, but also increases hunger tenfold.
    • +
    +

    kevinz000 updated:

    +
      +
    • Cryo cells can now be properly rotated with a wrench.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now make a new tasty traditional treat: butterdogs. Watch out, they're slippery.
    • +
    + +

    25 November 2017

    +

    CosmicScientist updated:

    +
      +
    • bolas are back in tablecrafting!
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Catpeople are now distracted instead of debilitated
    • +
    • Normal cats now go for laser pointers
    • +
    +

    SpaceManiac updated:

    +
      +
    • You can no longer buckle people to roller beds from inside of a locker.
    • +
    +

    YPOQ updated:

    +
      +
    • AIs and cyborgs can interact with unscrewed airlocks and APCs.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes thermite burning hotter than the boiling point of stone
    • +
    +

    zennerx updated:

    +
      +
    • Zombies don't reanimate with no head!
    • +
    + +

    24 November 2017

    +

    ACCount updated:

    +
      +
    • Removed "console screen" stock part. Just use glass sheets instead.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Spessmen are now smart enough to realize you don't need to turn around to pull cigarette butts
    • +
    +

    SpaceManiac updated:

    +
      +
    • Fix water misters being inappropriately glued to hands in some cases.
    • +
    • Some misplaced decals in the Hotel brig have been corrected.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Custom shuttle dockers can no longer place docking regions inside other custom docker regions.
    • +
    + +

    23 November 2017

    +

    GupGup updated:

    +
      +
    • Fixes hostile mobs attacking surrounding tiles when trying to attack someone
    • +
    +

    MrStonedOne and Jordie updated:

    +
      +
    • As a late note, serverops be advise that mysql is no longer supported. existing mysql databases will need to be converted to mariadb
    • +
    +

    Robustin updated:

    +
      +
    • RND consoles will no longer display options for machines or disks that are not connected/inserted.
    • +
    +

    ShizCalev updated:

    +
      +
    • Aliens in soft-crit will now use the correct sprite.
    • +
    +

    XDTM updated:

    +
      +
    • Added two new symptoms: one allows viruses to still work while dead, and allows infection of undead species, and one allows infection of inorganic species (such as plasmapeople or golems).
    • +
    + +

    22 November 2017

    +

    ACCount updated:

    +
      +
    • Old integrated circuit save file format is ditched in favor of JSON. Readability, both of save files and save code, is improved greatly.
    • +
    • Integrated circuit panels now open with screwdriver instead of crowbar, to match every single other thing on this server.
    • +
    • Integrated circuit printer now stores up to 25 metal sheets.
    • +
    • Fixed integrated circuit rechargers not recharging guns properly and not updating icons.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    Anonmare updated:

    +
      +
    • Laserpoitners now incapcitate catpeople
    • +
    +

    AutomaticFrenzy updated:

    +
      +
    • cell chargers weren't animating properly
    • +
    • disable_warning wasn't getting checked and the chat was being spammed
    • +
    +

    Code by Pyko, Ported by Frozenguy5 updated:

    +
      +
    • Rat Kebabs and Double Rat Kebabs have been added!
    • +
    +

    Cyberboss updated:

    +
      +
    • Server tools API changed to version 3.2.0.1
    • +
    • "ahelp" chat command can now accept a ticket number as opposed to a ckey
    • +
    +

    DaxDupont updated:

    +
      +
    • CentCom has issued a firmware updated for the operating computers. It is no longer needed to manually refresh the procedure and patient status.
    • +
    • Proximity sensors no longer beep when unarmed.
    • +
    • Plant trays will now properly process fluorine and adjust toxins and water contents.
    • +
    +

    Francinum updated:

    +
      +
    • The shuttle build plate is now better sized for all stations.
    • +
    +

    Iamgoofball updated:

    +
      +
    • fixes grammar on logic gate descriptions
    • +
    • fixes grammar on list circuits
    • +
    • fixes grammar on trig circuits
    • +
    • fixed grammar on output circuits
    • +
    +

    JJRcop updated:

    +
      +
    • Fixes changeling eggs not putting the changeling in control if the brainslug is destroyed before hatching.
    • +
    • The silicon airlock menu looks a little more like it used to.
    • +
    +

    Kor updated:

    +
      +
    • Blobbernauts will no longer spawn if a player is not selected to control it, preventing AI blobbernauts from running off the blob and to their deaths.
    • +
    • Following complaints that cargo has been selling all the materials they receive rather than distributing them, mineral exporting has been removed.
    • +
    +

    MMMiracles updated:

    +
      +
    • Power regen on the regular tesla relay has been reduced to 50, from 150.
    • +
    +

    Naksu updated:

    +
      +
    • Sped up saycode to remove free lag from highpop
    • +
    • Using a chameleon projector will now dismount you from any vehicles you are riding, in order to prevent wacky space glitches and being sent to a realm outside space and time.
    • +
    +

    Shadowlight213 updated:

    +
      +
    • Added round id to the status world topic
    • +
    +

    ShizCalev updated:

    +
      +
    • Chameleon goggles will no longer go invisible when selecting Optical Tray scanners.
    • +
    • Engineering and Atmos scanner goggles will now have correctly colored inhand sprites.
    • +
    • The computers on all maps have have been updated for the latest directional sprite changes. Please report any computers facing in strange directions to your nearest mapper.
    • +
    • MetaStation - The consoles in medbay have had their directions corrected.
    • +
    • The Nanotrasen logo on modular computers has been fixed, rejoice!
    • +
    • PubbyStation - Unpowered air injectors in various locations have been fixed.
    • +
    • MetaStation - Air injector leading out of the incinerator has been fixed
    • +
    • MetaStation - Corrected a couple maintenance airlocks being powered by the wrong areas.
    • +
    • Computers will no longer rotate incorrectly when being deconstructed.
    • +
    • You can now rotate computer frames during construction.
    • +
    • Chairs, PA parts, infrared emitters, and doppler arrays will now rotate clockwise.
    • +
    • Throwing drinking glasses and cartons will now consistently cause them to break!
    • +
    • Humans missing legs or are legcuffed will no longer move slower in areas without gravity.
    • +
    • The structures external to stations are now properly lit. Make sure you bring a flashlight.
    • +
    • Computers will no longer delete themselves when being built, whoops!
    • +
    • Space cats will no longer have a smashed helmet when they lay down.
    • +
    +

    Skylar Lineman, your local R&D moonlighter updated:

    +
      +
    • Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research "nodes" with research points passively generated when there is atleast one research server properly cooled, powered, and online.
    • +
    • R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department.
    • +
    • The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!
    • +
    • You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points.
    • +
    • You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent "world destroyer" bombs from instantly finishing research.
    • +
    +

    SpaceManiac updated:

    +
      +
    • HUDs from mechs and helmets no longer conflict with HUD glasses and no longer inappropriately remove implanted HUDs.
    • +
    • Chasm code has been refactored to be more sane.
    • +
    • Building lattices over chasms no longer sometimes deletes the chasm.
    • +
    • Ladders have been refactored and should be far less buggy.
    • +
    • Jacob's ladder actually works again.
    • +
    • Pizza box stacking works again.
    • +
    • Fix some permanent-on and permanent-off bugs caused by the HUD stacking change.
    • +
    +

    WJohnston updated:

    +
      +
    • A bunch of new turf decals for mappers to play with, coming in yellow, white, and red varieties!
    • +
    • Green banded default airlocks now have extended click area like all other airlocks.
    • +
    +

    Y0SH1 M4S73R updated:

    +
      +
    • The R&D Server's name is now improper.
    • +
    • The R&D Server now has an explanation of what it does.
    • +
    +

    arsserpentarium updated:

    +
      +
    • now lists should work properly
    • +
    +

    duncathan updated:

    +
      +
    • The RPD has a shiny new UI!
    • +
    • The RPD can now paint pipes as it lays them, for quicker piping projects.
    • +
    • Atmos scrubbers (vent and portable) can now filter any and all gases.
    • +
    +

    ike709 updated:

    +
      +
    • Added new vent and scrubber sprites by Partheo.
    • +
    • Fixed some computers facing the wrong direction.
    • +
    +

    jammer312 updated:

    +
      +
    • fixed conjuration spells forgetting about conjured items
    • +
    +

    kevinz000 updated:

    +
      +
    • purple bartender suit and apron added to clothesmates!
    • +
    • long hair 3 added, check it out. both have sprites from okand!
    • +
    +

    nicbn updated:

    +
      +
    • Now rolling beds and office chairs have a sound!
    • +
    +

    oranges updated:

    +
      +
    • Removed the shocker circuit
    • +
    +

    psykzz updated:

    +
      +
    • Grilles have new damaged and default sprites
    • +
    • Added TGUI for Turbine computer
    • +
    +

    tserpas1289 updated:

    +
      +
    • Any suit that could hold emergency oxygen tanks can now also hold plasma man internals
    • +
    • Hydroponics winter coats now can hold emergency oxygen tanks just like the other winter coats.
    • +
    • Plasma men jumpsuits can now hold accessories like pocket protectors and medals.
    • +
    +

    zennerx updated:

    +
      +
    • fixed a bug that made you try and scream while unconscious due to a fire
    • +
    • Skateboard crashes now give slight brain damage!
    • +
    • Using a helmet prevents brain damage from the skateboard!
    • +
    + +

    15 November 2017

    +

    Fury updated:

    +
      +
    • Added new sprites for the Heirophant Relay (clock cultist telecomms equipment).
    • +
    +

    Naksu updated:

    +
      +
    • Removed fire-related free lag. change: fire alarms and cameras no longer work after being ripped off a wall by a singulo
    • +
    • Minor speedups to movement processing. change: Fat mobs no longer gain temperature by running.
    • +
    +

    Robustin updated:

    +
      +
    • Cult population scaling no longer operates on arbitrary breakpoints. Each additional player between the between the breakpoints will add to the "chance" that an additional cultist will spawn.
    • +
    • On average you will see less roundstart cultists in lowpop and more roundstart cultists in highpop.
    • +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • The tesla will now move toward power beacons at a significantly slower rate.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The post-round station integrity report is now functional again.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Gas overlays no longer block clicks, on 512
    • +
    + +

    14 November 2017

    +

    ike709 updated:

    +
      +
    • Added directional computer sprites. Maps haven't been changed yet.
    • +
    +

    psykzz updated:

    +
      +
    • AI Airlock UI to use TGUI
    • +
    • Allow AI to swap between electrified door states without having to un-electrify first.
    • +
    +

    selea/arsserpentarium updated:

    +
      +
    • Integrated circuits have been added to Research!
    • +
    • You can use these to create devices with very complex behaviors.
    • +
    • Research the Integrated circuits printer to get started.
    • +
    + +

    13 November 2017

    +

    Cobby updated:

    +
      +
    • The Xray now only hits the first mob it comes into contact with instead of being outright removed from the game.
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Reebe now has ambience sounds
    • +
    +

    Floyd / Qustinnus: updated:

    +
      +
    • Adds a few sound_loop datums to machinery.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Broken cable cuffs no longer has an invisible sprite.
    • +
    +

    PKPenguin321 updated:

    +
      +
    • Welders must now be screwdrivered open to reveal their fuel tank.
    • +
    • You can empty welders into open containers (like beakers or glasses) when they're screwdrivered open.
    • +
    • You can now insert any chemical into a welder, but all most will do is clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends to explode.
    • +
    +

    Qbopper and JJRcop updated:

    +
      +
    • The default internet sound volume was changed from 100 to 25. Stop complaining in OOC about your ears!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Posters may no longer be placed on diagonal wall corners.
    • +
    +

    WJohnston updated:

    +
      +
    • Removes stationary docking ports for syndicate infiltrator ships on all maps. Use the docking navigator computer instead! This gives the white ship and syndicate infiltrator more room to navigate and place custom locations that are otherwise occupied by fixed shuttle landing zones that are rarely used.
    • +
    +

    Xhuis updated:

    +
      +
    • Deep fryers now have sound.
    • +
    • Deep fryers now use cooking oil, a specialized reagent that becomes highly damaging at high temperatures. You can get it from grinding soybeans and meat.
    • +
    • Deep fryers now become more efficient with higher-level micro lasers, using less oil and frying faster.
    • +
    • Deep fryers now slowly use oil as it fries objects, instead of all at once.
    • +
    • You can now correctly refill deep fryers with syringes and pills.
    • +
    +

    nicn updated:

    +
      +
    • Damage from low pressure has been doubled.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now select a nearby area to expand when using a blueprint instead of making a new area.
    • +
    • New shuttle areas can be created using blueprints. This is currently not useful but will be used later for shuttle construction.
    • +
    • Blueprints can modify existing areas on station.
    • +
    • Blueprint functionality has been added to the debug tab as a verb.
    • +
    + +

    12 November 2017

    +

    Cyberboss updated:

    +
      +
    • Clockwork slabs no longer refer to components
    • +
    + +

    11 November 2017

    +

    DaxDupont updated:

    +
      +
    • Medbots can inject from one tile away again.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The detective and heads of staff are no longer attacked by portable turrets.
    • +
    +

    deathride58 updated:

    +
      +
    • You can no longer delete girders, lattices, or catwalks with the RPD
    • +
    • Fixes runtimes that occur when clicking girders, lattices, catwalks, or disposal pipes with the RPD in paint mode
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes ruin cable spawning and probably some other bugs
    • +
    + +

    10 November 2017

    +

    Anonmare updated:

    +
      +
    • Adds an organ storage bag to the syndicate medborg.
    • +
    +

    AnturK updated:

    +
      +
    • Dying in shapeshifted form reverts you to the original one. (You're still dead)
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Redtexting as a traitor now plays a depressing tune to you
    • +
    +

    Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation) updated:

    +
      +
    • Adds about 30 new ambience sounds
    • +
    • added new defines for ambience lists.
    • +
    +

    Iamgoofball updated:

    +
      +
    • Cooldown on the Ripley's mining drills has been halved.
    • +
    • The frequency of the Ripley's ore pulse has been doubled.
    • +
    +

    Jalleo updated:

    +
      +
    • Removed a variable to state which RCD's can deconstruct reinforced walls
    • +
    • Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside borg ones
    • +
    +

    Kor updated:

    +
      +
    • Cult mode will once again print out names at round end.
    • +
    +

    Mark9013100 updated:

    +
      +
    • Deltastation now has a Whiteship.
    • +
    • Charcoal bottles have been renamed, and have been given a more informative description.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • spellchecked the hotel staff.
    • +
    • Added frog masks. Reeeeeeeeee!!
    • +
    +

    More Robust Than You updated:

    +
      +
    • Blobbernauts and spores are no longer killed by blob victory
    • +
    • New blob overminds off the station Z level are moved to the station
    • +
    • You can now use banhammers as a weapon
    • +
    • Monkeys can no longer transmit diseases through hardsuits
    • +
    • Xenobio blobbernauts can no longer walk on blob tiles
    • +
    +

    Naksu updated:

    +
      +
    • Added deterministic output slots to the slime processor
    • +
    • Fixed some interactions with ghosts and items
    • +
    • Nonhumans such as monkeys can now be scanned for chemicals with the health analyzer.
    • +
    +

    Okand37 (DeltaStation Updates) updated:

    +
      +
    • Tweaked Atmospherics
    • +
    • Fixed the Incinerator air injector
    • +
    • Tweaked Engineering
    • +
    • Added logs to the Chaplain's closet for gimmicks (bonfires)
    • +
    • Tweaked Security
    • +
    • Fixed medical morgue maintenance not providing radiation shielding and exterior chemistry windoor
    • +
    • Bar now has a door from the backroom to the theatre stage
    • +
    • Tweaked Locker Room/Dormitories
    • +
    +

    ShizCalev updated:

    +
      +
    • You can now -actually- load pie cannons.
    • +
    • The captain's winter coat can now hold a flashlight.
    • +
    • The captain's and security winter coats can now hold internals tanks.
    • +
    • All winter coats can now hold toys, lighters, and cigarettes.
    • +
    • The captain's hardsuit can now hold pepperspray.
    • +
    • Updated the Test Map debugging verb to report more issues regarding APCs. DELTASTATION
    • +
    • Reverted Okand37's morgue changes which broke power in the area.
    • +
    • Corrected wrong area on the Southern airlock leading into electrical maintenance. ALL STATIONS
    • +
    • Corrected numerous duplicate APCs in areas which led to power issues.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Ghosts can no longer create sparks from the hand teleporter's portals.
    • +
    • Digging on Lavaland no longer shows two progress bars.
    • +
    • The holodeck now has an "Offline" option.
    • +
    • Injury and crit overlays are now scaled properly for zoomed-out views.
    • +
    • Already-downloaded software is now hidden from the NTNet software downloader.
    • +
    • The crafting, language, and building buttons are now positioned correctly in zoomed-out views.
    • +
    • Bluespace shelter walls no longer smooth with non-shelter walls and windows.
    • +
    +

    Swindly updated:

    +
      +
    • Organ storage bags can be used to perform limb augmentation.
    • +
    • You can now cancel a cavity implant during the implanting/removing step by using drapes while holding the appropriate tool in your inactive hand. Cyborgs can cancel the surgery by using drapes alone.
    • +
    • Fixed hot items and fire heating reagents to temperatures higher than their heat source.
    • +
    • Sprays can now be heated with hot items.
    • +
    • The heating of reagents by hot items, fire, and microwaves now scales linearly with the difference between the reagent holder's temperature and the heat source's temperature instead of constantly.
    • +
    • The body temperature of a mob with reagents is affected by the temperature of the mob's reagents.
    • +
    • Reagent containers can now be heated by hot air.
    • +
    +

    Thefastfoodguy updated:

    +
      +
    • Spamming runes / battlecries / etc will no longer trigger spam prevention
    • +
    +

    WJohnston updated:

    +
      +
    • Ancient station lighting fixed on beta side (medical and atmos remains)
    • +
    +

    XDTM updated:

    +
      +
    • Ghosts now have a Toggle Health Scan verb, which allows them to health scan mobs they click on.
    • +
    +

    Xhuis updated:

    +
      +
    • Ratvar and Nar-Sie plushes now have a unique interaction.
    • +
    • Clockwork marauders are now on harm intent.
    • +
    • The Clockwork Marauder scripture now takes five seconds longer to invoke per marauder summoned in the last 20 seconds, capping at 30 extra seconds.
    • +
    • Clockwork marauders no longer gain a health bonus when war is declared.
    • +
    • Moved the BoxStation deep fryers up one tile.
    • +
    • Microwaves have new sounds!
    • +
    +

    YPOQ updated:

    +
      +
    • EMPs can pulse multiple wires
    • +
    +

    as334 updated:

    +
      +
    • Pluoxium can now be formed by irradiating tiles with CO2 in the air.
    • +
    • Rad collectors now steadily form Tritium at a slow pace.
    • +
    • Nerfs fusion by making it slower, and produce radioactivity.
    • +
    • Noblium formation now requires significantly more energy input.
    • +
    • Tanks now melt if their temperature is above 1 Million Kelvin.
    • +
    +

    deathride58 updated:

    +
      +
    • Directional character icon previews now function properly. Other things relying on getflaticon probably work with directional icons again, as well.
    • +
    +

    nicbn updated:

    +
      +
    • Canister sprites for the new gases
    • +
    +

    ninjanomnom updated:

    +
      +
    • Shuttle parallax has been fixed once more
    • +
    • You can no longer set up the auxiliary base's shuttle beacon overlapping with the edge of the map
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Replica fabricatoring airlocks and windoors keeps the old name
    • +
    • Narsie and Ratvar converting airlocks and windoors keeps the old name
    • +
    + +

    02 November 2017

    +

    ACCount updated:

    +
      +
    • "Tail removal" and "tail attachment" surgeries are merged with "organ manipulation".
    • +
    • New sprites for reflectors. They finally look like something.
    • +
    • You can lock reflector's rotation by using a screwdriver. Use the screwdriver again to unlock it.
    • +
    • Reflector examine now shows the current angle and rotation lock status.
    • +
    • You can now use a welder to repair damaged reflectors.
    • +
    • Multiple reflector bugs are fixed.
    • +
    +

    Improvedname updated:

    +
      +
    • Removes statues from gold slime pool
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Updated Clown Box sprite to match the others.
    • +
    +

    More Robust Than You updated:

    +
      +
    • ONLY ADMINS CAN ACTIVATE THE ARK NOW
    • +
    • The Ark's time measurements are now a bit more readable
    • +
    +

    MrStonedOne updated:

    +
      +
    • Meteor events will not happen before 25 minutes, the worst versions before 35 and 45 minutes.
    • +
    • Meteor events are now player gated to 15, 20, and 25 players respectively
    • +
    • The more destructive versions of meteor events now have a slightly higher chance of triggering, to offset the decrease in how often it is that they will even qualify.
    • +
    • Fixed the changelog generator.
    • +
    +

    Naksu updated:

    +
      +
    • Smartfridges and chem/condimasters now output items in a deterministic 3x3 grid rather than in a huge pile in the middle of the tile.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admins can once again spawn nuke teams on demand.
    • +
    +

    Xhuis updated:

    +
      +
    • Admins can now create sound emitters (/obj/effect/sound_emitter) that can be customized to play sounds to different people, at different volumes, and at different locations such as by z-level. They're much more versatile for events than the Play Sound commands!
    • +
    • You can now add grenades to plushies! You'll need to cut out the stuffing first.
    • +
    • Clockwork cult tips of the round have been updated to match the rework.
    • +
    • Abscond and Reebe rifts now place servants directly at the Ark instead of below the "base" area.
    • +
    +

    nicbn updated:

    +
      +
    • Brown gas renamed to nitryl.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes decals not rotating correctly with the turf.
    • +
    • Fixes a runtime causing some turfs to be left behind by removed shuttles.
    • +
    • Shuttles should be roughly 40-50% smoother.
    • +
    • Fixes the cargo shuttle occasionally breaking if a mob got on at exactly the right time.
    • +
    + +

    30 October 2017

    +

    PKPenguin321 updated:

    +
      +
    • You can now use beakers/cups/etc that have welding fuel in them on welders to refuel them.
    • +
    +

    bgobandit updated:

    +
      +
    • Due to cuts to Nanotrasen's Occupational Safety and Health Administration (NO-SHA) budget, station fixtures no longer undergo as much safety testing. (Translation for rank and file staff: More objects on the station will hurt you.)
    • +
    + +

    29 October 2017

    +

    Armhulen updated:

    +
      +
    • Frost Spiders now use Frost OIL!
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Skeletons can now have their own spectral instruments
    • +
    • \[Dooting Intensifies\]
    • +
    • the variable "too_spooky" defines if it will spawn new instruments, by default TRUE.
    • +
    +

    Naksu updated:

    +
      +
    • Removed meteor-related free lag
    • +
    • Cleaned up dangling mob references from alerts
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer become an enhanced clockwork golem with mutation toxin.
    • +
    • Normal clockwork golems now have 20% armor, down from 40%.
    • +
    +

    as334 updated:

    +
      +
    • This changelog has been updated and so read it again if you are interested in doing assmos.
    • +
    • Atmospherics has been massively expanded including new gases.
    • +
    • These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and Tritium.
    • +
    • Brown Gas is acidic to breath, but mildly stimulation.
    • +
    • Stimulum is more stimulating and much safer.
    • +
    • Pluoxium is a non-reactive form of oxygen that delivers more oxygen into the bloodstream.
    • +
    • Hyper-Noblium is an extremely noble gas, and stops gases from reacting.
    • +
    • Tritium is radioactive and flammable.
    • +
    • New reactions have also been added to create these gases.
    • +
    • Tritium formation: Heat large amounts of oxygen with plasma. Make sure you have a filter ready and setup!
    • +
    • Fusion has been reintroduced. Plasma will fuse when heated to a high thermal energy with Tritium as a catalyst. Make sure to manage the waste products.
    • +
    • Brown Gas formation: Heat Oxygen and Nitrogen.
    • +
    • BZ fixation: Heat Tritium and Plasma.
    • +
    • Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.
    • +
    • Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high heat. Cools rapidly.
    • +
    • Pluoxium is unable to be formed.
    • +
    • Freon has been removed. Use cold nitrogen for your SME problems now.
    • +
    • Water vapor now freezes the tile it is on when it is cooled heavily.
    • +
    +

    naltronix updated:

    +
      +
    • fixes that table that wasnt accessible in Metastation
    • +
    + +

    28 October 2017

    +

    Mark9013100 updated:

    +
      +
    • The Medical Cloning manual has been updated.
    • +
    + +

    27 October 2017

    +

    Anonmare updated:

    +
      +
    • Adds new grindables
    • +
    +

    JamieH updated:

    +
      +
    • Buildmode map generators will now show you a preview of the area you're changing
    • +
    • Buildmode map generators will now ask before nuking the map
    • +
    • Buildmode map generator corners can now only be set by left clicking
    • +
    +

    Kor updated:

    +
      +
    • Cloth golems will be available as a roundstart race during Halloween.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Created a system to profile code on a line by line basis and return detailed info about how much time was spent (in milliseconds) on each line(s).
    • +
    +

    Xhuis updated:

    +
      +
    • Servants can no longer teleport into the gravity generator, EVA, or telecomms.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Hardsuit helmets work like geiger counters for the user.
    • +
    • Radiation should perform a little better in places.
    • +
    • Various radiation symptom thresholds have been tweaked.
    • +
    • Contamination strengths at different ranges have been tweaked.
    • +
    • Contaminated objects have less range for their radiation.
    • +
    • Hitting something with a contaminated object reduces its strength faster.
    • +
    • Contaminated objects decay faster.
    • +
    • Both radiation healing medicines have been buffed a bit.
    • +
    • Passive radiation loss for mobs is nerfed.
    • +
    • There is a soft cap for mob radiation now.
    • +
    • Projectiles, ammo casings, and implants are disallowed from becoming contaminated.
    • +
    • Suit storage units can completely cleanse contamination from stored objects
    • +
    • The first time an object is contaminated enough to spread more contamination admins will be warned. This is also added to stat tracking.
    • +
    • Thermite works on floors and can be ignited by sufficiently hot fires now
    • +
    • Thermite has been made into a component
    • +
    • Thermite no longer removes existing overlays on turfs
    • +
    + +

    26 October 2017

    +

    Kor and JJRcop updated:

    +
      +
    • Added vampires. They will be available as a roundstart race during the Halloween holiday event.
    • +
    +

    ShizCalev updated:

    +
      +
    • Reflectors will no longer drop more materials than they took to make when deconstructed.
    • +
    • You will no longer be prompted to reenter your body while being defibbed if you can't actually be revived.
    • +
    • You can no longer teleport past the ticket stands of the Luxury Emergency Shuttle.
    • +
    • Lightgeists can now -actually- be spawned with gold slime cores.
    • +
    • The Staff of Change will now randomly assign a cyborg module when transforming a mob into a cyborg.
    • +
    +

    Xhuis updated:

    +
      +
    • Clockwork marauders now move more slowly below 40% health.
    • +
    • Instead of a 40% chance (or more) chance to block projectiles, clockwork marauders now have three fixed 100% blocks; after using those three, they cannot block anymore without avoiding projectiles for ten seconds. This number increases to four if war is declared.
    • +
    • Projectiles that deal no damage DO reduce marauders' shield health. Use disabler shots to open them up, then use lasers to go for the kill!
    • +
    • Cogscarab shells and marauder armor now appear in the spawners menu.
    • +
    • You can no longer stack infinitely many stargazers on one tile.
    • +
    +

    nicbn updated:

    +
      +
    • Chemical heater and smoke machine resprited.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Portable generators have a sound while active.
    • +
    • The supermatter has a sound that scales with stored energy.
    • +
    +

    ninjanomnom & Wjohn updated:

    +
      +
    • Cable cuffs now inherit the color of the cables used to make them.
    • +
    • Split cable stacks keep their color.
    • +
    • The blue cable color is now a better blue.
    • +
    + +

    25 October 2017

    +

    Cruix updated:

    +
      +
    • Shuttle navigation computers can now place new transit locations over the shuttle's current position.
    • +
    +

    JJRcop updated:

    +
      +
    • The heart of darkness revives you as a shadowperson if you aren't one already.
    • +
    +

    ShizCalev updated:

    +
      +
    • Shades will no longer always hear a heartbeat.
    • +
    • Golem abilities will now be start on cooldown when they are made.
    • +
    + +

    24 October 2017

    +

    Armhulen updated:

    +
      +
    • Wizards may now shapeshift into viper spiders.
    • +
    +

    Improvedname updated:

    +
      +
    • Blacklists holoparasite's from surplus crates
    • +
    +

    Kor updated:

    +
      +
    • Added dullahans, which will be available from the character set up menu during the Halloween event.
    • +
    • Severed heads will no longer appear bald.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixes champrojector camera bugs
    • +
    +

    Naksu updated:

    +
      +
    • Grinders will now grind grown items like cocoa pods again
    • +
    • Cameras no longer keep hard references to mobs in their motion tracking list.
    • +
    +

    ShizCalev updated:

    +
      +
    • Creatures made via gold slime cores will now be given the proper name of their master.
    • +
    +

    deathride58 updated:

    +
      +
    • Deltastation's armory now contains reinforced windows surrounding the lethal weaponry. This makes Delta's armory consistent with Box.
    • +
    • There are now decals in places where extra Security lockers can spawn.
    • +
    • Cleaned up semicolons in Meta and Boxstation's .dmms
    • +
    + +

    22 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Blood Brother now properly shows up in player panel
    • +
    +

    Naksu updated:

    +
      +
    • Paper bins no longer let server admins know that pens were eaten.
    • +
    • Removed dangling mob references to last attacker/attacked
    • +
    +

    Robustin updated:

    +
      +
    • Medical biosuits (and hardsuits) now offer heavy, but not complete, radiation resistance.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Contents of silicon mobs are no longer considered for targets of radiation. This blocks them from being contaminated.
    • +
    + +

    21 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Heads of staff will now have cat organs removed at roundstart
    • +
    +

    Robustin updated:

    +
      +
    • Spray tan no longer stuns when ingested.
    • +
    +

    Thunder12345 updated:

    +
      +
    • Sentient cats no longer forget to fall over when they die
    • +
    + +

    20 October 2017

    +

    Kor updated:

    +
      +
    • You can now select your Halloween race, rather than having it assigned randomly via event.
    • +
    +

    Robustin updated:

    +
      +
    • Fixed a bug where detonating maxcaps, especially multiple maxcaps, on Reebe guaranteed that everyone would die and thus the Clock Cult would immediately lose; Reebe maxcap is now 2/5/10.
    • +
    +

    ShizCalev updated:

    +
      +
    • All reflector prisms/mirrors have had their angles corrected.
    • +
    • Remains left over by dusting or soul-stoning a mob are now dissoluble with acid.
    • +
    • Changelings using biodegrade to escape restraints will now leave a pile of goop.
    • +
    • Fixed messages related to changelings using biodegrade not appearing.
    • +
    + +

    19 October 2017

    +

    Kor updated:

    +
      +
    • Blob is now a side antagonist.
    • +
    • Event and admin blobs will now be able to choose their spawn location.
    • +
    • Blob can now win in any mode by gaining enough tiles to reach Critical Mass.
    • +
    • Blobs that have Critical Mass have unlimited points, and a minute after achieving critical mass, they will spread to every tile on station, killing anyone still on board and ending the round.
    • +
    • Using an analyzer on a blob will now reveal its progress towards Critical Mass.
    • +
    • The blob event is now more common.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • You will no longer trip on inactive honkbots.
    • +
    • Sentient Honkbots are no longer forced to speak when somebody trip on them.
    • +
    +

    Naksu updated:

    +
      +
    • Manned turrets stop firing when there's no-one in the turret shooting.
    • +
    • mobs will enter a deep power-saving state when there's not much to do except wander around. change: bees are slightly more passive in general
    • +
    +

    deathride58 updated:

    +
      +
    • You can now press Ctrl+H to stop pulling, or simply H to stop pulling if you're in hotkey mode.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Engineering scanner goggles have a radiation mode now
    • +
    • Objects placed under showers are cleansed of radioactive contamination over a short time.
    • +
    • Showers make sound now.
    • +
    +

    oranges updated:

    +
      +
    • Removed the bluespace pipe
    • +
    + +

    18 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fixes automatic fire on guns.
    • +
    +

    Gun Hog updated:

    +
      +
    • The GPS item now correctly changes its name when the GPS tag is changed.
    • +
    +

    Improvedname updated:

    +
      +
    • Reverts katana's to its orginal size being huge
    • +
    +

    Mercenaryblue updated:

    +
      +
    • it should be far easier to clean out your face from multiple cream pies.
    • +
    +

    More Robust Than You updated:

    +
      +
    • People that are burning slightly less will appear to be burning... slightly less.
    • +
    +

    Robustin updated:

    +
      +
    • The smoke machine now properly generates transparent smoke, transmits chemicals, and displays the proper icons.
    • +
    +

    ShizCalev updated:

    +
      +
    • You can no longer build reinforced floors directly on top of dirt, asteroid sand, ice, or beaches. You'll have to first construct flooring on top of it instead.
    • +
    • Corrected mapping issues introduced with the latest SM engine/radiation update across all relevant maps.
    • +
    • The tools on the Caravan Ambush space ruin have had their speeds corrected.
    • +
    • Slappers will no longer appear as a latex balloon in your hand.
    • +
    • Renault now has a comfy new bed on Metastation!
    • +
    • Engineering cyborgs now have access to geiger counters.
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer pick up brass chairs.
    • +
    +

    Y0SH1_M4S73R updated:

    +
      +
    • Disabling leg actuators sets the power drain per step to the correct value.
    • +
    +

    duncathan updated:

    +
      +
    • Filters no longer stop passing any gas through if the filtered output is full.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can vomit blood at high enough radiation.
    • +
    • Radiation knockdown is far far shorter.
    • +
    • Genetics modification is less harmful but still, upgrade your machines.
    • +
    • Pentetic acid is useless for low amounts of radiation but indispensable for high amounts now.
    • +
    • Singularity radiation has been normalized and Pubby engine has been remapped.
    • +
    • No more hair loss spam
    • +
    • Mob rad contamination has been disabled for now. Regular contamination is still a thing.
    • +
    • Fixed turfs not rotating
    • +
    • Fixed stealing structures you shouldn't be moving
    • +
    + +

    17 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fancy boxes(ie: donut boxes) now show the proper content amount in the sprite and no longer go invisible when empty.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • when decapitated, banana-flavored cream no longer hovers where your head used to be.
    • +
    +

    More Robust Than You updated:

    +
      +
    • EI NATH! now causes a flash of light
    • +
    +

    Naksu updated:

    +
      +
    • Pinned notes will now show up on vault, abductor, centcom and large glass airlocks.
    • +
    • Removed a misleading message when handling full stacks of sheets.
    • +
    • Pre-filled glass bottles (uplink, medbay, botany) will now give visual feedback about how much stuff is left inside, and the color of contents will match an empty bottle being filled with the same reagent.
    • +
    • Player-controlled "neutral" mobs such as minebots are now considered valid targets by clock cult's ocular wardens.
    • +
    +

    Xhuis updated:

    +
      +
    • Cogged APCs can now be correctly unlocked with an ID card.
    • +
    +

    duncathan updated:

    +
      +
    • Portable air pumps can output to a maximum of 25 atmospheres.
    • +
    +

    kevinz000 updated:

    +
      +
    • Legacy projectiles have been removed. Instead, all projectiles are now PIXEL PROJECTILES!
    • +
    • Reflectors can now be at any angle you want. Alt click them to set angle!
    • +
    • Pipes can now be layered up to 3 layers.
    • +
    +
    + +GoonStation 13 Development Team +
    + Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    + Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    +
    +
    +

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    +

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    +
    + + diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6a6e5f672c..ab40b78512 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -13457,4 +13457,921 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Thermite no longer removes existing overlays on turfs 2017-10-28: Mark9013100: +<<<<<<< HEAD - tweak: The Medical Cloning manual has been updated. +======= + - tweak: The Medical Cloning manual has been updated. +2017-10-29: + Armhulen: + - rscadd: Frost Spiders now use Frost OIL! + Mercenaryblue: + - rscadd: Skeletons can now have their own spectral instruments + - rscadd: \[Dooting Intensifies\] + - admin: the variable "too_spooky" defines if it will spawn new instruments, by + default TRUE. + Naksu: + - bugfix: Removed meteor-related free lag + - bugfix: Cleaned up dangling mob references from alerts + Xhuis: + - bugfix: You can no longer become an enhanced clockwork golem with mutation toxin. + - balance: Normal clockwork golems now have 20% armor, down from 40%. + as334: + - spellcheck: This changelog has been updated and so read it again if you are interested + in doing assmos. + - rscadd: Atmospherics has been massively expanded including new gases. + - rscadd: These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and + Tritium. + - rscadd: Brown Gas is acidic to breath, but mildly stimulation. + - rscadd: Stimulum is more stimulating and much safer. + - rscadd: Pluoxium is a non-reactive form of oxygen that delivers more oxygen into + the bloodstream. + - rscadd: Hyper-Noblium is an extremely noble gas, and stops gases from reacting. + - rscadd: Tritium is radioactive and flammable. + - rscadd: New reactions have also been added to create these gases. + - rscadd: 'Tritium formation: Heat large amounts of oxygen with plasma. Make sure + you have a filter ready and setup!' + - rscadd: Fusion has been reintroduced. Plasma will fuse when heated to a high thermal + energy with Tritium as a catalyst. Make sure to manage the waste products. + - rscadd: 'Brown Gas formation: Heat Oxygen and Nitrogen.' + - rscadd: 'BZ fixation: Heat Tritium and Plasma.' + - rscadd: 'Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.' + - rscadd: 'Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high + heat. Cools rapidly.' + - rscadd: Pluoxium is unable to be formed. + - rscdel: Freon has been removed. Use cold nitrogen for your SME problems now. + - rscadd: Water vapor now freezes the tile it is on when it is cooled heavily. + naltronix: + - bugfix: fixes that table that wasnt accessible in Metastation +2017-10-30: + PKPenguin321: + - tweak: You can now use beakers/cups/etc that have welding fuel in them on welders + to refuel them. + bgobandit: + - tweak: 'Due to cuts to Nanotrasen''s Occupational Safety and Health Administration + (NO-SHA) budget, station fixtures no longer undergo as much safety testing. + (Translation for rank and file staff: More objects on the station will hurt + you.)' +2017-11-02: + ACCount: + - tweak: '"Tail removal" and "tail attachment" surgeries are merged with "organ + manipulation".' + - imageadd: New sprites for reflectors. They finally look like something. + - rscadd: You can lock reflector's rotation by using a screwdriver. Use the screwdriver + again to unlock it. + - rscadd: Reflector examine now shows the current angle and rotation lock status. + - rscadd: You can now use a welder to repair damaged reflectors. + - bugfix: Multiple reflector bugs are fixed. + Improvedname: + - rscdel: Removes statues from gold slime pool + Mercenaryblue: + - imageadd: Updated Clown Box sprite to match the others. + More Robust Than You: + - admin: ONLY ADMINS CAN ACTIVATE THE ARK NOW + - tweak: The Ark's time measurements are now a bit more readable + MrStonedOne: + - tweak: Meteor events will not happen before 25 minutes, the worst versions before + 35 and 45 minutes. + - tweak: Meteor events are now player gated to 15, 20, and 25 players respectively + - balance: The more destructive versions of meteor events now have a slightly higher + chance of triggering, to offset the decrease in how often it is that they will + even qualify. + - bugfix: Fixed the changelog generator. + Naksu: + - tweak: Smartfridges and chem/condimasters now output items in a deterministic + 3x3 grid rather than in a huge pile in the middle of the tile. + SpaceManiac: + - bugfix: Admins can once again spawn nuke teams on demand. + Xhuis: + - admin: Admins can now create sound emitters (/obj/effect/sound_emitter) that can + be customized to play sounds to different people, at different volumes, and + at different locations such as by z-level. They're much more versatile for events + than the Play Sound commands! + - rscadd: You can now add grenades to plushies! You'll need to cut out the stuffing + first. + - tweak: Clockwork cult tips of the round have been updated to match the rework. + - tweak: Abscond and Reebe rifts now place servants directly at the Ark instead + of below the "base" area. + nicbn: + - tweak: Brown gas renamed to nitryl. + ninjanomnom: + - bugfix: Fixes decals not rotating correctly with the turf. + - bugfix: Fixes a runtime causing some turfs to be left behind by removed shuttles. + - code_imp: Shuttles should be roughly 40-50% smoother. + - bugfix: Fixes the cargo shuttle occasionally breaking if a mob got on at exactly + the right time. +2017-11-10: + Anonmare: + - bugfix: Adds an organ storage bag to the syndicate medborg. + AnturK: + - balance: Dying in shapeshifted form reverts you to the original one. (You're still + dead) + Floyd / Qustinnus: + - soundadd: Redtexting as a traitor now plays a depressing tune to you + Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation): + - soundadd: Adds about 30 new ambience sounds + - refactor: added new defines for ambience lists. + Iamgoofball: + - tweak: Cooldown on the Ripley's mining drills has been halved. + - tweak: The frequency of the Ripley's ore pulse has been doubled. + Jalleo: + - tweak: Removed a variable to state which RCD's can deconstruct reinforced walls + - balance: Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside + borg ones + Kor: + - bugfix: Cult mode will once again print out names at round end. + Mark9013100: + - rscadd: Deltastation now has a Whiteship. + - tweak: Charcoal bottles have been renamed, and have been given a more informative + description. + Mercenaryblue: + - spellcheck: spellchecked the hotel staff. + - rscadd: Added frog masks. Reeeeeeeeee!! + More Robust Than You: + - bugfix: Blobbernauts and spores are no longer killed by blob victory + - bugfix: New blob overminds off the station Z level are moved to the station + - bugfix: You can now use banhammers as a weapon + - tweak: Monkeys can no longer transmit diseases through hardsuits + - tweak: Xenobio blobbernauts can no longer walk on blob tiles + Naksu: + - tweak: Added deterministic output slots to the slime processor + - bugfix: Fixed some interactions with ghosts and items + - bugfix: Nonhumans such as monkeys can now be scanned for chemicals with the health + analyzer. + Okand37 (DeltaStation Updates): + - rscadd: Tweaked Atmospherics + - bugfix: Fixed the Incinerator air injector + - rscadd: Tweaked Engineering + - rscadd: Added logs to the Chaplain's closet for gimmicks (bonfires) + - rscadd: Tweaked Security + - bugfix: Fixed medical morgue maintenance not providing radiation shielding and + exterior chemistry windoor + - rscadd: Bar now has a door from the backroom to the theatre stage + - rscadd: Tweaked Locker Room/Dormitories + ShizCalev: + - bugfix: You can now -actually- load pie cannons. + - bugfix: The captain's winter coat can now hold a flashlight. + - bugfix: The captain's and security winter coats can now hold internals tanks. + - tweak: All winter coats can now hold toys, lighters, and cigarettes. + - tweak: The captain's hardsuit can now hold pepperspray. + - rscadd: Updated the Test Map debugging verb to report more issues regarding APCs. + DELTASTATION + - bugfix: Reverted Okand37's morgue changes which broke power in the area. + - bugfix: Corrected wrong area on the Southern airlock leading into electrical maintenance. + ALL STATIONS + - bugfix: Corrected numerous duplicate APCs in areas which led to power issues. + SpaceManiac: + - bugfix: Ghosts can no longer create sparks from the hand teleporter's portals. + - bugfix: Digging on Lavaland no longer shows two progress bars. + - bugfix: The holodeck now has an "Offline" option. + - bugfix: Injury and crit overlays are now scaled properly for zoomed-out views. + - bugfix: Already-downloaded software is now hidden from the NTNet software downloader. + - bugfix: The crafting, language, and building buttons are now positioned correctly + in zoomed-out views. + - bugfix: Bluespace shelter walls no longer smooth with non-shelter walls and windows. + Swindly: + - rscadd: Organ storage bags can be used to perform limb augmentation. + - bugfix: You can now cancel a cavity implant during the implanting/removing step + by using drapes while holding the appropriate tool in your inactive hand. Cyborgs + can cancel the surgery by using drapes alone. + - bugfix: Fixed hot items and fire heating reagents to temperatures higher than + their heat source. + - bugfix: Sprays can now be heated with hot items. + - tweak: The heating of reagents by hot items, fire, and microwaves now scales linearly + with the difference between the reagent holder's temperature and the heat source's + temperature instead of constantly. + - tweak: The body temperature of a mob with reagents is affected by the temperature + of the mob's reagents. + - tweak: Reagent containers can now be heated by hot air. + Thefastfoodguy: + - bugfix: Spamming runes / battlecries / etc will no longer trigger spam prevention + WJohnston: + - bugfix: Ancient station lighting fixed on beta side (medical and atmos remains) + XDTM: + - rscadd: Ghosts now have a Toggle Health Scan verb, which allows them to health + scan mobs they click on. + Xhuis: + - rscadd: Ratvar and Nar-Sie plushes now have a unique interaction. + - balance: Clockwork marauders are now on harm intent. + - balance: The Clockwork Marauder scripture now takes five seconds longer to invoke + per marauder summoned in the last 20 seconds, capping at 30 extra seconds. + - balance: Clockwork marauders no longer gain a health bonus when war is declared. + - tweak: Moved the BoxStation deep fryers up one tile. + - rscadd: Microwaves have new sounds! + YPOQ: + - bugfix: EMPs can pulse multiple wires + as334: + - rscadd: Pluoxium can now be formed by irradiating tiles with CO2 in the air. + - rscadd: Rad collectors now steadily form Tritium at a slow pace. + - balance: Nerfs fusion by making it slower, and produce radioactivity. + - balance: Noblium formation now requires significantly more energy input. + - balance: Tanks now melt if their temperature is above 1 Million Kelvin. + deathride58: + - bugfix: Directional character icon previews now function properly. Other things + relying on getflaticon probably work with directional icons again, as well. + nicbn: + - imageadd: Canister sprites for the new gases + ninjanomnom: + - bugfix: Shuttle parallax has been fixed once more + - bugfix: You can no longer set up the auxiliary base's shuttle beacon overlapping + with the edge of the map + uraniummeltdown: + - tweak: Replica fabricatoring airlocks and windoors keeps the old name + - tweak: Narsie and Ratvar converting airlocks and windoors keeps the old name +2017-11-11: + DaxDupont: + - bugfix: Medbots can inject from one tile away again. + SpaceManiac: + - bugfix: The detective and heads of staff are no longer attacked by portable turrets. + deathride58: + - bugfix: You can no longer delete girders, lattices, or catwalks with the RPD + - bugfix: Fixes runtimes that occur when clicking girders, lattices, catwalks, or + disposal pipes with the RPD in paint mode + ninjanomnom: + - bugfix: Fixes ruin cable spawning and probably some other bugs +2017-11-12: + Cyberboss: + - bugfix: Clockwork slabs no longer refer to components +2017-11-13: + Cobby: + - rscadd: The Xray now only hits the first mob it comes into contact with instead + of being outright removed from the game. + Floyd / Qustinnus: + - soundadd: Reebe now has ambience sounds + 'Floyd / Qustinnus:': + - soundadd: Adds a few sound_loop datums to machinery. + Frozenguy5: + - bugfix: Broken cable cuffs no longer has an invisible sprite. + PKPenguin321: + - rscadd: Welders must now be screwdrivered open to reveal their fuel tank. + - rscadd: You can empty welders into open containers (like beakers or glasses) when + they're screwdrivered open. + - rscadd: You can now insert any chemical into a welder, but all most will do is + clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends + to explode. + Qbopper and JJRcop: + - tweak: The default internet sound volume was changed from 100 to 25. Stop complaining + in OOC about your ears! + SpaceManiac: + - bugfix: Posters may no longer be placed on diagonal wall corners. + WJohnston: + - rscdel: Removes stationary docking ports for syndicate infiltrator ships on all + maps. Use the docking navigator computer instead! This gives the white ship + and syndicate infiltrator more room to navigate and place custom locations that + are otherwise occupied by fixed shuttle landing zones that are rarely used. + Xhuis: + - rscadd: Deep fryers now have sound. + - tweak: Deep fryers now use cooking oil, a specialized reagent that becomes highly + damaging at high temperatures. You can get it from grinding soybeans and meat. + - tweak: Deep fryers now become more efficient with higher-level micro lasers, using + less oil and frying faster. + - tweak: Deep fryers now slowly use oil as it fries objects, instead of all at once. + - bugfix: You can now correctly refill deep fryers with syringes and pills. + nicn: + - balance: Damage from low pressure has been doubled. + ninjanomnom: + - rscadd: You can now select a nearby area to expand when using a blueprint instead + of making a new area. + - rscadd: New shuttle areas can be created using blueprints. This is currently not + useful but will be used later for shuttle construction. + - tweak: Blueprints can modify existing areas on station. + - admin: Blueprint functionality has been added to the debug tab as a verb. +2017-11-14: + ike709: + - imageadd: Added directional computer sprites. Maps haven't been changed yet. + psykzz: + - refactor: AI Airlock UI to use TGUI + - tweak: Allow AI to swap between electrified door states without having to un-electrify + first. + selea/arsserpentarium: + - rscadd: Integrated circuits have been added to Research! + - rscadd: You can use these to create devices with very complex behaviors. + - rscadd: Research the Integrated circuits printer to get started. +2017-11-15: + Fury: + - rscadd: Added new sprites for the Heirophant Relay (clock cultist telecomms equipment). + Naksu: + - bugfix: 'Removed fire-related free lag. change: fire alarms and cameras no longer + work after being ripped off a wall by a singulo' + - tweak: 'Minor speedups to movement processing. change: Fat mobs no longer gain + temperature by running.' + Robustin: + - refactor: Cult population scaling no longer operates on arbitrary breakpoints. + Each additional player between the between the breakpoints will add to the "chance" + that an additional cultist will spawn. + - tweak: On average you will see less roundstart cultists in lowpop and more roundstart + cultists in highpop. + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - tweak: The tesla will now move toward power beacons at a significantly slower + rate. + SpaceManiac: + - bugfix: The post-round station integrity report is now functional again. + ninjanomnom: + - bugfix: Gas overlays no longer block clicks, on 512 +2017-11-22: + ACCount: + - refactor: Old integrated circuit save file format is ditched in favor of JSON. + Readability, both of save files and save code, is improved greatly. + - tweak: Integrated circuit panels now open with screwdriver instead of crowbar, + to match every single other thing on this server. + - tweak: Integrated circuit printer now stores up to 25 metal sheets. + - bugfix: Fixed integrated circuit rechargers not recharging guns properly and not + updating icons. + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + Anonmare: + - balance: Laserpoitners now incapcitate catpeople + AutomaticFrenzy: + - bugfix: cell chargers weren't animating properly + - bugfix: disable_warning wasn't getting checked and the chat was being spammed + Code by Pyko, Ported by Frozenguy5: + - rscadd: Rat Kebabs and Double Rat Kebabs have been added! + Cyberboss: + - server: Server tools API changed to version 3.2.0.1 + - admin: '"ahelp" chat command can now accept a ticket number as opposed to a ckey' + DaxDupont: + - tweak: CentCom has issued a firmware updated for the operating computers. It is + no longer needed to manually refresh the procedure and patient status. + - bugfix: Proximity sensors no longer beep when unarmed. + - bugfix: Plant trays will now properly process fluorine and adjust toxins and water + contents. + Francinum: + - tweak: The shuttle build plate is now better sized for all stations. + Iamgoofball: + - spellcheck: fixes grammar on logic gate descriptions + - spellcheck: fixes grammar on list circuits + - bugfix: fixes grammar on trig circuits + - spellcheck: fixed grammar on output circuits + JJRcop: + - bugfix: Fixes changeling eggs not putting the changeling in control if the brainslug + is destroyed before hatching. + - tweak: The silicon airlock menu looks a little more like it used to. + Kor: + - bugfix: Blobbernauts will no longer spawn if a player is not selected to control + it, preventing AI blobbernauts from running off the blob and to their deaths. + - rscdel: Following complaints that cargo has been selling all the materials they + receive rather than distributing them, mineral exporting has been removed. + MMMiracles: + - balance: Power regen on the regular tesla relay has been reduced to 50, from 150. + Naksu: + - bugfix: Sped up saycode to remove free lag from highpop + - bugfix: Using a chameleon projector will now dismount you from any vehicles you + are riding, in order to prevent wacky space glitches and being sent to a realm + outside space and time. + Shadowlight213: + - code_imp: Added round id to the status world topic + ShizCalev: + - bugfix: Chameleon goggles will no longer go invisible when selecting Optical Tray + scanners. + - rscadd: Engineering and Atmos scanner goggles will now have correctly colored + inhand sprites. + - tweak: The computers on all maps have have been updated for the latest directional + sprite changes. Please report any computers facing in strange directions to + your nearest mapper. + - bugfix: MetaStation - The consoles in medbay have had their directions corrected. + - imageadd: The Nanotrasen logo on modular computers has been fixed, rejoice! + - bugfix: PubbyStation - Unpowered air injectors in various locations have been + fixed. + - bugfix: MetaStation - Air injector leading out of the incinerator has been fixed + - bugfix: MetaStation - Corrected a couple maintenance airlocks being powered by + the wrong areas. + - bugfix: Computers will no longer rotate incorrectly when being deconstructed. + - bugfix: You can now rotate computer frames during construction. + - bugfix: Chairs, PA parts, infrared emitters, and doppler arrays will now rotate + clockwise. + - bugfix: Throwing drinking glasses and cartons will now consistently cause them + to break! + - bugfix: Humans missing legs or are legcuffed will no longer move slower in areas + without gravity. + - bugfix: The structures external to stations are now properly lit. Make sure you + bring a flashlight. + - bugfix: Computers will no longer delete themselves when being built, whoops! + - bugfix: Space cats will no longer have a smashed helmet when they lay down. + Skylar Lineman, your local R&D moonlighter: + - rscadd: Research has been completely overhauled into the techweb system! No more + levels, the station now unlocks research "nodes" with research points passively + generated when there is atleast one research server properly cooled, powered, + and online. + - rscadd: R&D lab has been replaced by the departmental lathe system on the three + major maps. Each department gets a lathe and possibly a circuit imprinter that + only have designs assigned by that department. + - rscadd: The ore redemption machine has been moved into cargo bay on maps with + decentralized research to prevent the hallways from becoming a free for all. + Honk! + - balance: You shouldn't expect balance as this is the initial merge. Please put + all feedback and concerns on the forum so we can revise the system over the + days, weeks, and months, to make this enjoyable for everyone. Heavily wanted + are ideas of how to add more ways of generating points. + - balance: You can get techweb points by setting off bombs with an active science + doppler array listening. The bombs have to have a theoretical radius far above + maxcap to make a difference. You can only go up, not down, in radius, so you + can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically + scaled to prevent "world destroyer" bombs from instantly finishing research. + SpaceManiac: + - bugfix: HUDs from mechs and helmets no longer conflict with HUD glasses and no + longer inappropriately remove implanted HUDs. + - code_imp: Chasm code has been refactored to be more sane. + - bugfix: Building lattices over chasms no longer sometimes deletes the chasm. + - code_imp: Ladders have been refactored and should be far less buggy. + - bugfix: Jacob's ladder actually works again. + - bugfix: Pizza box stacking works again. + - bugfix: Fix some permanent-on and permanent-off bugs caused by the HUD stacking + change. + WJohnston: + - imageadd: A bunch of new turf decals for mappers to play with, coming in yellow, + white, and red varieties! + - bugfix: Green banded default airlocks now have extended click area like all other + airlocks. + Y0SH1 M4S73R: + - spellcheck: The R&D Server's name is now improper. + - spellcheck: The R&D Server now has an explanation of what it does. + arsserpentarium: + - bugfix: now lists should work properly + duncathan: + - rscadd: The RPD has a shiny new UI! + - rscadd: The RPD can now paint pipes as it lays them, for quicker piping projects. + - rscadd: Atmos scrubbers (vent and portable) can now filter any and all gases. + ike709: + - imageadd: Added new vent and scrubber sprites by Partheo. + - bugfix: Fixed some computers facing the wrong direction. + jammer312: + - bugfix: fixed conjuration spells forgetting about conjured items + kevinz000: + - rscadd: purple bartender suit and apron added to clothesmates! + - rscadd: long hair 3 added, check it out. both have sprites from okand! + nicbn: + - soundadd: Now rolling beds and office chairs have a sound! + oranges: + - rscdel: Removed the shocker circuit + psykzz: + - imageadd: Grilles have new damaged and default sprites + - rscadd: Added TGUI for Turbine computer + tserpas1289: + - tweak: Any suit that could hold emergency oxygen tanks can now also hold plasma + man internals + - tweak: Hydroponics winter coats now can hold emergency oxygen tanks just like + the other winter coats. + - bugfix: Plasma men jumpsuits can now hold accessories like pocket protectors and + medals. + zennerx: + - bugfix: fixed a bug that made you try and scream while unconscious due to a fire + - tweak: Skateboard crashes now give slight brain damage! + - rscadd: Using a helmet prevents brain damage from the skateboard! +2017-11-23: + GupGup: + - bugfix: Fixes hostile mobs attacking surrounding tiles when trying to attack someone + MrStonedOne and Jordie: + - server: As a late note, serverops be advise that mysql is no longer supported. + existing mysql databases will need to be converted to mariadb + Robustin: + - tweak: RND consoles will no longer display options for machines or disks that + are not connected/inserted. + ShizCalev: + - bugfix: Aliens in soft-crit will now use the correct sprite. + XDTM: + - rscadd: 'Added two new symptoms: one allows viruses to still work while dead, + and allows infection of undead species, and one allows infection of inorganic + species (such as plasmapeople or golems).' +2017-11-24: + ACCount: + - rscdel: Removed "console screen" stock part. Just use glass sheets instead. + More Robust Than You: + - tweak: Spessmen are now smart enough to realize you don't need to turn around + to pull cigarette butts + SpaceManiac: + - bugfix: Fix water misters being inappropriately glued to hands in some cases. + - bugfix: Some misplaced decals in the Hotel brig have been corrected. + ninjanomnom: + - bugfix: Custom shuttle dockers can no longer place docking regions inside other + custom docker regions. +2017-11-25: + CosmicScientist: + - bugfix: bolas are back in tablecrafting! + Dorsisdwarf: + - tweak: Catpeople are now distracted instead of debilitated + - rscadd: Normal cats now go for laser pointers + SpaceManiac: + - bugfix: You can no longer buckle people to roller beds from inside of a locker. + YPOQ: + - bugfix: AIs and cyborgs can interact with unscrewed airlocks and APCs. + ninjanomnom: + - bugfix: Fixes thermite burning hotter than the boiling point of stone + zennerx: + - bugfix: Zombies don't reanimate with no head! +2017-11-27: + ACCount: + - rscadd: 'New integrated circuit components: list constructors/deconstructors. + Useful for building lists and taking them apart.' + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + More Robust Than You: + - bugfix: Fixed cult leaders being de-culted upon election if they had a mindshield + implant + Naksu: + - bugfix: Hopefully fixed mesons granting the ability to hear people through walls. + Okand37: + - rscadd: Re-organized Delta's departmental protolathes for all departments. + - rscadd: Re-organized Delta's ORM placement by connecting it to the mining office, + which now has a desk for over handing materials to the outside. + - rscadd: Added a second Nanomed to Deltastation's medical bay. + - rscadd: Nanotrasen has decided to add proper caution signs to most docking ports + on Deltastation, warning individuals to be cautious around these areas. + - rscadd: Two health sensors are now placed in Deltastation's robotics area for + medibots. + - bugfix: Atmospheric Technicians at Deltastation can now open up their gas storage + in the supermatter power area as intended. + WJohnston: + - bugfix: Fixed a case where items would sometimes be placed underneath racks. + XDTM: + - balance: Viruses' healing symptoms have been reworked! + - rscdel: All existing healing symptoms have been removed in favour of new ones. + - rscdel: Weight Even and Weight Gain have been removed, so hunger can be used for + balancing in symptoms. + - rscadd: Starlight Condensation heals toxin damage if you're in space using starlight + as a catalyst. Being up to two tiles away also works, as long as you can still + see it, but slower. + - rscadd: Toxolysis (level 7) rapidly cleanses all chemicals from the body, with + no exception. + - rscadd: 'Cellular Molding heals brute damage depending on your body temperature: + the higher the temperature, the faster the healing. Requires above-average temperature + to activate, and the speed heavily increases while on fire.' + - rscadd: Regenerative Coma (level 8) causes the virus to send you into a deep coma + when you are heavily damaged (>70 brute+burn damage). While you are unconscious, + either from the virus or from other sources, the virus will heal both brute + and burn damage fairly quickly. Sleeping also works, but at reduced speed. + - rscadd: Tissue Hydration heals burn damage if you are wet (negative fire stacks) + or if you have water in your bloodstream. + - rscadd: Plasma Fixation (level 8) stabilizes temperature and heals burns while + plasma is in your body or while standing in a plasma cloud. Does not protect + from the poisoning effects of plasma. + - rscadd: Radioactive Resonance gives a mild constant brute and burn healing while + irradiated. The healing becomes more intense if you reach higher levels of radiation, + but is still less than the alternatives. + - rscadd: Metabolic Boost (level 7) doubles the rate at which you process chemicals, + good and bad, but also increases hunger tenfold. + kevinz000: + - bugfix: Cryo cells can now be properly rotated with a wrench. + ninjanomnom: + - rscadd: 'You can now make a new tasty traditional treat: butterdogs. Watch out, + they''re slippery.' +2017-11-28: + ACCount: + - rscdel: '"Machine prototype" is removed from the game.' + - rscdel: Mass-spectrometers are removed. Would anyone notice if not for this changelog + entry? + Cruix: + - rscadd: AI and observer diagnostic huds will now show the astar path of all bots, + and Pai bots will be given a visible path to follow when called by the AI. + JJRcop: + - admin: Fixed the Make space ninja verb. + Naksu: + - code_imp: rejiggered botcode a little bit + SpaceManiac: + - spellcheck: Admin-added "download research" objectives are now consistent with + automatic ones. + improvedname: + - tweak: toolbelts can now carry geiger counters + uraniummeltdown: + - rscadd: You can make many different types of office and comfy chairs with metal + - tweak: Stack menus use /datum/browser +2017-11-29: + MrStonedOne: + - tweak: The sloth no longer suspiciously moves fast when gliding between tiles. + - balance: The sloth's movespeed when inhabited by a player has been lowered from + once every 1/5 of a second to once every second. + SpaceManiac: + - spellcheck: The techweb node for mech LMGs no longer claims to be for mech tasers. +2017-11-30: + ninjanomnom: + - tweak: Reduced the max volume of sm by 1/5th and made the upper bounds only play + mid delamination. + psykzz: + - bugfix: Fixing the broken turbine computer +2017-12-02: + BeeSting12: + - spellcheck: Occupand ---> Occupant on opened cryogenic pods. + - spellcheck: Cyrogenic ---> Cryogenic on opened cryogenic pods. + CosmicScientist: + - rscadd: You can make plushies kiss one another! + Frozenguy5: + - tweak: The Particle Accelerator's wires can no longer be EMP'd + Naksu: + - code_imp: Cleans up some loc assignments + Robustin: + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - balance: Clockwork magicks will now prevent Bags of Holding from being combined + on Reebe. + - bugfix: Flashes will now burn out AFTER flashing when they fail instead of being + a ticking time bomb that waits to screw you over on your next attempt. + SpaceManiac: + - tweak: The R&D Console has been given a much prettier interface. + - tweak: Research scanner goggles now show materials and technology prospects in + a nicer way. + uraniummeltdown: + - imageadd: Construct shells have a new animated sprite +2017-12-03: + ExcessiveUseOfCobblestone: + - bugfix: You can now lay (buckle!) yourself to a bed to avoid being burnt to a + crisp during "the floor is lava" event. + Robustin: + - tweak: Igniting plasma statues no longer ignores ignition temperature and only + creates as much plasma as was used in its creation. + Xhuis: + - rscadd: Light fixtures now turn an ominous, dim red color when they lose power, + and draw from an internal power cell to maintain it until either the cell dies + (usually after 10 minutes) or power is restored. + - rscadd: You can override emergency light functionality from an APC. You can also + click on individual lights as a cyborg or AI to override them individually. + Traitor AIs also have a new ability that disables emergency lights across the + entire station. + zennerx: + - spellcheck: fixed some typos in the weapon firing mechanism description +2017-12-04: + AnturK: + - rscadd: You can now record and replay holopad messages using holodisks. + - rscadd: Holodisks are printable in autolathes. + Xhuis: + - bugfix: You now need fuel in your welder to repair mechs. +2017-12-05: + Cyberboss: + - sounddel: Reduced the volume of showers + Dax Dupont: + - rscadd: Nanotrasen is happy to announce the pinnacle in plasma research! The Disco + Inferno shuttle design is the result of decades of plasma research. Burn, baby, + burn! + MrPerson & ninjanomnom: + - refactor: Completely changed how keyboard input is read. + - rscadd: Holding two directions at the same time will now move you diagonally. + This works with the arrow keys, wasd, and the numpad. + - tweak: Moving diagonally takes twice as long as moving a cardinal direction. + - bugfix: You can use control to turn using wasd and the numpad instead of just + the arrow keys. + - rscdel: 'Some old non-hotkey mode behaviors, especially in relation to chatbox + interaction, can''t be kept with the new system. Of key note: You can''t type + while walking. This is due to limitations of byond and the work necessary to + overcome it is better done as another overhaul allowing custom controls.' + Robustin: + - rscdel: Reverted changes in 3d sound system that tripled the distance that sound + would carry. + SpaceManiac: + - spellcheck: Energy values are now measured in joules. What was previously 1 unit + is now 1 kJ. + - bugfix: Syndicate uplink implants now work again. + Xhuis: + - tweak: Stethoscopes now inform the user if the target can be defibrillated; the + user will hear a "faint, fluttery pulse." + coiax: + - rscadd: Quiet areas of libraries on station have now been equipped with a vending + machine containing suitable recreational activities. +2017-12-06: + Dax Dupont & Alek2ander: + - tweak: Binary chat messages been made more visible. + Revenant Defile ability: + - bugfix: Revenant's Defile now removes salt piles + XDTM: + - rscadd: 'Brain damage has been completely reworked! remove: Brain damage now no + longer simply makes you dumb. Although most of its effects have been shifted + into a brain trauma.' + - rscadd: Every time you take brain damage, there's a chance you'll suffer a brain + trauma. There are many variations of brain traumas, split in mild, severe, and + special. + - rscadd: Mild brain traumas are the easiest to get, can be lightly to moderately + annoying, and can be cured with mannitol and time. + - rscadd: Severe brain traumas are much rarer and require extensive brain damage + before you have a chance to get them; they are usually very debilitating. Unlike + mild traumas, they require surgery to cure. A new surgery procedure has been + added for this, the aptly named Brain Surgery. It can also heal minor traumas. + - rscadd: 'Special brain traumas are rarely gained in place of Severe traumas: they + are either complex or beneficial. However, they are also even easier to cure + than mild traumas, which means that keeping these will usually mean keeping + a mild trauma along with it.' + - rscadd: Mobs can only naturally have one mild trauma and one severe or special + trauma. + - balance: Brain damage will now kill and ruin the brain if it goes above 200. If + it somehow goes above 400, the brain will melt and be destroyed completely. + - balance: Many brain-damaging effects have been given a damage cap, making them + non-lethal. + - rscdel: The Unintelligible mutation has been removed and made into a brain trauma. + - rscdel: Brain damage no longer makes using machines a living hell. + - rscadd: Abductors give minor traumas to people they experiment on. + coiax: + - rscadd: The drone dispenser on Metastation has been moved to the maintenance by + Robotics. +2017-12-07: + ShizCalev: + - bugfix: Games vending machines can now properly be rebuilt. + - bugfix: Games vending machines can now be refilled via supply crates. + - rscadd: Games Supply Crates have been added to the cargo console. + SpaceManiac: + - bugfix: Radio frequency 148.9 is once again serviced by the telecomms system. + Xhuis: + - rscadd: Added the Eminence role to clockcult! Players can elect themselves or + ghosts as the Eminence from the eminence spire structure on Reebe. + - rscadd: The Eminence is incorporeal and invisible, and directs the entire cult. + Anything they say is heard over the Hierophant network, and they can issue commands + by middle-clicking themselves or different turfs. + - rscadd: The Eminence also has a single-use mass recall that warps all servants + to the Ark chamber. + - rscadd: Added traps, triggers, and brass filaments to link them. They can all + be constructed from brass sheets, and do different things and trigger in different + ways. Current traps include the brass skewer and steam vent, and triggers include + the pressure sensor, lever, and repeater. + - rscadd: The Eminence can activate trap triggers by clicking on them! + - rscadd: Servants can deconstruct traps instantly with a wrench. + - rscdel: Mending Mantra has been removed. + - tweak: Clockwork scriptures have been recolored and sorted based on their functions; + yellow scriptures are for construction, red for offense, blue for defense, and + purple for niche. + - balance: Servants now spawn with a PDA and black shoes to make disguise more feasible. + - balance: The Eminence can superheat up to 20 clockwork walls at a time. Superheated + walls are immune to hulk and mech punches, but can still be broken conventionally. + - balance: Clockwork walls are slightly faster to build before the Ark activates, + taking an extra second less. + - bugfix: Poly no longer continually undergoes binary fission when Ratvar is in + range. + - code_imp: The global records alert for servants will no longer display info that + doesn't affect them since the rework. + coiax: + - rscadd: The drone dispenser on Box Station has been moved from the Testing Lab + to the Morgue/Robotics maintenance tunnel. + deathride58: + - config: The default view range can now be defined in the config. The default is + 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen + range is 21x15. Do note that changing this value will affect the title screen. + The title screen images and the title screen area on the Centcom z-level will + have to be updated if the default view range is changed. +2017-12-08: + Dax Dupont: + - bugfix: Fixed observer chat flavor of silicon chat. + - bugfix: Grilles now no longer revert to a pre-broken icon state when you hit them + after they broke. + Dorsisdwarf: + - tweak: Minor fixes to some techweb nodes + - balance: Made flight suits, combat implants, and combat modules require more nodes + Fox McCloud: + - tweak: Slime blueprints can now make an area compatible with Xenobio consoles, + regardless of the name of the new area + MrDoomBringer: + - imageadd: All stations have been outfitted with brand new Smoke Machines! They + have nicer sprites now! + Shadowlight213: + - rscadd: You now can get a medal for wasting hours talking to the secret debug + tile. + - bugfix: Fixed runtime for the tile when poly's speech file doesn't exist. + Xhuis: + - rscadd: You can now make pet carriers from the autolathe, to carry around chef + meat and other small animals without having to drag them. The HoP, captain, + and CMO also start with carriers in their lockers for their pets. + YPOQ: + - bugfix: Fixed the camera failure, race swap, cursed items, and imposter wizard + random events + - tweak: The cursed items event no longer nullspaces items + jammer312: + - rscadd: Action buttons now remember positions where you locked. + - tweak: Now locking action buttons prevents them from being reset. +2017-12-10: + SpaceManiac: + - bugfix: External airlocks of the mining base and gulag are now cycle-linked. + - tweak: The pAI software interface is now accessible via an action button. + Swindly: + - rscadd: You can kill yourself with a few more items. + XDTM: + - tweak: Instead of activating randomly on speech, Godwoken Syndrome randomly grants + inspiration, causing the next message to be a Voice of God. + Xhuis: + - tweak: Flickering lights will now actually flicker and not go between emergency + lights and normal lighting. + - bugfix: Emergency lights no longer stay on forever in some cases. + kevinz000: + - rscadd: Nanotrasen would like to remind crewmembers and especially medical personnel + to stand clear of cadeavers before applying a defibrillator shock. (You get + shocked if you're pulling/grabbing someone being defibbed.) + - tweak: defib shock/charge sounds upped from 50% to 75%. +2017-12-11: + Anonmare: + - bugfix: Booze-o-mats have beer + Cruix: + - tweak: The white ship navigation computer now takes 10 seconds to designate a + landing spot, and users can no longer see the syndicate shuttle or its custom + landing location. If the white ship landing location would intersect the syndicate + shuttle or its landing location, it will fail after the 10 seconds have elapsed. + Frozenguy5: + - balance: Some hardsuits have had their melee, fire and rad armor ratings tweaked. + Improvedname: + - tweak: cats now drop their ears and tail when butchered. + Robustin: + - bugfix: Modes not in rotation have had their "false report" weights for the Command + Report standardized + SpaceManiac: + - bugfix: The MULEbots that the station starts with now show their ID numbers. + - bugfix: The dependency by Advanced Cybernetic Implants and Experimental Flight + Equipment on Integrated HUDs has been restored. + kevinz000: + - bugfix: flightsuits should no longer disappear when you take them off involuntarily + - bugfix: beam rifles actually fire striaght now + - bugfix: click catchers now actually work + - bugfix: you no longer see space in areas you normally can't see, instead of black. + in reality you can still see space but it's faint enough that you can't tell + so I'll say I fixed it. + uraniummeltdown: + - rscadd: Added MANY new types of airlock assembly that can be built with metal. + Use metal in hand to see the new airlock assembly recipes. + - rscadd: Added new airlock types to the RCD and airlock painter + - rscadd: Vault door assemblies can be built with 8 plasteel, high security assemblies + with 6 plasteel + - rscadd: Glass mineral airlocks are finally constructible. Use glass and mineral + sheets on an airlock assembly in any order to make them. + - tweak: Glass and mineral sheets are now able to be welded out of door assemblies + rather than having to deconstruct the whole thing + - rscdel: Airlock painter no longer works on airlock assemblies (still works on + airlocks) + - bugfix: Titanium airlocks no longer have any missing overlays +2017-12-12: + Mark9013100: + - rscadd: Medical Wardrobes now contain an additional standard and EMT labcoat. + Robustin: + - rscadd: The blood cult revive rune will now replace the souls of braindead or + inactive cultists/constructs when properly invoked. These "revivals" will not + count toward the revive limit. + - rscadd: The clock cult healing rune will now replace the souls of braindead or + inactive cultists/constructs when left atop the rune. These "revivals" will + not drain the rune's energy. + Swindly: + - bugfix: Swarmers can no longer deconstruct objects with living things in them. + kevinz000: + - bugfix: You can now print telecomms equipment again. +2017-12-13: + Naksu: + - bugfix: glass shards and bananium floors no longer make a sound when "walked" + over by a camera or a ghost + SpaceManiac: + - bugfix: Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now + have the correct description. + deathride58: + - bugfix: Genetics will no longer have a random block completely disappear each + round +2017-12-15: + AverageJoe82: + - rscadd: drones now have night vision + - rscdel: drones no longer have lights + Cruix: + - bugfix: Shuttles now place hyperspace ripples where they are about to land again. + Cyberboss: + - config: Added "$include" directives to config files. These are recursive. Only + config.txt will be default loaded if they are specified inside it + - config: Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name + byond://server.net:1337 + - config: CROSS_SERVER_ADDRESS removed + Epoc: + - bugfix: Adds Cybernetic Lungs to the Cyber Organs research node + JStheguy: + - rscadd: Added 10 new assembly designs to the integrated circuit printer, the difference + from current designs is purely aesthetics. + - imageadd: Added the icons for said new assembly designs to electronic_setups.dmi, + changed the current electronic mechanism and electronic machine sprites. + MrStonedOne: + - server: Added new admin flag, AUTOLOGIN, to control if admins start with admin + powers. this defaults to on, and can be removed with -AUTOLOGIN + - admin: Admins with +PERMISSION may now deadmin or readmin other admins via the + permission panel. + Naksu: + - code_imp: Preliminary work on tracking cliented living mobs across Z-levels to + facilitate mob AI changes later + - code_imp: Tidied up some loc assignments + - code_imp: fixes the remaining loc assignments + ShizCalev: + - soundadd: Revamped gun dry-firing sounds. + - tweak: Everyone around you will now hear when your gun goes click. You don't want + to hear click when you want to hear bang! + SpaceManiac: + - code_imp: Remote signaler and other non-telecomms radio code has been cleaned + up. + Xhuis: + - rscadd: Grinding runed metal and brass now produces iron/blood and iron/teslium, + respectively. + - balance: As part of some code-side improvements, the amount of reagents you get + from grinding some objects might be slightly different. + - bugfix: Some grinding recipes that didn't work, like dead mice and glowsticks, + now do. + - bugfix: All-In-One grinders now correctly grind up everything, instead of one + thing at a time. + nicbn: + - imageadd: Closet sprites changed. +2017-12-16: + Armhulen and lagnas2000 (+his team of amazing spriters): + - rscadd: Mi-go have entered your realm! + Robustin: + - balance: Marauder shields now take twice as long to regenerate and only recharge + one charge at a time. + - balance: Marauders now have 120hp down from 150hp. + - bugfix: The wizard event "race swap" should now stick to "safer" species. + - bugfix: Zombies are now properly stunned for a maximum of 2 seconds instead of + 2/10ths of a second. + - tweak: Zombie slowdown adjusted from -2 to -1.6. + SpaceManiac: + - bugfix: The shuttle will no longer be autocalled if the round has already ended. + Xhuis: + - tweak: Vitality matrices don't have visible messages when someone crosses them + anymore. +>>>>>>> 7f8905e... Fixes Mi-Go crediting (#33626) From 962f135957b8b1ee8ed5b09c30b8595ba540658f Mon Sep 17 00:00:00 2001 From: XDTM Date: Sun, 17 Dec 2017 18:10:25 +0100 Subject: [PATCH 044/213] [Ready]Brain Trauma additions --- code/__DEFINES/misc.dm | 2 +- code/__DEFINES/mobs.dm | 4 +- code/__DEFINES/stat.dm | 6 + code/_onclick/item_attack.dm | 2 + code/_onclick/other_mobs.dm | 1 + code/datums/brain_damage/imaginary_friend.dm | 157 ++++++++++++++++++ code/datums/brain_damage/mild.dm | 79 +++++++++ code/datums/brain_damage/severe.dm | 40 ++++- code/datums/brain_damage/special.dm | 40 +++-- code/datums/brain_damage/split_personality.dm | 3 +- code/datums/martial/psychotic_brawl.dm | 4 +- code/game/objects/items/implants/implant.dm | 3 + .../items/implants/implant_explosive.dm | 9 +- code/modules/flufftext/Hallucination.dm | 1 + code/modules/language/aphasia.dm | 13 ++ code/modules/mob/living/carbon/carbon.dm | 6 + .../modules/mob/living/carbon/damage_procs.dm | 10 +- code/modules/mob/living/carbon/examine.dm | 47 +++--- .../mob/living/carbon/human/examine.dm | 47 +++--- .../mob/living/carbon/human/species.dm | 14 +- .../mob/living/carbon/monkey/combat.dm | 11 +- code/modules/mob/living/life.dm | 3 + code/modules/mob/living/living.dm | 5 +- code/modules/mob/living/living_defense.dm | 57 +++++-- code/modules/surgery/organs/tongue.dm | 3 +- code/modules/surgery/organs/vocal_cords.dm | 17 +- icons/misc/language.dmi | Bin 2383 -> 4323 bytes .../{brain_damage_lines.json => traumas.json} | 55 ++++++ tgstation.dme | 15 ++ 29 files changed, 545 insertions(+), 109 deletions(-) create mode 100644 code/datums/brain_damage/imaginary_friend.dm create mode 100644 code/modules/language/aphasia.dm rename strings/{brain_damage_lines.json => traumas.json} (81%) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 6254f12e45..b5d07646d7 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -495,7 +495,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define RIDING_OFFSET_ALL "ALL" //text files -#define BRAIN_DAMAGE_FILE "brain_damage_lines.json" +#define BRAIN_DAMAGE_FILE "traumas.json" //Fullscreen overlay resolution in tiles. #define FULLSCREEN_OVERLAY_RESOLUTION_X 15 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 49e3c996fe..707ef6a9c1 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -52,8 +52,8 @@ /*see __DEFINES/inventory.dm for bodypart bitflag defines*/ //Brain Damage defines -#define BRAIN_DAMAGE_MILD 50 -#define BRAIN_DAMAGE_SEVERE 120 +#define BRAIN_DAMAGE_MILD 20 +#define BRAIN_DAMAGE_SEVERE 100 #define BRAIN_DAMAGE_DEATH 200 #define BRAIN_TRAUMA_MILD /datum/brain_trauma/mild diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 331bc6765f..86f14f8ec0 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -18,8 +18,14 @@ #define HUSK 64 #define NOCLONE 128 #define CLUMSY 256 +<<<<<<< HEAD #define DUMB 512 #define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE +======= +#define DUMB 512 +#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE +#define PACIFISM 2048 +>>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405) // bitflags for machine stat variable #define BROKEN 1 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 859c957a43..11c30bb33e 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -58,6 +58,8 @@ SendSignal(COMSIG_ITEM_ATTACK, M, user) if(flags_1 & NOBLUDGEON_1) return + if(user.disabilities & PACIFISM) + return if(!force) playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) else if(hitsound) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 02cdfe7c13..d52a7f6fdc 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -63,6 +63,7 @@ /atom/proc/attack_animal(mob/user) return + /mob/living/RestrainedClickOn(atom/A) return diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm new file mode 100644 index 0000000000..ea01a87506 --- /dev/null +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -0,0 +1,157 @@ +/datum/brain_trauma/special/imaginary_friend + name = "Imaginary Friend" + desc = "Patient can see and hear an imaginary person." + scan_desc = "partial schizophrenia" + gain_text = "You feel in good company, for some reason." + lose_text = "You feel lonely again." + var/mob/camera/imaginary_friend/friend + var/friend_initialized = FALSE + +/datum/brain_trauma/special/imaginary_friend/on_gain() + ..() + make_friend() + get_ghost() + +/datum/brain_trauma/special/imaginary_friend/on_life() + if(get_dist(owner, friend) > 9) + friend.yank() + if(!friend) + qdel(src) + return + if(!friend.client && friend_initialized) + addtimer(CALLBACK(src, .proc/reroll_friend), 600) + +/datum/brain_trauma/special/imaginary_friend/on_lose() + ..() + QDEL_NULL(friend) + +//If the friend goes afk, make a brand new friend. Plenty of fish in the sea of imagination. +/datum/brain_trauma/special/imaginary_friend/proc/reroll_friend() + if(friend.client) //reconnected + return + friend_initialized = FALSE + QDEL_NULL(friend) + make_friend() + get_ghost() + +/datum/brain_trauma/special/imaginary_friend/proc/make_friend() + friend = new(get_turf(src), src) + +/datum/brain_trauma/special/imaginary_friend/proc/get_ghost() + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend) + if(LAZYLEN(candidates)) + var/client/C = pick(candidates) + friend.key = C.key + friend_initialized = TRUE + else + qdel(src) + +/mob/camera/imaginary_friend + name = "imaginary friend" + real_name = "imaginary friend" + move_on_shuttle = TRUE + desc = "A wonderful yet fake friend." + see_in_dark = 0 + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + sight = NONE + see_invisible = SEE_INVISIBLE_LIVING + var/icon/human_image + var/image/current_image + var/mob/living/carbon/owner + var/datum/brain_trauma/special/imaginary_friend/trauma + +/mob/camera/imaginary_friend/Login() + ..() + to_chat(src, "You are the imaginary friend of [owner]!") + to_chat(src, "You are absolutely loyal to your friend, no matter what.") + to_chat(src, "You cannot directly influence the world around you, but you can see what [owner] cannot.") + +/mob/camera/imaginary_friend/Initialize(mapload, _trauma) + . = ..() + var/gender = pick(MALE, FEMALE) + real_name = random_unique_name(gender) + name = real_name + trauma = _trauma + owner = trauma.owner + human_image = get_flat_human_icon(null, pick(SSjob.occupations)) + Show() + +/mob/camera/imaginary_friend/proc/Show() + if(!client) //nobody home + return + + //Remove old image from owner and friend + if(owner.client) + owner.client.images.Remove(current_image) + + client.images.Remove(current_image) + + //Generate image from the static icon and the current dir + current_image = image(human_image, src, , MOB_LAYER, dir=src.dir) + current_image.override = TRUE + current_image.name = name + + //Add new image to owner and friend + if(owner.client) + owner.client.images |= current_image + + client.images |= current_image + +/mob/camera/imaginary_friend/Destroy() + if(owner.client) + owner.client.images.Remove(human_image) + if(client) + client.images.Remove(human_image) + return ..() + +/mob/camera/imaginary_friend/proc/yank() + if(!client) //don't bother if the friend is braindead + return + forceMove(get_turf(owner)) + Show() + +/mob/camera/imaginary_friend/say(message) + if (!message) + return + + if (src.client) + if(client.prefs.muted & MUTE_IC) + to_chat(src, "You cannot send IC messages (muted).") + return + if (src.client.handle_spam_prevention(message,MUTE_IC)) + return + + friend_talk(message) + +/mob/camera/imaginary_friend/proc/friend_talk(message) + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + + if(!message) + return + + log_talk(src,"[key_name(src)] : [message]",LOGSAY) + + var/rendered = "[name] [say_quote(message)]" + var/dead_rendered = "[name] (Imaginary friend of [owner]) [say_quote(message)]" + + to_chat(owner, "[rendered]") + to_chat(src, "[rendered]") + + for(var/mob/M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, owner) + to_chat(M, "[link] [dead_rendered]") + +/mob/camera/imaginary_friend/emote(act,m_type=1,message = null) + return + +/mob/camera/imaginary_friend/forceMove(atom/destination) + dir = get_dir(get_turf(src), destination) + loc = destination + if(get_dist(src, owner) > 9) + yank() + return + Show() + +/mob/camera/imaginary_friend/movement_delay() + return 2 diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 6bfa149aa7..7c2ba20a62 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -107,6 +107,26 @@ ..() +/datum/brain_trauma/mild/healthy + name = "Anosognosia" + desc = "Patient always feels healthy, regardless of their condition." + scan_desc = "self-awareness deficit" + gain_text = "You feel great!" + lose_text = "You no longer feel perfectly healthy." + +/datum/brain_trauma/mild/healthy/on_gain() + owner.set_screwyhud(SCREWYHUD_HEALTHY) + ..() + +/datum/brain_trauma/mild/healthy/on_life() + owner.set_screwyhud(SCREWYHUD_HEALTHY) //just in case of hallucinations + owner.adjustStaminaLoss(-5) //no pain, no fatigue + ..() + +/datum/brain_trauma/mild/healthy/on_lose() + owner.set_screwyhud(SCREWYHUD_NONE) + ..() + /datum/brain_trauma/mild/muscle_weakness name = "Muscle Weakness" desc = "Patient experiences occasional bouts of muscle weakness." @@ -133,3 +153,62 @@ to_chat(owner, "You feel a sudden weakness in your muscles!") owner.adjustStaminaLoss(50) ..() + +/datum/brain_trauma/mild/muscle_spasms + name = "Muscle Spasms" + desc = "Patient has occasional muscle spasms, causing them to move unintentionally." + scan_desc = "nervous fits" + gain_text = "Your muscles feel oddly faint." + lose_text = "You feel in control of your muscles again." + +/datum/brain_trauma/mild/muscle_spasms/on_life() + if(prob(7)) + switch(rand(1,5)) + if(1) + if(owner.canmove && !isspaceturf(owner.loc)) + to_chat(owner, "Your leg spasms!") + step(owner, pick(GLOB.cardinals)) + if(2) + if(owner.incapacitated()) + return + var/obj/item/I = owner.get_active_held_item() + if(I) + to_chat(owner, "Your fingers spasm!") + log_attack("[key_name(owner)] used [I] due to a Muscle Spasm.") + I.attack_self(owner) + if(3) + var/prev_intent = owner.a_intent + owner.a_intent = INTENT_HARM + + var/range = 1 + if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at + range = 7 + + var/list/mob/living/targets = list() + for(var/mob/M in oview(owner, range)) + if(isliving(M)) + targets += M + if(LAZYLEN(targets)) + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] attacked someone due to a Muscle Spasm.") //the following attack will log itself + owner.ClickOn(pick(targets)) + owner.a_intent = prev_intent + if(4) + var/prev_intent = owner.a_intent + owner.a_intent = INTENT_HARM + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] attacked himself to a Muscle Spasm.") + owner.ClickOn(owner) + owner.a_intent = prev_intent + if(5) + if(owner.incapacitated()) + return + var/obj/item/I = owner.get_active_held_item() + var/list/turf/targets = list() + for(var/turf/T in oview(owner, 3)) + targets += T + if(LAZYLEN(targets) && I) + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.") + owner.throw_item(pick(targets)) + ..() \ No newline at end of file diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index 08cee65085..ceda917713 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -7,7 +7,7 @@ /datum/brain_trauma/severe/mute name = "Mutism" desc = "Patient is completely unable to speak." - scan_desc = "extensive damage to the brain's language center" + scan_desc = "extensive damage to the brain's speech center" gain_text = "You forget how to speak!" lose_text = "You suddenly remember how to speak." @@ -25,6 +25,29 @@ owner.disabilities &= ~MUTE ..() +/datum/brain_trauma/severe/aphasia + name = "Aphasia" + desc = "Patient is unable to speak or understand any language." + scan_desc = "extensive damage to the brain's language center" + gain_text = "You have trouble forming words in your head..." + lose_text = "You suddenly remember how languages work." + var/datum/language_holder/prev_language + var/datum/language_holder/mob_language + +/datum/brain_trauma/severe/aphasia/on_gain() + mob_language = owner.get_language_holder() + prev_language = mob_language.copy() + mob_language.remove_all_languages() + mob_language.grant_language(/datum/language/aphasia) + ..() + +/datum/brain_trauma/severe/aphasia/on_lose() + mob_language.remove_language(/datum/language/aphasia) + mob_language.copy_known_languages_from(prev_language) //this will also preserve languages learned during the trauma + QDEL_NULL(prev_language) + mob_language = null + ..() + /datum/brain_trauma/severe/blindness name = "Cerebral Blindness" desc = "Patient's brain is no longer connected to its eyes." @@ -177,3 +200,18 @@ /datum/brain_trauma/severe/discoordination/on_lose() owner.disabilities &= ~MONKEYLIKE ..() + +/datum/brain_trauma/severe/pacifism + name = "Traumatic Non-Violence" + desc = "Patient is extremely unwilling to harm others in violent ways." + scan_desc = "pacific syndrome" + gain_text = "You feel oddly peaceful." + lose_text = "You no longer feel compelled to not harm." + +/datum/brain_trauma/severe/pacifism/on_gain() + owner.disabilities |= PACIFISM + ..() + +/datum/brain_trauma/severe/pacifism/on_lose() + owner.disabilities &= ~PACIFISM + ..() \ No newline at end of file diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index ddb8f8e6e6..db0ca60801 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -9,25 +9,35 @@ scan_desc = "god delusion" gain_text = "You feel a higher power inside your mind..." lose_text = "The divine presence leaves your head, no longer interested." - var/next_speech = 0 - var/inspiration = FALSE /datum/brain_trauma/special/godwoken/on_life() ..() - if(!inspiration && world.time > next_speech && prob(4)) - to_chat(owner, "[pick("You feel inspired!","You feel power course through you...","You feel something within you itching to speak...")]") - inspiration = TRUE + if(prob(4)) + if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious())) + speak("unstun", TRUE) + else if(prob(60) && owner.health <= HEALTH_THRESHOLD_CRIT) + speak("heal", TRUE) + else if(prob(30) && owner.a_intent == INTENT_HARM) + speak("aggressive") + else + speak("neutral", prob(25)) -/datum/brain_trauma/special/godwoken/on_say(message) - if(world.time > next_speech && inspiration) - playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 300, 1, 5) - var/cooldown = voice_of_god(message, owner, list("colossus","yell"), 2) - cooldown *= 0.33 - next_speech = world.time + cooldown - inspiration = FALSE - return "" - else - return message +/datum/brain_trauma/special/godwoken/proc/speak(type, include_owner = FALSE) + var/message + switch(type) + if("unstun") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_unstun") + if("heal") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_heal") + if("neutral") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral") + if("aggressive") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_aggressive") + else + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral") + + playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 200, 1, 5) + voice_of_god(message, owner, list("colossus","yell"), 2.5, include_owner, FALSE) /datum/brain_trauma/special/bluespace_prophet name = "Bluespace Prophecy" diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index c726b2ecb5..deed1c8406 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -23,7 +23,7 @@ /datum/brain_trauma/severe/split_personality/proc/get_ghost() set waitfor = FALSE - var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", null, null, null, 75, stranger_backseat) + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat) if(LAZYLEN(candidates)) var/client/C = pick(candidates) stranger_backseat.key = C.key @@ -136,6 +136,7 @@ /mob/living/split_personality/Login() ..() to_chat(src, "As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality.") + to_chat(src, "Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.") /mob/living/split_personality/say(message) to_chat(src, "You cannot speak, your other self is controlling your body!") diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm index 0d6a85359d..28f8e9502c 100644 --- a/code/datums/martial/psychotic_brawl.dm +++ b/code/datums/martial/psychotic_brawl.dm @@ -44,11 +44,9 @@ playsound(get_turf(D), 'sound/weapons/punch1.ogg', 40, 1, -1) D.apply_damage(rand(5,10), BRUTE, "head") A.apply_damage(rand(5,10), BRUTE, "head") - if(!istype(A.head,/obj/item/clothing/head/helmet/) && !istype(A.head,/obj/item/clothing/head/hardhat)) - A.adjustBrainLoss(5) if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat)) D.adjustBrainLoss(5) - A.Stun(rand(5,30)) + A.Stun(rand(10,45)) D.Stun(rand(5,30)) if(5,6) A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index 7ca82c1236..f5b50542d0 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -14,6 +14,9 @@ /obj/item/implant/proc/trigger(emote, mob/living/carbon/source) return +/obj/item/implant/proc/on_death(emote, mob/living/carbon/source) + return + /obj/item/implant/proc/activate() return diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index 8b19bb9d96..0dc22c3d83 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -3,7 +3,7 @@ desc = "And boom goes the weasel." icon_state = "explosive" actions_types = list(/datum/action/item_action/explosive_implant) - // Explosive implant action is always availible. + // Explosive implant action is always available. var/weak = 2 var/medium = 0.8 var/heavy = 0.4 @@ -11,6 +11,9 @@ var/popup = FALSE // is the DOUWANNABLOWUP window open? var/active = FALSE +/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed) + activate("death") + /obj/item/implant/explosive/get_data() var/dat = {"Implant Specifications:
    Name: Robust Corp RX-78 Employee Management Implant
    @@ -23,10 +26,6 @@ "} return dat -/obj/item/implant/explosive/trigger(emote, mob/source) - if(emote == "deathgasp") - activate("death") - /obj/item/implant/explosive/activate(cause) if(!cause || !imp_in || active) return 0 diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 194edd77b1..92dc109bbc 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -80,6 +80,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( /obj/effect/hallucination invisibility = INVISIBILITY_OBSERVER + anchored = TRUE var/mob/living/carbon/target = null /obj/effect/hallucination/simple diff --git a/code/modules/language/aphasia.dm b/code/modules/language/aphasia.dm new file mode 100644 index 0000000000..91f14f9111 --- /dev/null +++ b/code/modules/language/aphasia.dm @@ -0,0 +1,13 @@ +/datum/language/aphasia + name = "Gibbering" + desc = "It is theorized that any sufficiently brain-damaged person can speak this language." + speech_verb = "garbles" + ask_verb = "mumbles" + whisper_verb = "mutters" + exclaim_verb = "screams incoherently" + flags = LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + key = "i" + syllables = list("m","n","gh","h","l","s","r","a","e","i","o","u") + space_chance = 20 + default_priority = 10 + icon_state = "aphasia" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e2ae973d43..eacfb28d82 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -157,6 +157,8 @@ if(!throwable_mob.buckled) thrown_thing = throwable_mob stop_pulling() + if(disabilities & PACIFISM) + to_chat(src, "You gently let go of [throwable_mob].") var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) if(start_T && end_T) @@ -168,6 +170,10 @@ thrown_thing = I dropItemToGround(I) + if(disabilities & PACIFISM && I.throwforce) + to_chat(src, "You set [I] down gently on the ground.") + return + if(thrown_thing) visible_message("[src] has thrown [thrown_thing].") add_logs(src, thrown_thing, "has thrown") diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index aecf966350..a842cb0209 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -198,7 +198,7 @@ update_stamina() /mob/living/carbon/getBrainLoss() - . = BRAIN_DAMAGE_DEATH + . = 0 var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) if(B) . = B.get_brain_damage() @@ -207,6 +207,7 @@ /mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH) if(status_flags & GODMODE) return 0 + var/prev_brainloss = getBrainLoss() var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) if(!B) return @@ -224,6 +225,13 @@ else gain_trauma_type(BRAIN_TRAUMA_SEVERE) + if(prev_brainloss < 40 && brainloss >= 40) + to_chat(src, "You feel lightheaded.") + else if(prev_brainloss < 120 && brainloss >= 120) + to_chat(src, "You feel less in control of your thoughts.") + else if(prev_brainloss < 180 && brainloss >= 180) + to_chat(src, "You can feel your mind flickering on and off...") + /mob/living/carbon/setBrainLoss(amount) var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) if(B) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 8c97bc71a3..b8d9d510fd 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -43,31 +43,32 @@ msg += "" var/temp = getBruteLoss() - if(temp) - if (temp < 25) - msg += "[t_He] [t_has] minor bruising.\n" - else if (temp < 50) - msg += "[t_He] [t_has] moderate bruising!\n" - else - msg += "[t_He] [t_has] severe bruising!\n" + if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy + if(temp) + if (temp < 25) + msg += "[t_He] [t_has] minor bruising.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate bruising!\n" + else + msg += "[t_He] [t_has] severe bruising!\n" - temp = getFireLoss() - if(temp) - if (temp < 25) - msg += "[t_He] [t_has] minor burns.\n" - else if (temp < 50) - msg += "[t_He] [t_has] moderate burns!\n" - else - msg += "[t_He] [t_has] severe burns!\n" + temp = getFireLoss() + if(temp) + if (temp < 25) + msg += "[t_He] [t_has] minor burns.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate burns!\n" + else + msg += "[t_He] [t_has] severe burns!\n" - temp = getCloneLoss() - if(temp) - if(temp < 25) - msg += "[t_He] [t_is] slightly deformed.\n" - else if (temp < 50) - msg += "[t_He] [t_is] moderately deformed!\n" - else - msg += "[t_He] [t_is] severely deformed!\n" + temp = getCloneLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_is] slightly deformed.\n" + else if (temp < 50) + msg += "[t_He] [t_is] moderately deformed!\n" + else + msg += "[t_He] [t_is] severely deformed!\n" if(disabilities & DUMB) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 6ed9291b83..39caec803b 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -187,31 +187,32 @@ else if(l_limbs_missing >= 2 && r_limbs_missing >= 2) msg += "[t_He] [p_do()]n't seem all there.\n" - if(temp) - if(temp < 25) - msg += "[t_He] [t_has] minor bruising.\n" - else if(temp < 50) - msg += "[t_He] [t_has] moderate bruising!\n" - else - msg += "[t_He] [t_has] severe bruising!\n" + if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor bruising.\n" + else if(temp < 50) + msg += "[t_He] [t_has] moderate bruising!\n" + else + msg += "[t_He] [t_has] severe bruising!\n" - temp = getFireLoss() - if(temp) - if(temp < 25) - msg += "[t_He] [t_has] minor burns.\n" - else if (temp < 50) - msg += "[t_He] [t_has] moderate burns!\n" - else - msg += "[t_He] [t_has] severe burns!\n" + temp = getFireLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor burns.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate burns!\n" + else + msg += "[t_He] [t_has] severe burns!\n" - temp = getCloneLoss() - if(temp) - if(temp < 25) - msg += "[t_He] [t_has] minor cellular damage.\n" - else if(temp < 50) - msg += "[t_He] [t_has] moderate cellular damage!\n" - else - msg += "[t_He] [t_has] severe cellular damage!\n" + temp = getCloneLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor cellular damage.\n" + else if(temp < 50) + msg += "[t_He] [t_has] moderate cellular damage!\n" + else + msg += "[t_He] [t_has] severe cellular damage!\n" if(fire_stacks > 0) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0b02a2c711..dc3ade0fd8 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1315,11 +1315,14 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) + if(user.disabilities & PACIFISM) + to_chat(user, "You don't want to harm [target]!") + return FALSE if(target.check_block()) target.visible_message("[target] blocks [user]'s attack!") - return 0 + return FALSE if(attacker_style && attacker_style.harm_act(user,target)) - return 1 + return TRUE else var/atk_verb = user.dna.species.attack_verb @@ -1344,7 +1347,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) playsound(target.loc, user.dna.species.miss_sound, 25, 1, -1) target.visible_message("[user] has attempted to [atk_verb] [target]!",\ "[user] has attempted to [atk_verb] [target]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE var/armor_block = target.run_armor_check(affecting, "melee") @@ -1511,8 +1514,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.confused = max(H.confused, 20) H.adjustBrainLoss(20) H.adjust_blurriness(10) - if(prob(20)) + if(prob(10)) H.gain_trauma(/datum/brain_trauma/mild/concussion) + else + if(!I.is_sharp()) + H.adjustBrainLoss(I.force / 5) if(prob(I.force + ((100 - H.health)/2)) && H != user) var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev) diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index d6afdbdbc2..09d00465ee 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -120,16 +120,19 @@ /mob/living/carbon/monkey/proc/should_target(var/mob/living/L) if(L == src) - return 0 + return FALSE + + if(disabilities & PACIFISM) + return FALSE if(enemies[L]) - return 1 + return TRUE // target non-monkey mobs when aggressive, with a small probability of monkey v monkey if(aggressive && (!istype(L, /mob/living/carbon/monkey/) || prob(MONKEY_AGGRESSIVE_MVM_PROB))) - return 1 + return TRUE - return 0 + return FALSE /mob/living/carbon/monkey/proc/handle_combat() // Don't do any AI if inside another mob (devoured) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 0aafef753f..3ae022cdcc 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -137,6 +137,9 @@ eye_blurry = max(eye_blurry-1, 0) if(client && !eye_blurry) clear_fullscreen("blurry") + if(disabilities & PACIFISM && a_intent == INTENT_HARM) + to_chat(src, "You don't feel like harming anybody.") + a_intent_change(INTENT_HELP) /mob/living/proc/update_damage_hud() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f589ecbb20..c6f09fdb2f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -809,9 +809,12 @@ to_chat(src, "You don't have the dexterity to do this!") return /mob/living/proc/can_use_guns(obj/item/G) - if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) + if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) to_chat(src, "You don't have the dexterity to do this!") return FALSE + if(disabilities & PACIFISM) + to_chat(src, "You don't want to risk harming anyone!") + return FALSE return TRUE /mob/living/carbon/proc/update_stamina() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f77c65225f..6f639d0016 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -127,14 +127,19 @@ /mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0) if(user == src || anchored || !isturf(user.loc)) - return 0 + return FALSE if(!user.pulling || user.pulling != src) user.start_pulling(src, supress_message) return if(!(status_flags & CANPUSH)) to_chat(user, "[src] can't be grabbed more aggressively!") - return 0 + return FALSE + + if(user.disabilities & PACIFISM) + to_chat(user, "You don't want to risk hurting [src]!") + return FALSE + grippedby(user) //proc to upgrade a simple pull into a more aggressive grab. @@ -188,83 +193,101 @@ M.Feedstop() return // can't attack while eating! + if(disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if (stat != DEAD) add_logs(M, src, "attacked") M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE) - return 1 + return TRUE /mob/living/attack_animal(mob/living/simple_animal/M) M.face_atom(src) if(M.melee_damage_upper == 0) M.visible_message("\The [M] [M.friendly] [src]!") - return 0 + return FALSE else + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) M.do_attack_animation(src) visible_message("\The [M] [M.attacktext] [src]!", \ "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "attacked") - return 1 + return TRUE /mob/living/attack_paw(mob/living/carbon/monkey/M) if(isturf(loc) && istype(loc.loc, /area/start)) to_chat(M, "No attacking people at spawn, you jackass.") - return 0 + return FALSE if (M.a_intent == INTENT_HARM) + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH)) to_chat(M, "You can't bite with your mouth covered!") - return 0 + return FALSE M.do_attack_animation(src, ATTACK_EFFECT_BITE) if (prob(75)) add_logs(M, src, "attacked") playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) - return 1 + return TRUE else visible_message("[M.name] has attempted to bite [src]!", \ "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE /mob/living/attack_larva(mob/living/carbon/alien/larva/L) switch(L.a_intent) if("help") visible_message("[L.name] rubs its head against [src].") - return 0 + return FALSE else + if(L.disabilities & PACIFISM) + to_chat(L, "You don't want to hurt anyone!") + return + L.do_attack_animation(src) if(prob(90)) add_logs(L, src, "attacked") visible_message("[L.name] bites [src]!", \ "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - return 1 + return TRUE else visible_message("[L.name] has attempted to bite [src]!", \ "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE /mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) switch(M.a_intent) if ("help") visible_message("[M] caresses [src] with its scythe like arm.") - return 0 - + return FALSE if ("grab") grabbedby(M) - return 0 + return FALSE if("harm") + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE M.do_attack_animation(src) - return 1 + return TRUE if("disarm") M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return 1 + return TRUE /mob/living/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index a8d6e7840a..ba988f450d 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -15,7 +15,8 @@ /datum/language/monkey, /datum/language/narsie, /datum/language/beachbum, - /datum/language/ratvar + /datum/language/ratvar, + /datum/language/aphasia )) /obj/item/organ/tongue/Initialize(mapload) diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 78f258be67..cc0324ab6a 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -119,7 +119,7 @@ ///////////VOICE OF GOD/////////////// ////////////////////////////////////// -/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1) +/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1, include_speaker = FALSE, message_admins = TRUE) var/cooldown = 0 if(!user || !user.can_speak() || user.stat) @@ -139,7 +139,9 @@ message = lowertext(message) var/mob/living/list/listeners = list() for(var/mob/living/L in get_hearers_in_view(8, user)) - if(L.can_hear() && !L.null_rod_check() && L != user && L.stat != DEAD) + if(L.can_hear() && !L.null_rod_check() && L.stat != DEAD) + if(L == user && !include_speaker) + continue if(ishuman(L)) var/mob/living/carbon/human/H = L if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) @@ -209,12 +211,12 @@ var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown") var/static/regex/sleep_words = regex("sleep|slumber|rest") - var/static/regex/vomit_words = regex("vomit|throw up") - var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush") + var/static/regex/vomit_words = regex("vomit|throw up|sick") + var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush") var/static/regex/hallucinate_words = regex("see the truth|hallucinate") var/static/regex/wakeup_words = regex("wake up|awaken") - var/static/regex/heal_words = regex("live|heal|survive|mend|heroes never die") - var/static/regex/hurt_words = regex("die|suffer|hurt|pain") + var/static/regex/heal_words = regex("live|heal|survive|mend|life|heroes never die") + var/static/regex/hurt_words = regex("die|suffer|hurt|pain|death") var/static/regex/bleed_words = regex("bleed|there will be blood") var/static/regex/burn_words = regex("burn|ignite") var/static/regex/hot_words = regex("heat|hot|hell") @@ -566,7 +568,8 @@ else cooldown = COOLDOWN_NONE - message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + if(message_admins) + message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") log_game("[key_name(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") SSblackbox.record_feedback("tally", "voice_of_god", 1, log_message) diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi index f4894c2b90c0d864e1a2a80f2457ed507ebaba17..4e627f16c753a836d5dab75e447ca4f92881a78e 100644 GIT binary patch literal 4323 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 RSswrZ002ovPDHLkV1j^QUYq~` literal 2383 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 Boa+Dp diff --git a/strings/brain_damage_lines.json b/strings/traumas.json similarity index 81% rename from strings/brain_damage_lines.json rename to strings/traumas.json index 4a28998e2c..db7a226f23 100644 --- a/strings/brain_damage_lines.json +++ b/strings/traumas.json @@ -186,6 +186,7 @@ "", ";", ".h" +<<<<<<< HEAD:strings/brain_damage_lines.json ], "roles": [ @@ -215,4 +216,58 @@ "wizzerd" ] +======= + ], + + "god_foe": [ + "MORTALS", + "HERETICS", + "INSECTS", + "UNBELIEVERS", + "BLASPHEMERS", + "PARASITES", + "WEAKLINGS", + "PEASANTS" + ], + + "god_aggressive": [ + "BEGONE, @pick(god_foe)!", + "DIE, @pick(god_foe)!", + "BLEED, @pick(god_foe)!", + "BURN, @pick(god_foe)!", + "ALL WILL FALL BEFORE ME!", + "ENDLESS SUFFERING AWAITS YOU, @pick(god_foe).", + "DEATH TO @pick(god_foe)!" + ], + + "god_neutral": [ + "STOP", + "HALT.", + "BE SILENT.", + "QUIET", + "SEE THE TRUTH BEFORE YOU, MORTALS.", + "MORTALS, SAY YOUR NAME", + "BEGONE, MORTALS.", + "BE HEALED, MORTALS. I AM FEELING MERCIFUL.", + "DANCE FOR ME, LITTLE MORTALS.", + "YOU. STOP.", + "REST, MORTALS, TOMORROW IS A LONG DAY.", + "YOU MORTALS MAKE ME SICK.", + "HONK..." + ], + + "god_unstun": [ + "GET UP. I HAVE NO TIME TO LOSE.", + "GET UP, PRIEST.", + "GET UP." + ], + + "god_heal": [ + "YOU WILL LIVE TO SEE ANOTHER DAY.", + "YOU SHALL SURVIVE THIS, MY PRIEST.", + "BE HEALED, PRIEST.", + "YOUR LIFE IS IMPORTANT. KEEP IT." + ] + +>>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405):strings/traumas.json } diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..b9852a55bc 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -334,6 +334,7 @@ #include "code\datums\antagonists\revolution.dm" #include "code\datums\antagonists\wizard.dm" #include "code\datums\brain_damage\brain_trauma.dm" +#include "code\datums\brain_damage\imaginary_friend.dm" #include "code\datums\brain_damage\mild.dm" #include "code\datums\brain_damage\phobia.dm" #include "code\datums\brain_damage\severe.dm" @@ -1622,6 +1623,20 @@ #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" #include "code\modules\jobs\map_changes\map_changes.dm" +<<<<<<< HEAD +======= +#include "code\modules\keybindings\bindings_admin.dm" +#include "code\modules\keybindings\bindings_atom.dm" +#include "code\modules\keybindings\bindings_carbon.dm" +#include "code\modules\keybindings\bindings_client.dm" +#include "code\modules\keybindings\bindings_human.dm" +#include "code\modules\keybindings\bindings_living.dm" +#include "code\modules\keybindings\bindings_mob.dm" +#include "code\modules\keybindings\bindings_robot.dm" +#include "code\modules\keybindings\focus.dm" +#include "code\modules\keybindings\setup.dm" +#include "code\modules\language\aphasia.dm" +>>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405) #include "code\modules\language\beachbum.dm" #include "code\modules\language\codespeak.dm" #include "code\modules\language\common.dm" From 3b1c537bb42dd5287a6dca81ee2a88a9d4608454 Mon Sep 17 00:00:00 2001 From: Evsey Antonovich Date: Sun, 17 Dec 2017 22:30:06 +0500 Subject: [PATCH 045/213] changes one letter (#33591) --- code/game/objects/structures/mirror.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 711f9baf0b..44c12a21a1 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -89,7 +89,7 @@ name = "magic mirror" desc = "Turn and face the strange... face." icon_state = "magic_mirror" - var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie") + var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombies") var/list/choosable_races = list() /obj/structure/mirror/magic/New() From 3d375e0be97c18ca5c42534835bcd6023b6d1f72 Mon Sep 17 00:00:00 2001 From: duncathan salt Date: Sun, 17 Dec 2017 14:37:16 -0600 Subject: [PATCH 047/213] properly disables fusion (#33632) --- code/modules/atmospherics/gasmixtures/reactions.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 5a88c6837e..aabbe089fb 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -184,7 +184,7 @@ //fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. /datum/gas_reaction/fusion - exclude = FALSE + exclude = TRUE priority = 2 name = "Plasmic Fusion" id = "fusion" From ac95eb06e82d8142a0df021ac6c63f700baf06d0 Mon Sep 17 00:00:00 2001 From: oranges Date: Mon, 18 Dec 2017 10:01:41 +1300 Subject: [PATCH 049/213] Dance Machine now obeys instrument preference (#33607) --- code/game/machinery/dance_machine.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index ec8779b7d2..79ec733303 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -459,6 +459,8 @@ var/sound/song_played = sound(selection.song_path) for(var/mob/M in range(10,src)) + if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + continue if(!(M in rangers)) rangers[M] = TRUE M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) From 99a173b187be808b3f54e0ddebd1d170494c6c2c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:54:52 -0600 Subject: [PATCH 051/213] Update stat.dm --- code/__DEFINES/stat.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 86f14f8ec0..a23f050c13 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -18,14 +18,9 @@ #define HUSK 64 #define NOCLONE 128 #define CLUMSY 256 -<<<<<<< HEAD -#define DUMB 512 -#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE -======= #define DUMB 512 #define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE #define PACIFISM 2048 ->>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405) // bitflags for machine stat variable #define BROKEN 1 From d4c218ec09ae39a562927d887785ca3e4e702094 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:55:04 -0600 Subject: [PATCH 052/213] Update traumas.json --- strings/traumas.json | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/strings/traumas.json b/strings/traumas.json index db7a226f23..9b14a7b530 100644 --- a/strings/traumas.json +++ b/strings/traumas.json @@ -186,37 +186,6 @@ "", ";", ".h" -<<<<<<< HEAD:strings/brain_damage_lines.json - ], - - "roles": [ - "heds", - "ceptin", - "hop", - "arrdee", - "sek" - ], - - "cargo": [ - "GUNS", - "HATS", - "PIZEH", - "MEMES", - "GLOWY CYSTAL" - - ], - - "s_roles": [ - "ert", - "shadowlig", - "ninja", - "admen", - "mantor", - "bluh daymon", - "wizzerd" - - ] -======= ], "god_foe": [ @@ -268,6 +237,4 @@ "BE HEALED, PRIEST.", "YOUR LIFE IS IMPORTANT. KEEP IT." ] - ->>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405):strings/traumas.json } From 27e0d531c622c412ca1d0829d55e6d6737f21ac0 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:55:23 -0600 Subject: [PATCH 053/213] Update tgstation.dme --- tgstation.dme | 3 --- 1 file changed, 3 deletions(-) diff --git a/tgstation.dme b/tgstation.dme index b9852a55bc..d6fb877efa 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1623,8 +1623,6 @@ #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" #include "code\modules\jobs\map_changes\map_changes.dm" -<<<<<<< HEAD -======= #include "code\modules\keybindings\bindings_admin.dm" #include "code\modules\keybindings\bindings_atom.dm" #include "code\modules\keybindings\bindings_carbon.dm" @@ -1636,7 +1634,6 @@ #include "code\modules\keybindings\focus.dm" #include "code\modules\keybindings\setup.dm" #include "code\modules\language\aphasia.dm" ->>>>>>> b5d9845... [Ready]Brain Trauma additions (#33405) #include "code\modules\language\beachbum.dm" #include "code\modules\language\codespeak.dm" #include "code\modules\language\common.dm" From 420bebf36f6325d362740a30202cc3be7abfab55 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:29 -0600 Subject: [PATCH 054/213] Update radio.dm --- code/__HELPERS/radio.dm | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 56471142ca..39fe55c67c 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,19 +1,3 @@ -<<<<<<< HEAD -// Ensure the frequency is within bounds of what it should be sending/recieving at -/proc/sanitize_frequency(frequency, free = FALSE) - . = round(frequency) - if(free) - . = Clamp(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) - else - . = Clamp(frequency, MIN_FREQ, MAX_FREQ) - if(!(. % 2)) // Ensure the last digit is an odd number - . += 1 - -// Format frequency by moving the decimal. -/proc/format_frequency(frequency) - frequency = text2num(frequency) - return "[round(frequency / 10)].[frequency % 10]" -======= // Ensure the frequency is within bounds of what it should be sending/recieving at /proc/sanitize_frequency(frequency, free = FALSE) . = round(frequency) @@ -28,4 +12,3 @@ /proc/format_frequency(frequency) frequency = text2num(frequency) return "[round(frequency / 10)].[frequency % 10]" ->>>>>>> 25080ff... defines math (#33498) From d384941d5c781bb5f2ae1232efab043e7d530df5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:44 -0600 Subject: [PATCH 055/213] Update robot.dm --- code/_onclick/hud/robot.dm | 280 ------------------------------------- 1 file changed, 280 deletions(-) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index e227968f57..769cdb2244 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,282 +1,3 @@ -<<<<<<< HEAD -/obj/screen/robot - icon = 'icons/mob/screen_cyborg.dmi' - -/obj/screen/robot/module - name = "cyborg module" - icon_state = "nomod" - -/obj/screen/robot/Click() - if(isobserver(usr)) - return 1 - -/obj/screen/robot/module/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - if(R.module.type != /obj/item/robot_module) - R.hud_used.toggle_show_robot_modules() - return 1 - R.pick_module() - -/obj/screen/robot/module1 - name = "module1" - icon_state = "inv1" - -/obj/screen/robot/module1/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(1) - -/obj/screen/robot/module2 - name = "module2" - icon_state = "inv2" - -/obj/screen/robot/module2/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(2) - -/obj/screen/robot/module3 - name = "module3" - icon_state = "inv3" - -/obj/screen/robot/module3/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(3) - -/obj/screen/robot/radio - name = "radio" - icon_state = "radio" - -/obj/screen/robot/radio/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.radio.interact(R) - -/obj/screen/robot/store - name = "store" - icon_state = "store" - -/obj/screen/robot/store/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.uneq_active() - -/obj/screen/robot/lamp - name = "headlamp" - icon_state = "lamp0" - -/obj/screen/robot/lamp/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.control_headlamp() - -/obj/screen/robot/thrusters - name = "ion thrusters" - icon_state = "ionpulse0" - -/obj/screen/robot/thrusters/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_ionpulse() - -/datum/hud/robot - ui_style_icon = 'icons/mob/screen_cyborg.dmi' - -/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi') - ..() - var/mob/living/silicon/robot/mymobR = mymob - var/obj/screen/using - - using = new/obj/screen/language_menu - using.screen_loc = ui_borg_language_menu - static_inventory += using - -//Radio - using = new /obj/screen/robot/radio() - using.screen_loc = ui_borg_radio - static_inventory += using - -//Module select - using = new /obj/screen/robot/module1() - using.screen_loc = ui_inv1 - static_inventory += using - mymobR.inv1 = using - - using = new /obj/screen/robot/module2() - using.screen_loc = ui_inv2 - static_inventory += using - mymobR.inv2 = using - - using = new /obj/screen/robot/module3() - using.screen_loc = ui_inv3 - static_inventory += using - mymobR.inv3 = using - -//End of module select - -//Photography stuff - using = new /obj/screen/ai/image_take() - using.screen_loc = ui_borg_camera - static_inventory += using - - using = new /obj/screen/ai/image_view() - using.screen_loc = ui_borg_album - static_inventory += using - -//Sec/Med HUDs - using = new /obj/screen/ai/sensors() - using.screen_loc = ui_borg_sensor - static_inventory += using - -//Headlamp control - using = new /obj/screen/robot/lamp() - using.screen_loc = ui_borg_lamp - static_inventory += using - mymobR.lamp_button = using - -//Thrusters - using = new /obj/screen/robot/thrusters() - using.screen_loc = ui_borg_thrusters - static_inventory += using - mymobR.thruster_button = using - -//Intent - action_intent = new /obj/screen/act_intent/robot() - action_intent.icon_state = mymob.a_intent - static_inventory += action_intent - -//Health - healths = new /obj/screen/healths/robot() - infodisplay += healths - -//Installed Module - mymobR.hands = new /obj/screen/robot/module() - mymobR.hands.screen_loc = ui_borg_module - static_inventory += mymobR.hands - -//Store - module_store_icon = new /obj/screen/robot/store() - module_store_icon.screen_loc = ui_borg_store - - pull_icon = new /obj/screen/pull() - pull_icon.icon = 'icons/mob/screen_cyborg.dmi' - pull_icon.update_icon(mymob) - pull_icon.screen_loc = ui_borg_pull - hotkeybuttons += pull_icon - - - zone_select = new /obj/screen/zone_sel/robot() - zone_select.update_icon(mymob) - static_inventory += zone_select - - -/datum/hud/proc/toggle_show_robot_modules() - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - R.shown_robot_modules = !R.shown_robot_modules - update_robot_modules_display() - -/datum/hud/proc/update_robot_modules_display(mob/viewer) - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(!R.module) - return - - if(!R.client) - return - - if(R.shown_robot_modules && screenmob.hud_used.hud_shown) - //Modules display is shown - screenmob.client.screen += module_store_icon //"store" icon - - if(!R.module.modules) - to_chat(usr, "Selected module has no modules to select") - return - - if(!R.robot_modules_background) - return - - var/display_rows = Ceiling(length(R.module.get_inactive_modules()) / 8) - R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" - screenmob.client.screen += R.robot_modules_background - - var/x = -4 //Start at CENTER-4,SOUTH+1 - var/y = 1 - - for(var/atom/movable/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen += A - if(x < 0) - A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" - else - A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = ABOVE_HUD_LAYER - A.plane = ABOVE_HUD_PLANE - - x++ - if(x == 4) - x = -4 - y++ - - else - //Modules display is hidden - screenmob.client.screen -= module_store_icon //"store" icon - - for(var/atom/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen -= A - R.shown_robot_modules = 0 - screenmob.client.screen -= R.robot_modules_background - -/mob/living/silicon/robot/create_mob_hud() - if(client && !hud_used) - hud_used = new /datum/hud/robot(src) - - -/datum/hud/robot/persistent_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - for(var/i in 1 to R.held_items.len) - var/obj/item/I = R.held_items[i] - if(I) - switch(i) - if(1) - I.screen_loc = ui_inv1 - if(2) - I.screen_loc = ui_inv2 - if(3) - I.screen_loc = ui_inv3 - else - return - screenmob.client.screen += I - else - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I -======= /obj/screen/robot icon = 'icons/mob/screen_cyborg.dmi' @@ -554,4 +275,3 @@ else for(var/obj/item/I in R.held_items) screenmob.client.screen -= I ->>>>>>> 25080ff... defines math (#33498) From f377aa441f83e7f6747bccce81b63dcc9d834b7a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:54 -0600 Subject: [PATCH 056/213] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 6670bfbfa7..c9c8504955 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,14 +154,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() -<<<<<<< HEAD - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len - danger = Ceiling(danger, 10) -======= var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) ->>>>>>> 25080ff... defines math (#33498) scaleTC(danger) /obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. @@ -229,4 +224,4 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E src.updateUsrDialog() return -#undef NUKESCALINGMODIFIER \ No newline at end of file +#undef NUKESCALINGMODIFIER From 75ccc3b354aa62f4cab120cdcc1045e00be7037b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:02 -0600 Subject: [PATCH 057/213] Update anomalies.dm --- code/game/objects/effects/anomalies.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 70a6f1bdba..76fd5e5cbf 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -26,14 +26,8 @@ aSignal = new(src) aSignal.name = "[name] core" aSignal.code = rand(1,100) - -<<<<<<< HEAD - aSignal.frequency = rand(1200, 1599) - if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven! -======= aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ) if(ISMULTIPLE(aSignal.frequency, 2))//signaller frequencies are always uneven! ->>>>>>> 25080ff... defines math (#33498) aSignal.frequency++ if(new_lifespan) From 4bf535f808394e30d5923d5a75cec62a24bd8677 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:23 -0600 Subject: [PATCH 058/213] Update weldingtool.dm --- code/game/objects/items/tools/weldingtool.dm | 393 ++----------------- 1 file changed, 26 insertions(+), 367 deletions(-) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 415cd02585..6e3fab7212 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD #define WELDER_FUEL_BURN_INTERVAL 13 /obj/item/weldingtool name = "welding tool" @@ -22,7 +21,7 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) resistance_flags = FIRE_PROOF - materials = list(MAT_METAL=70, MAT_GLASS=30) + materials = list(MAT_METAL=70, MAT_GLASS=30) var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -52,7 +51,7 @@ cut_overlays() if(change_icons) var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)][ratio]") update_torch() return @@ -90,18 +89,15 @@ flamethrower_screwdriver(I, user) else if(istype(I, /obj/item/stack/rods)) flamethrower_rods(I, user) - else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) - var/amountNeeded = max_fuel - get_fuel() - var/obj/item/reagent_containers/container = I - if(length(container.reagents.reagent_list) > 1) - to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") - return ..() - if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) - container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) - to_chat(user, "You transfer some fuel from [container] to [src].") else - return ..() + . = ..() + update_icon() +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) @@ -124,7 +120,10 @@ /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) if(!proximity) return - + if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() if(welding) remove_fuel(1) var/turf/location = get_turf(user) @@ -140,6 +139,9 @@ /obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() switched_on(user) if(welding) set_light(light_intensity) @@ -235,9 +237,11 @@ return status = !status if(status) - to_chat(user, "You resecure [src].") + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE else - to_chat(user, "[src] can now be attached and modified.") + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER_1 add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) @@ -265,7 +269,7 @@ desc = "A slightly larger welder with a larger tank." icon_state = "indwelder" max_fuel = 40 - materials = list(MAT_GLASS=60) + materials = list(MAT_GLASS=60) /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -295,7 +299,7 @@ icon_state = "welder" toolspeed = 0.1 light_intensity = 0 - change_icons = 0 + change_icons = 0 /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -308,7 +312,7 @@ icon_state = "upindwelder" item_state = "upindwelder" max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -316,7 +320,7 @@ icon_state = "exwelder" item_state = "exwelder" max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -337,350 +341,5 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) -======= -#define WELDER_FUEL_BURN_INTERVAL 13 -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = CEILING(ratio*4, 1) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - . = ..() - update_icon() - -/obj/item/weldingtool/proc/explode() - var/turf/T = get_turf(loc) - var/plasmaAmount = reagents.get_reagent_amount("plasma") - dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder - qdel(src) - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) - return - if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) - reagents.trans_to(O, reagents.total_volume) - to_chat(user, "You empty [src]'s fuel tank into [O].") - update_icon() - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - if(src.reagents.has_reagent("plasma")) - message_admins("[key_name_admin(user)] activated a rigged welder.") - explode() - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src] and close the fuel tank.") - container_type = NONE - else - to_chat(user, "[src] can now be attached, modified, and refuelled.") - container_type = OPENCONTAINER_1 - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - ->>>>>>> 25080ff... defines math (#33498) -#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file + +#undef WELDER_FUEL_BURN_INTERVAL From 2771fe55e44a8c9a783f609cd0f9ad1247e15f82 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:33 -0600 Subject: [PATCH 059/213] Update pump.dm --- .../machinery/components/binary_devices/pump.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 898a8157ae..9d581fcb78 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -133,14 +133,8 @@ Thus, the two variables affect pump operation are set in New(): pressure = text2num(pressure) . = TRUE if(.) -<<<<<<< HEAD - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") -======= target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) ->>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/pump/atmosinit() From 28dfbc7ccc9a4be243dbec512ed6d21676bb24a0 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:46 -0600 Subject: [PATCH 060/213] Update volume_pump.dm --- .../machinery/components/binary_devices/volume_pump.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index bdc1ae15a3..2803d1bf09 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -133,14 +133,8 @@ Thus, the two variables affect pump operation are set in New(): rate = text2num(rate) . = TRUE if(.) -<<<<<<< HEAD - transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) - investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") -======= transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) ->>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal) From 2a7b168e0b5520a67752eba35f38941252740384 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:57 -0600 Subject: [PATCH 061/213] Update client_procs.dm --- code/modules/client/client_procs.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index f356d6c057..411816227f 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -673,8 +673,6 @@ GLOBAL_LIST(external_rsc_urls) return TRUE . = ..() -<<<<<<< HEAD -======= /client/proc/rescale_view(change, min, max) var/viewscale = getviewsize(view) var/x = viewscale[1] @@ -682,7 +680,6 @@ GLOBAL_LIST(external_rsc_urls) x = CLAMP(x+change, min, max) y = CLAMP(y+change, min,max) change_view("[x]x[y]") ->>>>>>> 25080ff... defines math (#33498) /client/proc/change_view(new_size) if (isnull(new_size)) From e6aaad19217abe3e8ac873cf349bdbc940023f71 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:58:06 -0600 Subject: [PATCH 062/213] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 1ade939ad3..dbde34d84d 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -18,16 +18,12 @@ announceWhen = rand(15, 30) /datum/round_event/disease_outbreak/start() -<<<<<<< HEAD - if(!virus_type) -======= var/advanced_virus = FALSE max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE if(!virus_type && !advanced_virus) ->>>>>>> 25080ff... defines math (#33498) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) @@ -62,4 +58,4 @@ D = new virus_type() D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + break From 5b107f392275ed2b1edbdf1b4b4c6855a56a47a1 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Sun, 17 Dec 2017 17:15:38 -0500 Subject: [PATCH 063/213] Microwave sound loops now stop in all cases where it should, such as being interrupted or breaking (#33598) * Stops microwave sound loops when it should * rogue sound! --- code/modules/food_and_drinks/kitchen_machinery/microwave.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 9f76139151..dfa249c04d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -277,9 +277,9 @@ operating = FALSE // Turn it off again aferwards icon_state = "mw" updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/proc/stop() - soundloop.stop() abort() /obj/machinery/microwave/proc/dispose() @@ -293,7 +293,6 @@ icon_state = "mwbloody1" // Make it look dirty!! /obj/machinery/microwave/proc/muck_finish() - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) visible_message("The microwave gets covered in muck!") dirty = 100 // Make it dirty so it can't be used util cleaned icon_state = "mwbloody" // Make it look dirty too @@ -303,6 +302,7 @@ if(prob(50)) new /obj/item/reagent_containers/food/snacks/badrecipe(src) qdel(S) + soundloop.stop() /obj/machinery/microwave/proc/broke() var/datum/effect_system/spark_spread/s = new @@ -314,6 +314,7 @@ flags_1 = null //So you can't add condiments operating = FALSE // Turn it off again aferwards updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/Topic(href, href_list) if(..() || panel_open) From a2dbbac70332e3dafd43afe10b265892be29cc55 Mon Sep 17 00:00:00 2001 From: coiax Date: Sun, 17 Dec 2017 22:17:09 +0000 Subject: [PATCH 065/213] Lollipop dispensers can push lollipops into people's hands (#33419) * Lollipop dispensers can push lollipops into people's hands :cl: coiax add: A lollipop dispenser in "dispense lollipops" mode can push the lollipop straight into the targets hand, rather than getting it dirty on the floor first. /:cl: Also tidied up and around the robot_items.dm file. This is a good idea because then you can give people lollipops as a cyborg that has the lollipop dispenser module. * Integers instead of numbers --- code/game/objects/items/robot/robot_items.dm | 51 ++++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e4485266b5..c0c927320c 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -33,7 +33,7 @@ add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])") /obj/item/borg/cyborghug - name = "Hugging Module" + name = "hugging module" icon_state = "hugmodule" desc = "For when a someone really needs a hug." var/mode = 0 //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH @@ -336,6 +336,10 @@ cooldown = world.time + 600 log_game("[user.ckey]([user]) used an emagged Cyborg Harm Alarm in ([user.x],[user.y],[user.z])") +#define DISPENSE_LOLLIPOP_MODE 1 +#define THROW_LOLLIPOP_MODE 2 +#define THROW_GUMBALL_MODE 3 + /obj/item/borg/lollipop name = "lollipop fabricator" desc = "Reward good humans with this. Toggle in-module to switch between dispensing and high velocity ejection modes." @@ -343,8 +347,9 @@ var/candy = 30 var/candymax = 30 var/charge_delay = 10 - var/charging = 0 - var/mode = 1 + var/charging = FALSE + var/mode = DISPENSE_LOLLIPOP_MODE + var/firedelay = 0 var/hitspeed = 2 var/hitdamage = 0 @@ -379,10 +384,22 @@ var/obj/O = A if(O.density) return FALSE - new /obj/item/reagent_containers/food/snacks/lollipop(T) + + var/obj/item/reagent_containers/food/snacks/lollipop/L = new(T) + + var/into_hands = FALSE + if(ismob(A)) + var/mob/M = A + into_hands = M.put_in_hands(L) + candy-- check_amount() - to_chat(user, "Dispensing lollipop...") + + if(into_hands) + user.visible_message("[user] dispenses a lollipop into the hands of [A].", "You dispense a lollipop into the hands of [A].", "You hear a click.") + else + user.visible_message("[user] dispenses a lollipop.", "You dispense a lollipop.", "You hear a click.") + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) return TRUE @@ -427,29 +444,33 @@ if(R.emagged) hitdamage = emaggedhitdamage switch(mode) - if(1) + if(DISPENSE_LOLLIPOP_MODE) if(!proximity) return FALSE dispense(target, user) - if(2) + if(THROW_LOLLIPOP_MODE) shootL(target, user, click_params) - if(3) + if(THROW_GUMBALL_MODE) shootG(target, user, click_params) hitdamage = initial(hitdamage) /obj/item/borg/lollipop/attack_self(mob/living/user) switch(mode) - if(1) - mode++ + if(DISPENSE_LOLLIPOP_MODE) + mode = THROW_LOLLIPOP_MODE to_chat(user, "Module is now throwing lollipops.") - if(2) - mode++ + if(THROW_LOLLIPOP_MODE) + mode = THROW_GUMBALL_MODE to_chat(user, "Module is now blasting gumballs.") - if(3) - mode = 1 + if(THROW_GUMBALL_MODE) + mode = DISPENSE_LOLLIPOP_MODE to_chat(user, "Module is now dispensing lollipops.") ..() +#undef DISPENSE_LOLLIPOP_MODE +#undef THROW_LOLLIPOP_MODE +#undef THROW_GUMBALL_MODE + /obj/item/ammo_casing/caseless/gumball name = "Gumball" desc = "Why are you seeing this?!" @@ -655,7 +676,7 @@ /obj/item/borg/sight/xray - name = "\proper x-ray Vision" + name = "\proper x-ray vision" icon = 'icons/obj/decals.dmi' icon_state = "securearea" sight_mode = BORGXRAY From 80c5bf53400579926c64cdc7c5bba9f87ff64ec8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:34:27 -0600 Subject: [PATCH 067/213] Update tgstation.dme --- tgstation.dme | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tgstation.dme b/tgstation.dme index d6fb877efa..60e0228790 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1623,16 +1623,6 @@ #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" #include "code\modules\jobs\map_changes\map_changes.dm" -#include "code\modules\keybindings\bindings_admin.dm" -#include "code\modules\keybindings\bindings_atom.dm" -#include "code\modules\keybindings\bindings_carbon.dm" -#include "code\modules\keybindings\bindings_client.dm" -#include "code\modules\keybindings\bindings_human.dm" -#include "code\modules\keybindings\bindings_living.dm" -#include "code\modules\keybindings\bindings_mob.dm" -#include "code\modules\keybindings\bindings_robot.dm" -#include "code\modules\keybindings\focus.dm" -#include "code\modules\keybindings\setup.dm" #include "code\modules\language\aphasia.dm" #include "code\modules\language\beachbum.dm" #include "code\modules\language\codespeak.dm" From 3c5632bad25b27cfc0c8f8bc9568b56b0c84e162 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:38:51 -0600 Subject: [PATCH 068/213] Update pill.dm --- .../reagents/reagent_containers/pill.dm | 159 +----------------- 1 file changed, 1 insertion(+), 158 deletions(-) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index b1a126ba62..5a2e888210 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,159 +1,3 @@ -<<<<<<< HEAD -/obj/item/reagent_containers/pill - name = "pill" - desc = "A tablet or capsule." - icon = 'icons/obj/chemical.dmi' - icon_state = "pill" - item_state = "pill" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - possible_transfer_amounts = list() - volume = 50 - var/apply_type = INGEST - var/apply_method = "swallow" - var/roundstart = 0 - var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills - -/obj/item/reagent_containers/pill/Initialize() - . = ..() - if(!icon_state) - icon_state = "pill[rand(1,20)]" - if(reagents.total_volume && roundstart) - name += " ([reagents.total_volume]u)" - - -/obj/item/reagent_containers/pill/attack_self(mob/user) - return - - -/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) - if(!canconsume(M, user)) - return 0 - - if(M == user) - M.visible_message("[user] attempts to [apply_method] [src].") - if(self_delay) - if(!do_mob(user, M, self_delay)) - return 0 - to_chat(M, "You [apply_method] [src].") - - else - M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ - "[user] attempts to force [M] to [apply_method] [src].") - if(!do_mob(user, M)) - return 0 - M.visible_message("[user] forces [M] to [apply_method] [src].", \ - "[user] forces [M] to [apply_method] [src].") - - - add_logs(user, M, "fed", reagentlist(src)) - if(reagents.total_volume) - reagents.reaction(M, apply_type) - reagents.trans_to(M, reagents.total_volume) - qdel(src) - return 1 - - -/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) - if(!proximity) - return - if(target.is_open_container() != 0 && target.reagents) - if(!target.reagents.total_volume) - to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") - return - to_chat(user, "You dissolve [src] in [target].") - for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius - to_chat(O, "[user] slips something into [target]!") - reagents.trans_to(target, reagents.total_volume) - qdel(src) - -/obj/item/reagent_containers/pill/tox - name = "toxins pill" - desc = "Highly toxic." - icon_state = "pill5" - list_reagents = list("toxin" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/cyanide - name = "cyanide pill" - desc = "Don't swallow this." - icon_state = "pill5" - list_reagents = list("cyanide" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/adminordrazine - name = "adminordrazine pill" - desc = "It's magic. We don't have to explain it." - icon_state = "pill16" - list_reagents = list("adminordrazine" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/morphine - name = "morphine pill" - desc = "Commonly used to treat insomnia." - icon_state = "pill8" - list_reagents = list("morphine" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/stimulant - name = "stimulant pill" - desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" - icon_state = "pill19" - list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/salbutamol - name = "salbutamol pill" - desc = "Used to treat oxygen deprivation." - icon_state = "pill16" - list_reagents = list("salbutamol" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/charcoal - name = "charcoal pill" - desc = "Neutralizes many common toxins." - icon_state = "pill17" - list_reagents = list("charcoal" = 10) - roundstart = 1 -/obj/item/reagent_containers/pill/epinephrine - name = "epinephrine pill" - desc = "Used to stabilize patients." - icon_state = "pill5" - list_reagents = list("epinephrine" = 15) - roundstart = 1 -/obj/item/reagent_containers/pill/mannitol - name = "mannitol pill" - desc = "Used to treat brain damage." - icon_state = "pill17" - list_reagents = list("mannitol" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/mutadone - name = "mutadone pill" - desc = "Used to treat genetic damage." - icon_state = "pill20" - list_reagents = list("mutadone" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/salicyclic - name = "salicylic acid pill" - desc = "Used to dull pain." - icon_state = "pill9" - list_reagents = list("sal_acid" = 24) - roundstart = 1 -/obj/item/reagent_containers/pill/oxandrolone - name = "oxandrolone pill" - desc = "Used to stimulate burn healing." - icon_state = "pill11" - list_reagents = list("oxandrolone" = 24) - roundstart = 1 - -/obj/item/reagent_containers/pill/insulin - name = "insulin pill" - desc = "Handles hyperglycaemic coma." - icon_state = "pill18" - list_reagents = list("insulin" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/shadowtoxin - name = "black pill" - desc = "I wouldn't eat this if I were you." - icon_state = "pill9" - color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) -======= /obj/item/reagent_containers/pill name = "pill" desc = "A tablet or capsule." @@ -308,5 +152,4 @@ desc = "I wouldn't eat this if I were you." icon_state = "pill9" color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) + list_reagents = list("shadowmutationtoxin" = 1) From 9cbe879b511e80947289698394e20a7b4f88d1ce Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:47:12 -0600 Subject: [PATCH 069/213] Update comms.dm --- code/controllers/configuration/entries/comms.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index 70197b6fd4..56cec985f1 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -4,11 +4,7 @@ /datum/config_entry/string/comms_key/ValidateAndSet(str_val) return str_val != "default_pwd" && length(str_val) > 6 && ..() -<<<<<<< HEAD -CONFIG_DEF(string/cross_server_address) -======= /datum/config_entry/keyed_string_list/cross_server ->>>>>>> 8c537ea... Adds config inclusion system (#33307) protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) @@ -21,4 +17,4 @@ GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fa /datum/config_entry/string/medal_hub_address /datum/config_entry/string/medal_hub_password - protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file + protection = CONFIG_ENTRY_HIDDEN From e93bb49994c8de5df04b9707432b64e6ec62ec90 Mon Sep 17 00:00:00 2001 From: coiax Date: Mon, 18 Dec 2017 01:27:17 +0000 Subject: [PATCH 070/213] Spinning resin or laying eggs on vents prompts the user if they're sure (#33302) add: Aliens (and humans with alien organs) are unable to create resin structures or lay eggs atop vents or scrubbers. This stops stupid aliens from obscuring entrances to the very helpful and useful atmospheric piping system. --- .../carbon/alien/humanoid/alien_powers.dm | 22 ++++++++++++++----- .../mob/living/carbon/alien/humanoid/queen.dm | 12 ++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index eb17ecc40a..a15e952bcf 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -59,6 +59,14 @@ Doesn't work on other aliens/AI.*/ return 0 return 1 +/obj/effect/proc_holder/alien/proc/check_vent_block(mob/living/user) + var/obj/machinery/atmospherics/components/unary/atmos_thing = locate() in user.loc + if(atmos_thing) + var/rusure = alert(user, "Laying eggs and shaping resin here would block access to [atmos_thing]. Do you want to continue?", "Blocking Atmospheric Component", "Yes", "No") + if(rusure != "No") + return FALSE + return TRUE + /obj/effect/proc_holder/alien/plant name = "Plant Weeds" desc = "Plants some alien weeds." @@ -243,7 +251,7 @@ Doesn't work on other aliens/AI.*/ name = "Secrete Resin" desc = "Secrete tough malleable resin." plasma_cost = 55 - check_turf = 1 + check_turf = TRUE var/list/structures = list( "resin wall" = /obj/structure/alien/resin/wall, "resin membrane" = /obj/structure/alien/resin/membrane, @@ -254,18 +262,22 @@ Doesn't work on other aliens/AI.*/ /obj/effect/proc_holder/alien/resin/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/resin) in user.loc) to_chat(user, "There is already a resin structure there.") - return 0 + return FALSE + + if(!check_vent_block(user)) + return FALSE + var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in structures if(!choice) - return 0 + return FALSE if (!cost_check(check_turf,user)) - return 0 + return FALSE to_chat(user, "You shape a [choice].") user.visible_message("[user] vomits up a thick purple substance and begins to shape it.") choice = structures[choice] new choice(user.loc) - return 1 + return TRUE /obj/effect/proc_holder/alien/regurgitate name = "Regurgitate" diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 4f79ed7d25..5a48e1c6d1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -79,16 +79,20 @@ name = "Lay Egg" desc = "Lay an egg to produce huggers to impregnate prey with." plasma_cost = 75 - check_turf = 1 + check_turf = TRUE action_icon_state = "alien_egg" /obj/effect/proc_holder/alien/lay_egg/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/egg) in get_turf(user)) - to_chat(user, "There's already an egg here.") - return 0 + to_chat(user, "There's already an egg here.") + return FALSE + + if(!check_vent_block(user)) + return FALSE + user.visible_message("[user] has laid an egg!") new /obj/structure/alien/egg(user.loc) - return 1 + return TRUE //Button to let queen choose her praetorian. /obj/effect/proc_holder/alien/royal/queen/promote From 2578484644f600badb30970b0f60a82ab12cf2f4 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 18 Dec 2017 00:21:25 -0200 Subject: [PATCH 072/213] Merge pull request #33613 from Armhulen/patch-32 deep fryers are quieter now... --- code/datums/looping_sounds/machinery_sounds.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 562311180d..b84133faf7 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -32,7 +32,7 @@ mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) mid_length = 2 end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' - volume = 25 + volume = 15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From ea47d74997658924a6b50676a9f1dbf0cac1852d Mon Sep 17 00:00:00 2001 From: AnturK Date: Mon, 18 Dec 2017 03:45:26 +0100 Subject: [PATCH 074/213] Adds repeated message squashing to chat. (#33605) * Adds repeated message squashing to chat. * Forgot to actually use the pref * Drops some unnecessary css * No trimming same thing three times * Increases size of repeats up to 24px, fixes scrolling --- .../browserassets/css/browserOutput.css | 13 +++ .../browserassets/html/browserOutput.html | 1 + .../browserassets/js/browserOutput.js | 79 ++++++++++++++----- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 4d31d082c6..824c86c69d 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -38,6 +38,19 @@ img.icon { vertical-align: bottom; } + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: 700; + line-height: 1; + color: #f00; +} + a {color: #0000ff;} a.visited {color: #ff00ff;} a:visited {color: #ff00ff;} diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 7b2d3ecfe0..82a1ed4885 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -39,6 +39,7 @@ Toggle ping display Highlight string Save chat log + Toggle line combining Clear all messages
    diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 2ef7704625..43092846c2 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -22,7 +22,7 @@ window.onerror = function(msg, url, line, col, error) { //Globals window.status = 'Output'; -var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages; +var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages, $last_message; var opts = { //General 'messageCount': 0, //A count...of messages... @@ -68,6 +68,8 @@ var opts = { 'defaultMusicVolume': 25, + 'messageCombining': true, + }; function clamp(val, min, max) { @@ -294,27 +296,54 @@ function output(message, flag) { opts.messageCount--; //I guess the count should only ever equal the limit } - //Actually append the message - var entry = document.createElement('div'); - entry.className = 'entry'; - - if (filteredOut) { - entry.className += ' hidden'; - entry.setAttribute('data-filter', filteredOut); + var handled = false; + var trimmed_message = message.trim() + var lastmessages = $messages.children('div.entry:last-child'); + if (opts.messageCombining && lastmessages.length && $last_message) + { + if($last_message == trimmed_message) + { + if(lastmessages.children('span.r').length) + { + var current_value = parseInt(lastmessages.children('span.r').text()) + lastmessages.children('span.r').text(current_value+1) + } + else + { + lastmessages.append($('', { 'class': 'r', 'text': 2})); + } + if(parseInt(lastmessages.css("font-size")) < 24) //Completely arbitrary max size + lastmessages.css("font-size","+=2") + opts.messageCount--; + handled = true; + } + } + + if(!handled) + { + //Actually append the message + var entry = document.createElement('div'); + entry.className = 'entry'; + + if (filteredOut) { + entry.className += ' hidden'; + entry.setAttribute('data-filter', filteredOut); + } + + $last_message = trimmed_message; + entry.innerHTML = trimmed_message; + $messages[0].appendChild(entry); + $(entry).find("img.icon").error(iconError); + //Actually do the snap + //Stuff we can do after the message shows can go here, in the interests of responsiveness + if (opts.highlightTerms && opts.highlightTerms.length > 0) { + highlightTerms(entry); + } } - entry.innerHTML = message.trim(); - $messages[0].appendChild(entry); - $(entry).find("img.icon").error(iconError); - //Actually do the snap if (!filteredOut && atBottom) { $('body,html').scrollTop($messages.outerHeight()); } - - //Stuff we can do after the message shows can go here, in the interests of responsiveness - if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms(entry); - } } function internalOutput(message, flag) @@ -568,6 +597,7 @@ $(function() { 'shighlightTerms': getCookie('highlightterms'), 'shighlightColor': getCookie('highlightcolor'), 'smusicVolume': getCookie('musicVolume'), + 'smessagecombining': getCookie('messagecombining'), }; if (savedConfig.sfontSize) { @@ -606,7 +636,15 @@ $(function() { opts.updatedVolume = newVolume; sendVolumeUpdate(); internalOutput('Loaded music volume of: '+savedConfig.smusicVolume+'', 'internal'); - } else { + } + if (savedConfig.smessagecombining) { + if (savedConfig.smessagecombining == 'false') { + opts.messageCombining = false; + } else { + opts.messageCombining = true; + } + } + else { $('#adminMusic').prop('volume', opts.defaultMusicVolume / 100); } @@ -922,6 +960,11 @@ $(function() { } }); + $('#toggleCombine').click(function(e) { + opts.messageCombining = !opts.messageCombining; + setCookie('messagecombining', (opts.messageCombining ? 'true' : 'false'), 365); + }); + $('img.icon').error(iconError); From 39a4d4c24fd86a148aa70b23cd8a1f5fc06df687 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:24:14 -0600 Subject: [PATCH 076/213] Automatic changelog generation for PR #4394 [ci skip] --- html/changelogs/AutoChangeLog-pr-4394.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4394.yml diff --git a/html/changelogs/AutoChangeLog-pr-4394.yml b/html/changelogs/AutoChangeLog-pr-4394.yml new file mode 100644 index 0000000000..68d57a2d11 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4394.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "The shuttle will no longer be autocalled if the round has already ended." From 4aa7e2e30b55a75cd1c2caa2de1536e9ae587626 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:25:44 -0600 Subject: [PATCH 077/213] Automatic changelog generation for PR #4389 [ci skip] --- html/changelogs/AutoChangeLog-pr-4389.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4389.yml diff --git a/html/changelogs/AutoChangeLog-pr-4389.yml b/html/changelogs/AutoChangeLog-pr-4389.yml new file mode 100644 index 0000000000..36f17b95de --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4389.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - tweak: "NEBs now consistently alt click to recolor" From c12fdd08e2e4df939d3cffa3ed8901cff9ad06f7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:26:10 -0600 Subject: [PATCH 078/213] Automatic changelog generation for PR #4377 [ci skip] --- html/changelogs/AutoChangeLog-pr-4377.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4377.yml diff --git a/html/changelogs/AutoChangeLog-pr-4377.yml b/html/changelogs/AutoChangeLog-pr-4377.yml new file mode 100644 index 0000000000..5234e24f49 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4377.yml @@ -0,0 +1,7 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively." + - balance: "As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different." + - bugfix: "Some grinding recipes that didn't work, like dead mice and glowsticks, now do." + - bugfix: "All-In-One grinders now correctly grind up everything, instead of one thing at a time." From 50bd078b433f0d08f963cca697cdc1dcd3ac03c5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 18 Dec 2017 13:45:38 -0500 Subject: [PATCH 079/213] Merge pull request #33636 from duncathan/max_reqs restores reaction max_reqs checking code --- .../atmospherics/gasmixtures/gas_mixture.dm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 64d77a27dc..2ebf5bd7d5 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -399,7 +399,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) return "" /datum/gas_mixture/react(turf/open/dump_location) - . = 0 + . = NO_REACTION reaction_results = new @@ -423,6 +423,22 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) continue reaction_loop //at this point, all minimum requirements for the reaction are satisfied. + /* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost + PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase. + enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible + + var/list/max_reqs = reaction.max_requirements.Copy() + if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \ + || (max_reqs["ENER"] && ener > max_reqs["ENER"])) + continue + max_reqs -= "TEMP" + max_reqs -= "ENER" + for(var/id in max_reqs) + if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id]) + continue reaction_loop + //at this point, all requirements for the reaction are satisfied. we can now react() + */ + . |= reaction.react(src, dump_location) if (. & STOP_REACTIONS) break From 1c142356fff22597bdd6f0e5bca27cf12ff4bd23 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Mon, 18 Dec 2017 10:51:22 -0500 Subject: [PATCH 081/213] Gun sounds (#33615) --- code/game/objects/items/toys.dm | 2 +- code/game/sound.dm | 10 ++++++++- code/modules/projectiles/box_magazine.dm | 4 ++-- code/modules/projectiles/gun.dm | 2 +- code/modules/projectiles/guns/ballistic.dm | 19 +++++++++++++++--- .../projectiles/guns/ballistic/revolver.dm | 4 ++-- .../projectiles/guns/ballistic/shotgun.dm | 3 ++- code/modules/projectiles/guns/energy.dm | 2 +- sound/weapons/gun_chamber_round.ogg | Bin 0 -> 10433 bytes .../{dry_fire_1.ogg => gun_dry_fire_1.ogg} | Bin .../{dry_fire_2.ogg => gun_dry_fire_2.ogg} | Bin .../{dry_fire_3.ogg => gun_dry_fire_3.ogg} | Bin .../{dry_fire_4.ogg => gun_dry_fire_4.ogg} | Bin sound/weapons/gun_magazine_insert_empty_1.ogg | Bin 0 -> 12615 bytes sound/weapons/gun_magazine_insert_empty_2.ogg | Bin 0 -> 11844 bytes sound/weapons/gun_magazine_insert_empty_3.ogg | Bin 0 -> 16135 bytes sound/weapons/gun_magazine_insert_empty_4.ogg | Bin 0 -> 12284 bytes sound/weapons/gun_magazine_insert_full_1.ogg | Bin 0 -> 13463 bytes sound/weapons/gun_magazine_insert_full_2.ogg | Bin 0 -> 10519 bytes sound/weapons/gun_magazine_insert_full_3.ogg | Bin 0 -> 13650 bytes sound/weapons/gun_magazine_insert_full_4.ogg | Bin 0 -> 13462 bytes sound/weapons/gun_magazine_insert_full_5.ogg | Bin 0 -> 14096 bytes sound/weapons/gun_magazine_remove_empty_1.ogg | Bin 0 -> 10077 bytes sound/weapons/gun_magazine_remove_empty_2.ogg | Bin 0 -> 8752 bytes sound/weapons/gun_magazine_remove_empty_3.ogg | Bin 0 -> 8957 bytes sound/weapons/gun_magazine_remove_empty_4.ogg | Bin 0 -> 10486 bytes sound/weapons/gun_magazine_remove_full.ogg | Bin 0 -> 9383 bytes sound/weapons/gun_slide_lock_1.ogg | Bin 0 -> 16722 bytes sound/weapons/gun_slide_lock_2.ogg | Bin 0 -> 14397 bytes sound/weapons/gun_slide_lock_3.ogg | Bin 0 -> 15524 bytes sound/weapons/gun_slide_lock_4.ogg | Bin 0 -> 15266 bytes sound/weapons/gun_slide_lock_5.ogg | Bin 0 -> 14194 bytes 32 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 sound/weapons/gun_chamber_round.ogg rename sound/weapons/{dry_fire_1.ogg => gun_dry_fire_1.ogg} (100%) rename sound/weapons/{dry_fire_2.ogg => gun_dry_fire_2.ogg} (100%) rename sound/weapons/{dry_fire_3.ogg => gun_dry_fire_3.ogg} (100%) rename sound/weapons/{dry_fire_4.ogg => gun_dry_fire_4.ogg} (100%) create mode 100644 sound/weapons/gun_magazine_insert_empty_1.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_2.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_3.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_4.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_1.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_2.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_3.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_4.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_5.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_1.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_2.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_3.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_4.ogg create mode 100644 sound/weapons/gun_magazine_remove_full.ogg create mode 100644 sound/weapons/gun_slide_lock_1.ogg create mode 100644 sound/weapons/gun_slide_lock_2.ogg create mode 100644 sound/weapons/gun_slide_lock_3.ogg create mode 100644 sound/weapons/gun_slide_lock_4.ogg create mode 100644 sound/weapons/gun_slide_lock_5.ogg diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index e82f536dad..259193b177 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -182,7 +182,7 @@ src.add_fingerprint(user) if (src.bullets < 1) user.show_message("*click*", 2) - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return playsound(user, 'sound/weapons/gunshot.ogg', 100, 1) src.bullets-- diff --git a/code/game/sound.dm b/code/game/sound.dm index 085c5eecd5..9cfa197738 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -182,7 +182,15 @@ if("bullet_miss") soundin = pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg') if("gun_dry_fire") - soundin = pick('sound/weapons/dry_fire_1.ogg', 'sound/weapons/dry_fire_2.ogg', 'sound/weapons/dry_fire_3.ogg', 'sound/weapons/dry_fire_4.ogg') + soundin = pick('sound/weapons/gun_dry_fire_1.ogg', 'sound/weapons/gun_dry_fire_2.ogg', 'sound/weapons/gun_dry_fire_3.ogg', 'sound/weapons/gun_dry_fire_4.ogg') + if("gun_insert_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_empty_1.ogg', 'sound/weapons/gun_magazine_insert_empty_2.ogg', 'sound/weapons/gun_magazine_insert_empty_3.ogg', 'sound/weapons/gun_magazine_insert_empty_4.ogg') + if("gun_insert_full_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_full_1.ogg', 'sound/weapons/gun_magazine_insert_full_2.ogg', 'sound/weapons/gun_magazine_insert_full_3.ogg', 'sound/weapons/gun_magazine_insert_full_4.ogg', 'sound/weapons/gun_magazine_insert_full_5.ogg') + if("gun_remove_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_remove_empty_1.ogg', 'sound/weapons/gun_magazine_remove_empty_2.ogg', 'sound/weapons/gun_magazine_remove_empty_3.ogg', 'sound/weapons/gun_magazine_remove_empty_4.ogg') + if("gun_slide_lock") + soundin = pick('sound/weapons/gun_slide_lock_1.ogg', 'sound/weapons/gun_slide_lock_2.ogg', 'sound/weapons/gun_slide_lock_3.ogg', 'sound/weapons/gun_slide_lock_4.ogg', 'sound/weapons/gun_slide_lock_5.ogg') if("law") soundin = pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg') if("honkbot_e") diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 324470ede4..0e6ab6c23f 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -87,7 +87,7 @@ if(num_loaded) if(!silent) to_chat(user, "You load [num_loaded] shell\s into \the [src]!") - playsound(user, 'sound/weapons/bulletinsert.ogg', 60, 1) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) A.update_icon() update_icon() @@ -98,7 +98,7 @@ if(A) user.put_in_hands(A) to_chat(user, "You remove a round from \the [src]!") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) + playsound(A, 'sound/weapons/bulletremove.ogg', 60, 1) update_icon() /obj/item/ammo_box/update_icon() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 42e1352b2d..047243cb45 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -107,7 +107,7 @@ /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index e75905b8c1..f5d846c912 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -30,8 +30,9 @@ var/obj/item/ammo_casing/AC = chambered //Find chambered round if(istype(AC)) //there's a chambered round if(casing_ejector) - AC.forceMove(get_turf(src)) //Eject casing onto ground. + AC.forceMove(drop_location()) //Eject casing onto ground. AC.SpinAnimation(10, 1) //next gen special effects + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null else if(empty_chamber) chambered = null @@ -58,7 +59,13 @@ if(user.transferItemToLoc(AM, src)) magazine = AM to_chat(user, "You load a new magazine into \the [src].") - chamber_round() + if(magazine.ammo_count()) + playsound(src, "gun_insert_full_magazine", 70, 1) + if(!chambered) + chamber_round() + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/gun_chamber_round.ogg', 100, 1), 3) + else + playsound(src, "gun_insert_empty_magazine", 70, 1) A.update_icon() update_icon() return 1 @@ -110,13 +117,19 @@ magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine.update_icon() + if(magazine.ammo_count()) + playsound(src, "sound/weapons/gun_magazine_remove_full.ogg", 70, 1) + else + playsound(src, "gun_remove_empty_magazine", 70, 1) magazine = null to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) AC.forceMove(drop_location()) AC.SpinAnimation(10, 1) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") + playsound(src, "gun_slide_lock", 70, 1) else to_chat(user, "There's no magazine in \the [src].") update_icon() @@ -162,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return (OXYLOSS) #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 4dafbc3f3c..a802ca8bbe 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -42,10 +42,10 @@ CB.forceMove(drop_location()) CB.SpinAnimation(10, 1) CB.update_icon() + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, CB, 'sound/weapons/bulletremove.ogg', 60, 1), 3) num_unloaded++ if (num_unloaded) to_chat(user, "You unload [num_unloaded] shell\s from [src].") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) else to_chat(user, "[src] is empty!") @@ -229,7 +229,7 @@ return user.visible_message("*click*") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") user.apply_damage(300, BRUTE, affecting) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index e6e06cfd68..d3b1815d0b 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -57,7 +57,8 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber chambered.forceMove(drop_location())//Eject casing - chambered.SpinAnimation(5, 1) + chambered.SpinAnimation(10, 1) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, chambered, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null /obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3adadb90eb..f556bd3f58 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return (OXYLOSS) diff --git a/sound/weapons/gun_chamber_round.ogg b/sound/weapons/gun_chamber_round.ogg new file mode 100644 index 0000000000000000000000000000000000000000..951b9d144d87e7a374a6f8f087de94c205a3c049 GIT binary patch literal 10433 zcmb7q1yodDyZ0HoK{|CnYUn`_L6HU-dT5l8lx_@C326`pL_%`t?vjv{ZbV9@q*Ge> z4*34x`>y+~@80#DwP&wA=Q;c7-`>wYGip{=ng9myudCtV-@!+$>T<|Uh=-$#skQ6X zEr@L4UrNguE>=)GYg3(T z?odUjpa5J@Kv3WglvB;#!P?2i!qvjT4R*yEg8g?YOjVF1R4N34$xfNqg|#2iS8yy{GYnS*G-?k%HB zH*-$13jtSd+8YAFZm7Sq;A&Q^s@Q67W~A5}XXTJIA#ddfLK!};V^;hL$I#1lKy)Sf zUmgCn9Z*mgX&gFpGHJXk_QA011Q(FiU$dZqA800^@QzZkjIy_kv45CVZI4HTLU{O& zoTiqFHh8%k>UvmAdbm$|cq;9S z%{npr|7w={@fQDklYG|A1xSLv>~d!8a%Po7vUa)f;9h&U8vtV}iR9^U5mIm!>T-Pm zHU&4?FDT{y17*^Gf^Zdf0FZ<;b~rPB0lk6b9d!}bbrqjmSvMmh)Q>PR{cwA-6&%b@@eKz5zQ|8&=> z{5OlUVnVrkI4k-DdwH(9!nOgi_0l#n86r5C#XQ1b7DrSqe{?MtePoNSnlRu-qmT#~ z`Y)ouphC@~rEuu3K@ybU(gVu@QSqOF+hHBN!8H6IZE%-SgPaX)!-Bk;cf_@|v~@k~ z_20Ws*901Vb)TQ~o}Y{`rV0A*iS=*f03c`rt}%%+4TpCn`>RUh{|)dz$Z@9ZddK+X z9jj6~tI7yZ|DKTAzR)m*oQ9B!CY9kZmHQ~Qh2~wuQDKWwZHsXai>Ydh$2H#i)&By_ zU)an~y8j1qt{}o98oBT&2J63&lg1hO^Iqg_#TZuo81|R(Rw0RbA3m<;Wf1%~c;KB+v5IJ%#tp9C80l46YFnuVR3L;4f0H#Dp0$3mlIRIOZM)ts$7?B9k>}1UWQ9P!A z9ym^lKN$?os5t;zVGQV#T1xgGlHvpaXbS}VNOKCA%K>B@!1rjz!B`ENJRAAk)Ab;g zJ3pT%ET5}4f8(@?tGAvvKfeg%vYyR-*0go@wS0>qCx5M;Yr3hdr@Umnsie|<_DFmb z1%kqRR!iIXz56`pbiF`$e*Sts&sir|Z&T^n!}?tcdF^p`ZI3|1ID6x-5h zO!u{Q4?&su4O)z=X_26^@;bB$CEuMw3V@Qkjtnu4HNTN#Ua_ zsihT*Oo^nI5(4@}Vd(+!(lB0kG9&>=Kv?ruQQIPTJ4vJw=_rs;gpM~=F6z*O<1o7_ zBRZ2&>IkKD)C9=NjRd&{&C){J6rsjUI}%VtVq7WyF$gYr9Lj(YU8#czEz6>OYzv>5 zFf9USfUM$BrpmnI6Q+e#pz!4cR5&R7N=BY`xZ-MBW{fCj9ykLA>j1T43P6eB!Q!+` zxnWhHRz)Cz6Wu}mxCmCIBXiA)2iEb`w4ka(#|$)39bpT~K-vmtPnZ&c!jad)!^-{< z&Q%r{W1w6%{?(vRxQg1$rfh=RtO!2w&8+BC&b3w`L3ComtVsCi+VU%P(GxbH<@8s= z$scp(T?q#raV^~7AK`koHoTqJTIrb;i+AamsTF}*6;@U0*cJ+}=$Vy(RTI%YaDPfr z#~~or#|LB~09gQMM=}bBxhpvn1#M68M{#vQQ6mN&j3}hRdUEUtGCai}d1b(uL3mX> z$^f(itVanL!TQT?2&KoEcC`lm#l3X6)U#-f9ynfv6atJ8G8Dd&C5wPBC!_k{E38>4 z_zEKmC5?y98bRWvqfkh&;!L~7J&sC92Lx2;#+5=qC$y8y3{MP~IhI_sJI#%Z9*;Rr z6(NsC=@|58q2dv?Hv&`r8MZlkR48B?0#;^FC2r<^VFWD}pp$3P`|XMuBS;GniW7 z3PmOjLxWmkTrF`7a(6js@wtS|*??$VFvT-bu1KT}3d|m^A~^y$PI}e^S7&l;3^JU` zY(P=*Dr;e2e%RuIwi*;vp<bTP&Ufrl0W23?a~B2mCUlr3}C2~ao%Mq}wzN$&W zK?3*{H1?`Q`F|Ke#&T6KSZ7^V4MJC?!}aL@r(*-11n&7{1b}m+6L9e1KaI${+EWNb zu~P!H=+Vjk(Fg=g7$M5R3`!}u@|0~^hn^@08+yW^unhbfRyC36%E1OgqNoboJi@D% zzqt-Eqp5BCK_@BMmVpr^eVFjowCK~(M^AP5#1sE5DZF&kLQybMq)h-2i-!xeV>9R| z+=I~*@?4!N$S?r`EI^7g5d!$(lYl1{ol@?KN}J5uyx7KH{w*AC?Uv@hzE z$maHl4y!0&2o@Ne5pTeqF4L{p1Mi%G;eggdffmVtJ}eAubrUEiKte{I1^9i&km+)| zK^Cpl%_+diNHL(8LkvigvD}emF@--;&cz80T?I^>Uo+nV1cmO7@bRVf0yJ*Ulds9% zkOe@gan&U;NK|Wogor%&fy42OGEVGo1&#&00Dwn#{epv^E#DJ+@K91(R{jw}Sylb- z@evOIkAN|hP!^U%(MXag(rB`GH)6Yf6tFCynks|=f^8P zu|&zitTdNG{5(8xfv1iZRyOw^A{-nqr!FlnB`$d`1uoeyZ(I^xVm9LOPhtC;2-Xt> z16?G9Hw;o20KQLm1+h2E&Nc7|N@;A5UQJIUOODhgmD+o{hshbaA?$*Z+S-9_@f4H^ zv9j6o7l;u;UfdvsZFZY=5{Wsn;vl85B{`V)`2FX*(}gvc96X-Vd#5`ue%XAhqkU*x z%9i)e$zZCIm!xr^wLC#Y|FU|zYjVl;ILuGJS>;vCDSn3N#ae!uxUspfuWkqGGIk>8 zvi?%^P0&ioefNX&--mHT$03twvk}RM&uRXwPP-WmIe%+-Ywfzv_Up1S$}X80p90Bw zyK=&*r+vSNdZU<5O*r5ogFu{`f(WId|6L*0+X~)2c11t#Y-~3%^$;Mw2Wa|PrM+YI-VQN8to zIPk~o0OP0XfY1*t60E^k)o$8bet2%>=~S?f3dvorcj~EEeLvY?*O#WEZf3hMiH^DN zsH`Xgc0baxI9>x(vHKz7v) zpOz5fK%GhVjDG8tK{4-5=X1DhN1DW7u_lCxcUHk>WlnWJgWPL`$m>U=wulHNi}2%p zZw-uoI$vqe{32OJ>D+HyMpHj8Et05$>h`NP?OXVKXkQ(|cLA@ZgHG6+WWzaJdmr9< zDZ>2Bu^vmU4vu!-mM>k^T5}UGUeHUYjSVn`eea>Jsv>rS*ki^GOH>?Jn=(c1YAhXm zIHoL_^kMq=#axx~aI2;wcxGcT&G-Ud`e1V8v&* z^k{wMz54?R{u23h_tH6%72UGuw@OSu{W*xQVzPT9t$VNzo$cp^$rboIJHyP9j7bpm zJ%qy%($BV!>Pp*bo6qL0;0qUG=M6@`#JzuC_*&1_!PPb)=dZ&`%S>fkD%X7L7mS?$ z^y$7&aN^_pc<+ywxyhGo#rYwqwpY6z5G)6>T zUht*9eC7G6nD6Y<`pda>531DEy1w=NO5SYTOg)aZrUkkJ|2ntU*7=Y+PJLpfq*xU@ zY+h}quHxbO-Ia`Idy|}VLrH@ zqy?Da4OXJC!Pe*QlWot0+sY2iQc8>Hb{|9&uDi<6k~w2d4&`eSbjaqv$9o%Ob!)Dl z|BlG^eZv=~iF>*e}15?ycN%uAFMgl*{*l}+2cWHV4tDDfLxOgg2k16C36t&~9IXiNFMM zZNxDw@hX{hG@1k&xfIPj>zH+qzifQlN91drF27xhXl-Ee3{~1L*q$U%%8Q-OSwiCy zhhZGpmjHPXK5S=A($)mlMJ)L8qC@t8Yz!CvUtNwahqMFWL8nSKS%cgilwvmP0EryBD6# zEnQSK9C{38eVSi$`c+>o;>FRl%r!dlnUdcgm&;hVv4LY=zu*ft`NK=s+uSUrPuySs^1S)03VUj*=d2Mh_6iLUjq`-GcOKt-t36f&%&#Yv z6!3LTj%vog|6RW!e%{&A(^pU2?lP1W;{CjE)%ra=0nR6?J(EsdMX5cU5=f=g&1#GndBmYHF5y;%&L?KTUIckCdHl#-v~k zwIuW361FOdX_&d_{xt7x zgnP-BWq2J&e*Mp%F#H(#`PNRp>vi=DMpT;zk>x=6jqlv2ORKbQk698qX30N(=x4>i zVP)ZL+X2Kff)^Pz&O~Lvhgi*;RBqsq%d@wicfvrGUai0W&o!}ea1|}xF}=l zcFcn(d^U=o8;|CH`iwbT_;|e9b?9iUT?!AS8OVsV>hEtH^cpH`l$ap+$vJdi#FF$u z(6-F*HbO1N2j#HSFLcy6@$urx>HNwfHVyat@q3@ks+;dGWZxW#vDc_hlYx@V-leZlLMficK$3Ta7N z`!@L~`mIZpc?3F2cAwA*KYYg{)XVIvH1`6c&#PS&PaCCgsC^>bnx{!vckqt;(5AWI zF&yARk-U~Z(^J?sBM!_nIl+-*(|p$}ziTvBZlWlW{Don1B_faknA4rfC4DMG@~nq7 zOa%aBmT_?;gF-Ob$+$3CUm8$Jr{M22zJ?Xj0N)RI9{32@9S;~)8S2+?c&`r!QCaRv zk`juH#mjF{k=#wh4zw!#LqLrxn=i>_>csx6Jzu`qqo*FN=z2LB`|ReTZ0vN;dLan` zYjgy0on~Vc8>wRD62>U0ipM7#&CK}sE4-#<-R#9?IU(%h_IzPuO7C4HdL_KsqoeVX zKVG~Q@bZqu@}R3&lR6qgo9bUgnpGb2-S0^BYMtS%48K!qzb3u^o}F{6lGLT5GNFf* z;9@M_g>OeF>Sj;wuLz&QdumIgD-x>)ySLRAUlq}gdKOFkN&3F?rz9swp8mx|+6$E; zsuGqh1GglTWZTy`ftTxXjs&IPa@c0cb@<0SICZ4sC@F5 zs^_QMq=!{i&s>5t^VE`EJqv!JjN2bOZx5{NtZnzCzbIa#@=J7TnYx(%Q`Qxytd3<< z#l=va=SNjK@XXtoXL?@S_bxpTYgm*W)u4}`^$n}{N5_YvJ1E#jZ7}^8DF%T^8NAvi zIaX6%4oLng+)j%2eO|_sk+a(8i@*p@8`oVfHa6VvmF#=cKRrB>T34Rfz3CA1+aJh1 zIUCUM%_$zkGS5@MEy!bDET8}S+?PElCazY0@$-?Lz%g_XkMw5Hv}{T%e>c&Pp9T<56G4V@X*kmawncF-&OJwwo!P_%lhSd1WU(ZpyJ<`$3aIAb-+s8m$1eKk=boB8f-qBO1>YW?>yO`EQ~Q zGxlqGG6JR#A2_^iA-)y-E8SH$tl#oOH3ZXOXA#55VwyEI-O$31Rg&Hj130gyNfZGj zadLMc5VG!3zc3b7GcF<~z~uLz%a!N1jJ9-CJ(Jd-$4ji8nS9_dR*9r%x}&^TGZg_r>bjZ;* zZD3k(og!0Zf!R7F=HE_M%|#CXpXRUAvPNNzU4(;q}TctBB;S z+Q$Zuf#gryeSs;SLq|&+t%%DcblWIqjni)qOA5%3tx>Yk66H?O(hxnjgOlUg-A9vm z_*p8dbIOyO@H*CGq}+0w+EN=5y>TKs5foc4H)JB?G-Nv8He$sXy_dKTbx^GsR37#+ z^bFkyAQ60Ux2WxTUebj#zJ+I_kh?895Z3ftjIaNuUvsGwui&$|hrcWBEtizAX3Pu| zu=#G@#$1C) zLz;CYiQK~=r}y!gQAMrI2~U?#rl2jEH$$*L{+{j*Bx{rkk1|Y<$^Eq-xOdwp0T(>M zS^&2N%Ux{Ei5Pc=lyF?%&PAPmd^v6uCtBydEOC+CPjWhY<{rh*2@|`Ft;_sW z{Nt%vU%j|x(L3c#$z0^H>@KO?IhMR`f03O}gAuiFc+=~e&F|yq&G(*L^tbAqbm-bG5gCMy5w-?mCjQe5g3p&?~V{UK6EeaaS zST+KMR4wd^$_ZacUo;1Nqvp{akE1Ls3F=Q%R@Odp7@0&Z7&ozJzQ-QjamAK@U7s;+ zot2al3Bmq=TaK%RYjXc#XdWXr&ez(5k>?&KKZBBBJ|#KtZytKQpKrD~dTV7AArZsb zBU{lN0?ogXzL{OOBFNcIwBa zy{a#WbHQNrV08Dmz@RFIbsf!FHuZ{Y$lwJJtj-1>pP8$o| zz(GYx4YfN&5jM8p^#`{sH$7f|{!NJa-O96*G_%ZTbc5p*y9ML=WeL`=r~mb`1QQ&_ zO-C`2{5e_p+FYBPoERVCtqQrh#BiZp9qamH=l<@^_Yh;6XL(#+0V7AE}X6Yv)%6NAj9=7xvfR! z_bP3+n0HQG(@gmIOxDomnTf3dR+AY12<<0-4{7{@)Q^z?%^op0+g09|nP=+A?q{V};&s6=s&<@=M-r|`&2{7gJ7MzMX1 zBYWo^8*6XY^CY>6Agt4Txx}}x7Aq3(?PL27jf*8`Z`(9nIM6;*7FalK?II+=;AHcBsa`xkNb!6(4*z(gH%Zc`5IaebT&SI}-uL{QR1c0!5sn2% ze`X+iX3jg+BjN3@3StPSvqM>-?yp#kcUxPM;=f0!dO}VY+_o`sUd2+ zZruU6$=2sBJrAw8q`1JltrzV4a6CZ54@XNIdvO#3gCih?mp6&Rst*|-(yt>gDSl4w zhvg-Zbv$tvdAXk-V}u7WfxHyL86^+S*O)t~B0g07g_9Qdp1(6@DYHLaYLn9cIS$p)N3_r4fgS(o{2seFy{(%(P&t86#g-%O6u>tz<+!qz-dyqXxC@U-U$AmBVX8X zeSs6RP@%0jeQ+>}F{$q%q^i&C)tnXud8MQMyXQW}&59nTYw3hEOwtV; zs9QS3W6guZW!5UHeAX%)uP0AGz8Ul6U8@zjJLKtbM4!ZHV8%R{Wd&|h5lQq-C-^46U4>QOosa+zu+ghf zj~hVU7Yrzj68P?ttG2LDCls0~y6!`b4cUBBd;3HO+4JT{+~{Z8u?1^G^p9H>1itl* zzmqv9A=A@GTQanS08z{0It}OiuJ^#gAh8OdD?k~p}!6Dt_v>e7J zK>xj3W$N=S4*qO?8U9=LY9Gv3&^>4P^&cI4F<#yNxgTv!*s$>iFOH#xm~|W4PDx|2 z#4F!7Yu)dA|MS_N;$RNfEg7a_Ok-bvbKUW_mma>uKd`WIfSsz*1K@&k@nfe*-{p_B z4+`F|(;-fPAEvrwhumGMtGCdS$@crD$l-vz?ce>z=JM0TNO$o%cjbw%0nGD1G{WzymVf!6-gX-}|{I=2O)EhN;lj-*h z*~Dv9gKn`dLloACjVF)hE);IP5qh0U;hJ(f@M`qdn|qJHabK$5uGtdh?j5WF{4T$M zIekG%NqXtSr|{s_H`JN9-~%@R6N-sq0IuJvOIC=IYB-2-ifD~B>q1N@H!Sae$i7kO zqxqELaj8OAx`{0_C*gdTeD%v_SN@F5osGH{-tFk)lbQAT$&5W-KbD3Lq7UX_R^vId zie+g)*T!SIvRT0*wQ0%Ed?&EoL#&E zb=%M_IU+uXdWhsP5n18n5_I6sVWwe$4rIS8K0EewQZ}9I=VUaV-AkSTi^vs19ktD{ zvSFS*AW(%xa+EPWKbL1@o$8{RfVL^>g2mU?HH@2NsZdvTL=#ARLdv(>XmD_0!u<1= zS)@5KPV7_@`ys@KgBp0dnbS`5Z7TY`vguS|b{`ckWXDrMqsD(hip9@{R<J zH_+grJAE4a+}}#ZyAZc~Ka2KZ+%cj$_w?|_lx!WGXUEfI-hoO9?C551{yF8vh3>l(0!Hj(_1qez^X~Vg2`S^_z-%UbTHks* zk?Gh!N7%){BA4po7_WmK&d*gM`zV8I;J{!L|s{0)vz(cATuaeYSN~cSS z1TOh-p2pO%XxwN}Pr$E=x}PJJd&VmlkldcV6AC8MnBd~s^ZUfs9+y6{U8F__bTwFh TnBV(NPWQM>E*%LIuu1+8zn1ii literal 0 HcmV?d00001 diff --git a/sound/weapons/dry_fire_1.ogg b/sound/weapons/gun_dry_fire_1.ogg similarity index 100% rename from sound/weapons/dry_fire_1.ogg rename to sound/weapons/gun_dry_fire_1.ogg diff --git a/sound/weapons/dry_fire_2.ogg b/sound/weapons/gun_dry_fire_2.ogg similarity index 100% rename from sound/weapons/dry_fire_2.ogg rename to sound/weapons/gun_dry_fire_2.ogg diff --git a/sound/weapons/dry_fire_3.ogg b/sound/weapons/gun_dry_fire_3.ogg similarity index 100% rename from sound/weapons/dry_fire_3.ogg rename to sound/weapons/gun_dry_fire_3.ogg diff --git a/sound/weapons/dry_fire_4.ogg b/sound/weapons/gun_dry_fire_4.ogg similarity index 100% rename from sound/weapons/dry_fire_4.ogg rename to sound/weapons/gun_dry_fire_4.ogg diff --git a/sound/weapons/gun_magazine_insert_empty_1.ogg b/sound/weapons/gun_magazine_insert_empty_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ef34a8e358d2ccf5d727964df9016793eb6c76d1 GIT binary patch literal 12615 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 ejqq)UGPNBGVeMf8c%FyZJb>#+$u000*N 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_empty_3.ogg b/sound/weapons/gun_magazine_insert_empty_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dda772be5d47d8b5b5c4bf2bbeb152795a7b0696 GIT binary patch literal 16135 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 KAoCM8@P7d0rpR&t literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_1.ogg b/sound/weapons/gun_magazine_insert_full_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dbbede3f710d440ef334213e4260cc433d3f41f5 GIT binary patch literal 13463 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 J<*XP*`#&{tjGq7i literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_3.ogg b/sound/weapons/gun_magazine_insert_full_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..95b9b891eff98fbcdae7afea7b6bd384dbc64b60 GIT binary patch literal 13650 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 Ld`CK30RMjh6Tq|g literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_4.ogg b/sound/weapons/gun_magazine_insert_full_4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d63f0310e562f01d827e2fc0e1d20ec2bf524d4f GIT binary patch literal 13462 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_5.ogg b/sound/weapons/gun_magazine_insert_full_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cfd6198760225ad387158c3f8ff4b0ca3452f3ce GIT binary patch literal 14096 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_1.ogg b/sound/weapons/gun_magazine_remove_empty_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a3ae4fa2ebf8e2b9b5344faa1a74117bb62c0613 GIT binary patch literal 10077 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 Rv2~gFHqXE13SjLB{|~qmHx~c^ literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_2.ogg b/sound/weapons/gun_magazine_remove_empty_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..da73e5217329f1cfe4fdcd5f8a68660b21c2ad1b GIT binary patch literal 8752 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_3.ogg b/sound/weapons/gun_magazine_remove_empty_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..18689dc26b6d51605e0bcca3cfd71d1bd05d4e28 GIT binary patch literal 8957 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%0D0`Y(PQR$Ly1HY!*F1ijRZ}|5cEXSN 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_slide_lock_3.ogg b/sound/weapons/gun_slide_lock_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b30be8ab84dfc56796cab3cc89060e0a9a89f818 GIT binary patch literal 15524 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%0AU@+j$` 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_slide_lock_5.ogg b/sound/weapons/gun_slide_lock_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5a4c1fa158c2587a9e7d917df309ea0f91ea3a71 GIT binary patch literal 14194 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 literal 0 HcmV?d00001 From da25df9329814e6372440e4559fa987cded4fdd6 Mon Sep 17 00:00:00 2001 From: nicbn Date: Mon, 18 Dec 2017 13:06:07 -0200 Subject: [PATCH 083/213] Makes the chemical smoke machine use stock parts for things --- .../chemistry/machinery/smoke_machine.dm | 41 +++++++++++----- tgui/src/interfaces/smoke_machine.ract | 48 +++++++++---------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index dc92dd3b52..86205caba5 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -1,3 +1,5 @@ +#define REAGENTS_BASE_VOLUME 100 // actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin + /obj/machinery/smoke_machine name = "smoke machine" desc = "A machine with a centrifuge installed into it. It produces smoke with any reagents you put into the machine." @@ -11,14 +13,13 @@ var/cooldown = 0 var/screen = "home" var/useramount = 30 // Last used amount - var/volume = 300 - var/setting = 3 - var/list/possible_settings = list(3,6,9) + var/setting = 1 // displayed range is 3 * setting + var/max_range = 3 // displayed max range is 3 * max range -/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting = 3, efficiency = 10, loc) - amount = setting +/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc) + amount = setting * 3 carry.copy_to(chemholder, 20) - carry.remove_any(setting * 16 / efficiency) + carry.remove_any(amount * 16 / efficiency) location = loc /datum/effect_system/smoke_spread/chem/smoke_machine @@ -28,10 +29,11 @@ opaque = FALSE alpha = 100 - /obj/machinery/smoke_machine/Initialize() . = ..() - create_reagents(volume) + create_reagents(REAGENTS_BASE_VOLUME) + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating /obj/machinery/smoke_machine/update_icon() if((!is_operational()) || (!on) || (reagents.total_volume == 0)) @@ -41,13 +43,20 @@ . = ..() /obj/machinery/smoke_machine/RefreshParts() - efficiency = 6 + var/new_volume = REAGENTS_BASE_VOLUME for(var/obj/item/stock_parts/matter_bin/B in component_parts) - efficiency += B.rating + new_volume += REAGENTS_BASE_VOLUME * B.rating + reagents.maximum_volume = new_volume + if(new_volume < reagents.total_volume) + reagents.reaction(loc, TOUCH) // if someone manages to downgrade it without deconstructing + reagents.clear_reagents() + efficiency = 9 for(var/obj/item/stock_parts/capacitor/C in component_parts) efficiency += C.rating + max_range = 1 for(var/obj/item/stock_parts/manipulator/M in component_parts) - efficiency += M.rating + max_range += M.rating + max_range = max(3, max_range) /obj/machinery/smoke_machine/process() ..() @@ -78,6 +87,11 @@ return return ..() +/obj/machinery/smoke_machine/deconstruct() + reagents.reaction(loc, TOUCH) + reagents.clear_reagents() + return ..() + /obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) @@ -99,6 +113,7 @@ data["active"] = on data["setting"] = setting data["screen"] = screen + data["maxSetting"] = max_range return data /obj/machinery/smoke_machine/ui_act(action, params) @@ -110,7 +125,7 @@ . = TRUE if("setting") var/amount = text2num(params["amount"]) - if (locate(amount) in possible_settings) + if(amount in 1 to max_range) setting = amount . = TRUE if("power") @@ -122,3 +137,5 @@ if("goScreen") screen = params["screen"] . = TRUE + +#undef REAGENTS_BASE_VOLUME diff --git a/tgui/src/interfaces/smoke_machine.ract b/tgui/src/interfaces/smoke_machine.ract index 9f21240430..983e04bce2 100644 --- a/tgui/src/interfaces/smoke_machine.ract +++ b/tgui/src/interfaces/smoke_machine.ract @@ -1,31 +1,31 @@ {{#if data.screen == "home"}} - - {{data.active ? "On" : "Off"}} - - - -
    - 3 - 6 - 9 - 12 - 15 -
    -
    - - {{#if data.isTankLoaded}} - {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units -
    + + {{data.active ? "On" : "Off"}} + + + +
    + 3 + 6 + 9 + 12 + 15 +
    +
    + + {{#if data.isTankLoaded}} + {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units +

    - {{#each adata.TankContents}} - {{Math.fixed(volume, 2)}} units of {{name}}
    - {{/each}} + {{#each adata.TankContents}} + {{Math.fixed(volume, 2)}} units of {{name}}
    + {{/each}} {{else}} - Tank Empty + Tank Empty {{/if}} Date: Mon, 18 Dec 2017 15:22:55 -0600 Subject: [PATCH 084/213] Update st_commands.dm --- code/modules/server_tools/st_commands.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm index 9ec87a595c..1e071550e0 100644 --- a/code/modules/server_tools/st_commands.dm +++ b/code/modules/server_tools/st_commands.dm @@ -51,7 +51,7 @@ /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and From a85f5eea6b0ce6c401f0f4c4c0a223b7c56577ab Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:23:55 -0600 Subject: [PATCH 085/213] Update server_tools.dm --- code/__DEFINES/server_tools.dm | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index 9547c381c1..a444caf02a 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,28 +1,29 @@ -// /tg/station 13 server tools API v3.1.0.2 +// /tg/station 13 server tools API +#define SERVICE_API_VERSION_STRING "3.2.0.1" //CONFIGURATION //use this define if you want to do configuration outside of this file #ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION //Comment this out once you've filled in the below -//#error /tg/station server tools interface unconfigured +#error /tg/station server tools interface unconfigured //Required interfaces (fill in with your codebase equivalent): //create a global variable named `Name` and set it to `Value` //These globals must not be modifiable from anywhere outside of the server tools -#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) //Read the value in the global variable `Name` -#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_READ_GLOBAL(Name) //Set the value in the global variable `Name` to `Value` -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) //display an announcement `message` from the server to all players -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) //Write a string `message` to a server log -#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_LOG(message) //Notify current in-game administrators of a string `event` -#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_NOTIFY_ADMINS(event) //The current amount of connected clients -#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len +#define SERVER_TOOLS_CLIENT_COUNT #endif //Required hooks: @@ -64,16 +65,15 @@ //IMPLEMENTATION -#define SERVICE_API_VERSION_STRING "3.1.0.2" - #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 #define REBOOT_MODE_SHUTDOWN 2 #define SERVICE_WORLD_PARAM "server_service" #define SERVICE_VERSION_PARAM "server_service_version" +#define SERVICE_INSTANCE_PARAM "server_instance" #define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll" +#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" #define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" #define SERVICE_CMD_HARD_REBOOT "hard_reboot" @@ -98,11 +98,12 @@ #define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" #define SERVICE_REQUEST_API_VERSION "api_ver" +#define SERVICE_RETURN_SUCCESS "SUCCESS" + /* The MIT License -Copyright (c) 2011 Dominic Tarr - +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to From 15adc5d0b044352f3b8a26aa31b391c4947f3dd6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:24:23 -0600 Subject: [PATCH 086/213] Update st_interface.dm --- code/modules/server_tools/st_interface.dm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm index 39bebbbb3d..b0b1b0a43c 100644 --- a/code/modules/server_tools/st_interface.dm +++ b/code/modules/server_tools/st_interface.dm @@ -30,7 +30,10 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) return if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") - call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(command) //trust no retval + var/instance = params[SERVICE_INSTANCE_PARAM] + if(!instance) + instance = "TG Station Server" //maybe just upgraded + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance, command) //trust no retval return TRUE /world/proc/ChatBroadcast(message) @@ -72,7 +75,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) switch(command) if(SERVICE_CMD_API_COMPATIBLE) SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_HARD_REBOOT) if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD) SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD) @@ -88,7 +91,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) if(!istext(msg) || !msg) return "No message set!" SERVER_TOOLS_WORLD_ANNOUNCE(msg) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_PLAYER_COUNT) return "[SERVER_TOOLS_CLIENT_COUNT]" if(SERVICE_CMD_LIST_CUSTOM) @@ -96,13 +99,13 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) else var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) if(custom_command_result) - return istext(custom_command_result) ? custom_command_result : "SUCCESS" + return istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS return "Unknown command: [command]" /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and From 573638d9a6af301bf231215df0e8dd989d798292 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 15:25:35 -0600 Subject: [PATCH 087/213] Automatic changelog generation for PR #4416 [ci skip] --- html/changelogs/AutoChangeLog-pr-4416.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4416.yml diff --git a/html/changelogs/AutoChangeLog-pr-4416.yml b/html/changelogs/AutoChangeLog-pr-4416.yml new file mode 100644 index 0000000000..543fe52edd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4416.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "The wizard event \"race swap\" should now stick to \"safer\" species." From 3454d658595ca48d4024cc43a80f080826f84c7a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 15:25:49 -0600 Subject: [PATCH 088/213] Automatic changelog generation for PR #4417 [ci skip] --- html/changelogs/AutoChangeLog-pr-4417.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4417.yml diff --git a/html/changelogs/AutoChangeLog-pr-4417.yml b/html/changelogs/AutoChangeLog-pr-4417.yml new file mode 100644 index 0000000000..46b7019353 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4417.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "Clockcult power alerts will no longer show outside of the clockcult gamemode (they could be triggered by scarabs.)" From 390c24b3fd05fba47bbb14631644e2131aa3238e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:42:17 -0600 Subject: [PATCH 089/213] Create server_tools.config.dm --- code/__DEFINES/server_tools.config.dm | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 code/__DEFINES/server_tools.config.dm diff --git a/code/__DEFINES/server_tools.config.dm b/code/__DEFINES/server_tools.config.dm new file mode 100644 index 0000000000..7d3c5b8eba --- /dev/null +++ b/code/__DEFINES/server_tools.config.dm @@ -0,0 +1,8 @@ +#define SERVER_TOOLS_EXTERNAL_CONFIGURATION +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len From 75d0b6c9423d58ad4248029e9b1d3c15c8b4d2f8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:43:05 -0600 Subject: [PATCH 090/213] Update tgstation.dme --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 4d438607f5..737f7e8274 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -73,6 +73,7 @@ #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\server_tools.config.dm" #include "code\__DEFINES\server_tools.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" From a9ed49d7753c4672a951f414592fef364b784d19 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:44:13 -0600 Subject: [PATCH 091/213] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index e2b9bbfbbc..3aefb8c03e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,9 @@ - -<<<<<<< HEAD ##Citadel Station 13
    Based and maintained from /tg/station.
    -======= + [![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) [![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) [![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) ->>>>>>> c47dde9... Merge pull request #33172 from praisenarsie/patch-12 [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) From 2f7c4ecc6fdb69352b43e849e3852dd3bc017055 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:44:45 -0600 Subject: [PATCH 092/213] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index e2b9bbfbbc..b286239314 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -<<<<<<< HEAD ##Citadel Station 13
    Based and maintained from /tg/station.
    -======= + [![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) [![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) [![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) ->>>>>>> c47dde9... Merge pull request #33172 from praisenarsie/patch-12 [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) From ec42803331e16b785a3c8db9e537d7e84842861d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 17:28:28 -0600 Subject: [PATCH 093/213] Automatic changelog generation for PR #4437 [ci skip] --- html/changelogs/AutoChangeLog-pr-4437.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4437.yml diff --git a/html/changelogs/AutoChangeLog-pr-4437.yml b/html/changelogs/AutoChangeLog-pr-4437.yml new file mode 100644 index 0000000000..9b11b0912e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4437.yml @@ -0,0 +1,4 @@ +author: "nicbn" +delete-after: True +changes: + - bugfix: "Now the chem smoke machine uses stock parts for volume and range." From 76e6cb4e48d84f3ef71b732e0ca6d6c5c58713c2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 17:31:07 -0600 Subject: [PATCH 094/213] Update server_tools.dm --- code/__DEFINES/server_tools.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index a444caf02a..c0fc133ada 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -5,7 +5,7 @@ //use this define if you want to do configuration outside of this file #ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION //Comment this out once you've filled in the below -#error /tg/station server tools interface unconfigured +//#error /tg/station server tools interface unconfigured //Required interfaces (fill in with your codebase equivalent): From 6b4099805f3905a18d30cd8b2c47ececfb9ae15c Mon Sep 17 00:00:00 2001 From: XDTM Date: Tue, 19 Dec 2017 03:30:20 +0100 Subject: [PATCH 095/213] [Ready] Adds abductor Mind Interface Devices, and a gland HUD (#33209) * Adds abductor Mind Interface Devices, and a gland HUD * . --- code/__DEFINES/atom_hud.dm | 32 +++---- code/datums/hud.dm | 1 + code/game/data_huds.dm | 3 + .../miniantags/abduction/abduction_gear.dm | 80 ++++++++++++++++++ .../gamemodes/miniantags/abduction/gland.dm | 74 ++++++++++++++-- .../miniantags/abduction/machinery/console.dm | 3 + .../browserassets/css/browserOutput.css | 1 + .../mob/living/carbon/carbon_defines.dm | 1 + .../mob/living/carbon/human/human_defines.dm | 2 +- .../carbon/human/species_types/abductors.dm | 10 +++ icons/mob/hud.dmi | Bin 13068 -> 13298 bytes icons/obj/abductor.dmi | Bin 56757 -> 58583 bytes interface/stylesheet.dm | 1 + 13 files changed, 187 insertions(+), 21 deletions(-) diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 2decc918f2..dcdf5aa268 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -17,8 +17,9 @@ #define DIAG_TRACK_HUD "13"// Mech tracking beacon #define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay #define DIAG_PATH_HUD "15"//Bot path indicators +#define GLAND_HUD "16"//Gland indicators for abductors //for antag huds. these are used at the /mob level -#define ANTAG_HUD "16" +#define ANTAG_HUD "17" //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior @@ -32,21 +33,22 @@ #define DATA_HUD_MEDICAL_ADVANCED 4 #define DATA_HUD_DIAGNOSTIC_BASIC 5 #define DATA_HUD_DIAGNOSTIC_ADVANCED 6 +#define DATA_HUD_ABDUCTOR 7 //antag HUD defines -#define ANTAG_HUD_CULT 7 -#define ANTAG_HUD_REV 8 -#define ANTAG_HUD_OPS 9 -#define ANTAG_HUD_WIZ 10 -#define ANTAG_HUD_SHADOW 11 -#define ANTAG_HUD_TRAITOR 12 -#define ANTAG_HUD_NINJA 13 -#define ANTAG_HUD_CHANGELING 14 -#define ANTAG_HUD_ABDUCTOR 15 -#define ANTAG_HUD_DEVIL 16 -#define ANTAG_HUD_SINTOUCHED 17 -#define ANTAG_HUD_SOULLESS 18 -#define ANTAG_HUD_CLOCKWORK 19 -#define ANTAG_HUD_BROTHER 20 +#define ANTAG_HUD_CULT 8 +#define ANTAG_HUD_REV 9 +#define ANTAG_HUD_OPS 10 +#define ANTAG_HUD_WIZ 11 +#define ANTAG_HUD_SHADOW 12 +#define ANTAG_HUD_TRAITOR 13 +#define ANTAG_HUD_NINJA 14 +#define ANTAG_HUD_CHANGELING 15 +#define ANTAG_HUD_ABDUCTOR 16 +#define ANTAG_HUD_DEVIL 17 +#define ANTAG_HUD_SINTOUCHED 18 +#define ANTAG_HUD_SOULLESS 19 +#define ANTAG_HUD_CLOCKWORK 20 +#define ANTAG_HUD_BROTHER 21 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 837e7a6a95..fc6c09be14 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -10,6 +10,7 @@ GLOBAL_LIST_INIT(huds, list( DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), + DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), ANTAG_HUD_CULT = new/datum/atom_hud/antag(), ANTAG_HUD_REV = new/datum/atom_hud/antag(), ANTAG_HUD_OPS = new/datum/atom_hud/antag(), diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 1afd2953a0..74ac93c023 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -60,6 +60,9 @@ /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) +/datum/atom_hud/abductor + hud_icons = list(GLAND_HUD) + /* MED/SEC/DIAG HUD HOOKS */ /* diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 9128847e16..3e7e5f01ef 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -2,6 +2,8 @@ #define VEST_COMBAT 2 #define GIZMO_SCAN 1 #define GIZMO_MARK 2 +#define MIND_DEVICE_MESSAGE 1 +#define MIND_DEVICE_CONTROL 2 //AGENT VEST /obj/item/clothing/suit/armor/abductor/vest @@ -278,6 +280,84 @@ if(!istype(I, /obj/item/device/radio/headset)) r.broadcasting = 0 //goddamned headset hacks +/obj/item/device/abductor/mind_device + name = "mental interface device" + desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \ + or to send a command to a test subject with a charged gland." + icon_state = "mind_device_message" + item_state = "silencer" + lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' + righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' + var/mode = MIND_DEVICE_MESSAGE + +/obj/item/device/abductor/mind_device/attack_self(mob/user) + if(!ScientistCheck(user)) + return + + if(mode == MIND_DEVICE_MESSAGE) + mode = MIND_DEVICE_CONTROL + icon_state = "mind_device_control" + else + mode = MIND_DEVICE_MESSAGE + icon_state = "mind_device_message" + to_chat(user, "You switch the device to [mode==MIND_DEVICE_MESSAGE? "TRANSMISSION": "COMMAND"] MODE") + +/obj/item/device/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params) + if(!ScientistCheck(user)) + return + + switch(mode) + if(MIND_DEVICE_CONTROL) + mind_control(target, user) + if(MIND_DEVICE_MESSAGE) + mind_message(target, user) + +/obj/item/device/abductor/mind_device/proc/mind_control(atom/target, mob/living/user) + if(iscarbon(target)) + var/mob/living/carbon/C = target + var/obj/item/organ/heart/gland/G = C.getorganslot("heart") + if(!istype(G)) + to_chat(user, "Your target does not have an experimental gland!") + return + if(!G.mind_control_uses) + to_chat(user, "Your target's gland is spent!") + return + if(G.active_mind_control) + to_chat(user, "Your target is already under a mind-controlling influence!") + return + + var/command = stripped_input(user, "Enter the command for your target to follow.\ + Uses Left: [G.mind_control_uses], Duration: [G.mind_control_duration / 10] seconds","Enter command") + + if(!command) + return + + if(QDELETED(user) || user.get_active_held_item() != src || loc != user) + return + + if(QDELETED(G)) + return + + G.mind_control(command, user) + to_chat(user, "You send the command to your target.") + +/obj/item/device/abductor/mind_device/proc/mind_message(atom/target, mob/living/user) + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + to_chat(user, "Your target is dead!") + return + var/message = stripped_input(user, "Write a message to send to your target's brain.","Enter message") + if(!message) + return + if(QDELETED(L) || L.stat == DEAD) + return + + to_chat(L, "You hear a voice in your head saying: [message]") + to_chat(user, "You send the message to your target.") + log_talk(user,"[key_name(user)] sent an abductor mind message to [L]/[L.ckey]: '[message]'", LOGSAY) + + /obj/item/device/firing_pin/abductor name = "alien firing pin" icon_state = "firing_pin_ayy" diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 22edb79c80..508f4e9f13 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -12,28 +12,68 @@ var/human_only = 0 var/active = 0 + var/mind_control_uses = 1 + var/mind_control_duration = 1800 + var/active_mind_control = FALSE + /obj/item/organ/heart/gland/proc/ownerCheck() if(ishuman(owner)) - return 1 + return TRUE if(!human_only && iscarbon(owner)) - return 1 - return 0 + return TRUE + return FALSE /obj/item/organ/heart/gland/proc/Start() active = 1 next_activation = world.time + rand(cooldown_low,cooldown_high) +/obj/item/organ/heart/gland/proc/update_gland_hud() + if(!owner) + return + var/image/holder = owner.hud_list[GLAND_HUD] + var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) + holder.pixel_y = I.Height() - world.icon_size + if(active_mind_control) + holder.icon_state = "hudgland_active" + else if(mind_control_uses) + holder.icon_state = "hudgland_ready" + else + holder.icon_state = "hudgland_spent" -/obj/item/organ/heart/gland/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user) + if(!ownerCheck() || !mind_control_uses || active_mind_control) + return + mind_control_uses-- + to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order...") + to_chat(owner, "[command]") + active_mind_control = TRUE + log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]") + update_gland_hud() + + addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration) + +/obj/item/organ/heart/gland/proc/clear_mind_control() + if(!ownerCheck() || !active_mind_control) + return + to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders.") + active_mind_control = FALSE + +/obj/item/organ/heart/gland/Remove(mob/living/carbon/M, special = 0) active = 0 if(initial(uses) == 1) uses = initial(uses) + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.remove_from_hud(owner) + clear_mind_control() ..() -/obj/item/organ/heart/gland/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0) ..() if(special != 2 && uses) // Special 2 means abductor surgery Start() + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.add_to_hud(owner) + update_gland_hud() /obj/item/organ/heart/gland/on_life() if(!beating) @@ -59,6 +99,8 @@ cooldown_high = 400 uses = -1 icon_state = "health" + mind_control_uses = 3 + mind_control_duration = 3000 /obj/item/organ/heart/gland/heals/activate() to_chat(owner, "You feel curiously revitalized.") @@ -71,6 +113,8 @@ cooldown_high = 1200 uses = -1 icon_state = "slime" + mind_control_uses = 1 + mind_control_duration = 2400 /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") @@ -86,6 +130,8 @@ cooldown_high = 300 uses = -1 icon_state = "mindshock" + mind_control_uses = 1 + mind_control_duration = 6000 /obj/item/organ/heart/gland/mindshock/activate() to_chat(owner, "You get a headache.") @@ -103,6 +149,8 @@ uses = -1 human_only = 1 icon_state = "species" + mind_control_uses = 5 + mind_control_duration = 300 /obj/item/organ/heart/gland/pop/activate() to_chat(owner, "You feel unlike yourself.") @@ -114,6 +162,8 @@ cooldown_high = 2400 uses = 1 icon_state = "vent" + mind_control_uses = 4 + mind_control_duration = 1800 /obj/item/organ/heart/gland/ventcrawling/activate() to_chat(owner, "You feel very stretchy.") @@ -125,6 +175,8 @@ cooldown_high = 2400 uses = 1 icon_state = "viral" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/viral/activate() to_chat(owner, "You feel sick.") @@ -141,6 +193,8 @@ cooldown_high = 1600 uses = 10 icon_state = "emp" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/emp/activate() to_chat(owner, "You feel a spike of pain in your head.") @@ -151,6 +205,8 @@ cooldown_high = 900 uses = 10 icon_state = "spider" + mind_control_uses = 2 + mind_control_duration = 2400 /obj/item/organ/heart/gland/spiderman/activate() to_chat(owner, "You feel something crawling in your skin.") @@ -164,6 +220,8 @@ icon_state = "egg" lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' + mind_control_uses = 2 + mind_control_duration = 1800 /obj/item/organ/heart/gland/egg/activate() to_chat(owner, "You lay an egg!") @@ -175,6 +233,8 @@ cooldown_low = 200 cooldown_high = 400 uses = -1 + mind_control_uses = 1 + mind_control_duration = 450 /obj/item/organ/heart/gland/bloody/activate() owner.blood_volume -= 20 @@ -192,6 +252,8 @@ cooldown_high = 600 human_only = 1 uses = 1 + mind_control_uses = 1 + mind_control_duration = 600 /obj/item/organ/heart/gland/bodysnatch/activate() to_chat(owner, "You feel something moving around inside you...") @@ -233,6 +295,8 @@ cooldown_low = 1200 cooldown_high = 1800 uses = -1 + mind_control_uses = 1 + mind_control_duration = 800 /obj/item/organ/heart/gland/plasma/activate() to_chat(owner, "You feel bloated.") diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm index f243f161c3..0b13c359eb 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm @@ -48,6 +48,7 @@ dat += "
    Agent Vest
    " dat += "Radio Silencer
    " dat += "Science Tool
    " + dat += "Mental Interface Device
    " else dat += "NO EXPERIMENT MACHINE DETECTED
    " @@ -109,6 +110,8 @@ Dispense(/obj/item/device/abductor/gizmo) if("vest") Dispense(/obj/item/clothing/suit/armor/abductor/vest) + if("mind_device") + Dispense(/obj/item/device/abductor/mind_device,cost=2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 824c86c69d..3403253c07 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -390,6 +390,7 @@ h1.alert, h2.alert {color: #000000;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} .abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 4e409391da..d601fde492 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -2,6 +2,7 @@ gender = MALE pressure_resistance = 15 possible_a_intents = list(INTENT_HELP, INTENT_HARM) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD) var/list/stomach_contents = list() var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know. var/list/internal_organs_slot= list() //Same as above, but stores "slot ID" - "organ" pairs for easy access. diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 8e72b26419..716373061d 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,5 +1,5 @@ /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD) possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) pressure_resistance = 25 //Hair colour and style diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index cf03d12130..cd273ec98e 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -9,3 +9,13 @@ /datum/species/abductor/copy_properties_from(datum/species/abductor/old_species) scientist = old_species.scientist + +/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.add_hud_to(C) + +/datum/species/abductor/on_species_loss(mob/living/carbon/C) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.remove_hud_from(C) diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 70988dbef5d00f35e33a2f7c9f09be60d7266c31..5e33807ec7987dd1926bc0a9921cc92a2c1af3a9 100644 GIT binary patch literal 13298 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 literal 13068 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 FzW^wclxhF~ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 38edd8dc7dafeeaa39eafe2bc344e75db021c8b4..5602b03f8772267d503484b6ac5ef21c9088192f 100644 GIT binary patch delta 9620 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 delta 7760 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 Date: Mon, 18 Dec 2017 20:42:10 -0600 Subject: [PATCH 097/213] Automatic changelog generation for PR #4442 [ci skip] --- html/changelogs/AutoChangeLog-pr-4442.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4442.yml diff --git a/html/changelogs/AutoChangeLog-pr-4442.yml b/html/changelogs/AutoChangeLog-pr-4442.yml new file mode 100644 index 0000000000..e480e91419 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4442.yml @@ -0,0 +1,8 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Abductors can now see if people already have glands! Never worry about abducting the same guy twice again." + - rscadd: "Added the Mind Interface Device to the abductor shop for 2 Credits. Only scientists can use it." + - rscadd: "The MID has two modes: Transmit and Control." + - rscadd: "Transmit will allow you to send a message anytime, anywhere to the mind of a target of your choice, regardless of language barriers. The message will be anonymous, but abductor-like." + - rscadd: "Control allows you to give a temporary directive to a target with an implanted gland, that they MUST follow. Duration and amount of uses varies by gland type. When a gland is spent, it will no longer respond to Control signals. The target forgets ever receiving the objective when the duration ends." From 8149f52777521e751ee9a6f8a790495f0a520ea5 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 18 Dec 2017 18:55:09 -0800 Subject: [PATCH 098/213] Adds jousting (#33531) --- code/__DEFINES/components.dm | 3 +- code/datums/components/jousting.dm | 81 ++++++++++++++++++++++++++++ code/game/objects/items.dm | 3 +- code/game/objects/items/twohanded.dm | 4 ++ tgstation.dme | 1 + 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 code/datums/components/jousting.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 87c226b839..0b2a3e06d4 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -61,6 +61,8 @@ #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) #define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) +#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (/mob/dropper) // /obj/item/clothing signals #define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () @@ -77,7 +79,6 @@ #define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): () #define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () - // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) diff --git a/code/datums/components/jousting.dm b/code/datums/components/jousting.dm new file mode 100644 index 0000000000..68621e60ec --- /dev/null +++ b/code/datums/components/jousting.dm @@ -0,0 +1,81 @@ +/datum/component/jousting + var/current_direction = NONE + var/max_tile_charge = 5 + var/min_tile_charge = 2 //tiles before this code gets into effect. + var/current_tile_charge = 0 + var/movement_reset_tolerance = 2 //deciseconds + var/unmounted_damage_boost_per_tile = 0 + var/unmounted_knockdown_chance_per_tile = 0 + var/unmounted_knockdown_time = 0 + var/mounted_damage_boost_per_tile = 2 + var/mounted_knockdown_chance_per_tile = 20 + var/mounted_knockdown_time = 20 + var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to. + var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever. + var/mob/current_holder + var/datum/component/redirect/listener + var/current_timerid + +/datum/component/jousting/Initialize() + if(!isitem(parent)) + . = COMPONENT_INCOMPATIBLE + stack_trace("Warning: Jousting component incorrectly applied to invalid parent type [parent.type]") + RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip) + RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop) + RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack) + +/datum/component/jousting/Destroy() + QDEL_NULL(listener) + return ..() + +/datum/component/jousting/proc/on_equip(mob/user, slot) + QDEL_NULL(listener) + current_holder = user + listener = new(user, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move)) + +/datum/component/jousting/proc/on_drop(mob/user) + QDEL_NULL(listener) + current_holder = null + current_direction = NONE + current_tile_charge = 0 + +/datum/component/jousting/proc/on_attack(mob/living/target, mob/user) + if(user != current_holder) + return + var/current = current_tile_charge + var/obj/item/I = parent + var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are. + if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge)) + return + var/turf/target_turf = get_step(user, current_direction) + if(target in range(1, target_turf)) + var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current + var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time) + var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current + var/sharp = I.is_sharp() + var/msg + if(damage) + msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]" + target.apply_damage(damage, BRUTE, user.zone_selected, 0) + if(prob(knockdown_chance)) + msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]" + if(target_buckled) + target.buckled.unbuckle_mob(target) + target.Knockdown(knockdown_time) + if(length(msg)) + user.visible_message("[msg]!") + +/datum/component/jousting/proc/mob_move(newloc, dir) + if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled)))) + return + if(dir != current_direction) + current_tile_charge = 0 + current_direction = dir + if(current_tile_charge < max_tile_charge) + current_tile_charge++ + if(current_timerid) + deltimer(current_timerid) + current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE) + +/datum/component/jousting/proc/reset_charge() + current_tile_charge = 0 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a74b246282..d4e5240642 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -286,7 +286,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(!user.put_in_active_hand(src)) dropped(user) - /obj/item/attack_paw(mob/user) if(!user) return @@ -400,6 +399,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return ITALICS | REDUCE_RANGE /obj/item/proc/dropped(mob/user) + SendSignal(COMSIG_ITEM_DROPPED, user) for(var/X in actions) var/datum/action/A = X A.Remove(user) @@ -431,6 +431,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // for items that can be placed in multiple slots // note this isn't called during the initial dressing of a player /obj/item/proc/equipped(mob/user, slot) + SendSignal(COMSIG_ITEM_EQUIPPED, user, slot) for(var/X in actions) var/datum/action/A = X if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index c11d41eaa8..58758668c3 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -429,6 +429,10 @@ var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" +/obj/item/twohanded/spear/Initialize() + . = ..() + AddComponent(/datum/component/jousting) + /obj/item/twohanded/spear/examine(mob/user) ..() if(explosive) diff --git a/tgstation.dme b/tgstation.dme index 737f7e8274..01dbb29b04 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -345,6 +345,7 @@ #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" #include "code\datums\components\infective.dm" +#include "code\datums\components\jousting.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\ntnet_interface.dm" #include "code\datums\components\paintable.dm" From ffb04fd0704a729e09c51267a4247e0d9d9be1b1 Mon Sep 17 00:00:00 2001 From: Shadowlight213 Date: Mon, 18 Dec 2017 17:18:45 -1000 Subject: [PATCH 100/213] Removes syndicate door access from Captain's PDA cartridge. (#33635) --- code/game/objects/items/devices/PDA/cart.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index bfcda7d271..1b9e2c0e14 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -180,9 +180,9 @@ /obj/item/cartridge/captain name = "\improper Value-PAK cartridge" - desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime and Clown) + desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie) icon_state = "cart-c" - access = ~(CART_CLOWN | CART_MIME) + access = ~(CART_CLOWN | CART_MIME | CART_REMOTE_DOOR) bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT spam_enabled = 1 From 4840a9c4189ea1e64e615a4a6ba6672e28f1af04 Mon Sep 17 00:00:00 2001 From: coiax Date: Tue, 19 Dec 2017 03:18:01 +0000 Subject: [PATCH 102/213] Codespeak manual rebalance/recost (#33638) :cl: coiax balance: The codespeak manual now has unlimited uses and costs 3 TC. fix: Nuke ops can now purchase the codespeak manual, as was intended. /:cl: It's an item that's just used for communication security, and also light memeing, so I'll make it cheaper. Also fixes a bug where I didn't specify the item path for the nuke ops version, so they couldn't buy it. --- code/modules/uplink/uplink_items.dm | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index d28adebe4b..ebff0fdbeb 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1096,16 +1096,9 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/device_tools/codespeak_manual name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. One use." - item = /obj/item/codespeak_manual - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/codespeak_manual_deluxe - name = "Deluxe Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." - cost = 8 - include_modes = list(/datum/game_mode/nuclear) + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." + item = /obj/item/codespeak_manual/unlimited + cost = 3 // Implants /datum/uplink_item/implants From fabfad270fbbef8c751b7313cc55220073386173 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 18 Dec 2017 22:42:25 -0500 Subject: [PATCH 104/213] Callback security and usr (#33599) * Gonna regret writing this one day * tmp -> temp * Make PushUsr() a /world proc * Callbacks now preserve usr * Fixes PushUsr return value * Fixes PushUsr invocations * Update modifyvariables.dm * Use weakrefs in callback user * Further fixes * Whoopsie --- code/__HELPERS/unsorted.dm | 8 ++++++++ code/datums/callback.dm | 20 ++++++++++++++++++++ code/modules/admin/verbs/modifyvariables.dm | 13 ++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9ec23fa966..0755074dec 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1508,6 +1508,14 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) return "\[[url_encode(thing.tag)]\]" return "\ref[input]" +// Makes a call in the context of a different usr +// Use sparingly +/world/proc/PushUsr(mob/M, datum/callback/CB) + var/temp = usr + usr = M + . = CB.Invoke() + usr = temp + //Returns a list of all servants of Ratvar and observers. /proc/servants_and_ghosts() . = list() diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 88d9427301..5566137189 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -48,6 +48,7 @@ var/datum/object = GLOBAL_PROC var/delegate var/list/arguments + var/datum/weakref/user /datum/callback/New(thingtocall, proctocall, ...) if (thingtocall) @@ -55,6 +56,8 @@ delegate = proctocall if (length(args) > 2) arguments = args.Copy(3) + if(usr) + user = WEAKREF(usr) /world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...) set waitfor = FALSE @@ -70,8 +73,16 @@ call(thingtocall, proctocall)(arglist(calling_arguments)) /datum/callback/proc/Invoke(...) + if(!usr) + var/datum/weakref/W = user + if(W) + var/mob/M = W.resolve() + if(M) + return world.PushUsr(M, src) + if (!object) return + var/list/calling_arguments = arguments if (length(args)) if (length(arguments)) @@ -87,8 +98,17 @@ //copy and pasted because fuck proc overhead /datum/callback/proc/InvokeAsync(...) set waitfor = FALSE + + if(!usr) + var/datum/weakref/W = user + if(W) + var/mob/M = W.resolve() + if(M) + return world.PushUsr(M, src) + if (!object) return + var/list/calling_arguments = arguments if (length(args)) if (length(arguments)) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 3a2e13fdcc..f6e8d93e62 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -213,7 +213,9 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/atom/newguy = new type() + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_DATUM) var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) @@ -221,7 +223,9 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/datum/newguy = new type() + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_TYPE) var/type = current_value @@ -237,7 +241,10 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/datum/newguy = new type() + if(istype(newguy)) + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_LIST) From 522b8383d8addd4f1503768b7d0ad92f1fe4a53b Mon Sep 17 00:00:00 2001 From: ACCount Date: Tue, 19 Dec 2017 07:55:01 +0300 Subject: [PATCH 106/213] [READY]Refactors reagent container types --- code/__DEFINES/reagents.dm | 41 ++- code/game/atoms.dm | 60 +-- code/game/machinery/limbgrower.dm | 2 +- code/game/objects/items/cigs_lighters.dm | 4 +- code/game/objects/items/extinguisher.dm | 7 +- .../objects/items/implants/implant_chem.dm | 2 +- code/game/objects/items/tanks/watertank.dm | 4 +- code/game/objects/items/tools/weldingtool.dm | 347 ++++++++++++++++++ code/game/objects/structures/janicart.dm | 2 +- code/game/objects/structures/mop_bucket.dm | 20 + code/game/objects/structures/watercloset.dm | 6 +- code/modules/crafting/craft.dm | 2 +- .../detectivework/footprints_and_rag.dm | 2 +- code/modules/food_and_drinks/drinks/drinks.dm | 51 +-- code/modules/food_and_drinks/food.dm | 2 +- .../modules/food_and_drinks/food/condiment.dm | 6 +- .../food_and_drinks/food/customizables.dm | 2 +- code/modules/food_and_drinks/food/snacks.dm | 2 +- .../kitchen_machinery/deep_fryer.dm | 2 +- .../kitchen_machinery/food_cart.dm | 4 +- .../kitchen_machinery/icecream_vat.dm | 4 +- .../kitchen_machinery/microwave.dm | 6 +- code/modules/hydroponics/hydroitemdefines.dm | 12 - code/modules/hydroponics/hydroponics.dm | 4 +- .../integrated_electronics/passive/power.dm | 2 +- .../subtypes/reagents.dm | 23 +- code/modules/mob/living/living.dm | 9 +- code/modules/paperwork/pen.dm | 2 +- .../projectiles/ammunition/ammo_casings.dm | 6 + .../projectiles/guns/energy/special.dm | 1 - code/modules/reagents/chemistry/holder.dm | 13 + .../chemistry/machinery/chem_dispenser.dm | 2 +- .../chemistry/machinery/chem_heater.dm | 2 +- .../chemistry/machinery/chem_master.dm | 2 +- .../reagents/chemistry/machinery/pandemic.dm | 2 +- .../chemistry/machinery/reagentgrinder.dm | 2 +- code/modules/reagents/reagent_containers.dm | 13 +- .../reagents/reagent_containers/borghydro.dm | 2 +- .../reagents/reagent_containers/dropper.dm | 2 +- .../reagents/reagent_containers/glass.dm | 40 +- .../reagents/reagent_containers/hypospray.dm | 4 +- .../reagents/reagent_containers/pill.dm | 11 +- .../reagents/reagent_containers/spray.dm | 16 +- .../reagents/reagent_containers/syringes.dm | 9 +- code/modules/reagents/reagent_dispenser.dm | 12 +- code/modules/research/circuitprinter.dm | 2 +- .../departmental_circuit_imprinter.dm | 2 +- code/modules/research/departmental_lathe.dm | 2 +- code/modules/research/protolathe.dm | 2 +- code/modules/research/rdmachines.dm | 2 +- .../research/xenobiology/xenobiology.dm | 2 +- 51 files changed, 577 insertions(+), 204 deletions(-) diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index c85365db90..d9e6225eb7 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -1,19 +1,30 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 +#define SOLID 1 +#define LIQUID 2 +#define GAS 3 -#define INJECTABLE_1 1024 //Makes reagents addable through droppers and syringes -#define DRAWABLE_1 2048 //If a syringe can draw from it -#define OPENCONTAINER_1 4096 //Is an open container for chemistry purposes -#define TRANSPARENT_1 8192 //Used for non-open containers which you still want to be able to see the reagents off. -#define TOUCH 1 //splashing -#define INGEST 2 //ingestion -#define VAPOR 3 //foam, spray, blob attack -#define PATCH 4 //patches -#define INJECT 5 //injection +// container_type defines +#define INJECTABLE 1 // Makes it possible to add reagents through droppers and syringes. +#define DRAWABLE 2 // Makes it possible to remove reagents through syringes. + +#define REFILLABLE 4 // Makes it possible to add reagents through any reagent container. +#define DRAINABLE 8 // Makes it possible to remove reagents through any reagent container. + +#define TRANSPARENT 16 // Used on containers which you want to be able to see the reagents off. +#define AMOUNT_VISIBLE 32 // For non-transparent containers that still have the general amount of reagents in them visible. + +// Is an open container for all intents and purposes. +#define OPENCONTAINER REFILLABLE | DRAINABLE | TRANSPARENT + + +#define TOUCH 1 // splashing +#define INGEST 2 // ingestion +#define VAPOR 3 // foam, spray, blob attack +#define PATCH 4 // patches +#define INJECT 5 // injection + //defines passed through to the on_reagent_change proc -#define DEL_REAGENT 1 //reagent deleted (fully cleared) -#define ADD_REAGENT 2 // reagent added -#define REM_REAGENT 3 // reagent removed (may still exist) +#define DEL_REAGENT 1 // reagent deleted (fully cleared) +#define ADD_REAGENT 2 // reagent added +#define REM_REAGENT 3 // reagent removed (may still exist) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b7d377fb61..211f9dea59 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -194,27 +194,22 @@ set waitfor = FALSE return -// Convenience proc to see if a container is open for chemistry handling -// returns true if open -// false if closed +// Convenience procs to see if a container is open for chemistry handling /atom/proc/is_open_container() - return container_type & OPENCONTAINER_1 - -/atom/proc/is_transparent() - return container_type & TRANSPARENT_1 + return is_refillable() && is_drainable() /atom/proc/is_injectable(allowmobs = TRUE) - if(isliving(src) && allowmobs) - var/mob/living/L = src - return L.can_inject() - if(container_type & OPENCONTAINER_1) - return TRUE - return container_type & INJECTABLE_1 + return reagents && (container_type & (INJECTABLE | REFILLABLE)) /atom/proc/is_drawable(allowmobs = TRUE) - if(is_injectable(allowmobs)) //Everything that can be injected can also be drawn from, but not vice versa - return TRUE - return container_type & DRAWABLE_1 + return reagents && (container_type & (DRAWABLE | DRAINABLE)) + +/atom/proc/is_refillable() + return reagents && (container_type & REFILLABLE) + +/atom/proc/is_drainable() + return reagents && (container_type & DRAINABLE) + /atom/proc/AllowDrop() return FALSE @@ -256,19 +251,26 @@ if(desc) to_chat(user, desc) - if(reagents && (is_open_container() || is_transparent())) //is_open_container() isn't really the right proc for this, but w/e - to_chat(user, "It contains:") - if(reagents.reagent_list.len) - if(user.can_see_reagents()) //Show each individual reagent - for(var/datum/reagent/R in reagents.reagent_list) - to_chat(user, "[R.volume] units of [R.name]") - else //Otherwise, just show the total volume - var/total_volume = 0 - for(var/datum/reagent/R in reagents.reagent_list) - total_volume += R.volume - to_chat(user, "[total_volume] units of various reagents") - else - to_chat(user, "Nothing.") + if(reagents) + if(container_type & TRANSPARENT) + to_chat(user, "It contains:") + if(reagents.reagent_list.len) + if(user.can_see_reagents()) //Show each individual reagent + for(var/datum/reagent/R in reagents.reagent_list) + to_chat(user, "[R.volume] units of [R.name]") + else //Otherwise, just show the total volume + var/total_volume = 0 + for(var/datum/reagent/R in reagents.reagent_list) + total_volume += R.volume + to_chat(user, "[total_volume] units of various reagents") + else + to_chat(user, "Nothing.") + else if(container_type & AMOUNT_VISIBLE) + if(reagents.total_volume) + to_chat(user, "It has [reagents.total_volume] unit\s left.") + else + to_chat(user, "It's empty.") + SendSignal(COMSIG_PARENT_EXAMINE, user) /atom/proc/relaymove(mob/user) diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index 47fee66b9e..e661bc24c5 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -10,7 +10,7 @@ icon = 'icons/obj/machines/limbgrower.dmi' icon_state = "limbgrower_idleoff" density = TRUE - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 9c7c34510c..ee0aa2c63c 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -102,7 +102,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigoff" throw_speed = 0.5 item_state = "cigoff" - container_type = INJECTABLE_1 + container_type = INJECTABLE w_class = WEIGHT_CLASS_TINY body_parts_covered = null grind_results = list() @@ -659,7 +659,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "[param_color]_vape" /obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/reagent_containers) && (O.container_type & OPENCONTAINER_1)) + if(O.is_drainable()) if(reagents.total_volume < chem_volume) if(O.reagents.total_volume > 0) O.reagents.trans_to(src,25) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index d334d12193..5f582b9e15 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -16,6 +16,7 @@ attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") dog_fashion = /datum/dog_fashion/back resistance_flags = FIRE_PROOF + container_type = AMOUNT_VISIBLE var/max_water = 50 var/last_use = 1 var/safety = TRUE @@ -48,7 +49,6 @@ /obj/item/extinguisher/attack_self(mob/user) safety = !safety src.icon_state = "[sprite_name][!safety]" - src.desc = "The safety is [safety ? "on" : "off"]." to_chat(user, "The safety is [safety ? "on" : "off"].") return @@ -67,11 +67,10 @@ /obj/item/extinguisher/examine(mob/user) ..() + to_chat(user, "The safety is [safety ? "on" : "off"].") + if(reagents.total_volume) - to_chat(user, "It contains [round(reagents.total_volume)] unit\s.") to_chat(user, "Alt-click to empty it.") - else - to_chat(user, "It is empty.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user)) diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm index 509784a699..e266f3ab09 100644 --- a/code/game/objects/items/implants/implant_chem.dm +++ b/code/game/objects/items/implants/implant_chem.dm @@ -2,7 +2,7 @@ name = "chem implant" desc = "Injects things." icon_state = "reagents" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER /obj/item/implant/chem/get_data() var/dat = {"Implant Specifications:
    diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index fa7d14d572..8a3dc21dbe 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -114,7 +114,7 @@ possible_transfer_amounts = list(25,50,100) volume = 500 flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = 0 var/obj/item/watertank/tank @@ -351,7 +351,7 @@ var/usage_ratio = 5 //5 unit added per 1 removed var/injection_amount = 1 amount_per_transfer_from_this = 5 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = FALSE possible_transfer_amounts = list(5,10,15) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 1c20c95e93..a09f0d2a1a 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD #define WELDER_FUEL_BURN_INTERVAL 13 /obj/item/weldingtool name = "welding tool" @@ -336,4 +337,350 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) +======= +#define WELDER_FUEL_BURN_INTERVAL 13 +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by Nanotrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = CEILING(ratio*4, 1) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + . = ..() + update_icon() + +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) + return + if(!status && O.is_refillable()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) + else + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) + +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) + + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE + else + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + +>>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) #undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index b6332492dd..0f12f847d7 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -5,7 +5,7 @@ icon_state = "cart" anchored = FALSE density = TRUE - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER //copypaste sorry var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite var/obj/item/storage/bag/trash/mybag = null diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index b2dc64fec7..43da5073ed 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/janitor.dmi' icon_state = "mopbucket" density = TRUE +<<<<<<< HEAD container_type = OPENCONTAINER_1 var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite @@ -21,4 +22,23 @@ to_chat(user, "You wet [I] in [src].") playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else +======= + container_type = OPENCONTAINER + var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite + + +/obj/structure/mopbucket/New() + create_reagents(100) + ..() + +/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/mop)) + if(reagents.total_volume < 1) + to_chat(user, "[src] is out of water!") + else + reagents.trans_to(I, 5) + to_chat(user, "You wet [I] in [src].") + playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + else +>>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) return ..() \ No newline at end of file diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 9009a7171d..77b992704a 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -483,9 +483,9 @@ if(istype(O, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RG = O - if(RG.container_type & OPENCONTAINER_1) + if(RG.is_refillable()) if(!RG.reagents.holder_full()) - RG.reagents.add_reagent("[dispensedreagent]", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + RG.reagents.add_reagent(dispensedreagent, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) to_chat(user, "You fill [RG] from [src].") return TRUE to_chat(user, "\The [RG] is full.") @@ -533,7 +533,7 @@ O.clean_blood() O.acid_level = 0 create_reagents(5) - reagents.add_reagent("[dispensedreagent]", 5) + reagents.add_reagent(dispensedreagent, 5) reagents.reaction(O, TOUCH) user.visible_message("[user] washes [O] using [src].", \ "You wash [O] using [src].") diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 3e4e93ca4c..85ae7c3b18 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -98,7 +98,7 @@ else if(istype(I, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = I - if(RC.container_type & OPENCONTAINER_1) + if(RC.is_drainable()) for(var/datum/reagent/A in RC.reagents.reagent_list) .[A.type] += A.volume .[I.type] += 1 diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 9415bef33d..793805977c 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -13,7 +13,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "rag" flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER amount_per_transfer_from_this = 5 possible_transfer_amounts = list() volume = 5 diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 6fb712ea41..c03b183ecc 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -8,7 +8,7 @@ icon_state = null lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it. possible_transfer_amounts = list(5,10,15,20,25,30,50) volume = 50 @@ -30,7 +30,7 @@ if(!canconsume(M, user)) return 0 - if (!is_open_container()) + if (!is_drainable()) to_chat(user, "[src]'s lid hasn't been opened!") return 0 @@ -44,7 +44,7 @@ if(!reagents || !reagents.total_volume) return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds the contents of [src] to [M].", "[user] feeds the contents of [src] to [M].") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) var/fraction = min(gulp_size/reagents.total_volume, 1) checkLiked(fraction, M) @@ -56,31 +56,16 @@ /obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity) if(!proximity) return - if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - if (!is_open_container()) - to_chat(user, "[target]'s tab isn't open!") - return - - if(!target.reagents.total_volume) - to_chat(user, "[target] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "[src] is full.") - return - - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] units of the contents of [target].") - - else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it. + if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) to_chat(user, "[src] is empty.") return - if(target.reagents.total_volume >= target.reagents.maximum_volume) + if(target.reagents.holder_full()) to_chat(user, "[target] is full.") return + var/refill = reagents.get_master_reagent_id() var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) to_chat(user, "You transfer [trans] units of the solution to [target].") @@ -90,6 +75,24 @@ bro.cell.use(30) addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 600) + else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. + if (!is_refillable()) + to_chat(user, "[src]'s tab isn't open!") + return + + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty.") + return + + if(reagents.holder_full()) + to_chat(user, "[src] is full.") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] units of the contents of [target].") + + else + /obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params) if(I.is_hot()) var/added_heat = (I.is_hot() / 100) //ishot returns a temperature @@ -142,7 +145,7 @@ possible_transfer_amounts = list() volume = 5 flags_1 = CONDUCT_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = TRUE resistance_flags = FIRE_PROOF isGlass = FALSE @@ -406,9 +409,9 @@ /obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user) - if(!is_open_container()) + if(!is_drainable()) to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER playsound(src, "can_open", 50, 1) spillable = TRUE return diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index e23f6b98a9..765f118c5e 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/food possible_transfer_amounts = list() volume = 50 //Sets the default container amount for all food items. - container_type = INJECTABLE_1 + container_type = INJECTABLE resistance_flags = FLAMMABLE var/foodtype = NONE var/last_check_time diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 3e6e2e8450..445e8e6534 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -10,7 +10,7 @@ desc = "Just your average condiment container." icon = 'icons/obj/food/containers.dmi' icon_state = "emptycondiment" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50) volume = 50 //Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites. @@ -45,7 +45,7 @@ if(!reagents || !reagents.total_volume) return // The condiment might be empty after the delay. user.visible_message("[user] feeds [M] from [src].") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) var/fraction = min(10/reagents.total_volume, 1) reagents.reaction(M, INGEST, fraction) @@ -70,7 +70,7 @@ to_chat(user, "You fill [src] with [trans] units of the contents of [target].") //Something like a glass or a food item. Player probably wants to transfer TO it. - else if(target.is_open_container() || istype(target, /obj/item/reagent_containers/food/snacks)) + else if(target.is_drainable() || istype(target, /obj/item/reagent_containers/food/snacks)) if(!reagents.total_volume) to_chat(user, "[src] is empty!") return diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 3351a67d39..f3460edcaa 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -291,7 +291,7 @@ desc = "A simple bowl, used for soups and salads." icon = 'icons/obj/food/soupsalad.dmi' icon_state = "bowl" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER materials = list(MAT_GLASS = 500) w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 7f574e0313..08b09124d5 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -94,7 +94,7 @@ if(!do_mob(user, M)) return - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) M.visible_message("[user] forces [M] to eat [src].", \ "[user] forces [M] to eat [src].") diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index a336d77404..40eae1b570 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -29,7 +29,7 @@ God bless America. anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW? var/cook_time = 0 var/oil_use = 0.05 //How much cooking oil is used per tick diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 8573a84c9b..26a2bec76f 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -15,7 +15,7 @@ var/portion = 10 var/selected_drink var/list/stored_food = list() - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/obj/item/reagent_containers/mixer /obj/machinery/food_cart/Initialize() @@ -100,7 +100,7 @@ stored_food[sanitize(S.name)]++ else stored_food[sanitize(S.name)] = 1 - else if(O.is_open_container()) + else if(O.is_drainable()) return else . = ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 1b00de1842..f2f288fe7a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -14,7 +14,7 @@ anchored = FALSE use_power = NO_POWER_USE layer = BELOW_OBJ_LAYER - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER max_integrity = 300 var/list/product_types = list() var/dispense_flavour = ICECREAM_VANILLA @@ -112,7 +112,7 @@ else to_chat(user, "[O] already has ice cream in it.") return 1 - else if(O.is_open_container()) + else if(O.is_drainable()) return else return ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index dfa249c04d..52ee5ebd2b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -81,7 +81,7 @@ src.icon_state = "mw" src.broken = 0 // Fix it! src.dirty = 0 // just to be sure - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER return 0 //to use some fuel else to_chat(user, "It's broken!") @@ -98,7 +98,7 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER src.updateUsrDialog() return 1 // Disables the after-attack so we don't spray the floor/user. else @@ -119,7 +119,7 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER else if(src.dirty==100) // The microwave is all dirty so can't be used! to_chat(user, "It's dirty!") diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 42a927f4e9..c72d9e5c28 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -24,12 +24,6 @@ lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' volume = 100 - container_type = OPENCONTAINER_1 - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 10 /obj/item/reagent_containers/spray/weedspray/Initialize() . = ..() @@ -48,12 +42,6 @@ lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' volume = 100 - container_type = OPENCONTAINER_1 - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 10 /obj/item/reagent_containers/spray/pestspray/Initialize() . = ..() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 5c1fafc1c4..08cb712542 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -712,8 +712,8 @@ else if(transfer_amount) // Droppers, cans, beakers, what have you. visi_msg="[user] uses [reagent_source] on [target]" irrigate = 1 - // Beakers, bottles, buckets, etc. Can't use is_open_container though. - if(istype(reagent_source, /obj/item/reagent_containers/glass/)) + // Beakers, bottles, buckets, etc. + if(reagent_source.is_drainable()) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) if(irrigate && transfer_amount > 30 && reagent_source.reagents.total_volume >= 30 && using_irrigation) diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 0941c033f6..2acce3d450 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -90,7 +90,7 @@ icon_state = "chemical_cell" extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\ ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER complexity = 4 inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 564c3a4851..b6307471f4 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -17,7 +17,7 @@ extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ into the smoke clouds when activated. The reagents are consumed when smoke is made." - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER volume = 100 complexity = 20 @@ -66,7 +66,7 @@ extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \ must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amount makes injector suck out reagents." - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER volume = 30 complexity = 20 @@ -145,7 +145,7 @@ return if(direction_mode == SYRINGE_INJECT) - if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.total_volume >= AM.reagents.maximum_volume) + if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.holder_full()) activate_pin(3) return @@ -156,12 +156,8 @@ return //Always log attemped injections for admins - var/list/rinject = list() - for(var/datum/reagent/R in reagents.reagent_list) - rinject += R.name - var/contained = english_list(rinject) - - add_logs(src, L, "attemped to inject", addition="which had [contained]") //TODO: proper logging (maybe last touched and assembled) + var/contained = reagents.log_list() + add_logs(src, L, "attemped to inject", addition="which had [contained]") L.visible_message("[acting_object] is trying to inject [L]!", \ "[acting_object] is trying to inject you!") busy = TRUE @@ -169,6 +165,7 @@ var/fraction = min(transfer_amount/reagents.total_volume, 1) reagents.reaction(L, INJECT, fraction) reagents.trans_to(L, transfer_amount) + add_logs(src, L, "injected", addition="which had [contained]") L.visible_message("[acting_object] injects [L] with its needle!", \ "[acting_object] injects you with its needle!") else @@ -263,8 +260,7 @@ activate_pin(2) return - // FALSE in those procs makes mobs invalid targets. - if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE)) + if(!source.is_drainable() || !target.is_refillable()) return source.reagents.trans_to(target, transfer_amount) @@ -276,7 +272,7 @@ icon_state = "reagent_storage" extended_desc = "This is effectively an internal beaker." - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER volume = 60 complexity = 4 @@ -398,8 +394,7 @@ if(!source.reagents || !target.reagents) return - // FALSE in those procs makes mobs invalid targets. - if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE)) + if(!source.is_drainable() || !target.is_refillable()) return if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f589ecbb20..f07eecd998 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -343,8 +343,15 @@ return 1 return 0 +// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general. /mob/living/proc/can_inject() - return 1 + return TRUE + +/mob/living/is_injectable(allowmobs = TRUE) + return (allowmobs && reagents && can_inject()) + +/mob/living/is_drawable(allowmobs = TRUE) + return (allowmobs && reagents && can_inject()) /mob/living/proc/get_organ_target() var/mob/shooter = src diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index fd52d8f0ac..cde600186f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -162,7 +162,7 @@ * Sleepypens */ /obj/item/pen/sleepy - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER /obj/item/pen/sleepy/attack(mob/living/M, mob/user) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index d51ea36e15..d3ca08dc85 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -284,9 +284,15 @@ icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/dart +<<<<<<< HEAD /obj/item/ammo_casing/shotgun/dart/New() ..() container_type |= OPENCONTAINER_1 +======= +/obj/item/ammo_casing/shotgun/dart/Initialize() + . = ..() + container_type |= OPENCONTAINER +>>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) create_reagents(30) reagents.set_reacting(TRUE) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 06bda36c66..a4ae8cae13 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -121,7 +121,6 @@ item_state = "plasmacutter" ammo_type = list(/obj/item/ammo_casing/energy/plasma) flags_1 = CONDUCT_1 - container_type = OPENCONTAINER_1 attack_verb = list("attacked", "slashed", "cut", "sliced") force = 12 sharpness = IS_SHARP diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9c4bff72cb..5958dc0eab 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -59,6 +59,19 @@ if(my_atom && my_atom.reagents == src) my_atom.reagents = null + +// Used in attack logs for reagents in pills and such +/datum/reagents/proc/log_list() + if(!length(reagent_list)) + return "no reagents" + + var/list/data = list() + for(var/r in reagent_list) //no reagents will be left behind + var/datum/reagent/R = r + data += "[R.id] ([round(R.volume, 0.1)]u)" + //Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. + return english_list(data) + /datum/reagents/proc/remove_any(amount = 1) var/list/cached_reagents = reagent_list var/total_transfered = 0 diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 745843474e..a0e1e64207 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -184,7 +184,7 @@ if(default_unfasten_wrench(user, I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) var/obj/item/reagent_containers/B = I . = 1 //no afterattack if(beaker) diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index a6d958220a..dc21eec6c0 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -64,7 +64,7 @@ if(default_deconstruction_crowbar(I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = 1 //no afterattack if(beaker) to_chat(user, "A container is already loaded into [src]!") diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 3e06449e3a..e0c3b23c5a 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -88,7 +88,7 @@ if(default_unfasten_wrench(user, I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = 1 // no afterattack if(panel_open) to_chat(user, "You can't use the [src.name] while its panel is opened!") diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index f6b0f464fd..ef186d8a79 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -225,7 +225,7 @@ /obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = TRUE //no afterattack if(stat & (NOPOWER|BROKEN)) return diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 223259f6f3..b5d715f5ff 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -62,7 +62,7 @@ if(default_unfasten_wrench(user, I)) return - if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) ) + if (istype(I, /obj/item/reagent_containers) && I.is_open_container()) if (!beaker) if(!user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 8698c10b05..842d2dc2c3 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -48,15 +48,6 @@ /obj/item/reagent_containers/afterattack(obj/target, mob/user , flag) return -/obj/item/reagent_containers/proc/reagentlist(obj/item/reagent_containers/snack) //Attack logs for regents in pills - var/data - if(snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries - for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind - data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. - return data - else - return "No reagents" - /obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user) if(!iscarbon(eater)) return 0 @@ -127,7 +118,11 @@ reagents.clear_reagents() /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) +<<<<<<< HEAD if(is_open_container()) reagents.chem_temp = max(reagents.chem_temp, 1000) reagents.handle_reactions() +======= + reagents.expose_temperature(1000) +>>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) ..() diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 28a07d5862..0a99d9da6e 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -173,7 +173,7 @@ Borg Shaker if(!proximity) return - else if(target.is_open_container() && target.reagents) + else if(target.is_refillable()) var/datum/reagents/R = reagent_list[mode] if(!R.total_volume) to_chat(user, "[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.") diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 30aa67e91a..144db32a6c 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -6,7 +6,7 @@ amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1, 2, 3, 4, 5) volume = 5 - container_type = TRANSPARENT_1 + container_type = TRANSPARENT /obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity) if(!proximity) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index df2df7c171..33a45fd27b 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -3,7 +3,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50) volume = 50 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = TRUE resistance_flags = ACID_PROOF @@ -44,7 +44,7 @@ if(!reagents || !reagents.total_volume) return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds something to [M].", "[user] feeds something to you.") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) else to_chat(user, "You swallow a gulp of [src].") var/fraction = min(5/reagents.total_volume, 1) @@ -56,32 +56,30 @@ if((!proximity) || !check_allowed_items(target,target_self=1)) return - else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - - if(target.reagents && !target.reagents.total_volume) - to_chat(user, "[target] is empty and can't be refilled!") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "[src] is full.") - return - - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") - - else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) to_chat(user, "[src] is empty!") return - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, "[target] is full.") + if(target.reagents.holder_full()) + to_chat(user, "[target] is full.") return - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) to_chat(user, "You transfer [trans] unit\s of the solution to [target].") + else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty and can't be refilled!") + return + + if(reagents.holder_full()) + to_chat(user, "[src] is full.") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") + else if(reagents.total_volume) if(user.a_intent == INTENT_HARM) user.visible_message("[user] splashes the contents of [src] onto [target]!", \ @@ -169,7 +167,6 @@ volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100) - flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" @@ -179,7 +176,6 @@ materials = list(MAT_METAL=3000) volume = 50 amount_per_transfer_from_this = 10 - flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/noreact/Initialize() . = ..() @@ -195,7 +191,6 @@ volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300) - flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/cryoxadone list_reagents = list("cryoxadone" = 30) @@ -238,7 +233,6 @@ amount_per_transfer_from_this = 20 possible_transfer_amounts = list(10,15,20,25,30,50,70) volume = 70 - flags_1 = OPENCONTAINER_1 flags_inv = HIDEHAIR slot_flags = SLOT_HEAD resistance_flags = NONE diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index dff0869322..53e0c9bfb6 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -10,7 +10,7 @@ volume = 30 possible_transfer_amounts = list() resistance_flags = ACID_PROOF - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = SLOT_BELT var/ignore_flags = 0 var/infinite = FALSE @@ -88,7 +88,7 @@ amount_per_transfer_from_this = 10 volume = 10 ignore_flags = 1 //so you can medipen through hardsuits - container_type = DRAWABLE_1 + container_type = DRAWABLE flags_1 = null list_reagents = list("epinephrine" = 10) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 5a2e888210..4908a55911 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -46,7 +46,7 @@ "[user] forces [M] to [apply_method] [src].") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) if(reagents.total_volume) reagents.reaction(M, apply_type) reagents.trans_to(M, reagents.total_volume) @@ -57,10 +57,15 @@ /obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) if(!proximity) return - if(target.is_open_container() != 0 && target.reagents) - if(!target.reagents.total_volume) + if(target.is_refillable()) + if(target.is_drainable() && !target.reagents.total_volume) to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") return + + if(target.reagents.holder_full()) + to_chat(user, "[target] is full.") + return + to_chat(user, "You dissolve [src] in [target].") for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius to_chat(O, "[user] slips something into [target]!") diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 789345ca77..f8158ba948 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -7,7 +7,7 @@ lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = SLOT_BELT throwforce = 0 w_class = WEIGHT_CLASS_SMALL @@ -23,17 +23,17 @@ possible_transfer_amounts = list(5,10,15,20,25,30,50,100) -/obj/item/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user) +/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user) if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) return - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution - if(!A.reagents.total_volume && A.reagents) - to_chat(user, "\The [A] is empty.") + if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1) + if(!A.reagents.total_volume) + to_chat(user, "[A] is empty.") return - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") + if(reagents.holder_full()) + to_chat(user, "[src] is full.") return var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill @@ -41,7 +41,7 @@ return if(reagents.total_volume < amount_per_transfer_from_this) - to_chat(user, "\The [src] is empty!") + to_chat(user, "[src] is empty!") return spray(A) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 87fb2b8a9e..17a671569f 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -13,7 +13,7 @@ var/busy = FALSE // needed for delayed drawing of blood var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun materials = list(MAT_METAL=10, MAT_GLASS=20) - container_type = TRANSPARENT_1 + container_type = TRANSPARENT /obj/item/reagent_containers/syringe/Initialize() . = ..() @@ -107,11 +107,8 @@ update_icon() if(SYRINGE_INJECT) - //Always log attemped injections for admins - var/list/rinject = list() - for(var/datum/reagent/R in reagents.reagent_list) - rinject += R.name - var/contained = english_list(rinject) + // Always log attemped injections for admins + var/contained = reagents.log_list() add_logs(user, L, "attemped to inject", src, addition="which had [contained]") if(!reagents.total_volume) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index ea80f4c508..f0c0ecfb68 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -5,7 +5,7 @@ icon_state = "water" density = TRUE anchored = FALSE - container_type = DRAWABLE_1 + container_type = DRAINABLE | AMOUNT_VISIBLE pressure_resistance = 2*ONE_ATMOSPHERE max_integrity = 300 var/tank_volume = 1000 //In units, how much the dispenser can hold @@ -18,7 +18,7 @@ boom() /obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers)) + if(W.is_refillable()) return 0 //so we can refill them via their afterattack. else return ..() @@ -28,14 +28,6 @@ reagents.add_reagent(reagent_id, tank_volume) . = ..() -/obj/structure/reagent_dispensers/examine(mob/user) - ..() - if(reagents.total_volume) - to_chat(user, "It has [reagents.total_volume] unit\s left.") - else - to_chat(user, "It's empty.") - - /obj/structure/reagent_dispensers/proc/boom() visible_message("\The [src] ruptures!") chem_splash(loc, 5, list(reagents)) diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index a66fdf7e03..26fa304209 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -8,7 +8,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). name = "circuit imprinter" desc = "Manufactures circuit boards for the construction of machines." icon_state = "circuit_imprinter" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/circuit_imprinter var/efficiency_coeff diff --git a/code/modules/research/departmental_circuit_imprinter.dm b/code/modules/research/departmental_circuit_imprinter.dm index bd3414884f..991feccb66 100644 --- a/code/modules/research/departmental_circuit_imprinter.dm +++ b/code/modules/research/departmental_circuit_imprinter.dm @@ -2,7 +2,7 @@ name = "Department Circuit Imprinter" desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" icon_state = "circuit_imprinter" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/circuit_imprinter/department console_link = FALSE requires_console = FALSE diff --git a/code/modules/research/departmental_lathe.dm b/code/modules/research/departmental_lathe.dm index 2e534195d9..83f543e4cb 100644 --- a/code/modules/research/departmental_lathe.dm +++ b/code/modules/research/departmental_lathe.dm @@ -2,7 +2,7 @@ name = "department protolathe" desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" icon_state = "protolathe" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/protolathe/department console_link = FALSE requires_console = FALSE diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 6c52fd4678..f76ff1c7ff 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -11,7 +11,7 @@ Note: Must be placed west/left of and R&D console to function. name = "protolathe" desc = "Converts raw materials into useful objects." icon_state = "protolathe" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/protolathe var/efficiency_coeff diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index ad75ddf07b..61b06d356e 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -59,7 +59,7 @@ return if(default_deconstruction_crowbar(O)) return - if(is_open_container() && O.is_open_container()) + if(is_refillable() && O.is_drainable()) return FALSE //inserting reagents into the machine if(Insert_Item(O, user)) return TRUE diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 7d8ff00e91..ae0e8f5c5e 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -11,7 +11,7 @@ throwforce = 0 throw_speed = 3 throw_range = 6 - container_type = INJECTABLE_1 + container_type = INJECTABLE | DRAWABLE grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions From 4e5671960d7231c1cce1743e5e98cf64621864d8 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 19 Dec 2017 11:56:09 -0200 Subject: [PATCH 107/213] Merge pull request #33651 from coiax/absorb-language Changelings learn languages from people they absorb --- code/game/gamemodes/changeling/powers/absorb.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 4584dc5a67..56003d91eb 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -58,6 +58,8 @@ user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) if(target.mind)//if the victim has got a mind + // Absorb a lizard, speak Draconic. + user.copy_known_languages_from(target) target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. From 65412db421d2f5272aeeff2dc9d8f785c45db919 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Tue, 19 Dec 2017 14:34:06 -0500 Subject: [PATCH 109/213] Update game_options.dm --- code/controllers/configuration/entries/game_options.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 4fa6133883..2d96e3c64b 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -243,9 +243,13 @@ value = 14 min_val = 4 -CONFIG_DEF(flag/allow_crew_objectives) -CONFIG_DEF(flag/allow_miscreants) -CONFIG_DEF(flag/allow_extended_miscreants) +//Cit changes - Adds config options for crew objectives and miscreants +/datum/config_entry/flag/allow_crew_objectives + +/datum/config_entry/flag/allow_miscreants + +/datum/config_entry/flag/allow_extended_miscreants +//End of Cit changes /datum/config_entry/number/bombcap/ValidateAndSet(str_val) . = ..() From edbe78cce846c8cefb82b8e17bc7593a36ef85e1 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 19 Dec 2017 13:49:34 -0600 Subject: [PATCH 110/213] Automatic changelog generation for PR #4382 [ci skip] --- html/changelogs/AutoChangeLog-pr-4382.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4382.yml diff --git a/html/changelogs/AutoChangeLog-pr-4382.yml b/html/changelogs/AutoChangeLog-pr-4382.yml new file mode 100644 index 0000000000..64568eb274 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4382.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - config: "Added \"$include\" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it" From 30e8b2a12da7c40da4eb64737d4c2ce1c52acd65 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 19 Dec 2017 15:30:19 -0500 Subject: [PATCH 111/213] Merge pull request #33683 from AnturK/getcommandfix Fixes get admin command --- code/game/atoms_movable.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 121ac00f1d..ddb768488a 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -516,7 +516,7 @@ . = ..() . -= "Jump to" .["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]" - .["Get"] = "?_src=holder;[HrefToken()];admingetmovable=[REF(src)]" + .["Get"] = "?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]" /atom/movable/proc/ex_check(ex_id) if(!ex_id) From d59e85e2144501beebb7782eef280db4d704f8a6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:20:39 -0600 Subject: [PATCH 113/213] Update weldingtool.dm --- code/game/objects/items/tools/weldingtool.dm | 393 ++----------------- 1 file changed, 26 insertions(+), 367 deletions(-) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index a09f0d2a1a..12c056c9af 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD #define WELDER_FUEL_BURN_INTERVAL 13 /obj/item/weldingtool name = "welding tool" @@ -22,7 +21,7 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) resistance_flags = FIRE_PROOF - materials = list(MAT_METAL=70, MAT_GLASS=30) + materials = list(MAT_METAL=70, MAT_GLASS=30) var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -52,7 +51,7 @@ cut_overlays() if(change_icons) var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)][ratio]") update_torch() return @@ -90,18 +89,15 @@ flamethrower_screwdriver(I, user) else if(istype(I, /obj/item/stack/rods)) flamethrower_rods(I, user) - else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) - var/amountNeeded = max_fuel - get_fuel() - var/obj/item/reagent_containers/container = I - if(length(container.reagents.reagent_list) > 1) - to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") - return ..() - if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) - container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) - to_chat(user, "You transfer some fuel from [container] to [src].") else - return ..() + . = ..() + update_icon() +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) @@ -124,7 +120,10 @@ /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) if(!proximity) return - + if(!status && O.is_refillable()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() if(welding) remove_fuel(1) var/turf/location = get_turf(user) @@ -140,6 +139,9 @@ /obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() switched_on(user) if(welding) set_light(light_intensity) @@ -235,9 +237,11 @@ return status = !status if(status) - to_chat(user, "You resecure [src].") + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE else - to_chat(user, "[src] can now be attached and modified.") + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) @@ -265,7 +269,7 @@ desc = "A slightly larger welder with a larger tank." icon_state = "indwelder" max_fuel = 40 - materials = list(MAT_GLASS=60) + materials = list(MAT_GLASS=60) /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -295,7 +299,7 @@ icon_state = "welder" toolspeed = 0.1 light_intensity = 0 - change_icons = 0 + change_icons = 0 /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -308,7 +312,7 @@ icon_state = "upindwelder" item_state = "upindwelder" max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -316,7 +320,7 @@ icon_state = "exwelder" item_state = "exwelder" max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -337,350 +341,5 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) -======= -#define WELDER_FUEL_BURN_INTERVAL 13 -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = CEILING(ratio*4, 1) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - . = ..() - update_icon() - -/obj/item/weldingtool/proc/explode() - var/turf/T = get_turf(loc) - var/plasmaAmount = reagents.get_reagent_amount("plasma") - dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder - qdel(src) - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) - return - if(!status && O.is_refillable()) - reagents.trans_to(O, reagents.total_volume) - to_chat(user, "You empty [src]'s fuel tank into [O].") - update_icon() - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - if(src.reagents.has_reagent("plasma")) - message_admins("[key_name_admin(user)] activated a rigged welder.") - explode() - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src] and close the fuel tank.") - container_type = NONE - else - to_chat(user, "[src] can now be attached, modified, and refuelled.") - container_type = OPENCONTAINER - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - ->>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) -#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file + +#undef WELDER_FUEL_BURN_INTERVAL From 063854e2d02af928adb3a7ad8ea5e1450b33eb7a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:28:37 -0600 Subject: [PATCH 114/213] Update aphasia.dm --- code/modules/language/aphasia.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/language/aphasia.dm b/code/modules/language/aphasia.dm index 91f14f9111..070a792ecd 100644 --- a/code/modules/language/aphasia.dm +++ b/code/modules/language/aphasia.dm @@ -5,7 +5,7 @@ ask_verb = "mumbles" whisper_verb = "mutters" exclaim_verb = "screams incoherently" - flags = LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + flags_1 = LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD key = "i" syllables = list("m","n","gh","h","l","s","r","a","e","i","o","u") space_chance = 20 From a8db6dc9c2657ff22088c7a9ba26fd9c86de3d5e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:29:36 -0600 Subject: [PATCH 115/213] Update mop_bucket.dm --- code/game/objects/structures/mop_bucket.dm | 32 ++++------------------ 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 43da5073ed..d468e87a34 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -1,28 +1,9 @@ -/obj/structure/mopbucket - name = "mop bucket" - desc = "Fill it with water, but don't forget a mop!" - icon = 'icons/obj/janitor.dmi' - icon_state = "mopbucket" +/obj/structure/mopbucket + name = "mop bucket" + desc = "Fill it with water, but don't forget a mop!" + icon = 'icons/obj/janitor.dmi' + icon_state = "mopbucket" density = TRUE -<<<<<<< HEAD - container_type = OPENCONTAINER_1 - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - - -/obj/structure/mopbucket/New() - create_reagents(100) - ..() - -/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mop)) - if(reagents.total_volume < 1) - to_chat(user, "[src] is out of water!") - else - reagents.trans_to(I, 5) - to_chat(user, "You wet [I] in [src].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - else -======= container_type = OPENCONTAINER var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite @@ -40,5 +21,4 @@ to_chat(user, "You wet [I] in [src].") playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else ->>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) - return ..() \ No newline at end of file + return ..() From b46275079e30e6530f82ea4f704d65cd5528c7e5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:29:45 -0600 Subject: [PATCH 116/213] Update ammo_casings.dm --- code/modules/projectiles/ammunition/ammo_casings.dm | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index d3ca08dc85..edd28e72a8 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -284,15 +284,9 @@ icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/dart -<<<<<<< HEAD -/obj/item/ammo_casing/shotgun/dart/New() - ..() - container_type |= OPENCONTAINER_1 -======= /obj/item/ammo_casing/shotgun/dart/Initialize() . = ..() container_type |= OPENCONTAINER ->>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) create_reagents(30) reagents.set_reacting(TRUE) @@ -308,4 +302,4 @@ reagents.add_reagent("spore", 6) reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT reagents.add_reagent("coniine", 6) - reagents.add_reagent("sodium_thiopental", 6) \ No newline at end of file + reagents.add_reagent("sodium_thiopental", 6) From 1b9d60c604109f136d892f1a631365466d66e9c1 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:29:55 -0600 Subject: [PATCH 117/213] Update reagent_containers.dm --- code/modules/reagents/reagent_containers.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 842d2dc2c3..2645997d22 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -118,11 +118,5 @@ reagents.clear_reagents() /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) -<<<<<<< HEAD - if(is_open_container()) - reagents.chem_temp = max(reagents.chem_temp, 1000) - reagents.handle_reactions() -======= reagents.expose_temperature(1000) ->>>>>>> 40699a8... [READY]Refactors reagent container types (#33470) ..() From 678762209a047cfce5b5c66621ea7e13b617b61c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:33:31 -0600 Subject: [PATCH 118/213] Update ticker.dm --- code/controllers/subsystem/ticker.dm | 201 --------------------------- 1 file changed, 201 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index f178a1bd24..0f06caa20d 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -398,207 +398,6 @@ SUBSYSTEM_DEF(ticker) var/mob/living/L = I L.notransform = FALSE -<<<<<<< HEAD -/datum/controller/subsystem/ticker/proc/declare_completion() - set waitfor = FALSE - var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED - var/num_survivors = 0 - var/num_escapees = 0 - var/num_shuttle_escapees = 0 - var/list/successfulCrew = list() - var/list/miscreants = list() - - to_chat(world, "


    The round has ended.") - if(LAZYLEN(GLOB.round_end_notifiees)) - send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") - -/* var/nocredits = config.no_credits_round_end - for(var/client/C in GLOB.clients) - if(!C.credits && !nocredits) - C.RollCredits() - C.playtitlemusic(40)*/ - - //Player status report - for(var/i in GLOB.mob_list) - var/mob/Player = i - if(Player.mind && !isnewplayer(Player)) - if(Player.stat != DEAD && !isbrain(Player)) - num_survivors++ - if(station_evacuated) //If the shuttle has already left the station - var/list/area/shuttle_areas - if(SSshuttle && SSshuttle.emergency) - shuttle_areas = SSshuttle.emergency.shuttle_areas - if(!Player.onCentCom() && !Player.onSyndieBase()) - to_chat(Player, "You managed to survive, but were marooned on [station_name()]...") - else - num_escapees++ - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - if(shuttle_areas[get_area(Player)]) - num_shuttle_escapees++ - else - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - else - to_chat(Player, "You did not survive the events on [station_name()]...") - - CHECK_TICK - - //Round statistics report - var/datum/station_state/end_state = new /datum/station_state() - end_state.count() - var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) - - to_chat(world, "
    [GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]") - to_chat(world, "
    [GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]") - if(mode.station_was_nuked) - SSticker.news_report = STATION_DESTROYED_NUKE - var/total_players = GLOB.joined_player_list.len - if(total_players) - to_chat(world, "
    [GLOB.TAB]Total Population: [total_players]") - if(station_evacuated) - to_chat(world, "
    [GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)") - to_chat(world, "
    [GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)") - news_report = STATION_EVACUATED - if(SSshuttle.emergency.is_hijacked()) - news_report = SHUTTLE_HIJACK - to_chat(world, "
    [GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)") - to_chat(world, "
    ") - - CHECK_TICK - - //Silicon laws report - for (var/i in GLOB.ai_list) - var/mob/living/silicon/ai/aiPlayer = i - if (aiPlayer.stat != DEAD && aiPlayer.mind) - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:") - aiPlayer.show_laws(1) - else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:") - aiPlayer.show_laws(1) - - to_chat(world, "Total law changes: [aiPlayer.law_change_counter]") - - if (aiPlayer.connected_robots.len) - var/robolist = "[aiPlayer.real_name]'s minions were: " - for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) - if(robo.mind) - robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" - to_chat(world, "[robolist]") - - CHECK_TICK - - for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) - if (!robo.connected_ai && robo.mind) - if (robo.stat != DEAD) - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:") - else - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:") - - if(robo) //How the hell do we lose robo between here and the world messages directly above this? - robo.laws.show_laws(world) - - CHECK_TICK - - mode.declare_completion()//To declare normal completion. - - CHECK_TICK - - //calls auto_declare_completion_* for all modes - for(var/handler in typesof(/datum/game_mode/proc)) - if (findtext("[handler]","auto_declare_completion_")) - call(mode, handler)(force_ending) - - CHECK_TICK - - if(CONFIG_GET(string/cross_server_address)) - send_news_report() - - CHECK_TICK - - //Print a list of antagonists to the server log - var/list/total_antagonists = list() - //Look into all mobs in world, dead or alive - for(var/datum/mind/Mind in minds) - var/temprole = Mind.special_role - if(temprole) //if they are an antagonist of some sort. - if(temprole in total_antagonists) //If the role exists already, add the name to it - total_antagonists[temprole] += ", [Mind.name]([Mind.key])" - else - total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob - total_antagonists[temprole] += ": [Mind.name]([Mind.key])" - - CHECK_TICK - - //Now print them all into the log! - log_game("Antagonists at round end were...") - for(var/i in total_antagonists) - log_game("[i]s[total_antagonists[i]].") - - CHECK_TICK - - for(var/datum/mind/crewMind in minds) - if(!crewMind.current || !crewMind.objectives.len) - continue - for(var/datum/objective/miscreant/MO in crewMind.objectives) - miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
    Objective: [MO.explanation_text] (Optional)" - for(var/datum/objective/crew/CO in crewMind.objectives) - if(CO.check_completion()) - to_chat(crewMind.current, "
    Your optional objective: [CO.explanation_text] Success!") - successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
    Objective: [CO.explanation_text] Success! (Optional)" - else - to_chat(crewMind.current, "
    Your optional objective: [CO.explanation_text] Failed.") - - if (successfulCrew.len) - var/completedObjectives = "The following crew members completed their Crew Objectives:
    " - for(var/i in successfulCrew) - completedObjectives += "[i]
    " - to_chat(world, "[completedObjectives]
    ") - else - if(CONFIG_GET(flag/allow_crew_objectives)) - to_chat(world, "Nobody completed their Crew Objectives!
    ") - - CHECK_TICK - - if (miscreants.len) - var/miscreantObjectives = "The following crew members were miscreants:
    " - for(var/i in miscreants) - miscreantObjectives += "[i]
    " - to_chat(world, "[miscreantObjectives]
    ") - - CHECK_TICK - - mode.declare_station_goal_completion() - - CHECK_TICK - //medals, placed far down so that people can actually see the commendations. - if(GLOB.commendations.len) - to_chat(world, "Medal Commendations:") - for (var/com in GLOB.commendations) - to_chat(world, com) - - CHECK_TICK - - //Collects persistence features - if(mode.allow_persistence_save) - SSpersistence.CollectData() - - //stop collecting feedback during grifftime - SSblackbox.Seal() - - sleep(50) - ready_for_reboot = TRUE - standard_reboot() - -/datum/controller/subsystem/ticker/proc/standard_reboot() - if(ready_for_reboot) - if(mode.station_was_nuked) - Reboot("Station destroyed by Nuclear Device.", "nuke") - else - Reboot("Round ended.", "proper completion") - else - CRASH("Attempted standard reboot without ticker roundend completion") - -======= ->>>>>>> 3d81385... Roundend report refactor (#33246) /datum/controller/subsystem/ticker/proc/send_tip_of_the_round() var/m if(selected_tip) From 98d752fe215851f39f7db700dac8248f59651f43 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:34:27 -0600 Subject: [PATCH 119/213] Update traitor_bro.dm --- code/game/gamemodes/brother/traitor_bro.dm | 35 ---------------------- 1 file changed, 35 deletions(-) diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index 34373da5c8..978f871ba2 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -62,41 +62,6 @@ /datum/game_mode/traitor/bros/generate_report() return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." -<<<<<<< HEAD -/datum/game_mode/proc/auto_declare_completion_brother() - if(!LAZYLEN(brother_teams)) - return - var/text = "
    The blood brothers were:" - var/teamnumber = 1 - for(var/datum/objective_team/brother_team/team in brother_teams) - if(!team.members.len) - continue - text += "
    Team #[teamnumber++]" - for(var/datum/mind/M in team.members) - text += printplayer(M) - var/win = TRUE - var/objective_count = 1 - for(var/datum/objective/objective in team.objectives) - if(objective.check_completion()) - text += "
    Objective #[objective_count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[objective_count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - win = FALSE - objective_count++ - if(win) - text += "
    The blood brothers were successful!" - SSblackbox.record_feedback("tally", "brother_success", 1, "SUCCESS") - else - text += "
    The blood brothers have failed!" - SSblackbox.record_feedback("tally", "brother_success", 1, "FAIL") - text += "
    " - to_chat(world, text) - -======= ->>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] brotherhud.join_hud(brother_mind.current) From cb8c6cd5e2484365c55d6134a384fd513ebdb182 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:34:38 -0600 Subject: [PATCH 120/213] Update changeling.dm --- code/game/gamemodes/changeling/changeling.dm | 44 -------------------- 1 file changed, 44 deletions(-) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 6fc06f7bca..ad76d41d47 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -94,50 +94,6 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ as paranoia may spread and inhibit workplace efficiency." -<<<<<<< HEAD -/datum/game_mode/proc/auto_declare_completion_changeling() - var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention - if(changelings.len) - var/text = "
    The changelings were:" - for(var/datum/mind/changeling in changelings) - var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling) - var/changelingwin = 1 - if(!changeling.current) - changelingwin = 0 - - text += printplayer(changeling) - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - text += "
    Changeling ID: [ling.changelingID]." - text += "
    Genomes Extracted: [ling.absorbedcount]" - - if(changeling.objectives.len) - var/count = 1 - for(var/datum/objective/objective in changeling.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - changelingwin = 0 - count++ - - if(changelingwin) - text += "
    The changeling was successful!" - SSblackbox.record_feedback("tally", "changeling_success", 1, "SUCCESS") - else - text += "
    The changeling has failed." - SSblackbox.record_feedback("tally", "changeling_success", 1, "FAIL") - text += "
    " - - to_chat(world, text) - - return 1 - -======= ->>>>>>> 3d81385... Roundend report refactor (#33246) /proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name From 61c7080c34e5c5490228a6bc763c444f3ed58bfd Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:34:59 -0600 Subject: [PATCH 121/213] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 0c6a8fd1e0..71824c4590 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -450,8 +450,6 @@ /datum/game_mode/proc/OnNukeExplosion(off_station) if(off_station < 2) station_was_nuked = TRUE //Will end the round on next check. -<<<<<<< HEAD -======= //Additional report section in roundend report /datum/game_mode/proc/special_report() @@ -466,4 +464,3 @@ SSticker.news_report = STATION_EVACUATED if(SSshuttle.emergency.is_hijacked()) SSticker.news_report = SHUTTLE_HIJACK ->>>>>>> 3d81385... Roundend report refactor (#33246) From 2d65e0df49aed7715aec38161214e9bb24127913 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:35:29 -0600 Subject: [PATCH 122/213] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 127 ------------------------- 1 file changed, 127 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index c7fc1bfdc8..a6eb199322 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -171,88 +171,6 @@ return FALSE //its a static var btw ..() -<<<<<<< HEAD -/datum/game_mode/nuclear/declare_completion() - var/disk_rescued = 1 - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - disk_rescued = 0 - break - var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - to_chat(world, "Humiliating Syndicate Defeat") - to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") - - SSticker.news_report = NUKE_SYNDICATE_BASE - - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - SSticker.mode_result = "win - syndicate nuke" - to_chat(world, "Syndicate Major Victory!") - to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - to_chat(world, "Total Annihilation") - to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station" - to_chat(world, "Crew Minor Victory") - to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") - to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - to_chat(world, "Crew Major Victory!") - to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") - - SSticker.news_report = OPERATIVES_KILLED - - else if (disk_rescued) - SSticker.mode_result = "loss - evacuation - disk secured" - to_chat(world, "Crew Major Victory") - to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVES_KILLED - - else if (!disk_rescued && are_operatives_dead()) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - to_chat(world, "Neutral Victory!") - to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && crew_evacuated) - SSticker.mode_result = "halfwin - detonation averted" - to_chat(world, "Syndicate Minor Victory!") - to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && !crew_evacuated) - SSticker.mode_result = "halfwin - interrupted" - to_chat(world, "Neutral Victory") - to_chat(world, "Round was mysteriously interrupted!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - ..() - return -======= /datum/game_mode/nuclear/set_round_result() var result = nuke_team.get_result() switch(result) @@ -287,57 +205,12 @@ SSticker.mode_result = "halfwin - interrupted" SSticker.news_report = OPERATIVE_SKIRMISH return ..() ->>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." -<<<<<<< HEAD -/datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) - var/text = "
    The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/datum/mind/syndicate in syndicates) - text += printplayer(syndicate) - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H.purchase_log) - purchases += H.purchase_log.generate_render() - else - stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") - text += "
    " - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - to_chat(world, text) - return TRUE - - -/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(GLOB.last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - to_chat(M, "That name is reserved.") - return nukelastname(M) - - return capitalize(newname) - -/proc/NukeNameAssign(lastname,list/syndicates) - for(var/datum/mind/synd_mind in syndicates) - var/mob/living/carbon/human/H = synd_mind.current - synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) - synd_mind.current.real_name = synd_mind.name - return - -======= ->>>>>>> 3d81385... Roundend report refactor (#33246) /proc/is_nuclear_operative(mob/M) return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates From a30de42820db062adab30126aee731ffa5e55f7c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:35:45 -0600 Subject: [PATCH 123/213] Update traitor.dm --- code/game/gamemodes/traitor/traitor.dm | 72 -------------------------- 1 file changed, 72 deletions(-) diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 468725074d..42c96cb5c0 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -86,78 +86,6 @@ new_antag.should_specialise = TRUE character.add_antag_datum(new_antag) -<<<<<<< HEAD - - -/datum/game_mode/traitor/declare_completion() - ..() - return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder. - - -/datum/game_mode/proc/auto_declare_completion_traitor() - if(traitors.len) - var/text = "
    The [traitor_name]s were:" - for(var/datum/mind/traitor in traitors) - var/traitorwin = TRUE - - text += printplayer(traitor) - - var/TC_uses = 0 - var/uplink_true = FALSE - var/purchases = "" - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H && H.owner && H.owner == traitor.key) - TC_uses += H.spent_telecrystals - uplink_true = TRUE - purchases += H.purchase_log.generate_render(FALSE) - - var/objectives = "" - if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in traitor.objectives) - if(objective.check_completion()) - objectives += "
    Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - objectives += "
    Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - traitorwin = FALSE - count++ - - if(uplink_true) - text += " (used [TC_uses] TC) [purchases]" - if(TC_uses==0 && traitorwin) - var/static/icon/badass = icon('icons/badass.dmi', "badass") - text += "[icon2html(badass, world)]" - - text += objectives - - var/special_role_text - if(traitor.special_role) - special_role_text = lowertext(traitor.special_role) - else - special_role_text = "antagonist" - - - if(traitorwin) - text += "
    The [special_role_text] was successful!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "SUCCESS") - else - text += "
    The [special_role_text] has failed!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "FAIL") - SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg') - - text += "
    " - - text += "
    The code phrases were: [GLOB.syndicate_code_phrase]
    \ - The code responses were: [GLOB.syndicate_code_response]
    " - to_chat(world, text) - - return TRUE - -======= ->>>>>>> 3d81385... Roundend report refactor (#33246) /datum/game_mode/traitor/generate_report() return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." From 7d193a530322b0ea2d3755b5441450d5ff244a8d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:35:57 -0600 Subject: [PATCH 124/213] Update wizard.dm --- code/game/gamemodes/wizard/wizard.dm | 45 ---------------------------- 1 file changed, 45 deletions(-) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 6dd38e9d58..0d9655ae8e 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -64,54 +64,9 @@ SSticker.mode_result = "loss - wizard killed" SSticker.news_report = WIZARD_KILLED -<<<<<<< HEAD - for(var/datum/mind/wizard in wizards) - - text += "
    [wizard.key] was [wizard.name] (" - if(wizard.current) - if(wizard.current.stat == DEAD) - text += "died" - else - text += "survived" - if(wizard.current.real_name != wizard.name) - text += " as [wizard.current.real_name]" - else - text += "body destroyed" - text += ")" - - var/count = 1 - var/wizardwin = 1 - for(var/datum/objective/objective in wizard.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - wizardwin = 0 - count++ - - if(wizard.current && wizardwin) - text += "
    The wizard was successful!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "SUCCESS") - else - text += "
    The wizard has failed!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "FAIL") - if(wizard.spell_list.len>0) - text += "
    [wizard.name] used the following spells: " - var/i = 1 - for(var/obj/effect/proc_holder/spell/S in wizard.spell_list) - text += "[S.name]" - if(wizard.spell_list.len > i) - text += ", " - i++ - text += "
    " -======= /datum/game_mode/wizard/special_report() if(finished) return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" ->>>>>>> 3d81385... Roundend report refactor (#33246) //returns whether the mob is a wizard (or apprentice) /proc/iswizard(mob/living/M) From 5ed003a0f5c80bafe74db8b1746e559ea4f31e00 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 15:36:07 -0600 Subject: [PATCH 125/213] Update client_defines.dm --- code/modules/client/client_defines.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index a7e3b20e7a..10d3866672 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -68,9 +68,6 @@ var/datum/chatOutput/chatOutput -<<<<<<< HEAD -======= var/list/credits //lazy list of all credit object bound to this client var/datum/player_details/player_details //these persist between logins/logouts during the same round. ->>>>>>> 3d81385... Roundend report refactor (#33246) From 16f1a07b9228aceda04f1b875179d8f7a870ccba Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 16:41:09 -0600 Subject: [PATCH 126/213] diseases --- code/modules/events/disease_outbreak.dm | 68 ++++++++++++++++++++----- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index eb7625e08c..8f8ad97c0e 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -10,22 +10,30 @@ var/virus_type + var/max_severity = 3 -/datum/round_event/disease_outbreak/announce(fake) + +/datum/round_event/disease_outbreak/announce() priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') /datum/round_event/disease_outbreak/setup() announceWhen = rand(15, 30) + /datum/round_event/disease_outbreak/start() - if(!virus_type) + var/advanced_virus = FALSE + max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + if(prob(20 + (10 * max_severity))) + advanced_virus = TRUE + + if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) - for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) var/turf/T = get_turf(H) if(!T) continue - if(!(T.z in GLOB.station_z_levels)) + if(T.z != ZLEVEL_STATION) continue if(!H.client) continue @@ -41,16 +49,48 @@ continue var/datum/disease/D - if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. - continue - D = new virus_type() - var/datum/disease/dnaspread/DS = D - DS.strain_data["name"] = H.real_name - DS.strain_data["UI"] = H.dna.uni_identity - DS.strain_data["SE"] = H.dna.struc_enzymes + if(!advanced_virus) + if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. + continue + D = new virus_type() + var/datum/disease/dnaspread/DS = D + DS.strain_data["name"] = H.real_name + DS.strain_data["UI"] = H.dna.uni_identity + DS.strain_data["SE"] = H.dna.struc_enzymes + else + D = new virus_type() else - D = new virus_type() + D = make_virus(max_severity, max_severity) D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + + if(advanced_virus) + var/datum/disease/advance/A = D + var/list/name_symptoms = list() //for feedback + for(var/datum/symptom/S in A.symptoms) + name_symptoms += S.name + message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]") + log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]") + break + +/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level) + if(max_symptoms > SYMPTOM_LIMIT) + max_symptoms = SYMPTOM_LIMIT + var/datum/disease/advance/A = new(FALSE, null) + A.symptoms = list() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A From 516db4851fac58836d26a3409150e1dd78ce65b6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 16:53:21 -0600 Subject: [PATCH 127/213] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 8f8ad97c0e..01f5c007cd 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -29,11 +29,11 @@ if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) - 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)) var/turf/T = get_turf(H) if(!T) continue - if(T.z != ZLEVEL_STATION) + if(T.z != ZLEVEL_STATION_PRIMARY) continue if(!H.client) continue From a59b693555456852e0e95915e79eebf238f68980 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 19 Dec 2017 17:01:56 -0600 Subject: [PATCH 128/213] Automatic changelog generation for PR #4458 [ci skip] --- html/changelogs/AutoChangeLog-pr-4458.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4458.yml diff --git a/html/changelogs/AutoChangeLog-pr-4458.yml b/html/changelogs/AutoChangeLog-pr-4458.yml new file mode 100644 index 0000000000..4e51890691 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4458.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "The Disease Outbreak event now can generate random advanced viruses, with more symptoms and higher level as round time goes on." From 0a05b499fd26f2e95257b89c919cd2293b085657 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:14:57 -0600 Subject: [PATCH 129/213] Update cleanable.dm --- code/game/objects/effects/decals/cleanable.dm | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0e0c7c606e..031e5059b3 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -46,11 +46,8 @@ if(istype(W, /obj/item/clothing/mask/cigarette)) return else - var/hotness = W.is_hot() - var/added_heat = (hotness / 100) - src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness) - src.reagents.handle_reactions() - to_chat(user, "You heat [src] with [W]!") + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [W]!") else return ..() @@ -62,8 +59,7 @@ /obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume) if(reagents) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() From 5e0ddfce60ae9d6aefa090f87977c36ffa071eae Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:15:37 -0600 Subject: [PATCH 130/213] Update drinks.dm --- code/modules/food_and_drinks/drinks/drinks.dm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index c03b183ecc..5eae2b80d8 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -94,12 +94,10 @@ else /obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params) - if(I.is_hot()) - var/added_heat = (I.is_hot() / 100) //ishot returns a temperature - if(reagents) - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") ..() /obj/item/reagent_containers/food/drinks/throw_impact(atom/target, mob/thrower) From 9e452adcc83c25ee9decc8412c0a49f051699e07 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:16:45 -0600 Subject: [PATCH 131/213] Update holder.dm --- code/modules/reagents/chemistry/holder.dm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 5958dc0eab..737e07c2a8 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -241,8 +241,7 @@ var/list/cached_reagents = reagent_list var/list/cached_addictions = addiction_list if(C) - chem_temp = C.bodytemperature - handle_reactions() + expose_temperature(C.bodytemperature, 0.25) var/need_mob_update = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent @@ -744,6 +743,16 @@ out += "[taste_desc]" return english_list(out, "something indescribable") + + +/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02) + var/temp_delta = (temperature - chem_temp) * coeff + if(temp_delta > 0) + chem_temp = min(chem_temp + max(temp_delta, 1), temperature) + else + chem_temp = max(chem_temp + min(temp_delta, -1), temperature) + chem_temp = round(chem_temp) + handle_reactions() /////////////////////////////////////////////////////////////////////////////////// From 39b016306cf60c4662036d0f1828b6103330c162 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:17:54 -0600 Subject: [PATCH 132/213] Update reagent_containers.dm --- code/modules/reagents/reagent_containers.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 2645997d22..6fb21e847b 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -71,8 +71,7 @@ ..() /obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() /obj/item/reagent_containers/throw_impact(atom/target) @@ -120,3 +119,6 @@ /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) reagents.expose_temperature(1000) ..() + +/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + reagents.expose_temperature(exposed_temperature) From fdfdaa230a55509f8b2b0b06f3c982222e6d1d29 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:18:27 -0600 Subject: [PATCH 133/213] Update glass.dm --- code/modules/reagents/reagent_containers/glass.dm | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 33a45fd27b..06a242cca9 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -89,15 +89,9 @@ /obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params) var/hotness = I.is_hot() - if(hotness) - var/added_heat = (hotness / 100) //ishot returns a temperature - if(reagents) - if(reagents.chem_temp < hotness) //can't be heated to be hotter than the source - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() - else - to_chat(user, "[src] is already hotter than [I]!") + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs var/obj/item/reagent_containers/food/snacks/egg/E = I @@ -403,4 +397,4 @@ /obj/item/reagent_containers/glass/beaker/large/bromine name = "bromine beaker" - list_reagents = list("bromine" = 50) \ No newline at end of file + list_reagents = list("bromine" = 50) From 349b0f4f20f100f441d63256897215b7513da887 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:19:05 -0600 Subject: [PATCH 134/213] Update spray.dm --- code/modules/reagents/reagent_containers/spray.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index f8158ba948..2e34e39f8f 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -123,6 +123,14 @@ current_range = spray_range to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.") +/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params) + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") + return ..() + + /obj/item/reagent_containers/spray/verb/empty() set name = "Empty Spray Bottle" set category = "Object" From a0a4acbc2c9f8d21b828d27262d7d7cdcaab6b8b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:33:55 -0600 Subject: [PATCH 135/213] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 153 +++++-------------------- 1 file changed, 31 insertions(+), 122 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index a6eb199322..f131046cac 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,7 +1,3 @@ -/datum/game_mode - var/list/datum/mind/syndicates = list() - var/nukeops_lastname = "" - /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -18,12 +14,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/list/pre_nukeops = list() + var/datum/team/nuclear/nuke_team + /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) for(var/i = 0, i < n_agents, ++i) @@ -33,120 +28,23 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(synd_mind.current) - set_antag_hud(synd_mind.current, "synd") - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(synd_mind.current) - set_antag_hud(synd_mind.current, null) - //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - var/nuke_code = random_nukecode() - var/agent_number = 1 - var/datum/mind/leader = pick(pre_nukeops) - syndicates += pre_nukeops - for(var/i = 1 to pre_nukeops.len) - var/datum/mind/op = pre_nukeops[i] - - forge_syndicate_objectives(op) - greet_syndicate(op) - equip_syndicate(op.current) - - if(nuke_code) - op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(op.current, "The nuclear authorization code is: [nuke_code]") - - if(op == leader) - op.current.forceMove(pick(GLOB.nukeop_leader_start)) - prepare_syndicate_leader(op, nuke_code) - else - op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) - op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" - - update_synd_icons_added(op) - op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code + //Assign leader + var/datum/mind/leader_mind = pre_nukeops[1] + var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = L.nuke_team + //Assign the remaining operatives + for(var/i = 2 to pre_nukeops.len) + var/datum/mind/nuke_mind = pre_nukeops[i] + nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return ..() -/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) - var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) - synd_mind.current.real_name = "[syndicate_name()] [leader_title]" - to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - - var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands(challenge, TRUE) - - var/static/id_cache = typecacheof(/obj/item/card/id) - var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) - if(foundIDs.len) - for(var/i in 1 to foundIDs.len) - var/obj/item/card/id/ID = foundIDs[i] - ID.name = "lead agent card" - ID.access += ACCESS_SYNDICATE_LEADER - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") - - var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current - if(A) - A.command = TRUE - - if(nuke_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = synd_mind.current - H.put_in_hands(P, TRUE) - H.update_icons() - else - nuke_code = "code will be provided later" - return - -/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname, syndicates) - - -/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - - -/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if(you_are) - to_chat(syndicate.current, "You are a [syndicate_name()] agent!") - syndicate.announce_objectives() - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) - synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - if(telecrystals) - synd_mob.equipOutfit(/datum/outfit/syndicate) - else - synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return TRUE - /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- - var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") - syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 - nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -154,8 +52,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in syndicates) - if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) + for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) return FALSE return TRUE @@ -164,7 +62,7 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(are_operatives_dead()) + if(nuke_team.operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! @@ -172,6 +70,7 @@ ..() /datum/game_mode/nuclear/set_round_result() + ..() var result = nuke_team.get_result() switch(result) if(NUKE_RESULT_FLUKE) @@ -204,7 +103,6 @@ else SSticker.mode_result = "halfwin - interrupted" SSticker.news_report = OPERATIVE_SKIRMISH - return ..() /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ @@ -212,7 +110,7 @@ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -225,18 +123,28 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1) + backpack_contents = list(/obj/item/storage/box/syndie=1,\ + /obj/item/kitchen/knife/combat/survival) var/tc = 25 + var/command_radio = FALSE + + +/datum/outfit/syndicate/leader + name = "Syndicate Leader - Basic" + id = /obj/item/card/id/syndicate/nuke_leader + r_hand = /obj/item/device/nuclear_challenge + command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 - /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.SYND_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_SYNDICATE) + R.freqlock = TRUE + if(command_radio) + R.command = TRUE if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) @@ -261,4 +169,5 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1) + /obj/item/gun/ballistic/automatic/pistol=1,\ + /obj/item/kitchen/knife/combat/survival) From 1b6b8a7c00e78577985e4ebe5d37bf46cde433e5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:46:15 -0600 Subject: [PATCH 136/213] Update cleanable.dm --- code/game/objects/effects/decals/cleanable.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 031e5059b3..f06525863d 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -46,6 +46,7 @@ if(istype(W, /obj/item/clothing/mask/cigarette)) return else + var/hotness = W.is_hot() reagents.expose_temperature(hotness) to_chat(user, "You heat [name] with [W]!") else From 30796ad34230002b0b546160b567a825f1916127 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:56:06 -0600 Subject: [PATCH 137/213] Update cit_arousal.dm --- code/citadel/cit_arousal.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/citadel/cit_arousal.dm b/code/citadel/cit_arousal.dm index 0c03ffb399..077824fe9e 100644 --- a/code/citadel/cit_arousal.dm +++ b/code/citadel/cit_arousal.dm @@ -62,14 +62,14 @@ /mob/living/proc/adjustArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(arousalloss + amount, min_arousal, max_arousal) + arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/setArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(amount, min_arousal, max_arousal) + arousalloss = CLAMP(amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() From 6c39e94bba650ea321b18f55c4ba7c2f94e6fe4c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:56:52 -0600 Subject: [PATCH 138/213] Update observer.dm --- code/modules/mob/dead/observer/observer.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 1837024a7f..4ecae3730d 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -471,7 +471,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set hidden = TRUE var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT if(input) - client.change_view(Clamp(client.view + input, 7, max_view)) + client.change_view(CLAMP(client.view + input, 7, max_view)) /mob/dead/observer/verb/boo() set category = "Ghost" From 56737f32de54d6af4ec692fffd7734a3c760e9e7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:59:55 -0600 Subject: [PATCH 139/213] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 1eae6c7899..01f5c007cd 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -13,7 +13,7 @@ var/max_severity = 3 -/datum/round_event/disease_outbreak/announce(fake) +/datum/round_event/disease_outbreak/announce() priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') /datum/round_event/disease_outbreak/setup() @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE @@ -33,7 +33,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(!(T.z in GLOB.station_z_levels)) + if(T.z != ZLEVEL_STATION_PRIMARY) continue if(!H.client) continue @@ -51,7 +51,7 @@ var/datum/disease/D if(!advanced_virus) if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.has_disability(BLIND))) //A blindness disease would be the worst. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. continue D = new virus_type() var/datum/disease/dnaspread/DS = D From f3e031fe2f6ad04345af87c330876751dd22f574 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:02:16 -0600 Subject: [PATCH 140/213] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 08210bf706..66a266ddb3 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,8 +154,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) - var/danger = GLOB.joined_player_list.len - nukeops.len + var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len +// var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) +// var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) scaleTC(danger) From 63b1b1df88119d22c3d18bdfb4b4768be80e6b88 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:40:20 -0600 Subject: [PATCH 141/213] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 01f5c007cd..8f5c0e50b5 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE From bcbb4102bfd039f18a334129e293a38c28ecfff9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:50:43 -0600 Subject: [PATCH 142/213] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 8f5c0e50b5..d83c966ff6 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE From dfa53390dfda9e4b967d55ef346658b4d34f0f68 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:12:26 -0600 Subject: [PATCH 143/213] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 306 +++++++++++++++++++------ 1 file changed, 242 insertions(+), 64 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index f131046cac..94c372ef23 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,3 +1,7 @@ +/datum/game_mode + var/list/datum/mind/syndicates = list() + var/nukeops_lastname = "" + /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -14,10 +18,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/list/pre_nukeops = list() - var/datum/team/nuclear/nuke_team + var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! + var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station + var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level + var/list/pre_nukeops = list() /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) @@ -28,23 +33,120 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(synd_mind.current) + set_antag_hud(synd_mind.current, "synd") + +/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(synd_mind.current) + set_antag_hud(synd_mind.current, null) + //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - //Assign leader - var/datum/mind/leader_mind = pre_nukeops[1] - var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) - nuke_team = L.nuke_team - //Assign the remaining operatives - for(var/i = 2 to pre_nukeops.len) - var/datum/mind/nuke_mind = pre_nukeops[i] - nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) + var/nuke_code = random_nukecode() + var/agent_number = 1 + var/datum/mind/leader = pick(pre_nukeops) + syndicates += pre_nukeops + for(var/i = 1 to pre_nukeops.len) + var/datum/mind/op = pre_nukeops[i] + + forge_syndicate_objectives(op) + greet_syndicate(op) + equip_syndicate(op.current) + + if(nuke_code) + op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) + to_chat(op.current, "The nuclear authorization code is: [nuke_code]") + + if(op == leader) + op.current.forceMove(pick(GLOB.nukeop_leader_start)) + prepare_syndicate_leader(op, nuke_code) + else + op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) + op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" + + update_synd_icons_added(op) + op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) + + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke.r_code = nuke_code return ..() +/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) + var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) + synd_mind.current.real_name = "[syndicate_name()] [leader_title]" + to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + + var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge + synd_mind.current.put_in_hands(challenge, TRUE) + + var/static/id_cache = typecacheof(/obj/item/card/id) + var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) + if(foundIDs.len) + for(var/i in 1 to foundIDs.len) + var/obj/item/card/id/ID = foundIDs[i] + ID.name = "lead agent card" + ID.access += ACCESS_SYNDICATE_LEADER + else + message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") + + var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current + if(A) + A.command = TRUE + + if(nuke_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = synd_mind.current + H.put_in_hands(P, TRUE) + H.update_icons() + else + nuke_code = "code will be provided later" + return + +/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) + nukeops_lastname = nukelastname(synd_mind.current) + NukeNameAssign(nukeops_lastname, syndicates) + + +/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) + var/datum/objective/nuclear/syndobj = new + syndobj.owner = syndicate + syndicate.objectives += syndobj + + +/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) + if(you_are) + to_chat(syndicate.current, "You are a [syndicate_name()] agent!") + syndicate.announce_objectives() + +/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) + synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + if(telecrystals) + synd_mob.equipOutfit(/datum/outfit/syndicate) + else + synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) + return TRUE + /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- + var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") + syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 + nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -52,8 +154,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) - if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + for(var/datum/mind/operative_mind in syndicates) + if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) return FALSE return TRUE @@ -62,55 +164,142 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(nuke_team.operatives_dead()) + if(are_operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! return FALSE //its a static var btw ..() -/datum/game_mode/nuclear/set_round_result() +/datum/game_mode/nuclear/declare_completion() + var/disk_rescued = 1 + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + disk_rescued = 0 + break + var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + to_chat(world, "Humiliating Syndicate Defeat") + to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") + + SSticker.news_report = NUKE_SYNDICATE_BASE + + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + SSticker.mode_result = "win - syndicate nuke" + to_chat(world, "Syndicate Major Victory!") + to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") + + SSticker.news_report = STATION_NUKED + + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + to_chat(world, "Total Annihilation") + to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") + + SSticker.news_report = STATION_NUKED + + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + SSticker.mode_result = "halfwin - blew wrong station" + to_chat(world, "Crew Minor Victory") + to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") + + SSticker.news_report = NUKE_MISS + + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") + to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") + + SSticker.news_report = NUKE_MISS + + else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + to_chat(world, "Crew Major Victory!") + to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") + + SSticker.news_report = OPERATIVES_KILLED + + else if (disk_rescued) + SSticker.mode_result = "loss - evacuation - disk secured" + to_chat(world, "Crew Major Victory") + to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") + + SSticker.news_report = OPERATIVES_KILLED + + else if (!disk_rescued && are_operatives_dead()) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + to_chat(world, "Neutral Victory!") + to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") + + SSticker.news_report = OPERATIVE_SKIRMISH + + else if (!disk_rescued && crew_evacuated) + SSticker.mode_result = "halfwin - detonation averted" + to_chat(world, "Syndicate Minor Victory!") + to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") + + SSticker.news_report = OPERATIVE_SKIRMISH + + else if (!disk_rescued && !crew_evacuated) + SSticker.mode_result = "halfwin - interrupted" + to_chat(world, "Neutral Victory") + to_chat(world, "Round was mysteriously interrupted!") + + SSticker.news_report = OPERATIVE_SKIRMISH + ..() - var result = nuke_team.get_result() - switch(result) - if(NUKE_RESULT_FLUKE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - SSticker.news_report = NUKE_SYNDICATE_BASE - if(NUKE_RESULT_NUKE_WIN) - SSticker.mode_result = "win - syndicate nuke" - SSticker.news_report = STATION_NUKED - if(NUKE_RESULT_NOSURVIVORS) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - SSticker.news_report = STATION_NUKED - if(NUKE_RESULT_WRONG_STATION) - SSticker.mode_result = "halfwin - blew wrong station" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_WRONG_STATION_DEAD) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - SSticker.news_report = NUKE_MISS - if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_CREW_WIN) - SSticker.mode_result = "loss - evacuation - disk secured" - SSticker.news_report = OPERATIVES_KILLED - if(NUKE_RESULT_DISK_LOST) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - SSticker.news_report = OPERATIVE_SKIRMISH - if(NUKE_RESULT_DISK_STOLEN) - SSticker.mode_result = "halfwin - detonation averted" - SSticker.news_report = OPERATIVE_SKIRMISH - else - SSticker.mode_result = "halfwin - interrupted" - SSticker.news_report = OPERATIVE_SKIRMISH + return /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." +/datum/game_mode/proc/auto_declare_completion_nuclear() + if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) + var/text = "
    The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/datum/mind/syndicate in syndicates) + text += printplayer(syndicate) + for(var/datum/component/uplink/H in GLOB.uplinks) + if(H.purchase_log) + purchases += H.purchase_log.generate_render() + else + stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") + text += "
    " + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + to_chat(world, text) + return TRUE + + +/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. + var/randomname = pick(GLOB.last_names) + var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) + + if (!newname) + newname = randomname + + else + if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") + to_chat(M, "That name is reserved.") + return nukelastname(M) + + return capitalize(newname) + +/proc/NukeNameAssign(lastname,list/syndicates) + for(var/datum/mind/synd_mind in syndicates) + var/mob/living/carbon/human/H = synd_mind.current + synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) + synd_mind.current.real_name = synd_mind.name + return + /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) + return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -123,28 +312,18 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1,\ - /obj/item/kitchen/knife/combat/survival) + backpack_contents = list(/obj/item/storage/box/syndie=1) var/tc = 25 - var/command_radio = FALSE - - -/datum/outfit/syndicate/leader - name = "Syndicate Leader - Basic" - id = /obj/item/card/id/syndicate/nuke_leader - r_hand = /obj/item/device/nuclear_challenge - command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 + /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears - R.set_frequency(FREQ_SYNDICATE) - R.freqlock = TRUE - if(command_radio) - R.command = TRUE + R.set_frequency(GLOB.SYND_FREQ) + R.freqlock = 1 if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) @@ -169,5 +348,4 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1,\ - /obj/item/kitchen/knife/combat/survival) + /obj/item/gun/ballistic/automatic/pistol=1) From e6cab75e71c4f7a1b178b2eb3fb55d23315e9005 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:22:03 -0600 Subject: [PATCH 144/213] NukeDatum --- code/__HELPERS/names.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index bfcfd23f50..90205168b5 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -121,9 +121,6 @@ GLOBAL_VAR(command_name) return new_station_name /proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name var/name = "" @@ -146,8 +143,7 @@ GLOBAL_VAR(command_name) else name += pick("-", "*", "") name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - syndicate_name = name + return name From 36b527610684e169b45c8ace5e11c771dd454a31 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:23:16 -0600 Subject: [PATCH 145/213] Create nukeop.dm --- datums/antagonists/nukeop.dm | 320 +++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 datums/antagonists/nukeop.dm diff --git a/datums/antagonists/nukeop.dm b/datums/antagonists/nukeop.dm new file mode 100644 index 0000000000..46e1ac3602 --- /dev/null +++ b/datums/antagonists/nukeop.dm @@ -0,0 +1,320 @@ +#define NUKE_RESULT_FLUKE 0 +#define NUKE_RESULT_NUKE_WIN 1 +#define NUKE_RESULT_CREW_WIN 2 +#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 +#define NUKE_RESULT_DISK_LOST 4 +#define NUKE_RESULT_DISK_STOLEN 5 +#define NUKE_RESULT_NOSURVIVORS 6 +#define NUKE_RESULT_WRONG_STATION 7 +#define NUKE_RESULT_WRONG_STATION_DEAD 8 + +/datum/antagonist/nukeop + name = "Nuclear Operative" + job_rank = ROLE_OPERATIVE + var/datum/objective_team/nuclear/nuke_team + var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/nukeop_outfit = /datum/outfit/syndicate + +/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(M) + set_antag_hud(M, "synd") + +/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_added(M) + +/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_removed(M) + +/datum/antagonist/nukeop/proc/equip_op() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/H = owner.current + + H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + H.equipOutfit(nukeop_outfit) + return TRUE + +/datum/antagonist/nukeop/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") + owner.announce_objectives() + return + +/datum/antagonist/nukeop/on_gain() + give_alias() + forge_objectives() + . = ..() + equip_op() + memorize_code() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/nukeop/get_team() + return nuke_team + +/datum/antagonist/nukeop/proc/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Syndicate nuke not found during nuke team creation.") + nuke_team.memorized_code = null + +/datum/antagonist/nukeop/proc/give_alias() + if(nuke_team && nuke_team.syndicate_name) + var/number = 1 + number = nuke_team.members.Find(owner) + owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" + +/datum/antagonist/nukeop/proc/memorize_code() + if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) + owner.store_memory("[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]", 0, 0) + to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") + else + to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") + +/datum/antagonist/nukeop/proc/forge_objectives() + if(nuke_team) + owner.objectives |= nuke_team.objectives + +/datum/antagonist/nukeop/proc/move_to_spawnpoint() + var/team_number = 1 + if(nuke_team) + team_number = nuke_team.members.Find(owner) + owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) + +/datum/antagonist/nukeop/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.nukeop_leader_start)) + +/datum/antagonist/nukeop/create_team(datum/objective_team/nuclear/new_team) + if(!new_team) + if(!always_new_team) + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) + if(N.nuke_team) + nuke_team = N.nuke_team + return + nuke_team = new /datum/objective_team/nuclear + nuke_team.update_objectives() + assign_nuke() //This is bit ugly + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + nuke_team = new_team + +/datum/antagonist/nukeop/leader + name = "Nuclear Operative Leader" + nukeop_outfit = /datum/outfit/syndicate/leader + always_new_team = TRUE + var/title + +/datum/antagonist/nukeop/leader/memorize_code() + ..() + if(nuke_team && nuke_team.memorized_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + P.forceMove(get_turf(H)) + else + H.put_in_hands(P, TRUE) + H.update_icons() + +/datum/antagonist/nukeop/leader/give_alias() + title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + if(nuke_team && nuke_team.syndicate_name) + owner.current.real_name = "[nuke_team.syndicate_name] [title]" + else + owner.current.real_name = "Syndicate [title]" + +/datum/antagonist/nukeop/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) + + +/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() + if(!nuke_team) + return + nuke_team.rename_team(ask_name()) + +/datum/objective_team/nuclear/proc/rename_team(new_name) + syndicate_name = new_name + name = "[syndicate_name] Team" + for(var/I in members) + var/datum/mind/synd_mind = I + var/mob/living/carbon/human/H = synd_mind.current + if(!istype(H)) + continue + var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) + H.fully_replace_character_name(H.real_name,chosen_name) + +/datum/antagonist/nukeop/leader/proc/ask_name() + var/randomname = pick(GLOB.last_names) + var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) + if (!newname) + newname = randomname + else + newname = reject_bad_name(newname) + if(!newname) + newname = randomname + + return capitalize(newname) + +/datum/antagonist/nukeop/lone + name = "Lone Operative" + always_new_team = TRUE + send_to_spawnpoint = FALSE //Handled by event + nukeop_outfit = /datum/outfit/syndicate/full + +/datum/antagonist/nukeop/lone/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Station self destruct ot found during lone op team creation.") + nuke_team.memorized_code = null + +/datum/objective_team/nuclear + var/list/objectives + var/syndicate_name + var/obj/machinery/nuclearbomb/tracked_nuke + var/core_objective = /datum/objective/nuclear + var/memorized_code + +/datum/objective_team/nuclear/New() + ..() + syndicate_name = syndicate_name() + +/datum/objective_team/nuclear/proc/update_objectives() + objectives = list() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + return + +/datum/objective_team/nuclear/proc/disk_rescued() + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/operatives_dead() + for(var/I in members) + var/datum/mind/operative_mind = I + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/syndies_escaped() + var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") + return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT)) + +/datum/objective_team/nuclear/proc/get_result() + var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME + var/disk_rescued = disk_rescued() + var/syndies_didnt_escape = !syndies_escaped() + var/station_was_nuked = SSticker.mode.station_was_nuked + var/nuke_off_station = SSticker.mode.nuke_off_station + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + return NUKE_RESULT_FLUKE + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + return NUKE_RESULT_NUKE_WIN + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + return NUKE_RESULT_NOSURVIVORS + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION_DEAD + else if ((disk_rescued || evacuation) && operatives_dead()) + return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD + else if (disk_rescued) + return NUKE_RESULT_CREW_WIN + else if (!disk_rescued && operatives_dead()) + return NUKE_RESULT_DISK_LOST + else if (!disk_rescued && evacuation) + return NUKE_RESULT_DISK_STOLEN + else + return //Undefined result + +/datum/objective_team/nuclear/proc/roundend_display() + to_chat(world,"[syndicate_name] Operatives:") + + switch(get_result()) + if(NUKE_RESULT_FLUKE) + to_chat(world, "Humiliating Syndicate Defeat") + to_chat(world, "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") + if(NUKE_RESULT_NUKE_WIN) + to_chat(world, "Syndicate Major Victory!") + to_chat(world, "[syndicate_name] operatives have destroyed [station_name()]!") + if(NUKE_RESULT_NOSURVIVORS) + to_chat(world, "Total Annihilation") + to_chat(world, "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") + if(NUKE_RESULT_WRONG_STATION) + to_chat(world, "Crew Minor Victory") + to_chat(world, "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") + if(NUKE_RESULT_WRONG_STATION_DEAD) + to_chat(world, "[syndicate_name] operatives have earned Darwin Award!") + to_chat(world, "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + to_chat(world, "Crew Major Victory!") + to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name] Operatives") + if(NUKE_RESULT_CREW_WIN) + to_chat(world, "Crew Major Victory") + to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!") + if(NUKE_RESULT_DISK_LOST) + to_chat(world, "Neutral Victory!") + to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!") + if(NUKE_RESULT_DISK_STOLEN) + to_chat(world, "Syndicate Minor Victory!") + to_chat(world, "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") + else + to_chat(world, "Neutral Victory") + to_chat(world, "Mission aborted!") + + var/text = "
    The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/I in members) + var/datum/mind/syndicate = I + text += SSticker.mode.printplayer(syndicate) //to be moved + for(var/U in GLOB.uplinks) + var/datum/component/uplink/H = U + if(H.owner == syndicate.key) + TC_uses += H.spent_telecrystals + if(H.purchase_log) + purchases += H.purchase_log.generate_render(show_key = FALSE) + else + stack_trace("WARNING: Nuke Op uplink with no purchase_log Owner: [H.owner]") + text += "
    " + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + to_chat(world, text) From 614e93b9755576e8caf591824e2471602298068e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:26:28 -0600 Subject: [PATCH 146/213] Update mind.dm --- code/datums/mind.dm | 102 +++++++++----------------------------------- 1 file changed, 20 insertions(+), 82 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c0ab1dc015..5ec2eddeab 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -208,12 +208,10 @@ SSticker.mode.update_brother_icons_removed(src) /datum/mind/proc/remove_nukeop() - if(src in SSticker.mode.syndicates) - SSticker.mode.syndicates -= src - SSticker.mode.update_synd_icons_removed(src) - special_role = null - remove_objectives() - remove_antag_equip() + var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(nuke) + remove_antag_datum(nuke.type) + special_role = null /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) @@ -329,14 +327,19 @@ SSticker.mode.add_cultist(src) else if(is_revolutionary(creator)) - var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev) ++ var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) converter.add_revolutionary(src,FALSE) else if(is_servant_of_ratvar(creator)) add_servant_of_ratvar(current) else if(is_nuclear_operative(creator)) - make_Nuke(null, null, 0, FALSE) + var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + var/datum/antagonist/nukeop/N = new(src) + N.send_to_spawnpoint = FALSE + N.nukeop_outfit = null + add_antag_datum(N,converter.nuke_team) + enslaved_to = creator @@ -490,7 +493,8 @@ /** NUCLEAR ***/ text = "nuclear" - if (SSticker.mode.config_tag=="nuclear") + var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(N) text = uppertext(text) text = "[text]: " if (src in SSticker.mode.syndicates) @@ -713,7 +717,7 @@ out += sections[i]+"
    " - if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current)) + if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current)) text = "Uplink: give" var/datum/component/uplink/U = find_syndicate_uplink() if(U) @@ -1071,36 +1075,14 @@ message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].") log_admin("[key_name(usr)] has de-nuke op'ed [current].") if("nuclear") - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - if (SSticker.mode.syndicates.len==1) - SSticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - special_role = "Syndicate" - assigned_role = "Syndicate" - to_chat(current, "You are a [syndicate_name()] agent!") - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - message_admins("[key_name_admin(usr)] has nuke op'ed [current].") - log_admin("[key_name(usr)] has nuke op'ed [current].") + if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) + add_antag_datum(/datum/antagonist/nukeop) + special_role = "Syndicate" + assigned_role = "Syndicate" + message_admins("[key_name_admin(usr)] has nuke op'ed [current].") + log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) - if("dressup") - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - if (!SSticker.mode.equip_syndicate(current)) - to_chat(usr, "Equipping a syndicate failed!") if("tellcode") var/code for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines) @@ -1348,50 +1330,6 @@ T.should_specialise = TRUE add_antag_datum(T) - -/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE) - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - assigned_role = "Syndicate" - special_role = "Syndicate" - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - current.faction |= "syndicate" - - if(spawnloc) - current.forceMove(spawnloc) - - if(ishuman(current)) - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - SSticker.mode.equip_syndicate(current, telecrystals) - - if (nuke_code) - store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: [nuke_code]") - else - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - store_memory("Syndicate Nuclear Bomb Code: [nuke.r_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: nuke.r_code") - else - to_chat(current, "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.
    ") - - if (leader) - SSticker.mode.prepare_syndicate_leader(src,nuke_code) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - /datum/mind/proc/make_Changling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(!C) From 5983d7b13db2c7d34c5958f01cac0b45a597bb04 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:27:36 -0600 Subject: [PATCH 147/213] Update antag_spawner.dm --- code/game/gamemodes/antag_spawner.dm | 61 +++++++++++++++------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 3358052c7f..e62c91168b 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -4,7 +4,7 @@ w_class = WEIGHT_CLASS_TINY var/used = 0 -/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) return /obj/item/antag_spawner/proc/equip_antag(mob/target) @@ -67,18 +67,16 @@ else to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user) +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key var/datum/mind/app_mind = M.mind - - var/datum/antagonist/wizard/apprentice/app = new(app_mind) app.master = user - app.school = school + app.school = kind var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard) if(master_wizard) @@ -107,7 +105,7 @@ if(used) to_chat(user, "[src] is out of power!") return FALSE - if(!(user.mind in SSticker.mode.syndicates)) + if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(user.z != ZLEVEL_CENTCOM) @@ -127,25 +125,25 @@ return used = TRUE var/mob/dead/observer/theghost = pick(nuke_candidates) - spawn_antag(theghost.client, get_turf(src), "syndieborg", user.mind) + spawn_antag(theghost.client, get_turf(src), "syndieborg") do_sparks(4, TRUE, src) qdel(src) else to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") -/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key - var/code = "BOMB-NOT-FOUND" - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - code = nuke.r_code - M.mind.make_Nuke(null, code, 0, FALSE) - var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname) - M.mind.name = newname - M.real_name = newname - M.name = newname + + var/datum/antagonist/nukeop/new_op = new(M.mind) + new_op.send_to_spawnpoint = FALSE + new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals + + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(creator_op) + M.mind.add_antag_datum(new_op,creator_op.nuke_team) + M.mind.special_role = "Nuclear Operative" //////SYNDICATE BORG /obj/item/antag_spawner/nuke_ops/borg_tele @@ -162,8 +160,12 @@ name = "syndicate medical teleporter" borg_to_spawn = "Medical" -/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/silicon/robot/R + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(!creator_op) + return + switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/modules/syndicate/medical(T) @@ -174,8 +176,8 @@ if(prob(50)) brainfirstname = pick(GLOB.first_names_female) var/brainopslastname = pick(GLOB.last_names) - if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops. - brainopslastname = SSticker.mode.nukeops_lastname + if(creator_op.nuke_team.syndicate_name) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = creator_op.nuke_team.syndicate_name var/brainopsname = "[brainfirstname] [brainopslastname]" R.mmi.name = "Man-Machine Interface: [brainopsname]" @@ -185,7 +187,11 @@ R.real_name = R.name R.key = C.key - R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE) + + var/datum/antagonist/nukeop/new_borg = new(R.mind) + new_borg.send_to_spawnpoint = FALSE + R.mind.add_antag_datum(new_borg,creator_op.nuke_team) + R.mind.special_role = "Syndicate Cyborg" ///////////SLAUGHTER DEMON @@ -213,7 +219,7 @@ return used = 1 var/mob/dead/observer/theghost = pick(demon_candidates) - spawn_antag(theghost.client, get_turf(src), initial(demon_type.name),user.mind) + spawn_antag(theghost.client, get_turf(src), initial(demon_type.name)) to_chat(user, shatter_msg) to_chat(user, veil_msg) playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) @@ -222,8 +228,7 @@ to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", datum/mind/user) - +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.holder = holder @@ -232,15 +237,15 @@ S.mind.special_role = S.name SSticker.mode.traitors += S.mind var/datum/objective/assassinate/new_objective - if(user) + if(usr) new_objective = new /datum/objective/assassinate new_objective.owner = S.mind - new_objective.target = user - new_objective.explanation_text = "[objective_verb] [user.name], the one who summoned you." + new_objective.target = usr.mind + new_objective.explanation_text = "[objective_verb] [usr.real_name], the one who summoned you." S.mind.objectives += new_objective var/datum/objective/new_objective2 = new /datum/objective new_objective2.owner = S.mind - new_objective2.explanation_text = "[objective_verb] everyone[user ? " else while you're at it":""]." + new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]." S.mind.objectives += new_objective2 to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ From 992984388bb2f91686a4ec62ea57c47d40eb5e55 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:29:04 -0600 Subject: [PATCH 148/213] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 803e73b9e0..a62b5f6087 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,6 +19,7 @@ var/probability = 0 var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm + var/nuke_off_station = 0 //Used for tracking where the nuke hit var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist @@ -526,7 +527,7 @@ /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." -//By default nuke just ends the round -/datum/game_mode/proc/OnNukeExplosion(off_station) - if(off_station < 2) - station_was_nuked = TRUE //Will end the round on next check. + /datum/game_mode/proc/OnNukeExplosion(off_station) + nuke_off_station = off_station + if(off_station < 2). + station_was_nuked = TRUE //Will end the round on next check. From 951a54088207084a8eb10da3f2a2ba4cdccc5a34 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:29:27 -0600 Subject: [PATCH 149/213] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 295 ++++++------------------- 1 file changed, 62 insertions(+), 233 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 94c372ef23..4fcde56a72 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,7 +1,3 @@ -/datum/game_mode - var/list/datum/mind/syndicates = list() - var/nukeops_lastname = "" - /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -18,12 +14,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/list/pre_nukeops = list() + var/datum/objective_team/nuclear/nuke_team + /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) for(var/i = 0, i < n_agents, ++i) @@ -33,120 +28,23 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(synd_mind.current) - set_antag_hud(synd_mind.current, "synd") - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(synd_mind.current) - set_antag_hud(synd_mind.current, null) - //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - var/nuke_code = random_nukecode() - var/agent_number = 1 - var/datum/mind/leader = pick(pre_nukeops) - syndicates += pre_nukeops - for(var/i = 1 to pre_nukeops.len) - var/datum/mind/op = pre_nukeops[i] - - forge_syndicate_objectives(op) - greet_syndicate(op) - equip_syndicate(op.current) - - if(nuke_code) - op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(op.current, "The nuclear authorization code is: [nuke_code]") - - if(op == leader) - op.current.forceMove(pick(GLOB.nukeop_leader_start)) - prepare_syndicate_leader(op, nuke_code) - else - op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) - op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" - - update_synd_icons_added(op) - op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code + //Assign leader + var/datum/mind/leader_mind = pre_nukeops[1] + var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = L.nuke_team + //Assign the remaining operatives + for(var/i = 2 to pre_nukeops.len) + var/datum/mind/nuke_mind = pre_nukeops[i] + nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return ..() -/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) - var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) - synd_mind.current.real_name = "[syndicate_name()] [leader_title]" - to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - - var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands(challenge, TRUE) - - var/static/id_cache = typecacheof(/obj/item/card/id) - var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) - if(foundIDs.len) - for(var/i in 1 to foundIDs.len) - var/obj/item/card/id/ID = foundIDs[i] - ID.name = "lead agent card" - ID.access += ACCESS_SYNDICATE_LEADER - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") - - var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current - if(A) - A.command = TRUE - - if(nuke_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = synd_mind.current - H.put_in_hands(P, TRUE) - H.update_icons() - else - nuke_code = "code will be provided later" - return - -/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname, syndicates) - - -/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - - -/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if(you_are) - to_chat(syndicate.current, "You are a [syndicate_name()] agent!") - syndicate.announce_objectives() - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) - synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - if(telecrystals) - synd_mob.equipOutfit(/datum/outfit/syndicate) - else - synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return TRUE - /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- - var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") - syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 - nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -154,8 +52,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in syndicates) - if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) + for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) return FALSE return TRUE @@ -164,7 +62,7 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(are_operatives_dead()) + if(nuke_team.operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! @@ -172,85 +70,39 @@ ..() /datum/game_mode/nuclear/declare_completion() - var/disk_rescued = 1 - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - disk_rescued = 0 - break - var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - to_chat(world, "Humiliating Syndicate Defeat") - to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") - - SSticker.news_report = NUKE_SYNDICATE_BASE - - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - SSticker.mode_result = "win - syndicate nuke" - to_chat(world, "Syndicate Major Victory!") - to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - to_chat(world, "Total Annihilation") - to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station" - to_chat(world, "Crew Minor Victory") - to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") - to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - to_chat(world, "Crew Major Victory!") - to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") - - SSticker.news_report = OPERATIVES_KILLED - - else if (disk_rescued) - SSticker.mode_result = "loss - evacuation - disk secured" - to_chat(world, "Crew Major Victory") - to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVES_KILLED - - else if (!disk_rescued && are_operatives_dead()) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - to_chat(world, "Neutral Victory!") - to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && crew_evacuated) - SSticker.mode_result = "halfwin - detonation averted" - to_chat(world, "Syndicate Minor Victory!") - to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && !crew_evacuated) - SSticker.mode_result = "halfwin - interrupted" - to_chat(world, "Neutral Victory") - to_chat(world, "Round was mysteriously interrupted!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - ..() - return + var result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH + return ..() /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ @@ -258,48 +110,16 @@ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." /datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) - var/text = "
    The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/datum/mind/syndicate in syndicates) - text += printplayer(syndicate) - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H.purchase_log) - purchases += H.purchase_log.generate_render() - else - stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") - text += "
    " - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - to_chat(world, text) + var/list/nuke_teams = list() + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) //collect all nuke teams + nuke_teams |= N.nuke_team + for(var/datum/objective_team/nuclear/nuke_team in nuke_teams) + nuke_team.roundend_display() return TRUE -/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(GLOB.last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - to_chat(M, "That name is reserved.") - return nukelastname(M) - - return capitalize(newname) - -/proc/NukeNameAssign(lastname,list/syndicates) - for(var/datum/mind/synd_mind in syndicates) - var/mob/living/carbon/human/H = synd_mind.current - synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) - synd_mind.current.real_name = synd_mind.name - return - /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -315,15 +135,24 @@ backpack_contents = list(/obj/item/storage/box/syndie=1) var/tc = 25 + var/command_radio = FALSE + + +/datum/outfit/syndicate/leader + name = "Syndicate Leader - Basic" + id = /obj/item/card/id/syndicate/nuke_leader + r_hand = /obj/item/device/nuclear_challenge + command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 - /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears R.set_frequency(GLOB.SYND_FREQ) R.freqlock = 1 + if(command_radio) + R.command = TRUE if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) From c545ef06cdf7c4fea3619fd9a0c814fdc5d05b1e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:30:23 -0600 Subject: [PATCH 150/213] Update nuclearbomb.dm --- code/game/gamemodes/nuclear/nuclearbomb.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index e35eaed9f1..d6d14a3f84 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -77,16 +77,16 @@ icon = 'icons/obj/machines/nuke_terminal.dmi' icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved - use_tag = TRUE /obj/machinery/nuclearbomb/syndicate + use_tag = TRUE //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) if(0) - if(istype(NM) && NM.syndies_didnt_escape) + if(istype(NM) && !NM.nuke_team.syndies_escaped()) return CINEMATIC_ANNIHILATION else return CINEMATIC_NUKE_WIN @@ -572,4 +572,4 @@ This is here to make the tiles around the station mininuke change when it's arme user.visible_message("[user] is pretending to go delta! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/machines/alarm.ogg', 30, -1, 1) addtimer(CALLBACK(src, .proc/manual_suicide, user), 101) - return MANUAL_SUICIDE \ No newline at end of file + return MANUAL_SUICIDE From 9d90a2bf5bae16bbe482065812b93b4a0ea3c824 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:30:54 -0600 Subject: [PATCH 151/213] Update pinpointer.dm --- code/game/gamemodes/nuclear/pinpointer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 2df573dc6d..7047729294 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -71,9 +71,9 @@ target = null var/list/possible_targets = list() var/turf/here = get_turf(src) - for(var/V in SSticker.mode.syndicates) + for(var/V in get_antagonists(/datum/antagonist/nukeop)) var/datum/mind/M = V - if(M.current && M.current.stat != DEAD) + if(ishuman(M.current) && M.current.stat != DEAD) possible_targets |= M.current var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here) if(closest_operative) From 2b434438e0f179d2c89f590407219f731207ca38 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:31:17 -0600 Subject: [PATCH 152/213] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 66a266ddb3..8679652a10 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,7 +154,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len // var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) // var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) From 74bba8aea72f22b13b0526c94a3c38d9b1abc2a3 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:31:44 -0600 Subject: [PATCH 153/213] Update cards_ids.dm --- code/game/objects/items/cards_ids.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index ed9a6712a8..0f65281328 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -155,6 +155,11 @@ update_label("John Doe", "Clowny") name = "agent card" access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE) var/anyone = FALSE //Can anyone forge the ID or just syndicate? + +/obj/item/card/id/syndicate/nuke_leader + name = "lead agent card" + access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) + /obj/item/card/id/syndicate/Initialize() . = ..() From 80412ae3b914483a380c089a9835a6b62683cb05 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:32:18 -0600 Subject: [PATCH 154/213] Update player_panel.dm --- code/modules/admin/player_panel.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index fa6e184ab4..b5d908d669 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -384,9 +384,10 @@ dat += "
    [other_players] players in invalid state or the statistics code is bugged!" dat += "
    " - if(SSticker.mode.syndicates.len) + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + if(nukeops.len) dat += "
    " - for(var/datum/mind/N in SSticker.mode.syndicates) + for(var/datum/mind/N in nukeops) var/mob/M = N.current if(M) dat += "" From da2bf6293f6d1361f0a4000df94795b0660d83c9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:34:02 -0600 Subject: [PATCH 155/213] Update one_click_antag.dm --- code/modules/admin/verbs/one_click_antag.dm | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 8a18dc9ac5..836a6e26be 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -238,26 +238,18 @@ if(agentcount < 3) return 0 - var/nuke_code = random_nukecode() - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code - //Let's find the spawn locations var/leader_chosen = FALSE - var/spawnpos = 1 //Decides where they'll spawn. 1=leader. - + + var/datum/objective_team/nuclear/nuke_team for(var/mob/c in chosen) - if(spawnpos > GLOB.nukeop_start.len) - spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position var/mob/living/carbon/human/new_character=makeBody(c) if(!leader_chosen) leader_chosen = TRUE - new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE) + var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = N.nuke_team else - new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code) - spawnpos++ + new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return 1 else return 0 From 2148eb021b13c153c1ba54d91bf6d7cb8a435c6e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:34:44 -0600 Subject: [PATCH 156/213] Update randomverbs.dm --- code/modules/admin/verbs/randomverbs.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 48ba94bb76..eed265598e 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact. A.equip_wizard() if("Syndicate") new_character.forceMove(pick(GLOB.nukeop_start)) - call(/datum/game_mode/proc/equip_syndicate)(new_character) + var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + N.equip_op() if("Space Ninja") var/list/ninja_spawn = list() for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) From 9ab75d37b7f62faf46771307b6d20dd9b7c18338 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:35:41 -0600 Subject: [PATCH 157/213] Update operative.dm --- code/modules/events/operative.dm | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 47130ff924..894ad7e995 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -27,31 +27,13 @@ A.copy_to(operative) operative.dna.update_dna_identity() - operative.equipOutfit(/datum/outfit/syndicate/full) - var/datum/mind/Mind = new /datum/mind(selected.key) Mind.assigned_role = "Lone Operative" Mind.special_role = "Lone Operative" - SSticker.mode.traitors |= Mind Mind.active = 1 - var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines - if(nuke) - var/nuke_code - if(!nuke.r_code || nuke.r_code == "ADMIN") - nuke_code = random_nukecode() - nuke.r_code = nuke_code - else - nuke_code = nuke.r_code - - Mind.store_memory("Station Self-Destruct Device Code: [nuke_code]", 0, 0) - to_chat(Mind.current, "The nuclear authorization code is: [nuke_code]") - - var/datum/objective/nuclear/O = new() - O.owner = Mind - Mind.objectives += O - Mind.transfer_to(operative) + Mind.add_antag_datum(/datum/antagonist/nukeop/lone) message_admins("[key_name_admin(operative)] has been made into lone operative by an event.") log_game("[key_name(operative)] was spawned as a lone operative by an event.") From efc41a15d3b2ca37a7717595f9b30959b04c3205 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:36:03 -0600 Subject: [PATCH 158/213] Update mob_helpers.dm --- code/modules/mob/mob_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 3dc56c936b..747d589c05 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if(M.mind in SSticker.mode.cult) return 2 if("nuclear") - if(M.mind in SSticker.mode.syndicates) + if(M.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) return 2 if("changeling") if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE)) From 7c3dc0705c29630bd87283d7a8ca14f40d4f01ea Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:36:49 -0600 Subject: [PATCH 159/213] Update tgstation.dme --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 6123e6c34a..cdd7f3aed4 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -329,6 +329,7 @@ #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\internal_affairs.dm" #include "code\datums\antagonists\ninja.dm" +#include "code\datums\antagonists\nukeop.dm" #include "code\datums\antagonists\pirate.dm" #include "code\datums\antagonists\revolution.dm" #include "code\datums\antagonists\wizard.dm" From a8e36670e214d24aa4bcad869a30f89f97db91a8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:02:03 -0600 Subject: [PATCH 160/213] Update mind.dm --- code/datums/mind.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 5ec2eddeab..d68566f4e4 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -327,7 +327,7 @@ SSticker.mode.add_cultist(src) else if(is_revolutionary(creator)) -+ var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) + var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) converter.add_revolutionary(src,FALSE) else if(is_servant_of_ratvar(creator)) From 36ad355f9d31c4a54d18640e79a809e1fe36c799 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:08:49 -0600 Subject: [PATCH 161/213] Update mind.dm --- code/datums/mind.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index d68566f4e4..f0d2337814 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1077,10 +1077,10 @@ if("nuclear") if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) add_antag_datum(/datum/antagonist/nukeop) - special_role = "Syndicate" - assigned_role = "Syndicate" - message_admins("[key_name_admin(usr)] has nuke op'ed [current].") - log_admin("[key_name(usr)] has nuke op'ed [current].") + special_role = "Syndicate" + assigned_role = "Syndicate" + message_admins("[key_name_admin(usr)] has nuke op'ed [current].") + log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) if("tellcode") From 7dec65ff857a2e8ce04d7c054abe9fb7fdae7f1e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:20:09 -0600 Subject: [PATCH 162/213] fuck --- {datums => code/datums}/antagonists/nukeop.dm | 0 tgstation.dme | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {datums => code/datums}/antagonists/nukeop.dm (100%) diff --git a/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm similarity index 100% rename from datums/antagonists/nukeop.dm rename to code/datums/antagonists/nukeop.dm diff --git a/tgstation.dme b/tgstation.dme index cdd7f3aed4..2852a1d295 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2452,7 +2452,7 @@ #include "modular_citadel\cydonian_armor.dm" #include "modular_citadel\polychromic_clothes.dm" #include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" #include "modular_citadel\code\modules\crafting\recipes.dm" -#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" // END_INCLUDE From 4d5c32ae5648a4d8775a9298dbcefbcee52480bc Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 22:11:04 -0600 Subject: [PATCH 163/213] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a62b5f6087..e23464fbdd 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -527,7 +527,8 @@ /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." - /datum/game_mode/proc/OnNukeExplosion(off_station) +//By default nuke just ends the round +/datum/game_mode/proc/OnNukeExplosion(off_station) nuke_off_station = off_station - if(off_station < 2). - station_was_nuked = TRUE //Will end the round on next check. + if(off_station < 2) +station_was_nuked = TRUE //Will end the round on next check. From 5bd61908a3f222a8128c5543fde870bf306fb25f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 23:53:36 -0600 Subject: [PATCH 164/213] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index e23464fbdd..ca6755dbd3 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -531,4 +531,4 @@ /datum/game_mode/proc/OnNukeExplosion(off_station) nuke_off_station = off_station if(off_station < 2) -station_was_nuked = TRUE //Will end the round on next check. + station_was_nuked = TRUE //Will end the round on next check. From d6a5ee596b2d97877d1956dd5524d82d2ccf0a0d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 23:55:36 -0600 Subject: [PATCH 165/213] Update mind.dm --- code/datums/mind.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index f0d2337814..b41dadc95a 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -493,11 +493,11 @@ /** NUCLEAR ***/ text = "nuclear" - var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) - if(N) + if (SSticker.mode.config_tag=="nuclear") text = uppertext(text) text = "[text]: " - if (src in SSticker.mode.syndicates) + var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(N) text += "OPERATIVE | nanotrasen" text += "
    To shuttle, undress, dress up." var/code From 8a1ed708881310b760eaef93e4b23df0327d9adc Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 20 Dec 2017 00:08:37 -0600 Subject: [PATCH 166/213] Update roundend.dm --- code/__HELPERS/roundend.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 7bd08167e6..9ba1c767b7 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -71,10 +71,10 @@ if(LAZYLEN(GLOB.round_end_notifiees)) send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") - for(var/client/C in GLOB.clients) + /*for(var/client/C in GLOB.clients) if(!C.credits) C.RollCredits() - C.playtitlemusic(40) + C.playtitlemusic(40)*/ display_report() @@ -409,4 +409,4 @@ else objective_parts += "Objective #[count]: [objective.explanation_text] Fail." count++ - return objective_parts.Join("
    ") \ No newline at end of file + return objective_parts.Join("
    ") From e6e197c88a36455a36d266548a895c58020a035c Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 20 Dec 2017 00:52:33 -0500 Subject: [PATCH 167/213] Adds NAMEOF, VARSET_CALLBACK, and VARSET_LIST_CALLBACK (#33543) * Adds NAMEOF and VARSET_CALLBACK * Fix VARSET_CALLBACK * Change names, add VARSET_LIST_CALLBACK * Fix var names * Additional macro safety. Update commen * ImprovedName * Fixing --- code/__HELPERS/unsorted.dm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 207e69fa9b..28b31f4e98 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1514,3 +1514,20 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) for(var/V in GLOB.player_list) if(is_servant_of_ratvar(V) || isobserver(V)) . += V + +//datum may be null, but it does need to be a typed var +#define NAMEOF(datum, X) (list(##datum.##X, #X)[2]) + +#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value) +//dupe code because dm can't handle 3 level deep macros +#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value) + +/proc/___callbackvarset(list_or_datum, var_name, var_value) + if(length(list_or_datum)) + list_or_datum[var_name] = var_value + return + var/datum/D = list_or_datum + if(IsAdminAdvancedProcCall()) + D.vv_edit_var(var_name, var_value) //same result generally, unless badmemes + else + D.vars[var_name] = var_value From d960c45e7766810106c6ab447686620dce240036 Mon Sep 17 00:00:00 2001 From: oranges Date: Wed, 20 Dec 2017 17:45:39 +1300 Subject: [PATCH 169/213] Merge pull request #33622 from duncathan/assert_gas restores add_gas(), assert_gas(), and thermal_energy() as wrapper procs --- code/__DEFINES/atmospherics.dm | 2 -- code/game/mecha/equipment/tools/other_tools.dm | 2 +- .../effects/effect_system/effects_smoke.dm | 2 +- code/game/objects/items/tanks/jetpack.dm | 2 +- code/game/objects/items/tanks/tank_types.dm | 8 ++++---- code/game/turfs/open.dm | 4 ++-- code/modules/admin/verbs/debug.dm | 2 +- .../atmospherics/gasmixtures/gas_mixture.dm | 15 ++++++++++++++- .../components/trinary_devices/filter.dm | 2 +- .../machinery/components/unary_devices/tank.dm | 2 +- .../components/unary_devices/vent_scrubber.dm | 2 +- .../modules/atmospherics/machinery/other/miner.dm | 2 +- .../atmospherics/machinery/portable/canister.dm | 2 +- .../atmospherics/machinery/portable/scrubber.dm | 2 +- code/modules/power/singularity/collector.dm | 2 +- 15 files changed, 31 insertions(+), 20 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 20d80cb904..1024bb1229 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -202,6 +202,4 @@ #define ADD_GAS(gas_id, out_list)\ var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id]; out_list[gas_id] = tmp_gaslist.Copy(); -//ASSERT_GAS(gas_id, gas_mixture) - used to guarantee that the gas list for this id exists in gas_mixture.gases. -//Must be used before adding to a gas. May be used before reading from a gas. #define ASSERT_GAS(gas_id, gas_mixture) if (!gas_mixture.gases[gas_id]) { ADD_GAS(gas_id, gas_mixture.gases) }; diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 8951a0dbd5..385d112542 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -422,7 +422,7 @@ if(!istype(T)) return var/datum/gas_mixture/GM = new - ADD_GAS(/datum/gas/plasma, GM.gases) + GM.add_gas(/datum/gas/plasma) if(prob(10)) GM.gases[/datum/gas/plasma][MOLES] += 100 GM.temperature = 1500+T0C //should be enough to start a fire diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 3de8432ee9..4dc985c9a1 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -169,7 +169,7 @@ qdel(H) var/list/G_gases = G.gases if(G_gases[/datum/gas/plasma]) - ASSERT_GAS(/datum/gas/nitrogen, G) + G.assert_gas(/datum/gas/nitrogen) G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES]) G_gases[/datum/gas/plasma][MOLES] = 0 G.garbage_collect() diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index f1644f0b1a..6466696b98 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -17,7 +17,7 @@ /obj/item/tank/jetpack/New() ..() if(gas_type) - ASSERT_GAS(gas_type,air_contents) + air_contents.assert_gas(gas_type) air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) ion_trail = new diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 7a1fa569a3..4a687b458d 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -21,7 +21,7 @@ /obj/item/tank/internals/oxygen/New() ..() - ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.assert_gas(/datum/gas/oxygen) air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -87,7 +87,7 @@ /obj/item/tank/internals/plasma/New() ..() - ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.assert_gas(/datum/gas/plasma) air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -124,7 +124,7 @@ /obj/item/tank/internals/plasmaman/New() ..() - ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.assert_gas(/datum/gas/plasma) air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -166,7 +166,7 @@ /obj/item/tank/internals/emergency_oxygen/New() ..() - ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.assert_gas(/datum/gas/oxygen) air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 5d83d677de..0eddbc411e 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -355,6 +355,6 @@ if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen]) air.gases[/datum/gas/carbon_dioxide][MOLES]=max(air.gases[/datum/gas/carbon_dioxide][MOLES]-(pulse_strength/1000),0) air.gases[/datum/gas/oxygen][MOLES]=max(air.gases[/datum/gas/oxygen][MOLES]-(pulse_strength/2000),0) - ASSERT_GAS(/datum/gas/pluoxium,air) + air.assert_gas(/datum/gas/pluoxium) air.gases[/datum/gas/pluoxium][MOLES]+=(pulse_strength/4000) - air.garbage_collect() \ No newline at end of file + air.garbage_collect() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b02fe03c18..e2bb78c9ec 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -735,7 +735,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) if(Rad.anchored) if(!Rad.loaded_tank) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) - ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents) + Plasma.air_contents.assert_gas(/datum/gas/plasma) Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 64d77a27dc..376ca08b28 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -37,14 +37,24 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) reaction_results = new //listmos procs +//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm -// The following procs used to live here: thermal_energy(), assert_gas() and add_gas(). They have been moved into defines in code/__DEFINES/atmospherics.dm + //assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases. + //Must be used before adding to a gas. May be used before reading from a gas. +/datum/gas_mixture/proc/assert_gas(gas_id) + ASSERT_GAS(gas_id, src) //assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type. /datum/gas_mixture/proc/assert_gases() for(var/id in args) ASSERT_GAS(id, src) + //add_gas(gas_id) - similar to assert_gas(), but does not check for an existing + //gas list for this id. This can clobber existing gases. + //Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas(). +/datum/gas_mixture/proc/add_gas(gas_id) + ADD_GAS(gas_id, gases) + //add_gases(args) - shorthand for calling add_gas() once for each gas_type. /datum/gas_mixture/proc/add_gases() var/cached_gases = gases @@ -101,6 +111,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/return_volume() //liters return max(0, volume) +/datum/gas_mixture/proc/thermal_energy() //joules + return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas + /datum/gas_mixture/proc/archive() //Update archived versions of variables //Returns: 1 in all cases diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 9a8034064c..a1d6dc8c7e 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -103,7 +103,7 @@ var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature - ASSERT_GAS(filter_type, filtered_out) + filtered_out.add_gas(filter_type) filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES] removed.gases[filter_type][MOLES] = 0 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index ec1fcdfc52..4e9df101a6 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -17,7 +17,7 @@ air_contents.volume = volume air_contents.temperature = T20C if(gas_type) - ASSERT_GAS(gas_type, air_contents) + air_contents.assert_gas(gas_type) air_contents.gases[gas_type][MOLES] = AIR_CONTENTS name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index b3ade6f0fb..8fffd70840 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -179,7 +179,7 @@ filtered_out.temperature = removed.temperature for(var/gas in filter_types & removed_gases) - ADD_GAS(gas, filtered_gases) + filtered_out.add_gas(gas) filtered_gases[gas][MOLES] = removed_gases[gas][MOLES] removed_gases[gas][MOLES] = 0 diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index cb28f17802..f63065b431 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -132,7 +132,7 @@ if(!isopenturf(O)) return FALSE var/datum/gas_mixture/merger = new - ASSERT_GAS(spawn_id, merger) + merger.assert_gas(spawn_id) merger.gases[spawn_id][MOLES] = (spawn_mol) merger.temperature = spawn_temp O.assume_air(merger) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index ddc562bbb7..7b6351e939 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -196,7 +196,7 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) - ADD_GAS(gas_type, air_contents.gases) + air_contents.add_gas(gas_type) if(starter_temp) air_contents.temperature = starter_temp air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 3ba7e0a110..4bb7b02288 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -45,7 +45,7 @@ filtered.temperature = filtering.temperature for(var/gas in filtering.gases & scrubbing) - ADD_GAS(gas, filtered.gases) + filtered.add_gas(gas) filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. filtering.gases[gas][MOLES] = 0 filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 36dd615e86..a5e9db1fde 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -37,7 +37,7 @@ eject() else loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= 0.001*drainratio - ASSERT_GAS(/datum/gas/tritium,loaded_tank.air_contents) + loaded_tank.air_contents.assert_gas(/datum/gas/tritium) loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += 0.001*drainratio loaded_tank.air_contents.garbage_collect() From b305f1bb26cc3ee6fd5f05ec5649cbe696c6ad8a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 19 Dec 2017 19:28:35 -0500 Subject: [PATCH 171/213] Merge pull request #33664 from optimumtact/darkgenerallordhassnowflakeears Halve gun empty sound level --- code/game/objects/items/toys.dm | 2 +- code/modules/projectiles/gun.dm | 2 +- code/modules/projectiles/guns/ballistic.dm | 2 +- code/modules/projectiles/guns/ballistic/revolver.dm | 2 +- code/modules/projectiles/guns/energy.dm | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 259193b177..689f50769c 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -182,7 +182,7 @@ src.add_fingerprint(user) if (src.bullets < 1) user.show_message("*click*", 2) - playsound(src, "gun_dry_fire", 60, 1) + playsound(src, "gun_dry_fire", 30, 1) return playsound(user, 'sound/weapons/gunshot.ogg', 100, 1) src.bullets-- diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 047243cb45..ff7ed7653e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -107,7 +107,7 @@ /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") - playsound(src, "gun_dry_fire", 60, 1) + playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index f5d846c912..c4ba7a33b7 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 60, 1) + playsound(src, "gun_dry_fire", 30, 1) return (OXYLOSS) #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index a802ca8bbe..f642a94284 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -229,7 +229,7 @@ return user.visible_message("*click*") - playsound(src, "gun_dry_fire", 60, 1) + playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") user.apply_damage(300, BRUTE, affecting) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index e80f0758c1..b52a56426b 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 60, 1) + playsound(src, "gun_dry_fire", 30, 1) return (OXYLOSS) From 25d5e5b6b46963e695c9bb7f0b8ab470d15627ac Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 19 Dec 2017 17:23:26 -0500 Subject: [PATCH 173/213] Merge pull request #33594 from AnturK/knockoff Adds knock off component --- code/__DEFINES/components.dm | 1 + code/datums/components/knockoff.dm | 53 +++++++++++++++++++ code/game/objects/items.dm | 2 + code/game/objects/items/cigs_lighters.dm | 1 + .../mob/living/carbon/human/species.dm | 8 +-- tgstation.dme | 1 + 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 code/datums/components/knockoff.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 0b2a3e06d4..4bb27d56d6 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -82,6 +82,7 @@ // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) #define CALTROP_BYPASS_SHOES 1 #define CALTROP_IGNORE_WALKERS 2 diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm new file mode 100644 index 0000000000..35d1e5423e --- /dev/null +++ b/code/datums/components/knockoff.dm @@ -0,0 +1,53 @@ +//Items with these will have a chance to get knocked off when disarming +/datum/component/knockoff + var/knockoff_chance = 100 //Chance to knockoff + var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed + var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed + var/datum/component/redirect/disarm_redirect + +/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable) + if(!isitem(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("Knockoff component misuse") + RegisterSignal(COMSIG_ITEM_EQUIPPED,.proc/OnEquipped) + RegisterSignal(COMSIG_ITEM_DROPPED,.proc/OnDropped) + + src.knockoff_chance = knockoff_chance + + if(zone_override) + target_zones = zone_override + + if(slots_knockoffable) + src.slots_knockoffable = slots_knockoffable + +/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone) + var/obj/item/I = parent + var/mob/living/carbon/human/wearer = I.loc + if(!istype(wearer)) + return + if(target_zones && !(zone in target_zones)) + return + if(!prob(knockoff_chance)) + return + if(!wearer.dropItemToGround(I)) + return + + wearer.visible_message("[attacker] knocks off [wearer]'s [I.name]!","[attacker] knocks off your [I.name]!") + +/datum/component/knockoff/proc/OnEquipped(mob/living/carbon/human/H,slot) + if(!istype(H)) + return + if(slots_knockoffable && !(slot in slots_knockoffable)) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + return + if(!disarm_redirect) + disarm_redirect = H.AddComponent(/datum/component/redirect,list(COMSIG_HUMAN_DISARM_HIT),CALLBACK(src,.proc/Knockoff)) + +/datum/component/knockoff/proc/OnDropped(mob/living/M) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + +/datum/component/knockoff/Destroy() + QDEL_NULL(disarm_redirect) + . = ..() \ No newline at end of file diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d4e5240642..823a91cead 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -406,6 +406,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(DROPDEL_1 & flags_1) qdel(src) in_inventory = FALSE + SendSignal(COMSIG_ITEM_DROPPED,user) // called just as an item is picked up (loc is not yet changed) /obj/item/proc/pickup(mob/user) @@ -436,6 +437,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/datum/action/A = X if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. A.Grant(user) + SendSignal(COMSIG_ITEM_EQUIPPED,user,slot) in_inventory = TRUE //sometimes we only want to grant the item's action if it's equipped in a specific slot. diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 9c7c34510c..fd414b8d9a 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -129,6 +129,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM reagents.add_reagent_list(list_reagents) if(starts_lit) light() + AddComponent(/datum/component/knockoff,90,list("mouth"),list(slot_wear_mask))//90% to knock off when wearing a mask /obj/item/clothing/mask/cigarette/Destroy() STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0b02a2c711..a3ebf5ab2f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1366,8 +1366,6 @@ GLOBAL_LIST_EMPTY(roundstart_races) else if(target.lying) target.forcesay(GLOB.hit_appends) - - /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) var/aim_for_mouth = user.zone_selected == "mouth" var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item() @@ -1387,10 +1385,12 @@ GLOBAL_LIST_EMPTY(roundstart_races) return 1 else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - + if(target.w_uniform) target.w_uniform.add_fingerprint(user) - var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) + var/randomized_zone = ran_zone(user.zone_selected) + target.SendSignal(COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) + var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) var/randn = rand(1, 100) if(randn <= 25) playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) diff --git a/tgstation.dme b/tgstation.dme index 6123e6c34a..74cf9934cc 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -343,6 +343,7 @@ #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\knockoff.dm" #include "code\datums\components\infective.dm" #include "code\datums\components\jousting.dm" #include "code\datums\components\material_container.dm" From 5f69eac0503b6d225b25d395db5b67c048a229bd Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 20 Dec 2017 00:19:39 -0600 Subject: [PATCH 175/213] Update mind.dm --- code/datums/mind.dm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 14d619c917..88d84eeb6c 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -202,12 +202,10 @@ SSticker.mode.update_brother_icons_removed(src) /datum/mind/proc/remove_nukeop() - if(src in SSticker.mode.syndicates) - SSticker.mode.syndicates -= src - SSticker.mode.update_synd_icons_removed(src) - special_role = null - remove_objectives() - remove_antag_equip() + var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(nuke) + remove_antag_datum(nuke.type) +special_role = null /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) From 00d3b8f1b7d831020d8ea187ce4d10185247fef9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 20 Dec 2017 02:53:51 -0600 Subject: [PATCH 176/213] a lot of shit synced in this one commit. --- code/__HELPERS/roundend.dm | 20 ++++----- code/datums/antagonists/abductor.dm | 16 ++++---- code/datums/antagonists/antag_datum.dm | 6 +-- code/datums/antagonists/brother.dm | 18 ++++---- code/datums/antagonists/clockcult.dm | 18 ++++---- code/datums/antagonists/cult.dm | 30 +++++++------- code/datums/antagonists/pirate.dm | 25 ++++++----- code/datums/antagonists/revolution.dm | 36 ++++++++-------- code/datums/antagonists/wizard.dm | 14 +++---- code/datums/mind.dm | 12 +++--- code/game/gamemodes/antag_spawner.dm | 6 +-- code/game/gamemodes/brother/traitor_bro.dm | 8 ++-- code/game/gamemodes/clock_cult/clock_cult.dm | 9 ++-- code/game/gamemodes/cult/cult.dm | 10 ++--- code/game/gamemodes/cult/cult_comms.dm | 8 ++-- code/game/gamemodes/cult/runes.dm | 41 +++++++------------ code/game/gamemodes/game_mode.dm | 2 +- .../miniantags/abduction/abduction.dm | 16 ++++---- code/game/gamemodes/nuclear/nuclear.dm | 21 ++++------ code/game/gamemodes/revolution/revolution.dm | 2 +- code/game/gamemodes/wizard/soulstone.dm | 1 - code/modules/admin/player_panel.dm | 2 +- code/modules/admin/verbs/one_click_antag.dm | 15 ++++--- code/modules/power/singularity/narsie.dm | 2 +- tgstation.dme | 3 +- 25 files changed, 161 insertions(+), 180 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 9ba1c767b7..3b346f7e1c 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -47,7 +47,7 @@ antag_info["antagonist_name"] = A.name //For auto and custom roles antag_info["objectives"] = list() antag_info["team"] = list() - var/datum/objective_team/T = A.get_team() + var/datum/team/T = A.get_team() if(T) antag_info["team"]["type"] = T.type antag_info["team"]["name"] = T.name @@ -84,9 +84,9 @@ //Set news report and mode result mode.set_round_result() - + send2irc("Server", "Round just ended.") - + if(CONFIG_GET(string/cross_server_address)) send_news_report() @@ -142,15 +142,15 @@ parts += mode.special_report() CHECK_TICK - + //AI laws parts += law_report() - + CHECK_TICK //Antagonists parts += antag_report() - + CHECK_TICK //Medals parts += medal_report() @@ -202,7 +202,7 @@ /datum/controller/subsystem/ticker/proc/show_roundend_report(client/C,common_report) var/list/report_parts = list() - + report_parts += personal_report(C) report_parts += common_report @@ -212,7 +212,7 @@ roundend_report.set_content(report_parts.Join()) roundend_report.stylesheets = list() roundend_report.add_stylesheet("roundend",'html/browser/roundend.css') - + roundend_report.open(0) /datum/controller/subsystem/ticker/proc/personal_report(client/C) @@ -311,7 +311,7 @@ all_teams |= A.get_team() all_antagonists += A - for(var/datum/objective_team/T in all_teams) + for(var/datum/team/T in all_teams) result += T.roundend_report() for(var/datum/antagonist/X in all_antagonists) if(X.get_team() == T) @@ -336,7 +336,7 @@ previous_category = A result += A.roundend_report() result += "
    " - + if(all_antagonists.len) var/datum/antagonist/last = all_antagonists[all_antagonists.len] result += last.roundend_report_footer() diff --git a/code/datums/antagonists/abductor.dm b/code/datums/antagonists/abductor.dm index 3b8935d9fa..a98acf054e 100644 --- a/code/datums/antagonists/abductor.dm +++ b/code/datums/antagonists/abductor.dm @@ -2,7 +2,7 @@ name = "Abductor" roundend_category = "abductors" job_rank = ROLE_ABDUCTOR - var/datum/objective_team/abductor_team/team + var/datum/team/abductor_team/team var/sub_role var/outfit var/landmark_type @@ -20,7 +20,7 @@ landmark_type = /obj/effect/landmark/abductor/scientist greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve." -/datum/antagonist/abductor/create_team(datum/objective_team/abductor_team/new_team) +/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team) if(!new_team) return if(!istype(new_team)) @@ -73,20 +73,20 @@ A.scientist = TRUE -/datum/objective_team/abductor_team - member_name = "abductor" +/datum/team/abductor_team + member_name = "abductor" var/team_number var/list/datum/mind/abductees = list() -/datum/objective_team/abductor_team/is_solo() +/datum/team/abductor_team/is_solo() return FALSE -/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) +/datum/team/abductor_team/proc/add_objective(datum/objective/O) O.team = src O.update_explanation_text() objectives += O -/datum/objective_team/abductor_team/roundend_report() +/datum/team/abductor_team/roundend_report() var/list/result = list() var/won = TRUE @@ -127,7 +127,7 @@ var/datum/objective/abductee/O = new objtype() objectives += O owner.objectives += objectives - + /datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner) diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 6b5a573eff..9b5dbb6d75 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -49,7 +49,7 @@ GLOBAL_LIST_EMPTY(antagonists) return //Assign default team and creates one for one of a kind team antagonists -/datum/antagonist/proc/create_team(datum/objective_team/team) +/datum/antagonist/proc/create_team(datum/team/team) return //Proc called when the datum is given to a mind. @@ -84,7 +84,7 @@ GLOBAL_LIST_EMPTY(antagonists) LAZYREMOVE(owner.antag_datums, src) if(!silent && owner.current) farewell() - var/datum/objective_team/team = get_team() + var/datum/team/team = get_team() if(team) team.remove_member(owner) qdel(src) @@ -155,6 +155,6 @@ GLOBAL_LIST_EMPTY(antagonists) else already_registered_objectives |= A.objectives objectives = owner.objectives - already_registered_objectives - + //This one is created by admin tools for custom objectives /datum/antagonist/custom \ No newline at end of file diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm index dd3bdef9d2..b06c75e4fa 100644 --- a/code/datums/antagonists/brother.dm +++ b/code/datums/antagonists/brother.dm @@ -2,12 +2,12 @@ name = "Brother" job_rank = ROLE_BROTHER var/special_role = "blood brother" - var/datum/objective_team/brother_team/team + var/datum/team/brother_team/team /datum/antagonist/brother/New(datum/mind/new_owner) return ..() -/datum/antagonist/brother/create_team(datum/objective_team/brother_team/new_team) +/datum/antagonist/brother/create_team(datum/team/brother_team/new_team) if(!new_team) return if(!istype(new_team)) @@ -57,15 +57,15 @@ SSticker.mode.update_brother_icons_added(owner) -/datum/objective_team/brother_team +/datum/team/brother_team name = "brotherhood" member_name = "blood brother" var/meeting_area -/datum/objective_team/brother_team/is_solo() +/datum/team/brother_team/is_solo() return FALSE -/datum/objective_team/brother_team/proc/update_name() +/datum/team/brother_team/proc/update_name() var/list/last_names = list() for(var/datum/mind/M in members) var/list/split_name = splittext(M.name," ") @@ -73,7 +73,7 @@ name = last_names.Join(" & ") -/datum/objective_team/brother_team/roundend_report() +/datum/team/brother_team/roundend_report() var/list/parts = list() parts += "The blood brothers of [name] were:" @@ -95,14 +95,14 @@ return "
    [parts.Join("
    ")]
    " -/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) +/datum/team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) O.team = src if(needs_target) O.find_target() O.update_explanation_text() objectives += O -/datum/objective_team/brother_team/proc/forge_brother_objectives() +/datum/team/brother_team/proc/forge_brother_objectives() objectives = list() var/is_hijacker = prob(10) for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) @@ -113,7 +113,7 @@ else if(!locate(/datum/objective/escape) in objectives) add_objective(new/datum/objective/escape) -/datum/objective_team/brother_team/proc/forge_single_objective() +/datum/team/brother_team/proc/forge_single_objective() if(prob(50)) if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) add_objective(new/datum/objective/destroy, TRUE) diff --git a/code/datums/antagonists/clockcult.dm b/code/datums/antagonists/clockcult.dm index 5f99ccc5dd..48f9b53425 100644 --- a/code/datums/antagonists/clockcult.dm +++ b/code/datums/antagonists/clockcult.dm @@ -4,7 +4,7 @@ roundend_category = "clock cultists" job_rank = ROLE_SERVANT_OF_RATVAR var/datum/action/innate/hierophant/hierophant_network = new() - var/datum/objective_team/clockcult/clock_team + var/datum/team/clockcult/clock_team var/make_team = TRUE //This should be only false for tutorial scarabs /datum/antagonist/clockcult/silent @@ -17,14 +17,14 @@ /datum/antagonist/clockcult/get_team() return clock_team -/datum/antagonist/clockcult/create_team(datum/objective_team/clockcult/new_team) +/datum/antagonist/clockcult/create_team(datum/team/clockcult/new_team) if(!new_team && make_team) //TODO blah blah same as the others, allow multiple for(var/datum/antagonist/clockcult/H in GLOB.antagonists) if(H.clock_team) clock_team = H.clock_team return - clock_team = new /datum/objective_team/clockcult + clock_team = new /datum/team/clockcult return if(make_team && !istype(new_team)) stack_trace("Wrong team type passed to [type] initialization.") @@ -175,7 +175,7 @@ SSticker.mode.servants_of_ratvar -= owner SSticker.mode.update_servant_icons_removed(owner) if(!silent) - owner.current.visible_message("[owner] seems to have remembered their true allegiance!", ignored_mob = owner.current) + owner.current.visible_message("[owner] seems to have remembered their true allegiance!", ignored_mob = owner.current) to_chat(owner, "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.") owner.current.log_message("Has renounced the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG) owner.wipe_memory() @@ -185,19 +185,19 @@ . = ..() -/datum/objective_team/clockcult +/datum/team/clockcult name = "Clockcult" var/list/objective var/datum/mind/eminence -/datum/objective_team/clockcult/proc/check_clockwork_victory() +/datum/team/clockcult/proc/check_clockwork_victory() if(GLOB.clockwork_gateway_activated) return TRUE return FALSE -/datum/objective_team/clockcult/roundend_report() +/datum/team/clockcult/roundend_report() var/list/parts = list() - + if(check_clockwork_victory()) parts += "Ratvar's servants defended the Ark until its activation!" else @@ -213,5 +213,5 @@ if(members.len) parts += "Ratvar's servants were:" parts += printplayerlist(members - eminence) - + return "
    [parts.Join("
    ")]
    " \ No newline at end of file diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm index bce9123fb3..916123ddff 100644 --- a/code/datums/antagonists/cult.dm +++ b/code/datums/antagonists/cult.dm @@ -9,19 +9,19 @@ var/ignore_implant = FALSE var/give_equipment = FALSE - var/datum/objective_team/cult/cult_team + var/datum/team/cult/cult_team /datum/antagonist/cult/get_team() return cult_team -/datum/antagonist/cult/create_team(datum/objective_team/cult/new_team) +/datum/antagonist/cult/create_team(datum/team/cult/new_team) if(!new_team) //todo remove this and allow admin buttons to create more than one cult for(var/datum/antagonist/cult/H in GLOB.antagonists) if(H.cult_team) cult_team = H.cult_team return - cult_team = new /datum/objective_team/cult + cult_team = new /datum/team/cult cult_team.setup_objectives() return if(!istype(new_team)) @@ -59,7 +59,7 @@ SSticker.mode.cult += owner // Only add after they've been given objectives SSticker.mode.update_cult_icons_added(owner) current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - + if(cult_team.blood_target && cult_team.blood_target_image && current.client) current.client.images += cult_team.blood_target_image @@ -183,28 +183,28 @@ current.update_action_buttons_icon() current.remove_status_effect(/datum/status_effect/cult_master) -/datum/objective_team/cult +/datum/team/cult name = "Cult" var/blood_target var/image/blood_target_image var/blood_target_reset_timer - + var/cult_vote_called = FALSE var/cult_mastered = FALSE var/reckoning_complete = FALSE -/datum/objective_team/cult/proc/setup_objectives() +/datum/team/cult/proc/setup_objectives() //SAC OBJECTIVE , todo: move this to objective internals var/list/target_candidates = list() var/datum/objective/sacrifice/sac_objective = new sac_objective.team = src - + for(var/mob/living/carbon/human/player in GLOB.player_list) if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && player.stat != DEAD) target_candidates += player.mind - + if(target_candidates.len == 0) message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") for(var/mob/living/carbon/human/player in GLOB.player_list) @@ -214,7 +214,7 @@ if(LAZYLEN(target_candidates)) sac_objective.target = pick(target_candidates) sac_objective.update_explanation_text() - + var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) var/datum/preferences/sacface = sac_objective.target.current.client.prefs var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) @@ -235,7 +235,7 @@ summon_objective.team = src objectives += summon_objective -/datum/objective/sacrifice +/datum/objective/sacrifice var/sacced = FALSE var/sac_image @@ -268,13 +268,13 @@ /datum/objective/eldergod/check_completion() return summoned || completed -/datum/objective_team/cult/proc/check_cult_victory() +/datum/team/cult/proc/check_cult_victory() for(var/datum/objective/O in objectives) if(!O.check_completion()) return FALSE return TRUE -/datum/objective_team/cult/roundend_report() +/datum/team/cult/roundend_report() var/list/parts = list() if(check_cult_victory()) @@ -291,9 +291,9 @@ else parts += "Objective #[count]: [objective.explanation_text] Fail." count++ - + if(members.len) parts += "The cultists were:" parts += printplayerlist(members) - + return "
    [parts.Join("
    ")]
    " \ No newline at end of file diff --git a/code/datums/antagonists/pirate.dm b/code/datums/antagonists/pirate.dm index e0ce38c1e4..9bf20a4bf5 100644 --- a/code/datums/antagonists/pirate.dm +++ b/code/datums/antagonists/pirate.dm @@ -2,7 +2,7 @@ name = "Space Pirate" job_rank = ROLE_TRAITOR roundend_category = "space pirates" - var/datum/objective_team/pirate/crew + var/datum/team/pirate/crew /datum/antagonist/pirate/greet() to_chat(owner, "You are a Space Pirate!") @@ -12,15 +12,16 @@ /datum/antagonist/pirate/get_team() return crew -/datum/antagonist/pirate/create_team(datum/objective_team/pirate/new_team) +/datum/antagonist/pirate/create_team(datum/team/pirate/new_team) if(!new_team) for(var/datum/antagonist/pirate/P in GLOB.antagonists) if(P.crew) - new_team = P.crew + crew = P.crew + return if(!new_team) - crew = new /datum/objective_team/pirate + crew = new /datum/team/pirate crew.forge_objectives() - return + return if(!istype(new_team)) stack_trace("Wrong team type passed to [type] initialization.") crew = new_team @@ -35,10 +36,10 @@ owner.objectives -= crew.objectives . = ..() -/datum/objective_team/pirate +/datum/team/pirate name = "Pirate crew" -/datum/objective_team/pirate/proc/forge_objectives() +/datum/team/pirate/proc/forge_objectives() var/datum/objective/loot/getbooty = new() getbooty.team = src getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas @@ -104,13 +105,11 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( /datum/objective/loot/check_completion() return ..() || get_loot_value() >= target_value - - -/datum/objective_team/pirate/roundend_report() +/datum/team/pirate/roundend_report() var/list/parts = list() parts += "Space Pirates were:" - + var/all_dead = TRUE for(var/datum/mind/M in members) if(considered_alive(M)) @@ -126,5 +125,5 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( parts += "The pirate crew was successful!" else parts += "The pirate crew has failed." - - return parts.Join("
    ") \ No newline at end of file + + return "
    [parts.Join("
    ")]
    " \ No newline at end of file diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm index 14c6d1ab0e..3209b9221c 100644 --- a/code/datums/antagonists/revolution.dm +++ b/code/datums/antagonists/revolution.dm @@ -6,7 +6,7 @@ roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen job_rank = ROLE_REV var/hud_type = "rev" - var/datum/objective_team/revolution/rev_team + var/datum/team/revolution/rev_team /datum/antagonist/rev/can_be_owned(datum/mind/new_owner) . = ..() @@ -40,17 +40,17 @@ . = ..() /datum/antagonist/rev/greet() - to_chat(owner, " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") + to_chat(owner, "You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") owner.announce_objectives() -/datum/antagonist/rev/create_team(datum/objective_team/revolution/new_team) +/datum/antagonist/rev/create_team(datum/team/revolution/new_team) if(!new_team) //For now only one revolution at a time for(var/datum/antagonist/rev/head/H in GLOB.antagonists) if(H.rev_team) rev_team = H.rev_team return - rev_team = new /datum/objective_team/revolution + rev_team = new /datum/team/revolution rev_team.update_objectives() rev_team.update_heads() return @@ -78,7 +78,7 @@ old_owner.add_antag_datum(new_revhead,old_team) new_revhead.silent = FALSE to_chat(old_owner, "You have proved your devotion to revolution! You are a head revolutionary now!") - + /datum/antagonist/rev/head name = "Head Revolutionary" @@ -132,14 +132,14 @@ old_owner.add_antag_datum(new_rev,old_team) new_rev.silent = FALSE to_chat(old_owner, "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!") - + /datum/antagonist/rev/farewell() if(ishuman(owner.current)) - owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!") - to_chat(owner, "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...") + owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", ignored_mob = owner.current) + to_chat(owner, "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...") else if(issilicon(owner.current)) - owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.") - to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.") + owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", ignored_mob = owner.current) + to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.") /datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter) log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!") @@ -164,7 +164,7 @@ if(remove_clumsy && owner.assigned_role == "Clown") to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") H.dna.remove_mutation(CLOWNMUT) - + if(give_flash) var/obj/item/device/assembly/flash/T = new(H) var/list/slots = list ( @@ -177,17 +177,17 @@ to_chat(H, "The Syndicate were unfortunately unable to get you a flash.") else to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.") - + if(give_hud) var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H) S.Insert(H, special = FALSE, drop_if_replaced = FALSE) to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") -/datum/objective_team/revolution +/datum/team/revolution name = "Revolution" var/max_headrevs = 3 -/datum/objective_team/revolution/proc/update_objectives(initial = FALSE) +/datum/team/revolution/proc/update_objectives(initial = FALSE) var/untracked_heads = SSjob.get_all_heads() for(var/datum/objective/mutiny/O in objectives) untracked_heads -= O.target @@ -199,16 +199,16 @@ objectives += new_target for(var/datum/mind/M in members) M.objectives |= objectives - + addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) -/datum/objective_team/revolution/proc/head_revolutionaries() +/datum/team/revolution/proc/head_revolutionaries() . = list() for(var/datum/mind/M in members) if(M.has_antag_datum(/datum/antagonist/rev/head)) . += M -/datum/objective_team/revolution/proc/update_heads() +/datum/team/revolution/proc/update_heads() if(SSticker.HasRoundStarted()) var/list/datum/mind/head_revolutionaries = head_revolutionaries() var/list/datum/mind/heads = SSjob.get_all_heads() @@ -229,7 +229,7 @@ addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) -/datum/objective_team/revolution/roundend_report() +/datum/team/revolution/roundend_report() if(!members.len) return diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm index 7f23215d6c..e856a6642f 100644 --- a/code/datums/antagonists/wizard.dm +++ b/code/datums/antagonists/wizard.dm @@ -11,7 +11,7 @@ var/strip = TRUE //strip before equipping var/allow_rename = TRUE var/hud_version = "wizard" - var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices + var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices var/move_to_lair = TRUE var/outfit_type = /datum/outfit/wizard var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ @@ -33,7 +33,7 @@ /datum/antagonist/wizard/proc/unregister() SSticker.mode.wizards -= src -/datum/antagonist/wizard/create_team(datum/objective_team/wizard/new_team) +/datum/antagonist/wizard/create_team(datum/team/wizard/new_team) if(!new_team) return if(!istype(new_team)) @@ -43,7 +43,7 @@ /datum/antagonist/wizard/get_team() return wiz_team -/datum/objective_team/wizard +/datum/team/wizard name = "wizard team" var/datum/antagonist/wizard/master_wizard @@ -307,18 +307,18 @@ parts += "The wizard was successful!" else parts += "The wizard has failed!" - + if(owner.spell_list.len>0) parts += "[owner.name] used the following spells: " var/list/spell_names = list() for(var/obj/effect/proc_holder/spell/S in owner.spell_list) spell_names += S.name parts += spell_names.Join(", ") - + return parts.Join("
    ") //Wizard with apprentices report -/datum/objective_team/wizard/roundend_report() +/datum/team/wizard/roundend_report() var/list/parts = list() parts += "Wizards/witches of [master_wizard.owner.name] team were:" @@ -326,5 +326,5 @@ parts += " " parts += "[master_wizard.owner.name] apprentices were:" parts += printplayerlist(members - master_wizard.owner) - + return "
    [parts.Join("
    ")]
    " \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index dbbb30e231..231ce66f28 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -149,7 +149,7 @@ return LAZYADD(antag_datums, A) A.create_team(team) - var/datum/objective_team/antag_team = A.get_team() + var/datum/team/antag_team = A.get_team() if(antag_team) antag_team.add_member(src) A.on_gain() @@ -206,7 +206,7 @@ var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) if(nuke) remove_antag_datum(nuke.type) -special_role = null + special_role = null /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) @@ -333,7 +333,7 @@ special_role = null N.send_to_spawnpoint = FALSE N.nukeop_outfit = null add_antag_datum(N,converter.nuke_team) - + enslaved_to = creator @@ -775,13 +775,13 @@ special_role = null objective = locate(href_list["obj_edit"]) if (!objective) return - + for(var/datum/antagonist/A in antag_datums) if(objective in A.objectives) target_antag = A objective_pos = A.objectives.Find(objective) break - + if(!target_antag) //Shouldn't happen stack_trace("objective without antagonist found") objective_pos = objectives.Find(objective) @@ -943,7 +943,7 @@ special_role = null var/datum/objective/objective = locate(href_list["obj_delete"]) if(!istype(objective)) return - + for(var/datum/antagonist/A in antag_datums) if(objective in A.objectives) A.objectives -= objective diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index e413f0ebaf..d8ba1f5fa1 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -73,7 +73,7 @@ C.prefs.copy_to(M) M.key = C.key var/datum/mind/app_mind = M.mind - + var/datum/antagonist/wizard/apprentice/app = new(app_mind) app.master = user app.school = kind @@ -165,7 +165,7 @@ var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) if(!creator_op) return - + switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/modules/syndicate/medical(T) @@ -187,7 +187,7 @@ R.real_name = R.name R.key = C.key - + var/datum/antagonist/nukeop/new_borg = new(R.mind) new_borg.send_to_spawnpoint = FALSE R.mind.add_antag_datum(new_borg,creator_op.nuke_team) diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index 978f871ba2..609f5bb6ab 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -1,6 +1,6 @@ /datum/game_mode var/list/datum/mind/brothers = list() - var/list/datum/objective_team/brother_team/brother_teams = list() + var/list/datum/team/brother_team/brother_teams = list() /datum/game_mode/traitor/bros name = "traitor+brothers" @@ -13,7 +13,7 @@ Blood Brothers: Accomplish your objectives.\n\ Crew: Do not let the traitors or brothers succeed!" - var/list/datum/objective_team/brother_team/pre_brother_teams = list() + var/list/datum/team/brother_team/pre_brother_teams = list() var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 traitors_required = FALSE //Only teams are possible @@ -36,7 +36,7 @@ for(var/j = 1 to num_teams) if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies) break - var/datum/objective_team/brother_team/team = new + var/datum/team/brother_team/team = new var/team_size = prob(10) ? min(3, possible_brothers.len) : 2 for(var/k = 1 to team_size) var/datum/mind/bro = pick(possible_brothers) @@ -49,7 +49,7 @@ return ..() /datum/game_mode/traitor/bros/post_setup() - for(var/datum/objective_team/brother_team/team in pre_brother_teams) + for(var/datum/team/brother_team/team in pre_brother_teams) team.meeting_area = pick(meeting_areas) meeting_areas -= team.meeting_area team.forge_brother_objectives() diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 778cf41022..e4f75ea563 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -112,8 +112,8 @@ Credit where due: var/servants_to_serve = list() var/roundstart_player_count var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.) - - var/datum/objective_team/clockcult/main_clockcult + + var/datum/team/clockcult/main_clockcult /datum/game_mode/clockwork_cult/pre_setup() if(CONFIG_GET(flag/protect_roles_from_antagonist)) @@ -189,10 +189,9 @@ Credit where due: return FALSE /datum/game_mode/clockwork_cult/check_finished() - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed + if(GLOB.ark_of_the_clockwork_justiciar && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed return FALSE - . = ..() + return ..() /datum/game_mode/clockwork_cult/proc/check_clockwork_victory() return main_clockcult.check_clockwork_victory() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 67e2225772..697a5c8eba 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -6,13 +6,13 @@ /proc/iscultist(mob/living/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) -/datum/objective_team/cult/proc/is_sacrifice_target(datum/mind/mind) +/datum/team/cult/proc/is_sacrifice_target(datum/mind/mind) for(var/datum/objective/sacrifice/sac_objective in objectives) if(mind == sac_objective.target) return TRUE return FALSE - -/proc/is_convertable_to_cult(mob/living/M,datum/objective_team/cult/specific_cult) + +/proc/is_convertable_to_cult(mob/living/M,datum/team/cult/specific_cult) if(!istype(M)) return FALSE if(M.mind) @@ -54,7 +54,7 @@ var/list/cultists_to_cult = list() //the cultists we'll convert - var/datum/objective_team/cult/main_cult + var/datum/team/cult/main_cult /datum/game_mode/cult/pre_setup() @@ -96,7 +96,7 @@ var/datum/antagonist/cult/new_cultist = new(cult_mind) new_cultist.give_equipment = equip - + if(cult_mind.add_antag_datum(new_cultist)) if(stun) cult_mind.current.Unconscious(100) diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 2938f5abf4..b809f2419c 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -30,7 +30,7 @@ user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common) user.whisper(html_decode(message)) var/title = "Acolyte" - var/span = "cultitalic" + var/span = "cult italic" if(user.mind && user.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER)) span = "cultlarge" if(ishuman(user)) @@ -97,7 +97,7 @@ var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) pollCultists(owner,C.cult_team) -/proc/pollCultists(var/mob/living/Nominee,datum/objective_team/cult/team) //Cult Master Poll +/proc/pollCultists(var/mob/living/Nominee,datum/team/cult/team) //Cult Master Poll if(world.time < CULT_POLL_WAIT) to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].") return @@ -276,7 +276,7 @@ return FALSE var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - + if(target in view(7, get_turf(ranged_ability_user))) C.cult_team.blood_target = target var/area/A = get_area(target) @@ -297,7 +297,7 @@ return TRUE return FALSE -/proc/reset_blood_target(datum/objective_team/cult/team) +/proc/reset_blood_target(datum/team/cult/team) for(var/datum/mind/B in team.members) if(B.current && B.current.stat != DEAD && B.current.client) if(team.blood_target) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index fc6a36376b..ff85499029 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -407,8 +407,8 @@ structure_check() searches for nearby cultist structures required for the invoca var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE) if(!C) return - - + + var/big_sac = FALSE if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) @@ -510,10 +510,10 @@ structure_check() searches for nearby cultist structures required for the invoca message_admins("[key_name_admin(user)] erased a Narsie rune with a null rod") ..() -//Rite of Resurrection: Requires a dead or inactive cultist. When reviving the dead, you can only perform one revival for every sacrifice your cult has carried out. +//Rite of Resurrection: Requires the corpse of a cultist and that there have been less revives than the number of people GLOB.sacrificed /obj/effect/rune/raise_dead - cultist_name = "Revive Cultist" - cultist_desc = "requires a dead, mindless, or inactive cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be given a new life." + cultist_name = "Resurrect Cultist" + cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived." invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below icon_state = "1" color = RUNE_COLOR_MEDIUMRED @@ -534,11 +534,16 @@ structure_check() searches for nearby cultist structures required for the invoca return rune_in_use = TRUE for(var/mob/living/M in T.contents) - if(iscultist(M) && (M.stat == DEAD || !M.client || M.client.is_afk())) + if(iscultist(M) && M.stat == DEAD) potential_revive_mobs |= M if(!potential_revive_mobs.len) to_chat(user, "There are no dead cultists on the rune!") - log_game("Raise Dead rune failed - no cultists to revive") + log_game("Raise Dead rune failed - no corpses to revive") + fail_invoke() + rune_in_use = FALSE + return + if(LAZYLEN(GLOB.sacrificed) <= revives_used) + to_chat(user, "You have sacrificed too few people to revive a cultist!") fail_invoke() rune_in_use = FALSE return @@ -554,25 +559,9 @@ structure_check() searches for nearby cultist structures required for the invoca else invocation = initial(invocation) ..() - if(mob_to_revive.stat == DEAD) - if(LAZYLEN(GLOB.sacrificed) <= revives_used) - to_chat(user, "Your cult must carry out another sacrifice before it can revive a cultist!") - fail_invoke() - rune_in_use = FALSE - return - revives_used++ - mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it! - mob_to_revive.grab_ghost() - else if(!mob_to_revive.client || mob_to_revive.client.is_afk()) - set waitfor = FALSE - var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.name], an inactive blood cultist?", "[name]", null, "Blood Cultist", 50, mob_to_revive) - var/mob/dead/observer/theghost = null - if(candidates.len) - theghost = pick(candidates) - to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.") - message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.") - mob_to_revive.ghostize(0) - mob_to_revive.key = theghost.key + revives_used++ + mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it! + mob_to_revive.grab_ghost() to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"") mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \ "You awaken suddenly from the void. You're alive!") diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 344eb53507..a0e5a9f147 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -465,4 +465,4 @@ if(EMERGENCY_ESCAPED_OR_ENDGAMED) SSticker.news_report = STATION_EVACUATED if(SSshuttle.emergency.is_hijacked()) - SSticker.news_report = SHUTTLE_HIJACK + SSticker.news_report = SHUTTLE_HIJACK \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 050cac443d..f9e8f8d752 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -10,7 +10,7 @@ required_players = 15 maximum_players = 50 var/max_teams = 4 - var/list/datum/objective_team/abductor_team/abductor_teams = list() + var/list/datum/team/abductor_team/abductor_teams = list() var/finished = FALSE var/static/team_count = 0 @@ -37,7 +37,7 @@ if(team_number > max_teams) return //or should it try to stuff them in anway ? - var/datum/objective_team/abductor_team/team = new + var/datum/team/abductor_team/team = new team.team_number = team_number team.name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names team.add_objective(new/datum/objective/experiment) @@ -50,6 +50,7 @@ antag_candidates -= scientist team.members |= scientist scientist.assigned_role = "Abductor Scientist" + scientist.special_role = "Abductor Scientist" log_game("[scientist.key] (ckey) has been selected as [team.name] abductor scientist.") if(!agent) @@ -57,18 +58,19 @@ antag_candidates -= agent team.members |= agent agent.assigned_role = "Abductor Agent" + agent.special_role = "Abductor Agent" log_game("[agent.key] (ckey) has been selected as [team.name] abductor agent.") abductor_teams += team return team /datum/game_mode/abduction/post_setup() - for(var/datum/objective_team/abductor_team/team in abductor_teams) + for(var/datum/team/abductor_team/team in abductor_teams) post_setup_team(team) return ..() //Used for create antag buttons -/datum/game_mode/abduction/proc/post_setup_team(datum/objective_team/abductor_team/team) +/datum/game_mode/abduction/proc/post_setup_team(datum/team/abductor_team/team) for(var/datum/mind/M in team.members) if(M.assigned_role == "Abductor Scientist") M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_SCIENTIST, team) @@ -77,7 +79,7 @@ /datum/game_mode/abduction/check_finished() if(!finished) - for(var/datum/objective_team/abductor_team/team in abductor_teams) + for(var/datum/team/abductor_team/team in abductor_teams) for(var/datum/objective/O in team.objectives) if(O.check_completion()) SSshuttle.emergency.request(null, set_coefficient = 0.5) @@ -101,9 +103,9 @@ /datum/objective/experiment/check_completion() for(var/obj/machinery/abductor/experiment/E in GLOB.machines) - if(!istype(team, /datum/objective_team/abductor_team)) + if(!istype(team, /datum/team/abductor_team)) return FALSE - var/datum/objective_team/abductor_team/T = team + var/datum/team/abductor_team/T = team if(E.team_number == T.team_number) return E.points >= target_amount return FALSE diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 4fcde56a72..890a3bb456 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -17,7 +17,7 @@ var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! var/list/pre_nukeops = list() - var/datum/objective_team/nuclear/nuke_team + var/datum/team/nuclear/nuke_team /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) @@ -69,7 +69,8 @@ return FALSE //its a static var btw ..() -/datum/game_mode/nuclear/declare_completion() +/datum/game_mode/nuclear/set_round_result() + ..() var result = nuke_team.get_result() switch(result) if(NUKE_RESULT_FLUKE) @@ -102,22 +103,12 @@ else SSticker.mode_result = "halfwin - interrupted" SSticker.news_report = OPERATIVE_SKIRMISH - return ..() /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." -/datum/game_mode/proc/auto_declare_completion_nuclear() - var/list/nuke_teams = list() - for(var/datum/antagonist/nukeop/N in GLOB.antagonists) //collect all nuke teams - nuke_teams |= N.nuke_team - for(var/datum/objective_team/nuclear/nuke_team in nuke_teams) - nuke_team.roundend_display() - return TRUE - - /proc/is_nuclear_operative(mob/M) return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) @@ -132,7 +123,8 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1) + backpack_contents = list(/obj/item/storage/box/syndie=1,\ + /obj/item/kitchen/knife/combat/survival) var/tc = 25 var/command_radio = FALSE @@ -177,4 +169,5 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1) + /obj/item/gun/ballistic/automatic/pistol=1,\ + /obj/item/kitchen/knife/combat/survival) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index cbfdb98c69..f20e16b36b 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -26,7 +26,7 @@ var/finished = 0 var/check_counter = 0 var/max_headrevs = 3 - var/datum/objective_team/revolution/revolution + var/datum/team/revolution/revolution var/list/datum/mind/headrev_candidates = list() /////////////////////////// diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 92c01bc241..8b80b9ab69 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -64,7 +64,6 @@ to_chat(user, "\"Come now, do not capture your bretheren's soul.\"") return add_logs(user, M, "captured [M.name]'s soul", src) - transfer_soul("VICTIM", M, user) ///////////////////Options for using captured souls/////////////////////////////////////// diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index b5d908d669..2a3812be3b 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -524,7 +524,7 @@ if(SSticker.mode.brother_teams.len > 0) dat += "
    Syndicates
    [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]
    " - for(var/datum/objective_team/brother_team/team in SSticker.mode.brother_teams) + for(var/datum/team/brother_team/team in SSticker.mode.brother_teams) for(var/datum/mind/brother in team.members) var/mob/M = brother.current if(M) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 1d60f4f28d..ece3775872 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -240,14 +240,13 @@ //Let's find the spawn locations var/leader_chosen = FALSE - - var/datum/objective_team/nuclear/nuke_team + var/datum/team/nuclear/nuke_team for(var/mob/c in chosen) var/mob/living/carbon/human/new_character=makeBody(c) if(!leader_chosen) leader_chosen = TRUE var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader) - nuke_team = N.nuke_team + nuke_team = N.nuke_team else new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return 1 @@ -309,13 +308,13 @@ //Assign antag status and the mission SSticker.mode.traitors += Commando.mind Commando.mind.special_role = "deathsquad" - + var/datum/objective/missionobj = new missionobj.owner = Commando.mind missionobj.explanation_text = mission missionobj.completed = 1 Commando.mind.objectives += missionobj - + Commando.mind.add_antag_datum(/datum/antagonist/auto_custom) //Greet the commando @@ -364,13 +363,13 @@ //Assign antag status and the mission SSticker.mode.traitors += newmob.mind newmob.mind.special_role = "official" - + var/datum/objective/missionobj = new missionobj.owner = newmob.mind missionobj.explanation_text = mission missionobj.completed = 1 newmob.mind.objectives += missionobj - + newmob.mind.add_antag_datum(/datum/antagonist/auto_custom) if(CONFIG_GET(flag/enforce_human_authority)) @@ -472,7 +471,7 @@ //Assign antag status and the mission SSticker.mode.traitors += ERTOperative.mind ERTOperative.mind.special_role = "ERT" - + var/datum/objective/missionobj = new missionobj.owner = ERTOperative.mind missionobj.explanation_text = mission diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 9801e98614..15b76d2641 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -50,7 +50,7 @@ var/list/all_cults = list() for(var/datum/antagonist/cult/C in GLOB.antagonists) all_cults |= C.cult_team - for(var/datum/objective_team/cult/T in all_cults) + for(var/datum/team/cult/T in all_cults) deltimer(T.blood_target_reset_timer) T.blood_target = src var/datum/objective/eldergod/summon_objective = locate() in T.objectives diff --git a/tgstation.dme b/tgstation.dme index 98b6a4dcab..64e5b2c686 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -490,6 +490,7 @@ #include "code\game\gamemodes\antag_hud.dm" #include "code\game\gamemodes\antag_spawner.dm" #include "code\game\gamemodes\antag_spawner_cit.dm" +#include "code\game\gamemodes\antag_team.dm" #include "code\game\gamemodes\cit_objectives.dm" #include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\game_mode.dm" @@ -1305,8 +1306,8 @@ #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" -#include "code\modules\client\player_details.dm" #include "code\modules\client\message.dm" +#include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" #include "code\modules\client\preferences_toggles.dm" From b83dd9330999929f7943809c8440a3996404d2cf Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Wed, 20 Dec 2017 06:55:42 -0500 Subject: [PATCH 177/213] lizard stuff (#33669) --- code/modules/mob/living/carbon/human/species_types/humans.dm | 5 +++++ .../mob/living/carbon/human/species_types/lizardpeople.dm | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index fe0acc4feb..31883b4dcd 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -19,6 +19,11 @@ if(H) H.endTailWag() +/datum/species/human/spec_stun(mob/living/carbon/human/H,amount) + if(H) + H.endTailWag() + . = ..() + /datum/species/human/space_move(mob/living/carbon/human/H) var/obj/item/device/flightpack/F = H.get_flightpack() if(istype(F) && (F.flight) && F.allow_thrust(0.01, src)) diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 257abf63d0..0d006196aa 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -42,6 +42,11 @@ if(H) H.endTailWag() +/datum/species/lizard/spec_stun(mob/living/carbon/human/H,amount) + if(H) + H.endTailWag() + . = ..() + /* Lizard subspecies: ASHWALKERS */ From 2be1b5eb2948692eb1060e2a6931a346a0f88394 Mon Sep 17 00:00:00 2001 From: Michiyamenotehifunana <31995558+Michiyamenotehifunana@users.noreply.github.com> Date: Wed, 20 Dec 2017 23:05:05 +0800 Subject: [PATCH 179/213] Removes pierce immunity from roundstart xenos --- .../mob/living/carbon/human/species_types/furrypeople.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm index 79bbee9db1..fe41c074c0 100644 --- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm @@ -90,10 +90,9 @@ id = "xeno" say_mod = "hisses" default_color = "00FF00" - species_traits = list(MUTCOLORS,LIPS,DIGITIGRADE,PIERCEIMMUNE,SPECIES_ORGANIC) + species_traits = list(MUTCOLORS,LIPS,DIGITIGRADE,SPECIES_ORGANIC) mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "taur","mam_body_markings") default_features = list("xenotail"="xeno","xenohead"="standard","xenodorsal"="standard","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None","mam_body_markings" = "xeno") - heatmod = 1.3 attack_verb = "slash" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' From 2c4e5bae9e36b64f37454e41e46d0aa4e703332f Mon Sep 17 00:00:00 2001 From: jughu Date: Wed, 20 Dec 2017 19:02:02 +0100 Subject: [PATCH 180/213] Fixes grammer issue (#33679) --- code/modules/research/designs/autolathe_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 39fd0bf182..ff2ccc938f 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -681,7 +681,7 @@ category = list("hacked", "Security") /datum/design/a357 - name = "Ammo Box (.357)" + name = "Speed Loader (.357)" id = "a357" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) From 84f51a8cbbd6aad92d06010b4cbead01d8006c06 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 20 Dec 2017 13:24:06 -0600 Subject: [PATCH 182/213] antag team --- code/game/gamemodes/antag_team.dm | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 code/game/gamemodes/antag_team.dm diff --git a/code/game/gamemodes/antag_team.dm b/code/game/gamemodes/antag_team.dm new file mode 100644 index 0000000000..372ee26dfa --- /dev/null +++ b/code/game/gamemodes/antag_team.dm @@ -0,0 +1,34 @@ +//A barebones antagonist team. +/datum/team + var/list/datum/mind/members = list() + var/name = "team" + var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. + +/datum/team/New(starting_members) + . = ..() + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/M in starting_members) + add_member(M) + else + add_member(starting_members) + +/datum/team/proc/is_solo() + return members.len == 1 + +/datum/team/proc/add_member(datum/mind/new_member) + members |= new_member + +/datum/team/proc/remove_member(datum/mind/member) + members -= member + +//Display members/victory/failure/objectives for the team +/datum/team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
    ") \ No newline at end of file From 5869eae8e9ce04c767f9ae0599e79a4f2f012b58 Mon Sep 17 00:00:00 2001 From: QualityVan Date: Tue, 19 Dec 2017 21:56:45 -0500 Subject: [PATCH 183/213] Fixes some syndicate duffelbags missing inhands --- code/game/objects/items/storage/backpack.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 14529b4078..533858b748 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -419,7 +419,7 @@ name = "suspicious looking duffel bag" desc = "A large duffel bag for holding extra tactical supplies." icon_state = "duffel-syndie" - item_state = "duffel-syndie" + item_state = "duffel-syndieammo" silent = 1 slowdown = 0 From 48de10d250307e90246cded9ccddbc70d93d4547 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 20 Dec 2017 21:25:02 -0600 Subject: [PATCH 185/213] Automatic changelog generation for PR #4467 [ci skip] --- html/changelogs/AutoChangeLog-pr-4467.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4467.yml diff --git a/html/changelogs/AutoChangeLog-pr-4467.yml b/html/changelogs/AutoChangeLog-pr-4467.yml new file mode 100644 index 0000000000..ae009bf26f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4467.yml @@ -0,0 +1,4 @@ +author: "improvedname" +delete-after: True +changes: + - bugfix: "Corrects 357. speedloader in the autolathe" From 9273eeb83231e782284c7e3cf00a525f0647ee9e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 20 Dec 2017 21:25:43 -0600 Subject: [PATCH 186/213] Automatic changelog generation for PR #4464 [ci skip] --- html/changelogs/AutoChangeLog-pr-4464.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4464.yml diff --git a/html/changelogs/AutoChangeLog-pr-4464.yml b/html/changelogs/AutoChangeLog-pr-4464.yml new file mode 100644 index 0000000000..17f7d8fc07 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4464.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can enforce no smoking zones with a disarm aimed at the smokers mouth." From 425c4314c0197a49f47abc64c504a0b39f705650 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 20 Dec 2017 21:30:24 -0600 Subject: [PATCH 187/213] Automatic changelog generation for PR #4453 [ci skip] --- html/changelogs/AutoChangeLog-pr-4453.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4453.yml diff --git a/html/changelogs/AutoChangeLog-pr-4453.yml b/html/changelogs/AutoChangeLog-pr-4453.yml new file mode 100644 index 0000000000..24bce9c510 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4453.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "A changeling will learn all languages from anyone they absorb." From f3e7f5f2fd2e1634c7cebc1e9c708944ee312189 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 20 Dec 2017 21:42:40 -0600 Subject: [PATCH 188/213] Automatic changelog generation for PR #4420 [ci skip] --- html/changelogs/AutoChangeLog-pr-4420.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4420.yml diff --git a/html/changelogs/AutoChangeLog-pr-4420.yml b/html/changelogs/AutoChangeLog-pr-4420.yml new file mode 100644 index 0000000000..305d701c7f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4420.yml @@ -0,0 +1,10 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "A few new traumas have been added." + - balance: "Thresholds to get brain traumas have been lowered, as they currently pretty much only trigger if you intentionally chug impedrezene." + - tweak: "Melee head hits deal minor brain damage. Crits still do a significant amount." + - tweak: "Nuke Op implants no longer trigger on deathgasp. (They still explode on death)" + - tweak: "You'll now receive messages when crossing certain brain damage thresholds." + - tweak: "Split Personalities are instructed not to suicide while in control." + - tweak: "Godwoken Syndrome now randomly sends Voice of God commands, instead of being controllable." From 408cf32ddc3cd189656d45fedb1d4c8ffdbae011 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 20 Dec 2017 21:47:52 -0600 Subject: [PATCH 189/213] Automatic changelog generation for PR #4445 [ci skip] --- html/changelogs/AutoChangeLog-pr-4445.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4445.yml diff --git a/html/changelogs/AutoChangeLog-pr-4445.yml b/html/changelogs/AutoChangeLog-pr-4445.yml new file mode 100644 index 0000000000..6dd7a7e486 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4445.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed captain's PDA showing unusable Toggle Remote Door menu option" From 92b018bed7e9c59336464352357e474574323c55 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Thu, 21 Dec 2017 01:08:39 -0500 Subject: [PATCH 190/213] Fixes bullets making sounds in space and water (#33672) * Bullet sounds * explicit lists --- code/modules/projectiles/ammunition.dm | 45 +++++++++++++++++++ .../projectiles/ammunition/caseless.dm | 1 + code/modules/projectiles/ammunition/energy.dm | 1 + .../modules/projectiles/ammunition/special.dm | 1 + code/modules/projectiles/box_magazine.dm | 5 ++- code/modules/projectiles/guns/ballistic.dm | 6 +-- .../projectiles/guns/ballistic/revolver.dm | 4 +- .../projectiles/guns/ballistic/shotgun.dm | 3 +- 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 71befb50f1..4e341fa2a4 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -17,6 +17,7 @@ var/delay = 0 //Delay for energy weapons var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the ammo is fired. + var/heavy_metal = TRUE /obj/item/ammo_casing/New() @@ -58,3 +59,47 @@ to_chat(user, "You fail to collect anything!") else return ..() + +/obj/item/ammo_casing/throw_impact(atom/A) + if(heavy_metal) + bounce_away(FALSE, NONE) + . = ..() + +/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, delay = 3) + SpinAnimation(10, 1) + update_icon() + var/turf/T = get_turf(src) + if(still_warm && T && (is_type_in_typecache(T, GLOB.bullet_bounce_away_sizzle))) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/items/welder.ogg', 20, 1), delay) + else if(T && (!is_type_in_typecache(T, GLOB.bullet_bounce_away_blacklist))) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/bulletremove.ogg', 60, 1), delay) + +GLOBAL_LIST_INIT(bullet_bounce_away_sizzle, typecacheof(list( + /turf/closed/indestructible/rock/snow, + /turf/closed/wall/ice, + /turf/closed/wall/mineral/snow, + /turf/open/floor/grass/snow, + /turf/open/floor/holofloor/snow, + /turf/open/floor/plating/asteroid/snow, + /turf/open/floor/plating/ice, + /turf/open/water))) + +GLOBAL_LIST_INIT(bullet_bounce_away_blacklist, typecacheof(list( + /turf/closed/indestructible/rock/snow, + /turf/closed/indestructible/splashscreen, + /turf/closed/wall/mineral/snow, + /turf/open/chasm, + /turf/open/floor/carpet, + /turf/open/floor/grass, + /turf/open/floor/holofloor/beach, + /turf/open/floor/holofloor/carpet, + /turf/open/floor/holofloor/grass, + /turf/open/floor/holofloor/hyperspace, + /turf/open/floor/holofloor/snow, + /turf/open/floor/plating/asteroid/snow, + /turf/open/floor/plating/beach, + /turf/open/indestructible/reebe_void, + /turf/open/lava, + /turf/open/space, + /turf/open/water, + /turf/template_noop))) diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm index 7432f9f8e7..b3439c86b2 100644 --- a/code/modules/projectiles/ammunition/caseless.dm +++ b/code/modules/projectiles/ammunition/caseless.dm @@ -4,6 +4,7 @@ /obj/item/ammo_casing/caseless desc = "A caseless bullet casing." firing_effect_type = null + heavy_metal = FALSE /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index dcd9d356ad..40c198ec4e 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -7,6 +7,7 @@ var/select_name = "energy" fire_sound = 'sound/weapons/laser.ogg' firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy + heavy_metal = FALSE /obj/item/ammo_casing/energy/chameleon projectile_type = /obj/item/projectile/energy/chameleon diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm index 11fd12da70..de103b399e 100644 --- a/code/modules/projectiles/ammunition/special.dm +++ b/code/modules/projectiles/ammunition/special.dm @@ -3,6 +3,7 @@ desc = "I didn't even know magic needed ammo..." projectile_type = /obj/item/projectile/magic firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic + heavy_metal = FALSE /obj/item/ammo_casing/magic/change projectile_type = /obj/item/projectile/magic/change diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 0e6ab6c23f..bf941108ff 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -96,9 +96,10 @@ /obj/item/ammo_box/attack_self(mob/user) var/obj/item/ammo_casing/A = get_round() if(A) - user.put_in_hands(A) + if(!user.put_in_hands(A)) + A.bounce_away(FALSE, NONE) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) to_chat(user, "You remove a round from \the [src]!") - playsound(A, 'sound/weapons/bulletremove.ogg', 60, 1) update_icon() /obj/item/ammo_box/update_icon() diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index c4ba7a33b7..680c86ff5c 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -31,8 +31,7 @@ if(istype(AC)) //there's a chambered round if(casing_ejector) AC.forceMove(drop_location()) //Eject casing onto ground. - AC.SpinAnimation(10, 1) //next gen special effects - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) + AC.bounce_away(TRUE) chambered = null else if(empty_chamber) chambered = null @@ -125,8 +124,7 @@ to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) AC.forceMove(drop_location()) - AC.SpinAnimation(10, 1) - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) + AC.bounce_away() chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") playsound(src, "gun_slide_lock", 70, 1) diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index f642a94284..563b3d9ad5 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -40,9 +40,7 @@ CB = magazine.get_round(0) if(CB) CB.forceMove(drop_location()) - CB.SpinAnimation(10, 1) - CB.update_icon() - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, CB, 'sound/weapons/bulletremove.ogg', 60, 1), 3) + CB.bounce_away(FALSE, NONE) num_unloaded++ if (num_unloaded) to_chat(user, "You unload [num_unloaded] shell\s from [src].") diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index d3b1815d0b..e702013233 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -57,8 +57,7 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber chambered.forceMove(drop_location())//Eject casing - chambered.SpinAnimation(10, 1) - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, chambered, 'sound/weapons/bulletremove.ogg', 60, 1), 3) + chambered.bounce_away() chambered = null /obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M) From 6c4d687db6c0ccca8a13275d59245b8313ed67e0 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 21 Dec 2017 07:11:32 +0100 Subject: [PATCH 192/213] Immovable rod abuse, smite and event trigger. (#33681) --- code/__DEFINES/admin.dm | 1 + code/modules/admin/verbs/randomverbs.dm | 8 ++++- code/modules/events/immovable_rod.dm | 41 ++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 65d028ea34..7622fc0ea7 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -145,6 +145,7 @@ #define ADMIN_PUNISHMENT_GIB "Gib" #define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" #define ADMIN_PUNISHMENT_FIREBALL "Fireball" +#define ADMIN_PUNISHMENT_ROD "Immovable Rod" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index eed265598e..8f13d887aa 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1207,7 +1207,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!holder) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL) + var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1229,6 +1229,12 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits bluespace_artillery(target) if(ADMIN_PUNISHMENT_FIREBALL) new /obj/effect/temp_visual/target(get_turf(target)) + if(ADMIN_PUNISHMENT_ROD) + var/turf/T = get_turf(target) + var/startside = pick(GLOB.cardinals) + var/turf/startT = spaceDebrisStartLoc(startside, T.z) + var/turf/endT = spaceDebrisFinishLoc(startside, T.z) + new /obj/effect/immovablerod(startT, endT,target) var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]." message_admins(msg) diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index b933e566be..9612fd8018 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -12,6 +12,16 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 typepath = /datum/round_event/immovable_rod min_players = 15 max_occurrences = 5 + var/atom/special_target + + +/datum/round_event_control/immovable_rod/admin_setup() + if(!check_rights(R_FUN)) + return + + var/aimed = alert("Aimed at current location?","Sniperod", "Yes", "No") + if(aimed == "Yes") + special_target = get_turf(usr) /datum/round_event/immovable_rod announceWhen = 5 @@ -20,10 +30,11 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 priority_announce("What the fuck was that?!", "General Alert") /datum/round_event/immovable_rod/start() + var/datum/round_event_control/immovable_rod/C = control var/startside = pick(GLOB.cardinals) var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY) var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY) - new /obj/effect/immovablerod(startT, endT) + new /obj/effect/immovablerod(startT, endT, C.special_target) /obj/effect/immovablerod name = "immovable rod" @@ -36,18 +47,28 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 var/z_original = 0 var/destination var/notify = TRUE + var/atom/special_target -/obj/effect/immovablerod/New(atom/start, atom/end) +/obj/effect/immovablerod/New(atom/start, atom/end, aimed_at) ..() SSaugury.register_doom(src, 2000) z_original = z destination = end + special_target = aimed_at if(notify) notify_ghosts("\A [src] is inbound!", enter_link="(Click to orbit)", source=src, action=NOTIFY_ORBIT) GLOB.poi_list += src - if(end && end.z==z_original) + + var/special_target_valid = FALSE + if(special_target) + var/turf/T = get_turf(special_target) + if(T.z == z_original) + special_target_valid = TRUE + if(special_target_valid) + walk_towards(src, special_target, 1) + else if(end && end.z==z_original) walk_towards(src, destination, 1) /obj/effect/immovablerod/Topic(href, href_list) @@ -60,11 +81,20 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 GLOB.poi_list -= src . = ..() -/obj/effect/immovablerod/Move() +/obj/effect/immovablerod/Moved() if((z != z_original) || (loc == destination)) qdel(src) + if(special_target && loc == get_turf(special_target)) + complete_trajectory() return ..() +/obj/effect/immovablerod/proc/complete_trajectory() + //We hit what we wanted to hit, time to go + special_target = null + destination = get_edge_target_turf(src, dir) + walk(src,0) + walk_towards(src, destination, 1) + /obj/effect/immovablerod/ex_act(severity, target) return 0 @@ -83,6 +113,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 x = clong.x y = clong.y + if(special_target && clong == special_target) + complete_trajectory() + if(isturf(clong) || isobj(clong)) if(clong.density) clong.ex_act(EXPLODE_HEAVY) From 30fb3f8f5c6e7b770331b09a5035ee1963f51176 Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Wed, 20 Dec 2017 22:33:54 -0800 Subject: [PATCH 194/213] Fix pulling things across space transitions (#33689) --- code/game/turfs/space/space.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index b1e8215592..5399b748e6 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -139,9 +139,11 @@ if(isliving(A)) var/mob/living/L = A - if(L.pulling) + var/atom/movable/AM = L.pulling + if(AM) var/turf/T = get_step(L.loc,turn(A.dir, 180)) - L.pulling.forceMove(T) + AM.forceMove(T) + L.start_pulling(AM) //now we're on the new z_level, proceed the space drifting stoplag()//Let a diagonal move finish, if necessary From 39ecfd64dbdb1db91a375027b302a1ae1073f5d2 Mon Sep 17 00:00:00 2001 From: MoreRobustThanYou Date: Thu, 21 Dec 2017 01:41:01 -0500 Subject: [PATCH 196/213] Fix smoke machine runtime (#33697) * Fix smoke machine runtime * Woops. --- code/modules/reagents/chemistry/machinery/smoke_machine.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index 86205caba5..7941853a91 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -46,6 +46,8 @@ var/new_volume = REAGENTS_BASE_VOLUME for(var/obj/item/stock_parts/matter_bin/B in component_parts) new_volume += REAGENTS_BASE_VOLUME * B.rating + if(!reagents) + create_reagents(new_volume) reagents.maximum_volume = new_volume if(new_volume < reagents.total_volume) reagents.reaction(loc, TOUCH) // if someone manages to downgrade it without deconstructing From 82114e753d102bf6a39a8159924e15d2259ff2cb Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 21 Dec 2017 01:43:43 -0500 Subject: [PATCH 198/213] Merge pull request #33704 from Fox-McCloud/arm-implant-fix Fixes Arm Implant EMP Effect --- code/modules/surgery/organs/augments_arms.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index e23e7ff7d3..a90923e58f 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -61,7 +61,7 @@ /obj/item/organ/cyberimp/arm/emag_act() return 0 -/obj/item/organ/cyberimp/arm/gun/emp_act(severity) +/obj/item/organ/cyberimp/arm/emp_act(severity) if(prob(15/severity) && owner) to_chat(owner, "[src] is hit by EMP!") // give the owner an idea about why his implant is glitching From 636a87ab8f9283817fa0bced4392294f8c4f3cb5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 21 Dec 2017 01:45:48 -0500 Subject: [PATCH 200/213] The runtime condenser now supports taking input from stdin and outputting on stdout --- tools/Runtime Condenser/Main.cpp | 419 +++++++++++++++++++ tools/Runtime Condenser/RuntimeCondenser.exe | Bin 216064 -> 258048 bytes 2 files changed, 419 insertions(+) diff --git a/tools/Runtime Condenser/Main.cpp b/tools/Runtime Condenser/Main.cpp index 732318269b..3f8678992b 100644 --- a/tools/Runtime Condenser/Main.cpp +++ b/tools/Runtime Condenser/Main.cpp @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* Runtime Condenser by Nodrak * Cleaned up and refactored by MrStonedOne * This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance @@ -387,3 +388,421 @@ int main() { return 0; } +======= +/* Runtime Condenser by Nodrak + * Cleaned up and refactored by MrStonedOne + * This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance + * of the runtime will log the source, usr and src, the rest will just add to the total. Infinite loops will + * also be caught and displayed (if any) above the list of runtimes. + * + * How to use: + * 1) Copy and paste your list of runtimes from Dream Daemon into input.exe + * 2) Run RuntimeCondenser.exe + * 3) Open output.txt for a condensed report of the runtimes + * + * How to compile: + * Requires visual c++ compiler 2012 or any linux compiler with c++11 support. + * Windows: + * Normal: cl.exe /EHsc /Ox /Qpar Main.cpp + * Debug: cl.exe /EHsc /Zi Main.cpp + * Linux: + * Normal: g++ -O3 -std=c++11 Main.cpp -o rc + * Debug: g++ -g -Og -std=c++11 Main.cpp -o rc + * Any Compile errors most likely indicate lack of c++11 support. Google how to upgrade or nag coderbus for help.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PROGRESS_FPS 10 +#define PROGRESS_BAR_INNER_WIDTH 50 +#define LINEBUFFER (32*1024) //32KiB + +using namespace std; + +struct runtime { + string text; + string proc; + string source; + string usr; + string src; + string loc; + unsigned int count; +}; +struct harddel { + string type; + unsigned int count; +}; +//What we use to read input +string * lastLine = new string(); +string * currentLine = new string(); +string * nextLine = new string(); + +//Stores lines we want to keep to print out +unordered_map storedRuntime; +unordered_map storedInfiniteLoop; +unordered_map storedHardDel; + +//Stat tracking stuff for output +unsigned int totalRuntimes = 0; +unsigned int totalInfiniteLoops = 0; +unsigned int totalHardDels = 0; + + +bool endofbuffer = false; +//like substr, but returns an empty string if the string is smaller then start, rather then an exception. +inline string safe_substr(string * S, size_t start = 0, size_t end = string::npos) { + if (start > S->length()) + start = S->length(); + return S->substr(start, end); +} +//getline() is slow as fucking balls. this is quicker because we prefill a buffer rather then read 1 byte at a time searching for newlines, lowering on i/o calls and overhead. (110MB/s vs 40MB/s on a 1.8GB file pre-filled into the disk cache) +//if i wanted to make it even faster, I'd use a reading thread, a new line searching thread, another thread or four for searching for runtimes in the list to see if they are unique, and finally the main thread for displaying the progress bar. but fuck that noise. +inline string * readline(FILE * f) { + static char buf[LINEBUFFER]; + static size_t pos = 0; + static size_t size = 0; + + for (size_t i = pos; i < LINEBUFFER; i++) { + char c = buf[i]; + if (i >= size && (pos || i < LINEBUFFER-1)) { + if (feof(f) || ferror(f)) + break; + if (size && pos) { //move current stuff to start of buffer + size -= pos; + i -= pos; + memmove(buf, &buf[pos], size); + } + //fill remaining buffer + size += fread(&buf[i], 1, LINEBUFFER-size-1, f); + pos = 0; + c = buf[i]; + } + if (c == '\n') { + //trim off any newlines from the start + while (i > pos && (buf[pos] == '\r' || buf[pos] == '\n')) + pos++; + string * s = new string(&buf[pos], i-pos); + pos = i+1; + return s; + } + + } + string * s = new string(&buf[pos], size-pos); + pos = 0; + size = 0; + endofbuffer = true; + return s; +} + +inline void forward_progress(FILE * inputFile) { + delete(lastLine); + lastLine = currentLine; + currentLine = nextLine; + nextLine = readline(inputFile); + //strip out any timestamps. + if (nextLine->length() >= 10) { + if ((*nextLine)[0] == '[' && (*nextLine)[3] == ':' && (*nextLine)[6] == ':' && (*nextLine)[9] == ']') + nextLine->erase(0, 10); + } +} +//deallocates to, copys from to to. +inline void string_send(string * &from, string * &to) { + delete(to); + to = new string(*from); +} +inline void printprogressbar(unsigned short progress /*as percent*/) { + double const modifer = 100.0L/(double)PROGRESS_BAR_INNER_WIDTH; + size_t bars = (double)progress/modifer; + cerr << "\r[" << string(bars, '=') << ((progress < 100) ? ">" : "") << string(PROGRESS_BAR_INNER_WIDTH-(bars+((progress < 100) ? 1 : 0)), ' ') << "] " << progress << "%"; + cerr.flush(); +} + +bool readFromFile(bool isstdin) { + //Open file to read + FILE * inputFile = stdin; + if (!isstdin) + inputFile = fopen("Input.txt", "r"); + + if (ferror(inputFile)) + return false; + long long fileLength = 0; + clock_t nextupdate = 0; + if (!isstdin) { + fseek(inputFile, 0, SEEK_END); + fileLength = ftell(inputFile); + fseek(inputFile, 0, SEEK_SET); + nextupdate = clock(); + } + + if (feof(inputFile)) + return false; //empty file + do { + //Update our lines + forward_progress(inputFile); + //progress bar + + if (!isstdin && clock() >= nextupdate) { + int dProgress = (int)(((long double)ftell(inputFile) / (long double)fileLength) * 100.0L); + printprogressbar(dProgress); + nextupdate = clock() + (CLOCKS_PER_SEC/PROGRESS_FPS); + } + //Found a runtime! + if (safe_substr(currentLine, 0, 14) == "runtime error:") { + if (currentLine->length() <= 17) { //empty runtime, check next line. + //runtime is on the line before this one. (byond bug) + if (nextLine->length() < 2) { + string_send(lastLine, nextLine); + } + forward_progress(inputFile); + string * tmp = new string("runtime error: " + *currentLine); + string_send(tmp, currentLine); + delete(tmp); + } + //we assign this to the right container in a moment. + unordered_map * storage_container; + + //runtime is actually an infinite loop + if (safe_substr(currentLine, 15, 23) == "Infinite loop suspected" || safe_substr(currentLine, 15, 31) == "Maximum recursion level reached") { + //use our infinite loop container. + storage_container = &storedInfiniteLoop; + totalInfiniteLoops++; + // skip the line about world.loop_checks + forward_progress(inputFile); + string_send(lastLine, currentLine); + } else { + //use the runtime container + storage_container = &storedRuntime; + totalRuntimes++; + } + + string key = *currentLine; + bool procfound = false; //so other things don't have to bother checking for this again. + if (safe_substr(nextLine, 0, 10) == "proc name:") { + key += *nextLine; + procfound = true; + } + + //(get the address of a runtime from (a pointer to a container of runtimes)) to then store in a pointer to a runtime. + //(and who said pointers were hard.) + runtime* R = &((*storage_container)[key]); + + //new + if (R->text != *currentLine) { + R->text = *currentLine; + if (procfound) { + R->proc = *nextLine; + forward_progress(inputFile); + } + R->count = 1; + + //search for source file info + if (safe_substr(nextLine, 2, 12) == "source file:") { + R->source = *nextLine; + //skip again + forward_progress(inputFile); + } + //If we find this, we have new stuff to store + if (safe_substr(nextLine, 2, 4) == "usr:") { + forward_progress(inputFile); + forward_progress(inputFile); + //Store more info + R->usr = *lastLine; + R->src = *currentLine; + if (safe_substr(nextLine, 2, 8) == "src.loc:") { + R->loc = *nextLine; + forward_progress(inputFile); + } + } + + } else { //existed already + R->count++; + if (procfound) + forward_progress(inputFile); + } + + } else if (safe_substr(currentLine, 0, 7) == "Path : ") { + string deltype = safe_substr(currentLine, 7); + if (deltype.substr(deltype.size()-1,1) == " ") //some times they have a single trailing space. + deltype = deltype.substr(0, deltype.size()-1); + + unsigned int failures = strtoul(safe_substr(nextLine, 11).c_str(), NULL, 10); + if (failures <= 0) + continue; + + totalHardDels += failures; + harddel* D = &storedHardDel[deltype]; + if (D->type != deltype) { + D->type = deltype; + D->count = failures; + } else { + D->count += failures; + } + } + } while (!feof(inputFile) || !endofbuffer); //Until end of file + if (!isstdin) + printprogressbar(100); + cerr << endl; + return true; +} + +bool runtimeComp(const runtime &a, const runtime &b) { + return a.count > b.count; +} + +bool hardDelComp(const harddel &a, const harddel &b) { + return a.count > b.count; +} + +bool writeToFile(bool usestdio) { + //Open and clear the file + ostream * output = &cout; + ofstream * outputFile; + if (!usestdio) + output = outputFile = new ofstream("Output.txt", ios::trunc); + + + if(usestdio || outputFile->is_open()) { + *output << "Note: The source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped.\n\n"; + if(storedInfiniteLoop.size() > 0) + *output << "Total unique infinite loops: " << storedInfiniteLoop.size() << endl; + + if(totalInfiniteLoops > 0) + *output << "Total infinite loops: " << totalInfiniteLoops << endl << endl; + + *output << "Total unique runtimes: " << storedRuntime.size() << endl; + *output << "Total runtimes: " << totalRuntimes << endl << endl; + if(storedHardDel.size() > 0) + *output << "Total unique hard deletions: " << storedHardDel.size() << endl; + + if(totalHardDels > 0) + *output << "Total hard deletions: " << totalHardDels << endl << endl; + + + //If we have infinite loops, display them first. + if(storedInfiniteLoop.size() > 0) { + vector infiniteLoops; + infiniteLoops.reserve(storedInfiniteLoop.size()); + for (unordered_map::iterator it=storedInfiniteLoop.begin(); it != storedInfiniteLoop.end(); it++) + infiniteLoops.push_back(it->second); + storedInfiniteLoop.clear(); + sort(infiniteLoops.begin(), infiniteLoops.end(), runtimeComp); + *output << "** Infinite loops **"; + for (int i=0; i < infiniteLoops.size(); i++) { + runtime* R = &infiniteLoops[i]; + *output << endl << endl << "The following infinite loop has occurred " << R->count << " time(s).\n"; + *output << R->text << endl; + if(R->proc.length()) + *output << R->proc << endl; + if(R->source.length()) + *output << R->source << endl; + if(R->usr.length()) + *output << R->usr << endl; + if(R->src.length()) + *output << R->src << endl; + if(R->loc.length()) + *output << R->loc << endl; + } + *output << endl << endl; //For spacing + } + + + //Do runtimes next + *output << "** Runtimes **"; + vector runtimes; + runtimes.reserve(storedRuntime.size()); + for (unordered_map::iterator it=storedRuntime.begin(); it != storedRuntime.end(); it++) + runtimes.push_back(it->second); + storedRuntime.clear(); + sort(runtimes.begin(), runtimes.end(), runtimeComp); + for (int i=0; i < runtimes.size(); i++) { + runtime* R = &runtimes[i]; + *output << endl << endl << "The following runtime has occurred " << R->count << " time(s).\n"; + *output << R->text << endl; + if(R->proc.length()) + *output << R->proc << endl; + if(R->source.length()) + *output << R->source << endl; + if(R->usr.length()) + *output << R->usr << endl; + if(R->src.length()) + *output << R->src << endl; + if(R->loc.length()) + *output << R->loc << endl; + } + *output << endl << endl; //For spacing + + //and finally, hard deletes + if(totalHardDels > 0) { + *output << endl << "** Hard deletions **"; + vector hardDels; + hardDels.reserve(storedHardDel.size()); + for (unordered_map::iterator it=storedHardDel.begin(); it != storedHardDel.end(); it++) + hardDels.push_back(it->second); + storedHardDel.clear(); + sort(hardDels.begin(), hardDels.end(), hardDelComp); + for(int i=0; i < hardDels.size(); i++) { + harddel* D = &hardDels[i]; + *output << endl << D->type << " - " << D->count << " time(s).\n"; + } + } + if (!usestdio) { + outputFile->close(); + delete outputFile; + } + } else { + return false; + } + return true; +} + +int main(int argc, const char * argv[]) { + ios_base::sync_with_stdio(false); + ios::sync_with_stdio(false); + bool usestdio = false; + if (argc >= 2 && !strcmp(argv[1], "-s")) + usestdio = true; + + char exit; //Used to stop the program from immediately exiting + cerr << "Reading input.\n"; + if(readFromFile(usestdio)) { + cerr << "Input read successfully!\n"; + } else { + cerr << "Input failed to open, shutting down.\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 1; + } + + + cerr << "Writing output.\n"; + if(writeToFile(usestdio)) { + cerr << "Output was successful!\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 0; + } else { + cerr << "The output file could not be opened, shutting down.\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 1; + } + + return 0; +} +>>>>>>> dbccf52... Merge pull request #33702 from MrStonedOne/rc-the-unix-way diff --git a/tools/Runtime Condenser/RuntimeCondenser.exe b/tools/Runtime Condenser/RuntimeCondenser.exe index e53102f219ae3b742e7189e864747027d1a71094..642efd09f035bac9cb105b9e920cf4b020c4ba22 100644 GIT binary patch literal 258048 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 HAqRNS=@|;+ePerS|&ZyGHzjVb~ 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%0DjQmYtJ|3}N0*dH? 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

    4{-Kyq{FW$h+ZN8KDR#`L zmfeo*vug2ieT@=7eXm>v^V#1;0O8%grDf-bSEePSBQ5(-&;M7n%(rRbU`BMKo)a^L z`M4#WIEnlS7k`;oY1RByt0tXK%$vjHoabsT{+2ZrXFa`YF3Mq#p144bHj3tIz|Qar zpr4Gyq{~m!&@U&ZA14kji3?2&)I{Ma^&R%S!4UnE`oHz4{~#gZ(}d3$eaWdh?nHlO zj6Z>4-%T8|agBbkKG@fBHV|`lO#^F4wS-Unj-?zSoT#%@M)^%>EA&4Zr^W?}qnBK+ zBMZ!urf}*gt199s%BCEn8%+TbYw2RLL=aiJ zm=syMm@G>QS(KQpmM%84$T68ny5l?PXz1u$YU$!TEL~)&BfdCZo;S&nrHkFIrHe`C z(#2#JEcQ`L7u6!h?4_N*w0iMDukDsMa~3NZ4^@AjUfHAib5~_2=g*stf4o=UlX|TB z{l3QyxRQEI=?RYTb|)fF9Hf_0FDm1umJ6-4<}$-7`woqV2GiBxz;xsAHMR=bJVsPV zs5e&@$-eL|#t{5)AYZJ}UwKyNq!vdT58O+knl-A=6k{F=g~s5++5Ak+J_UR@*YBQncduq`Q_HHniw*9^L}Kyh9rASX=QZtj zhm+WH;clYI(pKf6eOj1l8LGPU&XrNrELIzjv%huqWr1EKiE@$ki268x1q}2ER#4Y(;R%X?#v1)H;ij zI`7YI3$c|()6zq+0#d_SmOQ06X=ZWsBmUgxLHj*-@qCTP#dD3%NcVbcsFPYXb18D1 z7pDN9p`WCMy7_a@$SJ^QBvT=WKktlQKY(XP1N@A-;?bo3PyIT*ESGBc%DAbwSD z82bBHQ(so^>7TXA{e^SocSx)DnA87j2A&)c>s05P7e^O|i^HUJPXT#rOgTvZ!0$fc z&pplUMBZzS>majcxR0QoN%)$OfmD6QxLCf@pUes0?aw=Dq|C6o;@&=mzN(YGy*2N5T z3tQM{K)vDpJ>ujUbC1ZU=WEyiPJU%fu55tVVyMWxV@Q4de)q+wP%lD9QK#;aKi)35 zMTZ=yAkw5FIcqnFKbbaxG?75^`^-R+mywWLmnjR<<{avD!0(uL3Je@FR=W z=YgCxp7x3J=_HJt(Y@#@-^EyGZ8WyvSpGbu^8M$z!la~xJX<6n%ZTcf#x{I7SpSh8m zWag)dolRnG#R#VC#pk@*u=ehOt=1bxG(l! zF%*M-w`@h(FMdAitDD=qISr>in6!G#9sTRx@7#YyeB-K#cl5{G@Vqa){Y2;Yxl-k+ zo){P7lE}Q4TG_AEN|l`8x+GGI+ttfQqF#y}qF>~AFr%hT^3X?A(;epSjU3}6*3(}x zEp^Pt-A3P?lvMCJ#_weGVEyN2MgwxH4;l5x#M4-P$WRtuPnu->l;NNZ)3~Heo%+hL zc55gpIbxztX0yK~7V8|?04ZCC)z2ju>4aBsPp5qjY;nen;zwodRU_AC7y$ZQx<>zl+3^U#sVQ$xv6V!_{ z9+51(*C7jO90z-aEOZvD}$vT&cAYFi%~F7=NiV{?pg(B|Ah8zOclBE3~+2^d*;b`opZ<8L9LhFfMR#X;X6z?-MvuGmZ_DiE##CG$bGfUS~r8ecdOKN<$bWRV2(Rnj8F@z=ZxNqyc`$9X_eVoLpiy_58lT&j1f zm6O|Y^~YlTCH-UMTjQl)qM1LQqF1tZfpf;E`UA@l)-2DUEKmO|&-GcJo>`v0^y@fb z`ibJCP|t==P@{!Pi?0sF7k3MFQXQqZSq}xqCg)5w8a66TLQco&_j6!X5$K?7qsQr`ZO9dK9Y7}I{Fn5HXwii9H% z85cI=c5fWt5W4&B8OjkE+_5yp82T>Nm?UL!z(9OVm$8w2yG(qaLjFsh{^5+h_5ns7 zl>0@sML{|RYQ%&RVJ!ifN-x?(cirqezbFSDb)2GMpw1~AGH7C3R`+vzVN%%h(4d3o z_RzFxo@7cseq^*ai;q=fnlpW&s71rh?s0gHKnxdcGlz1|1^z64OOJ_9i}oJ#g<=+U z4{Qrxym-;Khm+n@_P_SbD>ZZx`M z&_Cf+UpWesNlw~G&b)rvIx6~aSkYLcsq7xPFgOO?a7^m<1vQDG4uh7NX0?3BoW7{) z9#4Jo#&e}_Cr)FJ55;!agvY`va$&BL$xfWYM0HQ&Osq7^vUBhCyM!gdKjKBQJZb9U zuErbYTk}BdTy-fm2YGRB6%$2COccE=?{5sf%c!jQM$Sy1iMl>0A9K>d}?0-h_1ebj!{J zcQLR?tqWAO{_JNzD~_HK{4w?ywov;63}vcLZO+;p$cpmkp5(?Cz5co4zME&Jyy0l7 zKOgJQqsP9l=Ka2OPnX7y_Z?`-81xARuOB|%QtaU9HNUrM=E^b8wmNG!A!K^P@s@K< zVh_cPc=Xv;Z+vFj8_WI?Tq*C|hlqK4%25Z>afrAFn2~1r8e7r_H4-UNhDmUi-_6X) zv#ok|Bge92H>WWR*sQ-^5u4_2tn9?nG=KJq3H~w9o>?MCyWXt4z8+W-mB#MI6LMKk zLq#l$xGwR!^iR;LXE*7&`-H}RM9<-pY5S|X!4&;)VAL~0!Dl~HzFJ1)o$y3u=sh;U zA$`xFSm9J!W0lipq5fI$WjeG>7JuVfs^6g8lL7B3e{K_3s1x00x{?m*Qf~IU_v!AY z%^fo;SL{GZgI?97A0fjo<}1!M`Q6Ra1~nAZP&CfeC;y;T-;+X?j~xFP9vp8;$ZZ+z zpZo*%Y_+7lyX-yPy|2C{I*`i>-a)W(U+O#4i88HmS%Mzz9}{4ByDt>ue>BkQ`#5I& z(!c82hgi(_oDii-H21_M#aY~U+90kKXo5Ma2+YD%{k+Qyv$HD9&?3F+kltXIB?VdY zSFv<=q4|@IF zn}|Hl`s9@`U4LCTeki2@j{7IWN&Hiv*IRx%9-T~avNjgXlKA;LN8f2VJEOCh6gg;W2lZ@vHH_3b{&>3^2K-3djuz7^{J=jhu*P~*5$=xf)v z;?_am3c>$V^sS=h%lftv62FSRU34s>Zj-y$MuG#FcC_Z1{>jQoPKa$`Jjb|9t|HvFx?A;m zm&aLszKbWm`h2`6w)%WmuOlP$*VWxJd~FHNXP%^o#$koaZqC#KnMX#&E$&q8m^MB{ zqu!s-uhq5E@@XTJys^cx(?SQGukP^~gVbz*c_QI61gB#Z+EyI>idL;@)BL&XLNBsT zAA&>Q=Z)XJLB+dh%jGe~FmJH6`urfzpz8BOJU3OJAL{vS_4(1xucs1c^?CR5#Ojad zRiBSy_7jKVPC=QK7+;(a^nfZ(=hHbDFN@b%`!J5g=B#C^lwR$&pd77cl7jOxmKAN+ zy`(&1MK9)hD!WvFJT!e(uW_NMu`mT6Rj2&kt$sXx_NAy@7~HQp3{#XFgMX6gAlK*WqBs(7i=WgS>rA z5}n@|Ok6b=w}s&Enr@hPHlY%H#%!6?|2ty5G=AsMYe%!P3AYh>-Ql`aATB)4-WP1Z zs2}##O|HMlP-i=G;Cr9L4Y%RUC8CZ-^##_Sy{&LWR7E%alR(wZ&6@++J2!{3U%}P6 zV`;pedsuHs-D3@pH>y<-DNQMi{8j~GdNHZ0Tx1-W*UT3rzjsq%T9eZ^h!nVg%juJf zw)2bE#MbJ3rn}f)yHD9zQ=E4wD8o6~zSMv0IrkyNYXvcQd-$-Q7o_kWSI#IJfx=uc*Zeu2T zdD_ZjOYV@tbff-e{l|SBbqRa)+--E~W%3OSI2*JtLbtrO2>sj}SC{NUA1|@t+Y3WN*9bLGsi+h{y-d6v9-=lv&`ff-;j?V9Le&wKTjE5cz;*TCHwQhF-NM!M(1~?=19>i}z1uB{COCsKJXYdl~e)G^K0nT$$R{{W7%@o*(dB zIQOwi|PpAE(qlbiI`0HZs2~qHl`Yx4h_z_W@Y@745?s7#&mGGspPh ze3@fqg|Ktw&q-+iXh&?QZ_%N44^{0R)|ehT(W@AN(YfOdeb0hpN!eVNYsAUotmK+K ziT|vfJ1V#cRF7~x4B!+y=5!H)OQe~kNs62`LlO7xHrX; zj|TTT(K!w7Euw5hb@xMaE_D(}bS0V+zv3K^v+ixtb7`RK>Z^7$bvl_=RcXohQB57R zB)55o!=fm=i=x~oigF){a=%}_P`c6$6&r4MZx|pVPetM{4VI%p6@NeP27lE?ZY`vi zKH$$=glLSzve>)mV_#~XY zO$v(n4(@e7BKH{ZaTaQ4c$hHXUzo55iEM>#rA%9QNo_|pqD=Xqj51{rr>RUowUp^u zf1WamGCj`%R#~uc7WFI2H2eHGOPQWm%JeL2Vw5udRL`zcx`T$bQbK;3P_;p-g3QCX zKR}HA*&iXvh5o9KL;aLW-Eg@|HAGGN@u>u!zND_|!OAGmm-IS*~@3qK(vn~ILzN!-%J3*_OG|zAKXuJqti$5hz$li*ucOg-?m(e*cK)(S&p@Kr2Sz2OwIR&sBhCMM|5B^@kD{lb zyVvm{g-*Z&ge3-==HJtX(`n;FLuQt=+U`vpO8adQUT>QzxyYOI>l;u++;QR0+s(4i z!AgMjRYdB% zh?H~X?V~QrwdCro zyOnOnIGuHFugfH7U#SlvIv33eN00t3oV`i(S8l8KO?nqn8z6s%vo@PjLHP88>D=Cd zIJc5ckmU+t)j_aj+S{gt`_sz>dTYBt`@JH~2&59|>y$umy`n&$btgyZ*=u!#w5mHF z$~EY7>!&y{4V6X$rxaW>(tgeIv}dB%g@59uC?g4k_V zu^DKdyEz8=uhemE`4F9wJ*f1I@bY6*yCgI{NKhhx-uELRQ{U0Ok|nlirt3$fQwzgo zbm07YBXNngmR4vp6ShRjEdul?6PlQ?g{;6ZmJ~bWs|Q^q+;Ngu`{-((P52~`IGlDg z?FdreSa}_vW%SosOrbvE$VY&c2lVWndXpz=tnO}<>Tw>AZIxJacRIX>9LHE;XY}>w z$~Uk;_xp&LR=aN?=B|W#T}VWGB*Rm#)!vdp{Wt~PtMWpM^yLXC7rwFu?-gxN_Nvye z&ItR0(WCBMHagU$dc+8C-2SMcERD6JcUG<*Tx&LYAR%ly7vxe*Nh0WbJ3laZlg0 zH#|Ml-t;7-9rs?-Rh!L7GqJ0d4iM0#Y0@2Y%t|>pb4JbQ7^6JN3Zn^d(A%x6v?p9Q z*T^oTuIb9GK4d1!t<_ZV3#kXTZ~=I6()2BIGx&kHEpk)%ftW3FbNGSiEiQp5R_}LW z5gxQnVsloj{>Ja*QgAbOka!a+B}Ud9fMklh(~oO_W@19U-$Op`b#1F zDv+cg@vtIZ-J0u3B8#|^0U}Zv0HY}cn|iG5D>d&UcdqeEw*T7K5$ACJ0#)cflX{@G zZmF>QC5c9H{3S(#F#RP(gzz0k2;X0llx^1QO}~@Uhu^nAgiDcqUP}js-#smU3ujHT z70-*)2S};UU@i1@L+WUAJ&A+%D$kHl9w`RRVHShN4wjUvIM#k}M7kV#@LS&H82xG9 zbJ&Dn=ufedWjgtwWZ1m*mGbeD@a0Nbc}->I%`0T(&3}~@m65NOkNVX835Q>T?H2Ro z;~g7x%#&7-|42oRN|(y%@HNIr?F6}?ot-Ma#w4kkpv$U~7^A1?M_(1uu;l&?PYUHA z1!PvwH>7$}Eu?xPOj13OE&V9>EfdOg)n6?N;j{pBhHN!D zTO2h7)4Ot#+e;(RcL&jpDfKKy;T~vOY|r%KXgnAJdDmz!9`%f7?+%;z27PiJ-P{Y# zRWjIHp-xkl#=b}jqnI6yr&(#l(&Ze0eyL0k8VlK4(;(Dq#vF{goK1dUZ;@6_c8&YU zB=xNob-}WxW!+Z9(Jdveiq1O)gtM~jajLPGjRWR#RZoxS28n+~$dZ&5jdby^5A89I zGC$}W9_vjo{)x$4`s{l>+$E2hg4U_VpCDj5YoyPxRKzB87-WVRx2z~#7PInfWs$vB zXsYpz;q8k}owcKB7p59>zJZjIIahwBCLbTqHD^7?sn&chPH9AC$a?0Rj1`fzjdYCc zJXb5c{hdEt=IyQIScW@D;x^CjuLBbvW1C}4^b{mvf7U==0PbD9yYHfv1F z+xtQv?)a3oH>z~iE=&DgZZ9-%Xq;+YmbrT3-7%cjJ^)rz9C541+}%IA&iN{BZsO7N zEM7*yrr#q4;Tg}$W0pDJ0YE|NnjNd%+vMVrNTYXdfsnwl5H^nlOQzEuW?j`Zg|g?@(!44^e}^Zd$)&(GedYgJ9jK+S}=y~HnIkbJIfe?wM{iXKy7ni zhg?gXRh%(RZE%LNM;6^wd~IOd^OD*kuJ678qZu4;iSy24zJ7dw0(yL@}-jU^Ex?P%pec88(e$Q{eFdU|8ia?dPsN=%J0xDnCTP^|NpZ#mvJ zxfNVUS!{{%_GRy0I=5)OAMJ^&`6r1~FHWQshSab`ne+4q79m)^U%z{+TR`qBrYplXHEghp8Wy4))oER!2DD zb9$Y7l$$tk#kRaUre5q}pYk=byY5LilO!G4H1{dBmd2S9o5S4n2)MD9UNpiC`@GGhQgCyzX zU#R~ZwBMh*I5lcg6FOB0T=G?2EA zFD(~Lzn-`JX+ppxb|V)0N5`8bPq#C!c&Ny;^C`Ioku}aEE2$N1{mt9^3inblu;1hK z&E(Z9v-x@`wx`4vm=I4O(<^6Kz0zvGlyj@imlYqrQrN``GN|44kAa64sc3q&yX~^w z9PMtKZMVN8(N>J#wB6o`xH+F%ieSG|NPDSbt?%$=7H{kjFLiJq*TMap9o%n|m~yUC zF;zTirs;g@+KBIp`L-L}4g2=wkYdFoUp)x_KB4Bkl1?KmuJ_nJrEPkpg^jS{db92N z2dQOyhKk!YTzC_T-PK$1nrMD1uNt`*q*rEmceFY__k9xf zwT4rVr0!=0bIto&R8)<(-v9y6ae*jr93v1^n0FtW%Q$Z@kQtt_m$}K2dp&p6)_Fc2 z`Jw0L+Ebnns1G>x!0An#I^lFA^v#*Gl=nd9MFJD_3llB~910Ier;`#MP|IJNgMsYb z!Q>P=7b`cxT+SK%=0&-NdgU5nbxV}9mOay&Z?jl01_GRe6%Gb(yvSwGmJhaOwfp!Y z5MUoRTlvICAaF>`zr!5JUK9L{VBk@SV2d(xWK=l#17++kuHRBd_Kk*v&nV+|@vux8 z<;!vKag4(Hz*Dun(N|aVH?`52`D^-Wb&2|fHY^We*{QW;a>*0RDFcCtD!svCbct~x zS+$IFl#xDDIM`VjpknTWRbQRVUm}Z<$WFdTWZj6&Mw`N$%DWu2RCS7lNwo zaBO}LHuo3*&B0bM;(tB75IM03~ylVhY@$^VbUzf1i8 z()KUKAo*=3I-k7G`3tYtTCWd9@+a@-%KJ9qW4Zla_?G3e`LIu)P=~)X{Bc-<60k@DM%$?!Iwa{e_qEeIq)%uhiP!NN zN$*t&woZb*{+md8cSh2itkRP;83g=R$ABv(V3Gv<76C2(2Lf_GPVgTTnML}?wsbwU zPgRRLvs#Sn7}ZFLYP;}xTzgb1Mxj4BLVuG!;SgjbbPRj(7lcg=5;mcoes3hvX^MWy z1p$xYHz;FcRiUUvpJTDacAwF*xJSAk|Zuhl24A=)Q9Mq4V; zHi=L?NwgL}{z8#k#<$yzN7{}1+Ks!~jlWPvrIcR8s1ki@lVamWlZ{%(q(A#PNqZz| z&CU_MaO68N#~3~63iV-+1laiz0gh0kgar}**Idc}x5WQ6@&CN#-zwzT2z9d+zlCHN zGY9{^x;Rs?b0zR82|ULNOnOqj!>_mb*{n}EL9js`gWVv(T0}Mm5iF2>D){({%l!Xy zD_*KU#7kUz%w~bgX&RzW*yDgcIgLJP_0`V~KHEoBikRbq&tX=^nBY}nR5jevoG(bs zO`>RiK~+=yxk7w#LAQ!eg|u|&d;16u$(BQXhV^;7P+c-P8OpG1#T_(|$oFuwsM0ZHyYmU?x zi#PX+pYs!zw{l{{`?>uw->V{oH|agjW(H`_U#@DZ_IE|F>P5}8h9R(<#f@(>76 z6ye|_5{qec+7Vq^hexUC$eR?$Z4zCR@NbmRwrhKDuBaMI9J_XlX@ea_rp3$fOZXoq z$tNoRC&brX;{T+WN-p<*MEno`GyYFfu@3DzBfdI`{|jOob-DlN#eaSb{EDu%Wx~?eGw>HtyAMd9$?p?r27!dnB5#50y5La4iG97YHwRsj zc-H9?){@>e9pmXF@gzy5zs63S^mTU(=ZrtCI*Cdwck2^&60~^>zBfu!{1+;wB31oS z{_8vV->Og8g8wbzf2h=o-+tNuH%hQLVlN=$Gc29sA70aGQyeM0WM zjuA%qDMY4S<5NLrMObaO&K!C%We_-mu4v}YER zv}?ohFT~dM65JLXsO-(bZP?B9EGE22Jdtwyjzl_HGVo%DNF($~KeJN2Buc%iw!K8& z3tf}seTmfj*Yt)xw`_iYK6C3SP79WFpw8_71`+Vlx$ z@b{SbTP4D?#P(+=!i|N&otOJh6aN>amC5?D|K?zFPqVy|K$D+4^$FW0|AdR^p|hKb zq)`-sqeCPj-}I?z{~1H5{;=(EhwY%MiPhfyN+RhlOnjB<1<{f44%@pO{!_Y$?Hz23 zvyV&oRZ@b>&G3QjmS8ja6>N><8-9vBj~3sPr5tih-;y4*-tJTNSBy8A#*Q?0l~6^J z(cX3_o4XP|j{5&pd;PbHq?umR&UF&#FI1v-|DvyUcDMQ3s884jT|dKfM6P})AqPs9 zenv=kxCTF2Wcw!{BKJ>Vtzh zR0pfXH0{OY>(~$75Gx?Rz4)K^@BDW+{R`Oshy6SM+h|mXU%>PqE?SqBsm*&qY&pzH zn@i>QSgtPoS&6sr1ifT zenDOaD4&OmlX6~^SV${5N43aC?_n3iMcU*{;&0>)2MJ+1gh}SJjkP9o*kqnG&)-$Z zn9h*_?Gr@B;i7&26@FakV)5eyDKx~&U->n}Hd`hmUicyIU*^YaTua;#domKHC1N^d znO=~9iXY<3;zz4`Y4KxF3jC0l5q?N4CO^d4h);zd8x=nc>?S`>V^aL6u2#bM@Az@% zzrv5xaTY($kU~SO{5AQ}W|@rh^a5WL_b>C~m&b)47b0OaOR5`UV=U7P5>W9&d|CWR zQZFrjT!$KbL0(4qA+ebJ5NG53?eHT#SL7p(Hzq$4F)4nOGnS!pUe1qQ)2_Rpi@_cz z=z9b;#^Y`J-lCwG?=j7viTQSAW{bR5G_=qC+OAdnF@FCf!M>2!SF6{2;WWN=G5nhN z(2sDM={Y4tQ}iPZvEugVe7siPN}$eDF#UNsY0a9s_XUZpA$I-s_iJL(vtnM@fZ1QO z58K{d&+ylnAry9#P(P7SdleKNQ81~h)uuDKIRhpL#pnhJI99al!~wFJh%T)$xt;8V_7Hq_;>D>f_`$D zD$0MaaHc3lW~>~I!oPF7h|R?QosGMQWs0aSII8ggpw6=j~JI_I$4|vY=Tzw{5>&d4OjoPX*7@Jm2Ek$ny)HojeD5-sNfKNjw{^_2Idd=U$%4JjFau z@I1}4f#;_@bv(y--sSm}M>|J)JpFm@;u*s;nWvEF37$1P-{JWY&rY6$JS{xud6L@5 zAI}(`hk1&4p5R%{^F5xQ^6ccXe~TZ^)UKubxewgT^G}|&*dO4zjpu2eU-SH!C&0Vs zcv>IG)arO#4`yoR4`phzb68Y^c`a@mdA9M`zh5?`YuElIU2}h$u07+;(2~B9p*26B zVZYYysm{=z@0O{p!Oy??Rq$ebX}Q;Pt7nM^bA`9mvtVI?tDvHytYYNlb{BpN7nCmW z6u3&t%F11p-pcZVxt@Y~T6X@D1q;0kT@?j$y%m)U%1T`&1&azwu;jOF3p9zODGyx`L$bFE#VsC z(jG3zpSPfNzH5P^JKm&UQkn-rbLSRRRu+0oN|yGM#T6=VuEKoMn&L@}>yaj8VB-ExcTlB`v_Zn*_#E#6(~DX4Jemo6nk9x)Qh@USTYCI`&?n8ML9&Iigo1tVP&bBEG|%8I%0 zYMzTCb>&wSxbjO%T!j^73tb+3jvfE-q{*(bLSD}sbFDj^5>M0T` z3rZ>rTnj2)b1TZq%M0e+8V`3b&4(?im*!w{nTII7r3)VS627CbRw7L*e_8nz^IY=^ zC{D!GE@v~`mjhf9pG_$-neH7Ni2D-1MVF+a(l+0J`NfGN)a$Zztt<6-4nj;F$S)~S zwM8q;hY`f>sqhMDuBJ?FD1L9J?#m;;P1!a{UYUx6}X|~yAIz_^7w8G~QzK-y%-)pC>a%rWffY7b@v1y$A z$4srMEM4N8H7CEaVB|Xq;koT^_HW=VPwVf=_nvf3T0DPlQu?ivQ0Xnzjr) zW8pt6OtRkJ4N5%oShghLzlnVnm=L9D8$gOo+XljJm9F$!_F=!-a+mc6l8zIUcnF4$ z$<#W568=dG`+;rPPgv-)+&_XI2`_aeu`E;T0lL6$U^-X|3jO&OeIMd~GVZKcQvR_j zdTy}%{VB!_f30PAff7H?S`p!{x7@jjLb+d0Mwa284z2|=z>VO2;7;&Puo=7-Yy;h3 zVtJ;P4Z6Uw;4tuRFbli^ECL?_J>W2K71$lz2;Ky41+&09a3FXB91a@bgJ2t&2_`v0=9uygHo=j zXDzWZQxy7$!~P7o29$cU3G5H<2Dyk( z)xR6Tlh{{)t)L%_Ta>BkU^2KG90>LThk?nU)UUqaWb75-Jg^q51y_OVK>Jr-P_b}9 zr5XUx!COGjpXGvdzFh@N(9)G!X_@qki|BtXS}+%(ly@>L=%DH~^PQ`#f~yPV^# zTuNIW=_Y9N7BJGFl~}6!$ps6`J-oNtmHdkN-i7oog(gX_Jby0z=+a1tag{76m3l-Mzd|)9v}mPs>6nt9G;|AP)FDLDMQ0SCwexmX zgtz(g=8pViUI~! zj6)z-rDwS#f0dqD-cqQVTV%1mooAPli3~7CtMHafp;_`UtD`*FnX_n8iNWhx!fTbm z%2|rn3(0l<{DN7P3!adoj>zdO@oaWUw9*34;W+|~mhJ?wUvbkj?By9F6q;NXYr^<3xCE{oHX(RG-SusW;x~y~;SI~uOPsX#f zyg-v7^}Jb(I-$EgzQr=~oHa)z9e0cWjGjeiF0T>o?-!IZ-fNdVJpy%W%OGCPO?Tu?)W}7UrWZWL8DVl9^?4 z3*SV(8M0m?-{$bRZ~+qz73h{l!n6e?B?a>t-OgFc{7WSX6`(CBC+bl-)R$K*$ma!G zk_>n%%1T6Qn2JUGSbgq-0x4RJp>=*o#b@!(Wy`xIyJ~_&{M&Xr^R~Ss+2}}9woR3b zY`f+bEnq4G;$&7v#e*Idt;ah%$&RAZ!CmQGTcpW~T{r9zBb2Clq|4hBX*X<1QE{mD z#wLNPaY@Eadwboo?2&P**gMLt*gGoD2#YTjq4qkZYJ<|;%pT3V%)LFP_IOksblG(f z)q)7jLm|`NTZ+PN1ta#$h!T;ey`##iT4E2I+uJ6IPPJxcT5A4>!hxgS5^9}U^D6R7 z5zb1F$dn{Ndy5!WSPIx0wu>53O2kvJ#A7C>nrc(ONL0jog|dlb0g0k zJkp1i{@^t{2|Ou0sXRoXeszDMA9o~OyPHSm6XYlTF8K}N8G8F2sl)EP>+azr^5@K* zS5P>=XhHE~B@0W-${(+&^mrF7Ub0lWsr>r&=yp}t#Ds+S_%8B`Gk={s{_yqHe-|FHCJEVty{OGq$DT5tIS_l^}9lR8JVNUxX1D$D%uef+o^M0m-vLlu2(tD zzqnT)x<^}k?Fb%WL-ljd?UM2N+UK4daW6PDHTA_&|JpqYUUI1lJ<|K=#fG(TRM-*j z9Cn8LhVPT(KV&nb`S+{%lQNUC>HY>|>`%-wey%;IwPbFArFOJ|9p2BaT-ai!p%PNz zU9sPmA&UBW@SAusT^q!+F)Bmbjs2nMjL7_6L5FzlF#oTjOS}BvK*oaRzsuiT$)3eX z^WXieWu$WXzf1ksF!r+lMQLB{U&k1pVr*vri)Q@yRsPxGUH`8Zdxv~~xm1h(zm|Zg zn#eykbbY0tU4nv7MYaEnj{0i^h9CU!`He69 z=*3N&fBcgzFa7jqTYvtGUvB%=uYa@sw=eJ5x$BkR?f(6%uhrG>*}Lx#`x_b$9DM!I z9}gdCI(qE*i9fyZX7gKbzjN}>@4naa{s$kP`pZXuHG&_9PXEW>{@(h@r=Okq$Jujj zpP&Edg)dl&a9LZG)a~kPy7%bWEBV^q*Y&ynhQ6+TH>UI-aMR5Lzjn)@!9#Ant-TE$ znKtU4d+$sC*G=<`NAqURn*FceKe?=G`HKJU{Qq~S|9{PYv(qsyYy5=!CuTqJV9rB) zYs{T8b=vetO#c7t_x~gK{}?m070iAXFr%7Euklu9ZcEhcs-}%Csmzd14x%(MkF6*u z5FA(FnIb)5F;BA1Wy``9>dKHYu~@tc0lSLJ18C6npsOMf`xzk}n{`~{w|Wfhls9?fTx zImB71jV>vxEV%5gHxLi3n{!hFV0V@gWKSd)_r3KT8wQt!e^>f7Z+^<}qG%A#yxIUmR;sn1&2 zNplQ^0~?tqFzu#iN!heZ5p;Z?TUk(HrD=M7fO%BO`}j)aV!^yi94C&>&M%Loc1ivz zBWAkBt7$j-Kbq$HmN}0-5R|_0P%s7@4#t96pv-&cfbtz-8YuJovqAZOPz1^ts2r5> z&Js}OxvN2$uU-XS1+E3<`_g()z87o+<@>-EP{vW)z-z#rV0W+%RP+0w%>OrmGEQm+ zrSsha_67}5zAv5#fZ166y1iTwu0uBdj!4cqE za3r_^Oar%o_k!EO`@lLd9XtePfX(1&@Dw-(ya2kvxbGrAV0UmF=mN)sgTV>laPWR` z3^)9z#Py6J`7faQ@}OgRB%1`2)G3-0C$3qfsJ4Z*bLTyr@$x_NGliv zUI06TaqE#AusawJy1+zmFesDE;jRCE?_zs4^9LV!D(P`a2}WjE(4=blxx5);Ce6~+ywRpw}EM3BN*kP+`um2DKH*v zmG|HUdEXy8zR!Cw8H@+}gK6MUFlr$5$a`?2ya%U=`(Wr1cd%UC!DZq;lzJ)d;5u;! zH;Vf(>ZQ1YJH;K`C+@@Hm)OCRVjl&+#15Vjd%6b0v4e?%W1v$o3pxcSLZ@I3^%IO) zM*RePgVR9Kg_%SlIvf&NPi1~nchSbkuLOHDxCDF~tOb7st_3%O8^CXXTfigWcJNPN z9e4~p1il0|gS)^};6AVwJPBR^r45Mt0cV1M-NDyD7uX1vLzlEkgRy@f90NWE4#i#C zxJR+i1qVWJ6j+2E7HA$&zD-wyJHVm5j|SIccY|5jW57+=rLEZpJ_F|99t-Zq4hvOZ zK>7xa*nb3`0KW;gfYLUd27d##fj*SBKSLS8h99- z2fh!MgYSULz<0q_;9KB2a6gz%Ii`Rcu@`_#uuI=#EA|p_8upvOo!E=yJ^6_T_hFw1 zuIK%&U=#LAu$uP?;7RQ3Km*(io&kRWY8zP-10;ekgUR4-LCQ_~D*dsq0;TUEeVU=z zrO&X6coV@<*ro5Wk@wOE%EIme4c?=Aw8_|i3C;$k@39v5u3!oF2f-r34Fs29F9u!M z`+~LD^TGA_zY1K7ohqyPkWO#|_GiH@;6sA=O9HoJe;8a#JVU@b>=ocP?6-r5urC3n z&omNj#{QJNCww#o!Xq3)X_U;7;hi z8eEJ0JKzRzGPni&E?CF=YryT;17I`p-X-qXmxGPG?+zZqJ_T&T-UDpLJ{3F#t_NGe zHK6vROzn9f3EToUi%D7XP^CET@O z5%wA2aOk`d^kAO{R)epCYr(zXMsORr4crOVfv(@DVT)&_24$_v%n_ocY?dIF9Qc+cY%%A=YYxBZvanVpDpg# zhk-5Fe+agLPlB^?zZp#0WUe{t1D0VQ2s*&w;0It9xE7oYz5vb!e+`y^KLwY7W5HUm z9L!g>iS-*w>RJ1tYN-ZKil}d+X(ObzhDQV|>w&ibu(k^oKuV@FZOHjGuJFpdRsbw#>?B$mK3d_C1im%8@r&6_^tUpyN z=LAJ6kvpYb1x0(Xbj!j8N*cxfm~x+E(ODVEmuNruXT?)urC(^#yU5CCky?=^{1j;t zK1i+B&=F?5`AUmO{>*$9TJ#rL;TKx`c+B$um=#~8(h@?S8L!7mzubyvzLk#0vU@E0 z`C@OSZ|1ksdcV+epKs+)_$?GxlAicv6^_cO$i)!KJ_9$AjUk%Zj}ZA7LJvcv!jzH8 zO0S4~h`cS7JR&PYkV@%qh`fkd{D{m9!ByHp zk((h%qv%MH9dQ>LM1I69I#Oh42)&RT%#yDmP$2P$EDfPmlXyzWjhLma5}6u;Z*dp7 zl01rkk*y(^#E;0Am?d42F`+^Hh@1(3?pNl=F=wcFMBc<*@+&eo1j@3MS;9_MVMX>N zT?s4lC-jfOEHWrOF?lX|H+8PaqQoiuVI>e|w~Ak6atNu4o)@_kv+zM=Q{oglMLvh% z;{nVfqe5pkW|31dKf>RM*gTe8h}_!cE3!KT-$JLnAA)b8ZHda4X?{ZaH_amBwjYsm zDQn?_$hwrN@KfYnXcKxCDw?wu&6TRG&2o{tAn8hbBlSVbQRGVMgqX)+mU@QbnDxr^Z`L2vy;Oy@>yPj^$0|SJ#UyN( z%9B|i%(~rC=0+=hW40Y;*_(C7EPJyL+Ob?a`nP%ERwFC34HLeKT$p*zQZj4iIYZHB z<~c*vV>8cYIhc9oPE5j9s(NYWp<{X`eP$l)v~!f?*=bKyrDmo*Nzq}ZJ<&=}_-&?P zrajK8r@}Ln$EI#E$5xfpjAGuHT(;8~qsrGzBU{xaI}KAWNE)ULm}!hw_20~&Nyi*j z){@5MWn`vjmVljJw&ID&xA7{sX1qDd-HbO|m4L~&E5|Ff;?jIfR`tS+*OXr~-Z3gq z9pk#R3>K;yb}5YyBDuCaPq54)&r=k=!bh>0C1>Yrx|J8ROr&1g{1W{nVdTyKY43aB z7s8ou z%rz9x(D^rQNt)g=Hda6$^vUM0MQGNQgEpD*6|nbaJOC^+o~L`8jJHDFQ)BT9F;kd0 z7wMi4OE1!WWi!5J7>9Ji#4kb5nemG)>CE$CWy#AiaoCK<($^R~(>%hgRIbH7u@v^V z2>Iq*NxtGVa7HwlkHoxaHrEtFk0_mFh%;ySYc0$CD3Uz$t*2q8Ao);w^twoP)I;VtS)uC( z)7Mg>mES;@DSiI7bzS@u*&7pZloO}_&G<~>2z3t3DW-BV@OR?1hv%ze|!s4vI%s7ob z7N@^vyh!hBmcB}t3G+)>z04nCy373ULS4?xZ!^-s;W1w`N7o1D zXneC7hDN*@U#0gk^KI#` zx#nOiS>{WzK4WqEOE@&^m^h^OY&G`MCD_`E^*8NLP&$oQwtiv# z!PbVA`j}(u$5MS>U_LVYYi)xy-P#7W9$XE1o9j4MFPq@XJyWxPe!EBh}{|uCEl5rQWd_I#hvs>VMK(Y9sYQpB=Sl#ri_^$CRwu@B4C3@-%hI3sLj*&Dbo=npPWW5jRUf*s}Lh8F?o>9 zq!O!i3$O-x0lnqK4atLS1Mxy$vX$1pJsjlu|Af5p1tsu7QlcKC{-#l9(|d+y{37%j zYZviJx=@aGkfkL}$j4uEHZWVpw8WGXc^)L2Qq;g^3>)T^=}0XCHJV@cwIV@zk_PQ7 zDYBd7K~#bY*;Udf_BU8E74(bHTREt=7`hrh#)9^g@`*>HN>U*0rP-HhdeC0d{I^o4 zMr#<-cCv^xXOm50c0M>`({2y#FwySmNOK15cF)I7+DLhs*a=wxJzG3NuGtQ1J#kqG z*;3C0XEz%SA1)Hm{V+SLP>*L}hv0qyA^8*j``NSSI)wBLxewt4O5ehsz1AU&r*wqJ zAJ@p#(5ose?66Uc4EhQ^M<1=U< z7lp}eCi;#>ZW*}67qPGtM0d1rKyuN2ZuQ>H@BQyk~wP{J>R8JaHY>glv^@?PRfGRnOtHqK1Vhc&sM=TjpZW!gbrbF z+(Gm|0)5GiJBT|dGB#@F%$eiqa`KQ5u0)%Zk%iN6Zk}J7aWEdF+oCBsI=dhn7o6_W zDqPWYUhZHH@B1MO|L9gfH%Vvd=-eco(Og_v%+13A=1iO!Uz!)d_p~Z;PP&j=oKr!0 zfgCg&`FaSPa*6=2n8ol6xB#Da({t&3b)gxmztN$0Uzhh*HD=JMn)TTtx0HfWYm40O#TqCXr@#-?rtVBWmxfxz@NI-LNnB-=b(Hj1pl#igZr zSFQ50_mmgwx{EUCe_Eqt;+_~;s%tpivwewK&<@%kTda>53Q0@Jr)E0D$_MWmo$_G} zMvuJ4U>c)cW=Vm(^?HJISba3N2h+|%t;FjrP@}yyvc|OTOV-B}yC<&BGTKHV$v7F| zN`#A1j-KH!fY#G0Z9dvgJAA1~r@bylpT-dzA*>#a{E%BQy@p?=A zW=s4QOZ-+#d|PCY=Hr%l4C(+a{R|EH0J-=_+Oh=wG7I|?`W#`z1+3E2jUHHnzN7wG zV4iKL!Yo^I30G8t-PDqm0=2iiu$W9EzG+dehZQ;OJ_i|;o`VcMM1~pK5h=g8Odni? zMkth>o2Q#sE+60Vq%oGCvqCSssw9w4Ws3rN-~fG)%QBW1tSK!4m3$yjetwyezlP_Q zuMq&n9KMUPlI+g%VtfoBCm$bTfla9_#*~8D1QQA74@?_0+rXCO6vOPp+QZOeo`9K$ zg@e&EN>9eb2{XiZ!YNs@cNbhfs2D`YObzXR|AJ& z+|@N#udj(4KOP>zRaadFMd$gNjG8*k?un;K8B1$0-@_@$$fyH3TVhRJ4N7rv3knJf zqN5M4DlNUFv^2yYKsML)6g_t*n*e{)5|4U1n4W0FlY!$$oKCusmCG>FX>0}%KNmJJ z4e=r)J_qp%#LZJ)wHBOaOM15je~*!#iL#U0f^|uVn|v-a;>1sd5vLw$Fyh3|RwGV) zb{lcxXTXS`g?RKcjOMwB+l=^P#M6y9@la#L>Dhmy5hq!-SmK?C(}^OgYru#T57E!E zbmA?^h!g!Z#OcHm@n2xX3BTTm6aF?MPWau3Q`?FE-H6j^BubBdj^widHA7aGxZjA+ zM|uEpIzd6a)gw-)5~%DpBTnf(Mx5#$G~)EEIs96?)C|G%vKB zp;DwLETM8HUiQTaKFjU-FwVX2)oLOAdoUXGqst})Wt^G>ZE;5qC}%^Ex5JX6ZTw- zbcU=GNs^vvk(6j`l4XJahp|i?nmEK0(V*uaBjq!@L%WCjmZkj=+Uud7W~E2Qp+2JB zM614s^FgO6R)Gp}#x#uWc+wLP+TWv8y28uRYLwQTRGxg-ee>yQ2|aP9=kfc;Bk9s^ zFX=7ejwB0aTiISR?JfG6i6p&7P5{j({52nWouuc_gL7u@dm`{lqvZJO^B19Nq$9(9zPfJJ$w=i zPM0MMt5^%qFt& z%f>#P0;BOl{si?5&7-E=Y3G%mveLe8I1SQ!+Nm^gO&^2KC750Y^)sDRpc>ftVf|^& zg|w4v)9W@Z5uJ;t^9WWBDJ`gb)AY8Gl_9+#OG6`=&2a~sORagtA!`}YFy~*gjiK|e zHP2dR-+6cn+Cd{DI1kelGkKq?>ukPWB?Yy@-wb_3#GL7jkQ zfEqv(pc}9kKr&sf|GGdR5#5D2zQUJVgs?QHJU2(5*q1LauLvMcH_MmfH!LUvH_Mmj zV_U$C=N6R>yN1 zbCCG)iadRvOjWT~liBwM6>OZH3^?z6&iKxxzO}fF#5dr*isxe-|K5@0U#hay25SBmWG*G{AJgsQ?v)WE7r)cs1YxK=$f<{fnok zp=|c*6_z+P{4_3`zRp;ZPuW~{5q%B?-}A)QN3Lxp9svYcIyJd?C5x}7Uv)r>kyc3` zd`4B8;SHK7W#0fSYE(;swVvg$Oz>P`qtw3 zx(q(0s#kBRf0(*8dpMu5J~EZ;)rDmhm1upSu)MSgAE>4eR^yA$rPRK>0^2AoSaE`_ zw*}d-&^QnqTy}0r>6-lrD!VdJfzN)@7jyLP$ex+TWiQIiq`A-NyW!pry&st%=`ZOf z6MP;;x$Kfv#fA9pbx~1yA@z86P#8?hEgiQ{-g)O+a#0o^an4zp7Z^==;dmnoka)B9 zLzt9;k`BQ$WxZeQ?7*60d`>wRA3!xf)Ko@a2ewh$%{+Vv2+tQSYHeZwXIL@zTg5QW zsLW6s_mSBF=!T5f3jMQD=CHM8VqDu&hd&NZhD|& zlNZlVhNCD*$`j4IsM0yY`xghMpwverT6I*j_G!}8jUvQ&o3cHzFqNHfb& zo|T@p4CVEKcGPRZc8o(>9PSeUR{jW&_@>KB&svu9;v?`J%R-O%3gEuTNTYo7veKb4 z);b6$3P8RT)nS#7nde6&Tt3!3v#lgIqLqod2Ms<e8MGJ&}HS* zTAuRiftQN%=0!5f#C7>P&1r*d>zd9>1C zx%jn93ti%I2=`IlR(&0rM{7Bv6&;zvi701Y)UH(AryFUMZ(dfOs7xaAMv_CVg&y(N zfcpY~Nzt3B^q_WOL`+nkK``n zJ_8U=lW<4U9cy`_*#x{A3r&(uJ?h8t;0KnSEgg26$ ztYwK_C+dxVGuT!tlZbl}VDd&dBlV@V9MReXynuxk@m7KR+Aw;AHxh5wvP91|E`{3` zMy~_+Jz?|+ZzOuwvP3TpGKqRC*jDP-INT=!!sSP}BlWAbJkiWR-B}izRHgv;RRF7A z6W&NXTFVl>Cg3%P(QCzhXBa)g8;PE^EYa%#-jIbJwK=*6>oq|5*dpAK+H5UPGzWl} zj`HS3d@RF#0l=IS31=jov6iFqQBf&eV;HSw+;6kcBAk(ES<4Zv1mN{sXi;1C;6Cc@ zPU~t_8FL1^~9?NG=0#E#P^;H-Oj~ksJ@m0$dO11pEw`l@iI-0iFiL zr$*w3(<8Yz01-1IxibI-fJVT#fTUUY-B~~(vV4EAs`2pF0dO#4|}$Ys{ijxxj#-Di%1YfBH}){KH1YoWXK0Jwe&S4|uC?FTcP_#@~AE#jBt zFn~Cv4TaICG(W(+&M)xm@*q}rM~1=zpfV~6I0J(-)B7g=dmyip~xlS6G^uQj(e~>sZBO`+(KB()&@6MQF-A%eQd@|ptWnCe7`Q}Z z!zj2lu$y$%8TOOtw;rI3pOB4fLejo^z8ht!t^Q;drXeIg=rTjIPhvk}d3(d^BRoG9 zFs^~bee20YS*j=2s3-ma^;8-41Q1#;s)uNt?`P=+Mp%xJXN0#Sqg4~<-wI60S@j|c_v`8K#n>NHLtt*Va$#*;CLH+ZFWh_N~vj4XF zLCd^SZycQ$3A9XJ(h#S5v%=_`y!c_COkJoC!!heLachh@sm_>7^|p>uCL4W3Z7o1Z zbV`k|%IG`N?O%RWf4!lvRK98y+*r`1>ja}75h2l_ zd$Yc#1JLm6rP-e?SB~Ca1E6L0*AU{wV|0ILdnk=~=))K``^z7OV^(Y8wpehBM#DAw zgUU7@0M~C;f^ds-^tN??mf5x*#EE`?7=23f1I%llV|2QcJ`K`MLY!#G2(1^TQQfpo zX$;FV@d$_H>Q7~TJl6=%Ho_buEHc7NjBq_dqD?;5o>6EIrZCz=M#vd7qKz;Xq2FW( zVb>ydN4!M>D4g^eqk*V?4H{+XhWH@A!Vet6O+skBD9vw4IC%v6)nWA8N1(sSpub@R z`Xoc!%%E=W48t+2Cte75a7GX}`twkJ!*N?6H)HFSMaBD368TI#29;|dJ9-Hsill;IVKGG2u43|mK z^UU^=Z^h;K^)%W`qsy8%?Hj+IX3}f`9h!fd5q1Eqv}q5TF0*_b;`{}EO46SLP-x9- zG3w1Q>KFt);&(4XlV94Wvz8-%pBVJ(X%D=}!o)9FIT4{*j`nluGV7yqJ_A1rdyC7&|{WUi(pQq|4MBhXptG z%l+dLjemhQg*`@S-cNkPPs#hufA-A-=TGPf&F>1M|Gkk6FH@tV?{GRs@oPXO#2hKmX@4)$YeG;1A9VVyyc7^7LxBswDL-Vb2{>!g^ z?o|L?rhI$D=+BEt4#^L%|GmRm{yhjE1ekPM!st9Vj^Q1Ka3a9Ov(~2`mdwon?3bU& zWbP1vU&mm7ilUN-$0({Cw(*o3VL;DUY-~j0z8`T)--FP4Q5sz)UsgG`#Uyj>0J>(O ze!7-@&1^;iLepl@{ySYJA7nGmFz`*f?O}3xW)h=k=68hUzd0*3KV1H6=Z5B6`#3h2~rP zmE^-$9ytH~s?hv!`peda=3Did=x1FX)b)TR9*%d*6+yhsmUwu7o_`Iik7%D@iJxx7 zO+5;ye|63N`OLgE8Nb7^|9l(r62kJs<=EB`TD~o;pO&Wh zw-K-n@K?YmfS&*p_C#{W15O8c0U3Z5fMUSqfa?HFfF}Uk0X=}dfavcdxi|n1m=CxB zPzJafa0_4);7@>7z+V9$0tNvw|BU1&0nP-dfK0%JfVF_D0UH4i0onm?0zL$M3*df0 zeSidj3y=!P1mpwO0yY3{2iyy21^gAz2lxpP3%Q&QNChkc6adx&t^?c&cnHu6pzGps zbMPCDWjKv@QC?t9ac-G@cog4@w5H?zX*2zU@kc_{@sWtk=Oa4xoR#u}U+_D9Sl zDq%kp$#Kt&OV7($9scu?9Cuo>^8#XPFm{OUuhC)qemJ zr$wlw{A96DfV}`XZxj3-6w6Hj(q_VhzdsQ!)L2q(%^K?#<^`GUeAHSry0Mv@|0>gEJ z84?1QF&@7Rx!>$#Dc91z$<(IM-=*YA#%Jc0ttu?Wp-|(EagJLzK6CgtL9e7Zim~4U zt))8Njk%A8az zcc3|8zmN%PA25ysj5&_`X1x9zpSogP7UZ4o=i`SjQDRku^|L%RK^#Ux|Gm>BF1aj^ z$|RQ-mM70&Jcm15@5#mZ#Z->F68xs-t*BhNGOx^R<&B*F+oJ{>4@c;~I!Y9Ve{J-i zOrwg+ON#PRa0oG)YEHq~bKFC~pu3b(s0`^iej|@G+&}=|(WC{GYYrXmkgyc|04R5Z zDa#ZZWH{%{Jxlc_Q;nO5{(_nFD4wX-&VJjJ{pc$FwC7WlYIG!xA)MH!6xRP#H^~sD zT#i~;nOC+ZBd-jHk}*Vb^K{*ZDkoUz8iYXDPpLDDahkoPn2xZspfdac=x0*cR9-YQP(Q6&KY)SratJqra@>zI) zr6Q#3Lioz3Y`^~UK%OZuYkBe#a#x2Eu;eevrFVux$%oKK&k%;$Cn0&dZbCCE@>Z6V ztubp4ZTs@sdBu5n^@?fNzQ`6{&L(ZqyLCUvA-K#t*$*ZgYgT+M0n^}em_mQ**;;~8 z4?1$W`LfA@wPCn%`_L?{EY1Z{6CpI;kiI`P)f@v@YW!-&p|OP*bV_m!0@gfy^2ZdM zNj^mWMR~<5D+=~MZc8dFmY3u&$FGjB98oux!=ETzRT`>25uyEO>V4sFQ(ax~^emaK z6ukaaR=BbN@1*2TwFw@NeVU!;Mcaxswv02+I@6X>lv4?3Ajwu#n44Ezj+cv&lZv1G zu3U8qe!n}(mR=D!)0Ui`Zd){Gc3S3Q+oG9^XD&K>X6l)YK3EOAYOV-PXb-u^DZ-F@ z;5tI_YdoR%oW20tw;sX@e$$AR3BMm2u8Wlq&#$M~11*;yZxUKByPw^Sj`!R6+dn_; z)95X0oM}NAVI>yJII#YuRgx9Onn!WUCm6fNB=GM_AR6b3X=q0wtUYn=sBndGWzo51 z;O`F%a}i=Y^=YpVi#7OF^FQ-H{pfMerB*iLopu0SrjDB-Oa1NX`zyCUI{U*n)6LK< z|KAx}=O~)L!hKPbw~V#;o{bfWrX?0S*Bi450mJdS8q} zN~4hG70NpdVCE5BDof#!0HRA~i_(q)OfZ1bPX9mG!!fOuYKgzFJfTdo99el39Nxfw7OaJO;4 z86ol01fcpJ01)1j0OId80Oh|6p!|3Uh2%p(av>js^387(BC21MUSm$qX5#-xVZUcYAj$p*rfk62{${VZH}Pv2gO`7f{0!)D+= zf8Tre*;w{If7ktsCHal;@!yD_Y~Viu{MYa8zxR0V(|ZT*J#YW?FW;<}ScrkQ@VyJ( zvvJGcyYM~xzW8tTe%SXT-sQdAQc`Emnw>W1thwp)<}b)txM*?alCzg)opbL0>~{Uf z-0fFA3{P~w>S6njtNtHB;QtN9pm`<*@@#{xYzK4zIssjPZa@#97tjY701N{50-{^+ z-5S6ofDMoUNCYGScz_6y05ZT2NCl(;(gB%(Y(N2k@Jj(zfEqv@paHNE&Hr%7O@OU{ZGbjF2cQek1K0`Z z2kZvy0qh0DJO-M8Bmm({2vY$WfNVeopcc>w*b3MNXajTuh5(HXC=(ZakM2M!OyAD7 zUjNBG$;yNRmFB;NJ86mfdSnQ8cnCeGgRkkfAf6Q70V zI(vxJ5LfuOiMbj&t5xtg`|bB4gvaB)6yXU7D-fQ9uo~gf2x}42{JsI<5eOR)k}tLq zA^Dq42+25YMM!?^HiRc4Y(q%CXFEb0!VZMwpLHT6pRF6=M1;Kv$#?8ScpSn3gyiE5 zA|&5<2qF23+!HhO?^;D8JO#J02qz%IT=D+Z&HDYEk7Mzu=XRWMqe$`1Uv<59!uGf3`)z}FKVEu9^TRLRRp{?N|Cdug zJ^sc8$9;LF|Ki)f7-5njN#By0tmE?W&8GoaVXVhtj_48Eqfj_~DOt{ru(S4=qgD{MqVVUEfZfUb}8e zYGUlM4-Ne(cGrs?Kc#;8K+ktSeEIQNYj1mfW?t9JHy^R(Pn(Y0b>FPR^Nx+FTz7Tl z>K$qGvS#!@aI44XY<=vj#q%Ec^nB&T^L^LfeapGOp1);qv#mYz{tfP&H-5SP-0OQ! zJ^$Jt-(UIAZA0Ik_T0Ul=YLRBoWA1^ci66rT$J5$Y9-psz1sC^7rTDeE>;eG_r6m4 zGo+mx@O`x4hC7NUT=~8B!dpps$9+j%OQg`)r4HOUGhgW$LSO z&))fn_TkE>8ay)}KJn4l8?=PUFMZPXluyXHeyx_X{eSn|f7%yUG@q_rwsmuVTcCPY_XkVV+)EGYnw)vbmA~G+PPzFf?{RB$ zPfZcpx5_79`-ZfB_8qO9vbaz3H5& zruGlFU-t9BODEp_dEL27Z%Zy3MAC(-58+SXllWvljsJo_N>GJcg?ojEg~x=?gfE40_Qm#F>>c)A`#Q(f zj(W#!j{6-CIkq`=I*t>I#0_GMGu3&X^KR#M=ii)3u9>cE*Cno}T=DLi?t9$tx^Ix) zl|Gg(^W5sW$8)rIsyEeJ;$7>#-usxh-8EEg^nZWrzs9ub}qUKCyzz7~E&OPuy(`>*yx9q|s{;dRV$EOu;hbU2O_XNbAt zX7Oq9CGi#UWAQU_Q2bsz%o*!E-g%NU$?0`!&N=D7;mCimamfQ<-6n-`5E~YxmR{5sme=QFY$=EP(*MxU%<~2 zvV>yeeTEIFT0QSoZ=B6r&GOd?>OH?-)X+@G&1^V8W+hQ#b4>X&G~@y zKG$Qe=Uw;t9{0UW6G{f&!$Yt|XchA9RrXzu#b`~Xc$GNLIRX5?<^0SUt}T+eDxgXd1qQ=aENFMGN??|Y_u74JgtpS>O4-QMrKalT|iwJF+SZH2~V<8%=CK0=r**oAiC5W8$Iw_j(EbROi6 zcV8(zA$3ZEH`iO{y~6vJ?^EADeZNzZl}zO_rC#}18L!5x3)O)7dv!oPPV;J6+NIi^ z+B+oUQuh6?Rl+sGH2ZA(JN5y4jpIu37WD87t~XsDyA=0q_b%V}KA)T`-v|8~r|`;^ z%5BQ~$~ZMeU84R$eM@~^<7!x6eW6QrhkYV6W|o*GJ}Pc;wYnmu#nKAtVrh!(lJA$# zRtl7SwMwNQ3&{ivi}>yQT6?YiM*Eo#$+2846hC)<e&nC}>0gZ!kNpv+dDRF*+b8`MViHT4c^&nCQMfI#9G@fYy7@R>r1(1CH8 zX}{FI%l@rB!f}H8E%z?>tr#*OH|aC!Y)^rwz!+W;(67PC%6LjKZ@0Z^1y@$)k z%CqG8@)TvdlCKmiVaeCw(9-r#NUZuCCtea*Ye`w#CPZ@h1v z??K-WzF&Rg{E6t0rb`_(4NQDf2fgKik7A=ge|#H zyG*-M+pN8$^=KbypKD)fKWbbz^VbgMY);4!x6Qf6XyjoFit6tHmAS!OkLQIY#bA=MvXjt~1@Yy6<$ixnFP}?#=fN z`c}#v@-OnK%2K5boE5;nsoEBjPapFsdHbL2xsJa(qQt3Ui+H?Kbf&--Ed$LM77{gKOsp#JTBMe$mFlJH73x*$wdzgk ztc{GrXrZhnYjd@$wCl8+wL7$*(L)jX{=LA@=QA-fEBI^pyZ9~q zWBfB{{X`)_I72u`xIkDfTp=_FcMA6jK6{$|9JGJ7c$Mn`=~1aoI@;6jo$otY`GNWy zi-uJA{ilQ4GCp6pSh!i(D6|PL3(595_LcS$`%U&c>@D^?98Tw6=LFXz*A&-m*H)L! z9SIw~P1-JfDE%aH9=~UfXDRypLC-UuuRO&VAx*H+d%Wk!tK~ZRRrxJ>m;9yt4SM=e zC002}nTnB_tjtvwDn&}Qa+Pv}a=-EfbaA_~LwQqqSNTBsRQUorFr@qf`*@fds~)4C zs7_X=s)FiLWi?fu1Fcx9OY%as1aiDgT@M|pS8szQy-#gc|D-;lKCM0vS-z(Bs5>Fg z&oJuts6S!k9jqO$P1KIpY+9l=O><~I&9BYU=3|C9N6XRjwIZ!TTccf}U88N#Zh?ir zN4sBpSbI!s)!H%ZzoNZ`dG$l>Gi|r_6UopPp|5SD`6KyB{HeU1Pvy_&FSQRz$iw0a z<{2+4MfswAF}_$|oG;!t$!GH=_!50dKHew#B%kc_`%-;rzI0!PFVmOhTjtC51w!=c z_r5oLKlv2-9?TriWAuC?e=dI|e16X^KOciP3X`vIcX?waSZ1i@F`{JX||T zn+acK9ki!g8z2klk08^+9l=k8_cfKD4qlh=Iq(cF=C9)$FoV3!CkW|6vtVvq>4;Gx;vQ`~}kzI(GWa!Rj`C0ixwDT8vnR1izAX+v@ZBs?`QKfb(EG3r_!PTKXE&Si0 z|4w+36YVG4)9r^iCct(bju|DzneMD`zU+J-c4~@yy8BvK!8hO|9x0uG`qxSiW5)kX zI>d9N=NR}@_rS`3=K0m*_CDdA=-c4i?(6p@Lh9YJrbMV`!+u|>Zc{s;NgSj*0rE|N zo`8Yu2(AGE2d`qGP%1nxjJF?UpX6|eUd%EtiXVw5!&ChVb8(N0b06zYa?f&K;9lpx z&ArY2y!#dRx9;&$lJvaviuAVhcW|>3UR@_F&##_IUc0y0TkAdE*9m*_A++Em_^Up7 zi~NQ>74~wqa*N_oXQ?YO0{)`DqkgYG0^jrv;;A%3_tAbQoG)w^whKFiLE#r6(jIG{ zVZYY?vHcH@*Bp{~srZ8Uws?fI)OoG*PG<)!`kUZ%kCTJ6mv%D8$j(o=(<2%Xs z7vFB*(eefO&~qESs4tbt>KU-+w_tp}13UhcdWd$Wc9vGEJ+F09pVma^-;IvuPsUjC z^JnoHe1I?Ie}~?ES$N)_4e$A{j=RLKo%OCJ*E{g7zIOfSigL%e?{bqz`;z-0X^Nys z=SbJ1XLCFcdEWMX>RIKhQvRr9!p7dO{(>4OYLhh?qa&b|V60!S-KIUMZP)ODO|B85 zQ~CS&hhS5`=YQrSgoA~{g`6u@Gx7OI7-g?eF=&;pNg zhwziY*$=YE*eBTI?I+o%;53kE_d(`!>U-i|v=#*V(VP-)+B7Um3(Y+>UC; zddD@6rDBzMnRqY!Gp~2h_lQiM!L{1oG;UJ_xnx`#`f{bPN+=iB2s?#Ogi^;9j#kHZ z$3gI=CW+HTNjzID6W5AYi1%S#@g{tmFT@|jDb6#U9;fO&$9aMCGUubtcQHo)>3qbs z+m-9CbkCILqHk}Mwn*PfLsAs%J zrM4El)xomduHC0`EjV=q{y6?n{xn{ImvWwcHD=szqdC!HaQ-2yy)2N zI9xnVbVAD4i7$)&uw18Lg>{}Y*Lj!oQ|I^2BV0VzD_6Q2;In_?+T%LTZNpk6-+i6? z5AH=$ozyLTB>hV|604DPlb9lTt|cBZmcK&<_L(WZFoy?(5AT=GO^iZTc5r|Xp8 zD?62w)Eh9L_NslV19Rb>q=$GSFN5|h{!IH*_89RP*9ou@iLRSmXGof79_&`N=Q__u z&&RL^pU4L(9%Y4cBj)y3l&=&n7Vq7lYyn>bf29oLF zyT)DXu5)j2*Sj0sjqZ)^P3|Ulv-=5mg>(Z}mCr~g!ZYP~e1{I@E_a*&4}UvWN58tJ zqul-O?=UOy(hRj2^FI*$k@yxe)>iyx_}f46cF6t@!dqC;pMueR3B01u?Ka0njt3ll z4!8IiRxn4yN501S5LUh_e5B7^F6hpk?)TiMNvoxGutr1vKzt=_C|Rv$&5 ze6Gf7$HH@&t*>ma)o#*$uRWl>puMWStMzGr*Y;2wGVt9#1PAd)^S{H$oCaCt@@4$* z`Fr>W`6v0e_z(Ec`9c0iK1w(SYvO5w8`f<$?8|!LLF{Av1r~Rg@RjfbY}z6AI9M}> zUBUWxo_#4+{p+#Tyb~k*5&K{4UG_eEzx`|bUVEhDAjc7oILGmh1c&JGI8q#ELrNu% zHL!0tJN^K9{n_!1<4wmqj!zt)IlguL(-A4gh)0Q2L{U`5H2CJ{V_mitYu=aimEnN+ zt@w*L1M~Potj{W-$#u?KFkbtdUtmoA%NY${gZxt7<#naH(AaFeUlob(KM1@a3KG@> ze%R|YSnLeg>?~OAY#{*4U4(hMLa2iEt`RoCem7uLZG={Cg&p4}WID63-l=icqP7jr z24^EyQk$Gj&StE9TCnzMb+$R%F<*8%yPVz59%rv}CphYN4mfu^2f^16{AJD+<+8aF zFg}vNorqOZwkzN&a22^qT@|h>%&c{;4X%1vn?6^+YXJ6m5H@GXwbvDm*(}x_hdqf& zus{j!M0gB5c1|R>?Do4;-C6Es?re9!U4T85Qg;Q`$|LK33;c^#cs%Xy4tJ-!%iZnn zare4+y8GPy?g961_n>=^d&s@l%}MdnB*`WvNQv-6cuABbNtXQ59?S@PrC3j#Cmy>8 zHcx^l(UauiJ)%d#ddZKq(lSrLQ{<_@xUcnWz+TNpPZMm)Hcy+U1EaVHYo~tCZqFXr zgD7u|H_kiBo8V1?hah7WmF~^-F2hVyc>vc z9`9an6#VBn_|6INn??A{sqmLG;VTEQ?yA6SQVV~r!M726dfR+$z7Ag({H2}n-*)@< z`1bmuwNk}S%yoGPcwnOKzu*FrDN8Ty- zW1YGOYt$$uMu}4#kCFlIc-=kcepxTU9N8Ug}ttwx*lX2z1u78l=^h} zb767^ff~H;hi5YVn9=q)_QKbV5#!(iB)~rxMOjRRm!2su69d>Stq`llTI`uNh#SQw zjH_*8o7f?CVQlTh47eL};9fDx8RLv|PI4w-=TUUZ*j-I`W31(vzSc)Bm z8eg5S-q+~c z?6}lm6<&}1s7>(bTI5!_UGBu1rdRHh2e1n>gmrl|*5&bvO-aPQq@?(jG$jKo%53a0 zmMT?BjZ%jl&_-pG(yX*7txCJnsdOv7*gG1~SLvJ@jWv3_YEu(cUX`%(nxz`-_7^(ef$7s!6BX#qJ>x?Ua-N_=P`HqF>hpG z&dA1mQHr^uMySI~(TG{18M8zy{QXY&FTFyaFo4z75N63}tgqtjcowQZH~shQ#a6U! z8(K#OB9gXExmY|knB=fwCQWoC;rW4xon6`CccePf9O;e>N2a4%tP$HW8hSAn1~C$% zF%E1P1ro+U21Y;u^uGq$-w54rf#!EY@B5(j|5=v zcz)Au--(^@J$B9!gO((q1u{6#bYwe<9951|*p@0-7ju@a{}1NbXjq_F*r0e=q0l*3 zcKKnC(qNG?V3V?7l|pCXYFCYACT@h4+5|h*3`=z&D{ao!ar&r{FkaI2y~_%W7Mcw< zVyv`cl+Y}&Ti?lyh5e6LC#eb8ze>mG$i|a|BDEGHgZ4AqFeZBOTw%Aqrx}Iu5TnIu zNm!%$F%mNMu~3CkutD31QP6~OK-$uZQP8LL!`Bm6^ z4LAy*1*On~daTZx@N}=$(dKB!)2TkkAZE2FF&eX4tUj-an9oJ=( ziOu?K)`fYj4^Pkbh(r2JHVJbW@AP91OVekuB3;8w-D<+@MIKwwR~vH1>Ka4-8Pk$1 z_-CXO4X#G$LaRPQv$=UUW~y|IsyeA2^9YTl@YzGsM^de)9#1LS;QK`DK9B6p&^?`M z-OJgE5z__VX1DIwOfoF~GI%o8u=6dt?=k?p9&30jWXUV`@lJYmyB(wZBYxQFD&6-TCHwZ+cjoW`$>=bBDtLy&(R04 zqYcob4!#T4a|o-41lY?A_}0}zEp(<8nnD(ltl=bks=WZ(QLWpBc4$QpEW%!Ulx`Cw zXhRzGVHtKn>af??0xf8FbfN#_b#EqB%n(cA!E8itccYIvXS6dB{hH;>M!$x7B)#yu zIaf67Ks#SFk+ zQtvkF)^evbAVtG7U_L<_o(=@y?bg6b)_WS^>u%D$-FEDm>@@t`Ay~^e!^`FIydWL+ zvcOvkds&0NuY=8OGW^?i-NWtk4nPayF!N_&o^Qn5-ho-2!%XhS>|KKyyB)JM2hY=n zS()bJB7H7yfS=g{>(Y%mI7**;Q-|kVvMV*PD(zS$a+p*7m`7{S$L+8c=-WZIhUYL# z`Y|)s@Eb52Zo@pd6BZ#_w*;w}_X;rAHDR9Xz#KOq>=9z^JPuEf)6er$Sy{I(X?&4h zz5{b;Jl0qBLKk{H5l_C`UAOD`;`{ zKYM0D@3Mz2Q3Y&KEwpe0EK-A`(XmmtOU;h0&`Q%fb-+G#Il3J^j$WKb=yUX=Rl9Y2 zH3UDL6QhQ$Ry_Q18`_%)pPYwRz6`#2HT>|6@V`6Ze|N(JC#%KbnSY!!9^SVN{&%8o zy~O{(@1`{)q%?MoNnlI@V-gsXz?cNaBrqm{F$s)GU`zsI5*U-fm;}ZoFeZU935-c# zOafyP7?Z%51jZyVCV?>tj7eZj0%H;wlfak+#w0K%fiVe;NnlI@V-gsXz?cNaBrqm{ I|7{ZZU$L!W9smFU From e3a3082596b3d925a30f1d9a5037ef2151bad4e1 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 21 Dec 2017 01:46:19 -0500 Subject: [PATCH 201/213] Merge pull request #33703 from kevinz000/patch-407 Integrated circuit smoke circuit now requires atleast 10 units of reagents to generate smoke --- .../integrated_electronics/subtypes/reagents.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 78b1e9682e..952015039c 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -1,3 +1,5 @@ +#define IC_SMOKE_REAGENTS_MINIMUM_UNITS 10 + /obj/item/integrated_circuit/reagent category_text = "Reagent" resistance_flags = UNACIDABLE | FIRE_PROOF @@ -8,8 +10,6 @@ if(volume) create_reagents(volume) - - /obj/item/integrated_circuit/reagent/smoke name = "smoke generator" desc = "Unlike most electronics, creating smoke is completely intentional." @@ -44,6 +44,8 @@ push_data() /obj/item/integrated_circuit/reagent/smoke/do_work() + if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS)) + return var/location = get_turf(src) var/datum/effect_system/smoke_spread/chem/S = new S.attach(location) @@ -54,11 +56,9 @@ notified = TRUE S.start() - if(reagents) - reagents.clear_reagents() + reagents.clear_reagents() activate_pin(2) - /obj/item/integrated_circuit/reagent/injector name = "integrated hypo-injector" desc = "This scary looking thing is able to pump liquids into whatever it's pointed at." From 09c802f984f33e1078b1e8421f2cd3b4ca486ae8 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 21 Dec 2017 01:50:39 -0500 Subject: [PATCH 203/213] Merge pull request #33550 from ninjanomnom/instanceless-component-dupe Adds instanceless component dupe mode --- code/__DEFINES/components.dm | 7 +- code/datums/components/README.md | 5 +- code/datums/components/_component.dm | 100 ++++++++++++++------------ code/datums/components/radioactive.dm | 11 +-- code/datums/components/thermite.dm | 9 ++- 5 files changed, 76 insertions(+), 56 deletions(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 4bb27d56d6..78ade5c650 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -6,9 +6,10 @@ // How multiple components of the exact same type are handled in the same datum -#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) -#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed -#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) +#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed +#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new // All signals. Format: // When the signal is called: (signal arguments) diff --git a/code/datums/components/README.md b/code/datums/components/README.md index 574e628741..026b387e27 100644 --- a/code/datums/components/README.md +++ b/code/datums/components/README.md @@ -40,6 +40,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it * `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added * `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it + * `COMPONENT_DUPE_UNIQUE_PASSARGS`: New component will never exist and instead its initialization arguments will be passed on to the old component. 1. `/datum/component/var/dupe_type` (protected, type) * Definition of a duplicate component type * `null` means exact match on `type` (default) @@ -66,6 +67,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * All components a datum owns are deleted with the datum * Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set * If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it + * Properly handles duplicate situations based on the `dupe_mode` var 1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final) * Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead 1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async) @@ -104,9 +106,8 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Allows the component to react to ownership transfers 1. `/datum/component/proc/_RemoveFromParent()` (private, final) * Clears `parent` and removes the component from it's component list -1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final) +1. `/datum/component/proc/_JoinParent` (private, final) * Tries to add the component to it's `parent`s `datum_components` list - * Properly handles duplicate situations based on the `dupe_mode` var 1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz) * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments * Makes a component listen for the specified `signal` on it's `parent` datum. diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index c54376d787..fcd4651459 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -6,54 +6,16 @@ var/datum/parent /datum/component/New(datum/P, ...) - if(type == /datum/component) - qdel(src) - CRASH("[type] instantiated!") - - //check for common mishaps - if(!isnum(dupe_mode)) - qdel(src) - CRASH("[type]: Invalid dupe_mode!") - var/dt = dupe_type - if(dt && !ispath(dt)) - qdel(src) - CRASH("[type]: Invalid dupe_type!") - parent = P var/list/arguments = args.Copy(2) if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) qdel(src, TRUE, TRUE) return - _CheckDupesAndJoinParent(P) + _JoinParent(P) -/datum/component/proc/_CheckDupesAndJoinParent() +/datum/component/proc/_JoinParent() var/datum/P = parent - var/dm = dupe_mode - - var/datum/component/old - if(dm != COMPONENT_DUPE_ALLOWED) - var/dt = dupe_type - if(!dt) - old = P.GetExactComponent(type) - else - old = P.GetComponent(dt) - if(old) - //One or the other has to die - switch(dm) - if(COMPONENT_DUPE_UNIQUE) - old.InheritComponent(src, TRUE) - qdel(src, TRUE, TRUE) - return - if(COMPONENT_DUPE_HIGHLANDER) - InheritComponent(old, FALSE) - qdel(old, FALSE, TRUE) - - //provided we didn't eat someone - if(!old) - //let the others know - P.SendSignal(COMSIG_COMPONENT_ADDED, src) - //lazy init the parent's dc list var/list/dc = P.datum_components if(!dc) @@ -212,10 +174,59 @@ return list(.) /datum/proc/AddComponent(new_type, ...) - var/nt = new_type + var/datum/component/nt = new_type + var/dm = initial(nt.dupe_mode) + var/dt = initial(nt.dupe_type) + + var/datum/component/old_comp + var/datum/component/new_comp + + if(ispath(nt)) + if(nt == /datum/component) + CRASH("[nt] attempted instantiation!") + if(!isnum(dm)) + CRASH("[nt]: Invalid dupe_mode ([dm])!") + if(dt && !ispath(dt)) + CRASH("[nt]: Invalid dupe_type ([dt])!") + else + new_comp = nt + args[1] = src - var/datum/component/C = new nt(arglist(args)) - return QDELING(C) ? GetExactComponent(new_type) : C + + if(dm != COMPONENT_DUPE_ALLOWED) + if(!dt) + old_comp = GetExactComponent(nt) + else + old_comp = GetComponent(dt) + if(old_comp) + switch(dm) + if(COMPONENT_DUPE_UNIQUE) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + old_comp.InheritComponent(new_comp, TRUE) + qdel(new_comp) + if(COMPONENT_DUPE_HIGHLANDER) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + new_comp.InheritComponent(old_comp, FALSE) + qdel(old_comp) + if(COMPONENT_DUPE_UNIQUE_PASSARGS) + if(!new_comp) + var/list/arguments = args.Copy(2) + old_comp.InheritComponent(null, TRUE, arguments) + else + old_comp.InheritComponent(new_comp, TRUE) + else if(!new_comp) + new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal + else if(!new_comp) + new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal + + if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy + SendSignal(COMSIG_COMPONENT_ADDED, new_comp) + return new_comp + return old_comp /datum/proc/LoadComponent(component_type, ...) . = GetComponent(component_type) @@ -235,7 +246,8 @@ C._RemoveFromParent() helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C) C.parent = src - C._CheckDupesAndJoinParent() + if(C == AddComponent(C)) + C._JoinParent() /datum/proc/TransferComponents(datum/target) var/list/dc = datum_components diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm index c149fd8492..fc0456ad10 100644 --- a/code/datums/components/radioactive.dm +++ b/code/datums/components/radioactive.dm @@ -4,7 +4,7 @@ #define RAD_AMOUNT_EXTREME 1000 /datum/component/radioactive - dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/source @@ -47,13 +47,16 @@ if(strength <= RAD_BACKGROUND_RADIATION) return PROCESS_KILL -/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original) +/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, list/arguments) if(!i_am_original) return if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger return - var/datum/component/radioactive/other = C - strength = max(strength, other.strength) + if(C) + var/datum/component/radioactive/other = C + strength = max(strength, other.strength) + else + strength = max(strength, arguments[1]) /datum/component/radioactive/proc/rad_examine(mob/user, atom/thing) var/atom/master = parent diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm index f76178213d..11611cadfb 100644 --- a/code/datums/components/thermite.dm +++ b/code/datums/components/thermite.dm @@ -1,5 +1,5 @@ /datum/component/thermite - dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/amount var/overlay @@ -46,10 +46,13 @@ master.cut_overlay(overlay) return ..() -/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original) +/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments) if(!i_am_original) return - amount += newC.amount + if(newC) + amount += newC.amount + else + amount += arguments[1] /datum/component/thermite/proc/thermite_melt(mob/user) var/turf/master = parent From 14942fb582482d127ef0fd0660ee521495c4ba35 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 21 Dec 2017 02:37:52 -0500 Subject: [PATCH 205/213] Merge pull request #33706 from AnturK/dumbmechacode Fixes some mecha code. --- code/game/mecha/mecha.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 799344fe54..2d148b4ff4 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -571,9 +571,9 @@ if(bumpsmash && occupant) //Need a pilot to push the PUNCH button. if(nextsmash < world.time) obstacle.mech_melee_attack(src) - if(!obstacle || !obstacle.density) - step(src,dir) nextsmash = world.time + smashcooldown + if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) + step(src,dir) if(isobj(obstacle)) var/obj/O = obstacle if(!O.anchored) From 86fed404b167266251f31a4bab1ef658081c1919 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 21 Dec 2017 04:36:01 -0600 Subject: [PATCH 207/213] Update weldingtool.dm --- code/game/objects/items/tools/weldingtool.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index ee51e6bf82..12c056c9af 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -241,7 +241,7 @@ container_type = NONE else to_chat(user, "[src] can now be attached, modified, and refuelled.") - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) From 4d01f1c6bf6cad2b88e089a5c270a8dc9ad7d7cb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 04:56:37 -0600 Subject: [PATCH 208/213] Automatic changelog generation for PR #4475 [ci skip] --- html/changelogs/AutoChangeLog-pr-4475.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4475.yml diff --git a/html/changelogs/AutoChangeLog-pr-4475.yml b/html/changelogs/AutoChangeLog-pr-4475.yml new file mode 100644 index 0000000000..f37e80ed55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4475.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Passing a space transition no longer interrupts pulls." From e070e5b023aaab3907a6b2d23253ce434c711f23 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 04:57:21 -0600 Subject: [PATCH 209/213] Automatic changelog generation for PR #4477 [ci skip] --- html/changelogs/AutoChangeLog-pr-4477.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4477.yml diff --git a/html/changelogs/AutoChangeLog-pr-4477.yml b/html/changelogs/AutoChangeLog-pr-4477.yml new file mode 100644 index 0000000000..bba0dab724 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4477.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes arm implants being immune to EMPs" From 0decf08a7f68c623f2ae36625eb6d597ac259c42 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 04:58:08 -0600 Subject: [PATCH 210/213] Automatic changelog generation for PR #4479 [ci skip] --- html/changelogs/AutoChangeLog-pr-4479.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4479.yml diff --git a/html/changelogs/AutoChangeLog-pr-4479.yml b/html/changelogs/AutoChangeLog-pr-4479.yml new file mode 100644 index 0000000000..623a1ada72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4479.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscdel: "Integrated circuit smoke circuits now require 10 units of reagents to fire." From 13c6a7d73830ed0081cbdac7642527afbcad61f7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 04:59:02 -0600 Subject: [PATCH 211/213] Automatic changelog generation for PR #4466 [ci skip] --- html/changelogs/AutoChangeLog-pr-4466.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4466.yml diff --git a/html/changelogs/AutoChangeLog-pr-4466.yml b/html/changelogs/AutoChangeLog-pr-4466.yml new file mode 100644 index 0000000000..e8239ebfb4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4466.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - balance: "Roundstart xenos are no longer pierce immune, also no more extra damage from heat." From fddd04c964e1eaed5c012b97000d0c2ce5567bfa Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 04:59:47 -0600 Subject: [PATCH 212/213] Automatic changelog generation for PR #4446 [ci skip] --- html/changelogs/AutoChangeLog-pr-4446.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4446.yml diff --git a/html/changelogs/AutoChangeLog-pr-4446.yml b/html/changelogs/AutoChangeLog-pr-4446.yml new file mode 100644 index 0000000000..3811f7ffb7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4446.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - balance: "The codespeak manual now has unlimited uses and costs 3 TC." + - bugfix: "Nuke ops can now purchase the codespeak manual, as was intended." From c4f2e2f911e16733da3ef1deb9834de740bcb27e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 21 Dec 2017 05:01:34 -0600 Subject: [PATCH 213/213] Automatic changelog generation for PR #4412 [ci skip] --- html/changelogs/AutoChangeLog-pr-4412.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4412.yml diff --git a/html/changelogs/AutoChangeLog-pr-4412.yml b/html/changelogs/AutoChangeLog-pr-4412.yml new file mode 100644 index 0000000000..6280189218 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4412.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - tweak: "Vitality matrices don't have visible messages when someone crosses them anymore."

    Brothers