Merge pull request #6829 from Neerti/projectile_hit_sounds

QoL: Projectiles
This commit is contained in:
Atermonera
2020-03-16 21:55:24 -07:00
committed by GitHub
30 changed files with 283 additions and 44 deletions

View File

@@ -359,6 +359,9 @@
handle_click_empty(user)
break
if(i == 1) // So one burst only makes one message and not 3+ messages.
handle_firing_text(user, target, pointblank, reflex)
process_accuracy(projectile, user, target, i, held_twohanded)
if(pointblank)
@@ -387,14 +390,6 @@
if(one_handed_penalty >= 20)
to_chat(user, "<span class='warning'>You struggle to keep \the [src] pointed at the correct position with just one hand!</span>")
var/target_for_log
if(ismob(target))
target_for_log = target
else
target_for_log = "[target.name]"
add_attack_logs(user,target_for_log,"Fired gun [src.name] ([reflex ? "REFLEX" : "MANUAL"])")
//update timing
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.setMoveCooldown(move_delay)
@@ -500,11 +495,9 @@
src.visible_message("*click click*")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
//called after successfully firing
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(fire_anim)
flick(fire_anim, src)
// Called when the user is about to fire.
// Moved from handle_post_fire() because if using a laser, the message for when someone got shot would show up before the firing message.
/obj/item/weapon/gun/proc/handle_firing_text(mob/user, atom/target, pointblank = FALSE, reflex = FALSE)
if(silenced)
to_chat(user, "<span class='warning'>You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex":""]</span>")
for(var/mob/living/L in oview(2,user))
@@ -521,6 +514,19 @@
"You hear a [fire_sound_text]!"
)
var/target_for_log
if(ismob(target))
target_for_log = target
else
target_for_log = "[target.name]"
add_attack_logs(user, target_for_log, "Fired gun '[src.name]' ([reflex ? "REFLEX" : "MANUAL"])")
//called after successfully firing
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(fire_anim)
flick(fire_anim, src)
if(muzzle_flash)
set_light(muzzle_flash)

View File

@@ -10,6 +10,8 @@
unacidable = TRUE
pass_flags = PASSTABLE
mouse_opacity = 0
hitsound = 'sound/weapons/pierce.ogg'
var/hitsound_wall = null // Played when something hits a wall, or anything else that isn't a mob.
////TG PROJECTILE SYTSEM
//Projectile stuff
@@ -128,12 +130,18 @@
var/temporary_unstoppable_movement = FALSE
// When a non-hitscan projectile hits something, a visual effect can be spawned.
// This is distinct from the hitscan's "impact_type" var.
var/impact_effect_type = null
/obj/item/projectile/proc/Range()
range--
if(range <= 0 && loc)
on_range()
/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range
impact_sounds(loc)
impact_visuals(loc) // So it does a little 'burst' effect, but not actually do anything (unless overrided).
qdel(src)
/obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight.
@@ -444,10 +452,14 @@
qdel(beam_index)
/obj/item/projectile/proc/vol_by_damage()
if(damage)
return CLAMP((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
if(damage || agony)
var/value_to_use = damage > agony ? damage : agony
// Multiply projectile damage by 1.2, then CLAMP the value between 30 and 100.
// This was 0.67 but in practice it made all projectiles that did 45 or less damage play at 30,
// which is hard to hear over the gunshots, and is rather rare for a projectile to do that much.
return CLAMP((value_to_use) * 1.2, 30, 100)
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume.
return 50 //if the projectile doesn't do damage or agony, play its hitsound at 50% volume.
/obj/item/projectile/proc/finalize_hitscan_and_generate_tracers(impacting = TRUE)
if(trajectory && beam_index)
@@ -588,6 +600,9 @@
//called when the projectile stops flying because it Bump'd with something
/obj/item/projectile/proc/on_impact(atom/A)
impact_sounds(A)
impact_visuals(A)
if(damage && damage_type == BURN)
var/turf/T = get_turf(A)
if(T)
@@ -629,16 +644,27 @@
def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part
result = target_mob.bullet_act(src, def_zone)
if(!istype(target_mob))
return FALSE // Mob deleted itself or something.
if(result == PROJECTILE_FORCE_MISS)
if(!silenced)
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
target_mob.visible_message("<span class='notice'>\The [src] misses \the [target_mob] narrowly!</span>")
playsound(target_mob, "bullet_miss", 75, 1)
return FALSE
//hit messages
if(silenced)
to_chat(target_mob, "<span class='danger'>You've been hit in the [parse_zone(def_zone)] by \the [src]!</span>")
playsound(target_mob, hitsound, 5, 1, -1)
to_chat(target_mob, span("critical", "You've been hit in the [parse_zone(def_zone)] by \the [src]!"))
else
visible_message("<span class='danger'>\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
var/volume = vol_by_damage()
playsound(target_mob, hitsound, volume, 1, -1)
// X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
target_mob.visible_message(
span("danger", "\The [target_mob] was hit in the [parse_zone(def_zone)] by \the [src]!"),
span("critical", "You've been hit in the [parse_zone(def_zone)] by \the [src]!")
)
//admin logs
if(!no_attack_log)
@@ -743,3 +769,28 @@
preparePixelProjectile(target, get_turf(src), params, forced_spread)
return fire(angle_override, direct_target)
// Makes a brief effect sprite appear when the projectile hits something solid.
/obj/item/projectile/proc/impact_visuals(atom/A, hit_x, hit_y)
if(impact_effect_type && !hitscan) // Hitscan things have their own impact sprite.
if(isnull(hit_x) && isnull(hit_y))
if(trajectory)
// Effect goes where the projectile 'stopped'.
hit_x = A.pixel_x + trajectory.return_px()
hit_y = A.pixel_y + trajectory.return_py()
else if(A == original)
// Otherwise it goes where the person who fired clicked.
hit_x = A.pixel_x + p_x - 16
hit_y = A.pixel_y + p_y - 16
else
// Otherwise it'll be random.
hit_x = A.pixel_x + rand(-8, 8)
hit_y = A.pixel_y + rand(-8, 8)
new impact_effect_type(get_turf(A), src, hit_x, hit_y)
/obj/item/projectile/proc/impact_sounds(atom/A)
if(hitsound_wall && !ismob(A)) // Mob sounds are handled in attack_mob().
var/volume = CLAMP(vol_by_damage() + 20, 0, 100)
if(silenced)
volume = 5
playsound(get_turf(A), hitsound_wall, volume, 1, -1)

View File

@@ -14,6 +14,8 @@
light_range = 2
light_power = 0.5
light_color = "#FF0D00"
hitsound = 'sound/weapons/sear.ogg'
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
muzzle_type = /obj/effect/projectile/muzzle/laser
tracer_type = /obj/effect/projectile/tracer/laser
@@ -211,6 +213,7 @@
agony = 40
damage_type = HALLOSS
light_color = "#FFFFFF"
hitsound = 'sound/weapons/zapbang.ogg'
combustion = FALSE
@@ -257,3 +260,4 @@
damage = 30
agony = 15
eyeblur = 2
hitsound = 'sound/weapons/zapbang.ogg'

View File

@@ -8,6 +8,8 @@
check_armour = "bullet"
embed_chance = 20 //Modified in the actual embed process, but this should keep embed chance about the same
sharp = 1
hitsound_wall = "ricochet"
impact_effect_type = /obj/effect/temp_visual/impact_effect
var/mob_passthrough_check = 0
muzzle_type = /obj/effect/projectile/muzzle/bullet

View File

@@ -4,6 +4,11 @@
damage = 0
damage_type = BURN
check_armour = "energy"
impact_effect_type = /obj/effect/temp_visual/impact_effect
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
hitsound = 'sound/weapons/zapbang.ogg'
var/flash_strength = 10
//releases a burst of light on impact or after travelling a distance
@@ -11,6 +16,7 @@
name = "chemical shell"
icon_state = "bullet"
fire_sound = 'sound/weapons/gunshot_pathetic.ogg'
hitsound_wall = null
damage = 5
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
var/flash_range = 0
@@ -91,6 +97,7 @@
light_range = 2
light_power = 0.5
light_color = "#33CC00"
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
combustion = FALSE
@@ -157,6 +164,7 @@
light_range = 2
light_power = 0.5
light_color = "#33CC00"
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
combustion = FALSE
@@ -209,10 +217,11 @@
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage_type = BURN
check_armour = "energy"
light_color = "#0000FF"
light_color = "#00AAFF"
embed_chance = 0
muzzle_type = /obj/effect/projectile/muzzle/pulse
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
/obj/item/projectile/energy/phase
name = "phase wave"

View File

@@ -7,6 +7,9 @@
combustion = FALSE
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
/obj/item/projectile/forcebolt/strong
name = "force bolt"

View File

@@ -11,6 +11,9 @@
light_color = "#55AAFF"
combustion = FALSE
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
hitsound_wall = 'sound/weapons/effects/searwall.ogg'
hitsound = 'sound/weapons/ionrifle.ogg'
var/sev1_range = 0
var/sev2_range = 1
@@ -18,8 +21,8 @@
var/sev4_range = 1
/obj/item/projectile/ion/on_impact(var/atom/target)
empulse(target, sev1_range, sev2_range, sev3_range, sev4_range)
return 1
empulse(target, sev1_range, sev2_range, sev3_range, sev4_range)
..()
/obj/item/projectile/ion/small
sev1_range = -1
@@ -58,6 +61,7 @@
light_range = 2
light_power = 0.5
light_color = "#55AAFF"
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
combustion = FALSE
@@ -133,6 +137,7 @@
light_range = 2
light_power = 0.5
light_color = "#33CC00"
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
combustion = FALSE
@@ -189,6 +194,7 @@
light_range = 2
light_power = 0.5
light_color = "#FFFFFF"
impact_effect_type = /obj/effect/temp_visual/impact_effect/monochrome_laser
/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0)
var/mob/M = target
@@ -211,6 +217,7 @@
if(ishuman(target))
var/mob/living/carbon/human/M = target
M.Confuse(rand(5,8))
..()
/obj/item/projectile/chameleon
name = "bullet"