Limit smoke effects, e.g. from concrete cure
Standardize a "fair limiting" mechanism that limits the items accepted into a queue, and returns a uniform random sample when flushed. Pass all cooking/curing smoke effects into fair limit queue. Apply fairl limit queue to fire sparks too. Pliant concrete curing checks still seem to lag the server somewhat, but at least now they shouldn't hammer the client with particles and kill framerate too.
This commit is contained in:
parent
22ff675761
commit
fd181833f4
@ -41,6 +41,29 @@ function nodecore.mkreg()
|
||||
return f, t
|
||||
end
|
||||
|
||||
function nodecore.fairlimit(max)
|
||||
local queue = {}
|
||||
local qty = 0
|
||||
local function add(item)
|
||||
qty = qty + 1
|
||||
if qty > max then
|
||||
local id = math_random(1, qty)
|
||||
if id <= max then
|
||||
queue[id] = item
|
||||
end
|
||||
else
|
||||
queue[qty] = item
|
||||
end
|
||||
end
|
||||
local function flush()
|
||||
local batch = queue
|
||||
queue = {}
|
||||
qty = 0
|
||||
return batch
|
||||
end
|
||||
return add, flush
|
||||
end
|
||||
|
||||
function nodecore.memoize(func)
|
||||
local cachedval
|
||||
local cached
|
||||
|
@ -1,41 +1,50 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local math, minetest, nodecore, type
|
||||
= math, minetest, nodecore, type
|
||||
local ipairs, math, minetest, nodecore, type
|
||||
= ipairs, math, minetest, nodecore, type
|
||||
local math_random
|
||||
= math.random
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local smoke_add, smoke_flush = nodecore.fairlimit(50)
|
||||
|
||||
local smoking = {}
|
||||
|
||||
nodecore.register_globalstep("smoke queue", function()
|
||||
for _, item in ipairs(smoke_flush()) do
|
||||
local pos, qty, time = item.pos, item.qty, item.time
|
||||
local now = minetest.get_us_time() / 1000000
|
||||
local key = minetest.hash_node_position(pos)
|
||||
local old = smoking[key]
|
||||
if old and now < old.exp then minetest.delete_particlespawner(old.id) end
|
||||
if (not time) or (time <= 0) then
|
||||
smoking[key] = nil
|
||||
return
|
||||
end
|
||||
if type(qty) ~= "number" then qty = 1 end
|
||||
if qty < 1 then
|
||||
if math_random() > qty then return end
|
||||
qty = 1
|
||||
end
|
||||
smoking[key] = {
|
||||
id = minetest.add_particlespawner({
|
||||
texture = "nc_api_craft_smoke.png",
|
||||
collisiondetection = true,
|
||||
amount = (qty or 2) * time,
|
||||
time = time,
|
||||
minpos = {x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4},
|
||||
maxpos = {x = pos.x + 0.4, y = pos.y + 0.4, z = pos.z + 0.4},
|
||||
minvel = {x = -0.1, y = 0.3, z = -0.1},
|
||||
maxvel = {x = 0.1, y = 0.7, z = 0.1},
|
||||
minexptime = 1,
|
||||
maxexptime = 5,
|
||||
minsize = 1,
|
||||
maxsize = 3
|
||||
}),
|
||||
exp = now + time
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
function nodecore.smokefx(pos, time, qty)
|
||||
local now = minetest.get_us_time() / 1000000
|
||||
local key = minetest.hash_node_position(pos)
|
||||
local old = smoking[key]
|
||||
if old and now < old.exp then minetest.delete_particlespawner(old.id) end
|
||||
if (not time) or (time <= 0) then
|
||||
smoking[key] = nil
|
||||
return
|
||||
end
|
||||
if type(qty) ~= "number" then qty = 1 end
|
||||
if qty < 1 then
|
||||
if math_random() > qty then return end
|
||||
qty = 1
|
||||
end
|
||||
smoking[key] = {
|
||||
id = minetest.add_particlespawner({
|
||||
texture = "nc_api_craft_smoke.png",
|
||||
collisiondetection = true,
|
||||
amount = (qty or 2) * time,
|
||||
time = time,
|
||||
minpos = {x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4},
|
||||
maxpos = {x = pos.x + 0.4, y = pos.y + 0.4, z = pos.z + 0.4},
|
||||
minvel = {x = -0.1, y = 0.3, z = -0.1},
|
||||
maxvel = {x = 0.1, y = 0.7, z = 0.1},
|
||||
minexptime = 1,
|
||||
maxexptime = 5,
|
||||
minsize = 1,
|
||||
maxsize = 3
|
||||
}),
|
||||
exp = now + time
|
||||
}
|
||||
return smoke_add({pos = pos, time = time, qty = qty})
|
||||
end
|
||||
|
@ -7,13 +7,10 @@ local math_random
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
local sparks = {}
|
||||
local sparkqty = 0
|
||||
local sparkmax = 50
|
||||
local sparks_add, sparks_flush = nodecore.fairlimit(50)
|
||||
|
||||
nodecore.register_globalstep("fire sparks", function()
|
||||
if sparkqty < 1 then return end
|
||||
for i = 1, #sparks do
|
||||
local pos = sparks[i]
|
||||
for _, pos in ipairs(sparks_flush()) do
|
||||
minetest.after(math_random(), function()
|
||||
minetest.add_particlespawner({
|
||||
amount = math_random(1, 3),
|
||||
@ -35,8 +32,6 @@ nodecore.register_globalstep("fire sparks", function()
|
||||
})
|
||||
end)
|
||||
end
|
||||
sparks = {}
|
||||
sparkqty = 0
|
||||
end)
|
||||
|
||||
do
|
||||
@ -55,16 +50,7 @@ do
|
||||
chance = 1,
|
||||
nodenames = {modname .. ":fire"},
|
||||
action = function(pos)
|
||||
sparkqty = sparkqty + 1
|
||||
if sparkqty > sparkmax then
|
||||
local sparkid = math_random(1, sparkqty)
|
||||
if sparkid <= sparkmax then
|
||||
sparks[sparkid] = pos
|
||||
end
|
||||
else
|
||||
sparks[sparkqty] = pos
|
||||
end
|
||||
|
||||
sparks_add(pos)
|
||||
local found = {}
|
||||
for _, dp in ipairs(flamedirs) do
|
||||
local npos = vector.add(pos, dp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user