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 00000000000..81a1424b655 Binary files /dev/null and b/icons/obj/firingpins.dmi differ diff --git a/maps/_common/areas/station/research.dm b/maps/_common/areas/station/research.dm index 5f7c3394db2..28a5e36f88c 100644 --- a/maps/_common/areas/station/research.dm +++ b/maps/_common/areas/station/research.dm @@ -76,6 +76,10 @@ name = "\improper Research - Miscellaneous Research" icon_state = "toxmisc" +/area/rnd/test_range + name = "\improper Research - Weapons Testing Range" + flags = FIRING_RANGE + /area/toxins station_area = 1 diff --git a/maps/_common/areas/station/security.dm b/maps/_common/areas/station/security.dm index 41a7c642828..ff6ca1d58c8 100644 --- a/maps/_common/areas/station/security.dm +++ b/maps/_common/areas/station/security.dm @@ -60,6 +60,7 @@ /area/security/range name = "\improper Security - Firing Range" icon_state = "firingrange" + flags = FIRING_RANGE /area/security/tactical name = "\improper Security - Tactical Equipment" diff --git a/maps/aurora/aurora-3_sublevel.dmm b/maps/aurora/aurora-3_sublevel.dmm index e02256e68f5..6e23043f2d5 100644 --- a/maps/aurora/aurora-3_sublevel.dmm +++ b/maps/aurora/aurora-3_sublevel.dmm @@ -17503,14 +17503,24 @@ /turf/simulated/floor/plating, /area/medical/patient_wing) "FP" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, /obj/effect/floor_decal/corner/mauve, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + icon_state = "map-scrubbers"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled/white, /area/outpost/research/hallway) "FQ" = ( @@ -24812,8 +24822,7 @@ /obj/machinery/atmospherics/valve/digital{ dir = 4; icon_state = "map_valve0"; - name = "Air Bypass valve"; - + name = "Air Bypass valve" }, /turf/simulated/floor/tiled, /area/engineering/atmos) @@ -25041,6 +25050,435 @@ }, /turf/simulated/floor/tiled/freezer, /area/crew_quarters/medbreak) +"TS" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TT" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TU" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TV" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TW" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TX" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"TY" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 5 + }, +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 9 + }, +/obj/machinery/bodyscanner{ + tag = "icon-body_scanner_0 (WEST)"; + icon_state = "body_scanner_0"; + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"TZ" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 5 + }, +/obj/machinery/body_scanconsole{ + tag = "icon-body_scannerconsole (WEST)"; + icon_state = "body_scannerconsole"; + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ua" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 5 + }, +/obj/structure/bed/chair/office/light{ + tag = "icon-officechair_white (EAST)"; + icon_state = "officechair_white"; + dir = 4 + }, +/obj/machinery/firealarm/north, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ub" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 5 + }, +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 6 + }, +/obj/structure/table/reinforced, +/obj/item/weapon/paper_bin, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uc" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"Ud" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 9 + }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -23; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ue" = ( +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uf" = ( +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ug" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 6 + }, +/obj/structure/table/reinforced, +/obj/item/weapon/pen, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uh" = ( +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + icon_state = "rwindow"; + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "Biohazard"; + name = "Biohazard Shutter"; + opacity = 0 + }, +/obj/structure/window/reinforced, +/turf/simulated/floor/plating, +/area/outpost/research/hallway) +"Ui" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"Uj" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + icon_state = "intact-supply"; + dir = 6 + }, +/obj/machinery/power/apc{ + dir = 8; + name = "west bump"; + pixel_x = -24 + }, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uk" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ul" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Um" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Un" = ( +/obj/machinery/door/airlock/glass_research{ + name = "Test Range" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/outpost/research/hallway) +"Uo" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/outpost/research/hallway) +"Up" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/outpost/research/hallway) +"Uq" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"Ur" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 9 + }, +/obj/effect/floor_decal/industrial/warning, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Us" = ( +/obj/effect/floor_decal/industrial/warning, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Ut" = ( +/obj/effect/floor_decal/industrial/warning, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uu" = ( +/obj/effect/floor_decal/corner/mauve{ + icon_state = "corner_white"; + dir = 6 + }, +/obj/effect/floor_decal/industrial/warning, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/test_range) +"Uv" = ( +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + icon_state = "rwindow"; + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "Biohazard"; + name = "Biohazard Shutter"; + opacity = 0 + }, +/obj/effect/floor_decal/industrial/warning, +/obj/structure/window/reinforced{ + icon_state = "rwindow"; + dir = 1 + }, +/turf/simulated/floor/plating, +/area/outpost/research/hallway) +"Uw" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"Ux" = ( +/obj/machinery/door/window/southright, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"Uy" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + icon_state = "rwindow"; + dir = 8 + }, +/obj/item/device/firing_pin/test_range, +/obj/item/device/firing_pin/test_range, +/obj/item/device/firing_pin/test_range, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"Uz" = ( +/obj/structure/table/reinforced, +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UA" = ( +/obj/structure/table/reinforced, +/obj/item/target, +/obj/item/target, +/obj/item/target, +/obj/structure/closet/crate{ + name = "Target Crate" + }, +/obj/item/weapon/storage/box/monkeycubes, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UB" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UC" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UD" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UE" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UF" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UG" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UH" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UI" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UJ" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UK" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UL" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UM" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UN" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UO" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UP" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UQ" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UR" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"US" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UT" = ( +/turf/simulated/wall/r_wall, +/area/rnd/test_range) +"UU" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UV" = ( +/obj/structure/target_stake, +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UW" = ( +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UX" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UY" = ( +/obj/machinery/light{ + dir = 4; + status = 2 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) +"UZ" = ( +/obj/effect/decal/cleanable/blood, +/turf/simulated/floor/tiled/dark, +/area/rnd/test_range) (1,1,1) = {" aa @@ -42154,16 +42592,16 @@ aa aa aa aa +TS +TS +TS +TS +TS +TS +TS +TS ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +mb aa KO Ls @@ -42411,17 +42849,17 @@ aa aa aa aa -ac -ac -ac -ac -ac -ac -ac -ac -ac -aa -aa +TS +TY +Ud +Uj +Ur +Ux +UC +TS +TS +TS +TS KO Lt LV @@ -42668,17 +43106,17 @@ aa aa aa aa -ac -ac -ac -ac -ac -ac -ac -ac -ac -aa -aa +TS +TZ +Ue +Uk +Us +Uy +UC +UX +UC +UC +UZ KO Lu LW @@ -42925,17 +43363,17 @@ aa aa aa aa -ac -ac -ac -ac -ac -ac -ac -ac -aa -aa -aa +TS +Ua +Ue +Uk +Us +Uz +UE +UE +UE +UE +UV KO KO KO @@ -43182,17 +43620,17 @@ aa aa aa aa -aa -ac -ac -ac -ac -ac -ac -aa -aa -aa -aa +TS +Ub +Ug +Um +Uu +UA +UC +UY +UC +UC +UC KP Lv Lv @@ -43441,9 +43879,9 @@ xv xv xv uZ -vs -vs -vs +Uh +Un +Uv vs xe xy @@ -43699,7 +44137,7 @@ Db SQ Ex Ff -vt +vv Co Hp HY @@ -43956,7 +44394,7 @@ Dc SQ vb uD -uD +vv GK Hq HZ @@ -63763,7 +64201,7 @@ OM Pn PI PZ -TR +TQ Ko aa aa diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm index c487edf5a90..4a661954e68 100644 --- a/maps/aurora/aurora-4_mainlevel.dmm +++ b/maps/aurora/aurora-4_mainlevel.dmm @@ -12813,6 +12813,7 @@ dir = 4 }, /obj/structure/table/rack, +/obj/item/weapon/storage/box/firingpins, /turf/simulated/floor/tiled/dark, /area/security/armoury) "axm" = ( @@ -14647,6 +14648,7 @@ pixel_y = -2 }, /obj/item/weapon/storage/box/teargas, +/obj/item/weapon/storage/box/firingpins, /turf/simulated/floor/tiled/dark, /area/security/armoury) "aAp" = (