From b22cb0e59d1a94ece5bbc62b8350db50e80a2a51 Mon Sep 17 00:00:00 2001 From: Pacmandevil Date: Sat, 27 Jan 2018 14:59:00 -0400 Subject: [PATCH] [Ready for review until the inevitable map conflicts] Firing pins (#3375) I'm going full steam ahead with this. Adds firing pins/ Authentication mechanisms. these are needed to fire any specific weapon. Weapons generally spawn with firing pins in them. or at least should. The exception to this is anything made in R&D - which needs to secure a firing pin from somewhere. There's currently the following firing pins: One that checks for a specific implant, EG a loyalty implant one. One that always fails, and can replace other pins. (this one would likely be admin only. it's clown themed) The Laser tag code got refactored to the pins. so each gun has a different pin. if you somehow got this pin, you could make it so you could only shoot a gun while wearing a laser tag vest, for example. A Testing range pin, which only allows firing in specific areas - of which are mapped in currently. A DNA locked one. and a subtype which will explode if someone else tries to use it. the system's designed to be easy enough to add on to. Feedback fourm is here: --- aurorastation.dme | 1 + code/__defines/misc.dm | 1 + code/datums/uplink/devices and tools.dm | 7 + code/game/machinery/vending_types.dm | 3 +- .../objects/items/weapons/storage/boxes.dm | 41 ++ code/game/objects/random/random.dm | 3 +- code/modules/cargo/randomstock.dm | 3 + code/modules/mob/inventory.dm | 2 + code/modules/projectiles/gun.dm | 71 ++- code/modules/projectiles/guns/energy/laser.dm | 5 + .../projectiles/guns/energy/lawgiver.dm | 5 +- code/modules/projectiles/guns/energy/magic.dm | 3 + .../modules/projectiles/guns/energy/mining.dm | 1 - .../projectiles/guns/energy/nuclear.dm | 2 + code/modules/projectiles/guns/energy/pulse.dm | 2 + .../projectiles/guns/energy/special.dm | 10 +- code/modules/projectiles/guns/energy/stun.dm | 1 + .../projectiles/guns/projectile/automatic.dm | 2 + .../projectiles/guns/projectile/revolver.dm | 1 + code/modules/projectiles/pins.dm | 207 +++++++ html/changelogs/PMD-Pins.yml | 5 + icons/obj/firingpins.dmi | Bin 0 -> 2869 bytes maps/_common/areas/station/research.dm | 4 + maps/_common/areas/station/security.dm | 1 + maps/aurora/aurora-3_sublevel.dmm | 564 ++++++++++++++++-- maps/aurora/aurora-4_mainlevel.dmm | 2 + 26 files changed, 874 insertions(+), 73 deletions(-) create mode 100644 code/modules/projectiles/pins.dm create mode 100644 html/changelogs/PMD-Pins.yml create mode 100644 icons/obj/firingpins.dmi diff --git a/aurorastation.dme b/aurorastation.dme index 59d6869c3cb..32ba906df6f 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1938,6 +1938,7 @@ #include "code\modules\projectiles\ammunition.dm" #include "code\modules\projectiles\effects.dm" #include "code\modules\projectiles\gun.dm" +#include "code\modules\projectiles\pins.dm" #include "code\modules\projectiles\projectile.dm" #include "code\modules\projectiles\ammunition\boxes.dm" #include "code\modules\projectiles\ammunition\bullets.dm" diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index c35dbf72abf..545fa26481a 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -174,6 +174,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define RAD_SHIELDED 1 //shielded from radiation, clearly #define SPAWN_ROOF 2 // if we should attempt to spawn a roof above us. #define HIDE_FROM_HOLOMAP 4 // if we shouldn't be drawn on station holomaps +#define FIRING_RANGE 8 // Convoluted setup so defines can be supplied by Bay12 main server compile script. // Should still work fine for people jamming the icons into their repo. diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm index 9a364ccbd6e..077009b2a1d 100644 --- a/code/datums/uplink/devices and tools.dm +++ b/code/datums/uplink/devices and tools.dm @@ -15,6 +15,13 @@ path = /obj/item/weapon/storage/secure/briefcase/money desc = "A briefcase with 10,000 untraceable credits for funding your sneaky activities." +/datum/uplink_item/item/tools/firingpin //todo, make this a special syndicate one instead of just a normal one? + name = "Firing Pin" + item_cost = 2 + path = /obj/item/device/firing_pin + desc = "A Syndicate-branded Firing pin - It should be compatible with nearly every weapon onboard." + + /datum/uplink_item/item/tools/clerical name = "Morphic Clerical Kit" item_cost = 3 diff --git a/code/game/machinery/vending_types.dm b/code/game/machinery/vending_types.dm index e6a76cbb7a5..bdc5ad0079c 100644 --- a/code/game/machinery/vending_types.dm +++ b/code/game/machinery/vending_types.dm @@ -650,7 +650,8 @@ /obj/item/ammo_magazine/c45x = 6, /obj/item/ammo_magazine/a556 = 12, /obj/item/ammo_magazine/a556/ap = 4, - /obj/item/weapon/material/hatchet/tacknife = 4 + /obj/item/weapon/material/hatchet/tacknife = 4, + /obj/item/device/firing_pin = 12 ) //This one's from bay12 diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index ce1e89760d7..dcb904320cf 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -18,6 +18,7 @@ * Kitchen utensil box * Random preserved snack box * For syndicate call-ins see uplink_kits.dm + * Firing pin boxes - Testing and Normal. one for sec, one for science. */ /obj/item/weapon/storage/box @@ -338,6 +339,46 @@ new /obj/item/weapon/grenade/flashbang(src) new /obj/item/weapon/grenade/flashbang(src) +/obj/item/weapon/storage/box/firingpins + name = "box of firing pins" + desc = "A box of NT brand Firearm authentication pins; Needed to operate most weapons." + +/obj/item/weapon/storage/box/firingpins/fill() + ..() + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + new /obj/item/device/firing_pin(src) + +/obj/item/weapon/storage/box/testpins + name = "box of firing pins" + desc = "A box of NT brand Testing Authentication pins; allows guns to fire in designated firing ranges." + +/obj/item/weapon/storage/box/testpins/fill() + ..() + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + new /obj/item/device/firing_pin/test_range(src) + +/obj/item/weapon/storage/box/loyaltypins + name = "box of firing pins" + desc = "A box of specialised \"loyalty\" authentication pins produced by Nanotrasen; these check to see if the user of the gun it's installed in has been implanted with a loyalty implant. Often used in ERTs." + +/obj/item/weapon/storage/box/loyaltypins/fill() + ..() + new /obj/item/device/firing_pin/implant/loyalty(src) + new /obj/item/device/firing_pin/implant/loyalty(src) + new /obj/item/device/firing_pin/implant/loyalty(src) + new /obj/item/device/firing_pin/implant/loyalty(src) + /obj/item/weapon/storage/box/teargas name = "box of pepperspray grenades" desc = "A box containing 7 tear gas grenades. A gas mask is printed on the label.
WARNING: Exposure carries risk of serious injury or death. Keep away from persons with lung conditions." diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 4acc3c73bed..a76310135f4 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -811,7 +811,8 @@ /obj/random/hoodie = 0.5, /obj/random/junk = 0.9, /obj/item/weapon/spacecash/ewallet/lotto = 0.3, - /obj/random/spacecash = 0.3 + /obj/random/spacecash = 0.3, + /obj/item/device/firing_pin = 0.3 ) /obj/random/hoodie diff --git a/code/modules/cargo/randomstock.dm b/code/modules/cargo/randomstock.dm index 74b292b98f4..e25bcdad2ae 100644 --- a/code/modules/cargo/randomstock.dm +++ b/code/modules/cargo/randomstock.dm @@ -165,6 +165,7 @@ var/list/global/random_stock_uncommon = list( "sord" = 1, "policebaton" = 1.5, "stunbaton" = 0.75,//batons spawn with no powercell + "firingpin" = 3, "watches" = 3, "MMI" = 1.5, "voidsuit" = 2, @@ -1062,6 +1063,8 @@ var/list/global/random_stock_large = list( new /obj/random/action_figure(L) if("plushie") new /obj/random/plushie(L) + if("firingpin") + new /obj/item/weapon/storage/box/firingpins(L) if("mediumcell") var/number = rand(1,2) while (number > 0) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 79bafd43160..74c524eaf6d 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -344,3 +344,5 @@ var/list/slot_equipment_priority = list( \ for(var/entry in get_equipped_items(include_carried)) drop_from_inventory(entry) qdel(entry) + + diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 84886e35c66..0b4f232315d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -65,6 +65,8 @@ var/list/dispersion = list(0) var/reliability = 100 + var/obj/item/device/firing_pin/pin = /obj/item/device/firing_pin//standard firing pin for most guns. + var/next_fire_time = 0 @@ -76,6 +78,7 @@ var/recoil_wielded = 0 var/accuracy_wielded = 0 var/wielded = 0 + var/needspin = TRUE //aiming system stuff @@ -84,16 +87,23 @@ var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person. var/tmp/lock_time = -100 -/obj/item/weapon/gun/Initialize() +/obj/item/weapon/gun/Initialize(mapload) . = ..() for(var/i in 1 to firemodes.len) firemodes[i] = new /datum/firemode(src, firemodes[i]) if(isnull(scoped_accuracy)) scoped_accuracy = accuracy + + if (mapload && !pin && needspin) + pin = /obj/item/device/firing_pin + + if(pin && needspin) + pin = new pin(src) queue_icon_update() + //Checks whether a given mob can use the gun //Any checks that shouldn't result in handle_click_empty() being called if they fail should go here. //Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there. @@ -102,6 +112,7 @@ return 0 if(!user.IsAdvancedToolUser()) return 0 + if(user.disabilities & PACIFIST) to_chat(user, "You don't want to risk harming anyone!") return 0 @@ -124,6 +135,20 @@ else handle_click_empty(user) return 0 + + if(pin && needspin) + if(pin.pin_auth(user) || pin.emagged) + return 1 + else + pin.auth_fail(user) + return 0 + else + if(needspin) + to_chat(user, "[src]'s trigger is locked. This weapon doesn't have a firing pin installed!") + return 0 + else + return 1 + return 1 /obj/item/weapon/gun/emp_act(severity) @@ -397,6 +422,14 @@ var/obj/item/projectile/in_chamber = consume_next_projectile() if (istype(in_chamber)) user.visible_message("[user] pulls the trigger.") + if (!pin && needspin)//Checks the pin of the gun. + user.visible_message("*click click*") + mouthshoot = 0 + return + if (!pin.pin_auth() && needspin) + user.visible_message("*click click*") + mouthshoot = 0 + return if(silenced) playsound(user, fire_sound, 10, 1) else @@ -606,6 +639,20 @@ mob_can_equip(M as mob, slot) return 0 + +/obj/item/weapon/gun/examine(mob/user) + ..() + if(needspin) + if(pin) + user << "There is a \[pin] in the trigger mechanism." + else + user << "It doesn't have a firing pin installed, and won't fire." + +obj/item/weapon/gun/Destroy() + if (istype(pin)) + QDEL_NULL(pin) + return ..() + /obj/item/weapon/gun/proc/handle_reliability_fail(var/mob/user) var/severity = 1 @@ -628,4 +675,24 @@ return /obj/item/weapon/gun/proc/critical_fail(var/mob/user) - return \ No newline at end of file + return + +/obj/item/weapon/gun/attackby(var/obj/item/I as obj, var/mob/user as mob) + if(!pin) + return ..() + + if(isscrewdriver(I)) + visible_message("[user] begins to try and pry out [src]'s firing pin!") + if(do_after(user,45 SECONDS,act_target = src)) + if(pin.durable) + visible_message("[user] pops the [pin] out of [src]!") + pin.forceMove(get_turf(src)) + pin = null//clear it out. + else + user.visible_message( + "[user] breaks some electronics free from [src] with a crack.", + "You apply a bit too much force to [pin], and it breaks in two. Oops.", + "You hear a metallic crack.") + qdel(pin) + pin = null + .=..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 66c398d416b..fb2a000e82e 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -65,6 +65,7 @@ obj/item/weapon/gun/energy/retro charge_cost = 400 max_shots = 5 fire_delay = 20 + pin = null can_turret = 1 turret_sprite_set = "cannon" @@ -86,6 +87,7 @@ obj/item/weapon/gun/energy/retro charge_cost = 100 max_shots = 20 fire_delay = 1 + pin = null can_turret = 1 turret_sprite_set = "xray" @@ -158,6 +160,7 @@ obj/item/weapon/gun/energy/retro move_delay = 0 fire_delay = 2 dispersion = list(1.0, -1.0, 2.0, -2.0) + pin = null can_turret = 1 turret_sprite_set = "laser" @@ -186,6 +189,7 @@ obj/item/weapon/gun/energy/retro item_state = "bluetag" projectile_type = /obj/item/projectile/beam/lastertag/blue required_vest = /obj/item/clothing/suit/bluetag + pin = /obj/item/device/firing_pin/tag/blue can_turret = 1 turret_is_lethal = 0 turret_sprite_set = "blue" @@ -195,6 +199,7 @@ obj/item/weapon/gun/energy/retro item_state = "redtag" projectile_type = /obj/item/projectile/beam/lastertag/red required_vest = /obj/item/clothing/suit/redtag + pin = /obj/item/device/firing_pin/tag/red can_turret = 1 turret_is_lethal = 0 turret_sprite_set = "red" diff --git a/code/modules/projectiles/guns/energy/lawgiver.dm b/code/modules/projectiles/guns/energy/lawgiver.dm index e4cb4bbd834..1d6309d81f1 100644 --- a/code/modules/projectiles/guns/energy/lawgiver.dm +++ b/code/modules/projectiles/guns/energy/lawgiver.dm @@ -14,6 +14,7 @@ var/message_enabled = 0 //If playing the message should be enabled var/message_disable = 0 //If the loop should be stopped var/default_desc = "A highly advanced firearm for the modern police force. It has multiple voice-activated firing modes." + pin = null firemodes = list( list( @@ -122,7 +123,7 @@ message_enabled = 0 message_disable = 0 -/obj/item/weapon/gun/energy/lawgiver/attack_self(mob/living/carbon/user as mob) +/obj/item/weapon/gun/energy/lawgiver/attack_self(mob/living/carbon/user as mob) //can probably remove this in favor of the DNA locked firing pins. not touching that now though. edit: lol nevermind snowflake code of the year if(dna != null) return else @@ -144,7 +145,7 @@ user << "You hear a soft beep from the gun and 'ID FAIL' flashes across the screen." user << "You feel a tiny prick in your hand!" user.drop_item() - //Blow up Unauthorized Users Hand + //Blow up Unauthorized Users Hand//todo, delet this, as it's duplicate behaviour from Firing pins. sleep(60) if(active_hand) LA.droplimb(0,DROPLIMB_BLUNT) diff --git a/code/modules/projectiles/guns/energy/magic.dm b/code/modules/projectiles/guns/energy/magic.dm index 1a2d2042ddc..a6cffd1ff6e 100644 --- a/code/modules/projectiles/guns/energy/magic.dm +++ b/code/modules/projectiles/guns/energy/magic.dm @@ -16,6 +16,8 @@ origin_tech = list(TECH_COMBAT = 7, TECH_MAGNET = 5, TECH_BLUESPACE = 7) self_recharge = 1 charge_meter = 0 + pin = /obj/item/device/firing_pin/magic + obj/item/weapon/gun/energy/staff/special_check(var/mob/living/user) if(HULK in user.mutations) @@ -187,6 +189,7 @@ obj/item/weapon/gun/energy/staff/focus/attack_self(mob/living/user as mob) projectile_type = /obj/item/projectile/magic origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 5, TECH_BLUESPACE = 6) charge_meter = 0 + pin = /obj/item/device/firing_pin/magic charge_failure_message = null /obj/item/weapon/gun/energy/wand/get_cell() diff --git a/code/modules/projectiles/guns/energy/mining.dm b/code/modules/projectiles/guns/energy/mining.dm index 8334b3803df..a7a340a757d 100644 --- a/code/modules/projectiles/guns/energy/mining.dm +++ b/code/modules/projectiles/guns/energy/mining.dm @@ -16,7 +16,6 @@ origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 4, TECH_POWER = 4) projectile_type = /obj/item/projectile/kinetic fire_sound = 'sound/weapons/Kenetic_accel.ogg' - var/max_mod_capacity = 100 var/list/modkits = list() diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index bef654a4492..1461dbb04e5 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -6,6 +6,7 @@ fire_sound = 'sound/weapons/Taser.ogg' slot_flags = SLOT_BELT max_shots = 10 + pin = null can_turret = 1 secondary_projectile_type = /obj/item/projectile/beam secondary_fire_sound = 'sound/weapons/Laser.ogg' @@ -38,6 +39,7 @@ force = 8 //looks heavier than a pistol self_recharge = 1 modifystate = null + pin = null reliability = 95 turret_sprite_set = "nuclear" charge_failure_message = "'s charging socket was removed to make room for a minaturized reactor." diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index d4411fd39e8..cc71bf1b51b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -9,6 +9,7 @@ projectile_type = /obj/item/projectile/beam sel_mode = 2 max_shots = 10 + pin = null can_turret = 1 secondary_projectile_type = /obj/item/projectile/beam/pulse secondary_fire_sound = 'sound/weapons/pulse.ogg' @@ -37,3 +38,4 @@ icon_state = "pulse_pistol" item_state = "pulse_pistol" max_shots = 5 + pin = null \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 0ad65be8261..1249710720b 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -41,6 +41,7 @@ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_POWER = 3) max_shots = 10 projectile_type = /obj/item/projectile/energy/declone + pin = null /obj/item/weapon/gun/energy/floragun name = "floral somatoray" @@ -111,8 +112,9 @@ w_class = 3.0 origin_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4) projectile_type = /obj/item/projectile/energy/phoron - can_turret = 1 - turret_is_lethal = 0 + pin = null + can_turret = 1 + turret_is_lethal = 0 turret_sprite_set = "net" /obj/item/weapon/gun/energy/beegun @@ -133,6 +135,7 @@ move_delay = 3 fire_delay = 0 dispersion = list(0.0, 0.2, -0.2) + pin = null /obj/item/weapon/gun/energy/mousegun name = "\improper NT \"Arodentia\" Exterminator ray" @@ -223,6 +226,7 @@ burst_delay = 1 fire_delay = 10 dispersion = list(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9) + pin = null firemodes = list( list(mode_name="concentrated burst", burst=10, burst_delay = 1, fire_delay = 10, dispersion = list(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)), @@ -285,9 +289,9 @@ burst = 1 burst_delay = 1 fire_delay = 0 + pin = null can_turret = 1 turret_sprite_set = "laser" - firemodes = list( list(mode_name="single shot", burst=1, burst_delay = 1, fire_delay = 0), list(mode_name="concentrated burst", burst=3, burst_delay = 1, fire_delay = 5) diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 9f0afe27f8c..cc94466045b 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -31,6 +31,7 @@ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2) projectile_type = /obj/item/projectile/energy/electrode max_shots = 8 + pin = null /obj/item/weapon/gun/energy/crossbow diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index e4bbf7ec724..bde122b56eb 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -12,6 +12,7 @@ multi_aim = 1 burst_delay = 2 sel_mode = 1 + pin = null firemodes = list( list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), @@ -321,6 +322,7 @@ allowed_magazines = list(/obj/item/ammo_magazine/trodpack) auto_eject = 1 auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' + pin = null firemodes = list( list(mode_name="single coil", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 9c3b59a1422..ad7a7fc8065 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -118,6 +118,7 @@ handle_casings = CYCLE_CASINGS max_shells = 7 ammo_type = /obj/item/ammo_casing/cap + needspin = FALSE /obj/item/weapon/gun/projectile/revolver/capgun/attackby(obj/item/W, mob/user) if(!iswirecutter(W) || icon_state == "revolver") diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm new file mode 100644 index 00000000000..e8d05b6df9d --- /dev/null +++ b/code/modules/projectiles/pins.dm @@ -0,0 +1,207 @@ +/* +Alright boys, Firing pins. hopefully with minimal shitcode. +"pin_auth(mob/living/user)" is the check to see if it fires, put the snowflake code here. return one to fire, zero to flop. ezpz + +Firing pins as a rule can't be removed without replacing them, blame a really shitty mechanism for it by NT or something idk, this is to stop people from just taking pins from like a capgun or something. +*/ + +/obj/item/device/firing_pin + name = "electronic firing pin" + desc = "A small authentication device, to be inserted into a firearm receiver to allow operation. NT safety regulations require all new designs to incorporate one." + icon = 'icons/obj/firingpins.dmi' + icon_state = "firing_pin" + item_state = "pen" + origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2) + flags = CONDUCT + w_class = 1 + attack_verb = list("poked") + var/emagged = FALSE + var/fail_message = "INVALID USER." + var/selfdestruct = 0 // Explode when user check is failed. + var/force_replace = 0 // Can forcefully replace other pins. + var/pin_replaceable = 0 // Can be replaced by any pin. + var/durable = FALSE //is destroyed when it's pried out with a screwdriver, see gun.dm + var/obj/item/weapon/gun/gun + + + +/obj/item/device/firing_pin/Initialize(mapload) + .=..() + if(istype(loc, /obj/item/weapon/gun)) + gun = loc + +/obj/item/device/firing_pin/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag) + if(istype(target, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/G = target + if(G.pin && (force_replace || G.pin.pin_replaceable)) + G.pin.forceMove(get_turf(G)) + G.pin.gun_remove(user) + to_chat(user, "You remove [G]'s old pin.") + + if(!G.pin) + gun_insert(user, G) + to_chat(user, "You insert [src] into [G].") + else + to_chat(user, "This firearm already has a firing pin installed.") + +/obj/item/device/firing_pin/emag_act(mob/user) + if(!emagged) + emagged = TRUE + to_chat(user, "You override the authentication mechanism.") + +/obj/item/device/firing_pin/proc/gun_insert(mob/living/user, obj/item/weapon/gun/G) + gun = G + user.drop_from_inventory(src) + forceMove(gun) + gun.pin = src + return + +/obj/item/device/firing_pin/proc/gun_remove(mob/living/user) + gun.pin = null + gun = null + qdel(src) + return + +/obj/item/device/firing_pin/proc/pin_auth(mob/living/user) + return 1 + +/obj/item/device/firing_pin/proc/auth_fail(mob/living/carbon/human/user) + user.show_message(fail_message, 1) + if(selfdestruct)//sound stolen from the lawgiver. todo, remove this from the lawgiver. there can only be one. + user.show_message("SELF-DESTRUCTING...
", 1) + visible_message("[gun] explodes!") + playsound(user, 'sound/weapons/lawgiver_idfail.ogg', 40, 1) + var/obj/item/organ/external/E = user.organs_by_name[user.hand ? "l_hand" : "r_hand"] + E.droplimb(0,DROPLIMB_BLUNT) + explosion(get_turf(gun), -1, 0, 2, 3) + if(gun) + qdel(gun) + +/* +Pins Below. +*/ + +//only used in wizard staffs/wands. +/obj/item/device/firing_pin/magic + name = "magic crystal shard" + desc = "A small enchanted shard which allows magical weapons to fire." + icon_state = "firing_pin_wizwoz" + +// Test pin, works only near firing ranges. +/obj/item/device/firing_pin/test_range + name = "test-range firing pin" + desc = "This safety firing pin allows weapons to be fired within proximity to a firing range." + fail_message = "TEST RANGE CHECK FAILED." + pin_replaceable = 1 + durable = TRUE + origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2) + +/obj/item/device/firing_pin/test_range/pin_auth(mob/living/user) + var/area/A = get_area(src) + if (A && (A.flags & FIRING_RANGE)) + return 1 + else + return 0 + +// Implant pin, checks for implant +/obj/item/device/firing_pin/implant + name = "implant-keyed firing pin" + desc = "This is a implant-locked firing pin which only authorizes users who are implanted with a certain device." + fail_message = "IMPLANT CHECK FAILED." + var/req_implant + +/obj/item/device/firing_pin/implant/pin_auth(mob/living/user) + if (locate(req_implant) in user) + return 1 + else + return 0 + +/obj/item/device/firing_pin/implant/loyalty + name = "loyalty firing pin" + desc = "This implant-locked firing pin authorizes the weapon for only loyalty-implanted users." + icon_state = "firing_pin_loyalty" + req_implant = /obj/item/weapon/implant/loyalty + +// Honk pin, clown joke item. +// Can replace other pins. Replace a pin in cap's laser for extra fun! This is generally adminbus only unless someone thinks of a use for it. +/obj/item/device/firing_pin/clown + name = "hilarious firing pin" + desc = "Advanced clowntech that can convert any firearm into a far more useful object." + color = "#FFFF00" + fail_message = "HONK!" + force_replace = 1 + +/obj/item/device/firing_pin/clown/pin_auth(mob/living/user) + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + return 0 + +// DNA-keyed pin. +// When you want to keep your toys for youself. +/obj/item/device/firing_pin/dna + name = "DNA-keyed firing pin" + desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link." + icon_state = "firing_pin_dna" + fail_message = "DNA CHECK FAILED." + var/unique_enzymes = null + +/obj/item/device/firing_pin/dna/afterattack(atom/target, mob/user, proximity_flag) + ..() + if(proximity_flag && iscarbon(target)) + var/mob/living/carbon/M = target + if(M.dna && M.dna.unique_enzymes) + unique_enzymes = M.dna.unique_enzymes + to_chat(user, "DNA-LOCK SET.") + +/obj/item/device/firing_pin/dna/pin_auth(mob/living/carbon/user) + if(istype(user) && user.dna && user.dna.unique_enzymes) + if(user.dna.unique_enzymes == unique_enzymes) + return 1 + + return 0 + +/obj/item/device/firing_pin/dna/auth_fail(mob/living/carbon/user) + if(!unique_enzymes) + if(istype(user) && user.dna && user.dna.unique_enzymes) + unique_enzymes = user.dna.unique_enzymes + to_chat(user, "DNA-LOCK SET.") + else + ..() + +/obj/item/device/firing_pin/dna/dredd + desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link. It has a small explosive charge on it." + selfdestruct = 1 + + +// Laser tag pins +/obj/item/device/firing_pin/tag + name = "laser tag firing pin" + desc = "A recreational firing pin, used in laser tag units to ensure users have their vests on." + fail_message = "SUIT CHECK FAILED." + var/obj/item/clothing/suit/suit_requirement = null + var/tagcolor = "" + +/obj/item/device/firing_pin/tag/pin_auth(mob/living/user) + if(ishuman(user)) + var/mob/living/carbon/human/M = user + if(istype(M.wear_suit, suit_requirement)) + return 1 + to_chat(user, "You need to be wearing [tagcolor] laser tag armor!") + return 0 + +/obj/item/device/firing_pin/tag/red + name = "red laser tag firing pin" + icon_state = "firing_pin_red" + suit_requirement = /obj/item/clothing/suit/redtag + tagcolor = "red" + +/obj/item/device/firing_pin/tag/blue + name = "blue laser tag firing pin" + icon_state = "firing_pin_blue" + suit_requirement = /obj/item/clothing/suit/bluetag + tagcolor = "blue" + +/obj/item/device/firing_pin/Destroy() + if(gun) + gun.pin = null + return ..() \ No newline at end of file diff --git a/html/changelogs/PMD-Pins.yml b/html/changelogs/PMD-Pins.yml new file mode 100644 index 00000000000..d51ab95892f --- /dev/null +++ b/html/changelogs/PMD-Pins.yml @@ -0,0 +1,5 @@ +author: Pacmandevil +delete-after: True +changes: + - rscadd: "Firing pins. Guns now need an Authentication device to fire. there are several different types." + - rscadd: "Science now has a testing range to test guns in." diff --git a/icons/obj/firingpins.dmi b/icons/obj/firingpins.dmi new file mode 100644 index 0000000000000000000000000000000000000000..81a1424b65552faf8fa16b26d06373fcbc5df537 GIT binary patch literal 2869 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