Gun Muzzle Flash (2) (#94172)

## About The Pull Request

Continues https://github.com/tgstation/tgstation/pull/81507

Adds a directional muzzle flash to all guns (excluding suppressors,
toys, e-bow, etc).
Changes color depending on the laser/projectile.
If anything is missed, let me know.

## Why It's Good For The Game

Realism
Cool visuals
Makes sense
This commit is contained in:
archbtw
2025-11-30 19:37:00 +00:00
committed by GitHub
parent 3858064261
commit 3425cf03e5
24 changed files with 60 additions and 0 deletions
@@ -16,6 +16,8 @@
var/caliber = null
///The bullet type to create when New() is called
var/projectile_type = null
///Muzzle flash color based on ammo casing.
var/muzzle_flash_color = LIGHT_COLOR_ORANGE
///the loaded projectile in this ammo casing
var/obj/projectile/loaded_projectile = null
///Pellets for spreadshot
@@ -9,3 +9,4 @@
fire_sound = 'sound/items/weapons/laser.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/red
newtonian_force = 0.5
muzzle_flash_color = LIGHT_COLOR_CYAN
@@ -2,6 +2,7 @@
projectile_type = /obj/projectile/beam/laser
e_cost = LASER_SHOTS(12, STANDARD_CELL_CHARGE)
select_name = "kill"
muzzle_flash_color = COLOR_SOFT_RED
/obj/item/ammo_casing/energy/laser/hellfire
projectile_type = /obj/projectile/beam/laser/hellfire
@@ -17,6 +18,7 @@
projectile_type = /obj/projectile/beam/laser
e_cost = LASER_SHOTS(16, STANDARD_CELL_CHARGE)
select_name = "kill"
muzzle_flash_color = COLOR_SOFT_RED
/obj/item/ammo_casing/energy/lasergun/pistol
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE)
@@ -112,6 +114,7 @@
select_name = "DESTROY"
fire_sound = 'sound/items/weapons/pulse.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/blue
muzzle_flash_color = LIGHT_COLOR_BLUE
/obj/item/ammo_casing/energy/laser/bluetag
projectile_type = /obj/projectile/beam/lasertag/bluetag
@@ -3,6 +3,7 @@
select_name = "ion"
fire_sound = 'sound/items/weapons/ionrifle.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/blue
muzzle_flash_color = LIGHT_COLOR_BLUE
/obj/item/ammo_casing/energy/ion/hos
projectile_type = /obj/projectile/ion/weak
@@ -5,6 +5,7 @@
e_cost = LASER_SHOTS(5, STANDARD_CELL_CHARGE)
harmful = FALSE
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect
muzzle_flash_color = LIGHT_COLOR_DIM_YELLOW
/obj/item/ammo_casing/energy/electrode/spec
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE)
@@ -26,6 +27,7 @@
fire_sound = 'sound/items/weapons/taser2.ogg'
harmful = FALSE
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/blue
muzzle_flash_color = LIGHT_COLOR_CYAN
/obj/item/ammo_casing/energy/disabler/smg
projectile_type = /obj/projectile/beam/disabler/weak
+21
View File
@@ -24,6 +24,16 @@
attack_verb_simple = list("strike", "hit", "bash")
action_slots = ALL
// Muzzle Flash
light_on = FALSE
light_system = OVERLAY_LIGHT_DIRECTIONAL
light_range = 3
light_color = LIGHT_COLOR_ORANGE
light_power = 0.5
var/can_muzzle_flash = TRUE
/// Muzzle Flash Duration
var/light_time = 0.1 SECONDS
var/gun_flags = NONE
var/fire_sound = 'sound/items/weapons/gun/pistol/shot.ogg'
var/vary_fire_sound = TRUE
@@ -207,10 +217,21 @@
else
playsound(src, fire_sound, fire_sound_volume, vary_fire_sound)
/obj/item/gun/proc/muzzle_flash_on()
if (can_muzzle_flash)
set_light_on(TRUE)
addtimer(CALLBACK(src, PROC_REF(muzzle_flash_off)), light_time, TIMER_UNIQUE | TIMER_OVERRIDE)
else
muzzle_flash_off()
/obj/item/gun/proc/muzzle_flash_off()
set_light_on(FALSE)
/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = FALSE, atom/pbtarget = null, message = TRUE)
if(recoil && !tk_firing(user))
shake_camera(user, recoil + 1, recoil)
fire_sounds()
muzzle_flash_on()
if(suppressed || !message)
return FALSE
if(tk_firing(user))
@@ -607,6 +607,7 @@
suppressor = new_suppressor
suppressed = suppressor.suppression
update_weight_class(w_class + suppressor.w_class) //so pistols do not fit in pockets when suppressed
can_muzzle_flash = FALSE
update_appearance()
/obj/item/gun/ballistic/clear_suppressor()
@@ -616,6 +617,7 @@
if(suppressor)
update_weight_class(w_class - suppressor.w_class)
suppressor = null
can_muzzle_flash = initial(can_muzzle_flash)
update_appearance()
/obj/item/gun/ballistic/click_alt(mob/user)
@@ -11,6 +11,7 @@
w_class = WEIGHT_CLASS_NORMAL
pin = /obj/item/firing_pin/implant/pindicate
bolt_type = BOLT_TYPE_NO_BOLT
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted
pin = /obj/item/firing_pin
@@ -90,6 +91,7 @@
cartridge_wording = "rocket"
empty_indicator = TRUE
tac_reloads = FALSE
can_muzzle_flash = FALSE
/// Do we shit flames behind us when we fire?
var/backblast = TRUE
@@ -14,6 +14,7 @@
item_flags = NONE
gun_flags = TOY_FIREARM_OVERLAY | NOT_A_REAL_GUN
casing_ejector = FALSE
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/automatic/toy/riot
spawn_magazine_type = /obj/item/ammo_box/magazine/toy/smg/riot
@@ -49,6 +50,7 @@
weapon_weight = WEAPON_LIGHT
pb_knockback = 0
gun_flags = TOY_FIREARM_OVERLAY | NOT_A_REAL_GUN
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/shotgun/toy/handle_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE)
. = ..()
@@ -75,6 +77,7 @@
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
gun_flags = NONE
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/shotgun/toy/crossbow/riot
spawn_magazine_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow/riot
@@ -89,6 +92,7 @@
casing_ejector = FALSE
clumsy_check = FALSE
gun_flags = TOY_FIREARM_OVERLAY | NOT_A_REAL_GUN
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted //Use this for actual toys
pin = /obj/item/firing_pin
@@ -108,6 +112,7 @@
casing_ejector = FALSE
clumsy_check = FALSE
gun_flags = TOY_FIREARM_OVERLAY | NOT_A_REAL_GUN
can_muzzle_flash = FALSE
/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted //Use this for actual toys
pin = /obj/item/firing_pin
+2
View File
@@ -238,6 +238,8 @@
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
fire_sound = shot.fire_sound
fire_delay = shot.delay
if (shot.muzzle_flash_color)
set_light_color(shot.muzzle_flash_color)
if (shot.select_name && user)
balloon_alert(user, "set to [shot.select_name]")
chambered = null
@@ -19,6 +19,7 @@
w_class = WEIGHT_CLASS_BULKY
ammo_type = list(/obj/item/ammo_casing/energy/event_horizon)
selfcharge = TRUE
light_color = COLOR_STRONG_BLUE
self_charge_amount = STANDARD_ENERGY_GUN_SELF_CHARGE_RATE * 10
/obj/item/gun/energy/event_horizon/Initialize(mapload)
@@ -7,6 +7,7 @@
ammo_type = list(/obj/item/ammo_casing/energy/laser/musket)
slot_flags = ITEM_SLOT_BACK
obj_flags = UNIQUE_RENAME
light_color = COLOR_PURPLE
/obj/item/gun/energy/laser/musket/add_bayonet_point()
AddComponent(/datum/component/bayonet_attachable, offset_x = 22, offset_y = 11)
@@ -118,6 +119,7 @@
While it doesn't manipulate temperature in and of itself, it does cause an violent eruption in anyone who is severely cold. Able to generate \
ammunition by manually spinning the weapon's nanite canister."
icon_state = "infernopistol"
light_color = COLOR_RED
ammo_type = list(/obj/item/ammo_casing/energy/nanite/inferno)
/obj/item/gun/energy/laser/thermal/cryo //the ice gun
@@ -126,6 +128,7 @@
While it doesn't manipulate temperature in and of itself, it does cause an internal explosion in anyone who is severely hot. Able to generate \
ammunition by manually spinning the weapon's nanite canister."
icon_state = "cryopistol"
light_color = COLOR_BLUE
ammo_type = list(/obj/item/ammo_casing/energy/nanite/cryo)
// The Deep Lore //
@@ -8,6 +8,7 @@
modifystate = TRUE
ammo_x_offset = 3
dual_wield_spread = 60
light_color = LIGHT_COLOR_CYAN
/obj/item/gun/energy/e_gun/Initialize(mapload)
. = ..()
@@ -7,6 +7,7 @@
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT)
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
shaded_charge = TRUE
light_color = COLOR_SOFT_RED
/obj/item/gun/energy/laser/Initialize(mapload)
. = ..()
@@ -144,6 +145,7 @@
icon_state = "hellgun"
ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire)
ammo_x_offset = 1
light_color = COLOR_AMMO_HELLFIRE
/obj/item/gun/energy/laser/captain
name = "antique laser gun"
@@ -157,6 +159,7 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire)
light_color = COLOR_AMMO_HELLFIRE
/obj/item/gun/energy/laser/captain/scattershot
name = "scatter shot laser rifle"
@@ -233,6 +236,7 @@
ammo_type = list(/obj/item/ammo_casing/energy/xray)
ammo_x_offset = 3
shaded_charge = FALSE
light_color = LIGHT_COLOR_GREEN
////////Laser Tag////////////////////
@@ -9,6 +9,7 @@
modifystate = TRUE
obj_flags = CONDUCTS_ELECTRICITY
slot_flags = ITEM_SLOT_BACK
light_color = COLOR_BLUE
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
cell_type = /obj/item/stock_parts/power_store/cell/pulse
@@ -9,6 +9,7 @@
obj_flags = CONDUCTS_ELECTRICITY
slot_flags = ITEM_SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/ion)
light_color = LIGHT_COLOR_BLUE
/obj/item/gun/energy/ionrifle/Initialize(mapload)
. = ..()
@@ -3,6 +3,7 @@
desc = "A low-capacity, energy-based stun gun used by security teams to subdue targets at range."
icon_state = "taser"
inhand_icon_state = null //so the human update icon uses the icon_state instead.
light_color = LIGHT_COLOR_DIM_YELLOW
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 3
+1
View File
@@ -9,6 +9,7 @@
fire_sound = 'sound/items/weapons/emitter.ogg'
obj_flags = CONDUCTS_ELECTRICITY
w_class = WEIGHT_CLASS_HUGE
can_muzzle_flash = FALSE
///what kind of magic is this
var/school = SCHOOL_EVOCATION
var/antimagic_flags = MAGIC_RESISTANCE
@@ -6,6 +6,7 @@
icon_state = "chemgun"
inhand_icon_state = "chemgun"
w_class = WEIGHT_CLASS_NORMAL
can_muzzle_flash = FALSE
throw_speed = 3
throw_range = 7
force = 4
@@ -5,6 +5,7 @@
icon_state = "riotgun"
inhand_icon_state = "riotgun"
w_class = WEIGHT_CLASS_BULKY
can_muzzle_flash = FALSE
throw_speed = 2
throw_range = 7
force = 5
@@ -18,6 +18,7 @@
sharpness = SHARP_POINTY
force = 18
antimagic_flags = NONE
can_muzzle_flash = FALSE
/obj/item/gun/magic/hook/shoot_with_empty_chamber(mob/living/user)
balloon_alert(user, "not ready yet!")
@@ -6,6 +6,7 @@
inhand_icon_state = "chronogun"
w_class = WEIGHT_CLASS_NORMAL
item_flags = parent_type::item_flags & ~NEEDS_PERMIT
can_muzzle_flash = FALSE
var/mob/living/current_target
var/last_check = 0
@@ -19,6 +19,7 @@
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT)
clumsy_check = FALSE
fire_sound = 'sound/items/syringeproj.ogg'
can_muzzle_flash = FALSE
gun_flags = NOT_A_REAL_GUN
var/load_sound = 'sound/items/weapons/gun/shotgun/insert_shell.ogg'
var/list/syringes = list()