diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 8f1c01be21..17b68f1d4e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -103,6 +103,8 @@ var/flight_x_offset = 0 var/flight_y_offset = 0 + var/obj/item/firing_pin/pin = /obj/item/firing_pin // YWStation add - Standard firing pin for most guns + /obj/item/weapon/gun/CtrlClick(mob/user) if(can_flashlight && ishuman(user) && src.loc == usr && !user.incapacitated(INCAPACITATION_ALL)) toggle_flashlight() @@ -123,6 +125,11 @@ /obj/item/weapon/gun/New() ..() + // YWStation Add + if(pin) + pin = new pin(src) + // YWStation Add End + for(var/i in 1 to firemodes.len) firemodes[i] = new /datum/firemode(src, firemodes[i]) @@ -230,8 +237,11 @@ return else - Fire(A, user, params) //Otherwise, fire normally. - return + if(user.get_active_hand().can_trigger_gun(user)) + Fire(A, user, params) //Otherwise, fire normally. + return + else + return /* //Commented out for quality control and testing if(automatic == 1)//Are we are going to be using automatic shooting @@ -253,6 +263,10 @@ /obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) if (A == user && user.zone_sel.selecting == O_MOUTH && !mouthshoot) + if(istype(user)) + var/mob/living/L = user + if(!can_trigger_gun(L)) + return handle_suicide(user) else if(user.a_intent == I_HURT) //point blank shooting if(user && user.client && user.aiming && user.aiming.active && user.aiming.aiming_at != A && A != user) @@ -736,9 +750,18 @@ /obj/item/weapon/gun/examine(mob/user) . = ..() +// YWStation Add + var/msg = "" + if(pin) + msg += "It has \a [pin] installed.\n" + msg += "[pin] looks like it could be removed with some tools.\n" + else + msg += "It doesn't have a firing pin installed, and won't fire.\n" if(firemodes.len > 1) var/datum/firemode/current_mode = firemodes[sel_mode] - to_chat(user, "The fire selector is set to [current_mode.name].") + msg += "The fire selector is set to [current_mode.name]." + to_chat(user, msg) +// YWStation Add End /obj/item/weapon/gun/proc/switch_firemodes(mob/user) if(firemodes.len <= 1) @@ -755,3 +778,23 @@ /obj/item/weapon/gun/attack_self(mob/user) switch_firemodes(user) + +// YWStation Add + +/obj/item/weapon/gun/proc/can_trigger_gun(mob/user) + . = ..() + if(!handle_pins(user)) + return FALSE + +/obj/item/weapon/gun/proc/handle_pins(mob/user) + if(pin) + if(pin.pin_auth(user) || pin.emagged) + return TRUE + else + pin.auth_fail(user) + return FALSE + else + to_chat(user, "[src]'s trigger is locked. This weapon doesn't have a firing pin installed!") + return FALSE + +// YWStation Add End \ No newline at end of file diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm new file mode 100644 index 0000000000..56438df950 --- /dev/null +++ b/code/modules/projectiles/pins.dm @@ -0,0 +1,232 @@ +/************************/ +/* Firing Pin Def */ +/************************/ + +/obj/item/firing_pin + name = "electronic firing pin" + desc = "A small authentication device, to be inserted into a firearm receiver to allow operation." + icon = 'icons/obj/device.dmi' + icon_state = "firing_pin" + item_state = "pen" + attack_verb = list("poked") + 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_removeable = 0 // Can be replaced by any pin. + var/obj/item/weapon/gun/gun + var/emagged = 0 + +/obj/item/firing_pin/New(newloc) + ..() + if(istype(newloc, /obj/item/weapon/gun)) + gun = newloc + +/obj/item/firing_pin/afterattack(atom/target, mob/user, adjacent, params) + . = ..() + if(adjacent) + if(istype(target, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/G = target + var/obj/item/firing_pin/old_pin = G.pin + if(old_pin && (force_replace || old_pin.pin_removeable)) + to_chat(user, "You remove [old_pin] from [G].") + if(Adjacent(user)) + user.put_in_hands(old_pin) + else + old_pin.forceMove(G.drop_location()) + old_pin.gun_remove(user) + + 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/firing_pin/emag_act(var/remaining_charges, var/mob/user) + if(emagged) + return + emagged = !emagged + to_chat(user, "You override the authentication mechanism.") + +/obj/item/firing_pin/proc/gun_insert(mob/living/user, obj/item/weapon/gun/G) + gun = G + forceMove(gun) + gun.pin = src + return + +/obj/item/firing_pin/proc/gun_remove(mob/living/user) + gun.pin = null + gun = null + return + +/obj/item/firing_pin/proc/pin_auth(mob/living/user) + return TRUE + +/obj/item/firing_pin/proc/auth_fail(mob/living/user) + if(user) + user.show_message(fail_message, 2) + if(selfdestruct) + if(user) + user.show_message("SELF-DESTRUCTING...") + to_chat(user, "[gun] explodes!") + explosion(get_turf(gun), -1, 0, 2, 3) + if(gun) + qdel(gun) + +/*********************/ +/* Firing Pins */ +/*********************/ + +// Magic weapon pin +/obj/item/firing_pin/magic + name = "magic crystal shard" + desc = "A small enchanted shard which allows magical weapons to fire." + + +// Test pin, works only near firing range. +/obj/item/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_removeable = TRUE + +/obj/item/firing_pin/test_range/pin_auth(mob/living/user) + if(!istype(user)) + return FALSE + for(var/obj/machinery/magnetic_controller/M in range(user, 3)) + return TRUE + return FALSE + +/**********************************************************************/ +/* Temporarily removed, as I have no clue how med systems work! -Gear */ +/**********************************************************************/ +/* +// Implant pin, checks for implant +/obj/item/firing_pin/implant + name = "implant-keyed firing pin" + desc = "This is a security firing pin which only authorizes users who are implanted with a certain device." + fail_message = "IMPLANT CHECK FAILED." + var/obj/item/implant/req_implant = null + +obj/item/firing_pin/implant/pin_auth(mob/living/user) + if(user) + for(var/obj/item/organ/external/E in user.organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(req_implant && I.type == req_implant) + return TRUE + return FALSE + + // Loyalty implant +/obj/item/firing_pin/implant/loyalty + name = "loyalty firing pin" + desc = "This Security 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's joke item. +// Can replace other pins. Replace a pin in cap's laser for extra fun! +// Left in for my own peace of mind. -Gear +/obj/item/firing_pin/clown + name = "hilarious firing pin" + desc = "Adcanced clowntech that can convert any firearm into a far more useful object." + color = "#FFFF00" + fail_message = "HONK!" + force_replace = TRUE + +/obj/item/firing_pin/clown/pin_auth(mob/living/user) + playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE) + return FALSE // :^) + + +/**********************************************************************/ +/* Temporarily removed, as I have no clue how med systems work! -Gear */ +/**********************************************************************/ +/* +// DNA-keyed pin. +// When you want to keep your toys for yourself. +/obj/item/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/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/firing_pin/dna/pin_auth(mob/living/carbon/user) + if(user && user.dna && user.dna.unique_enzymes) + if(user.dna.unique_enzymes == unique_enzymes) + return TRUE + return FALSE + +/obj/item/firing_pin/dna/auth_fail(mob/living/carbon/user) + if(!unique_enzymes) + if(user && user.dna && user.dna.unique_enzymes) + unique_enzymes = user.dna.unique_enzymes + to_chat(user, "DNA-LOCK SET.") + else + ..() + +/obj/item/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 = TRUE +*/ + + +// // Explorer firing pin +// // Usage restricted to off station Z-level +// /obj/item/firing_pin/explorer +// name = "outback firing pin" +// desc = "A firing pin used by the australian defense force, retrofit to prevent weapon discharge on the station." +// icon_state = "firing_pin_explorer" +// fail_message = "CANNOT FIRE WHILE ON STATION, MATE!" + +// // Checks that the user isn't on station Z-level +// /obj/item/firing_pin/explorer/pin_auth(mob/living/user) +// var/turf/station_check = get_turf(user) +// if(!station_check||is_station_level(station_check.z)) +// to_chat(user, "You cannot use your weapon while on the station!") +// return FALSE +// return TRUE + + +// Laser tag pins +/obj/item/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/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 TRUE + to_chat(user, "You need to be wearing [tagcolor] laser tag armor!") + return FALSE + + // Red laser tag firing pin +/obj/item/firing_pin/tag/red + name = "red laser tag firing pin" + icon_state = "firing_pin_red" + suit_requirement = /obj/item/clothing/suit/redtag + tagcolor = "red" + + // Blue laser tag firing pin +/obj/item/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/firing_pin/Destroy() + if(gun) + gun.pin = null + return ..() \ No newline at end of file diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 6fd1a8d0d3..fc15f5e24b 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 8f722b5bb3..9e431e3f7b 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2979,6 +2979,7 @@ #include "code\modules\projectiles\ammunition.dm" #include "code\modules\projectiles\dnalocking.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_yw.dm" #include "code\modules\projectiles\ammunition\magazines.dm"