From dd5915f83d58dbe9f9697eebb2d7e1ac6cb309dd Mon Sep 17 00:00:00 2001 From: Ssalty <65713506+KazooBard@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:40:15 +0100 Subject: [PATCH] Security: A lot of changes (#5132) ## About The Pull Request Special thanks to Cato for helping me with decisionmaking and balancing on this one [in a bunch of things here, but not all.] This PR changes a lot of things so I will be breaking it up into numbers. # 1. Security Vouchers: Primary Ported from monkestation, securirty no longer starts with a taser, but instead with two vouchers. A utility and a primary. All sec should get a utility, the HOS, ~~medic~~ and detective do not get a primary voucher. The vouchers can be redeemed at the same vendor that you get flashbangs/cuffs/donuts from. The choices are: - The default taser - The disabler and an energy shoulder holster to pair - A pepperball gun and a single clip - A flash-bulb riot shield Why the change?: - Warden might not be there to give you your preferred loadout, so even on lowpop, you get your preferred gear up to some extent. We're not giving out hellfire lasers here. It adds nothing that couldn't have been done before, frankly. - The weapons are availible roundstart already, with the exception of the pepperball, which was adjusted to match - More variety in security playstyle, allows sec officers to personalize and play in (mostly) different ways. - The disabler, which is the question I always get, is left in due to it being present in the game as a standalone tool AND some players just having a preferrence to shoot themselves in the foot, or don't like fiddling with modes on the go. The pepperball gun now has a higher shot delay, which is offset by how the weapon makes or breaks fights by applying item drop, knockdown and temporary blindness with it's reagent. Pair it with a baton and any antag who forgot a gas mask just lost. # 2. Security Vouchers: Utility The choices are: - Barrier nades x2 - Stingbangs x2 - Sec laptop, a laptop with relevant programs on it. Lets you view cameras on the go, among others. - Justice Helmet - Donuts - Weighted Space Law/Corporate Regulations. More on that later. - Security barrier projector. More on that later. - A pair of pinpointers, linked with eachother ## Weighted Space Law and Space Law changes: I'll call it space law but it's corporate regulations ok? - Space Law actually links you to wiki. Still teaches you legalese, so just use it more than once to open it. - Weighted Space Law, otherwise known as Space Law: Collecter's Edition. With a gold-coloured-metal-plated trim. Allows you to beat people with space law for 13 damage, a chance to teach them legalese so they can sue you after, and a funny message. Overall a gimmicky thing for more interesting interactions. ## Security Projector changes - Security projector can now CUFF people. Use it as handcuffs to do so. - The cuffs can be EMP'd away at a 50% chance. Makes sense according to what they are and it works for their general purpose of "infinite cuffs, but no cuffs". THE CUFFS FIZZLE OUT IF YOU LEAVE 1 SCREEN OF RANGE. This is because of the sheer amount of space you can save on cuffs by taking this 1 item in their stead, with the condition of "if you can keep them by you until you sit them in their cell.". Worse than cuffs, but a huge timesaver if you feel confident in your skills as an officer. # 3. Breaching Hammer Buff In the current meta, the breaching hammer is dead. Long-gone. Frangible rounds in shotguns, sawn off or otherwise, are much more worth it than any amount of cooperated breaching which leads to yourself being shocked as they are NOT insulated. For that reason, the hammer now takes just 1 person to breach and is resistant to electricity. It's easier to get than the frangible shotgun, it needs potentially less space counting the shots, is infinite, can be even used for dealing with insulated things as security. Simple as. Item revival, way behind meta, or even just convenience. ## Proof Of Testing aaaaaaaaa bbbbbbb ddddddd ccccccc ## Changelog :cl: add: Security starts with a primary and utility voucher for redemption in their equipment lathe to make a choice for what they want to use as their main, nonlethal weapon that round, and a bonus piece of gear on the side. add: Corporate Regulations: Collector's Edition, a space law book with some heft and blunt force to it... add: Security holobarriers can now additionally create holographic cuffs around people, which have a chance to disappear when EMP'd, and disappear if they leave the projector's range of 9 tiles [1 screen] add: Pepperball magazines now in security vendor, premium section balance: Pepperball guns fire much slower, fire delay 8 balance: Breaching hammers can be used by 1 person to breach and are now insulated fix: Space law books now link our website's space law /:cl: --------- Co-authored-by: Alexis --- code/game/objects/items/wiki_manuals.dm | 8 - code/modules/jobs/job_types/detective.dm | 6 +- .../jobs/job_types/head_of_security.dm | 4 +- code/modules/jobs/job_types/warden.dm | 10 +- .../code/game/objects/items/wiki_manuals.dm | 5 - .../modular_weapons/code/pepperball_gun.dm | 1 + .../modules/sec_haul/code/misc/vending.dm | 1 + .../code/peacekeeper/peacekeeper_hammer.dm | 88 +++------- .../code/modules/security/loadouts.dm | 55 +++++++ .../modules/security/sec_vouchers_vendor.dm | 152 ++++++++++++++++++ .../modules/security/secmed/security_medic.dm | 6 +- .../code/modules/security/securty_holosign.dm | 112 +++++++++++++ .../code/modules/security/space_law_book.dm | 81 ++++++++++ modular_zubbers/icons/obj/holocuffs.dmi | Bin 0 -> 324 bytes .../icons/obj/security_voucher.dmi | Bin 0 -> 903 bytes tgstation.dme | 5 +- 16 files changed, 441 insertions(+), 93 deletions(-) delete mode 100644 modular_skyrat/master_files/code/game/objects/items/wiki_manuals.dm create mode 100644 modular_zubbers/code/modules/security/loadouts.dm create mode 100644 modular_zubbers/code/modules/security/sec_vouchers_vendor.dm create mode 100644 modular_zubbers/code/modules/security/securty_holosign.dm create mode 100644 modular_zubbers/code/modules/security/space_law_book.dm create mode 100644 modular_zubbers/icons/obj/holocuffs.dmi create mode 100644 modular_zubbers/icons/obj/security_voucher.dmi diff --git a/code/game/objects/items/wiki_manuals.dm b/code/game/objects/items/wiki_manuals.dm index 75987feeb9a..e3647434e61 100644 --- a/code/game/objects/items/wiki_manuals.dm +++ b/code/game/objects/items/wiki_manuals.dm @@ -74,14 +74,6 @@ starting_title = "Space Law" page_link = "Space_Law" -//BUBBER EDIT ADDITION BEGIN: READING SPACE LAW HAS A CHANCE TO TEACH YOU LEGALESE -/obj/item/book/manual/wiki/security_space_law/attack_self(mob/user) - if(user.can_read(src) && prob(30)) - to_chat(user, span_notice("As you inhale the book's contents, you feel more sophisticated. After reading Space Law just once, you feel like you are an expert in pretending you know Latin. You can now speak Legalese.")) - user.grant_language(/datum/language/legalese, SPOKEN_LANGUAGE) //can speak but not understand - else return -//BUBBER EDIT ADDITION END - /obj/item/book/manual/wiki/security_space_law/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] pretends to read \the [src] intently... then promptly dies of laughter!")) return OXYLOSS diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index 64245d312ce..e56225c42a1 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -59,18 +59,16 @@ /obj/item/detective_scanner = 1, /obj/item/melee/baton = 1, /obj/item/storage/box/evidence = 1, - /obj/item/flashlight/seclite = 1, // BUBBER EDIT ADDITION ) - belt = /obj/item/storage/belt/holster/detective/full // SKYRAT EDIT CHANGE - ORIGINAL: /obj/item/modular_computer/pda/detective + belt = /obj/item/modular_computer/pda/detective ears = /obj/item/radio/headset/headset_sec/alt gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/fedora/det_hat mask = /obj/item/cigarette neck = /obj/item/clothing/neck/tie/detective shoes = /obj/item/clothing/shoes/sneakers/brown - l_pocket = /obj/item/modular_computer/pda/detective // SKYRAT EDIT CHANGE - ORIGINAL: /obj/item/toy/crayon/white + l_pocket = /obj/item/toy/crayon/white r_pocket = /obj/item/lighter - pda_slot = ITEM_SLOT_LPOCKET // BUBBER EDIT ADDITION chameleon_extras = list( /obj/item/clothing/glasses/sunglasses, diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm index 5e737ab1b18..09414aefcf6 100644 --- a/code/modules/jobs/job_types/head_of_security.dm +++ b/code/modules/jobs/job_types/head_of_security.dm @@ -40,11 +40,9 @@ voice_of_god_power = 1.4 //Command staff has authority - /datum/job/head_of_security/get_captaincy_announcement(mob/living/captain) return "Due to staffing shortages, newly promoted Acting Captain [captain.real_name] on deck!" - /datum/outfit/job/hos name = "Head of Security" jobtype = /datum/job/head_of_security @@ -53,7 +51,7 @@ id_trim = /datum/id_trim/job/head_of_security uniform = /obj/item/clothing/under/rank/security/head_of_security suit = /obj/item/clothing/suit/armor/hos/trenchcoat - suit_store = /obj/item/gun/energy/e_gun //BUBBER EDIT - REVERTS SKYRAT REMOVAL + suit_store = /obj/item/gun/energy/e_gun backpack_contents = list( /obj/item/evidencebag = 1, /obj/item/melee/baton/security/loaded/hos = 1, diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm index 528063e1001..d71857d0502 100644 --- a/code/modules/jobs/job_types/warden.dm +++ b/code/modules/jobs/job_types/warden.dm @@ -48,17 +48,13 @@ id_trim = /datum/id_trim/job/warden uniform = /obj/item/clothing/under/rank/security/warden - suit = /obj/item/clothing/suit/armor/vest/warden //SKYRAT EDIT CHANGE - Original: /obj/item/clothing/suit/armor/vest/warden/alt - suit_store = /obj/item/gun/energy/e_gun/advtaser //BUBBER EDIT CHANGE - Original: /obj/item/gun/energy/disabler - backpack_contents = list( - /obj/item/evidencebag = 1, - /obj/item/flashlight/seclite = 1, //BUBBER EDIT - ) + suit = /obj/item/clothing/suit/armor/vest/warden/alt + suit_store = /obj/item/gun/energy/disabler belt = /obj/item/modular_computer/pda/warden ears = /obj/item/radio/headset/headset_sec/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses gloves = /obj/item/clothing/gloves/color/black/security - head = /obj/item/clothing/head/hats/warden //SKYRAT EDIT CHANGE - Original: /obj/item/clothing/head/hats/warden/red + head = /obj/item/clothing/head/hats/warden/red shoes = /obj/item/clothing/shoes/jackboots/sec l_pocket = /obj/item/restraints/handcuffs r_pocket = /obj/item/assembly/flash/handheld diff --git a/modular_skyrat/master_files/code/game/objects/items/wiki_manuals.dm b/modular_skyrat/master_files/code/game/objects/items/wiki_manuals.dm deleted file mode 100644 index 97d31062593..00000000000 --- a/modular_skyrat/master_files/code/game/objects/items/wiki_manuals.dm +++ /dev/null @@ -1,5 +0,0 @@ -/obj/item/book/manual/wiki/security_space_law - name = "Corporate Regulations" - desc = "A set of Nanotrasen regulations for keeping law, order, and procedure followed within their space stations." - starting_title = "Corporate Regulations" - page_link = "Corporate_Regulations" diff --git a/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm index 633bc7d66fb..ac4f303a113 100644 --- a/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm +++ b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm @@ -11,6 +11,7 @@ lock_back_sound = 'sound/items/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/items/weapons/gun/pistol/slide_drop.ogg' fire_sound_volume = 50 + fire_delay = 8 /obj/item/gun/ballistic/automatic/pistol/pepperball/give_manufacturer_examine() AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) diff --git a/modular_skyrat/modules/sec_haul/code/misc/vending.dm b/modular_skyrat/modules/sec_haul/code/misc/vending.dm index 17b6aa9163e..094b4cccc3a 100644 --- a/modular_skyrat/modules/sec_haul/code/misc/vending.dm +++ b/modular_skyrat/modules/sec_haul/code/misc/vending.dm @@ -29,6 +29,7 @@ /obj/item/storage/belt/holster/energy = 4, /obj/item/storage/box/holobadge = 1, /obj/item/ammo_box/magazine/security = 12, + /obj/item/ammo_box/magazine/pepperball = 12, /obj/item/ammo_box/advanced/s12gauge/frangible = 2, ) diff --git a/modular_skyrat/modules/sec_haul/code/peacekeeper/peacekeeper_hammer.dm b/modular_skyrat/modules/sec_haul/code/peacekeeper/peacekeeper_hammer.dm index 5b097d1b0bb..3c839f6559b 100644 --- a/modular_skyrat/modules/sec_haul/code/peacekeeper/peacekeeper_hammer.dm +++ b/modular_skyrat/modules/sec_haul/code/peacekeeper/peacekeeper_hammer.dm @@ -13,14 +13,13 @@ w_class = WEIGHT_CLASS_NORMAL attack_verb_continuous = list("whacks","breaches","bulldozes","flings","thwachs") attack_verb_simple = list("breach","hammer","whack","slap","thwach","fling") + obj_flags = 0 + /// Delay between door hits var/breaching_delay = 2 SECONDS /// The door we aim to breach - var/breaching_target = null /// If we are in the process of breaching var/breaching = FALSE - /// If we are tracking the door and ourselves - var/registered = FALSE /// The person breaching , initially us but we receive a signal with another one var/breacher = null /// the amount that the force is multiplied by , that is then applied as damage to the door. @@ -30,82 +29,43 @@ . = ..() AddElement(/datum/element/kneecapping) -/obj/item/melee/breaching_hammer/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if(!istype(interacting_with, /obj/machinery/door)) - return NONE - user.changeNext_move(5 SECONDS) - if(!registered) - RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(remove_track), FALSE) - RegisterSignal(interacting_with, COMSIG_BREACHING, PROC_REF(try_breaching), TRUE) - to_chat(user, text = "You prepare to forcefully strike the door") - registered = TRUE - breacher = user - SEND_SIGNAL(interacting_with, COMSIG_BREACHING, user) - breaching_target = interacting_with - return ITEM_INTERACT_SUCCESS /// Removes any form of tracking from the user and the item , make sure to call it on he proper item /obj/item/melee/breaching_hammer/proc/remove_track(mob/living/carbon/human/user) - SIGNAL_HANDLER - if(!registered) - return FALSE - registered = FALSE breaching = FALSE - to_chat(user, text = "You relax yourself , and lay down the breaching hammer") - UnregisterSignal(user, COMSIG_MOVABLE_MOVED) - UnregisterSignal(breaching_target, COMSIG_BREACHING) - breaching_target = null + user.balloon_alert(user, "you put your hammer down!") breacher = null -/// Does the checks for breaching -/obj/item/melee/breaching_hammer/proc/try_breaching(obj/target, mob/living/carbon/human/user) - SIGNAL_HANDLER +/obj/item/melee/breaching_hammer/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) + if(istype(target, /obj/structure/table)) + var/obj/smash = target + smash.deconstruct(FALSE) + + else if(istype(target, /obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/opening = target + try_breaching(opening, user) + +/obj/item/melee/breaching_hammer/proc/try_breaching(obj/machinery/door/airlock/target, mob/living/carbon/human/user) if(breaching || (user == breacher)) return FALSE if(!(user.Adjacent(target))) remove_track(user) return NONE - var/mob/living/carbon/human/breach_buddy = breacher - var/target_item = breach_buddy.held_items.Find(src, 1, 0) - var/obj/item/melee/breaching_hammer/second_hammer = null - if(target_item) - second_hammer = breach_buddy.held_items[target_item] - if(!second_hammer) - remove_track(user) - return FALSE breaching = TRUE - INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/item/melee/breaching_hammer, breaching_loop ), user, target) - INVOKE_ASYNC(second_hammer, TYPE_PROC_REF(/obj/item/melee/breaching_hammer, breaching_loop ), breacher, target) - to_chat(breacher , text = "You begin forcefully smashing the [target]") - to_chat(user, text = "You begin forcefully smashing the [target]") + breacher = user + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/item/melee/breaching_hammer, breaching_loop), user, target) + user.balloon_alert(user, "you begin breaching the door!") -/// Keeps looping under the door is no more , or someone moves , gets shot , dies , incapacitated , stunned , etc +/// Keeps looping until the door is breached or conditions fail /obj/item/melee/breaching_hammer/proc/breaching_loop(mob/living/user, obj/target) - if(user.stat || !target) - remove_track(user) - return FALSE - if(!(user.Adjacent(target))) - remove_track(user) - return FALSE - if(target.get_integrity() < 1) - do_smoke(3, target.loc) - remove_track(user) - qdel(target, TRUE) - var/mob/living/carbon/human/silly = breacher - if(!silly) - remove_track(user) - return FALSE - if(!(silly.Adjacent(target))) - remove_track(user) - return FALSE - if(do_after(user, breaching_delay)) + while(!user.stat && target && user.Adjacent(target) && target.get_integrity() >= 1) + if(!do_after(user, breaching_delay, target)) + break if(QDELETED(target)) - return FALSE - target.take_damage(force*breaching_multipler) + break + target.take_damage(force * breaching_multipler) playsound(target, 'sound/items/weapons/sonic_jackhammer.ogg', 70) - visible_message("[user] smashes the [target] forcefully with the [src]") + target.visible_message(span_warning("[target] begins to cave in and deform with each blow from [src]!"), span_warning("We are breaching [target]."), \ + span_hear("you hear a thud of metal against metal.")) user.do_attack_animation(target, used_item = src) - breaching_loop(user, target) - return TRUE remove_track(user) - diff --git a/modular_zubbers/code/modules/security/loadouts.dm b/modular_zubbers/code/modules/security/loadouts.dm new file mode 100644 index 00000000000..8163c3f1c27 --- /dev/null +++ b/modular_zubbers/code/modules/security/loadouts.dm @@ -0,0 +1,55 @@ + +/datum/outfit/job/security + suit_store = /obj/item/flashlight/seclite + backpack_contents = list( + /obj/item/evidencebag = 1, + /obj/item/security_voucher/primary = 1, + /obj/item/security_voucher/utility = 1 + ) + head = /obj/item/clothing/head/security_garrison + glasses = /obj/item/clothing/glasses/hud/security + +/datum/outfit/job/corrections_officer + suit_store = /obj/item/flashlight/seclite + backpack_contents = list(/obj/item/melee/baton/security/loaded/departmental/prison, + /obj/item/restraints/handcuffs = 2, + /obj/item/clothing/mask/whistle, + /obj/item/security_voucher/primary = 1, + /obj/item/security_voucher/utility = 1 + ) + +/datum/outfit/job/detective + backpack_contents = list( + /obj/item/detective_scanner = 1, + /obj/item/melee/baton = 1, + /obj/item/storage/box/evidence = 1, + /obj/item/flashlight/seclite = 1, + /obj/item/security_voucher/utility = 1 + ) + belt = /obj/item/storage/belt/holster/detective/full + l_pocket = /obj/item/modular_computer/pda/detective + pda_slot = ITEM_SLOT_LPOCKET + + +/datum/outfit/job/warden + suit = /obj/item/clothing/suit/armor/vest/warden + suit_store = /obj/item/flashlight/seclite + backpack_contents = list( + /obj/item/evidencebag = 1, + /obj/item/security_voucher/primary = 1, + /obj/item/security_voucher/utility = 1 + ) + +//Brigmed is in it's own file +/datum/outfit/job/hos + backpack_contents = list( + /obj/item/evidencebag = 1, + /obj/item/melee/baton/security/loaded/hos = 1, + /obj/item/security_voucher/utility = 1, + /obj/item/flashlight/seclite + ) + +////////// JOBS BELOW /////////// + +/datum/job/head_of_security + head_announce = list(RADIO_CHANNEL_SECURITY) diff --git a/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm b/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm new file mode 100644 index 00000000000..b1bbc8a46ec --- /dev/null +++ b/modular_zubbers/code/modules/security/sec_vouchers_vendor.dm @@ -0,0 +1,152 @@ + +/obj/item/security_voucher + name = "security voucher" + desc = "A token to redeem a piece of equipment. Use it on a SecTech vendor." + icon = 'modular_zubbers/icons/obj/security_voucher.dmi' + icon_state = "security_voucher_primary" + w_class = WEIGHT_CLASS_TINY + +/obj/item/security_voucher/primary + name = "security primary voucher" + icon_state = "security_voucher_primary" + +/obj/item/security_voucher/utility + name = "security utility voucher" + icon_state = "security_voucher_utility" + +/obj/machinery/vending/security/Initialize(mapload) + . = ..() + AddElement(/datum/element/voucher_redeemer, /obj/item/security_voucher/primary, /datum/voucher_set/security/primary) + AddElement(/datum/element/voucher_redeemer, /obj/item/security_voucher/utility, /datum/voucher_set/security/utility) + + +/datum/voucher_set/security + blackbox_key = "security_voucher_redeemed" + +/datum/voucher_set/security/primary + +/datum/voucher_set/security/utility + +/datum/voucher_set/security/brig_physician + +/datum/voucher_set/security/primary/disabler + name = "Disabler" + description = "The standard issue energy gun of Nanotrasen security forces. Comes with it's own holster." + icon = 'icons/obj/weapons/guns/energy.dmi' + icon_state = "disabler" + set_items = list( + /obj/item/storage/belt/holster/energy/disabler, + ) + +/datum/voucher_set/security/primary/advanced_taser + name = "Hybrid Taser" + description = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams." + icon = 'icons/obj/weapons/guns/energy.dmi' + icon_state = "advtaser" + set_items = list( + /obj/item/gun/energy/e_gun/advtaser, + ) + +/datum/voucher_set/security/primary/disabler_smg + name = "Pepperball AGH" + description = "A slower firing handgun that fires 'pepperballs', which easily drop targets to the floor." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi' + icon_state = "peppergun" + set_items = list( + /obj/item/gun/ballistic/automatic/pistol/pepperball, + /obj/item/ammo_box/magazine/pepperball + ) + +/datum/voucher_set/security/primary/strobe_shield + name = "Strobe Shield" + description = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs." + icon = 'icons/obj/weapons/shields.dmi' + icon_state = "flashshield" + set_items = list( + /obj/item/shield/riot/flash, + ) + + +/datum/voucher_set/security/utility/sec_projector + name = "Security Holobarrier Projector" + description = "A holographic projector that creates holographic security barriers along with holographic handcuffs." + icon = 'icons/obj/devices/tool.dmi' + icon_state = "signmaker_sec" + set_items = list( + /obj/item/holosign_creator/security, + ) + +/datum/voucher_set/security/utility/lawbook + name = "Weighted Space Law Book" + description = "A special edition release of Nanotrasen Space Law. The decorative metal cover adds quite the amount of bulk... Be careful swinging it." + icon = 'modular_zubbers/icons/obj/security_voucher.dmi' + icon_state = "SpaceLawWeighted" + set_items = list( + /obj/item/book/manual/wiki/security_space_law/weighted, + ) + +/datum/voucher_set/security/utility/donut_box + name = "Box of Donuts" + description = "Tantalizing..." + icon = 'icons/obj/food/donuts.dmi' + icon_state = "donutbox" + set_items = list( + /obj/item/storage/fancy/donut_box, + /obj/item/reagent_containers/cup/glass/coffee, + ) + +/datum/voucher_set/security/utility/barrier + name = "Barrier Grenades" + description = "Two barrier grenades." + icon = 'icons/obj/weapons/grenade.dmi' + icon_state = "wallbang" + set_items = list( + /obj/item/grenade/barrier, + /obj/item/grenade/barrier, + ) + +/datum/voucher_set/security/utility/stingbang + name = "Stingbang Grenades" + description = "Two stingbang grenades." + icon = 'icons/obj/weapons/grenade.dmi' + icon_state = "timeg_locked" + set_items = list( + /obj/item/grenade/stingbang, + /obj/item/grenade/stingbang, + ) + +/datum/voucher_set/security/utility/justice_helmet + name = "Helmet of Justice" + description = "Crime fears the helmet of justice." + icon = 'icons/obj/clothing/head/helmet.dmi' + icon_state = "justice" + set_items = list( + /obj/item/clothing/mask/gas/sechailer/swat, + /obj/item/clothing/head/helmet/toggleable/justice, + ) + +/datum/voucher_set/security/utility/pinpointer_pairs + name = "Pinpointer Pair" + description = "A pair of handheld tracking devices that lock onto the other half of the matching pair." + icon = 'icons/obj/devices/tracker.dmi' + icon_state = "pinpointer" + set_items = list( + /obj/item/storage/box/pinpointer_pairs, + ) + +/datum/voucher_set/security/utility/laptop + name = "Security Laptop" + description = "A laptop pre-loaded with security software." + icon = 'icons/obj/devices/modular_laptop.dmi' + icon_state = "laptop-closed" + set_items = list( + /obj/item/modular_computer/laptop/preset/security, + ) + +/obj/item/modular_computer/laptop/preset/security + starting_programs = list( + /datum/computer_file/program/chatclient, + /datum/computer_file/program/crew_manifest, + /datum/computer_file/program/records/security, + /datum/computer_file/program/secureye, + ) diff --git a/modular_zubbers/code/modules/security/secmed/security_medic.dm b/modular_zubbers/code/modules/security/secmed/security_medic.dm index a07850d400e..90183461520 100644 --- a/modular_zubbers/code/modules/security/secmed/security_medic.dm +++ b/modular_zubbers/code/modules/security/secmed/security_medic.dm @@ -46,6 +46,11 @@ name = "Security Medic" jobtype = /datum/job/security_medic + backpack_contents = list( + /obj/item/security_voucher/primary = 1, + /obj/item/security_voucher/utility = 1 + ) + suit_store = /obj/item/flashlight/seclite belt = /obj/item/modular_computer/pda/security ears = /obj/item/radio/headset/headset_medsec uniform = /obj/item/clothing/under/rank/security/peacekeeper/security_medic @@ -55,7 +60,6 @@ suit = /obj/item/clothing/suit/armor/vest/peacekeeper/security_medic l_hand = /obj/item/storage/medkit/brute head = /obj/item/clothing/head/beret/sec/peacekeeper/security_medic - suit_store = /obj/item/gun/energy/e_gun/advtaser backpack = /obj/item/storage/backpack/security satchel = /obj/item/storage/backpack/satchel/sec duffelbag = /obj/item/storage/backpack/duffelbag/sec diff --git a/modular_zubbers/code/modules/security/securty_holosign.dm b/modular_zubbers/code/modules/security/securty_holosign.dm new file mode 100644 index 00000000000..8fc7f534ee1 --- /dev/null +++ b/modular_zubbers/code/modules/security/securty_holosign.dm @@ -0,0 +1,112 @@ + +/obj/item/holosign_creator/security + desc = "A holographic projector that creates holographic security barriers and restraints. You can remotely open barriers with it.\ + Restraints are applied with the creator itself, but the projections may destabilize when exposed to EMP's, or when the captive leaves it's 9 meter range." + +/obj/item/holosign_creator/security/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(!iscarbon(interacting_with)) + return ..() + var/mob/living/carbon/human = interacting_with + if(human.handcuffed) // is our target already handcuffed? + user.balloon_alert(user, "already cuffed") + return ITEM_INTERACT_BLOCKING + if(!human.canBeHandcuffed()) // does he actually have arms? + user.balloon_alert(user, "needs two hands") + return ITEM_INTERACT_BLOCKING + if(DOING_INTERACTION_WITH_TARGET(user, human)) + return ITEM_INTERACT_BLOCKING + log_combat(user, human, "attempted to handcuff") + playsound(src, 'sound/items/weapons/cablecuff.ogg', 30, TRUE, -2) + human.visible_message(span_danger("[user] begins restraining [human] with [src]!"), \ + span_userdanger("[user] begins shaping a holographic field around your hands!")) + if(!do_after(user, 4.5 SECONDS, human, extra_checks = CALLBACK(src, PROC_REF(can_handcuff), user))) // he is up for grabs, so lets handcuff them + return ITEM_INTERACT_BLOCKING + human.set_handcuffed(new /obj/item/restraints/handcuffs/holographic/used(human)) + human.update_handcuffed() + for(var/obj/item/restraints/handcuffs/holographic/used/ourcuffs in human.contents) + ourcuffs.our_projector = src + ourcuffs.our_guy = human + human.apply_status_effect(/datum/status_effect/holocuff_distance) + to_chat(user, span_notice("You restrain [human].")) + log_combat(user, human, "handcuffed") + return ITEM_INTERACT_SUCCESS + +/obj/item/holosign_creator/security/proc/can_handcuff(mob/living/carbon/victim) + if(QDELETED(victim)) + return FALSE + if(victim.handcuffed || victim.num_hands < 2) + return FALSE + return TRUE + +/* + * Handcuffs used for the security holobarrier projector + * the handcuffs themselfes should be un-obtainable, /used version is applied on our actual target + * as strong zipties, take 50% longer to handcuff someone with + */ + +/obj/item/restraints/handcuffs/holographic + name = "holographic energy field" + desc = "A weirdly solid holographic field... how did you get this? this item gives you the permission to scream at coders." + icon = 'modular_zubbers/icons/obj/holocuffs.dmi' + icon_state = "holocuffs" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + breakouttime = 45 SECONDS + flags_1 = NONE + var/our_projector + var/our_guy + + +/obj/item/restraints/handcuffs/holographic/used + desc = "A holographic projection of handcuffs, suprisingly hard to break out of" + item_flags = DROPDEL + +/obj/item/restraints/handcuffs/holographic/proc/check_distance() + SIGNAL_HANDLER + + if(!our_projector) + return + if(!our_guy) + return + var/dist = get_dist(get_turf(our_guy), get_turf(our_projector)) + if(dist > 5) + on_uncuffed() + +/obj/item/restraints/handcuffs/holographic/on_uncuffed(datum/source, mob/living/wearer) + . = ..() + wearer.visible_message(span_danger("[wearer]'s [name] breaks in a discharge of energy!"), span_userdanger("[wearer]'s [name] breaks in a discharge of energy!")) + do_sparks(2, TRUE, src) + wearer.remove_status_effect(/datum/status_effect/holocuff_distance) + qdel(src) + +/obj/item/restraints/handcuffs/holographic/emp_act(severity) + . = ..() + if(severity <= EMP_HEAVY) + if(prob(50)) + do_sparks(2, TRUE, our_guy) + qdel(src) + + +/datum/status_effect/holocuff_distance + id = "holocuffEffect" + status_type = STATUS_EFFECT_UNIQUE + tick_interval = STATUS_EFFECT_AUTO_TICK + alert_type = /atom/movable/screen/alert/status_effect/holocuff_distance + +/atom/movable/screen/alert/status_effect/holocuff_distance + name = "Holocuff Range" + desc = "If only I could get out of the projector's range, it'd lose control!" + icon = 'modular_zubbers/icons/obj/holocuffs.dmi' + icon_state = "holocuffs" + + +/datum/status_effect/holocuff_distance/tick(seconds_between_ticks) + . = ..() + for(var/obj/item/restraints/handcuffs/holographic/used/ourcuffs in owner.contents) + var/dist = get_dist(get_turf(ourcuffs.our_guy), get_turf(ourcuffs.our_projector)) + if(dist > 9) + do_sparks(2, TRUE, owner) + owner.dropItemToGround(ourcuffs, TRUE) + owner.visible_message(span_danger("[owner]'s holographic energy field breaks in a discharge of energy!"), span_userdanger("[owner]'s holographic energy field breaks in a discharge of energy!")) + Destroy() + diff --git a/modular_zubbers/code/modules/security/space_law_book.dm b/modular_zubbers/code/modules/security/space_law_book.dm new file mode 100644 index 00000000000..c95c5fcb3b8 --- /dev/null +++ b/modular_zubbers/code/modules/security/space_law_book.dm @@ -0,0 +1,81 @@ +/// The size of the window that the wiki books open in. +#define BOOK_WINDOW_BROWSE_SIZE "970x710" + +#define WIKI_PAGE_IFRAME(wikiurl, link_identifier) {" + + + + + + + +

You start skimming through the manual...

+ + + + "} + + + +/obj/item/book/manual/wiki/security_space_law + name = "Corporate Regulations" + desc = "A set of Nanotrasen regulations for keeping law, order, and procedure followed within their space stations." + starting_title = "Corporate Regulations" + page_link = "index.php?title=Space_Law" + +/obj/item/book/manual/wiki/security_space_law/attack_self(mob/user) // Was in /tg/ folder, moved it here, made it 100% chance to learn language since you can spam it inhand anyhow. Saves us all from carpal tunnel. + if(user.can_read(src) && !user.has_language(/datum/language/legalese, SPOKEN_LANGUAGE)) + to_chat(user, span_notice("As you inhale the book's contents, you feel more sophisticated. After reading Space Law just once, you feel like you are an expert in pretending you know Latin. You can now speak Legalese.")) + user.grant_language(/datum/language/legalese, SPOKEN_LANGUAGE) //can speak but not understand + else + .=..() + +/obj/item/book/manual/wiki/security_space_law/display_content(mob/living/user) + var/wiki_url = "http://wiki.bubberstation.org" + if(!wiki_url) + user.balloon_alert(user, "this book is empty!") + return + credit_book_to_reader(user) + if(user.client.byond_version < 516) //Remove this once 516 is stable + if(tgui_alert(user, "This book's page will open in your browser. Are you sure?", "Open The Wiki", list("Yes", "No")) != "Yes") + return + DIRECT_OUTPUT(user, link("[wiki_url]/[page_link]")) + else + DIRECT_OUTPUT(user, browse(WIKI_PAGE_IFRAME(wiki_url, page_link), "window=manual;size=[BOOK_WINDOW_BROWSE_SIZE]")) // if you change this GUARANTEE that it works. + +/obj/item/book/manual/wiki/security_space_law/weighted + name = "Corporate Regulations: Collector's Edition" + desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations. This one's quite heavy due to its extra pages and metal-plated cover." + icon = 'modular_zubbers/icons/obj/security_voucher.dmi' + icon_state = "SpaceLawWeighted" + force = 13 + throwforce = 13 + attack_verb_continuous = list("educates", "reprimands", "prosecutes", "teaches a lesson to") + attack_verb_simple = list("educate", "reprimand", "prosecute", "remind","teach a lesson to") + +/obj/item/book/manual/wiki/security_space_law/weighted/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) + if(!isliving(target)) + return + + var/mob/living/living_target = target + + if(user == living_target) + return + + if(living_target.stat == DEAD) + return + + if(prob(10)) + living_target.grant_language(/datum/language/legalese, SPOKEN_LANGUAGE) //IMMA TEACH YOU A LESSON + +#undef BOOK_WINDOW_BROWSE_SIZE +#undef WIKI_PAGE_IFRAME diff --git a/modular_zubbers/icons/obj/holocuffs.dmi b/modular_zubbers/icons/obj/holocuffs.dmi new file mode 100644 index 0000000000000000000000000000000000000000..def816ad50360267d946bdef617e5c9b14a19d74 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@o&cW^*8>L*{Ozl~V&^zb&1U1( z$^U@jj3q&S!3+-1ZlnP@xm6(%B`&GO$wiq3C7Jno3=9=>g2M`mO22;zF8KKMiI%sn z*10q1gExd4Tr__0Nawtd=1GR4p57f6#zDrHjlC4+JeqW5QiwvZrn0@d{Z13zwGo}& z#;TiFNNA*;I65q5y2U8vlf$%?43bBM8+g3g+U7K|JFvwwyl!KfAoXndMRtXE8~;0R3TFuWD}C1P SOrAN=Vg^rFKbLh*2~7ao!+W0q literal 0 HcmV?d00001 diff --git a/modular_zubbers/icons/obj/security_voucher.dmi b/modular_zubbers/icons/obj/security_voucher.dmi new file mode 100644 index 0000000000000000000000000000000000000000..26fcc31706a3c9d01a9d28ad264cb7d61609583f GIT binary patch literal 903 zcmV;219<$2P)v3!pxo8cyRaY6#5bC%wzanapMbCF#plhXEY-)*7~(1&xLTGtA7TqY*Rz%%Fy1fFDZ*Bkpc$}4xy9$Fq5Jl_VuUNDXd9`VR z5`@GiMM{~h6L%m!m{}G7K8w~8?C#;-)7;ox(_5CCp3Hat0E;YbNy!T#bN~PX8A(JzR9J=Wmg{b# zFc5{YxlFi(w4$aCO`6^Jf5{z>aTD-OYksZPCjucIn2)iIbBZD>>)#P$$NYlF0A;vD z%r7b)M6eQtr&Pb-RaM~;1hBepd?jMOB5?G52>pTp;3*OFsRK^F8=+qifNpUNcFd>x z#&=By6)2%r_tap|XUx|#V0?SN>G@OJ>JlYhY)g>e`F)y!rtdYP!iyb(3JhmL0JLoj zuo(#Q$4lq)^$gU60O_V&{tD6eyD_bZlW%8R5uMLp5uOH~h``QCh=5Os@aBz(@Yc<| z4H!i9-{GJitDlvXm6esM_zpX1eV|eRBAoAwVxB%%B>}h)B9!kD@F9(oI^ZId?-k%v z)xM?zu!B&(SAa>%MM=u9wECfZuK^2nup|Iz25u(b-<*hfy2|yJ)B$gV(1;seI1ux+ zTo){l=cEo)zE=nU?8eIX1+5}8MEAc3n0${2L5CgA=KHZ#Wb!@M7Y%%WTjA^=;3XMj z2d;FfKD2e2rU7;cC*a7JyhGTlNZ!AGlne;vd-?cf^f&)1d002ovPDHLkV1gtAu