Split utils.lua in two
This commit is contained in:
parent
1c46e62cd8
commit
12ea3900b2
1
init.lua
1
init.lua
@ -11,6 +11,7 @@ weapons_lib.mods = {}
|
||||
dofile(srcpath .. "/api/bullets.lua")
|
||||
dofile(srcpath .. "/api/mods.lua")
|
||||
dofile(srcpath .. "/api/weapons.lua")
|
||||
dofile(srcpath .. "/api/weapons_utils.lua")
|
||||
dofile(srcpath .. "/player_manager.lua")
|
||||
dofile(srcpath .. "/utils.lua")
|
||||
dofile(srcpath .. "/HUD/hud_crosshair.lua")
|
||||
|
234
src/api/weapons_utils.lua
Normal file
234
src/api/weapons_utils.lua
Normal file
@ -0,0 +1,234 @@
|
||||
local function cast_raycast() end
|
||||
local function get_shooter_left_dir() end
|
||||
local function get_shooter_up_dir() end
|
||||
local function debug_particles() end
|
||||
|
||||
|
||||
|
||||
-- per bloccare fisica
|
||||
local dummy = {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
pointable = false,
|
||||
collide_with_objects = false,
|
||||
visual = "sprite",
|
||||
visual_size = {x = 0, y = 0, z = 0},
|
||||
textures = { "blank.png" }
|
||||
},
|
||||
|
||||
-- quando sbuca, se non ha prole, cancellala
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
minetest.after(0.1, function()
|
||||
if #self.object:get_children() == 0 then
|
||||
self.object:remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
minetest.register_entity("weapons_lib:dummy", dummy)
|
||||
|
||||
|
||||
|
||||
-- I cast a 2x2 grid (assisted aim) to prevent the 0.1 delay. The grid value is
|
||||
-- actually hardcoded because:
|
||||
-- 1. it works and I don't need more features from it
|
||||
-- 2. I haven't got enough knowledge about vectors and rotations anyway
|
||||
function weapons_lib.get_pointed_objects(shooter, range, has_piercing, entity_table)
|
||||
local height, look_dir
|
||||
|
||||
if entity_table then
|
||||
height = entity_table.height
|
||||
look_dir = entity_table.dir
|
||||
else
|
||||
height = 1.475
|
||||
look_dir = shooter:get_look_dir()
|
||||
end
|
||||
|
||||
local hit_pointed_things = {}
|
||||
local left_dir = get_shooter_left_dir(shooter)
|
||||
local head_up_dir = get_shooter_up_dir(shooter, look_dir)
|
||||
local center = shooter:get_pos() + look_dir + {x=0, y=height, z=0}
|
||||
|
||||
local grid_width = 0.25
|
||||
local r_amount = 2
|
||||
local x_step = (grid_width / r_amount) * (-left_dir)
|
||||
local y_step = (grid_width / r_amount) * head_up_dir
|
||||
local ray_pos = center + (x_step / r_amount) + (y_step / r_amount)
|
||||
|
||||
for row = 1, r_amount do
|
||||
for column = 1, r_amount do
|
||||
local pthings = cast_raycast(shooter, ray_pos, look_dir, range, has_piercing)
|
||||
--debug_particles(look_dir, ray_pos, 30)
|
||||
|
||||
if pthings then
|
||||
-- rimuovo giocator3 già colpit3 da altro raggio
|
||||
for k, possible_target in pairs(pthings) do
|
||||
local object = possible_target.object
|
||||
local target_name = possible_target.object:get_player_name() or possible_target.object:get_luaentity().name
|
||||
for _, target in pairs(hit_pointed_things) do
|
||||
local hit_target_name = target.object:get_player_name() or target.object:get_luaentity().name
|
||||
if target_name == hit_target_name then
|
||||
pthings[k] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.insert_all(hit_pointed_things, pthings)
|
||||
end
|
||||
|
||||
ray_pos = ray_pos - x_step
|
||||
end
|
||||
|
||||
ray_pos = ray_pos - y_step
|
||||
ray_pos = ray_pos + x_step * r_amount
|
||||
end
|
||||
|
||||
return hit_pointed_things
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
---------------FUNZIONI LOCALI----------------
|
||||
----------------------------------------------
|
||||
|
||||
-- ritorna un array di giocatori con il numero di giocatori trovati a indice 1.
|
||||
-- Se non trova giocatori diversi da se stesso ritorna nil
|
||||
function cast_raycast(user, origin, dir, range, has_piercing)
|
||||
local a = vector.add(origin, vector.multiply(dir, 0))
|
||||
local b = vector.add(origin, vector.multiply(dir, range))
|
||||
local ray = minetest.raycast(a, b)
|
||||
local objects = {}
|
||||
|
||||
-- controllo su ogni cosa attraversata dal raycast (da a a b)
|
||||
for hit in ray do
|
||||
-- se è un oggetto
|
||||
if hit.type == "object" then
|
||||
-- se è un'entità
|
||||
if not hit.ref:is_player() then
|
||||
local entity = hit.ref:get_luaentity()
|
||||
-- se collide con un proiettile, lo distrugge, sennò salva l'entità per il danno
|
||||
if entity._is_bullet then
|
||||
entity:_destroy()
|
||||
else
|
||||
table.insert(objects, {object=hit.ref, headshot=false})
|
||||
end
|
||||
|
||||
-- se è un giocatore (e non chi spara)
|
||||
elseif hit.ref ~= user then
|
||||
if (hit.intersection_point.y - hit.ref:get_pos().y) > 1.275 then
|
||||
table.insert(objects, {object=hit.ref, headshot=true})
|
||||
else
|
||||
table.insert(objects, {object=hit.ref, headshot=false})
|
||||
end
|
||||
end
|
||||
|
||||
local is_player = hit.ref:is_player()
|
||||
local t_name = is_player and hit.ref:get_player_name() or hit.ref:get_luaentity().name
|
||||
|
||||
if not has_piercing then return objects end
|
||||
|
||||
else
|
||||
-- se è un nodo mi fermo, e ritorno l'array se > 0 (ovvero ha trovato obiettivi)
|
||||
if hit.type == "node" then
|
||||
if #objects > 0 then
|
||||
return has_piercing and objects or {objects[1]}
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se ho sparato a un obiettivo senza incrociare blocchi
|
||||
if #objects > 0 then
|
||||
return has_piercing and objects or {objects[1]}
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function get_shooter_left_dir(shooter)
|
||||
local yaw = shooter:get_look_horizontal() or shooter:get_yaw()
|
||||
local pl_left_dir = vector.new(math.cos(yaw), 0, math.sin(yaw))
|
||||
|
||||
return vector.normalize(pl_left_dir)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function get_shooter_up_dir(shooter, dir)
|
||||
return vector.rotate_around_axis(dir, get_shooter_left_dir(shooter), math.pi/2)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function debug_particles(dir, origin, range)
|
||||
minetest.add_particlespawner({
|
||||
amount = 5,
|
||||
time = 0.3,
|
||||
pos = vector.new(origin),
|
||||
vel = vector.multiply(dir, range),
|
||||
size = 2,
|
||||
texture = "bl_smg_trail.png"
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
------------------------------
|
||||
-- not my code, don't know, don't ask
|
||||
------------------------------
|
||||
|
||||
weapons_lib.grenade_explode = function(self)
|
||||
local explosion_range = self._explosion_range
|
||||
local explosion_damage = self._explosion_damage
|
||||
local origin = self.object:get_pos()
|
||||
local p_name = self._p_name
|
||||
if origin == nil then return end
|
||||
if origin.x == nil or origin.y == nil or origin.z == nil then return end
|
||||
|
||||
local objs = minetest.env:get_objects_inside_radius(origin, explosion_range)
|
||||
local entities = {}
|
||||
-- Se ho colpito qualcosa
|
||||
if objs then
|
||||
for _, obj in ipairs(objs) do
|
||||
if obj:is_player() then
|
||||
|
||||
local p_pos = obj:get_pos()
|
||||
local lenx = math.abs(p_pos.x - origin.x)
|
||||
local leny = math.abs(p_pos.y - origin.y)
|
||||
local lenz = math.abs(p_pos.z - origin.z)
|
||||
local hypot = math.sqrt((lenx * lenx) + (lenz * lenz))
|
||||
local dist = math.sqrt((hypot * hypot) + (leny * leny))
|
||||
local damage = explosion_damage - (explosion_damage * dist / explosion_range)
|
||||
local target_name = obj:get_player_name()
|
||||
|
||||
-- TODO: non funziona, la funzione è stata cambiata. Bisogna far passare l'arma
|
||||
weapons_lib.apply_damage(minetest.get_player_by_name(p_name), {object = obj}, damage, 0, false)
|
||||
|
||||
elseif obj ~= self.object and obj:get_luaentity() then
|
||||
table.insert(entities, obj:get_luaentity())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #entities == 0 then return end
|
||||
|
||||
self.object:remove()
|
||||
for _,entity in pairs(entities) do
|
||||
if entity.initial_properties ~= nil then
|
||||
if entity._is_bullet then
|
||||
entity:_destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
240
src/utils.lua
240
src/utils.lua
@ -1,245 +1,7 @@
|
||||
local function cast_raycast() end
|
||||
local function get_shooter_left_dir() end
|
||||
local function get_shooter_up_dir() end
|
||||
local function debug_particles() end
|
||||
|
||||
|
||||
|
||||
-- per bloccare fisica
|
||||
local dummy = {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
pointable = false,
|
||||
collide_with_objects = false,
|
||||
visual = "sprite",
|
||||
visual_size = {x = 0, y = 0, z = 0},
|
||||
textures = { "blank.png" }
|
||||
},
|
||||
|
||||
-- quando sbuca, se non ha prole, cancellala
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
minetest.after(0.1, function()
|
||||
if #self.object:get_children() == 0 then
|
||||
self.object:remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
minetest.register_entity("weapons_lib:dummy", dummy)
|
||||
|
||||
|
||||
|
||||
function weapons_lib.is_in_the_air(obj_ref)
|
||||
local obj_pos = obj_ref:get_pos()
|
||||
local node_beneath = vector.new(obj_pos.x, obj_pos.y - 0.4, obj_pos.z)
|
||||
local is_in_the_air = minetest.get_node(node_beneath).name == "air"
|
||||
|
||||
return is_in_the_air
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- I cast a 2x2 grid (assisted aim) to prevent the 0.1 delay. The grid value is
|
||||
-- actually hardcoded because:
|
||||
-- 1. it works and I don't need more features from it
|
||||
-- 2. I haven't got enough knowledge about vectors and rotations anyway
|
||||
function weapons_lib.get_pointed_objects(shooter, range, has_piercing, entity_table)
|
||||
local height, look_dir
|
||||
|
||||
if entity_table then
|
||||
height = entity_table.height
|
||||
look_dir = entity_table.dir
|
||||
else
|
||||
height = 1.475
|
||||
look_dir = shooter:get_look_dir()
|
||||
end
|
||||
|
||||
local hit_pointed_things = {}
|
||||
local left_dir = get_shooter_left_dir(shooter)
|
||||
local head_up_dir = get_shooter_up_dir(shooter, look_dir)
|
||||
local center = shooter:get_pos() + look_dir + {x=0, y=height, z=0}
|
||||
|
||||
local grid_width = 0.25
|
||||
local r_amount = 2
|
||||
local x_step = (grid_width / r_amount) * (-left_dir)
|
||||
local y_step = (grid_width / r_amount) * head_up_dir
|
||||
local ray_pos = center + (x_step / r_amount) + (y_step / r_amount)
|
||||
|
||||
for row = 1, r_amount do
|
||||
for column = 1, r_amount do
|
||||
local pthings = cast_raycast(shooter, ray_pos, look_dir, range, has_piercing)
|
||||
--debug_particles(look_dir, ray_pos, 30)
|
||||
|
||||
if pthings then
|
||||
-- rimuovo giocator3 già colpit3 da altro raggio
|
||||
for k, possible_target in pairs(pthings) do
|
||||
local object = possible_target.object
|
||||
local target_name = possible_target.object:get_player_name() or possible_target.object:get_luaentity().name
|
||||
for _, target in pairs(hit_pointed_things) do
|
||||
local hit_target_name = target.object:get_player_name() or target.object:get_luaentity().name
|
||||
if target_name == hit_target_name then
|
||||
pthings[k] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.insert_all(hit_pointed_things, pthings)
|
||||
end
|
||||
|
||||
ray_pos = ray_pos - x_step
|
||||
end
|
||||
|
||||
ray_pos = ray_pos - y_step
|
||||
ray_pos = ray_pos + x_step * r_amount
|
||||
end
|
||||
|
||||
return hit_pointed_things
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
---------------FUNZIONI LOCALI----------------
|
||||
----------------------------------------------
|
||||
|
||||
-- ritorna un array di giocatori con il numero di giocatori trovati a indice 1.
|
||||
-- Se non trova giocatori diversi da se stesso ritorna nil
|
||||
function cast_raycast(user, origin, dir, range, has_piercing)
|
||||
|
||||
local a = vector.add(origin, vector.multiply(dir, 0))
|
||||
local b = vector.add(origin, vector.multiply(dir, range))
|
||||
local ray = minetest.raycast(a, b)
|
||||
local objects = {}
|
||||
|
||||
-- controllo su ogni cosa attraversata dal raycast (da a a b)
|
||||
for hit in ray do
|
||||
-- se è un oggetto
|
||||
if hit.type == "object" then
|
||||
-- se è un'entità
|
||||
if not hit.ref:is_player() then
|
||||
local entity = hit.ref:get_luaentity()
|
||||
-- se collide con un proiettile, lo distrugge, sennò salva l'entità per il danno
|
||||
if entity._is_bullet then
|
||||
entity:_destroy()
|
||||
else
|
||||
table.insert(objects, {object=hit.ref, headshot=false})
|
||||
end
|
||||
|
||||
-- se è un giocatore (e non chi spara)
|
||||
elseif hit.ref ~= user then
|
||||
if (hit.intersection_point.y - hit.ref:get_pos().y) > 1.275 then
|
||||
table.insert(objects, {object=hit.ref, headshot=true})
|
||||
else
|
||||
table.insert(objects, {object=hit.ref, headshot=false})
|
||||
end
|
||||
end
|
||||
|
||||
local is_player = hit.ref:is_player()
|
||||
local t_name = is_player and hit.ref:get_player_name() or hit.ref:get_luaentity().name
|
||||
|
||||
if not has_piercing then return objects end
|
||||
|
||||
else
|
||||
-- se è un nodo mi fermo, e ritorno l'array se > 0 (ovvero ha trovato obiettivi)
|
||||
if hit.type == "node" then
|
||||
if #objects > 0 then
|
||||
return has_piercing and objects or {objects[1]}
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se ho sparato a un obiettivo senza incrociare blocchi
|
||||
if #objects > 0 then
|
||||
return has_piercing and objects or {objects[1]}
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function get_shooter_left_dir(shooter)
|
||||
local yaw = shooter:get_look_horizontal() or shooter:get_yaw()
|
||||
local pl_left_dir = vector.new(math.cos(yaw), 0, math.sin(yaw))
|
||||
|
||||
return vector.normalize(pl_left_dir)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function get_shooter_up_dir(shooter, dir)
|
||||
return vector.rotate_around_axis(dir, get_shooter_left_dir(shooter), math.pi/2)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function debug_particles(dir, origin, range)
|
||||
minetest.add_particlespawner({
|
||||
amount = 5,
|
||||
time = 0.3,
|
||||
pos = vector.new(origin),
|
||||
vel = vector.multiply(dir, range),
|
||||
size = 2,
|
||||
texture = "bl_smg_trail.png"
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
------------------------------
|
||||
-- not my code, don't know, don't ask
|
||||
------------------------------
|
||||
|
||||
weapons_lib.grenade_explode = function(self)
|
||||
local explosion_range = self._explosion_range
|
||||
local explosion_damage = self._explosion_damage
|
||||
local origin = self.object:get_pos()
|
||||
local p_name = self._p_name
|
||||
if origin == nil then return end
|
||||
if origin.x == nil or origin.y == nil or origin.z == nil then return end
|
||||
|
||||
local objs = minetest.env:get_objects_inside_radius(origin, explosion_range)
|
||||
local entities = {}
|
||||
-- Se ho colpito qualcosa
|
||||
if objs then
|
||||
for _, obj in ipairs(objs) do
|
||||
if obj:is_player() then
|
||||
|
||||
local p_pos = obj:get_pos()
|
||||
local lenx = math.abs(p_pos.x - origin.x)
|
||||
local leny = math.abs(p_pos.y - origin.y)
|
||||
local lenz = math.abs(p_pos.z - origin.z)
|
||||
local hypot = math.sqrt((lenx * lenx) + (lenz * lenz))
|
||||
local dist = math.sqrt((hypot * hypot) + (leny * leny))
|
||||
local damage = explosion_damage - (explosion_damage * dist / explosion_range)
|
||||
local target_name = obj:get_player_name()
|
||||
|
||||
-- TODO: non funziona, la funzione è stata cambiata. Bisogna far passare l'arma
|
||||
weapons_lib.apply_damage(minetest.get_player_by_name(p_name), {object = obj}, damage, 0, false)
|
||||
|
||||
elseif obj ~= self.object and obj:get_luaentity() then
|
||||
table.insert(entities, obj:get_luaentity())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #entities == 0 then return end
|
||||
|
||||
self.object:remove()
|
||||
for _,entity in pairs(entities) do
|
||||
if entity.initial_properties ~= nil then
|
||||
if entity._is_bullet then
|
||||
entity:_destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user