Skip to content

Commit

Permalink
Gun Safety PSA - Keep your gun safeties on to prevent accidental disc…
Browse files Browse the repository at this point in the history
…harges! (shiptest-ss13#3312)

<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

Unsafetied guns have a small chance to go off and fire on their own
under select conditions, which are currently:
- Being thrown and hitting something.
- Being on a ship when it takes off or docks. (Having it stored in a
stable container eg. lockers/crates, protect it from going off)
- Falling down while carrying a gun (Shoves, slips, etc)
- Paralyzes while holding a gun
- Having your gun holstered lowers the chance of it going off from
falling down due to the aforementioned causes
- Being EMPed if it's an energy weapon.

Modifies fire_casing so it works without a user.

## Why It's Good For The Game

<!-- Please add a short description of why you think these changes would
benefit the game. If you can't justify it in words, it might not be
worth adding. -->

Makes guns a bit more dangerous (to yourself mainly), and reinforces the
fact guns are Dangerous Weapons and you should be careful with them by
adding a mechanical reason to have your safety on outside of combat and
properly securing your weapons.

~~adds more medical gameplay due to increased injuries~~

## Changelog

:cl:
add: Unsaftied guns can go off on their own.
code: Changes ammo casing firing code so it's able to work without a
user.
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
  • Loading branch information
Gristlebee authored and MysticalFaceLesS committed Sep 22, 2024
1 parent f33c818 commit 23c1bc1
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 10 deletions.
5 changes: 5 additions & 0 deletions code/__DEFINES/guns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
#define MANUFACTURER_PGF "the Etherbor Industries emblem"
#define MANUFACTURER_IMPORT "Lanchester Import Co."

// Misfire chances if the gun's safety is off
#define GUN_NO_SAFETY_MALFUNCTION_CHANCE_LOW 100
#define GUN_NO_SAFETY_MALFUNCTION_CHANCE_MEDIUM 100
#define GUN_NO_SAFETY_MALFUNCTION_CHANCE_HIGH 100

/////////////////
// ATTACHMENTS //
/////////////////
Expand Down
2 changes: 2 additions & 0 deletions code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
. = ..()
if(!.)
return
owner.trip_with_gun("knockdown")
ADD_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))

/datum/status_effect/incapacitating/knockdown/on_remove()
Expand Down Expand Up @@ -79,6 +80,7 @@
. = ..()
if(!.)
return
owner.trip_with_gun("paralyze")
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
Expand Down
6 changes: 6 additions & 0 deletions code/game/objects/items/storage/storage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
if(EXPLODE_LIGHT)
SSexplosions.lowobj += A

/obj/item/storage/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
for(var/obj/item/gun/at_risk in get_all_contents())
if(at_risk.safety == FALSE && prob(GUN_NO_SAFETY_MALFUNCTION_CHANCE_HIGH))
at_risk.discharge("is hits the ground hard")

/obj/item/storage/canStrip(mob/who)
. = ..()
if(!. && rummage_if_nodrop)
Expand Down
26 changes: 17 additions & 9 deletions code/modules/projectiles/ammunition/_firing.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from, misfire = FALSE)
distro += variance
var/targloc = get_turf(target)
ready_proj(target, user, quiet, zone_override, fired_from)
ready_proj(target, user, quiet, zone_override, fired_from, misfire)
if(pellets == 1)
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
if(randomspread)
Expand All @@ -15,19 +15,20 @@
return FALSE
AddComponent(/datum/component/pellet_cloud, projectile_type, pellets)
SEND_SIGNAL(src, COMSIG_PELLET_CLOUD_INIT, target, user, fired_from, randomspread, spread, zone_override, params, distro)
if(user)
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)

if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)

user.newtonian_move(get_dir(target, user))
user.newtonian_move(get_dir(target, user))
update_appearance()
return TRUE

/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "", atom/fired_from)
/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "", atom/fired_from, misfire = FALSE)
if (!BB)
return
BB.original = target
BB.firer = user
BB.misfire = misfire
BB.fired_from = fired_from
if (zone_override)
BB.def_zone = zone_override
Expand All @@ -45,7 +46,11 @@
qdel(reagents)

/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread)
var/turf/curloc = get_turf(user)
var/turf/curloc
if(user)
curloc = get_turf(user)
else
curloc = get_turf(src)
if (!istype(targloc) || !istype(curloc) || !BB)
return FALSE

Expand All @@ -60,7 +65,10 @@
if(target) //if the target is right on our location we'll skip the travelling code in the proj's fire()
direct_target = target
if(!direct_target)
BB.preparePixelProjectile(target, user, params, spread)
if(user)
BB.preparePixelProjectile(target, user, params, spread)
else
BB.preparePixelProjectile(target, curloc, params, spread)
BB.fire(null, direct_target)
BB = null
return TRUE
Expand Down
48 changes: 48 additions & 0 deletions code/modules/projectiles/gun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,11 @@
if(zoomed)
zoom(user, user.dir)

/obj/item/gun/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(prob(GUN_NO_SAFETY_MALFUNCTION_CHANCE_HIGH))
discharge("hits the ground hard")

/obj/item/gun/update_overlays()
. = ..()
if(ismob(loc) && has_safety)
Expand Down Expand Up @@ -947,6 +952,49 @@
flash_loc.vis_contents -= muzzle_flash
muzzle_flash.applied = FALSE

// for guns firing on their own without a user
/obj/item/gun/proc/discharge(cause, seek_chance = 10)
var/target
if(!safety)
// someone is very unlucky and about to be shot
if(prob(seek_chance))
for(var/mob/living/target_mob in range(6, get_turf(src)))
if(!isInSight(src, target_mob))
continue
target = target_mob
break
if(!target)
var/fire_dir = pick(GLOB.alldirs)
target = get_ranged_target_turf(get_turf(src),fire_dir,6)
if(!chambered || !chambered.BB)
visible_message(span_danger("\The [src] [cause ? "[cause], suddenly going off" : "suddenly goes off"] without its safteies on! Luckily it wasn't live."))
playsound(src, dry_fire_sound, 30, TRUE)
else
visible_message(span_danger("\The [src] [cause ? "[cause], suddenly going off" : "suddenly goes off"] without its safeties on!"))
unsafe_shot(target)

/obj/item/gun/proc/unsafe_shot(target)
if(chambered)
chambered.fire_casing(target,null, null, null, suppressed, ran_zone(BODY_ZONE_CHEST, 50), 0, src,TRUE)
playsound(src, fire_sound, 100, TRUE)

/mob/living/proc/trip_with_gun(cause)
var/mob/living/carbon/human/human_holder
if(ishuman(src))
human_holder = src
for(var/obj/item/gun/at_risk in get_all_contents())
var/chance_to_fire = GUN_NO_SAFETY_MALFUNCTION_CHANCE_MEDIUM
var/did_fire = FALSE
if(human_holder)
// gun is less likely to go off in a holster
if(at_risk == human_holder.s_store)
chance_to_fire = GUN_NO_SAFETY_MALFUNCTION_CHANCE_LOW
if(at_risk.safety == FALSE && prob(chance_to_fire))
if(at_risk.process_fire(src,src,FALSE, null, pick(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG)) == TRUE)
log_combat(src,src,"misfired",at_risk,"caused by [cause]")
visible_message(span_danger("\The [at_risk.name]'s trigger gets caught as [src] falls, suddenly going off into [src]'s leg without its safties on!"), span_danger("\The [at_risk.name]'s trigger gets caught on something as you fall, suddenly going off into your leg without its safeties on!"))
emote("scream")

//I need to refactor this into an attachment
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
Expand Down
5 changes: 5 additions & 0 deletions code/modules/projectiles/guns/ballistic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,8 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
if(AC.BB)
process_fire(user, user, FALSE)
. = TRUE

/obj/item/gun/ballistic/unsafe_shot(target, empty_chamber = TRUE)
. = ..()
process_chamber(empty_chamber,TRUE)

6 changes: 6 additions & 0 deletions code/modules/projectiles/guns/energy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
/obj/item/gun/energy/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
if(prob(GUN_NO_SAFETY_MALFUNCTION_CHANCE_HIGH))
discharge("malfunctions from the EMP")
cell.use(round(cell.charge / severity))
chambered = null //we empty the chamber
recharge_newshot() //and try to charge a new shot
Expand Down Expand Up @@ -325,3 +327,7 @@
. += "\The [name] has [round(cell.charge/shot.e_cost)] shots remaining on <b>[shot.select_name]</b> mode."
else
. += span_notice("\The [name] doesn't seem to have a cell!")

/obj/item/gun/energy/unsafe_shot(target)
. = ..()
process_chamber()
6 changes: 5 additions & 1 deletion code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/def_zone = "" //Aiming at
var/atom/movable/firer = null//Who shot it
// if the projectile was the result of a misfire. For logging.
var/misfire = FALSE
var/atom/fired_from = null // the atom that the projectile was fired from (gun, turret)
var/suppressed = FALSE //Attack message
var/yo = null
Expand Down Expand Up @@ -284,7 +286,9 @@
for(var/datum/reagent/R in reagents.reagent_list)
reagent_note += "[R.name] ([num2text(R.volume)])"

if(ismob(firer))
if(misfire)
L.log_message("has been hit by a misfired [src] from \a [fired_from] last touched by [fired_from.fingerprintslast]", LOG_ATTACK, color = "orange")
else if(ismob(firer))
log_combat(firer, L, "shot", src, reagent_note)
else
L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
Expand Down
6 changes: 6 additions & 0 deletions code/modules/shuttle/on_move.dm
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ All ShuttleMove procs go here

/************************************Item move procs************************************/


/obj/item/storage/pod/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
// If the pod was launched, the storage will always open. The reserved_level check
Expand All @@ -299,6 +300,11 @@ All ShuttleMove procs go here
if (oldT && !is_reserved_level(oldT))
unlocked = TRUE

/obj/item/gun/lateShuttleMove(turf/oldT, list/movement_force, move_dir)
. = ..()
if(prob(GUN_NO_SAFETY_MALFUNCTION_CHANCE_MEDIUM))
discharge("is thrown around by the force of the take off")

/************************************Mob move procs************************************/

/mob/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock, list/obj/docking_port/mobile/towed_shuttles)
Expand Down

0 comments on commit 23c1bc1

Please sign in to comment.