From 61b7b077ca8f1cc2dff5a2235cfcaf737004f5b7 Mon Sep 17 00:00:00 2001 From: FatalErr42O <58855799+FatalError42O@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:46:48 -0700 Subject: [PATCH] added mixing between bullet whizz and cracking noises --- classes/Bullet_ray.lua | 69 ++++++++++++++++++++++++++++-------------- classes/Gun.lua | 8 ++++- init.lua | 2 ++ play_sound.lua | 9 +++--- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/classes/Bullet_ray.lua b/classes/Bullet_ray.lua index 1f81d1f..24d32e9 100644 --- a/classes/Bullet_ray.lua +++ b/classes/Bullet_ray.lua @@ -16,31 +16,33 @@ local ray = { --[1] will be preferred if present supersonic = { sound = "bullet_crack", - max_hear_distance = 3, + --max_hear_distance = 3, pitch = { - min = .6, - max = 1.5 + min = 1.2, + max = 1 }, gain = { - min = .9, --this uses distance instead of randomness - max = .4 + min = -.5, --this uses distance instead of randomness + max = 1 } }, subsonic = { sound = "bullet_whizz", - max_hear_distance = 3, + --max_hear_distance = 3, pitch = { - min = .5, + min = .7, max = 1.5 }, gain = { - min = .3, --this uses distance instead of randomness - max = .9 + min = 0, --this uses distance instead of randomness + max = 1 } }, }, supersonic_energy = Guns4d.config.minimum_supersonic_energy_assumption, - pass_sound_max_distance = 3, + pass_sound_max_distance = 6, + mix_supersonic_and_subsonic_sounds = Guns4d.config.mix_supersonic_and_subsonic_sounds, + pass_sound_mixing_factor = Guns4d.config.default_pass_sound_mixing_factor, --determines the ratio to use based on energy damage = 0, energy = 0, ITERATION_DISTANCE = Guns4d.config.default_penetration_iteration_distance, @@ -150,7 +152,7 @@ function ray:_iterate(initialized) --minetest.chat_send_all((distance*self.energy_dropoff)) --minetest.chat_send_all((distance)) if next_state == "transverse" then - print(vector.distance(self.pos, end_pos), vector.distance(self.pos, self.pos+(self.dir*self.range))) + --print(vector.distance(self.pos, end_pos), vector.distance(self.pos, self.pos+(self.dir*self.range))) self:bullet_hole(end_pos, end_normal) end else @@ -302,21 +304,42 @@ function ray:play_bullet_pass_sounds() if #self.history > i then v1 = v[i+1].energy else v1 = self.init_energy end local v2 = v.energy - local ratio = vector.distance(start_pos, nearest)/vector.distance(start_pos, pos) - local energy_at_point = v1+((v2-v1)*(1-ratio)) + local ip_r = vector.distance(start_pos, nearest)/vector.distance(start_pos, pos) + local energy_at_point = v1+((v2-v1)*(1-ip_r)) + local relative_distance = vector.distance(nearest, pos)/self.pass_sound_max_distance - local sound = self.pass_sounds.subsonic - if energy_at_point >= self.supersonic_energy then - sound = self.pass_sounds.supersonic - end - sound = Guns4d.table.deep_copy(sound) - sound.pos = nearest - for _, t in pairs({"gain", "pitch"}) do - if sound[t].min then - sound[t] = sound[t].max+((sound[t].min-sound[t].max)*(vector.distance(nearest, pos)/self.pass_sound_max_distance)) + if self.mix_supersonic_and_subsonic_sounds then + local f = self.pass_sound_mixing_factor + local x = (energy_at_point*relative_distance)/self.supersonic_energy + local denominator = ((x-1)+math.sqrt(f))^2 + local mix_ratio = Guns4d.math.clamp(1-(f/denominator), 0,1) + local sounds = {Guns4d.table.deep_copy(self.pass_sounds.supersonic), Guns4d.table.deep_copy(self.pass_sounds.subsonic)} + for _, sound in pairs(sounds) do + for _, t in pairs({"gain", "pitch"}) do + if sound[t].min then + sound[t] = sound[t].max+((sound[t].min-sound[t].max)*relative_distance) + end + end end + minetest.chat_send_all(dump({f, x, denominator, mix_ratio})) + sounds[1].gain = sounds[1].gain*mix_ratio --supersonic + sounds[2].gain = sounds[2].gain*(1-mix_ratio) --subsonic + sounds.pos = nearest + Guns4d.play_sounds(sounds) + + local sound = self.pass_sounds.subsonic + if energy_at_point >= self.supersonic_energy then + sound = self.pass_sounds.supersonic + end + sound = Guns4d.table.deep_copy(sound) + sound.pos = nearest + for _, t in pairs({"gain", "pitch"}) do + if sound[t].min then + sound[t] = sound[t].max+((sound[t].min-sound[t].max)*relative_distance) + end + end + Guns4d.play_sounds(sound) end - Guns4d.play_sounds(sound) end end end diff --git a/classes/Gun.lua b/classes/Gun.lua index a100b66..dde7495 100644 --- a/classes/Gun.lua +++ b/classes/Gun.lua @@ -298,6 +298,12 @@ function gun_default:draw() if props.visuals.animations.draw then self:set_animation(props.visuals.animations.draw, props.charging.default_draw_time) end + if props.sounds.draw then + local sounds = Guns4d.table.deep_copy(props.sounds.draw) + sounds.player = self.player + sounds.pos = self.pos + Guns4d.play_sounds(sounds) + end self.ammo_handler:chamber_round() self.rechamber_time = props.charging.default_draw_time end @@ -446,7 +452,7 @@ function gun_default:attempt_fire() self:recoil() self:muzzle_flash() - print(dump(self.properties.sounds.fire)) + --print(dump(self.properties.sounds.fire)) local fire_sound = Guns4d.table.deep_copy(self.properties.sounds.fire) --important that we copy because play_sounds modifies it. fire_sound.pos = self.pos Guns4d.play_sounds(fire_sound) diff --git a/init.lua b/init.lua index a53882a..be45f4b 100644 --- a/init.lua +++ b/init.lua @@ -23,6 +23,8 @@ Guns4d.config = { headshot_damage_factor = 1.75, enable_touchscreen_command_name = "guns4d_enable_touchmode", minimum_supersonic_energy_assumption = 900, --used to determine the energy of a "supersonic" bullet for bullet whizzing sound effects + mix_supersonic_and_subsonic_sounds = true, + default_pass_sound_mixing_factor = 10, default_penetration_iteration_distance = .25, --`["official_content.replace_ads_with_bloom"] = false, --`["official_content.uses_magazines"] = true diff --git a/play_sound.lua b/play_sound.lua index fdb726a..423d7bb 100644 --- a/play_sound.lua +++ b/play_sound.lua @@ -85,9 +85,9 @@ function Guns4d.play_sounds(soundspecs_list) local handle = #sound_handles+1 --determine the sound handle before playing sound_handles[handle] = {} local handle_object = sound_handles[handle] - for i, soundspec in pairs(soundspecs_list) do + for arg, soundspec in pairs(soundspecs_list) do if soundspec.to_player == "from_player" then soundspec.to_player = soundspec.player:get_player_name() end --setter of sound may not have access to this info, so add a method to use it. - assert(not (soundspec.to_player and soundspec.min_distance), "in argument '"..tostring(i).."' `min_distance` and `to_player` are incompatible parameters.") + assert(not (soundspec.to_player and soundspec.min_distance), "in argument '"..tostring(arg).."' `min_distance` and `to_player` are incompatible parameters.") local sound = soundspec.sound local outval for i, v in pairs(soundspec) do @@ -117,12 +117,13 @@ function Guns4d.play_sounds(soundspecs_list) if (dist > soundspec.min_hear_distance) and (player~=exclude_player_ref) then soundspec.exclude_player = nil --not needed anyway because we can just not play it for this player. soundspec.to_player = player:get_player_name() - play_sound(sound, soundspec, handle, i) + play_sound(sound, soundspec, handle, arg) end end else + print(dump(soundspec)) soundspec.sound = nil - play_sound(sound, soundspec, handle, i) + play_sound(sound, soundspec, handle, arg) end end return handle