From 05b7ce90ffcb2c45d59e2a929aaef928bf71f3a3 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Thu, 16 Apr 2026 22:29:57 -0500 Subject: [PATCH] Adds Lawyer/HoP/QM/Spy unique traitor item, the briefcase firearm mechanism (#95607) ## About The Pull Request Lawyers, Quartermasters, and Heads of Personnels can now purchase a `"Briefcase Embedded Firearm Trigger"` from the traitor uplink for 4 tc. The briefcase looks like a normal, unassuming briefcase - But when any weapon is placed inside, you gain the ability to "fire" the briefcase, which *actually* fires the weapon. Only the first weapon found is fired, even if it's empty. So while you CAN put 5 pistols inside, you'd have to cycle them in and out manually. This works with *any* weapon that can fit inside the briefcase, which essentially restricts it to pistols and some laser weapons. *No*, sniper rifles won't work in the briefcase. (You can't use it to bypass weapons that require two hands.) *Yes*, you can also handcuff the briefcase to your wrist as normal. (Who knows what this will allow.) --- Also purchaseable is an 8tc `"Briefcase Embedded Firearm (Combo Deal)"`, which comes pre-loaded with a Makarov and 0 magazines. This variant is also available to all Spies as a medium difficulty reward. --- Additionally I changed the boot-dagger's examine tell to only show to people holding the item. When I was implementing the briefcase gun I made the examine tell only show while held and I thought "well, the boot-dagger should follow the same logic". They're meant to be stealth objects so being able to figure it out from across the room feels weird. ## Why It's Good For The Game This was a random idea someone threw out that I thought fit the vibe and gameplay of traitors and spies really well. It's a very espionage-y idea, very James Bond. It will definitely catch a lot of people off guard. It basically allows the Lawyer to walk around with a pistol or revolver drawn at all times. I'm a bit worried it'll be too potent combined with handcuffs (nodrop revolver?), but the Lawyer doesn't get many Ws so maybe it's fine. ## Changelog :cl: Melbert add: Traitor Lawyers, Quartermasters, and Heads of Personnels can now purchase a "Briefcase Embedded Firearm Trigger" from the uplink for 4tc - a briefcase that allows any weapon stored within to be fired by "firing" the briefcase itself. Weapon sizes are restricted to whatever fits in a briefcase, meaning it practically only works with pistols and some laser weapons. It has a subtle examine tell that only appears while being held. add: Also available for 8tc is a combo deal that comes pre-loaded with a Makarov. This can also appear as a medium Spy reward. balance: The Spy item "boot dagger"'s examine tell now only appears if you're examining them WHILE holding them. /:cl: --- code/datums/storage/subtypes/others/misc.dm | 20 ++++++++++++ .../objects/items/devices/traitordevices.dm | 3 +- code/game/objects/items/storage/briefcase.dm | 19 ++++++++++++ code/modules/uplink/uplink_items.dm | 2 +- code/modules/uplink/uplink_items/job.dm | 31 ++++++++++++++++++- 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/code/datums/storage/subtypes/others/misc.dm b/code/datums/storage/subtypes/others/misc.dm index 2ef02380fa1..8781dfe16a2 100644 --- a/code/datums/storage/subtypes/others/misc.dm +++ b/code/datums/storage/subtypes/others/misc.dm @@ -144,6 +144,26 @@ /datum/storage/briefcase max_total_storage = 21 +/datum/storage/briefcase/gun + max_slots = 5 + max_total_storage = 15 + /// Max weapons weight that can be stored within, inclusive + var/max_weapon_weight = WEAPON_MEDIUM + +/datum/storage/briefcase/gun/can_insert(obj/item/to_insert, mob/user, messages, force) + . = ..() + if(!.) + return FALSE + + if(istype(to_insert, /obj/item/gun)) + var/obj/item/gun/gun = to_insert + if(gun.weapon_weight > max_weapon_weight) + if(messages && user) + user.balloon_alert(user, "too heavy!") + return FALSE + + return TRUE + ///Pill bottle /datum/storage/pillbottle allow_quick_gather = TRUE diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 5131590d8b7..0ba47962beb 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -598,4 +598,5 @@ effective or pretty fucking useless. /obj/item/clothing/shoes/jackboots/dagger/examine_more(mob/user) . = ..() - . += span_notice("Upon closer inspection, you notice a dagger embedded into the sole.") + if(user.is_holding(src)) + . += span_notice("Upon closer inspection, you notice a dagger embedded into the sole.") diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index 44eab479cd1..999996cbfc2 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -179,3 +179,22 @@ remote.pad = WEAKREF(src.pad) to_chat(user, span_notice("You link [pad] to [remote].")) return ITEM_INTERACT_BLOCKING + +/obj/item/storage/briefcase/gun + storage_type = /datum/storage/briefcase/gun + +/obj/item/storage/briefcase/gun/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + for(var/obj/item/gun/weapon in src) + return weapon.try_fire_gun(interacting_with, user, list2params(modifiers)) + return NONE + +/obj/item/storage/briefcase/gun/examine_more(mob/user) + . = ..() + if(user.is_holding(src)) + . += span_notice("Upon closer inspection, you notice a hole in the side of the briefcase.") + +/obj/item/storage/briefcase/gun/preloaded + +/obj/item/storage/briefcase/gun/preloaded/PopulateContents() + new /obj/item/gun/ballistic/automatic/pistol(src) + return ..() diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 5644e058244..f653faff9f0 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -78,7 +78,7 @@ /// Whether this can be discounted or not var/cant_discount = FALSE /// If discounted, is true. Used to send a signal to update reimbursement. - var/discounted = FALSE + VAR_FINAL/discounted = FALSE /// If this value is changed on two items they will share stock, defaults to not sharing stock with any other item var/stock_key = UPLINK_SHARED_STOCK_UNIQUE /// How many items of this stock can be purchased. diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm index 95e79fcff67..8f00aa8b285 100644 --- a/code/modules/uplink/uplink_items/job.dm +++ b/code/modules/uplink/uplink_items/job.dm @@ -14,7 +14,7 @@ cost = 2 restricted_roles = list(JOB_CURATOR) limited_stock = 1 //please don't spam deadchat - surplus = 1 + surplus = 1 /datum/uplink_item/role_restricted/mail_counterfeit_kit name = "GLA Brand Mail Counterfeit Kit" @@ -405,3 +405,32 @@ item = /obj/item/emitter_disk/blast cost = 5 restricted_roles = list(JOB_STATION_ENGINEER, JOB_CHIEF_ENGINEER) + +/datum/uplink_item/role_restricted/briefcase_gun + name = "Briefcase Embedded Firearm Trigger" + desc = "A briefcase with a firing mechanism built into the handle that connects to the first weapon stored within. \ + \"Aiming and firing\" the briefcase will instead trigger the firing mechanism, causing the weapon to fire through a discrete hole. \ + Work with any firearm you could fit inside." + item = /obj/item/storage/briefcase/gun + purchasable_from = UPLINK_TRAITORS + cant_discount = TRUE // remove this when we get uplink logic to have one discount apply to all items on the same stock key + cost = 4 + surplus = 0 + uplink_item_flags = NONE + stock_key = "briefcase_gun" + restricted_roles = list( + JOB_HEAD_OF_PERSONNEL, + JOB_LAWYER, + JOB_QUARTERMASTER, + ) + +/datum/uplink_item/role_restricted/briefcase_gun/with_gun + name = "Briefcase Embedded Firearm Trigger (Combo Deal)" + desc = parent_type::desc + " This COMBO DEAL comes with a pre-loaded Makarov pistol! (No extra magazines, though.)" + item = /obj/item/storage/briefcase/gun/preloaded + purchasable_from = parent_type::purchasable_from | UPLINK_SPY + cost = 8 + surplus = 50 + progression_minimum = /datum/uplink_item/dangerous/pistol::progression_minimum + population_minimum = /datum/uplink_item/dangerous/pistol::population_minimum + relevant_child_items = /datum/uplink_item/dangerous/pistol::relevant_child_items