From e36f09d01cae82df753db1c0eb9322225c69c62a Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Sat, 13 Apr 2024 14:24:58 -0400 Subject: [PATCH 1/6] ci: pull tg maplint identical atom support, add and fix matching cables lint (#25051) --- .../RandomRuins/SpaceRuins/meatpackers.dmm | 5 --- .../RandomRuins/SpaceRuins/onehalf.dmm | 38 +------------------ .../map_files/RandomRuins/SpaceRuins/ussp.dmm | 37 +++++++----------- _maps/map_files/generic/Lavaland.dmm | 5 --- .../maplint/lints/stacked_matching_cables.yml | 4 ++ tools/maplint/source/lint.py | 8 +++- 6 files changed, 27 insertions(+), 70 deletions(-) create mode 100644 tools/maplint/lints/stacked_matching_cables.yml diff --git a/_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm b/_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm index 6a22394fcae..067579f3be8 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm @@ -1277,10 +1277,6 @@ icon_state = "0-2" }, /obj/structure/cable, -/obj/structure/cable{ - d2 = 2; - icon_state = "0-2" - }, /turf/simulated/floor/plating, /area/ruin/unpowered/BMPship/Aft) "eg" = ( @@ -1602,7 +1598,6 @@ outputting = 0 }, /obj/structure/cable, -/obj/structure/cable, /turf/simulated/floor/plating, /area/ruin/unpowered/BMPship/Aft) "fb" = ( diff --git a/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm b/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm index 89dd8083a44..9cca10a3239 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm @@ -1136,20 +1136,6 @@ /obj/item/storage/firstaid, /turf/simulated/floor/plasteel, /area/ruin/space/onehalf/abandonedbridge) -"df" = ( -/obj/structure/lattice, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/template_noop, -/area/space/nearstation) "dg" = ( /obj/structure/girder/reinforced, /obj/item/stack/sheet/plasteel, @@ -1190,26 +1176,6 @@ /obj/effect/spawner/window/reinforced/grilled, /turf/simulated/floor/plating, /area/ruin/space/onehalf/abandonedbridge) -"dm" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - tag = "" - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - tag = "" - }, -/obj/machinery/door/poddoor/preopen{ - id_tag = "onehalf bridge"; - name = "bridge blast door" - }, -/obj/effect/spawner/window/reinforced/grilled, -/turf/simulated/floor/plating, -/area/ruin/space/onehalf/abandonedbridge) "dn" = ( /obj/effect/spawner/window/reinforced/grilled, /obj/structure/cable{ @@ -1796,7 +1762,7 @@ Ab cr cW ch -dm +dl ac aa "} @@ -1905,7 +1871,7 @@ ai ai ai cZ -df +ai ai af aa diff --git a/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm b/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm index c0a150801e6..f6febf65964 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm @@ -3010,20 +3010,6 @@ }, /turf/simulated/floor/plasteel/grimy, /area/ruin/space/derelict/crew_quarters) -"hp" = ( -/obj/machinery/power/solar, -/obj/structure/cable{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable{ - d2 = 4; - icon_state = "0-4" - }, -/turf/simulated/floor/plasteel/airless{ - icon_state = "solarpanel" - }, -/area/ruin/space/derelict/solar_control) "hq" = ( /obj/item/stack/ore/uranium, /turf/template_noop, @@ -7502,7 +7488,6 @@ "sp" = ( /obj/machinery/power/solar/fake, /obj/structure/cable, -/obj/structure/cable, /turf/simulated/floor/plasteel/airless{ icon_state = "solarpanel" }, @@ -7537,7 +7522,6 @@ /turf/template_noop, /area/ruin/space/derelict/solar_control) "st" = ( -/obj/structure/cable, /obj/machinery/power/tracker, /obj/structure/cable, /turf/simulated/floor/plasteel/airless{ @@ -7575,6 +7559,13 @@ }, /turf/simulated/wall/mineral/titanium/nodecon/nodiagonal, /area/ruin/space/derelict/arrival) +"NK" = ( +/obj/structure/cable{ + d2 = 8; + icon_state = "0-8" + }, +/turf/template_noop, +/area/template_noop) "Oh" = ( /obj/effect/spawner/airlock/w_to_e{ req_access_txt = 0 @@ -14166,7 +14157,7 @@ ac ac ac ac -ac +NK ac ac ac @@ -14356,18 +14347,18 @@ ac ac ac ac -hp -hp -hp -hp -hp +hs +hs +hs +hs +hs ac jO ac jO ag hs -hp +hs hs hs hs diff --git a/_maps/map_files/generic/Lavaland.dmm b/_maps/map_files/generic/Lavaland.dmm index 9769e9b96be..03e670f9f51 100644 --- a/_maps/map_files/generic/Lavaland.dmm +++ b/_maps/map_files/generic/Lavaland.dmm @@ -788,11 +788,6 @@ }, /area/mine/laborcamp/security) "cz" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /obj/structure/cable{ d1 = 1; d2 = 2; diff --git a/tools/maplint/lints/stacked_matching_cables.yml b/tools/maplint/lints/stacked_matching_cables.yml new file mode 100644 index 00000000000..6b041026257 --- /dev/null +++ b/tools/maplint/lints/stacked_matching_cables.yml @@ -0,0 +1,4 @@ +/obj/structure/cable: + banned_neighbors: + /obj/structure/cable: + identical: true diff --git a/tools/maplint/source/lint.py b/tools/maplint/source/lint.py index 4af9ad5c1cf..ee86d29be52 100644 --- a/tools/maplint/source/lint.py +++ b/tools/maplint/source/lint.py @@ -66,7 +66,13 @@ class BannedNeighbor: def matches(self, identified: Content, neighbor: Content): if self.identical: - return neighbor == identified + if identified.path != neighbor.path: + return False + + if identified.var_edits != neighbor.var_edits: + return False + + return True if self.typepath is not None: if self.typepath.matches_path(neighbor.path): From 1c86f0ac682e69ff2b615640f0116df286f8bb56 Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:25:50 -0500 Subject: [PATCH 2/6] severely reduces lag on some uis (#25116) * severely reduces lag on some uis * SHIP IT * Update code/modules/hydroponics/seed_extractor.dm --- code/_globalvars/lists/misc_lists.dm | 3 +++ code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm | 5 +++++ code/modules/hydroponics/gene_modder.dm | 6 +++++- code/modules/hydroponics/seed_extractor.dm | 6 +++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/code/_globalvars/lists/misc_lists.dm b/code/_globalvars/lists/misc_lists.dm index b4ac32d640c..f12c6a8271f 100644 --- a/code/_globalvars/lists/misc_lists.dm +++ b/code/_globalvars/lists/misc_lists.dm @@ -67,3 +67,6 @@ GLOBAL_LIST_EMPTY(looping_sounds) /// List of possible crits from things tipping over GLOBAL_LIST_EMPTY(tilt_crits) + +/// Stores a list of the cached seed icons. Used in the seed extractor and the gene modder +GLOBAL_LIST_EMPTY(seeds_cached_base64_icons) diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm index e0867c56652..8ddc1d8cfb3 100644 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm +++ b/code/game/objects/items/weapons/bio_chips/bio_chip_pad.dm @@ -9,6 +9,7 @@ w_class = WEIGHT_CLASS_SMALL var/obj/item/bio_chip_case/case + var/static/list/cached_base64_icons = list() /obj/item/bio_chip_pad/Destroy() if(case) @@ -80,6 +81,10 @@ data["contains_case"] = case ? TRUE : FALSE if(case && case.imp) var/datum/implant_fluff/implant_data = case.imp.implant_data + var/icon/base64icon = cached_base64_icons["[initial(case.imp.icon)][initial(case.imp.icon_state)]"] + if(!base64icon) + base64icon = "[icon2base64(icon(initial(case.imp.icon), initial(case.imp.icon_state), SOUTH, 1))]" + cached_base64_icons["[initial(case.imp.icon)][initial(case.imp.icon_state)]"] = base64icon data["implant"] = list( "name" = implant_data.name, "life" = implant_data.life, diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index 7d10426d9ed..cf66b5f57f8 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -167,8 +167,12 @@ data["seed"] = list() if(seed) + var/icon/base64icon = GLOB.seeds_cached_base64_icons["[initial(seed.icon)][initial(seed.icon_state)]"] + if(!base64icon) + base64icon = icon2base64(icon(initial(seed.icon), initial(seed.icon_state), SOUTH, 1)) + GLOB.seeds_cached_base64_icons["[initial(seed.icon)][initial(seed.icon_state)]"] = base64icon data["seed"] = list( - "image" = "[icon2base64(icon(initial(seed.icon), initial(seed.icon_state), SOUTH, 1))]", + "image" = "[base64icon]", "name" = seed.name, "variant" = seed.variant ) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 07616d4ae69..285882c39f9 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -136,8 +136,12 @@ for(var/datum/seed_pile/O in piles) var/obj/item/I = O.path + var/icon/base64icon = GLOB.seeds_cached_base64_icons["[initial(I.icon)][initial(I.icon_state)]"] + if(!base64icon) + base64icon = icon2base64(icon(initial(I.icon), initial(I.icon_state), SOUTH, 1)) + GLOB.seeds_cached_base64_icons["[initial(I.icon)][initial(I.icon_state)]"] = base64icon var/list/seed_info = list( - "image" = "[icon2base64(icon(initial(I.icon), initial(I.icon_state), SOUTH, 1))]", + "image" = "[base64icon]", "id" = O.id, "name" = O.name, "variant" = O.variant, From 0e93014f9d25621786f0b0d8c35e9c8ab83d59c7 Mon Sep 17 00:00:00 2001 From: Charlie Nolan Date: Sat, 13 Apr 2024 12:06:47 -0700 Subject: [PATCH 3/6] Mhelp/ahelp fixes. (#25122) Co-authored-by: FunnyMan3595 (Charlie Nolan) Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> --- code/modules/admin/verbs/adminpm.dm | 34 ++++++++++++++++++++------- code/modules/client/client_defines.dm | 2 +- code/modules/client/client_procs.dm | 3 +++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index cf562a6c90b..4da858daca0 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -120,7 +120,7 @@ var/datum/controller/subsystem/tickets/tickets_system // We treat PMs as mentorhelps if we were explicitly so, or if neither // party is an admin. - if(type == "Mentorhelp" || !(check_rights(R_ADMIN|R_MOD, 0, C.mob) || check_rights(R_ADMIN|R_MOD, 0, src.mob))) + if(type == "Mentorhelp" || !(check_rights(R_ADMIN|R_MOD, 0, C.mob) || check_rights(R_ADMIN|R_MOD, 0, mob))) send_span = "mentorhelp" recieve_span = "mentorhelp" message_type = MESSAGE_TYPE_MENTORPM @@ -167,22 +167,32 @@ return var/ping_link = check_rights(R_ADMIN, 0, mob) ? "(PING)" : "" - var/window_link = "(WINDOW)" + var/ticket_link var/alert_link = check_rights(R_ADMIN, FALSE, mob) ? "(ALERT)" : "" if(ticket_id != -1) if(message_type == MESSAGE_TYPE_MENTORPM) - window_link = "(TICKET)" + ticket_link = "(TICKET)" else - window_link = "(TICKET)" + ticket_link = "(TICKET)" var/emoji_msg = "[msg]" - recieve_message = "[type] from-[recieve_pm_type] [C.holder ? key_name(src, TRUE, type, ticket_id = ticket_id) : key_name_hidden(src, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg][C.holder ? "
[ping_link] [window_link] [alert_link]" : ""]
" + var/recieve_window_link = "(WINDOW)" + if(message_type == MESSAGE_TYPE_MENTORPM && check_rights(R_ADMIN|R_MENTOR, 0, C.mob)) + recieve_window_link = ticket_link + else if(message_type == MESSAGE_TYPE_ADMINPM && check_rights(R_ADMIN, 0, C.mob)) + recieve_window_link = ticket_link + recieve_message = "[type] from-[recieve_pm_type] [C.holder ? key_name(src, TRUE, type, ticket_id = ticket_id) : key_name_hidden(src, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg][C.holder ? "
[ping_link] [recieve_window_link] [alert_link]" : ""]
" if(message_type == MESSAGE_TYPE_MENTORPM) recieve_message = chat_box_mhelp(recieve_message) else recieve_message = chat_box_ahelp(recieve_message) to_chat(C, recieve_message) - var/send_message = "[send_pm_type][type] to-[holder ? key_name(C, TRUE, type, ticket_id = ticket_id) : key_name_hidden(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]

[ping_link] [window_link] [alert_link]" + var/send_window_link = "(WINDOW)" + if(message_type == MESSAGE_TYPE_MENTORPM && check_rights(R_ADMIN|R_MENTOR, 0, mob)) + send_window_link = ticket_link + else if(message_type == MESSAGE_TYPE_ADMINPM && check_rights(R_ADMIN, 0, mob)) + send_window_link = ticket_link + var/send_message = "[send_pm_type][type] to-[holder ? key_name(C, TRUE, type, ticket_id = ticket_id) : key_name_hidden(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]

[ping_link] [send_window_link] [alert_link]" if(message_type == MESSAGE_TYPE_MENTORPM) send_message = chat_box_mhelp(send_message) else @@ -191,9 +201,9 @@ var/third_party_message if(message_type == MESSAGE_TYPE_MENTORPM) - third_party_message = chat_box_mhelp("[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]->[key_name(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]
[ping_link] [window_link] [alert_link]
") + third_party_message = chat_box_mhelp("[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]->[key_name(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]
[ping_link] [ticket_link] [alert_link]
") else - third_party_message = chat_box_ahelp("[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]->[key_name(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]
[ping_link] [window_link] [alert_link]
") + third_party_message = chat_box_ahelp("[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]->[key_name(C, TRUE, type, ticket_id = ticket_id)]:

[emoji_msg]
[ping_link] [ticket_link] [alert_link]
") //play the recieving admin the adminhelp sound (if they have them enabled) //non-admins always hear the sound, as they cannot toggle it @@ -287,6 +297,7 @@ target.pm_tracker.show_ui(target.mob) /datum/pm_tracker + var/ckey var/current_title = "" var/open = FALSE var/list/datum/pm_convo/pms = list() @@ -294,6 +305,9 @@ var/window_id = "pms_window" var/forced = FALSE +/datum/pm_tracker/New(ckey_in) + ckey = ckey_in + /datum/pm_convo var/list/messages = list() var/archived = FALSE @@ -326,6 +340,10 @@ show_ui(user) /datum/pm_tracker/proc/show_ui(mob/user) + // Please do not open someone else's PMs, that makes them not very private. + if(user.ckey != ckey) + return + var/dat = "" // If it was forced open, make them use a special close button that alerts admins to closure diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 31edadc979f..aa06fa2055c 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -11,7 +11,7 @@ var/last_message = "" //contains the last message sent by this client - used to protect against copy-paste spamming. var/last_message_count = 0 //contains a number of how many times a message identical to last_message was sent. var/last_message_time = 0 //holds the last time (based on world.time) a message was sent - var/datum/pm_tracker/pm_tracker = new() + var/datum/pm_tracker/pm_tracker ///////// //OTHER// diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index d2412ed6d54..0ad98f3ae25 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -262,6 +262,9 @@ stat_panel = new(src, "statbrowser") stat_panel.subscribe(src, PROC_REF(on_stat_panel_message)) + // Create a PM tracker bound to this ckey. + pm_tracker = new(ckey) + tgui_panel = new(src, "browseroutput") tgui_say = new(src, "tgui_say") TopicData = null //Prevent calls to client.Topic from connect From c73443bc4790cc187ac259b7161b1544a818b8a3 Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Sun, 14 Apr 2024 04:49:49 +0200 Subject: [PATCH 4/6] Badass people can now execute again (#25109) * Badass people can now execute * Move comment --- code/modules/projectiles/gun.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index ed3abfcfec5..6b52313e991 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -171,13 +171,12 @@ if(flag) if(user.zone_selected == "mouth") - if(HAS_TRAIT(user, TRAIT_BADASS)) + if(target == user && HAS_TRAIT(user, TRAIT_BADASS)) // Check if we are blowing smoke off of our own gun, otherwise we are trying to execute someone user.visible_message("[user] blows smoke off of [src]'s barrel. What a badass.") else handle_suicide(user, target, params) return - //Exclude lasertag guns from the CLUMSY check. if(clumsy_check) if(istype(user)) From cb03f174a01fc171f65ba0bd6790e58856dddba1 Mon Sep 17 00:00:00 2001 From: Zantox Date: Sun, 14 Apr 2024 13:35:48 +0200 Subject: [PATCH 5/6] Add unit-tests for card decks (#24791) * Add unit-tests for card decks * Fix linter CI comments * Rename unit-test file due to duplicate filename * Fix review comments * Fix unit-test broken after review comment fixing * Remove blank unit-tests for card-decks * Use TRUE instead of magic-value 1 in cardshuffle sound call Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> --------- Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> --- code/modules/games/cards.dm | 14 +++++++--- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/games/test_cards.dm | 30 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 code/modules/unit_tests/games/test_cards.dm diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index ad5e29ab160..83d32b64ac4 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -50,10 +50,16 @@ /obj/item/deck/Initialize(mapload) . = ..() + build_decks() + update_icon(UPDATE_ICON_STATE) + +/obj/item/deck/proc/build_decks() + if(length(cards)) + // prevent building decks more than once + return for(var/deck in 1 to deck_size) build_deck() deck_total = length(cards) - update_icon(UPDATE_ICON_STATE) /obj/item/deck/proc/build_deck() return @@ -227,8 +233,10 @@ var/mob/living/user = usr if(cooldown < world.time - 1 SECONDS) cards = shuffle(cards) - user.visible_message("[user] shuffles [src].") - playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) + + if(user) + user.visible_message("[user] shuffles [src].") + playsound(user, 'sound/items/cardshuffle.ogg', 50, TRUE) cooldown = world.time diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 7f234307d41..76f2504ef03 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -2,6 +2,7 @@ //Keep this sorted alphabetically #ifdef UNIT_TESTS +#include "games\test_cards.dm" #include "jobs\test_job_globals.dm" #include "aicard_icons.dm" #include "announcements.dm" diff --git a/code/modules/unit_tests/games/test_cards.dm b/code/modules/unit_tests/games/test_cards.dm new file mode 100644 index 00000000000..bde0b9f1f8b --- /dev/null +++ b/code/modules/unit_tests/games/test_cards.dm @@ -0,0 +1,30 @@ +/datum/unit_test/card_deck/proc/validate_deck(obj/item/deck/deck) + var/list/card_count = list() + for(var/datum/playingcard/card in deck.cards) + if(card_count[card.name] == null) + card_count[card.name] = 1 + else if(card.name == "Joker") + card_count[card.name]++ + else + // duplicate card in deck + return FALSE + + if(length(card_count) != 53) // 2 Jokers, so 53 unique cards + return FALSE + return TRUE + + +/datum/unit_test/card_deck/Run() + // setup + var/loc = pick(block(run_loc_bottom_left, run_loc_top_right)) + var/obj/item/deck/cards/cards = new /obj/item/deck/cards(loc) + cards.build_decks() + + // is deck proper upon spawning + if(!validate_deck(cards)) + Fail("52 card deck not initialized correctly.") + + // is deck proper after shuffling + cards.deckshuffle() + if(!validate_deck(cards)) + Fail("52 card deck broken after shuffling.") From 95efc8fbda7ae52d83b7f5169746d5134a5c0eaf Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Sun, 14 Apr 2024 15:21:44 -0500 Subject: [PATCH 6/6] fix for the worlds shittiest exploit (#25130) --- code/game/machinery/doors/airlock.dm | 2 ++ code/game/machinery/doors/airlock_electronics.dm | 3 ++- code/game/objects/structures/displaycase.dm | 9 ++++++--- code/game/objects/structures/door_assembly.dm | 9 ++++++--- code/game/objects/structures/windoor_assembly.dm | 11 +++++++---- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index a51f7aadade..2f2c4ce3229 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1552,10 +1552,12 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays) ae.selected_accesses = req_one_access ae.one_access = 1 ae.unres_access_from = unres_sides + ae.is_installed = FALSE else ae = electronics electronics = null ae.forceMove(loc) + ae.is_installed = FALSE QDEL_LIST_CONTENTS(fillers) qdel(src) diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 070c29e377d..3b9da5c1be5 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -18,6 +18,8 @@ var/const/max_brain_damage = 60 /// Which direction has unrestricted access to the airlock (e.g. medbay doors from the inside) var/unres_access_from = null + /// Is this electronic installed in a door? + var/is_installed = FALSE /obj/item/airlock_electronics/Initialize(mapload) . = ..() @@ -38,7 +40,6 @@ return ui_interact(user) - // tgui\packages\tgui\interfaces\AirlockElectronics.js /obj/item/airlock_electronics/ui_state(mob/user) return GLOB.inventory_state diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index bf94750fbae..4a11d6cc15d 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -207,10 +207,12 @@ to_chat(user, "You start installing the electronics into [src]...") playsound(loc, I.usesound, 50, 1) if(do_after(user, 30, target = src)) - if(user.drop_item()) - I.forceMove(src) - electronics = I + var/obj/item/airlock_electronics/new_electronics = I + if(user.drop_item() && !new_electronics.is_installed) + new_electronics.forceMove(src) + electronics = new_electronics to_chat(user, "You install the airlock electronics.") + electronics.is_installed = TRUE else if(istype(I, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = I @@ -241,6 +243,7 @@ if(I.use_tool(src, user, 0, volume = I.tool_volume)) to_chat(user, "You remove the airlock electronics.") new /obj/item/airlock_electronics(drop_location(), 1) + electronics.is_installed = FALSE electronics = null /obj/structure/displaycase_chassis/wrench_act(mob/user, obj/item/I) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index fdfe4194b5a..6e3bcbd9171 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -82,14 +82,16 @@ user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...") if(do_after(user, 40 * W.toolspeed, target = src)) - if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) + var/obj/item/airlock_electronics/new_electronics = W + if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS || new_electronics.is_installed) return user.drop_item() - W.forceMove(src) + new_electronics.forceMove(src) to_chat(user, "You install the airlock electronics.") state = AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER name = "near finished airlock assembly" - electronics = W + electronics = new_electronics + electronics.is_installed = TRUE else if(istype(W, /obj/item/stack/sheet) && (!glass || !mineral)) var/obj/item/stack/sheet/S = W @@ -137,6 +139,7 @@ ae = electronics electronics = null ae.forceMove(loc) + ae.is_installed = FALSE update_appearance(UPDATE_NAME | UPDATE_OVERLAYS) /obj/structure/door_assembly/screwdriver_act(mob/user, obj/item/I) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 09f57dede18..6c34c677f50 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -155,16 +155,18 @@ user.visible_message("[user] installs the electronics into the windoor assembly.", "You start to install electronics into the windoor assembly...") user.drop_item() W.forceMove(src) + var/obj/item/airlock_electronics/new_electronics = W - if(do_after(user, 40 * W.toolspeed, target = src)) + if(do_after(user, 40 * new_electronics.toolspeed, target = src) && !new_electronics.is_installed) if(!src || electronics) - W.forceMove(loc) + new_electronics.forceMove(loc) return to_chat(user, "You install the windoor electronics.") name = "near finished windoor assembly" - electronics = W + electronics = new_electronics + electronics.is_installed = TRUE else - W.forceMove(loc) + new_electronics.forceMove(loc) else if(is_pen(W)) var/t = rename_interactive(user, W) @@ -247,6 +249,7 @@ ae = electronics electronics = null ae.forceMove(loc) + ae.is_installed = FALSE /obj/structure/windoor_assembly/wirecutter_act(mob/user, obj/item/I) if(state != WIRED_ASSEMBLY)