added bullet wizz
This commit is contained in:
parent
e6d7ef4a8b
commit
1cc8016732
@ -26,7 +26,7 @@ minetest.register_on_mods_loaded(function()
|
|||||||
RHA = RHA / groups.oddly_breakable_by_hand
|
RHA = RHA / groups.oddly_breakable_by_hand
|
||||||
end
|
end
|
||||||
if groups.choppy then
|
if groups.choppy then
|
||||||
RHA = RHA/(5*groups.choppy)
|
RHA = RHA/(10*groups.choppy)
|
||||||
end
|
end
|
||||||
if groups.flora or groups.grass then
|
if groups.flora or groups.grass then
|
||||||
RHA = 0
|
RHA = 0
|
||||||
|
@ -12,8 +12,38 @@ local ray = {
|
|||||||
sharp_to_blunt_conversion_factor = .5, -- 1mmRHA is converted to 1mPA of blunt force
|
sharp_to_blunt_conversion_factor = .5, -- 1mmRHA is converted to 1mPA of blunt force
|
||||||
blunt_damage_groups = {}, --minetest.deserialize(Guns4d.config.default_blunt_groups), --these are multiplied by blunt_damage
|
blunt_damage_groups = {}, --minetest.deserialize(Guns4d.config.default_blunt_groups), --these are multiplied by blunt_damage
|
||||||
sharp_damage_groups = {}, --minetest.deserialize(Guns4d.config.default_sharp_groups),
|
sharp_damage_groups = {}, --minetest.deserialize(Guns4d.config.default_sharp_groups),
|
||||||
ITERATION_DISTANCE = .3,
|
pass_sounds = {
|
||||||
damage = 0
|
--[1] will be preferred if present
|
||||||
|
supersonic = {
|
||||||
|
sound = "bullet_crack",
|
||||||
|
max_hear_distance = 3,
|
||||||
|
pitch = {
|
||||||
|
min = .6,
|
||||||
|
max = 1.5
|
||||||
|
},
|
||||||
|
gain = {
|
||||||
|
min = .9, --this uses distance instead of randomness
|
||||||
|
max = .4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subsonic = {
|
||||||
|
sound = "bullet_whizz",
|
||||||
|
max_hear_distance = 3,
|
||||||
|
pitch = {
|
||||||
|
min = .5,
|
||||||
|
max = 1.5
|
||||||
|
},
|
||||||
|
gain = {
|
||||||
|
min = .3, --this uses distance instead of randomness
|
||||||
|
max = .9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
supersonic_energy = Guns4d.config.minimum_supersonic_energy_assumption,
|
||||||
|
pass_sound_max_distance = 3,
|
||||||
|
damage = 0,
|
||||||
|
energy = 0,
|
||||||
|
ITERATION_DISTANCE = Guns4d.config.default_penetration_iteration_distance,
|
||||||
}
|
}
|
||||||
|
|
||||||
--find (valid) edge. Slabs or other nodeboxes that are not the last hit position are not considered (to account for holes) TODO: update to account for hollow nodes
|
--find (valid) edge. Slabs or other nodeboxes that are not the last hit position are not considered (to account for holes) TODO: update to account for hollow nodes
|
||||||
@ -250,29 +280,69 @@ function ray:bullet_hole(pos, normal)
|
|||||||
Guns4d.effects.spawn_bullet_hole_particle(pos, self.hole_scale, '(bullet_hole_1.png^(bullet_hole_2.png^[opacity:129))')
|
Guns4d.effects.spawn_bullet_hole_particle(pos, self.hole_scale, '(bullet_hole_1.png^(bullet_hole_2.png^[opacity:129))')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function ray:play_bullet_pass_sounds()
|
||||||
|
--iteration done, damage applied, find players to apply bullet whizz to
|
||||||
|
local start_pos = self.init_pos
|
||||||
|
local played_for = {}
|
||||||
|
for i = #self.history, 1, -1 do
|
||||||
|
local v = self.history[i]
|
||||||
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
|
if (player~=self.player) and not played_for[player] then
|
||||||
|
local pos = player:get_pos()+vector.new(0,player:get_properties().eye_height,0)
|
||||||
|
local nearest = Guns4d.nearest_point_on_line(start_pos, v.pos, pos)
|
||||||
|
if vector.distance(nearest, pos) < self.pass_sound_max_distance then
|
||||||
|
played_for[player] = true
|
||||||
|
if self.pass_sounds[1] then
|
||||||
|
local sound = Guns4d.table.deep_copy(self.pass_sounds[1])
|
||||||
|
sound.pos = nearest
|
||||||
|
Guns4d.play_sounds(self.pass_sounds[1])
|
||||||
|
else
|
||||||
|
--interpolate to find the energy of the shot to determine supersonic or not.
|
||||||
|
local v1
|
||||||
|
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 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))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Guns4d.play_sounds(sound)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
start_pos = v.pos
|
||||||
|
end
|
||||||
|
end
|
||||||
function ray.construct(def)
|
function ray.construct(def)
|
||||||
if def.instance then
|
if def.instance then
|
||||||
assert(def.player, "no player")
|
--these asserts aren't necessary, probably drags down performance a tiny bit.
|
||||||
|
|
||||||
|
--[[assert(def.player, "no player")
|
||||||
assert(def.pos, "no position")
|
assert(def.pos, "no position")
|
||||||
assert(def.dir, "no direction")
|
assert(def.dir, "no direction")
|
||||||
|
|
||||||
assert(def.gun, "no Gun object")
|
assert(def.gun, "no Gun object")
|
||||||
assert(def.range, "no range")
|
assert(def.range, "no range")
|
||||||
assert(def.energy, "no energy")
|
assert(def.energy, "no energy")
|
||||||
assert(def.energy_dropoff, "no energy dropoff")
|
assert(def.energy_dropoff, "no energy dropoff")]]
|
||||||
|
|
||||||
--use this if you don't want to use the built-in system for penetrations.
|
--use this if you don't want to use the built-in system for penetrations.
|
||||||
assert(not(def.ignore_penetration and not rawget(def, "hit_entity")), "bullet ray cannot ignore default penetration if hit_entity() is undefined. Use ignore_penetration for custom damage systems." )
|
-- assert((not (def.blunt_penetration and def.energy)) or (def.blunt_penetration < def.energy), "blunt penetration may not be greater than energy! Blunt penetration is in Joules/Megapascals, energy is also in Joules.")
|
||||||
if not def.ignore_penetration then
|
|
||||||
assert((not (def.blunt_penetration and def.energy)) or (def.blunt_penetration < def.energy), "blunt penetration may not be greater than energy! Blunt penetration is in Joules/Megapascals, energy is also in Joules.")
|
|
||||||
|
|
||||||
--"raw" damages define the damage (unaffected by armor groups) for the initial penetration value of each type.
|
|
||||||
--def.sharp_damage_groups = {} --tool capabilities
|
|
||||||
--def.blunt_damage_groups = {}
|
|
||||||
|
|
||||||
--guns4d mmRHA is used in traditional context.
|
--guns4d mmRHA is used in traditional context.
|
||||||
assert((not def.blunt_damage_groups) or not def.blunt_damage_groups["guns4d_mmRHA"], "guns4d_mmRHA damage group is not used in a traditional context. To increase penetration, increase sharp_penetration field.")
|
--assert((not def.blunt_damage_groups) or not def.blunt_damage_groups["guns4d_mmRHA"], "guns4d_mmRHA damage group is not used in a traditional context. To increase penetration, increase sharp_penetration field.")
|
||||||
assert((not def.blunt_damage_groups) or not def.blunt_damage_groups["guns4d_Pa"], "guns4d_Pa is not used in a traditional context. To increase blunt penetration, increase blunt_penetration field.")
|
--assert((not def.blunt_damage_groups) or not def.blunt_damage_groups["guns4d_Pa"], "guns4d_Pa is not used in a traditional context. To increase blunt penetration, increase blunt_penetration field.")
|
||||||
|
|
||||||
|
|
||||||
def.raw_sharp_damage = def.raw_sharp_damage or 0
|
def.raw_sharp_damage = def.raw_sharp_damage or 0
|
||||||
@ -284,14 +354,16 @@ function ray.construct(def)
|
|||||||
def.blunt_penetration = def.blunt_penetration or def.energy
|
def.blunt_penetration = def.blunt_penetration or def.energy
|
||||||
end
|
end
|
||||||
def.energy_sharp_ratio = (def.energy-def.blunt_penetration)/def.energy
|
def.energy_sharp_ratio = (def.energy-def.blunt_penetration)/def.energy
|
||||||
end
|
|
||||||
def.init_energy = def.energy
|
def.init_energy = def.energy
|
||||||
--blunt pen is in the same units (1 Joule/Area^3 = 1 Pa), so we use it to make the ratio by subtraction.
|
--blunt pen is in the same units (1 Joule/Area^3 = 1 Pa), so we use it to make the ratio by subtraction.
|
||||||
|
|
||||||
def.dir = vector.new(def.dir)
|
def.dir = vector.new(def.dir)
|
||||||
def.pos = vector.new(def.pos)
|
def.pos = vector.new(def.pos)
|
||||||
def.history = {}
|
def.history = {}
|
||||||
|
def.init_pos = vector.new(def.pos) --has to be cloned before iteration
|
||||||
def:_iterate()
|
def:_iterate()
|
||||||
|
def:play_bullet_pass_sounds()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Guns4d.bullet_ray = Instantiatable_class:inherit(ray)
|
Guns4d.bullet_ray = Instantiatable_class:inherit(ray)
|
4
init.lua
4
init.lua
@ -22,6 +22,8 @@ Guns4d.config = {
|
|||||||
default_fov = 80,
|
default_fov = 80,
|
||||||
headshot_damage_factor = 1.75,
|
headshot_damage_factor = 1.75,
|
||||||
enable_touchscreen_command_name = "guns4d_enable_touchmode",
|
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
|
||||||
|
default_penetration_iteration_distance = .25,
|
||||||
--`["official_content.replace_ads_with_bloom"] = false,
|
--`["official_content.replace_ads_with_bloom"] = false,
|
||||||
--`["official_content.uses_magazines"] = true
|
--`["official_content.uses_magazines"] = true
|
||||||
}
|
}
|
||||||
@ -29,7 +31,7 @@ local path = minetest.get_modpath("guns4d")
|
|||||||
|
|
||||||
print("file read?")
|
print("file read?")
|
||||||
local conf = Settings(path.."/guns4d_settings.conf"):to_table() or {}
|
local conf = Settings(path.."/guns4d_settings.conf"):to_table() or {}
|
||||||
local mt_conf = minetest.settings:to_table()
|
local mt_conf = minetest.settings:to_table() --allow use of MT config for servers that regularly update 4dguns through it's development
|
||||||
for i, v in pairs(Guns4d.config) do
|
for i, v in pairs(Guns4d.config) do
|
||||||
--Guns4d.config[i] = conf[i] or minetest.settings["guns4d."..i] or Guns4d.config[i]
|
--Guns4d.config[i] = conf[i] or minetest.settings["guns4d."..i] or Guns4d.config[i]
|
||||||
--cant use or because it'd evaluate to false if the setting is alse
|
--cant use or because it'd evaluate to false if the setting is alse
|
||||||
|
@ -284,3 +284,16 @@ function Guns4d.rltv_point_to_hud(pos, fov, aspect)
|
|||||||
local z = (pos.z/pos.z)*a11
|
local z = (pos.z/pos.z)*a11
|
||||||
return {x=x / 2,y=-y / 2} --output needs to be offset by +.5 on both for HUD elements, but this cannot be integrated.
|
return {x=x / 2,y=-y / 2} --output needs to be offset by +.5 on both for HUD elements, but this cannot be integrated.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Code: Elkien3 (CC BY-SA 3.0)
|
||||||
|
--https://github.com/Elkien3/spriteguns/blob/1c632fe12c35c840d6c0b8307c76d4dfa44d1bd7/init.lua#L76
|
||||||
|
function Guns4d.nearest_point_on_line(lineStart, lineEnd, pnt)
|
||||||
|
local line = vector.subtract(lineEnd, lineStart)
|
||||||
|
local len = vector.length(line)
|
||||||
|
line = vector.normalize(line)
|
||||||
|
|
||||||
|
local v = vector.subtract(pnt, lineStart)
|
||||||
|
local d = vector.dot(v, line)
|
||||||
|
d = Guns4d.math.clamp(d, 0, len);
|
||||||
|
return vector.add(lineStart, vector.multiply(line, d))
|
||||||
|
end
|
@ -32,8 +32,10 @@ local sqrt = math.sqrt
|
|||||||
-- however has the following changed or guns4d specific parameters.
|
-- however has the following changed or guns4d specific parameters.
|
||||||
-- @field min_hear_distance this is useful if you wish to play a sound which has a "far" sound, such as distant gunshots. incompatible `with to_player`
|
-- @field min_hear_distance this is useful if you wish to play a sound which has a "far" sound, such as distant gunshots. incompatible `with to_player`
|
||||||
-- @field sounds a @{misc_helpers.weighted_randoms| weighted_randoms table} for randomly selecting sounds. The output will overwrite the `sound` field.
|
-- @field sounds a @{misc_helpers.weighted_randoms| weighted_randoms table} for randomly selecting sounds. The output will overwrite the `sound` field.
|
||||||
-- @field to_player 4dguns changes `to_player` so it only plays positionless audio (as it is only intended for first person audio)
|
-- @field to_player 4dguns changes `to_player` so it only plays positionless audio (as it is only intended for first person audio). If set to string "from_player" and player present
|
||||||
|
-- @field player this is so to_player being set to "from_player". It's to be set to the player which fired the weapon.
|
||||||
-- @field delay delay the playing of the sound
|
-- @field delay delay the playing of the sound
|
||||||
|
-- @field has_speed_of_sound = true
|
||||||
-- @table guns4d_soundspec
|
-- @table guns4d_soundspec
|
||||||
|
|
||||||
local function handle_min_max(tbl)
|
local function handle_min_max(tbl)
|
||||||
@ -84,6 +86,7 @@ function Guns4d.play_sounds(soundspecs_list)
|
|||||||
sound_handles[handle] = {}
|
sound_handles[handle] = {}
|
||||||
local handle_object = sound_handles[handle]
|
local handle_object = sound_handles[handle]
|
||||||
for i, soundspec in pairs(soundspecs_list) do
|
for i, 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(i).."' `min_distance` and `to_player` are incompatible parameters.")
|
||||||
local sound = soundspec.sound
|
local sound = soundspec.sound
|
||||||
local outval
|
local outval
|
||||||
@ -95,9 +98,9 @@ function Guns4d.play_sounds(soundspecs_list)
|
|||||||
if type(sound) == "table" then
|
if type(sound) == "table" then
|
||||||
sound = Guns4d.math.weighted_randoms(sound)
|
sound = Guns4d.math.weighted_randoms(sound)
|
||||||
end
|
end
|
||||||
assert(sound, "no sound found")
|
assert(sound, "no sound provided")
|
||||||
if not mtul.paths.media_paths[sound..".ogg"] then
|
if not mtul.paths.media_paths[(sound or "[NIL]")..".ogg"] then
|
||||||
minetest.log("error", "no sound by the name `"..mtul.paths.media_paths[sound..".ogg"].."`")
|
minetest.log("error", "no sound by the name `"..mtul.paths.media_paths[(sound or "[NIL]")..".ogg"].."`")
|
||||||
end
|
end
|
||||||
--print(dump(soundspecs_list), i)
|
--print(dump(soundspecs_list), i)
|
||||||
if soundspec.to_player then soundspec.pos = nil end
|
if soundspec.to_player then soundspec.pos = nil end
|
||||||
|
BIN
sounds/elkien/bullet_crack.ogg
Normal file
BIN
sounds/elkien/bullet_crack.ogg
Normal file
Binary file not shown.
BIN
sounds/elkien/bullet_whizz.ogg
Normal file
BIN
sounds/elkien/bullet_whizz.ogg
Normal file
Binary file not shown.
14
sounds/elkien/license.txt
Normal file
14
sounds/elkien/license.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
license info is WIP, I borrowed code and textures/sounds from a lot of places so if you find license info that I have forgotten please let me know.
|
||||||
|
|
||||||
|
Code: Elkien3 (CC BY-SA 3.0)
|
||||||
|
Textures:
|
||||||
|
binoculars_binoculars.png (from Minetest Game): Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) Copyright (C) 2017 paramat
|
||||||
|
rangedweapons_*: bullets unedited, most of the others are edited from the guns from rangedweapons. (cc-by-sa 4.0 davidthecreator)
|
||||||
|
All others: Elkien3 (CC BY-SA 3.0)
|
||||||
|
Models: (CC BY-SA 3.0)
|
||||||
|
Modelers: Elkien3 (Colt Army), Extex (Remington870, Thompson, Pardini), FatalError (CZ, Mini14, Binoculars).
|
||||||
|
All tweaked and animated by Elkien3
|
||||||
|
Sounds:
|
||||||
|
I renamed some of them and don't remember exactly where each of them came from.
|
||||||
|
I do know some came from rangedweapons (cc-by-sa 4.0 davidthecreator)
|
||||||
|
The rest were sourced from youtube that were largely marked royalty free.
|
Loading…
x
Reference in New Issue
Block a user