nodecore-cd2025/mods/nc_api/action_node_pummel.lua

139 lines
3.7 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, nodecore, vector
= ipairs, math, minetest, nodecore, vector
local math_floor, math_random
= math.floor, math.random
-- LUALOCALS > ---------------------------------------------------------
local pummeling = {}
local function fxcore(pname, pointed, img)
img = img .. "^[mask:[combine\\:16x16\\:"
.. math_floor(math_random() * 12) .. ","
.. math_floor(math_random() * 12) .. "=nc_api_pummel.png"
minetest.log(img)
local a = pointed.above
local b = pointed.under
local vel = vector.subtract(a, b)
local mid = vector.multiply(vector.add(a, b), 0.5)
local p1 = {x = vel.y, y = vel.z, z = vel.x}
local p2 = {x = vel.z, y = vel.x, z = vel.y}
local s1 = vector.add(vector.add(mid, vector.multiply(p1, 0.5)), vector.multiply(p2, 0.5))
local s2 = vector.add(vector.add(mid, vector.multiply(p1, -0.5)), vector.multiply(p2, -0.5))
vel = vector.multiply(vel, 0.5)
return minetest.add_particlespawner({
amount = 5,
time = 1.5,
minpos = s1,
maxpos = s2,
minvel = vel,
maxvel = vel,
minexptime = 0.4,
maxexptime = 0.9,
minsize = 1,
maxsize = 5,
texture = img,
playername = pname
})
end
local function particlefx(pname, pointed, def)
local img = {}
if def.tiles then
for i = 1, 6 do
img[#img + 1] = def.tiles[i > #def.tiles and #def.tiles or i]
end
elseif def.inventory_image then
img[1] = def.inventory_image
end
if #img < 1 then return minetest.log("no pummel tile images found!") end
img = nodecore.pickrand(img)
if img.name then img = img.name end
for i = 1, 4 do fxcore(pname, pointed, img) end
end
minetest.register_on_punchnode(function(pos, node, puncher, pointed)
if not puncher:is_player() then return end
local pname = puncher:get_player_name()
node = node or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
if not def.pummeldefs then return end
local now = minetest.get_us_time() / 1000000
local pum = {
puncher = puncher,
pname = pname,
pos = pos,
pointed = pointed,
node = node,
def = def,
start = now,
wield = puncher:get_wielded_item():to_string(),
count = 0
}
local old = pummeling[pname]
local hash = minetest.hash_node_position
if old and hash(old.pos) == hash(pum.pos)
and hash(old.pointed.above) == hash(pum.pointed.above)
and hash(old.pointed.under) == hash(pum.pointed.under)
and pum.wield == old.wield
and old.last >= (now - 2)
then pum = old end
pum.count = pum.count + 1
pum.last = now
pum.duration = now - pum.start
pummeling[pname] = pum
local resolve
for i, v in ipairs(def.pummeldefs) do
if not resolve then
local ok = v.check(pos, node, pum)
if ok then
resolve = v.resolve
pum.check = ok
end
end
end
if not resolve then
pummeling[pname] = nil
return
end
if pum.count > 1 then
if pum.particles then minetest.delete_particlespawner(pum.particles) end
pum.particles = particlefx(pname, pointed, def)
end
if resolve(pos, node, pum) then
if pum.particles then minetest.delete_particlespawner(pum.particles) end
nodecore.player_knowledge_add(puncher, "pummel:" .. node.name)
pummeling[pname] = nil
end
end)
function nodecore.add_pummel(nodedef, check, resolve)
nodedef.pummeldefs = nodedef.pummeldefs or {}
nodedef.pummeldefs[#nodedef.pummeldefs + 1] = {
check = check,
resolve = resolve
}
end
function nodecore.extend_pummel(name, check, resolve)
nodecore.extend_item(name, function(copy)
return nodecore.add_pummel(copy, check, resolve)
end)
end
function nodecore.pummel_toolspeed(pos, node, stats)
return nodecore.toolspeed(
stats.puncher:get_wielded_item(),
stats.def.groups
)
end