guns4d-cd2025/classes/Bullet_hole.lua
2024-12-01 16:19:51 -08:00

155 lines
5.4 KiB
Lua

local player_positions = {}
minetest.register_globalstep(function(dt)
for i, v in pairs(player_positions) do
player_positions[i] = nil
end
for i, player_handler in pairs(Guns4d.players) do
table.insert(player_positions, player_handler.player:get_pos())
end
local count = 0
for i = #Guns4d.bullet_hole.instances+1, 1, -1 do --start at the last so the bullet_holes added sooner are expired.
local obj = Guns4d.bullet_hole.instances[i]
if obj then --obj can be a false value.
if (count > Guns4d.config.maximum_bullet_holes) and (obj.exp_time > 2.5) then
obj.exp_time = 2.5
end
count = count + 1
local closest_dist
for _, pos in pairs(player_positions) do
local dist = vector.distance(obj.pos, pos)
if (not closest_dist) or (dist < closest_dist) then
closest_dist = dist
end
end
if closest_dist > obj.deletion_distance then
obj:delete()
return
end
if (closest_dist > obj.render_distance) and obj.rendered then
obj:unrender()
elseif (closest_dist < obj.render_distance*.85) and not obj.rendered then
obj:render()
end
obj:update(dt)
end
end
end)
Guns4d.bullet_hole = leef.class.new_class:inherit({
texture = 'bullet_hole.png',
exp_time = 30, --how much time a rendered bullet hole takes to expire
unrendered_exptime = 10, --how much time an unrendered bullet hole takes to expire
deletion_distance = 100,
--heat_effect = false,
instances = {},
size = .15,
render_distance = 25,
particle_spawner_id = nil,
hole_entity = "guns4d:bullet_hole",
rendered = true,
})
local Bullet_hole = Guns4d.bullet_hole
---@diagnostic disable-next-line: duplicate-set-field
function Bullet_hole.construct(def)
if def.instance then
assert(def.pos)
assert(def.rotation)
--[[for i, v in pairs(def.pos) do
if math.abs(v-Guns4d.math.round(v)) > (.5-(def.size/2)) then
def.pos[i] = Guns4d.math.round(v)+((math.abs(v-Guns4d.math.round(v))/(v-Guns4d.math.round(v)))*(.5-(def.size/2)))
end
end]]
Bullet_hole.instances[(#Bullet_hole.instances)+1]=def
def.id = #Bullet_hole.instances
def.unrendered_expire_speed = def.exp_time/def.unrendered_exptime
def:render()
end
end
function Bullet_hole:render()
assert(self.instance)
self.rendered = true
local normal = vector.rotate(vector.new(0,0,1), self.rotation)
local ent = minetest.add_entity(self.pos+(normal*(.001+math.random()/1000)), self.hole_entity)
ent:set_rotation(vector.dir_to_rotation(normal))
ent:set_properties({visual_size={x=self.size, y=self.size, z=0}})
self.entity = ent
local lua_ent = ent:get_luaentity()
lua_ent.lua_instance = self
if self.particle_spawner_id then
minetest.delete_particlespawner(self.particle_spawner_id)
end
end
function Bullet_hole:unrender()
assert(self.instance)
self.rendered = false
local normal = vector.rotate(vector.new(0,0,1), self.rotation)
local time_left = self.exp_time/self.unrendered_expire_speed
local number_of_particles = 2
minetest.add_particle({
size = self.size*10,
texture = self.texture,
expiration_time = 2*time_left/math.ceil(number_of_particles*time_left),
pos = self.pos+(normal*.05)
})
self.particle_spawner_id = minetest.add_particlespawner({
pos = self.pos+(normal*.05),
amount = math.ceil(number_of_particles*time_left)*5, --multiply so it doesn't flash in and out of existence...
time=time_left,
exptime = time_left/math.ceil(number_of_particles*time_left),
texture = {
name = self.texture,
scale = self.size*10
}
})
if self.entity:get_pos() then
self.entity:remove()
end
end
function Bullet_hole:delete()
assert(self.instance)
Bullet_hole.instances[self.id] = false
if self.entity:get_pos() then
self.entity:remove()
end
if self.particle_spawner_id then
minetest.delete_particlespawner(self.particle_spawner_id)
end
end
function Bullet_hole:update(dt)
assert(self.instance)
if self.rendered then
self.exp_time = self.exp_time-dt
else
self.exp_time = self.exp_time-(dt*self.unrendered_expire_speed)
end
if self.exp_time <= 0 then
self:delete()
end
end
minetest.register_entity("guns4d:bullet_hole", {
initial_properties = {
visual = "cube",
visual_size = {x=.1, y=.1, z=0},
pointable = false,
static_save = false,
use_texture_alpha = true,
textures = {"blank.png", "blank.png", "blank.png", "blank.png", "bullet_hole.png", "blank.png"}
},
on_step = function(self, dt)
if TICK % 50 then
local lua_instance = self.lua_instance
if lua_instance.exp_time <= 0 then
self.object:remove()
return
end
if lua_instance.exp_time < 2.5 then
local properties = self.object:get_properties()
properties.textures[5] = lua_instance.texture..'^[opacity:'..(math.floor((12.75*tostring(lua_instance.exp_time/2.5)))*20)
self.object:set_properties(properties)
end
end
end
})