Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds secure energy guns and stun revolvers. #20674

Merged
merged 1 commit into from Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions baystation12.dme
Expand Up @@ -1912,6 +1912,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>