performances improvement for mcl_explosions

This commit is contained in:
AFCMS 2021-03-15 01:20:22 +01:00
parent fe6b7cb89b
commit 4b2c963222

View file

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