Skip to content

Commit

Permalink
Merge pull request #20674 from mustafakalash/useofforce
Browse files Browse the repository at this point in the history
Adds secure energy guns and stun revolvers.
  • Loading branch information
PurpleMartinJCK committed Mar 12, 2018
2 parents db31105 + d2a789c commit 2957f29
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 7 deletions.
1 change: 1 addition & 0 deletions baystation12.dme
Expand Up @@ -1913,6 +1913,7 @@
#include "code\modules\modular_computers\file_system\programs\research\email_administration.dm"
#include "code\modules\modular_computers\file_system\programs\research\ntmonitor.dm"
#include "code\modules\modular_computers\file_system\programs\security\digitalwarrant.dm"
#include "code\modules\modular_computers\file_system\programs\security\forceauthorization.dm"
#include "code\modules\modular_computers\hardware\_hardware.dm"
#include "code\modules\modular_computers\hardware\ai_slot.dm"
#include "code\modules\modular_computers\hardware\battery_module.dm"
Expand Down
7 changes: 6 additions & 1 deletion code/__defines/misc.dm
Expand Up @@ -217,4 +217,9 @@
#define REC_FIELD(KEY) /record_field/##KEY

#define SUPPLY_SECURITY_ELEVATED 1
#define SUPPLY_SECURITY_HIGH 2
#define SUPPLY_SECURITY_HIGH 2

// secure gun authorization settings
#define UNAUTHORIZED 0
#define AUTHORIZED 1
#define ALWAYS_AUTHORIZED 2
Expand Up @@ -79,6 +79,7 @@
..()
hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
hard_drive.store_file(new/datum/computer_file/program/digitalwarrant())
hard_drive.store_file(new/datum/computer_file/program/forceauthorization())
hard_drive.store_file(new/datum/computer_file/program/records())
hard_drive.store_file(new/datum/computer_file/program/wordprocessor())

Expand Down
Expand Up @@ -52,6 +52,7 @@
..()
hard_drive.store_file(new/datum/computer_file/program/chatclient())
hard_drive.store_file(new/datum/computer_file/program/card_mod())
hard_drive.store_file(new/datum/computer_file/program/forceauthorization())
hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
hard_drive.store_file(new/datum/computer_file/program/email_client())
hard_drive.store_file(new/datum/computer_file/program/records())
Expand Down
@@ -0,0 +1,52 @@
/datum/computer_file/program/forceauthorization
filename = "forceauthorization"
filedesc = "Use of Force Authorization Manager"
extended_desc = "Control console used to activate the NT Mk30-S NL authorization chip."
size = 4
program_icon_state = "security"
program_menu_icon = "locked"
requires_ntnet = 1
available_on_ntnet = 1
required_access = access_armory
usage_flags = PROGRAM_ALL
nanomodule_path = /datum/nano_module/forceauthorization/

/datum/nano_module/forceauthorization/
name = "Use of Force Authorization Manager"

/datum/nano_module/forceauthorization/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.default_state)
var/list/data = host.initial_data()

data["guns"] = list()
for(var/obj/item/weapon/gun/energy/secure/G in GLOB.registered_weapons)
var/turf/T = get_turf(G)
if(!T || !(T.z in GLOB.using_map.station_levels))
continue

var/list/modes = list()
for(var/i = 1 to G.firemodes.len)
if(G.authorized_modes[i] == ALWAYS_AUTHORIZED)
continue
var/datum/firemode/firemode = G.firemodes[i]
modes += list(list("index" = i, "mode_name" = firemode.name, "authorized" = G.authorized_modes[i]))

data["guns"] += list(list("name" = "[G]", "ref" = "\ref[G]", "owner" = G.registered_owner, "modes" = modes, "loc" = list("x" = T.x, "y" = T.y, "z" = T.z)))

ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "forceauthorization.tmpl", name, 700, 450, state = state)
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()

/datum/nano_module/forceauthorization/Topic(href, href_list)
if(..())
return 1

if(href_list["gun"] && ("authorize" in href_list) && href_list["mode"])
var/obj/item/weapon/gun/energy/secure/G = locate(href_list["gun"]) in GLOB.registered_weapons
var/do_authorize = text2num(href_list["authorize"])
var/mode = text2num(href_list["mode"])
return isnum(do_authorize) && isnum(mode) && G && G.authorize(mode, do_authorize, usr.name)

return 0
114 changes: 114 additions & 0 deletions code/modules/projectiles/guns/energy.dm
@@ -1,3 +1,5 @@
GLOBAL_LIST_INIT(registered_weapons, list())

/obj/item/weapon/gun/energy
name = "energy gun"
desc = "A basic energy-based gun."
Expand Down Expand Up @@ -105,3 +107,115 @@
else
icon_state = "[initial(icon_state)][ratio]"

/obj/item/weapon/gun/energy/secure
desc = "A basic energy-based gun with a secure authorization chip."
req_access = list(access_brig)
var/list/authorized_modes = list(ALWAYS_AUTHORIZED) // index of this list should line up with firemodes, unincluded firemodes at the end will default to unauthorized
var/registered_owner
var/emagged = 0

/obj/item/weapon/gun/energy/secure/Initialize()
if(!authorized_modes)
authorized_modes = list()

for(var/i = authorized_modes.len + 1 to firemodes.len)
authorized_modes.Add(UNAUTHORIZED)

. = ..()

/obj/item/weapon/gun/energy/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/card/id))
if(!emagged)
if(!registered_owner)
if(allowed(user))
var/obj/item/weapon/card/id/id = W
GLOB.registered_weapons += src
registered_owner = id.registered_name
user.visible_message("[user] swipes an ID through \the [src], registering it.", "You swipe an ID through \the [src], registering it.")
else
to_chat(user, "<span class='warning'>Access denied.</span>")
else
to_chat(user, "This weapon is already registered, you must reset it first.")
else
to_chat(user, "You swipe your ID, but nothing happens.")
else
..()

/obj/item/weapon/gun/energy/secure/verb/reset()
set name = "Reset Registration"
set category = "Object"
set src in usr

if(issilicon(usr))
return

if(allowed(usr))
usr.visible_message("[usr] presses the reset button on \the [src], resetting its registration.", "You press the reset button on \the [src], resetting its registration.")
registered_owner = null
GLOB.registered_weapons -= src

/obj/item/weapon/gun/energy/secure/Destroy()
GLOB.registered_weapons -= src

. = ..()

/obj/item/weapon/gun/energy/secure/proc/authorize(var/mode, var/authorized, var/by)
if(emagged || mode < 1 || mode > authorized_modes.len || authorized_modes[mode] == authorized)
return 0

authorized_modes[mode] = authorized

if(mode == sel_mode && !authorized)
switch_firemodes()

var/mob/M = get_holder_of_type(src, /mob)
if(M)
to_chat(M, "<span class='notice'>Your [src.name] has been [authorized ? "granted" : "denied"] [firemodes[mode]] fire authorization by [by].</span>")

return 1

/obj/item/weapon/gun/energy/secure/special_check()
if(!emagged && (!authorized_modes[sel_mode] || !registered_owner))
audible_message("<span class='warning'>\The [src] buzzes, refusing to fire.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
return 0

. = ..()

/obj/item/weapon/gun/energy/secure/switch_firemodes()
var/next_mode = get_next_authorized_mode()
if(firemodes.len <= 1 || next_mode == null || sel_mode == next_mode)
return null

sel_mode = next_mode
var/datum/firemode/new_mode = firemodes[sel_mode]
new_mode.apply_to(src)
update_icon()

return new_mode

/obj/item/weapon/gun/energy/secure/examine(var/mob/user)
..()

if(registered_owner)
to_chat(user, "A small screen on the side of the weapon indicates that it is registered to [registered_owner].")

/obj/item/weapon/gun/energy/secure/proc/get_next_authorized_mode()
. = sel_mode
do
.++
if(. > authorized_modes.len)
. = 1
if(. == sel_mode) // just in case all modes are unauthorized
return null
while(!authorized_modes[.] && !emagged)

/obj/item/weapon/gun/energy/secure/emag_act(var/charges, var/mob/user)
if(emagged || !charges)
return NO_EMAG_ACT
else
emagged = 1
registered_owner = null
GLOB.registered_weapons -= src
to_chat(user, "The authorization chip fries, giving you full use of \the [src].")
return 1
36 changes: 35 additions & 1 deletion code/modules/projectiles/guns/energy/nuclear.dm
Expand Up @@ -16,9 +16,28 @@
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill"),
)

/obj/item/weapon/gun/energy/secure/gun
name = "energy gun"
desc = "A more secure LAEP90, the LAEP90-S is designed to please paranoid constituents. Body cam not included."
icon_state = "energystun100"
item_state = null //so the human update icon uses the icon_state instead.
max_shots = 10
fire_delay = 10 // To balance for the fact that it is a pistol and can be used one-handed without penalty

projectile_type = /obj/item/projectile/beam/stun
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
modifystate = "energystun"
authorized_modes = list(ALWAYS_AUTHORIZED, AUTHORIZED)

firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="energystun"),
list(mode_name="shock", projectile_type=/obj/item/projectile/beam/stun/shock, modifystate="energyshock"),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill"),
)

/obj/item/weapon/gun/energy/gun/small
name = "small energy gun"
desc = "A smaller model of the versatile LAEP90 Perun, packing considerable utility in a smaller package. Best used in situations where full-sized sidearms are inappropriate."
desc = "A smaller model of the versatile LAEP90 Perun, the LAEP90-C packs considerable utility in a smaller package. Best used in situations where full-sized sidearms are inappropriate."
icon_state = "smallgunstun"
max_shots = 5
w_class = ITEM_SIZE_SMALL
Expand All @@ -31,6 +50,21 @@
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam/smalllaser, modifystate="smallgunkill"),
)

/obj/item/weapon/gun/energy/secure/gun/small
name = "small energy gun"
desc = "Combining the two LAEP90 variants, the secure and compact LAEP90-CS is the next best thing to keeping your security forces on a literal leash."
icon_state = "smallgunstun"
max_shots = 5
w_class = ITEM_SIZE_SMALL
force = 2
modifystate = "smallgunstun"

firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="smallgunstun"),
list(mode_name="shock", projectile_type=/obj/item/projectile/beam/stun/shock, modifystate="smallgunshock"),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam/smalllaser, modifystate="smallgunkill"),
)

/obj/item/weapon/gun/energy/gun/mounted
name = "mounted energy gun"
self_recharge = 1
Expand Down
16 changes: 15 additions & 1 deletion maps/torch/items/items.dm
Expand Up @@ -84,4 +84,18 @@ Weapons
desc = "A shiny Mosley Autococker automatic revolver, with black accents. Marketed as the 'Revolver for the Modern Era'. Uses .44 magnum rounds."
fire_delay = 5.7 //Autorevolver. Also synced with the animation
fire_anim = "mosley_fire"
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2)

/obj/item/weapon/gun/energy/secure/stunrevolver
name = "stun revolver"
desc = "This LAEP20 is fitted with an NT1019 chip, a component that allows remote authorization of weapon functionality, created by NanoTrasen following the Baetiff Incident."
icon_state = "stunrevolver"
item_state = "stunrevolver"
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
projectile_type = /obj/item/projectile/energy/electrode
max_shots = 8
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/energy/electrode, modifystate="stunrevolver"),
list(mode_name="shock", projectile_type=/obj/item/projectile/energy/electrode/stunshot, modifystate="stunrevolver")
)
req_access = list(access_sec_guard)
2 changes: 1 addition & 1 deletion maps/torch/structures/closets/research.dm
Expand Up @@ -177,7 +177,7 @@
/obj/item/clothing/accessory/holster/thigh,
/obj/item/clothing/accessory/badge/holo/NT,
/obj/item/device/megaphone,
/obj/item/weapon/gun/energy/stunrevolver,
/obj/item/weapon/gun/energy/secure/stunrevolver,
/obj/item/clothing/shoes/jackboots,
new /datum/atom_creator/weighted(list(/obj/item/weapon/storage/backpack/security, /obj/item/weapon/storage/backpack/satchel_sec)),
new /datum/atom_creator/weighted(list(/obj/item/weapon/storage/backpack/dufflebag/sec, /obj/item/weapon/storage/backpack/messenger/sec))
Expand Down
6 changes: 3 additions & 3 deletions maps/torch/structures/closets/security.dm
Expand Up @@ -26,7 +26,7 @@
/obj/item/taperoll/police,
/obj/item/device/hailer,
/obj/item/clothing/accessory/storage/black_vest,
/obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/secure/gun/small,
/obj/item/device/megaphone,
/obj/item/clothing/gloves/thick,
/obj/item/clothing/accessory/holster/thigh,
Expand Down Expand Up @@ -99,7 +99,7 @@
/obj/item/weapon/gun/energy/gun,
/obj/item/clothing/accessory/holster/thigh,
/obj/item/clothing/accessory/storage/black_vest,
/obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/secure/gun/small,
/obj/item/weapon/handcuffs,
/obj/item/device/hailer,
/obj/item/device/flash,
Expand Down Expand Up @@ -128,7 +128,7 @@
/obj/item/clothing/suit/armor/vest/detective,
/obj/item/clothing/head/helmet/solgov/security,
/obj/item/clothing/suit/armor/pcarrier/medium/security,
/obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/secure/gun/small,
/obj/item/clothing/accessory/holster/thigh,
/obj/item/device/flash,
/obj/item/weapon/melee/baton/loaded,
Expand Down
14 changes: 14 additions & 0 deletions nano/templates/forceauthorization.tmpl
@@ -0,0 +1,14 @@
<ul>
{{for data.guns :value:index}}
<li>
{{:value.name}} registered to {{:value.owner}} at ({{:value.loc.x}}, {{:value.loc.y}}, {{:value.loc.z}})<br />
{{for value.modes :inner_value:inner_index}}
{{if inner_value.authorized == "1"}}
{{:helper.link("Unauthorize " + inner_value.mode_name, null, {"gun" : value.ref, "mode" : inner_value.index, "authorize" : 0})}}
{{else}}
{{:helper.link("Authorize " + inner_value.mode_name, null, {"gun" : value.ref, "mode" : inner_value.index, "authorize" : 1})}}
{{/if}}
{{/for}}
</li>
{{/for}}
</ul>

0 comments on commit 2957f29

Please sign in to comment.