From 840161bc6771a2683a4658a060e42224191e3f00 Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:07:21 +0200 Subject: [PATCH 001/104] Makes meteors not take damage from railings (#22909) * One simple istype killing many Farragi * Qwerty Suggestion --- code/__DEFINES/is_helpers.dm | 8 ++++++++ code/game/objects/effects/meteors.dm | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 76c2c01fd13c..21ed7400cef5 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -121,3 +121,11 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( // Modsuits #define ismodcontrol(A) istype(A, /obj/item/mod/control) + +// Meteors +GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( + /turf/simulated/floor/plating/asteroid, + /turf/space +))) + +#define ispassmeteorturf(A) (is_type_in_typecache(A, GLOB.turfs_pass_meteor)) diff --git a/code/game/objects/effects/meteors.dm b/code/game/objects/effects/meteors.dm index 8f1e37496eab..2bfa9f094e81 100644 --- a/code/game/objects/effects/meteors.dm +++ b/code/game/objects/effects/meteors.dm @@ -111,7 +111,7 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops var/turf/T = get_turf(loc) ram_turf(T) - if(prob(10) && !isspaceturf(T))//randomly takes a 'hit' from ramming + if(prob(10) && !ispassmeteorturf(T))//randomly takes a 'hit' from ramming get_hit() /obj/effect/meteor/Destroy() @@ -133,7 +133,8 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops if(A) ram_turf(get_turf(A)) playsound(loc, meteorsound, 40, TRUE) - get_hit() + if(!istype(A, /obj/structure/railing)) + get_hit() /obj/effect/meteor/proc/ram_turf(turf/T) //first bust whatever is in the turf From 0e455176b25c1e5722169cc3f093981f0976ca63 Mon Sep 17 00:00:00 2001 From: Burzah <116982774+Burzah@users.noreply.github.com> Date: Sun, 22 Oct 2023 09:07:34 -0700 Subject: [PATCH 002/104] Adds additional logging for megaphone (#22949) * Adds additional logging for megaphone use * format change * Formatting change to log_say (review change) * Update code/game/objects/items/devices/megaphone.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --------- Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --- code/game/objects/items/devices/megaphone.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 46f64243e543..ef5b8e13fbb3 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -81,7 +81,8 @@ playsound(src, "sound/items/megaphone.ogg", 100, FALSE, 5) audible_message("[user.GetVoice()] [user.GetAltName()] broadcasts, \"[message]\"", hearing_distance = 14) - log_say(message, user) + log_say("(MEGAPHONE) [message]", user) + user.create_log(SAY_LOG, "(megaphone) '[message]'") for(var/obj/O in view(14, get_turf(src))) O.hear_talk(user, message_to_multilingual("[message]")) From 12b73a4d450bc2b6f3980b5006c68dd203127f23 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:49:59 -0400 Subject: [PATCH 003/104] Improves admin interaction with AIs (#22769) * admin-ai improvements * Update code/modules/admin/misc_admin_procs.dm Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * brug --------- Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> --- code/modules/admin/admin_verbs.dm | 4 ++ code/modules/admin/misc_admin_procs.dm | 43 +++++++++++++++---- code/modules/mob/living/silicon/ai/ai_mob.dm | 7 +++ .../modules/mob/living/silicon/ai/latejoin.dm | 1 + 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 10cc7b273842..d3918481b0fc 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -368,6 +368,7 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list( if(isobserver(mob)) //re-enter var/mob/dead/observer/ghost = mob + var/old_turf = get_turf(ghost) ghost.can_reenter_corpse = 1 //just in-case. ghost.reenter_corpse() log_admin("[key_name(usr)] re-entered their body") @@ -375,6 +376,9 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list( if(ishuman(mob)) var/mob/living/carbon/human/H = mob H.regenerate_icons() // workaround for #13269 + if(isAI(mob)) // client.mob, built in byond client var + var/mob/living/silicon/ai/ai = mob + ai.eyeobj.setLoc(old_turf) else if(isnewplayer(mob)) to_chat(src, "Error: Aghost: Can't admin-ghost whilst in the lobby. Join or observe first.") else diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm index 212836ece754..005fa9861bf5 100644 --- a/code/modules/admin/misc_admin_procs.dm +++ b/code/modules/admin/misc_admin_procs.dm @@ -889,27 +889,27 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space //returns 1 to let the dragdrop code know we are trapping this event //returns 0 if we don't plan to trap the event -/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, tothing) +/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, atom/tothing) if(!istype(frommob)) return //extra sanity check to make sure only observers are shoved into things //same as assume-direct-control perm requirements. if(!check_rights(R_VAREDIT,0)) //no varedit, check if they have r_admin and r_debug if(!check_rights(R_ADMIN|R_DEBUG,0)) //if they don't have r_admin and r_debug, return - return 0 //otherwise, if they have no varedit, but do have r_admin and r_debug, execute the rest of the code + return FALSE //otherwise, if they have no varedit, but do have r_admin and r_debug, execute the rest of the code if(!frommob.ckey) - return 0 + return FALSE if(isitem(tothing)) var/mob/living/toitem = tothing var/ask = alert("Are you sure you want to allow [frommob.name]([frommob.key]) to possess [toitem.name]?", "Place ghost in control of item?", "Yes", "No") if(ask != "Yes") - return 1 + return TRUE if(!frommob || !toitem) //make sure the mobs don't go away while we waited for a response - return 1 + return TRUE var/mob/living/simple_animal/possessed_object/tomob = new(toitem) @@ -931,10 +931,10 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No") if(ask != "Yes") - return 1 + return TRUE if(!frommob || !tomob) //make sure the mobs don't go away while we waited for a response - return 1 + return TRUE if(tomob.client) //no need to ghostize if there is no client tomob.ghostize(0) @@ -946,7 +946,34 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space tomob.ckey = frommob.ckey qdel(frommob) - return 1 + return TRUE + + if(istype(tothing, /obj/structure/AIcore/deactivated)) + + var/question = "Are you sure you want to place [frommob.name]([frommob.key]) in control of an empty AI core?" + + var/ask = alert(question, "Place ghost in control of an empty AI core?", "Yes", "No") + if(ask != "Yes") + return TRUE + + if(QDELETED(frommob) || QDELETED(tothing)) //make sure the mobs don't go away while we waited for a response + return TRUE + + message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of an empty AI core.") + log_admin("[key_name(usr)] stuffed [frommob.ckey] into an empty AI core.") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag") + + var/transfer_key = frommob.key // frommob is qdel'd in frommob.AIize() + var/mob/living/silicon/ai/ai_character = frommob.AIize() + ai_character.key = transfer_key // this wont occur in mind transferring if the mind is not active, which causes some weird stuff. This fixes it. + GLOB.empty_playable_ai_cores -= tothing + + ai_character.forceMove(get_turf(tothing)) + ai_character.view_core() + + qdel(tothing) + + return TRUE // Returns a list of the number of admins in various categories // result[1] is the number of staff that match the rank mask and are active diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm index ae0fcb3f72bd..c4edfb8b0701 100644 --- a/code/modules/mob/living/silicon/ai/ai_mob.dm +++ b/code/modules/mob/living/silicon/ai/ai_mob.dm @@ -1518,4 +1518,11 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( stored_locations[location_number] = eyeobj.loc return TRUE +/mob/living/silicon/ai/ghostize(can_reenter_corpse) + var/old_turf = get_turf(eyeobj) + . = ..() + if(isobserver(.)) + var/mob/dead/observer/ghost = . + ghost.forceMove(old_turf) + #undef TEXT_ANNOUNCEMENT_COOLDOWN diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm index 0824a740a646..e198fc92b476 100644 --- a/code/modules/mob/living/silicon/ai/latejoin.dm +++ b/code/modules/mob/living/silicon/ai/latejoin.dm @@ -33,6 +33,7 @@ GLOBAL_LIST_EMPTY(empty_playable_ai_cores) continue O.on_target_cryo() + view_core() // Ghost the current player and disallow them to return to the body if(TOO_EARLY_TO_GHOST) ghostize(FALSE) From a85d65d6d3b38884704541496b7352498b303571 Mon Sep 17 00:00:00 2001 From: Vi3trice <80771500+Vi3trice@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:51:57 -0400 Subject: [PATCH 004/104] hey dawg i heard you like lights (#22821) --- code/modules/shuttle/shuttle.dm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index b797d6d03e9f..e4c2de855b70 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -991,8 +991,13 @@ if(T.icon != icon) T.icon = icon if(color) - T.atom_colours = atom_colours.Copy() - T.update_atom_colour() + if(length(atom_colours)) + T.atom_colours = atom_colours.Copy() + T.update_atom_colour() + else + T.color = color // If you don't have atom_colours then you're working off an absolute color + if(light) + T.set_light(light_range, light_power, light_color) if(T.dir != dir) T.setDir(dir) return T From b508640e3988266935ea2a1201902f8a24335bb0 Mon Sep 17 00:00:00 2001 From: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:52:51 -0400 Subject: [PATCH 005/104] IPCs can die from low power (#22846) * im so not full from electricity grrr * Update code/modules/mob/living/carbon/human/species/machine.dm whitespace fix Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * now its the microbattery dying * Update code/modules/mob/living/carbon/human/species/machine.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --- code/modules/mob/living/carbon/examine.dm | 5 ++++- .../living/carbon/human/species/machine.dm | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index f9991c2e7145..f6dcb76dd2db 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -247,7 +247,10 @@ msg += "[p_they(TRUE)] look[p_s()] absolutely soaked.\n" if(nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) - msg += "[p_they(TRUE)] [p_are()] severely malnourished.\n" + if(ismachineperson(src)) + msg += "[p_their(TRUE)] power indicator is flashing red.\n" + else + msg += "[p_they(TRUE)] [p_are()] severely malnourished.\n" if(HAS_TRAIT(src, TRAIT_FAT)) msg += "[p_they(TRUE)] [p_are()] morbidly obese.\n" diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 6f75c43a8012..aa4d306a9add 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -127,6 +127,28 @@ H.update_hair() H.update_fhair() +/datum/species/machine/handle_life(mob/living/carbon/human/H) // Handles IPC starvation + if(isLivingSSD(H)) // We don't want AFK people dying from this + return + if(H.nutrition >= NUTRITION_LEVEL_HYPOGLYCEMIA) + return + + var/obj/item/organ/internal/cell/microbattery = H.get_organ_slot("heart") + if(!istype(microbattery)) //Maybe they're powered by an abductor gland or sheer force of will + return + if(prob(6)) + to_chat(H, "Error 74: Microbattery critical malfunction, likely cause: Extended strain.") + microbattery.receive_damage(4, TRUE) + else if(prob(4)) + H.Weaken(6 SECONDS) + H.Stuttering(20 SECONDS) + to_chat(H, "Power critical, shutting down superfluous functions.") + H.emote("collapse") + microbattery.receive_damage(2, TRUE) + else if(prob(4)) + to_chat(H, "Redirecting excess power from servos to vital components.") + H.Slowed(rand(15 SECONDS, 32 SECONDS)) + // Allows IPC's to change their monitor display /datum/action/innate/change_monitor name = "Change Monitor" From a60bfdf934a2313f890fea9115ecf947eba2c40f Mon Sep 17 00:00:00 2001 From: Varelion <99684831+Varelion@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:54:09 -0400 Subject: [PATCH 006/104] AltClick() Deck Shuffle (#22924) * Update tarot.dm Allow shuffle through AltClick(), reduce shuffle time. * Update cards.dm Allow AltClick to shuffle the deck. * Updated tarot.dm Removed the tarot shuffle, as it was already inherited from deck's new AltClick shuffle option. * Update cards.dm Lowered cooldown on cards.dm to match tarot.dm * Change tarot.dm and cards.dm Changed shuffling cooldown time from 5 seconds to one second. --- code/modules/games/cards.dm | 5 ++++- code/modules/games/tarot.dm | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 43088af133fa..e8ee0cd1e05c 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -239,6 +239,9 @@ /obj/item/deck/attack_self() deckshuffle() +/obj/item/deck/AltClick() + deckshuffle() + /obj/item/deck/verb/verb_shuffle() if(!isobserver(usr)) set category = "Object" @@ -249,7 +252,7 @@ /obj/item/deck/proc/deckshuffle() var/mob/living/user = usr - if(cooldown < world.time - 5 SECONDS) + if(cooldown < world.time - 1 SECONDS) cards = shuffle(cards) user.visible_message("[user] shuffles [src].") playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) diff --git a/code/modules/games/tarot.dm b/code/modules/games/tarot.dm index b176bbd78bea..da99f76b2fd3 100644 --- a/code/modules/games/tarot.dm +++ b/code/modules/games/tarot.dm @@ -15,7 +15,7 @@ /obj/item/deck/tarot/deckshuffle() var/mob/living/user = usr - if(cooldown < world.time - 5 SECONDS) + if(cooldown < world.time - 1 SECONDS) var/list/newcards = list() while(cards.len) var/datum/playingcard/P = pick(cards) @@ -28,3 +28,4 @@ playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) user.visible_message("[user] shuffles [src].", "You shuffle [src].") cooldown = world.time + From 00d70107021ed4d5d40b64ceb661ff9deb94baf5 Mon Sep 17 00:00:00 2001 From: Henri215 <77684085+Henri215@users.noreply.github.com> Date: Sun, 22 Oct 2023 13:54:32 -0300 Subject: [PATCH 007/104] PDA free DLC: New ringtones! (#22945) * PDA free DLC: New ringtones! * name tweaks --- code/modules/pda/PDA.dm | 16 ++++++++++++++-- sound/machines/notif1.ogg | Bin 0 -> 7193 bytes sound/machines/notif2.ogg | Bin 0 -> 8295 bytes 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 sound/machines/notif1.ogg create mode 100644 sound/machines/notif2.ogg diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index f0ee565a36b7..82783e62768b 100644 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -37,12 +37,24 @@ GLOBAL_LIST_EMPTY(PDAs) var/detonate = TRUE // Can the PDA be blown up? var/ttone = "beep" //The ringtone! var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg', - "boom" = 'sound/effects/explosionfar.ogg', + "boop" = 'sound/machines/boop.ogg', + "electronic" = 'sound/machines/notif1.ogg', + "chime" = 'sound/machines/notif2.ogg', "slip" = 'sound/misc/slip.ogg', "honk" = 'sound/items/bikehorn.ogg', "SKREE" = 'sound/voice/shriek1.ogg', "holy" = 'sound/items/PDA/ambicha4-short.ogg', - "xeno" = 'sound/voice/hiss1.ogg') + "boom" = 'sound/effects/explosionfar.ogg', + "gavel" = 'sound/items/gavel.ogg', + "xeno" = 'sound/voice/hiss1.ogg', + "smoke" = 'sound/magic/smoke.ogg', + "shatter" = 'sound/effects/pylon_shatter.ogg', + "energy" = 'sound/weapons/egloves.ogg', + "flare" = 'sound/goonstation/misc/matchstick_light.ogg', + "interference" = 'sound/misc/interference.ogg', + "zap" = 'sound/effects/eleczap.ogg', + "disgusting" = 'sound/effects/blobattack.ogg', + "hungry" = 'sound/weapons/bite.ogg') var/list/programs = list( new/datum/data/pda/app/main_menu, diff --git a/sound/machines/notif1.ogg b/sound/machines/notif1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b21c87bbbf5b9cc84bb77ab3999c016577917581 GIT binary patch literal 7193 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 P36-4g#|;JQCWHS1**)!c literal 0 HcmV?d00001 diff --git a/sound/machines/notif2.ogg b/sound/machines/notif2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..daa78a168c398dc98e348f1b7b3688a9f83f26a1 GIT binary patch literal 8295 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 literal 0 HcmV?d00001 From d5b70b641037dd2b4bd7378f3ba06154bb54966e Mon Sep 17 00:00:00 2001 From: datlo Date: Sun, 22 Oct 2023 18:54:45 +0200 Subject: [PATCH 008/104] Mimes get department backpack (#22948) --- code/game/jobs/job/support.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 0ef315a8aab3..5a4f493570bb 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -379,6 +379,9 @@ /obj/item/cane = 1 ) + backpack = /obj/item/storage/backpack/mime + satchel = /obj/item/storage/backpack/mime + /datum/outfit/job/mime/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) . = ..() if(H.gender == FEMALE) From bec3ef912b46195e98a26a5e9a45a09544033dfe Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 22 Oct 2023 13:00:18 -0400 Subject: [PATCH 009/104] Removing accessories from a jumpsuit is now a radial menu (#22696) * accessory + helper * elper * okay, less insanity * lewc review --- code/_onclick/hud/radial.dm | 42 +++++++++++++++++++++++++++++++ code/modules/clothing/clothing.dm | 13 ++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 7e56d84813ea..87dd423159ad 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -309,4 +309,46 @@ GLOBAL_LIST_EMPTY(radial_menus) GLOB.radial_menus -= uniqueid return answer +/** + * Similar to show_radial_menu, but choices is a list of atoms, for which icons will be automatically generated. + * Supports multiple items of the same name, 2 soaps will become soap (1) and soap (2) to the user. + * Otherwise, has the exact same arguments as show_radial_menu + */ +/proc/radial_menu_helper(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE) + var/list/duplicate_amount = list() + for(var/atom/atom in choices) + if(!duplicate_amount.Find(atom.name)) + duplicate_amount[atom.name] = 0 + else + duplicate_amount[atom.name]++ + var/list/duplicate_indexes = duplicate_amount.Copy() + + var/list/icon_state_choices = list() + var/list/return_choices = list() + for(var/atom/possible_atom in choices) + if(!istype(possible_atom)) + stack_trace("radial_menu_helper was passed a non-atom (\"[possible_atom]\", [possible_atom.type]) as a choice") + continue + var/mutable_appearance/atom_appearance = new(possible_atom.appearance) + + var/hover_outline_index = possible_atom.get_filter("hover_outline") + if(!isnull(hover_outline_index)) + atom_appearance.filters.Cut(hover_outline_index, hover_outline_index + 1) + + var/key = possible_atom.name + if(duplicate_amount[key]) + var/number = duplicate_amount[key] - duplicate_indexes[key] + duplicate_indexes[key]-- + key = "[key] ([number + 1])" + + icon_state_choices[key] = atom_appearance + return_choices[key] = possible_atom + + var/chosen_key = show_radial_menu(user, anchor, icon_state_choices, uniqueid, radius, custom_check, require_near) + + if(!chosen_key) + return + + return return_choices[chosen_key] + #undef ANIM_SPEED diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index d061aaf0f713..b59c865a3f8b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -756,7 +756,7 @@ if(istype(I, /obj/item/clothing/accessory)) attach_accessory(I, user, TRUE) - if(accessories.len) + if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) A.attackby(I, user, params) return TRUE @@ -882,11 +882,14 @@ return if(!Adjacent(usr)) return - if(!accessories.len) + if(!length(accessories)) return var/obj/item/clothing/accessory/A - if(accessories.len > 1) - A = input("Select an accessory to remove from [src]") as null|anything in accessories + if(length(accessories) > 1) + var/pick = radial_menu_helper(usr, src, accessories, custom_check = FALSE, require_near = TRUE) + if(!pick) + return + A = pick else A = accessories[1] remove_accessory(usr,A) @@ -904,7 +907,7 @@ to_chat(user, "You remove [A] from [src].") /obj/item/clothing/under/emp_act(severity) - if(accessories.len) + if(length(accessories)) for(var/obj/item/clothing/accessory/A in accessories) A.emp_act(severity) ..() From 37d3a3dbe02598c05adc4f969d4ce28028030416 Mon Sep 17 00:00:00 2001 From: matttheficus <57759731+matttheficus@users.noreply.github.com> Date: Sun, 22 Oct 2023 13:04:54 -0400 Subject: [PATCH 010/104] yay for autoresponse (#22937) --- code/controllers/configuration/sections/url_configuration.dm | 3 +++ code/controllers/subsystem/tickets/tickets.dm | 3 +++ config/example/config.toml | 2 ++ 3 files changed, 8 insertions(+) diff --git a/code/controllers/configuration/sections/url_configuration.dm b/code/controllers/configuration/sections/url_configuration.dm index 1ec1c55b6598..82dac8df1112 100644 --- a/code/controllers/configuration/sections/url_configuration.dm +++ b/code/controllers/configuration/sections/url_configuration.dm @@ -16,6 +16,8 @@ var/rules_url /// URL for the server github repository var/github_url + /// URL for the server exploit report locaion + var/exploit_url /// URL for server donations var/donations_url /// URL for a direct discord invite @@ -41,6 +43,7 @@ CONFIG_LOAD_STR(forum_url, data["forum_url"]) CONFIG_LOAD_STR(rules_url, data["rules_url"]) CONFIG_LOAD_STR(github_url, data["github_url"]) + CONFIG_LOAD_STR(exploit_url, data["exploit_url"]) CONFIG_LOAD_STR(donations_url, data["donations_url"]) CONFIG_LOAD_STR(discord_url, data["discord_url"]) CONFIG_LOAD_STR(discord_forum_url, data["discord_forum_url"]) diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm index 5ad4f92b71fb..d3310abcaa67 100644 --- a/code/controllers/subsystem/tickets/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -232,6 +232,9 @@ SUBSYSTEM_DEF(tickets) if(GLOB.configuration.url.github_url) response_phrases["Github Issue Report"] = "To report a bug, please go to our Github page. Then go to 'Issues'. Then 'New Issue'. Then fill out the report form. If the report would reveal current-round information, file it after the round ends." + if(GLOB.configuration.url.exploit_url) + response_phrases["Exploit Report"] = "To report an exploit, please go to our Exploit Report page. Then 'Start New Topic'. Then fill out the topic with as much information about the exploit that you can. If possible, add steps taken to reproduce the exploit. The Development Team will be informed automatically of the post." + var/sorted_responses = list() for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse sorted_responses += key diff --git a/config/example/config.toml b/config/example/config.toml index abd0bb1910c6..e4fe6402ea85 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -766,6 +766,8 @@ wiki_url = "https://www.paradisestation.org/wiki" rules_url = "https://www.paradisestation.org/rules" # Github address github_url = "https://github.com/ParadiseSS13/Paradise" +# Exploit address +exploit_url = "https://www.paradisestation.org/forum/179-exploit-reports/" # Discord address #discord_url = "http://example.org" # Discord address (forum-based invite) From eaa41485f9fb842b8b0a411c856d39d469f451ab Mon Sep 17 00:00:00 2001 From: Deniz <66401072+Oyu-De@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:14:58 +0100 Subject: [PATCH 011/104] Floorbot bug fix + Bridgemode Removal (#22531) * commented out * deleted bridge mode and targetdirection * Fixes replace tiles bug * Autotile - Damaged floor fix * Break_tile var moved up. SHOULD be final * Update code/modules/mob/living/simple_animal/bot/floorbot.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> --- .../mob/living/simple_animal/bot/floorbot.dm | 55 ++++--------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index bdbc065549cf..c98724dfc4e2 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -19,7 +19,6 @@ window_name = "Automatic Station Floor Repairer v1.1" var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details. - var/targetdirection var/amount = 10 var/replacetiles = 0 var/eattiles = 0 @@ -34,7 +33,6 @@ var/toolbox_color = "" #define HULL_BREACH 1 - #define BRIDGE_MODE 2 #define FIX_TILE 3 #define AUTO_TILE 4 #define REPLACE_TILE 5 @@ -83,13 +81,6 @@ dat += "Repair damaged tiles and platings: [fixfloors ? "Yes" : "No"]
" dat += "Traction Magnets: [anchored ? "Engaged" : "Disengaged"]
" dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" - var/bmode - if(targetdirection) - bmode = dir2text(targetdirection) - else - bmode = "disabled" - dat += "Bridge Mode : [bmode]
" - return dat @@ -135,20 +126,6 @@ nag_on_empty = !nag_on_empty if("anchor") anchored = !anchored - - if("bridgemode") - var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable") - switch(setdir) - if("north") - targetdirection = 1 - if("south") - targetdirection = 2 - if("east") - targetdirection = 4 - if("west") - targetdirection = 8 - if("disable") - targetdirection = null update_controls() /mob/living/simple_animal/bot/floorbot/handle_automated_action() @@ -176,16 +153,6 @@ //Normal scanning procedure. We have tiles loaded, are not emagged. if(!target && emagged < 2 && amount > 0) - if(targetdirection != null) //The bot is in bridge mode. - //Try to find a space tile immediately in our selected direction. - var/turf/T = get_step(src, targetdirection) - if(isspaceturf(T)) - target = T - - else //Find a space tile farther way! - target = scan(/turf/space) - process_type = BRIDGE_MODE - if(!target) process_type = HULL_BREACH //Ensures the floorbot does not try to "fix" space areas or shuttle docking zones. target = scan(/turf/space) @@ -279,10 +246,6 @@ if(is_hull_breach(scan_target)) //Ensure that the targeted space turf is actually part of the station, and not random space. result = scan_target anchored = TRUE //Prevent the floorbot being blown off-course while trying to reach a hull breach. - if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered. - if(get_dir(src, scan_target) == targetdirection) - result = scan_target - anchored = TRUE if(REPLACE_TILE) F = scan_target if(istype(F, /turf/simulated/floor/plating)) //The floor must not already have a tile. @@ -301,8 +264,8 @@ /mob/living/simple_animal/bot/floorbot/proc/repair(turf/target_turf) if(isspaceturf(target_turf)) - //Must be a hull breach or in bridge mode to continue. - if(!is_hull_breach(target_turf) && !targetdirection) + //Must be a hull breach to continue. + if(!is_hull_breach(target_turf)) target = null return @@ -317,7 +280,7 @@ anchored = TRUE if(isspaceturf(target_turf)) //If we are fixing an area not part of pure space, it is - visible_message("[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] ") + visible_message("[src] begins to repair the hole.") mode = BOT_REPAIRING update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, PROC_REF(make_bridge_plating), target_turf), 5 SECONDS) @@ -343,13 +306,19 @@ target = null /mob/living/simple_animal/bot/floorbot/proc/make_bridge_plating(turf/target_turf) + var/turf/simulated/floor/F = target if(mode != BOT_REPAIRING) return - if(autotile) //Build the floor and include a tile. + if(replacetiles) + F.break_tile_to_plating() target_turf.ChangeTurf(/turf/simulated/floor/plasteel) - else //Build a hull plating without a floor tile. - target_turf.ChangeTurf(/turf/simulated/floor/plating) + else + if(autotile) //Build the floor and include a tile. + F.break_tile_to_plating() + target_turf.ChangeTurf(/turf/simulated/floor/plasteel) + else //Build a hull plating without a floor tile. + target_turf.ChangeTurf(/turf/simulated/floor/plating) mode = BOT_IDLE amount-- update_icon(UPDATE_ICON_STATE) From 53589e559c4a899a1359ea4f2a710c3106e0e247 Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:15:55 -0500 Subject: [PATCH 012/104] fixes an omni od runtime (#23016) --- code/modules/reagents/chemistry/reagents/medicine.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index ab0610de9daa..259512c15f67 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -360,7 +360,7 @@ /datum/reagent/medicine/omnizine/overdose_process(mob/living/M, severity) if(HAS_TRAIT(M, TRAIT_BADASS)) - return + return list(0, STATUS_UPDATE_NONE) var/list/overdose_info = ..() var/effect = overdose_info[REAGENT_OVERDOSE_EFFECT] From 3388035c12fa8887d8344b2701e1b7c5e8fd3005 Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Tue, 24 Oct 2023 23:51:49 +0200 Subject: [PATCH 013/104] [s] Fixes an unathi nerf (#23019) * The fix * Removes parentheses --- code/modules/mob/living/carbon/human/species/_species.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 32441badbd12..4a4a36d0d392 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -325,8 +325,8 @@ if(HAS_TRAIT(H, TRAIT_FAT)) . += (1.5 - flight) - if(H.bodytemperature < H.dna.species.cold_level_1 && !(HAS_TRAIT(H, TRAIT_RESISTCOLD))) - . += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR + if(H.bodytemperature < H.dna.species.cold_level_1 && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) + . += (H.dna.species.cold_level_1 - H.bodytemperature) / COLD_SLOWDOWN_FACTOR var/leftover = . . = round_down(. * SLOWDOWN_MULTIPLIER) / SLOWDOWN_MULTIPLIER //This allows us to round in values of 0.5 A slowdown of 0.55 becomes 1.10, which is rounded to 1, then reduced to 0.5 From 55d696b593a2b455be505c2e29501993a12bb272 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:46:59 -0400 Subject: [PATCH 014/104] [s] Fixes an issue with bubblegum (#23027) * no we do NOT need you getting into the admin room THANK YOU * give it a break --- .../living/simple_animal/hostile/megafauna/bubblegum.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 8a3d90563ffa..91666e29827d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -646,3 +646,10 @@ Difficulty: Hard for(var/mob/living/carbon/human/H in range(20)) to_chat(H, "I WILL END YOU HERE AND NOW!") FindTarget(list(H), 1) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/round_2/Life(seconds, times_fired) + . = ..() + if(!istype(get_area(src), /area/ruin/space/bubblegum_arena)) + for(var/obj/effect/landmark/spawner/bubblegum/B in GLOB.landmarks_list) + forceMove(get_turf(B)) + break From 6e0905f6cfb2cf1ea7f46d1e5b9a2beb899fdf07 Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Thu, 26 Oct 2023 04:30:00 -0500 Subject: [PATCH 015/104] ghost role ruins are guaranteed spawns, ghost ruins no longer cost any points to spawn (#21849) * ghost role ruins are guarenteed spawns, ghost ruins no longer cost any points to spawn * exa request --- code/datums/ruins/lavaland.dm | 10 +++++----- code/datums/ruins/space_ruins.dm | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 1534ffafa858..e748e07ef943 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -32,10 +32,10 @@ name = "Seed Vault" id = "seed-vault" description = "The creators of these vaults were a highly advanced and benevolent race, and launched many into the stars, hoping to aid fledgling civilizations. \ - However, all the inhabitants seem to do is grow drugs and guns." + However, all the inhabitants seem to do is grow drugs and explosives." suffix = "lavaland_surface_seed_vault.dmm" - cost = 10 allow_duplicates = FALSE + always_place = TRUE /datum/map_template/ruin/lavaland/ash_walker name = "Ash Walker Nest" @@ -43,17 +43,17 @@ description = "A race of unbreathing lizards live here, that run faster than a human can, worship a broken dead city, and are capable of reproducing by something involving tentacles? \ Probably best to stay clear." suffix = "lavaland_surface_ash_walker1.dmm" - cost = 20 allow_duplicates = FALSE + cost = 20 // Not auto due to the nature of walkers /datum/map_template/ruin/lavaland/free_golem name = "Free Golem Ship" id = "golem-ship" description = "Lumbering humanoids, made out of precious metals, move inside this ship. They frequently leave to mine more minerals, which they somehow turn into more of them. \ Seem very intent on research and individual liberty, and also geology based naming?" - cost = 20 suffix = "lavaland_surface_golem_ship.dmm" allow_duplicates = FALSE + always_place = TRUE /datum/map_template/ruin/lavaland/althland_facility name = "Althland Facility" @@ -192,7 +192,7 @@ description = "A place of shelter for a lone hermit, scraping by to live another day." suffix = "lavaland_surface_hermit.dmm" allow_duplicates = FALSE - cost = 10 + always_place = TRUE /datum/map_template/ruin/lavaland/miningripley name = "Ripley" diff --git a/code/datums/ruins/space_ruins.dm b/code/datums/ruins/space_ruins.dm index 4a6b6eb082eb..9b7ce503c25c 100644 --- a/code/datums/ruins/space_ruins.dm +++ b/code/datums/ruins/space_ruins.dm @@ -168,7 +168,8 @@ name = "Ancient Space Station" description = "The crew of a space station awaken one hundred years after a crisis. Awaking to a derelict space station on the verge of collapse, and a hostile force of invading \ hivebots. Can the surviving crew overcome the odds and survive and rebuild, or will the cold embrace of the stars become their new home?" - cost = 2 + cost = 0 + always_place = TRUE allow_duplicates = FALSE /datum/map_template/ruin/space/wizardcrash From 223cd99fd21b6e3eed1c4f84435ca1882dec0600 Mon Sep 17 00:00:00 2001 From: Adrer Date: Thu, 26 Oct 2023 11:31:04 +0200 Subject: [PATCH 016/104] Reagent Grinder TGUI (#22645) * Reagent Grinder TGUI * Update tgui/packages/tgui/interfaces/ReagentGrinder.js Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update tgui/packages/tgui/interfaces/ReagentGrinder.js Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update tgui/packages/tgui/interfaces/ReagentGrinder.js Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Requested changes * Fixed import issues * Added operating component to KitchenMachine.js * Remember to push the bundle * Update tgui/packages/tgui/interfaces/ReagentGrinder.js Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Biogenerator processing change * Updated bundle * Fixes biogenerator processing * Update tgui/packages/tgui/interfaces/KitchenMachine.js Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update tgui/packages/tgui/interfaces/KitchenMachine.js Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update tgui/packages/tgui/interfaces/KitchenMachine.js Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Use config over sending name along with data * Ran prettier * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Updated description on Operating * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Missing parenthesis * Missing parenthesis * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/reagents/chemistry/machinery/reagentgrinder.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --------- Co-authored-by: Adrer Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> --- .../kitchen_machinery/kitchen_machine.dm | 5 - .../chemistry/machinery/reagentgrinder.dm | 171 ++++++++++-------- tgui/packages/tgui/interfaces/Biogenerator.js | 29 +-- .../tgui/interfaces/KitchenMachine.js | 27 +-- .../tgui/interfaces/ReagentGrinder.js | 138 ++++++++++++++ .../tgui/interfaces/common/Operating.js | 34 ++++ tgui/packages/tgui/public/tgui.bundle.js | 6 +- 7 files changed, 282 insertions(+), 128 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/ReagentGrinder.js create mode 100644 tgui/packages/tgui/interfaces/common/Operating.js diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm index d5eba519442a..36f707765e63 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm @@ -528,11 +528,6 @@ return data -/obj/machinery/kitchen_machine/ui_static_data(mob/user) - var/list/data = list() - data["name"] = name - return data - /obj/machinery/kitchen_machine/ui_act(action, params, datum/tgui/ui) . = ..() if(.) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 3c87b83c73d0..e225788fb0f3 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -160,6 +160,7 @@ /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) if(exchange_parts(user, I)) + SStgui.update_uis(src) return if((istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER)) && user.a_intent != INTENT_HARM) @@ -173,7 +174,7 @@ beaker = I beaker.loc = src update_icon(UPDATE_ICON_STATE) - updateUsrDialog() + SStgui.update_uis(src) return TRUE //no afterattack if(is_type_in_list(I, dried_items)) @@ -212,7 +213,7 @@ else to_chat(user, "You empty some of [B]'s contents into the All-In-One grinder.") - updateUsrDialog() + SStgui.update_uis(src) return TRUE if(!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) @@ -225,7 +226,7 @@ if(user.drop_item()) I.loc = src holdingitems += I - src.updateUsrDialog() + SStgui.update_uis(src) return FALSE @@ -234,95 +235,117 @@ return FALSE /obj/machinery/reagentgrinder/attack_hand(mob/user) - user.set_machine(src) - interact(user) - -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" - - if(!operating) - for (var/obj/item/O in holdingitems) - processing_chamber += "\A [html_encode(O.name)]
" - - if(!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if(!beaker) - beaker_contents = "No beaker attached.
" + ui_interact(user) + +/obj/machinery/reagentgrinder/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "ReagentGrinder", name, 400, 500, master_ui, state) + ui.open() + +/obj/machinery/reagentgrinder/ui_data(mob/user) + var/list/data = list() + data["operating"] = operating + data["inactive"] = length(holdingitems) == 0 ? TRUE : FALSE + data["limit"] = limit + data["count"] = length(holdingitems) + data["beaker_loaded"] = beaker ? TRUE : FALSE + data["beaker_current_volume"] = beaker ? beaker.reagents.total_volume : null + data["beaker_max_volume"] = beaker ? beaker.reagents.maximum_volume : null + var/list/beakerContents = list() + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + data["beaker_contents"] = beakerContents + + + var/list/items_counts = list() + var/list/name_overrides = list() + for(var/obj/O in holdingitems) + var/display_name = O.name + if(istype(O, /obj/item/stack)) + var/obj/item/stack/S = O + if(!items_counts[display_name]) + items_counts[display_name] = 0 + if(S.singular_name) + name_overrides[display_name] = S.singular_name + else + name_overrides[display_name] = display_name + if(S.amount > 1) + name_overrides[display_name] = "[name_overrides[display_name]]s" //name_overrides[display_name] Will be set on the first time as the singular form + + items_counts[display_name] += S.amount + continue + + else if(istype(O, /obj/item/reagent_containers/food)) + var/obj/item/reagent_containers/food/food = O + if(!items_counts[display_name]) + if(food.ingredient_name) + name_overrides[display_name] = food.ingredient_name + else + name_overrides[display_name] = display_name + else + if(food.ingredient_name_plural) + name_overrides[display_name] = food.ingredient_name_plural + else if(items_counts[display_name] == 1) // Must only add "s" once or you get stuff like "eggsssss" + name_overrides[display_name] = "[name_overrides[display_name]]s" //name_overrides[display_name] Will be set on the first time as the singular form + + items_counts[display_name]++ + + data["contents"] = list() + for(var/item in items_counts) + var/N = items_counts[item] + var/units + if(!(item in name_overrides)) + units = "[lowertext(item)]" else - is_beaker_ready = 1 - beaker_contents = "The beaker contains:
" - var/anything = 0 - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = 1 - beaker_contents += "[R.volume] - [R.name]
" - if(!anything) - beaker_contents += "Nothing
" - - - dat = {" - Processing chamber contains:
- [processing_chamber]
- [beaker_contents]
- "} - if(is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
" - dat += "Juice the reagents

" - if(holdingitems && holdingitems.len > 0) - dat += "Eject the reagents
" - if(beaker) - dat += "Detach the beaker
" - else - dat += "Please wait..." + units = "[name_overrides[item]]" - var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open(1) - return + var/list/data_pr = list( + "name" = capitalize(item), + "amount" = N, + "units" = units + ) -/obj/machinery/reagentgrinder/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - if(operating) - updateUsrDialog() + data["contents"] += list(data_pr) + return data + +/obj/machinery/reagentgrinder/ui_act(action, params, datum/tgui/ui) + . = ..() + if(.) return - switch(href_list["action"]) + + switch(action) + if("detach") + detach(ui.user) + if("eject") + eject(ui.user) if("grind") grind() if("juice") juice() - if("eject") - eject() - if("detach") - detach() -/obj/machinery/reagentgrinder/proc/detach() - if(usr.stat != 0) +/obj/machinery/reagentgrinder/proc/detach(mob/user) + if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) return if(!beaker) return - beaker.loc = src.loc + beaker.forceMove(loc) beaker = null update_icon(UPDATE_ICON_STATE) - updateUsrDialog() + SStgui.update_uis(src) -/obj/machinery/reagentgrinder/proc/eject() - if(usr.stat != 0) +/obj/machinery/reagentgrinder/proc/eject(mob/user) + if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) return if(holdingitems && holdingitems.len == 0) return for(var/obj/item/O in holdingitems) - O.loc = src.loc + O.forceMove(loc) holdingitems -= O holdingitems = list() - updateUsrDialog() + SStgui.update_uis(src) /obj/machinery/reagentgrinder/proc/is_allowed(obj/item/reagent_containers/O) for (var/i in blend_items) @@ -375,11 +398,11 @@ var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking operating = TRUE - updateUsrDialog() + SStgui.update_uis(src) spawn(50) pixel_x = initial(pixel_x) //return to its spot after shaking operating = FALSE - updateUsrDialog() + SStgui.update_uis(src) //Snacks for (var/obj/item/reagent_containers/food/snacks/O in holdingitems) @@ -413,11 +436,11 @@ var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking operating = TRUE - updateUsrDialog() + SStgui.update_uis(src) spawn(60) pixel_x = initial(pixel_x) //return to its spot after shaking operating = FALSE - updateUsrDialog() + SStgui.update_uis(src) //Snacks and Plants for (var/obj/item/reagent_containers/food/snacks/O in holdingitems) diff --git a/tgui/packages/tgui/interfaces/Biogenerator.js b/tgui/packages/tgui/interfaces/Biogenerator.js index a7a173be57d8..f9ce289712f4 100644 --- a/tgui/packages/tgui/interfaces/Biogenerator.js +++ b/tgui/packages/tgui/interfaces/Biogenerator.js @@ -8,18 +8,18 @@ import { Collapsible, NumberInput, ProgressBar, - Dimmer, } from '../components'; import { Window } from '../layouts'; +import { Operating } from '../interfaces/common/Operating'; export const Biogenerator = (props, context) => { - const { data } = useBackend(context); - const { container } = data; - + const { data, config } = useBackend(context); + const { container, processing } = data; + const { title } = config; return ( - + {!container ? : } @@ -48,25 +48,6 @@ const MissingContainer = (props, context) => { ); }; -const Processing = (props, context) => { - const { data } = useBackend(context); - const { processing } = data; - - if (processing) { - return ( - - - - -
- The biogenerator is processing... -
-
-
- ); - } -}; - const Storage = (props, context) => { const { act, data } = useBackend(context); const { diff --git a/tgui/packages/tgui/interfaces/KitchenMachine.js b/tgui/packages/tgui/interfaces/KitchenMachine.js index fa453213ffda..9f0d9c5b4da8 100644 --- a/tgui/packages/tgui/interfaces/KitchenMachine.js +++ b/tgui/packages/tgui/interfaces/KitchenMachine.js @@ -1,10 +1,12 @@ import { useBackend } from '../backend'; import { Button, Section, Table, Flex, Icon, Dimmer } from '../components'; import { Window } from '../layouts'; +import { Operating } from '../interfaces/common/Operating'; export const KitchenMachine = (props, context) => { - const { data } = useBackend(context); - const { ingredients } = data; + const { data, config } = useBackend(context); + const { ingredients, operating } = data; + const { title } = config; return ( @@ -13,7 +15,7 @@ export const KitchenMachine = (props, context) => { display="flex" className="Layout__content--flexColumn" > - +
@@ -71,22 +73,3 @@ const KitchenTop = (props, context) => { ); }; - -const Operating = (props, context) => { - const { data } = useBackend(context); - const { operating, name } = data; - - if (operating) { - return ( - - - - -
- The {name} is processing... -
-
-
- ); - } -}; diff --git a/tgui/packages/tgui/interfaces/ReagentGrinder.js b/tgui/packages/tgui/interfaces/ReagentGrinder.js new file mode 100644 index 000000000000..07689e887608 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ReagentGrinder.js @@ -0,0 +1,138 @@ +import { useBackend } from '../backend'; +import { Box, Button, Section, Table, Flex } from '../components'; +import { Window } from '../layouts'; +import { BeakerContents } from '../interfaces/common/BeakerContents'; +import { Operating } from '../interfaces/common/Operating'; + +export const ReagentGrinder = (props, context) => { + const { act, data, config } = useBackend(context); + const { operating } = data; + const { title } = config; + return ( + + + + + + + + + ); +}; + +const GrinderControls = (props, context) => { + const { act, data } = useBackend(context); + const { inactive } = data; + + return ( +
+ + +
+ ); +}; + +const GrinderContents = (props, context) => { + const { act, data } = useBackend(context); + const { contents, limit, count, inactive } = data; + + return ( +
+ + {count} / {limit} items + +
+ {contents.map((content) => ( + + + + + ))} +
+ {content.name} + + + {content.amount} {content.units} + +
+
+ ); +}; + +const GrinderReagents = (props, context) => { + const { act, data } = useBackend(context); + const { + beaker_loaded, + beaker_current_volume, + beaker_max_volume, + beaker_contents, + } = data; + + return ( +
+ + {beaker_current_volume} / {beaker_max_volume} units + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/common/Operating.js b/tgui/packages/tgui/interfaces/common/Operating.js new file mode 100644 index 000000000000..373bb26879f6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/common/Operating.js @@ -0,0 +1,34 @@ +import { Flex, Icon, Dimmer } from '../../components'; +const PropTypes = require('prop-types'); + +/** + * Shows a spinner while a machine is processing + * @property {object} props + */ +export const Operating = (props) => { + const { operating, name } = props; + if (operating) { + return ( + + + + +
+ The {name} is processing... +
+
+
+ ); + } +}; + +Operating.propTypes = { + /** + * Is the machine currently operating + */ + operating: PropTypes.bool, + /** + * The name of the machine + */ + name: PropTypes.string, +}; diff --git a/tgui/packages/tgui/public/tgui.bundle.js b/tgui/packages/tgui/public/tgui.bundle.js index c5f532ec36d5..a6a642e31b4c 100644 --- a/tgui/packages/tgui/public/tgui.bundle.js +++ b/tgui/packages/tgui/public/tgui.bundle.js @@ -1,5 +1,5 @@ -!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=231)}([function(e,t,n){"use strict";t.__esModule=!0;var o=n(233);Object.keys(o).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===o[e]||(t[e]=o[e]))}))},function(e,t,n){"use strict";t.__esModule=!0,t.useSharedState=t.useLocalState=t.useBackend=t.deleteLocalState=t.backendUpdate=t.backendSetSharedState=t.backendReducer=t.backendDeleteSharedState=void 0;var o=n(32),r=n(43);t.backendUpdate=function(e){return{type:"backend/update",payload:e}};var a=function(e,t){return{type:"backend/setSharedState",payload:{key:e,nextState:t}}};t.backendSetSharedState=a;var c=function(e){return{type:"backend/deleteSharedState",payload:e}};t.backendDeleteSharedState=c;t.backendReducer=function(e,t){var n=t.type,o=t.payload;if("backend/update"===n){var a=Object.assign({},e.config,o.config),c=Object.assign({},e.data,o.static_data,o.data),i=Object.assign({},e.shared);if(o.shared)for(var l=0,d=Object.keys(o.shared);l1?n-1:0),r=1;rn?n:e};t.clamp01=function(e){return e<0?0:e>1?1:e};t.scale=function(e,t,n){return(e-t)/(n-t)};t.round=function(e,t){return!e||isNaN(e)?e:(t|=0,a=(e*=n=Math.pow(10,t))>0|-(e<0),r=Math.abs(e%1)>=.4999999999854481,o=Math.floor(e),r&&(e=o+(a>0)),(r?e:Math.round(e))/n);var n,o,r,a};t.toFixed=function(e,t){return void 0===t&&(t=0),Number(e).toFixed(Math.max(t,0))};var o=function(e,t){return t&&e>=t[0]&&e<=t[1]};t.inRange=o;t.keyOfMatchingRange=function(e,t){for(var n=0,r=Object.keys(t);n0&&(t.style=l),t};t.computeBoxProps=N;var b=function(e){var t=e.textColor||e.color,n=e.backgroundColor;return(0,o.classes)([u(t)&&"color-"+t,u(n)&&"color-bg-"+n])};t.computeBoxClassName=b;var V=function(e){var t=e.as,n=void 0===t?"div":t,o=e.className,c=e.children,l=function(e,t){if(null==e)return{};var n,o,r={},a=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,i);if("function"==typeof c)return c(N(e));var d="string"==typeof o?o+" "+b(l):b(l),u=N(l);return(0,r.createVNode)(a.VNodeFlags.HtmlElement,n,d,c,a.ChildFlags.UnknownChildren,u)};t.Box=V,V.defaultHooks=o.pureComponentHooks},function(e,t,n){"use strict";function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}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 r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n",apos:"'"};return e.replace(/
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/&#?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/&#x?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";var o=n(41);e.exports=function(e){return o(e.length)}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=n(49),c=n(130),i=n(128);e.exports=function(e,t,n,l){var d=!!l&&!!l.unsafe,u=!!l&&!!l.enumerable,s=!!l&&!!l.noTargetGet,m=l&&l.name!==undefined?l.name:t;return r(n)&&c(n,m,l),e===o?(u?e[t]=n:i(t,n),e):(d?!s&&e[t]&&(u=!0):delete e[t],u?e[t]=n:a(e,t,n),e)}},function(e,t,n){"use strict";var o=n(60),r=n(7),a=n(85),c=n(19),i=n(23),l=n(91),d=r([].push),u=function(e){var t=1==e,n=2==e,r=3==e,u=4==e,s=6==e,m=7==e,p=5==e||s;return function(h,f,C,N){for(var b,V,g=c(h),v=a(g),y=o(f,C),_=i(v),x=0,k=N||l,L=t?k(h,_):n||m?k(h,0):undefined;_>x;x++)if((p||x in v)&&(V=y(b=v[x],x,g),e))if(t)L[x]=V;else if(V)switch(e){case 3:return!0;case 5:return b;case 6:return x;case 2:d(L,b)}else switch(e){case 4:return!1;case 7:d(L,b)}return s?-1:r||u?u:L}};e.exports={forEach:u(0),map:u(1),filter:u(2),some:u(3),every:u(4),find:u(5),findIndex:u(6),filterReject:u(7)}},function(e,t,n){"use strict";var o=n(8),r=n(14),a=n(100),c=n(64),i=n(30),l=n(56),d=n(18),u=n(173),s=Object.getOwnPropertyDescriptor;t.f=o?s:function(e,t){if(e=i(e),t=l(t),u)try{return s(e,t)}catch(n){}if(d(e,t))return c(!r(a.f,e,t),e[t])}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=n(71),c=o.TypeError;e.exports=function(e){if(r(e))return e;throw c(a(e)+" is not a function")}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=function(e){return r(e)?e:undefined};e.exports=function(e,t){return arguments.length<2?a(o[e]):o[e]&&o[e][t]}},function(e,t,n){"use strict";t.__esModule=!0,t.modalRegisterBodyOverride=t.modalOpen=t.modalClose=t.modalAnswer=t.ComplexModal=void 0;var o=n(0),r=n(1),a=n(2),c={};t.modalOpen=function(e,t,n){var o=(0,r.useBackend)(e),a=o.act,c=o.data,i=Object.assign(c.modal?c.modal.args:{},n||{});a("modal_open",{id:t,arguments:JSON.stringify(i)})};t.modalRegisterBodyOverride=function(e,t){c[e]=t};var i=function(e,t,n,o){var a=(0,r.useBackend)(e),c=a.act,i=a.data;if(i.modal){var l=Object.assign(i.modal.args||{},o||{});c("modal_answer",{id:t,answer:n,arguments:JSON.stringify(l)})}};t.modalAnswer=i;var l=function(e,t){(0,(0,r.useBackend)(e).act)("modal_close",{id:t})};t.modalClose=l;t.ComplexModal=function(e,t){var n=(0,r.useBackend)(t).data;if(n.modal){var d,u,s=n.modal,m=s.id,p=s.text,h=s.type,f=(0,o.createComponentVNode)(2,a.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),C="auto";if(c[m])u=c[m](n.modal,t);else if("input"===h){var N=n.modal.value;d=function(e){return i(t,m,N)},u=(0,o.createComponentVNode)(2,a.Input,{value:n.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(e,t){N=t}}),f=(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,a.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),(0,o.createComponentVNode)(2,a.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){return i(t,m,N)}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]})}else if("choice"===h){var b="object"==typeof n.modal.choices?Object.values(n.modal.choices):n.modal.choices;u=(0,o.createComponentVNode)(2,a.Dropdown,{options:b,selected:n.modal.value,width:"100%",my:"0.5rem",onSelected:function(e){return i(t,m,e)}}),C="initial"}else"bento"===h?u=(0,o.createComponentVNode)(2,a.Flex,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:n.modal.choices.map((function(e,r){return(0,o.createComponentVNode)(2,a.Flex.Item,{flex:"1 1 auto",children:(0,o.createComponentVNode)(2,a.Button,{selected:r+1===parseInt(n.modal.value,10),onClick:function(){return i(t,m,r+1)},children:(0,o.createVNode)(1,"img",null,null,1,{src:e})})},r)}))}):"boolean"===h&&(f=(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,a.Button,{icon:"times",content:n.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){return i(t,m,0)}}),(0,o.createComponentVNode)(2,a.Button,{icon:"check",content:n.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){return i(t,m,1)}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]}));return(0,o.createComponentVNode)(2,a.Modal,{maxWidth:e.maxWidth||window.innerWidth/2+"px",maxHeight:e.maxHeight||window.innerHeight/2+"px",onEnter:d,mx:"auto",overflowY:C,children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:p}),u,f]})}}},function(e,t,n){"use strict";var o=n(85),r=n(31);e.exports=function(e){return o(r(e))}},function(e,t,n){"use strict";var o=n(5).TypeError;e.exports=function(e){if(e==undefined)throw o("Can't call method on "+e);return e}},function(e,t,n){"use strict";function o(e,t,n,o,r,a,c){try{var i=e[a](c),l=i.value}catch(d){return void n(d)}i.done?t(l):Promise.resolve(l).then(o,r)}t.__esModule=!0,t.winset=t.winget=t.runCommand=t.callByondAsync=t.callByond=t.IS_IE8=void 0;var r=window.Byond,a=function(){var e=navigator.userAgent.match(/Trident\/(\d+).+?;/i);if(!e)return null;var t=e[1];return t?parseInt(t,10):null}(),c=null!==a&&a<=6;t.IS_IE8=c;var i=function(e,t){void 0===t&&(t={}),r.call(e,t)};t.callByond=i;var l=function(e,t){void 0===t&&(t={}),window.__callbacks__=window.__callbacks__||[];var n=window.__callbacks__.length,o=new Promise((function(e){window.__callbacks__.push(e)}));return r.call(e,Object.assign({},t,{callback:"__callbacks__["+n+"]"})),o};t.callByondAsync=l;t.runCommand=function(e){return i("winset",{command:e})};var d=function(){var e,t=(e=regeneratorRuntime.mark((function n(e,t){var o;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,l("winget",{id:e,property:t});case 2:return o=n.sent,n.abrupt("return",o[t]);case 4:case"end":return n.stop()}}),n)})),function(){var t=this,n=arguments;return new Promise((function(r,a){var c=e.apply(t,n);function i(e){o(c,r,a,i,l,"next",e)}function l(e){o(c,r,a,i,l,"throw",e)}i(undefined)}))});return function(e,n){return t.apply(this,arguments)}}();t.winget=d;t.winset=function(e,t,n){var o;return i("winset",((o={})[e+"."+t]=n,o))}},function(e,t,n){"use strict";t.__esModule=!0,t.zipWith=t.zip=t.uniqBy=t.toKeyedArray=t.toArray=t.sortBy=t.reduce=t.map=t.filter=void 0;t.toArray=function(e){if(Array.isArray(e))return e;if("object"==typeof e){var t=Object.prototype.hasOwnProperty,n=[];for(var o in e)t.call(e,o)&&n.push(e[o]);return n}return[]};t.toKeyedArray=function(e,t){return void 0===t&&(t="key"),o((function(e,n){var o;return Object.assign(((o={})[t]=n,o),e)}))(e)};t.filter=function(e){return function(t){if(null===t&&t===undefined)return t;if(Array.isArray(t)){for(var n=[],o=0;oi)return 1}return 0};t.sortBy=function(){for(var e=arguments.length,t=new Array(e),n=0;n"+l+""}},function(e,t,n){"use strict";var o=n(6);e.exports=function(e){return o((function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}))}},function(e,t,n){"use strict";t.__esModule=!0,t.computeFlexProps=t.computeFlexItemProps=t.FlexItem=t.Flex=void 0;var o=n(0),r=n(10),a=n(32),c=n(21),i=["className","direction","wrap","align","alignContent","justify","inline","spacing","spacingPrecise"],l=["className","grow","order","shrink","basis","align"];function d(e,t){if(null==e)return{};var n,o,r={},a=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var u=function(e){var t=e.className,n=e.direction,o=e.wrap,c=e.align,l=e.alignContent,u=e.justify,s=e.inline,m=e.spacing,p=void 0===m?0:m,h=e.spacingPrecise,f=void 0===h?0:h,C=d(e,i);return Object.assign({className:(0,r.classes)(["Flex",a.IS_IE8&&("column"===n?"Flex--ie8--column":"Flex--ie8"),s&&"Flex--inline",p>0&&"Flex--spacing--"+p,f>0&&"Flex--spacingPrecise--"+f,t]),style:Object.assign({},C.style,{"flex-direction":n,"flex-wrap":o,"align-items":c,"align-content":l,"justify-content":u})},C)};t.computeFlexProps=u;var s=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,c.Box,Object.assign({},u(e))))};t.Flex=s,s.defaultHooks=r.pureComponentHooks;var m=function(e){var t=e.className,n=e.grow,o=e.order,i=e.shrink,u=e.basis,s=void 0===u?e.width:u,m=e.align,p=d(e,l);return Object.assign({className:(0,r.classes)(["Flex__item",a.IS_IE8&&"Flex__item--ie8",t]),style:Object.assign({},p.style,{"flex-grow":n,"flex-shrink":i,"flex-basis":(0,c.unit)(s),order:o,"align-self":m})},p)};t.computeFlexItemProps=m;var p=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,c.Box,Object.assign({},m(e))))};t.FlexItem=p,p.defaultHooks=r.pureComponentHooks,s.Item=p},function(e,t,n){"use strict";var o,r,a,c=n(175),i=n(5),l=n(7),d=n(11),u=n(49),s=n(18),m=n(127),p=n(102),h=n(87),f=i.TypeError,C=i.WeakMap;if(c||m.state){var N=m.state||(m.state=new C),b=l(N.get),V=l(N.has),g=l(N.set);o=function(e,t){if(V(N,e))throw new f("Object already initialized");return t.facade=e,g(N,e,t),t},r=function(e){return b(N,e)||{}},a=function(e){return V(N,e)}}else{var v=p("state");h[v]=!0,o=function(e,t){if(s(e,v))throw new f("Object already initialized");return t.facade=e,u(e,v,t),t},r=function(e){return s(e,v)?e[v]:{}},a=function(e){return s(e,v)}}e.exports={set:o,get:r,has:a,enforce:function(e){return a(e)?r(e):o(e,{})},getterFor:function(e){return function(t){var n;if(!d(t)||(n=r(t)).type!==e)throw f("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";var o=Math.ceil,r=Math.floor;e.exports=function(e){var t=+e;return t!=t||0===t?0:(t>0?r:o)(t)}},function(e,t,n){"use strict";var o=n(40),r=Math.min;e.exports=function(e){return e>0?r(o(e),9007199254740991):0}},function(e,t,n){"use strict";var o=n(5),r=n(18),a=n(12),c=n(19),i=n(102),l=n(140),d=i("IE_PROTO"),u=o.Object,s=u.prototype;e.exports=l?u.getPrototypeOf:function(e){var t=c(e);if(r(t,d))return t[d];var n=t.constructor;return a(n)&&t instanceof n?n.prototype:t instanceof u?s:null}},function(e,t,n){"use strict";t.__esModule=!0,t.timeAgo=t.getGasLabel=t.getGasColor=t.UI_UPDATE=t.UI_INTERACTIVE=t.UI_DISABLED=t.UI_CLOSE=t.RADIO_CHANNELS=t.CSS_COLORS=t.COLORS=void 0;t.UI_INTERACTIVE=2;t.UI_UPDATE=1;t.UI_DISABLED=0;t.UI_CLOSE=-1;t.COLORS={department:{command:"#526aff",security:"#CF0000",medical:"#009190",science:"#993399",engineering:"#A66300",supply:"#9F8545",service:"#80A000",centcom:"#78789B",other:"#C38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}};t.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"];t.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Procedure",freq:1339,color:"#F70285"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}];var o=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"},{id:"ab",name:"Agent B",label:"Agent B",color:"purple"}];t.getGasLabel=function(e,t){var n=String(e).toLowerCase(),r=o.find((function(e){return e.id===n||e.name.toLowerCase()===n}));return r&&r.label||t||e};t.getGasColor=function(e){var t=String(e).toLowerCase(),n=o.find((function(e){return e.id===t||e.name.toLowerCase()===t}));return n&&n.color};t.timeAgo=function(e,t){if(e>t)return"in the future";var n=(t/=10)-(e/=10);if(n>3600){var o=Math.round(n/3600);return o+" hour"+(1===o?"":"s")+" ago"}if(n>60){var r=Math.round(n/60);return r+" minute"+(1===r?"":"s")+" ago"}var a=Math.round(n);return a+" second"+(1===a?"":"s")+" ago"}},function(e,t,n){"use strict";t.__esModule=!0,t.LabeledListItem=t.LabeledListDivider=t.LabeledList=void 0;var o=n(0),r=n(10),a=n(21),c=n(221),i=["className","label","labelColor","color","textAlign","verticalAlign","buttons","content","children","noColon"];var l=function(e){var t=e.children;return(0,o.createVNode)(1,"table","LabeledList",t,0)};t.LabeledList=l,l.defaultHooks=r.pureComponentHooks;var d=function(e){var t=e.className,n=e.label,c=e.labelColor,l=void 0===c?"label":c,d=e.color,u=e.textAlign,s=e.verticalAlign,m=e.buttons,p=e.content,h=e.children,f=e.noColon,C=void 0!==f&&f,N=function(e,t){if(null==e)return{};var n,o,r={},a=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,i),b=C?"":":";return(0,o.createVNode)(1,"tr",(0,r.classes)(["LabeledList__row",t]),[(0,o.createComponentVNode)(2,a.Box,{as:"td",color:l,verticalAlign:s,className:(0,r.classes)(["LabeledList__cell","LabeledList__label"]),children:n?n+b:null}),(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Box,Object.assign({as:"td",color:d,textAlign:u,verticalAlign:s,className:(0,r.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:m?undefined:2},N,{children:[p,h]}))),m&&(0,o.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",m,0)],0)};t.LabeledListItem=d,d.defaultHooks=r.pureComponentHooks;var u=function(e){var t=e.size?(0,a.unit)(Math.max(0,e.size-1)):0;return(0,o.createVNode)(1,"tr","LabeledList__row",(0,o.createVNode)(1,"td",null,(0,o.createComponentVNode)(2,c.Divider),2,{colSpan:3,style:{"padding-top":t,"padding-bottom":t}}),2)};t.LabeledListDivider=u,u.defaultHooks=r.pureComponentHooks,l.Item=d,l.Divider=u},function(e,t,n){"use strict";var o=n(7),r=o({}.toString),a=o("".slice);e.exports=function(e){return a(r(e),8,-1)}},function(e,t,n){"use strict";var o=n(7);e.exports=o({}.isPrototypeOf)},function(e,t,n){"use strict";var o=n(84),r=Function.prototype,a=r.apply,c=r.call;e.exports="object"==typeof Reflect&&Reflect.apply||(o?c.bind(a):function(){return c.apply(a,arguments)})},function(e,t,n){"use strict";var o=n(28);e.exports=o("navigator","userAgent")||""},function(e,t,n){"use strict";var o=n(8),r=n(17),a=n(64);e.exports=o?function(e,t,n){return r.f(e,t,a(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";var o=n(40),r=Math.max,a=Math.min;e.exports=function(e,t){var n=o(e);return n<0?r(n+t,0):a(n,t)}},function(e,t,n){"use strict";var o,r=n(9),a=n(134),c=n(132),i=n(87),l=n(178),d=n(129),u=n(102),s=u("IE_PROTO"),m=function(){},p=function(e){return"