Update collisioni con supporto a 5.3.

master
_Zaizen_ 2020-07-28 21:49:45 +02:00
parent 6379a3ae0a
commit 8ec527a4d4
2 changed files with 42 additions and 74 deletions

View File

@ -2,7 +2,6 @@ local function calc_dir_from_pos() end
local function jump() end
local function spawn_particles_sphere() end
local function get_dist() end
local function get_pointed_thing() end
@ -16,6 +15,7 @@ function quake.register_bullet(name, def)
initial_properties = {
name = name,
physical = def.physical,
collide_with_objects = def.collide_with_objects,
visual = def.visual,
visual_size = def.visual_size,
mesh = def.mesh,
@ -30,6 +30,7 @@ function quake.register_bullet(name, def)
explosion_damage = def.explosion_damage,
no_collision_time = 1/(2*def.speed), -- il tempo necessario per non far impattare il proiettile contro il giocatore
def = def,
is_bullet = true,
},
}
@ -71,59 +72,57 @@ function quake.register_bullet(name, def)
end
self.lifetime = 0
local pos = self.object:get_pos()
end
function bulletentity:on_step(dtime)
--moveresult è una metatabella dove vengono passati i dati delle collisioni della collisionbox
function bulletentity:on_step(dtime, moveresult)
-- incremento tempo di vita
self.lifetime = self.lifetime + dtime
local pos = self.object:get_pos()
local node = minetest.env:get_node(pos)
local dir = vector.normalize(self.object:get_velocity())
-- se ha raggiunto la durata di vita massima
if self.lifetime >= self.initial_properties.duration then
self:_destroy()
return
end
local hit = get_pointed_thing(pos, dir, self.p_name)
-- se il proiettile ha qualcosa sulla sua linea d'aria
if hit then
local hit_pos
local dist
-- se è un'entità
if hit.type == "object" and hit.ref then
-- se è un giocatore
if hit.ref:is_player() then
quake.shoot(self.p_name, hit.ref, self.initial_properties.damage, false)
self:_destroy()
return
end
-- se è un nodo
elseif hit.type == "node" then
hit_pos = hit["above"] -- NON SO IL PERCHé MA IN IRC MI HANNO DETTO COSì
local player_pos = self.shooter:get_pos()
local player_dist = get_dist(hit_pos, player_pos)
if player_dist <= self.initial_properties.explosion_range then
local dir_jump = calc_dir_from_pos(hit_pos, player_pos)
jump(self.shooter, self.initial_properties.jump, dir_jump)
-- controlla se collide con qualcosa
if moveresult.collides == true then
--collisions è una tabella dentro moveresult dove al primo indice c'è una tabella
--con vari dati in certi casi di collisione (solitamente se collide con oggetti)
if moveresult.collisions[1] then
--object è l'oggetto(player/entità) con cui collide il proiettile
if moveresult.collisions[1].object then
--controlla se è un player
if moveresult.collisions[1].object:is_player() then
if moveresult.collisions[1].object:get_player_name() ~= self.p_name then
quake.shoot(self.p_name, moveresult.collisions.object, self.initial_properties.damage, false)
self:_destroy()
return
end
self:_destroy()
return
end
--quando non è un player allora è una entity quindi la memorizzo per alleggerire il numero di accessi
local entity = moveresult.collisions[1].object:get_luaentity()
--i prossimi 2 check servono a verificare l'entità sia un proiettile
if entity.initial_properties ~= nil then
if entity.initial_properties.is_bullet then
--distrugge sia il proiettile con cui collide che se stesso
entity:_destroy()
self:_destroy()
return
end
end
end
--se non è presente il campo object distrugge comunque il proiettile per prevenire crash ed errori
self:_destroy()
return
end
--quando non esiste collisions[1] distrugge comunque perchè sta collidendo con qualcosa
self:_destroy()
return
end
end
--registra l'entità
@ -132,7 +131,6 @@ function quake.register_bullet(name, def)
end
function quake.shoot_bullet(shooter, bullet, pos_head, dir)
local username = shooter:get_player_name()
@ -216,27 +214,3 @@ local function get_nodedef_field(nodename, fieldname)
end
return minetest.registered_nodes[nodename][fieldname]
end
-- ottiene la cosa puntata dall'entità. Inizia da dietro l'entità perchè serve a verificare che non abbia attraversato un player senza colpirlo
function get_pointed_thing(pos_bullet, dir, username)
local p1 = vector.add(pos_bullet, vector.multiply(dir, -1))
local p2 = vector.add(pos_bullet, vector.multiply(dir, 0.1))
local ray = minetest.raycast(p1, p2, true, false)
for hit in ray do
-- se è un oggetto
if hit.type == "object" and hit.ref then
-- se è un giocatore
if hit.ref:is_player() then
-- e non è colui che spara
if hit.ref:get_player_name() ~= username then
return hit
end
end
else
if hit.type == "node" then
return hit
end
end
end
end

View File

@ -1,18 +1,12 @@
quake.register_bullet("quake:rocket",{
physical = false,
visual = "mesh",
visual_size = {x=1, y=1},
physical = true,
collide_with_objects = true,
mesh = "quake_rocket.obj",
textures = {
"quake_bullet_rocket.png",
"quake_bullet_rocket.png",
"quake_bullet_rocket.png",
"quake_bullet_rocket.png",
"quake_bullet_rocket.png",
"quake_bullet_rocket.png",
},
visual = "mesh",
visual_size = {x=1, y=1, z=1},
textures = {"quake_bullet_rocket.png"},
explosion_texture = "quake_rocket_particle.png",
collisionbox = {0,0,0,0,0,0},
collisionbox = {-0.05, -0.05, -0.05, 0.05, 0.05, 0.05}, -- {xmin, ymin, zmin, xmax, ymax, zmax}
speed = 30,
damage = 14,
jump = 0,