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

<img width="1409" height="684" alt="aaaaaaaaa"
src="https://github.com/user-attachments/assets/782c23ca-11bb-4ba7-8294-80086af1b134"
/>
<img width="307" height="269" alt="bbbbbbb"
src="https://github.com/user-attachments/assets/8d75a1bb-fb2e-44d8-8338-f22ed6be62da"
/>
<img width="260" height="311" alt="ddddddd"
src="https://github.com/user-attachments/assets/51229031-0a6d-480c-8021-0f57cd8496dc"
/>
<img width="193" height="181" alt="ccccccc"
src="https://github.com/user-attachments/assets/97254655-60f7-4713-9673-bb6b3071d97e"
/>
## Changelog

🆑
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
/🆑

---------

Co-authored-by: Alexis <catmc8565@gmail.com>
This commit is contained in:
Ssalty
2026-01-29 12:40:15 +01:00
committed by GitHub
parent fd8fcb0081
commit dd5915f83d
16 changed files with 441 additions and 93 deletions
-8
View File
@@ -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
+2 -4
View File
@@ -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,
@@ -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,
+3 -7
View File
@@ -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
@@ -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"
@@ -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)
@@ -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,
)
@@ -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)
@@ -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)
@@ -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,
)
@@ -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
@@ -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()
@@ -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) {"
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
iframe {
display: none;
}
</style>
</head>
<body>
<script type="text/javascript">
function pageloaded(myframe) {
document.getElementById("loading").style.display = "none";
myframe.style.display = "inline";
}
</script>
<p id='loading'>You start skimming through the manual...</p>
<iframe width='100%' height='97%' onload="pageloaded(this)" src="[##wikiurl]/[##link_identifier]&remove_links=1" frameborder="0" id="main_frame"></iframe>
</body>
</html>
"}
/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
Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

+4 -1
View File
@@ -7011,7 +7011,6 @@
#include "modular_skyrat\master_files\code\game\objects\items\religion.dm"
#include "modular_skyrat\master_files\code\game\objects\items\scratchingstone.dm"
#include "modular_skyrat\master_files\code\game\objects\items\toys.dm"
#include "modular_skyrat\master_files\code\game\objects\items\wiki_manuals.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\anomaly_neutralizer.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\chameleonproj.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\laserpointer.dm"
@@ -9730,8 +9729,12 @@
#include "modular_zubbers\code\modules\rr_opt_in\examine.dm"
#include "modular_zubbers\code\modules\rr_opt_in\rr_opt_config.dm"
#include "modular_zubbers\code\modules\rr_opt_in\rr_optin_preferences.dm"
#include "modular_zubbers\code\modules\security\loadouts.dm"
#include "modular_zubbers\code\modules\security\maid_sec.dm"
#include "modular_zubbers\code\modules\security\sec_clothing_overrides.dm"
#include "modular_zubbers\code\modules\security\sec_vouchers_vendor.dm"
#include "modular_zubbers\code\modules\security\securty_holosign.dm"
#include "modular_zubbers\code\modules\security\space_law_book.dm"
#include "modular_zubbers\code\modules\security\tasers.dm"
#include "modular_zubbers\code\modules\security\secmed\automapper.dm"
#include "modular_zubbers\code\modules\security\secmed\secmed_clothes.dm"