From 9d1680fcaa6ae6c0cbc5e0b7048f0c129c2b26cf Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:55:07 -0600 Subject: [PATCH 01/26] bumps ci to 1630 (#23904) --- _build_dependencies.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_build_dependencies.sh b/_build_dependencies.sh index b481c560f49e..058f897b55b6 100644 --- a/_build_dependencies.sh +++ b/_build_dependencies.sh @@ -6,11 +6,11 @@ export NODE_VERSION=20 # Stable Byond Major export STABLE_BYOND_MAJOR=515 # Stable Byond Minor -export STABLE_BYOND_MINOR=1628 +export STABLE_BYOND_MINOR=1630 # Beta Byond Major export BETA_BYOND_MAJOR=515 # Beta Byond Minor -export BETA_BYOND_MINOR=1628 +export BETA_BYOND_MINOR=1630 # Python version for mapmerge and other tools export PYTHON_VERSION=3.11.6 # RUSTG version From 4777528c6e07a5d2718b1e0ac616860037ee5c7c Mon Sep 17 00:00:00 2001 From: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> Date: Thu, 25 Jan 2024 03:16:29 -0500 Subject: [PATCH 02/26] [s] The PR I just made about fixing an IPC revival exploit but this time I'm on the right branch (#23916) * s help binary bot ling * Update code/modules/surgery/organs/organ_helpers.dm --------- Co-authored-by: Farie82 --- .../modules/mob/living/carbon/human/human_update_status.dm | 2 +- code/modules/surgery/organs/organ_helpers.dm | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_update_status.dm b/code/modules/mob/living/carbon/human/human_update_status.dm index 26972a8ecf2c..0c48d4b5fa1b 100644 --- a/code/modules/mob/living/carbon/human/human_update_status.dm +++ b/code/modules/mob/living/carbon/human/human_update_status.dm @@ -6,7 +6,7 @@ if(dna.species && dna.species.can_revive_by_healing) var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain) if(B) - if((health >= (HEALTH_THRESHOLD_DEAD + HEALTH_THRESHOLD_CRIT) * 0.5) && getBrainLoss() < 120 && !suiciding) + if((health >= (HEALTH_THRESHOLD_DEAD + HEALTH_THRESHOLD_CRIT) * 0.5) && check_vital_organs() && !suiciding) update_revive() create_debug_log("revived from healing, trigger reason: [reason]") diff --git a/code/modules/surgery/organs/organ_helpers.dm b/code/modules/surgery/organs/organ_helpers.dm index 6eaa4154e297..13c68ed9c4e7 100644 --- a/code/modules/surgery/organs/organ_helpers.dm +++ b/code/modules/surgery/organs/organ_helpers.dm @@ -107,4 +107,9 @@ .++ if(affecting.body_part == LEG_LEFT) .++ - +///Returns true if all the mob's vital organs are functional, otherwise returns false +/mob/living/carbon/human/proc/check_vital_organs() + for(var/obj/item/organ/internal/organ in internal_organs) + if(organ.vital && (organ.damage >= organ.max_damage)) + return FALSE + return TRUE From 4db9553aac585cd28f94e0e0754e840cd121b1d4 Mon Sep 17 00:00:00 2001 From: Volodymir Ohorodnytskyi <102746941+Legendaxe@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:49:20 +0200 Subject: [PATCH 03/26] fix: clear_credits (#939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Что этот PR делает По непонятной мне причине сразу после коммита рефактора титров где я починил титры, фикс пропал в коммите с новогодними титрами, похоже произошел провтык с ветками. ## Почему это хорошо для игры ## Изображения изменений ## Тестирование ## Changelog :cl: fix: починил призрачные титры после "пропуска синематика" /:cl: --- modular_ss220/credits/code/SScredits.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modular_ss220/credits/code/SScredits.dm b/modular_ss220/credits/code/SScredits.dm index 6a7252bde272..9ec4763e0937 100644 --- a/modular_ss220/credits/code/SScredits.dm +++ b/modular_ss220/credits/code/SScredits.dm @@ -39,4 +39,7 @@ SUBSYSTEM_DEF(credits) if(!client?.credits) return + for(var/credit in client.credits) + client.screen -= credit + client.credits.Cut() From 867da454c6049596d3728961b93c9a7e7162a1fd Mon Sep 17 00:00:00 2001 From: PhantornRU <41479614+PhantornRU@users.noreply.github.com> Date: Fri, 26 Jan 2024 03:41:35 +1000 Subject: [PATCH 04/26] Jobbaned Roles at poll_candidates (#23847) --- code/game/gamemodes/miniantags/revenant/revenant.dm | 2 +- code/game/objects/items/weapons/dice.dm | 2 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/deathsquad.dm | 2 +- code/modules/admin/verbs/gimmick_team.dm | 2 +- code/modules/admin/verbs/one_click_antag.dm | 2 +- code/modules/events/spider_terror.dm | 2 +- code/modules/mob/mob_misc_procs.dm | 2 +- code/modules/response_team/ert.dm | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index a5f4d6827967..51ce73175378 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -160,7 +160,7 @@ giveObjectivesandGoals() giveSpells() else - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant?", poll_time = 15 SECONDS, source = /mob/living/simple_animal/revenant) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant?", ROLE_REVENANT, poll_time = 15 SECONDS, source = /mob/living/simple_animal/revenant) var/mob/dead/observer/theghost = null if(candidates.len) theghost = pick(candidates) diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 998dd526021b..4264a6708f45 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -293,7 +293,7 @@ servant_mind.transfer_to(H) - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", poll_time = 30 SECONDS, source = H) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", ROLE_GHOST, poll_time = 30 SECONDS, source = H) if(length(candidates) && !QDELETED(H)) var/mob/dead/observer/C = pick(candidates) message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 83188ee73446..d4e15ff5b731 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1995,7 +1995,7 @@ var/petchoice = input("Select pet type", "Pets") as null|anything in pets if(isnull(petchoice)) return - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Play as the special event pet [H]?", poll_time = 20 SECONDS, min_hours = 10, source = petchoice) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Play as the special event pet [H]?", ROLE_SENTIENT, poll_time = 20 SECONDS, min_hours = 10, source = petchoice) var/mob/dead/observer/theghost = null if(candidates.len) var/mob/living/simple_animal/pet/P = new petchoice(H.loc) diff --git a/code/modules/admin/verbs/deathsquad.dm b/code/modules/admin/verbs/deathsquad.dm index 92b35362b752..d5a635293f78 100644 --- a/code/modules/admin/verbs/deathsquad.dm +++ b/code/modules/admin/verbs/deathsquad.dm @@ -73,7 +73,7 @@ GLOBAL_VAR_INIT(deathsquad_sent, FALSE) commando_ghosts = pollCandidatesWithVeto(src, usr, commando_number, "Join the DeathSquad?",, 21, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) else var/image/source = image('icons/obj/cardboard_cutout.dmi', "cutout_deathsquad") - commando_ghosts = SSghost_spawns.poll_candidates("Join the Deathsquad?",, GLOB.responseteam_age, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) + commando_ghosts = SSghost_spawns.poll_candidates("Join the Deathsquad?", ROLE_DEATHSQUAD, GLOB.responseteam_age, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) if(length(commando_ghosts) > commando_number) commando_ghosts.Cut(commando_number + 1) //cuts the ghost candidates down to the amount requested if(!length(commando_ghosts)) diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm index a3d853bffd24..667508713131 100644 --- a/code/modules/admin/verbs/gimmick_team.dm +++ b/code/modules/admin/verbs/gimmick_team.dm @@ -53,7 +53,7 @@ players_to_spawn += candidate else to_chat(src, "Polling candidates...") - players_to_spawn = SSghost_spawns.poll_candidates("Do you want to play as \a [initial(O.name)]?") + players_to_spawn = SSghost_spawns.poll_candidates("Do you want to play as \a [initial(O.name)]?", ROLE_GHOST) if(!players_to_spawn.len) to_chat(src, "Nobody volunteered.") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 89ba5e45f27e..7c9ad54d969e 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -137,7 +137,7 @@ if(confirm != "Yes") return 0 var/image/I = new('icons/mob/simple_human.dmi', "wizard") - var/list/candidates = SSghost_spawns.poll_candidates("Do you wish to be considered for the position of a Wizard Federation 'diplomat'?", "wizard", source = I) + var/list/candidates = SSghost_spawns.poll_candidates("Do you wish to be considered for the position of a Wizard Federation 'diplomat'?", ROLE_WIZARD, source = I) log_admin("[key_name(owner)] tried making a Wizard with One-Click-Antag") message_admins("[key_name_admin(owner)] tried making a Wizard with One-Click-Antag") diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm index 51f71526d24a..1f513b32ed1c 100644 --- a/code/modules/events/spider_terror.dm +++ b/code/modules/events/spider_terror.dm @@ -47,7 +47,7 @@ // Strongest, only used during highpop. spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen spawncount = 1 - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a terror spider?", null, TRUE, source = spider_type) + var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a terror spider?", ROLE_TSPIDER, TRUE, source = spider_type) if(length(candidates) < spawncount) message_admins("Warning: not enough players volunteered to be terrors. Could only spawn [length(candidates)] out of [spawncount]!") var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE) diff --git a/code/modules/mob/mob_misc_procs.dm b/code/modules/mob/mob_misc_procs.dm index ffd0c1ca9c60..4fde7c26c32d 100644 --- a/code/modules/mob/mob_misc_procs.dm +++ b/code/modules/mob/mob_misc_procs.dm @@ -166,7 +166,7 @@ var/question = "Do you want to play as [M.real_name ? M.real_name : M.name][M.job ? " ([M.job])" : ""]" if(alert("Do you want to show the antag status?","Show antag status","Yes","No") == "Yes") question += ", [M.mind?.special_role ? M.mind?.special_role : "No special role"]" - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("[question]?", poll_time = 10 SECONDS, min_hours = minhours, source = M) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("[question]?", ROLE_GHOST, poll_time = 10 SECONDS, min_hours = minhours, source = M) var/mob/dead/observer/theghost = null if(length(candidates)) diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index 33b4895a1e31..636b57a115e6 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(ert_request_messages) GLOB.active_team.cyborg_security_permitted = cyborg_security GLOB.send_emergency_team = TRUE - var/list/ert_candidates = shuffle(SSghost_spawns.poll_candidates("Join the Emergency Response Team?",, GLOB.responseteam_age, 45 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_ERT])) + var/list/ert_candidates = shuffle(SSghost_spawns.poll_candidates("Join the Emergency Response Team?", ROLE_ERT, GLOB.responseteam_age, 45 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_ERT])) if(!length(ert_candidates)) GLOB.active_team.cannot_send_team() GLOB.send_emergency_team = FALSE From 4237f77be14dc2c5082debbc9f02dceab8157c30 Mon Sep 17 00:00:00 2001 From: Henri215 <77684085+Henri215@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:44:38 -0300 Subject: [PATCH 05/26] Fixing a few grammar issues (#23842) * fixing some typos and spacings * another one * not that one * even more --- code/__DEFINES/tools_defines.dm | 2 +- code/_onclick/click_override.dm | 4 ++-- code/controllers/subsystem/SSjobs.dm | 2 +- code/controllers/subsystem/tickets/tickets.dm | 4 ++-- code/datums/action.dm | 4 ++-- code/datums/dog_fashion.dm | 4 ++-- code/datums/emote.dm | 2 +- code/game/gamemodes/cult/runes.dm | 2 +- .../game/gamemodes/miniantags/abduction/abduction_gear.dm | 2 +- .../miniantags/demons/slaughter demon/slaughter.dm | 2 +- code/game/gamemodes/wizard/artefact.dm | 2 +- code/game/gamemodes/wizard/soulstone.dm | 2 +- .../game/machinery/airlock_control/airlock_controllers.dm | 2 +- code/game/machinery/computer/arcade_games/recruiter.dm | 2 +- code/game/machinery/computer/buildandrepair.dm | 2 +- code/game/objects/items/devices/traitordevices.dm | 2 +- code/game/objects/items/toys.dm | 2 +- code/game/objects/items/weapons/cards_ids.dm | 2 +- code/game/objects/items/weapons/storage/backpack.dm | 2 +- .../crates_lockers/closets/secure/secure_closets.dm | 2 +- .../objects/structures/crates_lockers/closets/statue.dm | 2 +- code/game/objects/structures/crates_lockers/crates.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 6 +++--- code/modules/antagonists/_common/antag_datum.dm | 2 +- .../antagonists/revolutionary/datum_revolutionary.dm | 2 +- .../vampire/vampire_powers/dantalion_powers.dm | 2 +- code/modules/crafting/guncrafting.dm | 4 ++-- code/modules/hydroponics/fermenting_barrel.dm | 2 +- code/modules/mob/living/simple_animal/hostile/hivebot.dm | 2 +- .../mob/living/simple_animal/hostile/syndicate_mobs.dm | 6 +++--- code/modules/power/apc/apc.dm | 2 +- code/modules/surgery/organs/augments_arms.dm | 2 +- code/modules/surgery/organs/augments_eyes.dm | 2 +- code/modules/surgery/organs/augments_internal.dm | 8 ++++---- code/modules/surgery/organs/eyes.dm | 2 +- code/modules/surgery/organs/robolimbs.dm | 2 +- code/modules/surgery/organs/skeleton_organs.dm | 6 +++--- code/modules/surgery/organs/subtypes/drask_organs.dm | 2 +- code/modules/surgery/organs/subtypes/grey_organs.dm | 6 +++--- code/modules/surgery/organs/subtypes/skrell_organs.dm | 2 +- code/modules/surgery/organs/subtypes/unathi_organs.dm | 4 ++-- code/modules/surgery/organs/vocal_cords.dm | 2 +- 42 files changed, 59 insertions(+), 59 deletions(-) diff --git a/code/__DEFINES/tools_defines.dm b/code/__DEFINES/tools_defines.dm index 70af463f7ddb..dff98f4bda19 100644 --- a/code/__DEFINES/tools_defines.dm +++ b/code/__DEFINES/tools_defines.dm @@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(surgery_tool_behaviors, list( //Wirecutter messages #define WIRECUTTER_SNIP_MESSAGE user.visible_message("[user] cuts the wires from [src]!", "You cut the wires from [src]!", "You hear snipping.") -#define WIRECUTTER_ATTEMPT_DISMANTLE_MESSAGE user.visible_message("[user] begins cutting [src] apart... ", "You begin cutting [src] apart...", "You hear snipping.") +#define WIRECUTTER_ATTEMPT_DISMANTLE_MESSAGE user.visible_message("[user] begins cutting [src] apart...", "You begin cutting [src] apart...", "You hear snipping.") #define WIRECUTTER_DISMANTLE_SUCCESS_MESSAGE user.visible_message("[user] cuts [src] apart!", "You cut [src] apart!", "You hear snipping.") //Welder messages and other stuff diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm index c53bbb3d2f8e..d17ef01694fd 100644 --- a/code/_onclick/click_override.dm +++ b/code/_onclick/click_override.dm @@ -38,8 +38,8 @@ /datum/middleClickOverride/badminClicker/onClick(atom/A, mob/living/user) var/atom/movable/newObject = new summon_path newObject.loc = get_turf(A) - to_chat(user, "You release the power you had stored up, summoning \a [newObject.name]! ") - usr.loc.visible_message("[user] waves [user.p_their()] hand and summons \a [newObject.name]") + to_chat(user, "You release the power you had stored up, summoning \a [newObject.name]!") + usr.loc.visible_message("[user] waves [user.p_their()] hand and summons \a [newObject.name]!") ..() /datum/middleClickOverride/shock_implant diff --git a/code/controllers/subsystem/SSjobs.dm b/code/controllers/subsystem/SSjobs.dm index 7401c82c44e3..cd56d46c7f47 100644 --- a/code/controllers/subsystem/SSjobs.dm +++ b/code/controllers/subsystem/SSjobs.dm @@ -42,7 +42,7 @@ SUBSYSTEM_DEF(jobs) occupations = list() var/list/all_jobs = subtypesof(/datum/job) if(!all_jobs.len) - to_chat(world, "Error setting up jobs, no job datums found") + to_chat(world, "Error setting up jobs, no job datums found.") return 0 for(var/J in all_jobs) diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm index d3310abcaa67..e72f61da2227 100644 --- a/code/controllers/subsystem/tickets/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -252,14 +252,14 @@ SUBSYSTEM_DEF(tickets) C.man_up(returnClient(N)) T.lastStaffResponse = "Autoresponse: [message_key]" resolveTicket(N) - message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with: [message_key] ") + message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with: [message_key]") log_game("[C] has auto responded to [ticket_owner]\'s adminhelp with: [response_phrases[message_key]]") if("Mentorhelp") convert_ticket(T) else SEND_SOUND(returnClient(N), sound('sound/effects/adminhelp.ogg')) to_chat_safe(returnClient(N), "[key_name_hidden(C)] is autoresponding with: [response_phrases[message_key]]")//for this we want the full value of whatever key this is to tell the player so we do response_phrases[message_key] - message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with: [message_key] ") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key + message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with: [message_key]") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key T.lastStaffResponse = "Autoresponse: [message_key]" resolveTicket(N) log_game("[C] has auto responded to [ticket_owner]\'s adminhelp with: [response_phrases[message_key]]") diff --git a/code/datums/action.dm b/code/datums/action.dm index 0bdd5c4a0a36..0e6dc66076dc 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -445,7 +445,7 @@ /datum/action/item_action/instrument name = "Use Instrument" - desc = "Use the instrument specified" + desc = "Use the instrument specified." /datum/action/item_action/instrument/Trigger(left_click) if(istype(target, /obj/item/instrument)) @@ -551,7 +551,7 @@ /datum/action/item_action/accessory/herald name = "Mirror Walk" - desc = "Use near a mirror to enter it" + desc = "Use near a mirror to enter it." //Preset for spells /datum/action/spell_action diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 1cfaf3d24bf4..64ae1fcc5bb1 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -177,7 +177,7 @@ /datum/dog_fashion/head/sombrero name = "Segnor REAL_NAME" - desc = "You must respect Elder Dogname" + desc = "You must respect Elder Dogname." /datum/dog_fashion/head/sombrero/New(mob/M) ..() @@ -211,7 +211,7 @@ /datum/dog_fashion/head/cone name = "REAL_NAME" - desc = "Omnicone's Chosen Champion" + desc = "Omnicone's Chosen Champion." /datum/dog_fashion/back/hardsuit name = "Space Explorer REAL_NAME" diff --git a/code/datums/emote.dm b/code/datums/emote.dm index 1cb1668e1182..42304b2f8795 100644 --- a/code/datums/emote.dm +++ b/code/datums/emote.dm @@ -531,7 +531,7 @@ return FALSE if(!check_rights(R_ADMIN, FALSE, user)) if(!GLOB.dsay_enabled) - to_chat(user, "Deadchat is globally muted") + to_chat(user, "Deadchat is globally muted.") return FALSE /** diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 25b2bd9e46c9..9611bfcdbe0a 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -369,7 +369,7 @@ structure_check() searches for nearby cultist structures required for the invoca var/obj/item/melee/cultblade/dagger/D = new(get_turf(src)) if(H.equip_to_slot_if_possible(D, SLOT_HUD_IN_BACKPACK, FALSE, TRUE)) - to_chat(H, "You have a dagger in your backpack. Use it to do [SSticker.cultdat.entity_title1]'s bidding. ") + to_chat(H, "You have a dagger in your backpack. Use it to do [SSticker.cultdat.entity_title1]'s bidding.") else to_chat(H, "There is a dagger on the floor. Use it to do [SSticker.cultdat.entity_title1]'s bidding.") diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index bdac0e91c34d..83ea90eeb2af 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -506,7 +506,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} add_attack_logs(user, L, "Put to sleep with [src]") else L.AdjustDrowsy(2 SECONDS) - to_chat(user, "Sleep inducement works fully only on stunned specimens! ") + to_chat(user, "Sleep inducement works fully only on stunned specimens!") L.visible_message("[user] tried to induce sleep in [L] with [src]!", \ "You suddenly feel drowsy!") diff --git a/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm b/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm index b4436375173c..a1cc1cd7ba2d 100644 --- a/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm +++ b/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm @@ -244,7 +244,7 @@ // Eating a 2nd heart. Gives the ability to drag people into blood and eat them. if(HAS_TRAIT(user, TRAIT_BLOODCRAWL)) - to_chat(user, "You feel differ- CONSUME THEM! ") + to_chat(user, "You feel differ- CONSUME THEM!") ADD_TRAIT(user, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") qdel(src) // Replacing their demon heart with another demon heart is pointless, just delete this one and return. return TRUE diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 46a7ac918bfe..4fec8ed99bb2 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -76,7 +76,7 @@ return if(used) - to_chat(user, " You've already summoned an apprentice or you are in process of summoning one. ") + to_chat(user, "You've already summoned an apprentice or you are in process of summoning one.") return ui_interact(user) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index ab25da432f7b..f6d1716cd718 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -199,7 +199,7 @@ and the memories of your time as their servant with it.") to_chat(M, "Assist [user], your saviour, and get vengeance on those who enslaved you!") else - to_chat(M, "Your soulstone has been exorcised, and you are now bound to obey [user]. ") + to_chat(M, "Your soulstone has been exorcised, and you are now bound to obey [user].") for(var/mob/living/simple_animal/shade/EX in src) EX.holy = TRUE diff --git a/code/game/machinery/airlock_control/airlock_controllers.dm b/code/game/machinery/airlock_control/airlock_controllers.dm index 935a7619307a..1a229fb80731 100644 --- a/code/game/machinery/airlock_control/airlock_controllers.dm +++ b/code/game/machinery/airlock_control/airlock_controllers.dm @@ -105,7 +105,7 @@ add_fingerprint(usr) if(!allowed(usr)) - to_chat(usr, "Access denied") + to_chat(usr, "Access denied.") return TRUE switch(action) diff --git a/code/game/machinery/computer/arcade_games/recruiter.dm b/code/game/machinery/computer/arcade_games/recruiter.dm index 44341499fe4e..da0611a9930d 100644 --- a/code/game/machinery/computer/arcade_games/recruiter.dm +++ b/code/game/machinery/computer/arcade_games/recruiter.dm @@ -55,7 +55,7 @@ "Spent 2 years as a freelance journalist", "Known as a hero for keeping stations clean during attacks", "Worked as a bureaucrat for SolGov", "Worked in Donk Corporation's R&D department", "Did work for USSP as an translator", "Took care of Toxins, Xenobiology, Robotics and R&D as a single worker in the Research department", - "Served for 4 years as a soldier of the Prospero Order", "Traveled through various systems as an businessman", + "Served for 4 years as a soldier of the Prospero Order", "Traveled through various systems as a businessman", "Worked as a waiter for one year", "Has previous experience as a cameraman", "Spent years of their life being a janitor at Clown College", "Was given numerous good reviews for delivering cargo requests on time", "Helped old people cross the holostreet", "Has proven ability to read", "Served 4 years in NT navy", diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index f799538d9c0d..399172ace386 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -547,7 +547,7 @@ format_board_name() to_chat(user, "Access protocols set to [console_choice].") else - to_chat(user, "Access Denied") + to_chat(user, "Access Denied.") return return ..() diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 0449d907f9a0..e4f434a63842 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -20,7 +20,7 @@ icon_state = "[initial(icon_state)]" /obj/item/jammer/attack_self(mob/user) - to_chat(user, "You [active ? "deactivate [src]. It goes quiet with a small click." : "activate [src]. It starts to hum softly."] ") + to_chat(user, "You [active ? "deactivate [src]. It goes quiet with a small click." : "activate [src]. It starts to hum softly."]") active = !active update_icon(UPDATE_ICON_STATE) if(active) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 4f6292496495..20a7660b469e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -783,7 +783,7 @@ /obj/item/toy/plushie/ipcplushie/attackby(obj/item/B, mob/user, params) if(istype(B, /obj/item/food/snacks/breadslice)) new /obj/item/food/snacks/toast(get_turf(loc)) - to_chat(user, " You insert bread into the toaster. ") + to_chat(user, "You insert bread into the toaster.") playsound(loc, 'sound/machines/ding.ogg', 50, 1) qdel(B) else diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index f9844c0461ca..d949c064c277 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -277,7 +277,7 @@ guest_pass.forceMove(get_turf(src)) guest_pass = null else - to_chat(user, "There is no guest pass attached to this ID") + to_chat(user, "There is no guest pass attached to this ID.") /obj/item/card/id/serialize() var/list/data = ..() diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 9c74fa6f73ce..2ff7a75b2e0d 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -70,7 +70,7 @@ user.visible_message("[user] grins as [user.p_they()] begin[user.p_s()] to put a Bag of Holding into a Bag of Holding!", "You begin to put the Bag of Holding into the Bag of Holding!") if(do_after(user, 30, target=src)) investigate_log("has become a singularity. Caused by [user.key]","singulo") - user.visible_message("[user] erupts in evil laughter as [user.p_they()] put[user.p_s()] the Bag of Holding into another Bag of Holding!", "You can't help but laugh wildly as you put the Bag of Holding into another Bag of Holding, complete darkness surrounding you."," You hear the sound of scientific evil brewing! ") + user.visible_message("[user] erupts in evil laughter as [user.p_they()] put[user.p_s()] the Bag of Holding into another Bag of Holding!", "You can't help but laugh wildly as you put the Bag of Holding into another Bag of Holding, complete darkness surrounding you."," You hear the sound of scientific evil brewing!") qdel(W) var/obj/singularity/singulo = new /obj/singularity(get_turf(user)) singulo.energy = 300 //To give it a small boost diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index a1ad8350df0a..cce40bd6f9bf 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -56,7 +56,7 @@ visible_message("The locker has been [locked ? null : "un"]locked by [user].") update_icon() else - to_chat(user, "Access Denied") + to_chat(user, "Access Denied.") /obj/structure/closet/secure_closet/closed_item_click(mob/user) togglelock(user) diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index c07464d48ad1..38240e163151 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -115,4 +115,4 @@ if(user) user.dust() dump_contents() - visible_message("[src] shatters!. ") + visible_message("[src] shatters!") diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 8323cfac71a4..ebffc67c1513 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -225,7 +225,7 @@ visible_message("The crate has been [locked ? null : "un"]locked by [user].") update_icon() else - to_chat(user, "Access Denied") + to_chat(user, "Access Denied.") /obj/structure/closet/crate/secure/AltClick(mob/user) if(Adjacent(user) && !opened) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 2fe653b8dbb9..7943e30dc3de 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -295,14 +295,14 @@ for(var/mob/dead/observer/g in get_ghosts()) if(g.antagHUD) g.antagHUD = FALSE // Disable it on those that have it enabled - to_chat(g, "The Administrators have disabled AntagHUD ") + to_chat(g, "The Administrators have disabled AntagHUD.") GLOB.configuration.general.allow_antag_hud = FALSE to_chat(src, "AntagHUD usage has been disabled") action = "disabled" else for(var/mob/dead/observer/g in get_ghosts()) if(!g.client.holder) // Add the verb back for all non-admin ghosts - to_chat(g, "The Administrators have enabled AntagHUD ")// Notify all observers they can now use AntagHUD + to_chat(g, "The Administrators have enabled AntagHUD.")// Notify all observers they can now use AntagHUD GLOB.configuration.general.allow_antag_hud = TRUE action = "enabled" @@ -330,7 +330,7 @@ else for(var/mob/dead/observer/g in get_ghosts()) to_chat(g, "The administrator has placed restrictions on joining the round if you use AntagHUD") - to_chat(g, "Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions ") + to_chat(g, "Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions.") g.antagHUD = FALSE GLOB.antag_hud_users -= g.ckey action = "placed restrictions" diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 9dbe8cd39146..c537489e3d1b 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -336,7 +336,7 @@ GLOBAL_LIST_EMPTY(antagonists) */ /datum/antagonist/proc/farewell() if(owner && owner.current) - to_chat(owner.current,"You are no longer a [special_role]! ") + to_chat(owner.current,"You are no longer a [special_role]!") /** * Creates a new antagonist team. diff --git a/code/modules/antagonists/revolutionary/datum_revolutionary.dm b/code/modules/antagonists/revolutionary/datum_revolutionary.dm index 1081bf9da443..ed3be5c22cdf 100644 --- a/code/modules/antagonists/revolutionary/datum_revolutionary.dm +++ b/code/modules/antagonists/revolutionary/datum_revolutionary.dm @@ -25,7 +25,7 @@ /datum/antagonist/rev/farewell() if(owner && owner.current) - to_chat(owner.current,"You have been brainwashed! You are no longer a [special_role]! ") + to_chat(owner.current,"You have been brainwashed! You are no longer a [special_role]!") /datum/antagonist/rev/add_owner_to_gamemode() diff --git a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm index b2c6c2db499c..6ebffddb66fc 100644 --- a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm @@ -120,7 +120,7 @@ for(var/mob/M in targets) to_chat(M, "[full_title]: [input]") for(var/mob/M in GLOB.dead_mob_list) - to_chat(M, "[full_title] ([ghost_follow_link(user, ghost=M)]): [input] ") + to_chat(M, "[full_title] ([ghost_follow_link(user, ghost=M)]): [input]") log_say("(DANTALION) [input]", user) user.create_log(SAY_LOG, "(DANTALION) [input]") diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm index 794446de44cc..2b41fbf63bee 100644 --- a/code/modules/crafting/guncrafting.dm +++ b/code/modules/crafting/guncrafting.dm @@ -29,7 +29,7 @@ /obj/item/weaponcrafting/gunkit/nuclear name = "\improper advanced energy gun parts kit" - desc = "A suitcase containing the necessary gun parts to tranform a standard energy gun into an advaned energy gun." + desc = "A suitcase containing the necessary gun parts to transform a standard energy gun into an advanced energy gun." origin_tech = "combat=4;magnets=4;powerstorage=4" outcome = /obj/item/gun/energy/gun/nuclear @@ -53,7 +53,7 @@ /obj/item/weaponcrafting/gunkit/temperature name = "\improper temperature gun parts kit" - desc = "A suitcase containing the necessary gun parts to tranform a standard energy gun into a temperature gun. Fantastic at birthday parties and killing indigenious populations of Ash Walkers." + desc = "A suitcase containing the necessary gun parts to transform a standard energy gun into a temperature gun. Fantastic at birthday parties and killing indigenious populations of Ash Walkers." origin_tech = "combat=4;materials=4;powerstorage=3;magnets=2" outcome = /obj/item/gun/energy/temperature diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 222525119560..71c296d900bd 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -17,7 +17,7 @@ /obj/structure/fermenting_barrel/examine(mob/user) . = ..() - . += "It is currently [open ? "open, letting you pour liquids in." : "closed, letting you draw liquids from the tap."] " + . += "It is currently [open ? "open, letting you pour liquids in." : "closed, letting you draw liquids from the tap."]" /obj/structure/fermenting_barrel/proc/makeWine(obj/item/food/snacks/grown/G) if(G.reagents) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index a2a20770c767..8ce9afac83e4 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -4,7 +4,7 @@ /mob/living/simple_animal/hostile/hivebot name = "Hivebot" - desc = "A small robot" + desc = "A small robot." icon = 'icons/mob/hivebot.dmi' icon_state = "basic" icon_living = "basic" diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm index 0b36601101e7..2e35b5994676 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm @@ -51,7 +51,7 @@ user.do_attack_animation(src) if(O.force) if(prob(melee_block_chance)) - visible_message("[src] blocks [O] with its shield! ") + visible_message("[src] blocks [O] with its shield!") else var/damage = O.force if(O.damtype == STAMINA) @@ -60,11 +60,11 @@ visible_message("[src] is unharmed by [O]!") return adjustHealth(damage) - visible_message("[src] has been attacked with [O] by [user]. ") + visible_message("[src] has been attacked with [O] by [user].") playsound(loc, O.hitsound, 25, 1, -1) else to_chat(usr, "This weapon is ineffective, it does no damage.") - visible_message("[user] gently taps [src] with [O]. ") + visible_message("[user] gently taps [src] with [O].") /mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj) diff --git a/code/modules/power/apc/apc.dm b/code/modules/power/apc/apc.dm index fadf8593c894..91239fcf9cbc 100644 --- a/code/modules/power/apc/apc.dm +++ b/code/modules/power/apc/apc.dm @@ -346,7 +346,7 @@ else if(istype(W, /obj/item/mounted/frame/apc_frame) && opened) if(!(stat & BROKEN || opened == APC_COVER_OFF || obj_integrity < max_integrity)) // There is nothing to repair - to_chat(user, "You found no reason for repairing this APC") + to_chat(user, "You found no reason for repairing this APC.") return if(!(stat & BROKEN) && opened == APC_COVER_OFF) // Cover is the only thing broken, we do not need to remove elctronicks to replace cover user.visible_message("[user.name] replaces missing APC's cover.",\ diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 4231ecd31dbc..1dc73578f316 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -571,7 +571,7 @@ /obj/item/v1_arm_shell name = "vortex feedback arm implant frame" - desc = "An implant awaiting installation of a vortex anomaly core" + desc = "An implant awaiting installation of a vortex anomaly core." icon_state = "v1_arm" /obj/item/v1_arm_shell/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 5d7fb4d2bb57..d1d53dbb77a7 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -1,6 +1,6 @@ /obj/item/organ/internal/cyberimp/eyes name = "cybernetic eyes" - desc = "artificial photoreceptors with specialized functionality" + desc = "artificial photoreceptors with specialized functionality." icon_state = "eye_implant" implant_overlay = "eye_implant_overlay" slot = "eye_sight" diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index c5fa8032c335..ae39f0a84616 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -1,6 +1,6 @@ /obj/item/organ/internal/cyberimp name = "cybernetic implant" - desc = "a state-of-the-art implant that improves a baseline's functionality" + desc = "a state-of-the-art implant that improves a baseline's functionality." status = ORGAN_ROBOT var/implant_color = "#FFFFFF" var/implant_overlay @@ -21,7 +21,7 @@ /obj/item/organ/internal/cyberimp/brain name = "cybernetic brain implant" - desc = "injectors of extra sub-routines for the brain" + desc = "injectors of extra sub-routines for the brain." icon_state = "brain_implant" implant_overlay = "brain_implant_overlay" parent_organ = "head" @@ -204,7 +204,7 @@ /obj/item/organ/internal/cyberimp/brain/anti_sleep/hardened/compatible name = "Hardened Neural Jumpstarter implant" - desc = "A military-grade version of the standard implant, for NT's more elite forces. This one is compatible with the CNS Rebooter implant" + desc = "A military-grade version of the standard implant, for NT's more elite forces. This one is compatible with the CNS Rebooter implant." slot = "brain_antisleep" emp_proof = TRUE @@ -309,7 +309,7 @@ //[[[[CHEST]]]] /obj/item/organ/internal/cyberimp/chest name = "cybernetic torso implant" - desc = "implants for the organs in your torso" + desc = "implants for the organs in your torso." icon_state = "chest_implant" implant_overlay = "chest_implant_overlay" parent_organ = "chest" diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index aec0dcb6c1e1..700232bf3fe4 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -213,7 +213,7 @@ /obj/item/organ/internal/eyes/cybernetic/eyesofgod //no occuline allowed name = "\improper Eyes of the Gods" - desc = "Two eyes said to belong to the gods. But such vision comes at a price" + desc = "Two eyes said to belong to the gods. But such vision comes at a price." icon_state = "eyesofgod" eye_color = "#58a5ec" see_in_dark = 8 diff --git a/code/modules/surgery/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm index 8f53727e6971..d8037ad8066d 100644 --- a/code/modules/surgery/organs/robolimbs.dm +++ b/code/modules/surgery/organs/robolimbs.dm @@ -123,7 +123,7 @@ GLOBAL_DATUM(basic_robolimb, /datum/robolimb) /datum/robolimb/shellguard company = "Shellguard Munitions Standard Series" - desc = "This limb features exposed robust steel and paint to match Shellguards motifs" + desc = "This limb features exposed robust steel and paint to match Shellguards motifs." icon = 'icons/mob/human_races/cyberlimbs/shellguard/shellguard_main.dmi' has_subtypes = 1 diff --git a/code/modules/surgery/organs/skeleton_organs.dm b/code/modules/surgery/organs/skeleton_organs.dm index 7ccbb2c69f26..b1a6329b013f 100644 --- a/code/modules/surgery/organs/skeleton_organs.dm +++ b/code/modules/surgery/organs/skeleton_organs.dm @@ -36,15 +36,15 @@ /obj/item/skeleton/r_leg name = "skeleton right leg" - desc = "a skeleton right leg" + desc = "a skeleton right leg." icon_state = "r_leg" /obj/item/skeleton/l_foot name = "skeleton left foot" - desc = "a skeleton left foot" + desc = "a skeleton left foot." icon_state = "l_foot" /obj/item/skeleton/l_leg name = "skeleton left leg" - desc = "a skeleton left leg" + desc = "a skeleton left leg." icon_state = "l_leg" diff --git a/code/modules/surgery/organs/subtypes/drask_organs.dm b/code/modules/surgery/organs/subtypes/drask_organs.dm index 201c05b83e30..4d94b9e84d83 100644 --- a/code/modules/surgery/organs/subtypes/drask_organs.dm +++ b/code/modules/surgery/organs/subtypes/drask_organs.dm @@ -25,5 +25,5 @@ /obj/item/organ/internal/eyes/drask name = "drask eyeballs" icon = 'icons/obj/species_organs/drask.dmi' - desc = "Drask eyes. They look even stranger disembodied" + desc = "Drask eyes. They look even stranger disembodied." see_in_dark = 5 diff --git a/code/modules/surgery/organs/subtypes/grey_organs.dm b/code/modules/surgery/organs/subtypes/grey_organs.dm index 3dfe9f77c688..132a79faae0c 100644 --- a/code/modules/surgery/organs/subtypes/grey_organs.dm +++ b/code/modules/surgery/organs/subtypes/grey_organs.dm @@ -1,11 +1,11 @@ /obj/item/organ/internal/liver/grey name = "grey liver" - desc = "A small, odd looking liver" + desc = "A small, odd looking liver." icon = 'icons/obj/species_organs/grey.dmi' alcohol_intensity = 1.6 /obj/item/organ/internal/brain/grey - desc = "A large brain" + desc = "A large brain." icon = 'icons/obj/species_organs/grey.dmi' icon_state = "brain2" mmi_icon = 'icons/obj/species_organs/grey.dmi' @@ -21,7 +21,7 @@ /obj/item/organ/internal/eyes/grey name = "grey eyeballs" - desc = "They still look creepy and emotionless" + desc = "They still look creepy and emotionless." icon = 'icons/obj/species_organs/grey.dmi' see_in_dark = 5 diff --git a/code/modules/surgery/organs/subtypes/skrell_organs.dm b/code/modules/surgery/organs/subtypes/skrell_organs.dm index 09dd526c9b56..de58d05a866f 100644 --- a/code/modules/surgery/organs/subtypes/skrell_organs.dm +++ b/code/modules/surgery/organs/subtypes/skrell_organs.dm @@ -87,7 +87,7 @@ /obj/item/organ/internal/heart/skrell name = "skrell heart" - desc = "A stream lined heart" + desc = "A stream lined heart." icon = 'icons/obj/species_organs/skrell.dmi' /obj/item/organ/internal/brain/skrell diff --git a/code/modules/surgery/organs/subtypes/unathi_organs.dm b/code/modules/surgery/organs/subtypes/unathi_organs.dm index 13857d77ab23..c0887844d784 100644 --- a/code/modules/surgery/organs/subtypes/unathi_organs.dm +++ b/code/modules/surgery/organs/subtypes/unathi_organs.dm @@ -1,7 +1,7 @@ /obj/item/organ/internal/liver/unathi name = "unathi liver" icon = 'icons/obj/species_organs/unathi.dmi' - desc = "A large looking liver" + desc = "A large looking liver." alcohol_intensity = 0.8 /obj/item/organ/internal/eyes/unathi @@ -11,7 +11,7 @@ /obj/item/organ/internal/heart/unathi name = "unathi heart" - desc = "A large looking heart" + desc = "A large looking heart." icon = 'icons/obj/species_organs/unathi.dmi' /obj/item/organ/internal/brain/unathi diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index a809ec7ed82b..745e4220646a 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -491,7 +491,7 @@ GLOBAL_DATUM_INIT(multispin_words, /regex, regex("like a record baby")) log_game("[key_name(owner)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") /obj/item/organ/internal/vocal_cords/colossus/wizard - desc = "They carry the voice of an ancient god. This one is enchanted to implant it into yourself when used in hand" + desc = "They carry the voice of an ancient god. This one is enchanted to implant it into yourself when used in hand." /obj/item/organ/internal/vocal_cords/colossus/wizard/attack_self(mob/living/user) user.drop_item() From 4af0df0bd65cdbb52ffe8038e1dad2c23c647451 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:45:57 -0500 Subject: [PATCH 06/26] she darkens on my ness till I (#23844) --- code/modules/power/engines/supermatter/supermatter.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/power/engines/supermatter/supermatter.dm b/code/modules/power/engines/supermatter/supermatter.dm index 50fc30a67499..1e95a2216807 100644 --- a/code/modules/power/engines/supermatter/supermatter.dm +++ b/code/modules/power/engines/supermatter/supermatter.dm @@ -961,7 +961,7 @@ l_power = 3, l_color = SUPERMATTER_SINGULARITY_LIGHT_COLOUR, ) - if(!combined_gas > MOLE_PENALTY_THRESHOLD || !get_integrity() < SUPERMATTER_DANGER_PERCENT) + if(!combined_gas > MOLE_PENALTY_THRESHOLD || get_integrity() > SUPERMATTER_DANGER_PERCENT) for(var/obj/D in darkness_effects) qdel(D) return @@ -972,7 +972,7 @@ l_range = 4 + darkness_aoe, l_power = -1 - darkness_strength, l_color = "#ddd6cf") - if(!length(darkness_effects) && moveable) //Don't do this on movable sms oh god. Ideally don't do this at all, but hey, that's lightning for you + if(!length(darkness_effects) && !moveable) //Don't do this on movable sms oh god. Ideally don't do this at all, but hey, that's lightning for you darkness_effects += new /obj/effect/abstract(locate(x-3,y+3,z)) darkness_effects += new /obj/effect/abstract(locate(x+3,y+3,z)) darkness_effects += new /obj/effect/abstract(locate(x-3,y-3,z)) From 11d3b4381530d2eef7e4d03939359c4b322c21e9 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:05:46 -0500 Subject: [PATCH 07/26] IPCs once again get 65 damage from a heavy EMP, and 40 from a light. (#23865) * IPCs once again get 65 damage from a heavy EMP, and 40 from a light. * Update code/modules/surgery/organs/organ_external.dm Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> --------- Co-authored-by: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> --- code/modules/surgery/organs/organ_external.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index f744c86a1225..84683029ab1b 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -359,11 +359,11 @@ else if(emp_resistant) // IPC limbs switch(severity) if(1) - // 5.28 (9 * 0.66 burn_mod) burn damage, 65.34 damage with 11 limbs. - receive_damage(0, 9) + // 5.9 burn damage, 64.9 damage with 11 limbs. + receive_damage(0, 5.9) if(2) - // 3.63 (5 * 0.66 burn_mod) burn damage, 39.93 damage with 11 limbs. - receive_damage(0, 5.5) + // 3.63 burn damage, 39.93 damage with 11 limbs. + receive_damage(0, 3.63) else // Basic prosthetic limbs switch(severity) if(1) From f8a55e7178e3bf30d0796b651bb154a7da382754 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Thu, 25 Jan 2024 14:24:03 -0500 Subject: [PATCH 08/26] Remove unused 'salvage captain' ID and related areas (#23822) * Remove unused 'salvage captain' ID * Just remove as it was never used --- code/__DEFINES/access_defines.dm | 1 - code/game/area/shuttle_areas.dm | 57 -------------------- code/game/jobs/access.dm | 2 +- code/game/objects/items/weapons/cards_ids.dm | 7 --- 4 files changed, 1 insertion(+), 66 deletions(-) diff --git a/code/__DEFINES/access_defines.dm b/code/__DEFINES/access_defines.dm index d70c203f562c..ea67634a1bab 100644 --- a/code/__DEFINES/access_defines.dm +++ b/code/__DEFINES/access_defines.dm @@ -65,7 +65,6 @@ #define ACCESS_XENOARCH 65 #define ACCESS_PARAMEDIC 66 #define ACCESS_BLUESHIELD 67 -#define ACCESS_SALVAGE_CAPTAIN 69 // Salvage ship captain's quarters // #define ACCESS_MECHANIC 70 // AA07 2021-10-02 - Removed: Kept for history sake // #define ACCESS_PILOT 71 // AA07 2021-10-02 - Removed: Kept for history sake #define ACCESS_NTREP 73 diff --git a/code/game/area/shuttle_areas.dm b/code/game/area/shuttle_areas.dm index be9f5f44fb22..efd45956d8e5 100644 --- a/code/game/area/shuttle_areas.dm +++ b/code/game/area/shuttle_areas.dm @@ -234,63 +234,6 @@ /area/shuttle/research/outpost icon_state = "shuttle" -/area/shuttle/salvage - name = "\improper Salvage Ship" - icon_state = "yellow" - -/area/shuttle/salvage/start - name = "\improper Middle of Nowhere" - icon_state = "yellow" - -/area/shuttle/salvage/arrivals - name = "\improper Space Station Auxiliary Docking" - icon_state = "yellow" - -/area/shuttle/salvage/derelict - name = "\improper Derelict Station" - icon_state = "yellow" - -/area/shuttle/salvage/djstation - name = "\improper Ruskie DJ Station" - icon_state = "yellow" - -/area/shuttle/salvage/north - name = "\improper North of the Station" - icon_state = "yellow" - -/area/shuttle/salvage/east - name = "\improper East of the Station" - icon_state = "yellow" - -/area/shuttle/salvage/south - name = "\improper South of the Station" - icon_state = "yellow" - -/area/shuttle/salvage/commssat - name = "\improper The Communications Satellite" - icon_state = "yellow" - -/area/shuttle/salvage/mining - name = "\improper South-West of the Mining Asteroid" - icon_state = "yellow" - -/area/shuttle/salvage/abandoned_ship - name = "\improper Abandoned Ship" - icon_state = "yellow" - parallax_movedir = WEST - -/area/shuttle/salvage/clown_asteroid - name = "\improper Clown Asteroid" - icon_state = "yellow" - -/area/shuttle/salvage/trading_post - name = "\improper Trading Post" - icon_state = "yellow" - -/area/shuttle/salvage/transit - name = "\improper hyperspace" - icon_state = "shuttle" - /area/shuttle/supply name = "Supply Shuttle" icon_state = "shuttle3" diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 41701ab29314..cdc77fa8ad39 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -144,7 +144,7 @@ return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER, ACCESS_SYNDICATE_COMMAND) /proc/get_all_misc_access() - return list(ACCESS_SALVAGE_CAPTAIN, ACCESS_TRADE_SOL, ACCESS_CRATE_CASH, ACCESS_AWAY01) + return list(ACCESS_TRADE_SOL, ACCESS_CRATE_CASH, ACCESS_AWAY01) /proc/get_absolutely_all_accesses() return (get_all_accesses() | get_all_centcom_access() | get_all_syndicate_access() | get_all_misc_access()) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index d949c064c277..556839fdb0f0 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -717,13 +717,6 @@ name = "Prisoner [random_number]" registered_name = name -/obj/item/card/id/salvage_captain - name = "Captain's ID" - registered_name = "Captain" - icon_state = "centcom" - desc = "Finders, keepers." - access = list(ACCESS_SALVAGE_CAPTAIN) - /obj/item/card/id/medical name = "Medical ID" registered_name = "Medic" From 151a3b965e1a6b91ee77ffad22e682d02afcd2e0 Mon Sep 17 00:00:00 2001 From: Henri215 <77684085+Henri215@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:24:37 -0300 Subject: [PATCH 09/26] Fixes the metal foam box sprite being invisible (#23888) --- code/game/objects/items/weapons/storage/boxes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index c48d21529535..43e323d98307 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -1226,7 +1226,7 @@ /obj/item/storage/box/foam_grenades name = "foam grenades box" desc = "A box full of foam grenades." - icon_state = "flashbang" + icon_state = "flashbang_box" /obj/item/storage/box/foam_grenades/populate_contents() for(var/I in 1 to 7) From 7f62df8ff1d2d58869d8b3c084820fc65919a59f Mon Sep 17 00:00:00 2001 From: Henri215 <77684085+Henri215@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:24:59 -0300 Subject: [PATCH 10/26] Fixes multiverse sword sprite being invisible (#23887) --- code/game/gamemodes/wizard/artefact.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 4fec8ed99bb2..f6a00c9cf492 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -322,6 +322,7 @@ GLOBAL_LIST_EMPTY(multiverse) /obj/item/multisword name = "multiverse sword" desc = "A weapon capable of conquering the universe and beyond. Activate it to summon copies of yourself from others dimensions to fight by your side." + icon = 'icons/obj/energy_melee.dmi' lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' icon_state = "energy_katana" @@ -707,6 +708,7 @@ GLOBAL_LIST_EMPTY(multiverse) /obj/item/multisword/pike //If We are to be used and spent, let it be for a noble purpose. name = "phantom pike" desc = "A fishing pike that appears to be imbued with a peculiar energy." + icon = 'icons/obj/items.dmi' icon_state = "harpoon" item_state = "harpoon" cooldown_between_uses = 200 //Half the time From 2fed2559139f1736432c96e00d686006dbfe218e Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Thu, 25 Jan 2024 20:25:20 +0100 Subject: [PATCH 11/26] It is that fucing easy (#23881) --- code/modules/projectiles/projectile/magic_projectiles.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile/magic_projectiles.dm b/code/modules/projectiles/projectile/magic_projectiles.dm index ae210e6a0147..5a8f424c85e6 100644 --- a/code/modules/projectiles/projectile/magic_projectiles.dm +++ b/code/modules/projectiles/projectile/magic_projectiles.dm @@ -311,7 +311,6 @@ damage_type = BURN /obj/item/projectile/magic/animate/Bump(atom/change) - ..() if(isitem(change) || isstructure(change) && !is_type_in_list(change, GLOB.protected_objects)) if(istype(change, /obj/structure/closet/statue)) for(var/mob/living/carbon/human/H in change.contents) @@ -336,6 +335,7 @@ // Change our allegiance! var/mob/living/simple_animal/hostile/mimic/copy/C = change C.ChangeOwner(firer) + return ..() /obj/item/projectile/magic/slipping name = "magical banana" From 5b150dfe5e006398020c2276573ef409285b56d7 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Thu, 25 Jan 2024 14:28:31 -0500 Subject: [PATCH 12/26] allow quick spawn with doubleclick (#23851) --- html/create_object.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/html/create_object.html b/html/create_object.html index 49af318f6f0e..bcc0f71a270b 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -65,4 +65,10 @@ populateList(filtered); } + + function quickSpawn() { + document.spawner.submit(); + } + + document.getElementById('object_list').ondblclick = quickSpawn; From f09b509f1c600f73cd596e639a91d899acc12d58 Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Thu, 25 Jan 2024 19:29:20 +0000 Subject: [PATCH 13/26] remove additional debug logs (#23875) --- tgui/bin/tgui | 1 - tgui/bin/tgui_.ps1 | 1 - 2 files changed, 2 deletions(-) diff --git a/tgui/bin/tgui b/tgui/bin/tgui index 863eb91c464b..30e59c052133 100755 --- a/tgui/bin/tgui +++ b/tgui/bin/tgui @@ -109,7 +109,6 @@ task-validate-build() { cd "${base_dir}" local diff diff="$(git diff --text public/*)" - echo ${diff} if [[ -n ${diff} ]]; then echo "Error: our build differs from the build committed into git." echo "Please rebuild tgui." diff --git a/tgui/bin/tgui_.ps1 b/tgui/bin/tgui_.ps1 index 6658aeb0cdd3..c310007a70a6 100644 --- a/tgui/bin/tgui_.ps1 +++ b/tgui/bin/tgui_.ps1 @@ -96,7 +96,6 @@ function task-clean { ## Validates current build against the build stored in git function task-validate-build { $diff = git diff --text public/* - Write-Output $diff if ($diff) { Write-Output "Error: our build differs from the build committed into git." Write-Output "Please rebuild tgui." From 826b1851822d364197df13c275442e7bc7d974c1 Mon Sep 17 00:00:00 2001 From: Henri215 <77684085+Henri215@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:30:07 -0300 Subject: [PATCH 14/26] Fixes janihud highlight not being very visible sometimes (#23896) * Fixes janihud highlight not being very visible sometimes * damn you ants --- code/game/data_huds.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 51d8bbc88417..29124ecc5031 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -503,6 +503,7 @@ holder.icon_state = "hudjani" holder.alpha = 130 holder.plane = ABOVE_LIGHTING_PLANE + holder.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I'll just put this somewhere near the end... From fe9221bf5725e5e1e36cd13de4ca55f266846134 Mon Sep 17 00:00:00 2001 From: Mikhail Dzianishchyts Date: Thu, 25 Jan 2024 22:31:17 +0300 Subject: [PATCH 15/26] Fix multiple s-class sm anomalies per round (#23855) --- code/modules/power/engines/supermatter/supermatter.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/engines/supermatter/supermatter.dm b/code/modules/power/engines/supermatter/supermatter.dm index 1e95a2216807..9194a691e6ca 100644 --- a/code/modules/power/engines/supermatter/supermatter.dm +++ b/code/modules/power/engines/supermatter/supermatter.dm @@ -1223,7 +1223,7 @@ /datum/supermatter_event/sierra_tier = 1) var/datum/supermatter_event/event = pick(subtypesof(pickweight(events))) - if(istype(event, /datum/supermatter_event/sierra_tier) && has_run_sclass) + if(ispath(event, /datum/supermatter_event/sierra_tier) && has_run_sclass) make_next_event_time() return // We're only gonna have one s-class per round, take a break engineers run_event(event) From 6fca653d699d7b9d7d004a422d5baff51c1e9da7 Mon Sep 17 00:00:00 2001 From: Coolrune206 <71326864+Coolrune206@users.noreply.github.com> Date: Fri, 26 Jan 2024 05:31:41 +1000 Subject: [PATCH 16/26] increases fleshmend by one point (#23852) --- code/modules/antagonists/changeling/powers/fleshmend.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/changeling/powers/fleshmend.dm b/code/modules/antagonists/changeling/powers/fleshmend.dm index a2d46914432c..b0ee5255b5cd 100644 --- a/code/modules/antagonists/changeling/powers/fleshmend.dm +++ b/code/modules/antagonists/changeling/powers/fleshmend.dm @@ -4,7 +4,7 @@ helptext = "Does not regrow limbs. Partially recovers our blood. Functions while unconscious." button_icon_state = "fleshmend" chemical_cost = 20 - dna_cost = 4 + dna_cost = 5 req_stat = UNCONSCIOUS power_type = CHANGELING_PURCHASABLE_POWER category = /datum/changeling_power_category/defence From 44729b788aef1f6da7320e747a2d2b10c3f5fe0f Mon Sep 17 00:00:00 2001 From: PopeDaveThe3th <80988376+PopeDaveThe3th@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:33:23 -0500 Subject: [PATCH 17/26] Purges clown planet references from station traits (#23834) * ah shit, here we go again * Update code/datums/station_traits/neutral_traits.dm Co-authored-by: synthtee <127706731+SynthTwo@users.noreply.github.com> --------- Co-authored-by: synthtee <127706731+SynthTwo@users.noreply.github.com> --- code/datums/station_traits/neutral_traits.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 1374f9d0616d..91a8cbf084ac 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -2,14 +2,14 @@ name = "Bananium Shipment" trait_type = STATION_TRAIT_NEUTRAL weight = 5 - report_message = "Rumor has it that the clown planet has been sending support packages to clowns in this system." + report_message = "An unidentified benefactor has dispatched a mysterious shipment to your station's clown. It was reported to smell faintly of bananas." trait_to_give = STATION_TRAIT_BANANIUM_SHIPMENTS /datum/station_trait/bananium_shipment name = "Tranquilite Shipment" trait_type = STATION_TRAIT_NEUTRAL weight = 5 - report_message = "Rumor has it that the mime federation has been sending support packages to mimes in this system." + report_message = "Shipping records show an unmarked crate being delivered to your station's mime." trait_to_give = STATION_TRAIT_TRANQUILITE_SHIPMENTS /datum/station_trait/unique_ai From 6a11049bca1fe8bb902260b64c6ccfead9f732be Mon Sep 17 00:00:00 2001 From: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:34:58 -0500 Subject: [PATCH 18/26] Robotic Analyzer Buff + Cleanup (#23523) * analyzing robots * how can it analyze the reagents of organics * they may be snowflakes but theyre special to me * Update code/game/objects/items/devices/scanners.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * Update code/game/objects/items/devices/scanners.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * Update code/game/objects/items/devices/scanners.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Update code/game/objects/items/devices/scanners.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Update code/game/objects/items/devices/scanners.dm Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * whoopsies --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> --- code/game/objects/items/devices/scanners.dm | 124 ++++++++++++++++++ .../mob/living/silicon/robot/component.dm | 115 ---------------- 2 files changed, 124 insertions(+), 115 deletions(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 723c11a2c3c8..88a0193628a2 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -3,6 +3,7 @@ CONTAINS: T-RAY DETECTIVE SCANNER HEALTH ANALYZER +ROBOT ANALYZER GAS ANALYZER PLANT ANALYZER REAGENT SCANNER @@ -328,6 +329,129 @@ REAGENT SCANNER origin_tech = "magnets=2;biotech=2" usesound = 'sound/items/deconstruct.ogg' +/obj/item/robotanalyzer + name = "cyborg analyzer" + desc = "A hand-held scanner able to diagnose robotic injuries." + icon = 'icons/obj/device.dmi' + icon_state = "robotanalyzer" + item_state = "analyzer" + flags = CONDUCT + slot_flags = SLOT_FLAG_BELT + throwforce = 3 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 5 + throw_range = 10 + origin_tech = "magnets=1;biotech=1" + +/obj/item/robotanalyzer/attack(mob/living/M, mob/living/user) + if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50)) + var/list/msgs = list() + user.visible_message("[user] has analyzed the floor's components!", "You try to analyze the floor's vitals!") + msgs += "Analyzing Results for The floor:\n\t Overall Status: Unknown" + msgs += "\t Damage Specifics: [0]/Key: Burns/Brute" + msgs += "Chassis Temperature: ???" + to_chat(user, chat_box_healthscan(msgs.Join("
"))) + return + + user.visible_message("[user] has analyzed [M]'s components.", "You have analyzed [M]'s components.") + robot_healthscan(user, M) + add_fingerprint(user) + +/proc/robot_healthscan(mob/user, mob/living/M) + var/scan_type + var/list/msgs = list() + if(isrobot(M)) + scan_type = "robot" + else if(ishuman(M)) + scan_type = "prosthetics" + else if(isAI(M)) + scan_type = "ai" + else + to_chat(user, "You can't analyze non-robotic things!") + return + + switch(scan_type) + if("robot") + var/burn = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() + var/brute = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() + msgs += "Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health]% functional"]" + msgs += "\t Key: Electronics/Brute" + msgs += "\t Damage Specifics: [burn] - [brute]" + if(M.timeofdeath && M.stat == DEAD) + msgs += "Time of disable: [station_time_timestamp("hh:mm:ss", M.timeofdeath)]" + var/mob/living/silicon/robot/H = M + var/list/damaged = H.get_damaged_components(TRUE, TRUE, TRUE) // Get all except the missing ones + var/list/missing = H.get_missing_components() + msgs += "Localized Damage:" + if(!LAZYLEN(damaged) && !LAZYLEN(missing)) + msgs += "\t Components are OK." + else + if(LAZYLEN(damaged)) + for(var/datum/robot_component/org in damaged) + msgs += text("\t []: [][] - [] - [] - []", \ + capitalize(org.name), \ + (org.is_destroyed()) ? "DESTROYED " :"",\ + (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ + (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ + (org.toggled) ? "Toggled ON" : "Toggled OFF",\ + (org.powered) ? "Power ON" : "Power OFF") + if(LAZYLEN(missing)) + for(var/datum/robot_component/org in missing) + msgs += "\t [capitalize(org.name)]: MISSING" + + if(H.emagged && prob(5)) + msgs += "\t ERROR: INTERNAL SYSTEMS COMPROMISED" + + if("prosthetics") + var/mob/living/carbon/human/H = M + var/is_ipc = ismachineperson(H) + msgs += "Analyzing Results for [M]: [is_ipc ? "\n\t Overall Status: [H.stat > 1 ? "fully disabled" : "[H.health]% functional"]
" : "
"]" //for the record im sorry + msgs += "\t Key: Electronics/Brute" + msgs += "External prosthetics:" + var/organ_found + if(LAZYLEN(H.internal_organs)) + for(var/obj/item/organ/external/E in H.bodyparts) + if(!E.is_robotic() || (is_ipc && (E.get_damage() == 0))) //Non-IPCs have their cybernetics show up in the scan, even if undamaged + continue + organ_found = TRUE + msgs += "[E.name]: [E.brute_dam] [E.burn_dam]" + if(!organ_found) + msgs += "No prosthetics located." + msgs += "
" + msgs += "Internal prosthetics:" + organ_found = null + if(LAZYLEN(H.internal_organs)) + for(var/obj/item/organ/internal/O in H.internal_organs) + if(!O.is_robotic() || istype(O, /obj/item/organ/internal/cyberimp)) + continue + organ_found = TRUE + msgs += "[capitalize(O.name)]: [O.damage]" + if(!organ_found) + msgs += "No prosthetics located." + msgs += "
" + msgs += "Cybernetic implants:" + organ_found = null + if(LAZYLEN(H.internal_organs)) + for(var/obj/item/organ/internal/cyberimp/I in H.internal_organs) + organ_found = TRUE + msgs += "[capitalize(I.name)]: [I.crit_fail ? "CRITICAL FAILURE" : I.damage]" + if(!organ_found) + msgs += "No implants located." + msgs += "
" + if(is_ipc) + msgs.Add(get_chemscan_results(user, H)) + msgs += "Subject temperature: [round(H.bodytemperature-T0C, 0.01)]°C ([round(H.bodytemperature*1.8-459.67, 0.01)]°F)" + if("ai") + var/mob/living/silicon/ai/A = M + var/burn = A.getFireLoss() > 50 ? "[A.getFireLoss()]" : A.getFireLoss() + var/brute = A.getBruteLoss() > 50 ? "[A.getBruteLoss()]" : A.getBruteLoss() + msgs += "Analyzing Results for [M]:\n\t Overall Status: [A.stat > 1 ? "fully disabled" : "[A.health]% functional"]" + msgs += "\t Key: Electronics/Brute" + msgs += "\t Damage Specifics: [burn] - [brute]" + + to_chat(user, chat_box_healthscan(msgs.Join("
"))) + /obj/item/analyzer name = "analyzer" desc = "A hand-held environmental scanner which reports current gas levels." diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 49b7baaf9504..f3f11facad02 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -243,118 +243,3 @@ name = "radio" desc = "A modular, multi-frequency radio used by robots and exosuits to enable communication systems. Comes with built-in subspace receivers." icon_state = "radio" - -// -//Robotic Component Analyzer, basically a health analyzer for robots -// -/obj/item/robotanalyzer - name = "cyborg analyzer" - icon = 'icons/obj/device.dmi' - icon_state = "robotanalyzer" - item_state = "analyzer" - desc = "A hand-held scanner able to diagnose robotic injuries." - flags = CONDUCT - slot_flags = SLOT_FLAG_BELT - throwforce = 3 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 5 - throw_range = 10 - origin_tech = "magnets=1;biotech=1" - var/mode = 1 - -/obj/item/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob) - if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50)) - var/list/messages = list() - user.visible_message("[user] has analyzed the floor's vitals!", "You try to analyze the floor's vitals!") - messages.Add("Analyzing Results for The floor:\n\t Overall Status: Healthy") - messages.Add("\t Damage Specifics: [0]-[0]-[0]-[0]") - messages.Add("Key: Suffocation/Toxin/Burns/Brute") - messages.Add("Body Temperature: ???") - to_chat(user, chat_box_healthscan(messages.Join("
"))) - return - - user.visible_message("[user] has analyzed [M]'s components.","You have analyzed [M]'s components.") - robot_healthscan(user, M) - add_fingerprint(user) - - -/proc/robot_healthscan(mob/user, mob/living/M) - var/scan_type - if(isrobot(M)) - scan_type = "robot" - else if(ishuman(M)) - scan_type = "prosthetics" - else - to_chat(user, "You can't analyze non-robotic things!") - return - - var/list/messages = list() - switch(scan_type) - if("robot") - var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() - var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() - messages.Add("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health]% functional"]") - messages.Add("\t Key: Electronics/Brute") - messages.Add("\t Damage Specifics: [BU] - [BR]") - if(M.timeofdeath && M.stat == DEAD) - messages.Add("Time of Disable: [station_time_timestamp("hh:mm:ss", M.timeofdeath)]") - var/mob/living/silicon/robot/H = M - var/list/damaged = H.get_damaged_components(TRUE, TRUE, TRUE) // Get all except the missing ones - var/list/missing = H.get_missing_components() - messages.Add("Localized Damage:") - if(!LAZYLEN(damaged) && !LAZYLEN(missing)) - messages.Add("\t Components are OK.") - else - if(LAZYLEN(damaged)) - for(var/datum/robot_component/org in damaged) - messages.Add(text("\t []: [][] - [] - [] - []", \ - capitalize(org.name), \ - (org.is_destroyed()) ? "DESTROYED " :"",\ - (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \ - (org.brute_damage > 0) ? "[org.brute_damage]" :0, \ - (org.toggled) ? "Toggled ON" : "Toggled OFF",\ - (org.powered) ? "Power ON" : "Power OFF"),1) - if(LAZYLEN(missing)) - for(var/datum/robot_component/org in missing) - messages.Add("\t [capitalize(org.name)]: MISSING") - - if(H.emagged && prob(5)) - messages.Add("\t ERROR: INTERNAL SYSTEMS COMPROMISED") - - if("prosthetics") - var/mob/living/carbon/human/H = M - messages.Add("Analyzing Results for \the [H]:") - messages.Add("Key: Electronics/Brute") - - to_chat(user, "External prosthetics:") - var/organ_found - if(LAZYLEN(H.internal_organs)) - for(var/obj/item/organ/external/E in H.bodyparts) - if(!E.is_robotic()) - continue - organ_found = TRUE - messages.Add("[E.name]: [E.brute_dam] [E.burn_dam]") - if(!organ_found) - messages.Add("No prosthetics located.") - messages.Add("
") - messages.Add("Internal prosthetics:") - organ_found = null - if(LAZYLEN(H.internal_organs)) - for(var/obj/item/organ/internal/O in H.internal_organs) - if(!O.is_robotic() || istype(O, /obj/item/organ/internal/cyberimp)) - continue - organ_found = TRUE - messages.Add("[capitalize(O.name)]: [O.damage]") - if(!organ_found) - messages.Add("No prosthetics located.") - messages.Add("
") - messages.Add("Cybernetic implants:") - organ_found = null - if(LAZYLEN(H.internal_organs)) - for(var/obj/item/organ/internal/cyberimp/I in H.internal_organs) - organ_found = TRUE - messages.Add("[capitalize(I.name)]: [I.crit_fail ? "CRITICAL FAILURE" : I.damage]") - if(!organ_found) - messages.Add("No implants located.") - - to_chat(user, chat_box_healthscan(messages.Join("
"))) From 80f617027022fdab35fc7f6cb37a4c80c37f8b6f Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Thu, 25 Jan 2024 21:18:47 +0100 Subject: [PATCH 19/26] Small QOL improvement for (bluespace) light replacers (#23826) * Neat * Update code/game/objects/items/devices/lightreplacer.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/game/objects/items/devices/lightreplacer.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Lewc review --------- Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --- code/game/objects/items/devices/lightreplacer.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 74c9a68c1a9f..70469db1ff34 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -227,17 +227,18 @@ else return 0 -/obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity) +/obj/item/lightreplacer/afterattack(atom/target_turf, mob/U, proximity) . = ..() if(!proximity && !bluespace_toggle) return - if(!isturf(T)) + var/turf/replace_turf = get_turf(target_turf) + if(!istype(replace_turf)) return - if(get_dist(src, T) >= (U.client.maxview() + 2)) // To prevent people from using it over cameras + if(get_dist(src, target_turf) >= (U.client.maxview() + 2)) // To prevent people from using it over cameras return var/used = FALSE - for(var/atom/A in T) + for(var/atom/A in replace_turf) if(!CanUse(U)) break used = TRUE From ea945fbefa2167319e510829e7668bc5f93ddd16 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Fri, 26 Jan 2024 03:25:30 -0500 Subject: [PATCH 20/26] remove empty DM file (#23938) --- code/__DEFINES/antagonists.dm | 1 - paradise.dme | 1 - 2 files changed, 2 deletions(-) delete mode 100644 code/__DEFINES/antagonists.dm diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm deleted file mode 100644 index 8b137891791f..000000000000 --- a/code/__DEFINES/antagonists.dm +++ /dev/null @@ -1 +0,0 @@ - diff --git a/paradise.dme b/paradise.dme index 607b980ce6c6..801abdef0b62 100644 --- a/paradise.dme +++ b/paradise.dme @@ -30,7 +30,6 @@ #include "code\__DEFINES\access_defines.dm" #include "code\__DEFINES\admin_defines.dm" #include "code\__DEFINES\announce_defines.dm" -#include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\armour.dm" #include "code\__DEFINES\asset_defines.dm" #include "code\__DEFINES\atmospherics_defines.dm" From 3d29323107516cbb1eaea5dba2977626246c6b83 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Fri, 26 Jan 2024 10:55:25 -0500 Subject: [PATCH 21/26] protect syndie depot interior from radstorms (#23937) --- code/datums/weather/weather_types/radiation_storm.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index 3288038d4f1c..ccb43e11a816 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -27,6 +27,7 @@ /area/station/security/brig, /area/shuttle, /area/survivalpod, //although survivalpods are off-station, creating one on station no longer protects pods on station from the rad storm + /area/syndicate_depot/core, // exterior of depot still dangerous, gotta be inside /area/ruin, //Let us not completely kill space explorers. /area/station/command/server ) From 17a68e9242b52f8cfadc3047df1236b718d449f7 Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Fri, 26 Jan 2024 19:12:20 +0000 Subject: [PATCH 22/26] Revert "[FIX] Jobbaned Roles at poll_candidates" (#23927) --- code/game/gamemodes/miniantags/revenant/revenant.dm | 2 +- code/game/objects/items/weapons/dice.dm | 2 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/verbs/deathsquad.dm | 2 +- code/modules/admin/verbs/gimmick_team.dm | 2 +- code/modules/admin/verbs/one_click_antag.dm | 2 +- code/modules/events/spider_terror.dm | 2 +- code/modules/mob/mob_misc_procs.dm | 2 +- code/modules/response_team/ert.dm | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 51ce73175378..a5f4d6827967 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -160,7 +160,7 @@ giveObjectivesandGoals() giveSpells() else - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant?", ROLE_REVENANT, poll_time = 15 SECONDS, source = /mob/living/simple_animal/revenant) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a revenant?", poll_time = 15 SECONDS, source = /mob/living/simple_animal/revenant) var/mob/dead/observer/theghost = null if(candidates.len) theghost = pick(candidates) diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 4264a6708f45..998dd526021b 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -293,7 +293,7 @@ servant_mind.transfer_to(H) - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", ROLE_GHOST, poll_time = 30 SECONDS, source = H) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the servant of [user.real_name]?", poll_time = 30 SECONDS, source = H) if(length(candidates) && !QDELETED(H)) var/mob/dead/observer/C = pick(candidates) message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d4e15ff5b731..83188ee73446 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1995,7 +1995,7 @@ var/petchoice = input("Select pet type", "Pets") as null|anything in pets if(isnull(petchoice)) return - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Play as the special event pet [H]?", ROLE_SENTIENT, poll_time = 20 SECONDS, min_hours = 10, source = petchoice) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Play as the special event pet [H]?", poll_time = 20 SECONDS, min_hours = 10, source = petchoice) var/mob/dead/observer/theghost = null if(candidates.len) var/mob/living/simple_animal/pet/P = new petchoice(H.loc) diff --git a/code/modules/admin/verbs/deathsquad.dm b/code/modules/admin/verbs/deathsquad.dm index d5a635293f78..92b35362b752 100644 --- a/code/modules/admin/verbs/deathsquad.dm +++ b/code/modules/admin/verbs/deathsquad.dm @@ -73,7 +73,7 @@ GLOBAL_VAR_INIT(deathsquad_sent, FALSE) commando_ghosts = pollCandidatesWithVeto(src, usr, commando_number, "Join the DeathSquad?",, 21, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) else var/image/source = image('icons/obj/cardboard_cutout.dmi', "cutout_deathsquad") - commando_ghosts = SSghost_spawns.poll_candidates("Join the Deathsquad?", ROLE_DEATHSQUAD, GLOB.responseteam_age, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) + commando_ghosts = SSghost_spawns.poll_candidates("Join the Deathsquad?",, GLOB.responseteam_age, 60 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_DEATHSQUAD], TRUE, FALSE, source = source) if(length(commando_ghosts) > commando_number) commando_ghosts.Cut(commando_number + 1) //cuts the ghost candidates down to the amount requested if(!length(commando_ghosts)) diff --git a/code/modules/admin/verbs/gimmick_team.dm b/code/modules/admin/verbs/gimmick_team.dm index 667508713131..a3d853bffd24 100644 --- a/code/modules/admin/verbs/gimmick_team.dm +++ b/code/modules/admin/verbs/gimmick_team.dm @@ -53,7 +53,7 @@ players_to_spawn += candidate else to_chat(src, "Polling candidates...") - players_to_spawn = SSghost_spawns.poll_candidates("Do you want to play as \a [initial(O.name)]?", ROLE_GHOST) + players_to_spawn = SSghost_spawns.poll_candidates("Do you want to play as \a [initial(O.name)]?") if(!players_to_spawn.len) to_chat(src, "Nobody volunteered.") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 7c9ad54d969e..89ba5e45f27e 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -137,7 +137,7 @@ if(confirm != "Yes") return 0 var/image/I = new('icons/mob/simple_human.dmi', "wizard") - var/list/candidates = SSghost_spawns.poll_candidates("Do you wish to be considered for the position of a Wizard Federation 'diplomat'?", ROLE_WIZARD, source = I) + var/list/candidates = SSghost_spawns.poll_candidates("Do you wish to be considered for the position of a Wizard Federation 'diplomat'?", "wizard", source = I) log_admin("[key_name(owner)] tried making a Wizard with One-Click-Antag") message_admins("[key_name_admin(owner)] tried making a Wizard with One-Click-Antag") diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm index 1f513b32ed1c..51f71526d24a 100644 --- a/code/modules/events/spider_terror.dm +++ b/code/modules/events/spider_terror.dm @@ -47,7 +47,7 @@ // Strongest, only used during highpop. spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen spawncount = 1 - var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a terror spider?", ROLE_TSPIDER, TRUE, source = spider_type) + var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a terror spider?", null, TRUE, source = spider_type) if(length(candidates) < spawncount) message_admins("Warning: not enough players volunteered to be terrors. Could only spawn [length(candidates)] out of [spawncount]!") var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE) diff --git a/code/modules/mob/mob_misc_procs.dm b/code/modules/mob/mob_misc_procs.dm index 4fde7c26c32d..ffd0c1ca9c60 100644 --- a/code/modules/mob/mob_misc_procs.dm +++ b/code/modules/mob/mob_misc_procs.dm @@ -166,7 +166,7 @@ var/question = "Do you want to play as [M.real_name ? M.real_name : M.name][M.job ? " ([M.job])" : ""]" if(alert("Do you want to show the antag status?","Show antag status","Yes","No") == "Yes") question += ", [M.mind?.special_role ? M.mind?.special_role : "No special role"]" - var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("[question]?", ROLE_GHOST, poll_time = 10 SECONDS, min_hours = minhours, source = M) + var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("[question]?", poll_time = 10 SECONDS, min_hours = minhours, source = M) var/mob/dead/observer/theghost = null if(length(candidates)) diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index 636b57a115e6..33b4895a1e31 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(ert_request_messages) GLOB.active_team.cyborg_security_permitted = cyborg_security GLOB.send_emergency_team = TRUE - var/list/ert_candidates = shuffle(SSghost_spawns.poll_candidates("Join the Emergency Response Team?", ROLE_ERT, GLOB.responseteam_age, 45 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_ERT])) + var/list/ert_candidates = shuffle(SSghost_spawns.poll_candidates("Join the Emergency Response Team?",, GLOB.responseteam_age, 45 SECONDS, TRUE, GLOB.role_playtime_requirements[ROLE_ERT])) if(!length(ert_candidates)) GLOB.active_team.cannot_send_team() GLOB.send_emergency_team = FALSE From 010aec7f5049c6352435fdaa0beab2a747c992e6 Mon Sep 17 00:00:00 2001 From: dj-34 Date: Sat, 27 Jan 2024 00:23:20 +0500 Subject: [PATCH 23/26] Fix stacks dupe and ore duping with BS crystals (#23948) --- code/game/objects/items/stacks/stack.dm | 2 ++ code/modules/mining/machine_redemption.dm | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 11d45ad6448e..9a4586be8161 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -351,6 +351,8 @@ var/stackmaterial = round(input(user, "How many sheets do you wish to take out of this stack? (Maximum: [max])") as null|num) if(stackmaterial == null || stackmaterial <= min || stackmaterial > get_amount()) return + if(!Adjacent(user, 1)) + return change_stack(user,stackmaterial) to_chat(user, "You take [stackmaterial] sheets out of the stack.") diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 33ea40ed4126..746107d96a74 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -396,7 +396,11 @@ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) var/amount_compatible = materials.get_item_material_amount(O) if(amount_compatible) - materials.insert_item(O, sheet_per_ore) + // Prevents duping + if(O.refined_type) + materials.insert_item(O, sheet_per_ore) + else + materials.insert_item(O, 1) // Delete the stack ore_buffer -= O qdel(O) From 19433e8e1b59f06738d3b1a11986027d83cce430 Mon Sep 17 00:00:00 2001 From: dj-34 Date: Sat, 27 Jan 2024 00:35:09 +0500 Subject: [PATCH 24/26] [S] Fix hivelord core exploits & dupe with ore redemption (#23949) * Fix infinite hivelord cores exploit using lazarus * Fixed resource exploit for ore redemption --- code/modules/mining/machine_redemption.dm | 4 +++- .../mob/living/simple_animal/hostile/mining/hivelord.dm | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 746107d96a74..81faa38130b0 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -328,12 +328,14 @@ return FALSE var/stored = get_num_smeltable_alloy(D) var/desired = min(amount, stored, MAX_STACK_SIZE) + if(!desired) + return FALSE materials.use_amount(D.materials, desired) // Spawn the alloy var/result = new D.build_path(src) if(istype(result, /obj/item/stack/sheet)) var/obj/item/stack/sheet/mineral/A = result - A.amount = amount + A.amount = desired unload_mineral(A) else unload_mineral(result) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index ea3714913e5c..0c674ca45282 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -30,7 +30,7 @@ retreat_distance = 3 minimum_distance = 3 pass_flags = PASSTABLE - loot = list(/obj/item/organ/internal/regenerative_core) + butcher_results = list(/obj/item/organ/internal/regenerative_core = 1) var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood /mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target) @@ -172,6 +172,7 @@ throw_message = "bounces harmlessly off of" crusher_loot = /obj/item/crusher_trophy/legion_skull loot = list(/obj/item/organ/internal/regenerative_core/legion) + butcher_results = null brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion del_on_death = TRUE stat_attack = UNCONSCIOUS From f53e8fbae8ba6dfc4817dcdbbb9373ea5a0f3484 Mon Sep 17 00:00:00 2001 From: Aylong <69762909+Aylong220@users.noreply.github.com> Date: Sat, 27 Jan 2024 19:03:05 +0200 Subject: [PATCH 25/26] Fix: Chat Highlights - NoCrush Edition (#948) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Что этот PR делает Починка подсветки кириллицы, ноу вылет эдишн (наверное) ## Почему это хорошо для игры ## Изображения изменений ![image](https://github.com/ss220club/Paradise-SS220/assets/69762909/842808d8-6015-4654-aeab-8cb2f53f02e4) ## Тестирование Блять ## Changelog :cl: tweak: Добавлена подсветка слов в чате на кириллице /:cl: --- tgui/packages/tgui-panel/chat/renderer.js | 2 +- tgui/packages/tgui-panel/chat/replaceInTextNode.js | 2 +- tgui/public/tgui-panel.bundle.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tgui/packages/tgui-panel/chat/renderer.js b/tgui/packages/tgui-panel/chat/renderer.js index e18414f9cb08..37e6780657ad 100644 --- a/tgui/packages/tgui-panel/chat/renderer.js +++ b/tgui/packages/tgui-panel/chat/renderer.js @@ -190,7 +190,7 @@ class ChatRenderer { const highlightWholeMessage = setting.highlightWholeMessage; const matchWord = setting.matchWord; const matchCase = setting.matchCase; - const allowedRegex = /^[a-z0-9_\-$/^[\s\]\\]+$/gi; + const allowedRegex = /^[a-zа-яё0-9_\-$/^[\s\]\\]+$/gi; // SS220 EDIT - CYRILLIC SUPPORT const regexEscapeCharacters = /[!#$%^&*)(+=.<>{}[\]:;'"|~`_\-\\/]/g; const lines = String(text) .split(/[,|]/) diff --git a/tgui/packages/tgui-panel/chat/replaceInTextNode.js b/tgui/packages/tgui-panel/chat/replaceInTextNode.js index 753997b3b821..2242d84d43ec 100644 --- a/tgui/packages/tgui-panel/chat/replaceInTextNode.js +++ b/tgui/packages/tgui-panel/chat/replaceInTextNode.js @@ -93,7 +93,7 @@ export const replaceInTextNode = (regex, words, createNode) => (node) => { for (let word of words) { // Capture if the word is at the beginning, end, middle, // or by itself in a message - wordRegexStr += `^${word}\\W|\\W${word}\\W|\\W${word}$|^${word}$`; + wordRegexStr += `^${word}\\S\\w|\\S\\w${word}\\S\\w|\\S\\w${word}$|^${word}\\S\\w$`; // SS220 EDIT - CYRILLIC SUPPORT // Make sure the last character for the expression is NOT '|' if (++i !== words.length) { wordRegexStr += '|'; diff --git a/tgui/public/tgui-panel.bundle.js b/tgui/public/tgui-panel.bundle.js index cadf20f322ea..94e2f6271f81 100644 --- a/tgui/public/tgui-panel.bundle.js +++ b/tgui/public/tgui-panel.bundle.js @@ -134,11 +134,11 @@ * @file * @copyright 2020 Aleksej Komarov * @license MIT -*/var u=(0,o.createLogger)("chatRenderer"),v=24,s=function(S){for(var b=document.body,C=S;C&&C!==b;){if(C.scrollWidth=a.IMAGE_RETRY_LIMIT){u.error("failed to load an image after "+C+" attempts");return}var P=b.src;b.src=null,b.src=P+"#"+C,b.setAttribute("data-reload-n",C+1)},a.IMAGE_RETRY_DELAY)},E=function(S){var b=S.node,C=S.times;if(!(!b||!C)){var P=b.querySelector(".Chat__badge"),N=P||document.createElement("div");N.textContent=C,N.className=(0,r.classes)(["Chat__badge","Chat__badge--animate"]),requestAnimationFrame(function(){N.className="Chat__badge"}),P||b.appendChild(N)}},I=function(){function T(){var b=this;this.loaded=!1,this.rootNode=null,this.queue=[],this.messages=[],this.visibleMessages=[],this.page=null,this.events=new n.EventEmitter,this.scrollNode=null,this.scrollTracking=!0,this.handleScroll=function(C){var P=b.scrollNode,N=P.scrollHeight,w=P.scrollTop+P.offsetHeight,M=Math.abs(N-w)0&&(this.processBatch(this.queue),this.queue=[])}return b}(),S.assignStyle=function(){function b(C){C===void 0&&(C={});for(var P=0,N=Object.keys(C);P{}[\]:;'"|~`_\-\\/]/g,V=String(L).split(/[,|]/).map(function(it){return it.trim()}).filter(function(it){return it&&it.length>1&&D.test(it)&&((D.lastIndex=0)||!0)}),G,Y;if(V.length!==0){for(var z=[],et=c(V),at;!(at=et()).done;){var ft=at.value;if(ft.charAt(0)==="/"&&ft.charAt(ft.length-1)==="/"){var W=ft.substring(1,ft.length-1);if(/^(\[.*\]|\\.|.)$/.test(W))continue;z.push(W)}else G||(G=[]),ft=ft.replace(F,"\\$&"),G.push(ft)}var X=z.join("|"),nt="g"+($?"":"i");try{if(X)Y=new RegExp("("+X+")",nt);else{var ct=(U?"\\b":"")+"("+G.join("|")+")"+(U?"\\b":"");Y=new RegExp(ct,nt)}}catch(it){Y=null}N.highlightParsers||(N.highlightParsers=[]),N.highlightParsers.push({highlightWords:G,highlightRegex:Y,highlightColor:K,highlightWholeMessage:x})}})}return b}(),S.scrollToBottom=function(){function b(){this.scrollNode.scrollTop=this.scrollNode.scrollHeight}return b}(),S.changePage=function(){function b(C){if(!this.isReady()){this.page=C,this.tryFlushQueue();return}this.page=C,this.rootNode.textContent="",this.visibleMessages=[];for(var P=document.createDocumentFragment(),N,w=c(this.messages),M;!(M=w()).done;){var L=M.value;(0,i.canPageAcceptType)(C,L.type)&&(N=L.node,P.appendChild(N),this.visibleMessages.push(L))}N&&(this.rootNode.appendChild(P),N.scrollIntoView())}return b}(),S.getCombinableMessage=function(){function b(C){for(var P=Date.now(),N=this.visibleMessages.length,w=N-1,M=Math.max(0,N-a.COMBINE_MAX_MESSAGES),L=w;L>=M;L--){var K=this.visibleMessages[L],x=!K.type.startsWith(a.MESSAGE_TYPE_INTERNAL)&&(0,i.isSameMessage)(K,C)&&P0){this.visibleMessages=C.slice(P);for(var N=0;N0&&(this.messages=this.messages.slice(M),u.log("pruned "+M+" stored messages"))}}}return b}(),S.rebuildChat=function(){function b(){if(this.isReady()){for(var C=Math.max(0,this.messages.length-a.MAX_PERSISTED_MESSAGES),P=this.messages.slice(C),N=c(P),w;!(w=N()).done;){var M=w.value;M.node=void 0}this.rootNode.textContent="",this.messages=[],this.visibleMessages=[],this.processBatch(P,{notifyListeners:!1})}}return b}(),S.clearChat=function(){function b(){var C=this.visibleMessages;this.visibleMessages=[];for(var P=0;P\n\n\n
\n'+K+"
\n\n\n",F=new Blob([D]),V=new Date().toISOString().substring(0,19).replace(/[-:]/g,"").replace("T","-");window.navigator.msSaveBlob(F,"ss13-chatlog-"+V+".html")}}return b}(),T}();window.__chatRenderer__||(window.__chatRenderer__=new I);var O=e.chatRenderer=window.__chatRenderer__},97507:function(y,e){"use strict";e.__esModule=!0,e.replaceInTextNode=e.linkifyNode=e.highlightNode=void 0;function t(u,v){var s=typeof Symbol!="undefined"&&u[Symbol.iterator]||u["@@iterator"];if(s)return(s=s.call(u)).next.bind(s);if(Array.isArray(u)||(s=n(u))||v&&u&&typeof u.length=="number"){s&&(u=s);var p=0;return function(){return p>=u.length?{done:!0}:{done:!1,value:u[p++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(u,v){if(u){if(typeof u=="string")return r(u,v);var s=Object.prototype.toString.call(u).slice(8,-1);if(s==="Object"&&u.constructor&&(s=u.constructor.name),s==="Map"||s==="Set")return Array.from(u);if(s==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(s))return r(u,v)}}function r(u,v){(v==null||v>u.length)&&(v=u.length);for(var s=0,p=new Array(v);s=a.IMAGE_RETRY_LIMIT){u.error("failed to load an image after "+C+" attempts");return}var P=b.src;b.src=null,b.src=P+"#"+C,b.setAttribute("data-reload-n",C+1)},a.IMAGE_RETRY_DELAY)},E=function(S){var b=S.node,C=S.times;if(!(!b||!C)){var P=b.querySelector(".Chat__badge"),N=P||document.createElement("div");N.textContent=C,N.className=(0,r.classes)(["Chat__badge","Chat__badge--animate"]),requestAnimationFrame(function(){N.className="Chat__badge"}),P||b.appendChild(N)}},I=function(){function T(){var b=this;this.loaded=!1,this.rootNode=null,this.queue=[],this.messages=[],this.visibleMessages=[],this.page=null,this.events=new n.EventEmitter,this.scrollNode=null,this.scrollTracking=!0,this.handleScroll=function(C){var P=b.scrollNode,N=P.scrollHeight,w=P.scrollTop+P.offsetHeight,M=Math.abs(N-w)0&&(this.processBatch(this.queue),this.queue=[])}return b}(),S.assignStyle=function(){function b(C){C===void 0&&(C={});for(var P=0,N=Object.keys(C);P{}[\]:;'"|~`_\-\\/]/g,V=String(L).split(/[,|]/).map(function(it){return it.trim()}).filter(function(it){return it&&it.length>1&&D.test(it)&&((D.lastIndex=0)||!0)}),G,Y;if(V.length!==0){for(var z=[],et=c(V),at;!(at=et()).done;){var ft=at.value;if(ft.charAt(0)==="/"&&ft.charAt(ft.length-1)==="/"){var W=ft.substring(1,ft.length-1);if(/^(\[.*\]|\\.|.)$/.test(W))continue;z.push(W)}else G||(G=[]),ft=ft.replace(F,"\\$&"),G.push(ft)}var X=z.join("|"),nt="g"+($?"":"i");try{if(X)Y=new RegExp("("+X+")",nt);else{var ct=(U?"\\b":"")+"("+G.join("|")+")"+(U?"\\b":"");Y=new RegExp(ct,nt)}}catch(it){Y=null}N.highlightParsers||(N.highlightParsers=[]),N.highlightParsers.push({highlightWords:G,highlightRegex:Y,highlightColor:K,highlightWholeMessage:x})}})}return b}(),S.scrollToBottom=function(){function b(){this.scrollNode.scrollTop=this.scrollNode.scrollHeight}return b}(),S.changePage=function(){function b(C){if(!this.isReady()){this.page=C,this.tryFlushQueue();return}this.page=C,this.rootNode.textContent="",this.visibleMessages=[];for(var P=document.createDocumentFragment(),N,w=c(this.messages),M;!(M=w()).done;){var L=M.value;(0,i.canPageAcceptType)(C,L.type)&&(N=L.node,P.appendChild(N),this.visibleMessages.push(L))}N&&(this.rootNode.appendChild(P),N.scrollIntoView())}return b}(),S.getCombinableMessage=function(){function b(C){for(var P=Date.now(),N=this.visibleMessages.length,w=N-1,M=Math.max(0,N-a.COMBINE_MAX_MESSAGES),L=w;L>=M;L--){var K=this.visibleMessages[L],x=!K.type.startsWith(a.MESSAGE_TYPE_INTERNAL)&&(0,i.isSameMessage)(K,C)&&P0){this.visibleMessages=C.slice(P);for(var N=0;N0&&(this.messages=this.messages.slice(M),u.log("pruned "+M+" stored messages"))}}}return b}(),S.rebuildChat=function(){function b(){if(this.isReady()){for(var C=Math.max(0,this.messages.length-a.MAX_PERSISTED_MESSAGES),P=this.messages.slice(C),N=c(P),w;!(w=N()).done;){var M=w.value;M.node=void 0}this.rootNode.textContent="",this.messages=[],this.visibleMessages=[],this.processBatch(P,{notifyListeners:!1})}}return b}(),S.clearChat=function(){function b(){var C=this.visibleMessages;this.visibleMessages=[];for(var P=0;P\n\n\n
\n'+K+"
\n\n\n",F=new Blob([D]),V=new Date().toISOString().substring(0,19).replace(/[-:]/g,"").replace("T","-");window.navigator.msSaveBlob(F,"ss13-chatlog-"+V+".html")}}return b}(),T}();window.__chatRenderer__||(window.__chatRenderer__=new I);var O=e.chatRenderer=window.__chatRenderer__},97507:function(y,e){"use strict";e.__esModule=!0,e.replaceInTextNode=e.linkifyNode=e.highlightNode=void 0;function t(u,v){var s=typeof Symbol!="undefined"&&u[Symbol.iterator]||u["@@iterator"];if(s)return(s=s.call(u)).next.bind(s);if(Array.isArray(u)||(s=n(u))||v&&u&&typeof u.length=="number"){s&&(u=s);var p=0;return function(){return p>=u.length?{done:!0}:{done:!1,value:u[p++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(u,v){if(u){if(typeof u=="string")return r(u,v);var s=Object.prototype.toString.call(u).slice(8,-1);if(s==="Object"&&u.constructor&&(s=u.constructor.name),s==="Map"||s==="Set")return Array.from(u);if(s==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(s))return r(u,v)}}function r(u,v){(v==null||v>u.length)&&(v=u.length);for(var s=0,p=new Array(v);s9999)return{};b||(b=document.createDocumentFragment()),I||(I=[]);var N=g?g(T[0]):T[0],w=N.length,M=T.index+T[0].indexOf(N);S9999)return{};b||(b=document.createDocumentFragment()),I||(I=[]);var N=g?g(T[0]):T[0],w=N.length,M=T.index+T[0].indexOf(N);S Date: Sun, 28 Jan 2024 14:26:59 +0200 Subject: [PATCH 26/26] =?UTF-8?q?Add:=20=D0=A0=D0=B5=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B9=D1=82=20=D0=BD=D0=B0=D0=BF=D0=B8=D1=82=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D1=81=20=D1=80=D1=83=D0=BF=D0=B0=D1=80=D1=8B=20?= =?UTF-8?q?(#956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Что этот PR делает Заменяет старые спрайты напитков добавленных с рупары https://github.com/ss220club/Paradise-SS220/pull/898 на новые красивые спрайты Спрайты сделаны такими хорошими людьми как: Ingakem, Derk и Вано ## Почему это хорошо для игры Новые красивые спрайтики ## Изображения изменений ![Screenshot_121](https://github.com/ss220club/Paradise-SS220/assets/146962612/d67fceb0-0637-4932-a254-3ae682fb796f) ## Тестирование Проверено на локальном сервере ## Changelog :cl: imageadd: Респрайты портированных недавно с рупары напитков /:cl: --- modular_ss220/food/icons/drinks.dmi | Bin 19621 -> 21642 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modular_ss220/food/icons/drinks.dmi b/modular_ss220/food/icons/drinks.dmi index 1602b05e812cac0a7dfa174df865efd8531779fa..b9a162df1e1b2549eb5449e5debb7fd625c973a1 100644 GIT binary patch literal 21642 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ℜ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 literal 19621 zcmaI8byOVD(c_=BT|iiVSz zv7?cLxt)`_tqlO+mXVmyD^JUeB)-V1kKT*TFDx83Zly>&2mL0p_vIqWeCYG?=N#Y3 zJVdt+>`7&gaHk)e>6ZI5{5Dxlj5eSS>rKT3g!YMbP^(S4tF*ISX1i|VxZfP=z1tK5 zmhK?~<`B~*X@VB3UV|K&(qe0R(=vRN+uBFLD^eMy>=*@^dMwLw;^>$;K%Vj$f&Xt< z0hV#@*`<1tIjZ{*7or&TM?V8Siv6W1!=MX(3B#j%P;z)mO}6)#Ba_rfZPW<-poF9Z zMGfRv$lKllX?fl$e}r^1@$sAi5NWp5S+4ab6RwttbsbP+7k>_*I53vQvQbxMY$@3* zt^LEo)w66~QEZxZsB`%cc_@5>AHR=m zfQ$eU{oih=JS=&-LutdLI0nZg@Bg=+a`^%8PO7?n+`9`wSmew_^@Q%VwXA zrtD7VN~!P8O`iY&5`dJLu!>v8S*E)i#{9;xV0-~$!&Fjb0|^|arYajX33a+oFXF|K zZi46hW08YC)}kerB0AKX;y^iv9%oWH*-k+9AT(6&j79!POakF|X_?$Y&$NukSf`l= zxz#V@Ulb<}-Cx*P9a%Qx|BP{VZ>F*y`iYVK%7_*dmkg6X{~>m1b1q(TO7`p9gaFdG zyQ7;M*E7{9m+E({l9z82pBB8I3ror>22AP=>z7+D9##_-7o{8?rYqtPI>NZ@vvPlT zw0wFXFyH8!_yIM}7h_6(-MI@5Vdp1g=e2q5c!B#ZO`%>sP33S9R_KP?4PDJq9&ZY^ zT91Ur8bUj6Q94~KkI#zU2dW`X0Yi@RW*>wBGBzA<3BIJLy1m~geEIjh5 z_TQKx(OpS~`PIe-i)wEfGo)tDzor$Cna@{LcSP?XeK@k-uli9nFGhzIFzxI%^#DXZ zPusokXSY@)6!iTb<2^*;QpE$d}g~N*LJ8Q5umBk zW$$Mw9;bH+neaeEq2^VRO^=yglG)~q7&Jtdqo$zGUx+0xA5zBi zrGQ-SX|lKlj?g2h{roZQbg58iT_+&0fSYYU@?uFoSOFlW(_Qh_eV~Hv-i$ZOWH;34 z@r6^KVX4@KeK6b7an;UFGQ3|1dXv^uy;ah8btvEE$YBNySE9!Afd^|_`h=rQvQe[ zLWhu+$DA$GWve8ZPD@pk){lQMS=x3MPjiHH3 zH$N1}(ChPq&T}NCN=L}bY_K(f?iO;@l1$m$V|+bM6)hu@Dd#E{>g#_0)-u5~Bhsy1 zco`;z6u3Pdr(IalZ!wM%=ut&5kInuSTaANwdAYdtU|xZvl^RF?DQNxq+PO#Wu?P(V zL)6}$+1S|F%R&#}H-litq--Y8k3lZS+P$plIH;gyy$m;1?%}=%LR#ZpF409UGbW3z z>FS_0AiW-OHCujiB|9Y9g}Jwo?R)8+DO`_UT(d*lIx3w_dwVLQ#3bHKmGQhIr{DDi z?CkPF#-)2A`Qay1m%MA zPUgN1UR3gS^gXj`@fYg&?TS|qDr8%UFL7))!|P*#sIh=i)zS7T1O9%n_RtrBwjY)E z+vuS1*jQK+etvK6p5xhK@{=Te?N9cd*vHAzVktl?t@BQEq9ZekCYffBQw2i)0rVZV z+4<9q>B-J|oU5GO&l?sW5b65ve$udaoa5WV%<+E~L8T1RJTVhz}a=ugS6r4|(bMPNhM49Zm*MBd}9_6)XtTo<-M7qQq zoL|pdGS8ZbYC^rTUsAs#^kLtJUJ(~Wp4NIbAt4~t?$$hCfq zuL^CduUrKjar87+T@FuN9IaBK=A7o9rwP@~2GxH}wc`u24Fem3zR=dpuB^=!F*zp38XN?~>|J2G$V zYUa6bt^Yx&i)w9}17ZV z|JZlx z!)(z(ZOhKRXUY{Z74=R<%zfY*Q9uh#(XWcIo@%;(>3t0115Pqg=bT>BZjU*%&( zToe2Blx1cvB5u6j5FTaMDUg1>?1w_cKO~CEFGdr`??P7!m>;F^uhNBVIn3^5Bc6Zr zu->$Z3JdEwu!~F2R`~hzOSVdbO}oMGCTC68D>QYzrC9!UmzpA`_Jt-vRKh=PfuU@( z*naZGqRIQR9DQ~Nmk5e6_4xAeXxP|AnuLIf$Qb8)AcES-{)FqK+(9Vug&jR2>CtL4 zW4p`wPWz#U!@bdK%fLge$qQ=L+r|oGZazEjr5Kq|cTmg%th$e__jA#-sWIlBdd=H$ zarXBvJJQw5?rd^a)4Y#KUoI9$N-718HOaz4rhi+HA1BrV--KzZ-ctSV-%ZBJ z%4oR1@K?e^9w=BLo;ua+5qV6{zpH*$>-@=vMcyfCOTT@9%Nsi;;gpR#AggccybX$xm!K6Mf-F0mPQaQxHDq#oLbwp0eWYwEAG@2A4 z*{SvD1fzPhWdK^v;_327ccO}l3Q5q`^I^6mTrX{PN1yYe?r^POLO#w)VeTyz5~0qe zCKIYL1cQ}5-lXf~{lJgb(3_bLNP`t`btR|2=5K<=6^A#uj%E2dv8@9S%y?^PyZh-9 zR01tGo|Y-SpLx&5{>boY=M$SrC>*8RI6S=CC-8U*9AVPg*|q{gxe!@|U8me_ z8{f+^kLBePO5=*3iO+q$^Fw1Vh*TE*biKJ;)#;?Sx+WZFGu6FI=dF5RW|MObfuNGm zqYX|wk%VgKo*gmHH^epkY#@Qi5rP8tX+!`4aQ^(7009Gm!=vy8C0W#N)w)^f`*)Fw zKLfwWC7&G2)iU_pf6H~-4yqaRLJmnH(V?sgz?EMd#;1HcoJgMO_VtY+LJ?j+So$TJ$7kd^CsQP(`b9>asDpmMFk;9 zAgL?jom&j{ExV()zz7F&-iBz#Nk)j3CMS%UuLiXmZmv@@YxW*^2|QZ~5XLA=mwphi zzI@yfHw*h*1i4j}96F#SfiBM~s@7IVF0ccoW?-NsBMS%%g9ED*9-FP?O}o)Yfp^sH zHG4E5DX6V}X`jvC`b=sLi!ktfaT`02D)<&xD8YX*9sBZfnC)vbolh2UsI;wB_Y8|qb9IYp@C;#Pl? ze{t4`JNbF(0eE$qq^&*1JcW>rIu)THXnDmj(8@%2+WL1NM+{LL3zLx11x11~N17}2 zSW%J+LrBbujR*SSpn(7qf(fr)Y@9^Q88*nyMk!jdxsVFG0Y9&iV%rg6q12lK?coL~ zivPK{8nrFwPQ{pFRa(Y9W_^4)Q6VF8@`uzHn#CxBuMrUlsqqhipSKKzNwfKXu-sqF zi=HjFe^kuaCMgT77c2ZR4-EwV`nA^RT<#J-;Q5cr@%R|TQmNUl3UVeKNPU*wu~KjFb+W8|{sE((BHEZe&} z3(M*<{{EG2%UH6_@Z99T0scfzd`1&$U7yH`XpJ|2dK9gCv=}euVw2YHMf*g}odLu}+WZsLGK!!zE|InP#d)=1ZTV9R2pHew4 zmpJH#h8^$2xkaJfYd;y3g>2zAP^YqRO^r-1MV<+aWO6iNRA`_$NZ+yzHc(Y=pG^kf z7NLD#+Y#9~bN?|`$w&Dbh$t<`u4%IX({Uq=g=l_*<)?lR2_5zs)rGjGKX@g7cEIlj z6}2~@`yDz7gi}V882YntcOh^B{;v?e(*y~PF^dJs+wp#`FflT`7v<$~x7OF3{zy5~M7wF@f+G1N z%z{vH9qc4|$a9Q8_8Af1`=%#j>wf0w1 z`HUQ{L%62NMeXcvp8^v~Ht#_^UN-J!@wfWsC}fZHpw~fEyQ36rM+delTd($^I~3i6 z%r1SHhP$0enWp4qj9hA`spA?oH3uIts7Yj8#hayv^R%=$9`3DVj?)H@D}Z{O_0ha!?UKTv#TFZaZf3a_h8^ z%CRf!%~k_}+IlJVy0+BE{JiedEsnnNdF+W*s^dIhHgpvwZM8Y3prj*X)_5Ni8%s&W zE`w}(=q9!}d)(vn_!!7a%6zVo1ualfNV81s@~94tgqk>6u@OUwiENE~ zxhY1EX8>xP(qUvxrT@*~w;OF9U+{dp9!_+>JqV|eNxJfpmhKx}taxGU5f~IP_5t1U zb_6EoO%qCTYA-?Zbow*C=$K_dz7>)!aGe;S2SdC3y`^3LHG{Z6PTeM#A(pIO46F0{ z&@_SX53i2TeSJywDG#G_M=A3|4QN^5kJo5Mx5*-&N=S%yti|fX+^yPn*Sg=D zWV!9YM?^-t-_NVNgLkX>I#10xaTc67`Q1O#CAIp~+pSLS)OblbI?c2!mkny<8?R6>ud=7kXbA4dJK>9q!G4Es}fT^T-JyFW%jkDHU5 z?+={5F3t}I)nO~~8(1Bh@W;I`qQ z7kc5J;A~j0I!GRLF|kp5)|fQ6%76gnsmLZXXex)BRHB`kC3s$Uk)Y*Ua#Y6J(Z+l4 zE++mJXHu&u2X`dJ-tsAFb%Xc$?#b|c!S};^X=FMd@?fY~dQ`W19X|sr)L8eqNf1$lra(W)h|_d`s!aAzb{fahwsGoe=U~~{%~Et2?t+AF(*!(msEHN zzxcG|9fFR+L%0Nu4sF2rmlT0o&?lqv*={+JP^eh4T&gz+t;CbzoB&1W)F=_KH{4X@ zE$pp~z_uL{M&s?ykgC8}F$+|()(+2Qtp0f!QW)WI1NBnEr6no00(A1|q$Iy>U(qRp z9pL0J6JD_>Ry%Fej`hTIsVhJ9o*QI@1e>AJ#agS5*Y)678hhk&y(uerx>=qV-2b*- z8NBZ6ZSz85a`fz)mkPlVfz32W-Wg^hG)3cz7lEPmP2Olcn zC2HFqoqEMVl0mnkH(!vpJq*!M5E7W~3`1!AXsg?3w&ZnA)m}+vMVJ(1)aVTq<7TQY zDu0g6t|iYWm%-n^Y4x`ofGHmZ^wM>5Hxu#Hc*Y-soEpVfIvsKLTmu2vhr0si=?X1n z2jU#KLrk`+cDECZFp2 z(zBYaY1GPTp(`^=b&C)JSsW6l!ElfRM6n#_B7nKlcsZTrfbTmRH zF=&A63=4~k0L;;7YgP&Gv(^zY?`;~5w2mUAVay9x0D-cImg^vq%J|tJd7txjn>Uu6 z!AP8X<56sIZa~_~iY}Aam6Deie|R;Y#^d4LBlQKkBQov_x8Ss=}w98=|Ix$ z2wn;7WqnBfs4$KfN*<@=xe`p_|EA$UQ2LFZLZbP^yc;!9u@U)sn!Uv=JR@9q1U;R zy`I?#XR#hIpSH8kllRIMcCl-)=~@iX0R^0-!~x;VQl@qXe0&fsCkc&i=r?uRlOsP? zfBi5bQtc+*+mc*AzVBhYd+H}X`nW!I`|SN1B(L=CWEH+|l$&vF8BQ+a)|b(*E0ayJ zQckmQTu()>aKJSjB{nupsF)Q_oY8J+R4hxL*yYCH^Pq9BHxqBl+=&@33D^cYFoO3E zvvX>$FsXU|;p-qje47@3XhdwNDi>3(i0`vF;xc8*G_*z~$NM_#r@hj(#dW~qhK7`g zQ;&eb<*}Pp{hP98F5C7~Ey+NL^HtX=k*wuKyCdO2v9(pn&Ss7Y{nol&j zEUr<`@uex6l!GG%5*8I>nI@p7h6(H}aK4&EmGo13>mZOzZqIl>griHSMXVkb@w zh^VHP#q!hpY7#oK zj3(=q8ICe`)D4GDwrr9dJbx-edPXiBblFt8=mi~8=`YC*mpjZ>+ z=izdGa1z&WIg*?6`1SY8cfo`gq8iA<3%-4yt;d0&|C57e!hP323H|MrO+n-f6>njsQ=uy37H$=GhqRFLkrPnviD6%MP($Tfp`o6i-_=ih8|z)T21t0 zas%XFnLB5z@{byB+K;}_%S_Bq5+it{W<-`IQ{~?-zj@JkjgS0-*s`tev~|(9F>0=YF2S} zC9ii6rVRgr%jI87eg%<{TVZdp_%=b=l=D|3AU z`-MtMHsx}i2Ms)cbOXo2#aCU&E_J%(t}M0D>l7dXFRvHT1! z^o0bUID_KnD@-0zX=yXD2SyxjE?4p+1;&X%ojEd`Ay@9^hMW8|Z!u)5b zRn=@waKdPt`^DFN+wp((0^Fz&+lChKrQ0LNp&YOd2KBgSLA}6^#6VbczIV}X$5}eP zfj(v@%@i@)Ive}*f@qfrQ-_2s+VayT|CJi$M0rj++-BSQTTSjiPOMWYm6J%OD1WjU z7sj;L{=I*uGqKap5;QECHv7x+Y9S&ZDP%*Xn~&a;YqTOaU2sxX?eCG>iv0qvyxCyx z>A`GG8K=oBL9=D}_%{u2;x|m$n!VsWUWYZ#Fpk*EbKj3T^GAg=c@RMKIq}G^5`?ug zFom4v?!Y*j3yJeH@iEV^-KJ+UU`T@#hZP%5n%dv-^hTJntkM9ndiI=rl1e z*RCTd1{5Hsk*y^PNF*0%Cq_t(`yn&TAL{M_7X znt1uuH-XHh0~S((gcYc5o-jm=1eE|`R6`GFrxjV5_21W{esq5h%r(|l`^IMJZ0E+X zkbBz!vMR%Gb2j8~5(qnd5NT_6R~4?V=WLq2p^c|pf<{yr47QFjLl;!@5=qxMnbsbvIK_2+Ugm;u9umW39mH!2vzYa6b1j8+j~c1X&sXs z^^K!mH{s)_(=mh zXQ43^^ALX|q9}8;4Q%_%z5O_>hD%P0zz)M3Voae?;~R0{G}NxmSdaoTc1_O9WHYwt z*7ur@41%cW3yj*Jh=&wLd9yRhliWGS z7jWa?u$33m4BKw{ey^@GLrO_AQ&(`D2P_27wnqf4&o|d9R;?%vI|-s)k&06pDlxMm zYqzU6q$Cdrvui|^=3RYVU3E+jb}n?dprc<2JUHD+=M2cl?RufqFW=$kcZE0K+i1I; z%hiO_e=YK9FsIl3)0?eTcBpc4yahk=1Ca-X8TN)5sW|s1I2JI^E~Q*FXXDXzrJ=IT z`mMn)NNHRKIa&t7TadfyvLgM4pKE`br#M@1HZuBJfdH`C$-)pz8A>fJm7 zi2_MmL;;f;kWCCt+~E?$xY4FCIu;ga8{aQumDu= zUUj|xe^7L=IO)xWh*^9mklZ%mR6pK`US42q(!QGNguEDyx04u65lXx(7U_7+>2cegwH6a zx&Hl!>{MPpbXq4O(5TTEgY4u7Nug|Ii9D;K;pzXs(#8Lc5yc#u$nf02H@u0(SanK-e9#!FZu&}e8MYeBg_(J*#ug$8BMQN&C6 zCL6K-{B-#fk(`yh8J0xsh9&mv+d88s^QjW?Xr)?dad;H-Wr$2C9ZyLXUI4y2uW08t za8n#WVa>(pdM#EUTCG`?Uf;<3dZ9Kgt;dMAt69FI#PpY_pXeN$KO7K?*vHcQSz(uL zzWb)qdgv=CUz8J8o}BNh2a=3|p=zNHoAPethJ67Z(o+Q}4p>Avdp#xh@p;t4SET9N zO{w`q9c?ok@DEd@Zk{=1Lj8k(^Q#Z|^B-wp9-7G(1OGtSJg&O!sx8uh!FFkitPsom zY#gPLyy_yA5sEaAnHk35)KZB6>kNxym79UfDkGx(dXW z9o%0Uni31F+*W~}sjT~SUY3VvXPgyNBF(NLge#XD`l>}5RlzEVt-1zc(_Bgflcli;I9j;rWM>J4U^Xkg1`4mYLCv74I!X=xT*-D(KX>_hQ3p7K zRYq`4^^kQNCip^Lr$E4Q1@A{?(|*0tO6>iD*K=b1dT2pkv3Sh&)~gNg6569j2;@dn zS%%)vuSR|I8Y609BCT7vIb21IDq#(_93dZF)SyDa*MPd>_)=1>D)4Hr+IQ?j?$E$S zoQOje`$yMz?+N4IO03?#qt3n$XM>(H11K=Y%2^R<_*yEFc z7;o#I{Z=W;KZw|iw=byrL#vJZ2@EE*-sJk{?kpaNUp`CfCaRteNGlNY;_3tjrgI|c z$M5T0vULFogU$OJ8g2GLoC6lOQgVZ0EC+MWkf!C+a}zG^sUYx_i<6eY)wQyS8w|j! zHu=sa^bxS68YAn2McC3?T&ZN~0pGaLSVbja8!h0b&f%|g#4+28N98_{%b{awsWF}v z`PIwQ|M~@ZPG?()!+zgnVg$B_Lc$-O#dNxb?Yz$76F2ktFAXu_j;U4K5mMYC97^CK z`KPHWWNMzZIKW=i37#MhVhv0lBC?P7qX7OCW2rGO@SVHWF*G#Eno)Iev-xTGyXA53 zLTsTm%{&isn}bAxq@$t|<4XX^8;$z{v35DLgAZ#I7q|xbop5_Dvgo3&JMJXwy-ibYg2 zoH@q|XR)Q@wY%yc7wP=fVJ9586isqLT+VF}2LF0e8?C%x4rBc|Pdj=q;mqb#H7|aN zJ6k9oXen7k49&rlv8UF5#HhRsF;CzKcRinHZMa7itu;TwX;p3|*O)PMw$_h&`7D1% z##0D}^g|0$c08TDu*<2g3k2xa5Wv;!ss1>_C1T^p(sq}Uy-{YR)|xFv71|pC1z{zT zVhUfo9*Vxb=M?1n_gO+((A+CAPHmGfaA*wauf0A)iE7JLAGB9nZLPV)x};$oyODja z=VtFTaYrETg*xix1>j2{caQH?h&D2t$K81JGxFxAGhmWH`F+2Qq&Q@RKAia+iloC${+EryJ4y*; zY4c*NmarFaElT%zVl)PZhD&!Ix%Oaij#Sn47J}+3!4K}WA@!DylIrB;G}y(>??#>i zdqT}b)ncepO-+gTk-wibHQ|1-dp)Jmp=pxTfeXWRCjwRWRSxFeJ2~du1Q4VI)I5X; zTQ#eh$jS&u0hqwfM4y}m{gte@9C4usg!Wmlw%#gYj$cdTt$OTv^~l|;e*YaOE_|Rs z%s&``^=vaw;d~i4{x9eo{ZPh%&ub;f*RWeC;dz?btR*dTLy$rR^`V5szMhfiRbc*d zh}`Yv5G7;l!Xcu+Ql0VvBRoq=uyl?B1#yT}H~|M2kQ@+SitUhx$(`hS*8Ffnf{lTGU!s()KEF?xO~{q)3=pPy|~A)MC%2Qs+gr`w!gI zLp)%f_*(!*n_cX^EuT{x^0|3JgLB`ep5+?$GDbFqt? zZOh0+B&b^8j>!h@^AZD>;T0GN;;z<<6&p}j9-PupdtwP$9Ru#UWOJ^*LP$$U$%_~0 zf!DjiP+qDLUZoibEYKoZ4*M_I3%{~AxDPo5z@8}{Xj$tuWB$?m89sVege~Yyp}kz~ zRokL0xEJ@cz>mt)C2)5Q%svNS&jT!v?SfW5DFKRb;&_N2+*zV3*O^NYpi@|(g_KJH zJGhKEE~4ZU!z{e7r0+TI9HsA8Yrnzu<{phWFzQ1I#ixR~P z%j6HIR#a62W1%*dzuQuaeBw@kb4ot0*G#+7k4` zkUM5=;J3!OY^wpYj*ODXfcV$$yW;S_{lq@UwWHfIzG=7#tBT-FBKNkLcv?Xy^S7jK zb^6q~qw-p`#2H>yki^edu!HbPLmG?c5;1w;zce#>MmiMz&{01Tm zQE$xtbT(Fv>B-at7no5qyxmRCXar4d$&y!KqDvEJ4TW3u6?lk5(?zYImzB+bp|LS& zV_eRjQs>S>^sa?XHd-=6*c0tOgDL^!H;37fYu#G{+4JFbSGi=*mRxs(P^H@<=EZ)F z(k)B9*ZtF!CQCxRLZ&8R3&1Gt3#6GTs-ybN7JZMA*=K!-6{MdlaK#xwat3l|ggfRSy8fUogO znUzDsy^phjik|xAZ?sIyd{YJ%w_w|XwagO?g_XMEoo_pHrtj*(b!YlJE&MANI(CMA z-e&8qWtL!LST@T1(I%4>aUzA_bE9B3(m&02YRLVK`!~m=r1CFn;<&ZD+~~H;ITtLk zy{RKaRK##GLXoX%WLJ_pwf;b&xifS5)Z1U@$^TR%_D@klbBB78S2m|2ye**#h$L=F zvt?=KTFgXE0JyJ=s@EbD2H$m^>Twi-_L>B^U^Mi+SMGfbxU~g&RBbyK8tTufemgM8 zFN+?$z5>5N+*rK^<_U&*ze#_7;C-xjY`m4+vM}I$)xd)C-YqrbSlJr=Gd!}PfzU&} zC8p7!zv(xLKJ|*znZRl^d%rOLvGnP@>;1X48T*kK^hLjuc_G%qEi})sUvK0phyyuE zYPC%F;eJDBfHrbFGua=}zmk2m3TgvC@aYv}C7R{AZ$8X;wdc*0#2%5k(xNFEk}Q^l z2qe!7S|&s%#@W9XfoMS4L^>q4vu-Cy(G5sREzT7n9F%{wn=O@P z@^Xtyzp<}9wx(eITrCt0M9C)xe?xTWIew>qP`$&x>RDkRkUXSr=(w8n^HhfSordUV zs>us$ze$*@wL)Fk^WEuBBdTR~eCur_gmhAq)q|&k%Xr|RKzw;Yfw<-&(wi+=dei*M zg700tb)&qmkZ^IV;bOHun~unFMe0kfjUpb(vQ(UI$ZheYce}}7d7c>HI{KDH2FBGx zbv+0zO~UXOPM}RX>(1z&>koMxyu!%iDmQBGe`}U-NO9ydiZmZo|e{p=Nj(Ma`em7tUnQf=<<8x8j4`67! zXq9?Do7Bb>3Y)F)yd*v2;YT;LU%KbGdtjomq5{Ib?y^`99Fl%7f+X%eM^2P-NZP&b zkp$AJlV$nfja{I1?T zyZToziyE7T3GU-H1j;ovv0LS3Jy1Lp|C7YQM8~4{`bhgL;L0kOw09Bo9N_VIdgKp5 zMt*mM1f8=8ZhHWd{4J|lW=|t!GokdF8;*2n_g@AkXM5wWq>>hfI|PS9G9U{j<8P@l z+Hg46LPSDVgZals*LXrjl# ztDXF;9{4o^;xr>(m`|By6z=NhoH90GexZ4 z2a(l4D7RrOq-NQiSW%cW#@YTrPcDhprY(y2O-lgnXv(Sg#>+rEe$dPK!7%Ll#|#!d zG8*GuBb$(ihmyP~W;N;rOBp4U{4KZ3nTA7-+|i(* zUapGIL*O^iGgG_=)hF!jims}^C`ZTLW`y7fIA4TrBTnRI4`HX1FA)~x3&e3#x^Oj+ z?%6K{k|8TXLf(N}?iqa}O+Q(T!RB~AUhp~EB{7>mYj<5tmPv)D96yL(RWVQ^8oJ{?0+xw zS6rN5I}k{~=N6ZdK>z@^At${pn`Wolwrs;FA5LT{Lw<%{|5!%d84Smnrft&gwDtu( zNuHCDkZ_;S|59`?3|w{0Yx=EqgF1c(TdyI;`3V~9mRD1Dx{6rjV>v)RTK1dwoAwg3 zGB0Q_5*ml?6ZHE#uk7^Itsti&Q{69WJ8uELCOKA+3^v)15Vnp^CJdjak9e-G3apT%PD)^WQ`(0X zYt2u{WP4IkN@P+;RZwGDwj_Dgr3j@achM}G}#$7)kJu%=o z`-NAMhSYGwvkLQUoO4sf2E0BPLOHXHev(~pN*(UEs*MY!CQg^8`0R4MJfO#${LL1JPG=0Mq{S{pIk-*y-BvkMVna=|Hd-RSmfg4!gPn zsoQ19=@f(Bj*ts`wTioGz{01fdpyGLtbQZkW|+8f9hPLPdD~t>$XU7CKwQYrg5`ea z!ypB8mOtGpg-Hh z>6$^QEck&G^6WSJ6MOOF?Y*h<`K?IXrnPX|UXaJ>C@1{7#c{LvRQxn7%%k7Ij1ctg z%kQ3@S?JY-=aLGIS`j?||5v5@zg?5+|3X0#UQkdFC-fQHY1NYmJ`ckN_v$F$U3@yJjAo1=T0J_Vc(I2g9&$VAOUo3a(Yl zeCgVHR16>%xRR_(W-yiyjrXsJRd~@&HmR=-#HmlTDCl-F=fDsx_4VYys23^OWKR!g z43W^EVYzbuw!p3LHJ;&1_v4lk3|){tJc$WjzUE+AD*C>TkEJ$ckK;cs9uaq7H66l= z3%;ljQ^xo)axTaUx1SqOb`OQaoO*aVDOvr)gHg((v3C+;1DvA!r;C%4NT*TS=N)`VA^NuUJA%>2FvC-p+$Oe===d~7zZQMqJX<#^UzYvK&0O?jj>2HE(YCuGrw(aT=s>h3)M@&!b+X2`}Iu zBv>tD5VCj+IeKR!nW4QtC9+ge;&bqj6T7<9$Epgb&EUXX9!)SHA?d-A;HsLoAKZ#q zU%(BbU+I1-6{3fP;8MvcDfJ-!xQ&+6}Y0l z?79h1xHOMv5;@6+egS7r$cn<$txVLe6i8N$Qop48%gdr`$xi(RMAXlm4TY_lX&_U>$m#2<&R=XJwOlOV_v zFcX~)&Fdw*3SM98vz=BfPV(-r{){(G?^>jaa1`k4!Ig|o>$W}D73nOGZrMde$7dVhv(iR5b+8lvvU2KaD+J2brox>; zVfi18TzNEGX&1yk50(WgbDu(n_$^G?q3#HJ-8* zAfql@6tEwwC(k(qmbOt+TwAwWph{?IAp^L2-HcIk!vgcx(kPQXxX7cxl-I+gDcy(m z3>)76NBSAqu?={K{x(X~G})by)4&+|Y@Ldi>f8Z~GixePgm?m;f0=iy7Iro~fg%H6 zF9Hv0{vdUdd54@`kOL#tC~if?pWqQtJ|Rtr`O3nXsSHV>nbOT!n7lm>?RW5x$=&~I z?VOJrtuMZVXszn5vW+%?F%rybk3SQ}RnWZD-`5>Cw0x@=1J3u$VsNC6`b)bO5v9Rn zb)8gzKV{T?@vP&b1(Y4XTpF$ zz4l{+>ek2B*KhVkT&yozyBoga5rC1_Hx2vvxhero)A2yogMayx_8+<6?-T_`h2mGy z=Dy&-Q*mn&9z9C}?;Hza~c{NCKuS@L3!ED^xz%)Bl*z>=S(yN)9g>b*+%%f9TlAO z1VXM4-$l}kdjM@n4sppTr2kSPU zcQCZGs2O0Va?qgJ*5uF=+MLw*wOJ}~Ew|Lcxj+3J;&|y&iQ(je3Dz>U81WC*w=q9^ zZEo4s5aO08jOCtJy#BQZ!^UaaU8O8WRUGq}@MRjwMg!&Czf2fBU&$QA_yd@4nUMP7 zfeZqPUJO8GaVGW#q+*39-9R5Qchc4#T-i7_y@*YdVB>V%>%GVWH^@L16TD zT*c+z<8F%k0aeE?GED#ePu3~NbZ*GML?orMJX0i1rQ$N@f}(l06}ujEsx` zzhejW3;|l}K%@_d(#V5M7Z6Vz z%Du5uO+#bDd)n*={Jh=NsJ>i*yWbfgGz0$FXEY?I_0AC>f%T&+FRM}d)28_@AQ$q* zcd{EmROx-oC zZ!_EKd7G8m_jUis^BZ0b2gcIm6a1QR>-y^76}E~+Hyd7M31wMx*iN#3vt6=BRiN=z zsB0)&o?4ygwAG0i6svqduS+~z4}z55cIo~E{r|$uzDAK=P_E|&kRi6Y@F*FyU|r;f zM>#n;>6x21p-d}$J0N&L(>U|^Ns!lUCnO!t0db4Crm%P%4grmrVf!R4t*|l>9wm`- z;#XSY0BiS4%ZO~KRyhJgvKy;fiYc&k5>&xxJwpLV61|u0M%pTRBSI5Ii56QHG_|+P%%`>pJ(v{{=mNSH;8t%M<5(K-8NHYOQ|($vtm$O!4>Adz=XY ze@^pXKnWUE?N_RYzzg@HPvfr}Kp`cWvzZ-XiY~iD=RKd-1_=@2qvR_+GdY^=p3}W$ ztmadd=M}zr)$kf3!yTi^GChqFxmP6}g?$Tny_t!aj`w-f?cQF#{K%_sqVIqDU~a6G z@x?Y{XJ2&|N}u79#5EXlQ7C6{4{JNE)%b=~5`}T)r^*0+zf>)U4Hs;n2>4_cXkiCBP8c!pqc;i zp;>CFfe6X-TfnFKCbaTfqI=RUtSkJp&iPM1FOQuF_407?v695d$mChXW%{f(t}Jxp zw=oQ`BgaN8V-Y6pPQqu(Dw9AzMekkzHy8J>Y)5*HUktnO<_MJQ(0w^pW?@Da#ISlj?;%7u-b-9@-iST>Vy}4;><8mn7t2>q7dalXk ze;X%t4rSGBz~XZE52^NtzPx?kYQE~bXWJb z<0Pq`{MEfyf~+K^l5klwf&3<4f3UG-M5yddVoG9(LRHY93<#zZ$)u!p52~qlv0=%T zPuJTx_)3-bw&*~wpswCr5oKf$0;IO2%!yyjfpRh7AXT7^`2|h%!GL8XyMO8@`>