performances improvement for mcl_explosions

This commit is contained in:
AFCMS 2021-03-15 01:20:22 +01:00
parent fe6b7cb89b
commit 4b2c963222
1 changed files with 26 additions and 16 deletions

View File

@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
local S = minetest.get_translator("mcl_explosions")
local hash_node_position = minetest.hash_node_position
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_position_from_hash = minetest.get_position_from_hash
local get_node_drops = minetest.get_node_drops
local get_name_from_content_id = minetest.get_name_from_content_id
local get_voxel_manip = minetest.get_voxel_manip
local bulk_set_node = minetest.bulk_set_node
local check_for_falling = minetest.check_for_falling
local add_item = minetest.add_item
-- Saved sphere explosion shapes for various radiuses
local sphere_shapes = {}
@ -64,7 +74,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z
if d <= radius * radius then
local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos
sphere[hash_node_position(pos)] = pos
break
end
end
@ -79,7 +89,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z
if d <= radius * radius then
local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos
sphere[hash_node_position(pos)] = pos
break
end
end
@ -94,7 +104,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z
if d <= radius * radius then
local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos
sphere[hash_node_position(pos)] = pos
break
end
end
@ -156,7 +166,7 @@ end
-- inlined to avoid function calls and unnecessary table creation. This was
-- measured to give a significant performance increase.
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local vm = minetest.get_voxel_manip()
local vm = get_voxel_manip()
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
vector.add(pos, radius))
@ -207,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
br = max_blast_resistance
end
local hash = minetest.hash_node_position(npos)
local hash = hash_node_position(npos)
rpos_x = rpos_x + STEP_LENGTH * rdir_x
rpos_y = rpos_y + STEP_LENGTH * rdir_y
@ -230,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
-- Entities in radius of explosion
local punch_radius = 2 * strength
local objs = minetest.get_objects_inside_radius(pos, punch_radius)
local objs = get_objects_inside_radius(pos, punch_radius)
-- Trace rays for entity damage
for _, obj in pairs(objs) do
@ -359,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local remove = true
if do_drop or on_blast ~= nil then
local npos = minetest.get_position_from_hash(hash)
local npos = get_position_from_hash(hash)
if on_blast ~= nil then
on_blast(npos, 1.0, do_drop)
remove = false
else
local name = minetest.get_name_from_content_id(data[idx])
local drop = minetest.get_node_drops(name, "")
local name = get_name_from_content_id(data[idx])
local drop = get_node_drops(name, "")
for _, item in ipairs(drop) do
if type(item) ~= "string" then
item = item:get_name() .. item:get_count()
end
minetest.add_item(npos, item)
add_item(npos, item)
end
end
end
if remove then
if mod_fire and fire and math.random(1, 3) == 1 then
table.insert(fires, minetest.get_position_from_hash(hash))
table.insert(fires, get_position_from_hash(hash))
else
table.insert(airs, minetest.get_position_from_hash(hash))
table.insert(airs, get_position_from_hash(hash))
end
end
end
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
-- on_construct being called
if #airs > 0 then
minetest.bulk_set_node(airs, {name="air"})
bulk_set_node(airs, {name="air"})
end
if #fires > 0 then
minetest.bulk_set_node(fires, {name="mcl_fire:fire"})
bulk_set_node(fires, {name="mcl_fire:fire"})
end
-- Update falling nodes
for a=1, #airs do
local p = airs[a]
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z})
check_for_falling({x=p.x, y=p.y+1, z=p.z})
end
for f=1, #fires do
local p = fires[f]
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z})
check_for_falling({x=p.x, y=p.y+1, z=p.z})
end
-- Log explosion