Started a large refactor project.
The idea is to merge the pummel logic with crafting recipes, and move them up out of plain old api.
This commit is contained in:
parent
0627c22101
commit
f98e8be5c2
@ -13,8 +13,8 @@ ROADMAP (SHORT-TERM)
|
||||
- Need to make lode ore require same or higher tier tools than
|
||||
stone, not lower. Should not be hand-diggable in any form.
|
||||
- Metal casting, annealing, tempering
|
||||
- Hammer annealed prills -> annealed metal slabs/blocks
|
||||
- Hammer annealed slabs/blocks -> annealed tool heads
|
||||
- Axe annealed blocks/slabs -> annealed prills
|
||||
- Hammer annealed slabs -> annealed tool heads
|
||||
- Create and use annealed tools
|
||||
- Heat annealed tool heads -> glowing tool heads
|
||||
- Quench glowing tool heads -> tempered tool heads
|
||||
@ -30,6 +30,9 @@ ROADMAP (SHORT-TERM)
|
||||
- Chop dirt with an axe.
|
||||
- Hammer together 4 stones instead of 8.
|
||||
- Pummel tree from the side with a higher tier axe, stone/metal?
|
||||
- Social features
|
||||
- Randomize player appearance/colors
|
||||
- Hardcore names...?
|
||||
- Plant life stuff
|
||||
- Better tree growth, i.e. track cumulative time, apply
|
||||
environmental factors.
|
||||
|
@ -114,7 +114,7 @@ minetest.register_on_punchnode(function(pos, node, puncher, pointed)
|
||||
|
||||
if pum.count > 1 then
|
||||
if pum.particles then pum.particles() end
|
||||
pum.particles = particlefx(pname, pointed, def)
|
||||
pum.particles = particlefx(pname, pointed, pum.def)
|
||||
end
|
||||
|
||||
if resolve(pos, node, pum) then
|
||||
|
35
mods/nc_api/digparticles.lua
Normal file
35
mods/nc_api/digparticles.lua
Normal file
@ -0,0 +1,35 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local math, minetest, nodecore, pairs
|
||||
= math, minetest, nodecore, pairs
|
||||
local math_ceil, math_floor, math_random
|
||||
= math.ceil, math.floor, math.random
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
function nodecore.digparticles(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
|
||||
|
||||
def.amount = def.amount and math_ceil(def.amount / 4) or 4
|
||||
|
||||
local t = {}
|
||||
for i = 1, 4 do
|
||||
def.texture = img .. "^[mask:[combine\\:16x16\\:"
|
||||
.. math_floor(math_random() * 12) .. ","
|
||||
.. math_floor(math_random() * 12) .. "=nc_api_pummel.png"
|
||||
t[#t + 1] = minetest.add_particlespawner(def)
|
||||
end
|
||||
return function()
|
||||
for k, v in pairs(t) do
|
||||
minetest.delete_particlespawner(v)
|
||||
end
|
||||
end
|
||||
end
|
@ -4,11 +4,10 @@ local dofile, minetest, rawget, rawset
|
||||
= dofile, minetest, rawget, rawset
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
local nodecore = rawget(_G, "nodecore") or {}
|
||||
rawset(_G, "nodecore", nodecore)
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local path = minetest.get_modpath(modname)
|
||||
|
||||
dofile(path .. "/util_misc.lua")
|
||||
|
63
mods/nc_api/match.lua
Normal file
63
mods/nc_api/match.lua
Normal file
@ -0,0 +1,63 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, nodecore, pairs, type
|
||||
= minetest, nodecore, pairs, type
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local match_skip = {
|
||||
name = true,
|
||||
param2 = true,
|
||||
param = true,
|
||||
groups = true,
|
||||
inv = true,
|
||||
count = true,
|
||||
wear = true
|
||||
}
|
||||
|
||||
function nodecore.match(thing, crit)
|
||||
local stack = thing.stack
|
||||
if stack then
|
||||
thing.name = stack:get_name()
|
||||
thing.count = stack:get_count()
|
||||
thing.wear = stack:get_wear()
|
||||
end
|
||||
if not thing.name then
|
||||
thing = nodecore.underride(thing, minetest.get_node(thing))
|
||||
end
|
||||
|
||||
if type(crit) == "string" then crit = {name = crit} end
|
||||
if crit.name and thing.name ~= crit.name then return end
|
||||
if crit.param2 and thing.param2 ~= crit.param2 then return end
|
||||
if crit.param and thing.param ~= crit.param then return end
|
||||
if crit.count and thing.count ~= crit.count then return end
|
||||
if crit.wear then
|
||||
if crit.wear < 1 then crit.wear = crit.wear * 65535 end
|
||||
if thing.wear > crit.wear then return end
|
||||
end
|
||||
|
||||
local def = minetest.registered_items[thing.name]
|
||||
if crit.groups then
|
||||
if not def.groups then return end
|
||||
for k, v in pairs(crit.groups) do
|
||||
if v == true then
|
||||
if not def.groups[k] then return end
|
||||
elseif v == false then
|
||||
if def.groups[k] then return end
|
||||
else
|
||||
if def.groups[k] ~= v then return end
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, v in pairs(crit) do
|
||||
if not match_skip[k] then
|
||||
if def[k] ~= v then return end
|
||||
end
|
||||
end
|
||||
|
||||
if crit.inv then
|
||||
local stack = minetest.get_meta(thing):get_inventory():get_stack("solo", 1)
|
||||
if not stack or stack:is_empty() then return end
|
||||
return nodecore.match({stack = stack}, crit.inv)
|
||||
end
|
||||
|
||||
return thing
|
||||
end
|
74
mods/nc_api_craft/craft_check.lua
Normal file
74
mods/nc_api_craft/craft_check.lua
Normal file
@ -0,0 +1,74 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local ipairs, minetest, nodecore, pairs, type
|
||||
= ipairs, minetest, nodecore, pairs, type
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local function craftcheck(recipe, pos, node, data, xx, xz, zx, zz)
|
||||
local function rel(x, y, z)
|
||||
return {
|
||||
x = pos.x + xx * x + zx * z,
|
||||
y = pos.y + y,
|
||||
z = pos.z + xz * x + zz * z
|
||||
}
|
||||
end
|
||||
if recipe.check and not recipe.check(pos, data, rel) then return end
|
||||
if recipe.wield and (not data.crafter or not nodecore.match(
|
||||
{stack = data.crafter:get_wielded_item()}, recipe.wield)) then return end
|
||||
if recipe.normal then
|
||||
if data.pointed.type ~= "node" or
|
||||
recipe.normal.y ~= data.pointed.above.y - data.pointed.under.y then return end
|
||||
local rx = recipe.normal.x * xx + recipe.normal.z * zx
|
||||
if rx ~= data.pointed.above.x - data.pointed.under.x then return end
|
||||
local rz = recipe.normal.x * xz + recipe.normal.z * zz
|
||||
if rz ~= data.pointed.above.z - data.pointed.under.z then return end
|
||||
end
|
||||
for _, v in pairs(recipe.nodes) do
|
||||
if v ~= recipe.root and v.match then
|
||||
local p = rel(v.x, v.y, v.z)
|
||||
if not nodecore.match(p, v.match) then return end
|
||||
end
|
||||
end
|
||||
for _, v in pairs(recipe.nodes) do
|
||||
if v.replace then
|
||||
local p = rel(v.x, v.y, v.z)
|
||||
local r = v.replace
|
||||
while type(r) == "function" do
|
||||
r = r(p, v)
|
||||
end
|
||||
if r and type(r) == "string" then
|
||||
r = {name = r}
|
||||
end
|
||||
if r then minetest.set_node(p, r) end
|
||||
end
|
||||
end
|
||||
if recipe.items then
|
||||
for _, v in pairs(recipe.items) do
|
||||
nodecore.item_eject(rel(v.x or 0, v.y or 0, v.z or 0), v)
|
||||
end
|
||||
end
|
||||
if recipe.after then recipe.after(pos, rel, data) end
|
||||
return true
|
||||
end
|
||||
|
||||
function nodecore.craft_check(rtype, pos, node, data)
|
||||
data = data or {}
|
||||
local function go(xx, xz, zx, zz)
|
||||
return craftcheck(rc, pos, node, data, xx, xz, zx, zz)
|
||||
end
|
||||
for _, rc in ipairs(nodecore.craft_recipes[rtype] or {}) do
|
||||
if nodecore.match(node, rc.root.match) then
|
||||
if go(1, 0, 0, 1) then return true end
|
||||
if not rc.norotate then
|
||||
if go(0, -1, 1, 0) then return true end
|
||||
if go(-1, 0, 0, -1) then return true end
|
||||
if go(0, 1, -1, 0) then return true end
|
||||
if not rc.nomirror then
|
||||
if go(-1, 0, 0, 1) then return true end
|
||||
if go(0, 1, 1, 0) then return true end
|
||||
if go(1, 0, 0, -1) then return true end
|
||||
if go(0, -1, -1, 0) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
mods/nc_api_craft/depends.txt
Normal file
1
mods/nc_api_craft/depends.txt
Normal file
@ -0,0 +1 @@
|
||||
nc_api
|
13
mods/nc_api_craft/init.lua
Normal file
13
mods/nc_api_craft/init.lua
Normal file
@ -0,0 +1,13 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
-- SKIP: nodecore
|
||||
local dofile, minetest
|
||||
= dofile, minetest
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local path = minetest.get_modpath(modname)
|
||||
|
||||
dofile(path .. "/register_craft.lua")
|
||||
dofile(path .. "/craft_check.lua")
|
||||
dofile(path .. "/item_place_node.lua")
|
||||
dofile(path .. "/register_on_punchnode.lua")
|
24
mods/nc_api_craft/item_place_node.lua
Normal file
24
mods/nc_api_craft/item_place_node.lua
Normal file
@ -0,0 +1,24 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, nodecore
|
||||
= minetest, nodecore
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local old_place = minetest.item_place_node
|
||||
function minetest.item_place_node(itemstack, placer, pointed_thing, ...)
|
||||
local old_add = minetest.add_node
|
||||
minetest.add_node = function(pos, node, ...)
|
||||
local function helper2(...)
|
||||
nodecore.craft_check("place", pos, node, {
|
||||
crafter = placer,
|
||||
pointed = pointed_thing
|
||||
})
|
||||
return ...
|
||||
end
|
||||
return helper2(old_add(pos, node, ...))
|
||||
end
|
||||
local function helper(...)
|
||||
minetest.add_node = old_add
|
||||
return ...
|
||||
end
|
||||
return helper(old_place(itemstack, placer, pointed_thing, ...))
|
||||
end
|
53
mods/nc_api_craft/register_craft.lua
Normal file
53
mods/nc_api_craft/register_craft.lua
Normal file
@ -0,0 +1,53 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local error, math, nodecore, pairs, table, type
|
||||
= error, math, nodecore, pairs, table, type
|
||||
local math_floor, table_insert
|
||||
= math.floor, table.insert
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local craft_recipes = {}
|
||||
nodecore.craft_recipes = craft_recipes
|
||||
|
||||
function nodecore.register_craft(recipe)
|
||||
recipe.type = recipe.type or "place"
|
||||
local canrot
|
||||
recipe.nodes = recipe.nodes or {}
|
||||
for _, v in pairs(recipe.nodes) do
|
||||
v.x = v.x or 0
|
||||
v.y = v.y or 0
|
||||
v.z = v.z or 0
|
||||
canrot = canrot or v.x ~= 0 or v.z ~= 0
|
||||
if v.x == 0 and v.y == 0 and v.z == 0 then
|
||||
recipe.root = v
|
||||
end
|
||||
end
|
||||
if not recipe.root or not recipe.root.match then
|
||||
error "recipe.nodes must have a match for 0,0,0"
|
||||
end
|
||||
if not canrot then recipe.norotate = true end
|
||||
if recipe.normal then
|
||||
recipe.normal.x = recipe.normal.x or 0
|
||||
recipe.normal.y = recipe.normal.y or 0
|
||||
recipe.normal.z = recipe.normal.z or 0
|
||||
end
|
||||
local newp = recipe.priority or 0
|
||||
|
||||
local rectype = craft_recipes[recipe.type]
|
||||
if not rectype then
|
||||
rectype = {}
|
||||
craft_recipes[recipe.type] = rt
|
||||
end
|
||||
|
||||
local min = 1
|
||||
local max = #rectype + 1
|
||||
while max > min do
|
||||
local try = math_floor((min + max) / 2)
|
||||
local oldp = rectype[try].priority or 0
|
||||
if newp < oldp then
|
||||
min = try + 1
|
||||
else
|
||||
max = try
|
||||
end
|
||||
end
|
||||
table_insert(rectype, min, recipe)
|
||||
end
|
145
mods/nc_api_craft/register_on_punchnode.lua
Normal file
145
mods/nc_api_craft/register_on_punchnode.lua
Normal file
@ -0,0 +1,145 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local ipairs, math, minetest, nodecore, pairs, vector
|
||||
= ipairs, math, minetest, nodecore, pairs, 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"
|
||||
|
||||
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 = 3,
|
||||
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
|
||||
|
||||
local t = {}
|
||||
for i = 1, 4 do
|
||||
t[#t + 1] = fxcore(pname, pointed, img)
|
||||
end
|
||||
return function()
|
||||
for k, v in pairs(t) do
|
||||
minetest.delete_particlespawner(v)
|
||||
end
|
||||
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 pum.particles() end
|
||||
pum.particles = particlefx(pname, pointed, pum.def)
|
||||
end
|
||||
|
||||
if resolve(pos, node, pum) then
|
||||
if pum.particles then 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
|
@ -7,7 +7,7 @@ local modname = minetest.get_current_modname()
|
||||
|
||||
local hotitems = {}
|
||||
|
||||
local function reg(shape, rawdef)
|
||||
function nodecore.register_lode(shape, rawdef)
|
||||
for _, temper in pairs({"Hot", "Annealed", "Tempered"}) do
|
||||
local def = nodecore.underride({}, rawdef)
|
||||
def = nodecore.underride(def, {
|
||||
@ -41,11 +41,7 @@ local function reg(shape, rawdef)
|
||||
end
|
||||
end
|
||||
|
||||
reg("Prill", {
|
||||
type = "craft",
|
||||
inventory_image = modname .. "_#.png^[mask:" .. modname .. "_mask_prill.png"
|
||||
})
|
||||
reg("Slab", {
|
||||
nodecore.register_lode("Slab", {
|
||||
type = "node",
|
||||
drawtype = "nodebox",
|
||||
node_box = nodecore.fixedbox(-0.5, -0.5, -0.5, 0.5, 0, 0.5),
|
||||
@ -54,13 +50,49 @@ reg("Slab", {
|
||||
light_source = 6,
|
||||
crush_damage = 1
|
||||
})
|
||||
reg("Block", {
|
||||
nodecore.register_lode("Block", {
|
||||
type = "node",
|
||||
tiles = { modname .. "_#.png" },
|
||||
light_source = 8,
|
||||
crush_damage = 4
|
||||
})
|
||||
|
||||
nodecore.register_lode("Prill", {
|
||||
type = "craft",
|
||||
inventory_image = modname .. "_#.png^[mask:" .. modname .. "_mask_prill.png",
|
||||
})
|
||||
|
||||
nodecore.extend_item(modname .. ":prill_hot", function(def)
|
||||
def.pummel_stack = 4
|
||||
end)
|
||||
nodecore.extend_pummel(modname .. ":prill_hot",
|
||||
function(pos, node, stats)
|
||||
return nodecore.toolspeed(
|
||||
stats.puncher:get_wielded_item(),
|
||||
{ thumpy = 3 })
|
||||
end,
|
||||
function(pos, node, stats)
|
||||
if stats.duration >= stats.check then
|
||||
minetest.set_node(pos, {name = modname .. ":slab_hot"})
|
||||
end
|
||||
end)
|
||||
|
||||
nodecore.extend_pummel(modname .. ":slab_hot",
|
||||
function(pos, node, stats)
|
||||
if stats.pointed.above.y <= stats.pointed.under.y then return end
|
||||
if minetest.get_node(stats.pointed.under).name ~= modname .. ":slab_hot" then return end
|
||||
return nodecore.toolspeed(
|
||||
stats.puncher:get_wielded_item(),
|
||||
{ thumpy = 3 })
|
||||
end,
|
||||
function(pos, node, stats)
|
||||
if stats.duration >= stats.check then
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node({x = pos.x, y = pos.y - 1, z = pos.z},
|
||||
{name = modname .. ":block_hot"})
|
||||
end
|
||||
end)
|
||||
|
||||
local flame = {groups = {flame = true}}
|
||||
local function heated(pos)
|
||||
if nodecore.quenched(pos) then return end
|
||||
|
Loading…
x
Reference in New Issue
Block a user