minor refactor of recipe code.
just separated different recipe types into different files.
This commit is contained in:
parent
5305cc526d
commit
45f59f5e03
3 changed files with 153 additions and 147 deletions
|
@ -1,153 +1,9 @@
|
|||
blockgame.crafting = blockgame.crafting or {}
|
||||
local api = blockgame.crafting
|
||||
|
||||
local recipes = {}
|
||||
api.registered_recipes = recipes
|
||||
|
||||
local stack_recipes = {}
|
||||
|
||||
function api.register_stack_recipe (top_node, bottom_node, result, consumes_top)
|
||||
local consumes_top = consumes_top
|
||||
if consumes_top == nil then consumes_top = true end
|
||||
|
||||
stack_recipes[top_node] = stack_recipes[top_node] or {}
|
||||
|
||||
local def = {
|
||||
["type"] = "stack_two_nodes",
|
||||
index_key = top_node,
|
||||
top_node = top_node,
|
||||
bottom_node = bottom_node,
|
||||
result = result,
|
||||
consumes_top = consumes_top,
|
||||
}
|
||||
|
||||
table.insert(stack_recipes[top_node], def)
|
||||
table.insert(api.registered_recipes, def)
|
||||
end
|
||||
|
||||
function api.handle_placement (pos, new_node, placer, old_node, itemstack, pointed_thing)
|
||||
if stack_recipes[new_node.name] == nil then return false end
|
||||
|
||||
for _, recipe in pairs(stack_recipes[new_node.name]) do
|
||||
local result = api.handle_stack_recipe(recipe, pos, new_node)
|
||||
if result then return not recipe.consumes_top end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
blockgame.register_on_placenode(function (...)
|
||||
return blockgame.crafting.handle_placement(...)
|
||||
end)
|
||||
|
||||
function api.handle_stack_recipe (recipe, pos, top_node)
|
||||
if top_node.name ~= recipe.top_node then return false end
|
||||
|
||||
local down = vector.add(pos, vector.new(0, -1, 0))
|
||||
local below = minetest.get_node(down)
|
||||
if below.name ~= recipe.bottom_node then return false end
|
||||
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(down, recipe.result)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- pummeling is heavily based on nodecore by Warr1024 (both the mechanic itself and the code here implementing it).
|
||||
|
||||
local pummel_recipes = {}
|
||||
|
||||
function api.register_pummel_recipe (def)
|
||||
local def = def or {}
|
||||
|
||||
def.label = def.label or "unnamed pummel recipe"
|
||||
|
||||
-- TODO: throw errors when these defs are invalid instead of just returning.
|
||||
if not def.used_item then return false end
|
||||
if not def.target_node then return false end
|
||||
if not type(def.on_success) == "function" then return false end
|
||||
|
||||
local key = def.used_item
|
||||
def.index_key = key
|
||||
|
||||
def["type"] = "pummel"
|
||||
|
||||
pummel_recipes[key] = pummel_recipes[key] or {}
|
||||
|
||||
table.insert(pummel_recipes[key], def)
|
||||
table.insert(api.registered_recipes, def)
|
||||
end
|
||||
|
||||
-- TODO: add support for pummel recipes using groups instead of just specific node names.
|
||||
function api.pummel_check (pos, used_item, target_node)
|
||||
local key = used_item
|
||||
if not pummel_recipes[key] then return false end
|
||||
|
||||
local potential_recipes = pummel_recipes[key]
|
||||
for _, def in pairs(potential_recipes) do
|
||||
if def.target_node == target_node.name then
|
||||
if type(def.check) == "function" and not def.check(pos, used_item, target_node) then
|
||||
return false
|
||||
end
|
||||
def.on_success(pos, used_item, target_node)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
api.registered_recipes = {}
|
||||
|
||||
|
||||
local pummeling = {}
|
||||
|
||||
-- NOTE: might wanna change this to somehow store pummels per-node instead of per-player?
|
||||
blockgame.register_on_dignode(function (_, _, digger)
|
||||
if not (digger and digger:is_player()) then return end
|
||||
pummeling[digger:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
blockgame.register_on_punchnode(function (pos, node, puncher, pointed)
|
||||
if (not puncher:is_player()) or puncher:get_player_control().sneak then return end
|
||||
local player_name = puncher:get_player_name()
|
||||
-- if not minetest.interact(player_name) then return end
|
||||
if not minetest.check_player_privs(player_name, "interact") then return end
|
||||
|
||||
node = node or minetest.get_node(pos)
|
||||
local node_def = minetest.registered_items[node.name] or {}
|
||||
if not node_def.pointable then return end
|
||||
|
||||
local wield = puncher:get_wielded_item()
|
||||
local now = minetest.get_us_time() / 1000000
|
||||
|
||||
local pummel_data = {
|
||||
action = "pummel",
|
||||
crafter = puncher,
|
||||
crafter_name = player_name,
|
||||
pos = pos,
|
||||
pointed = pointed,
|
||||
node = node,
|
||||
node_def = node_def,
|
||||
start = now,
|
||||
wield = wield:get_name() .. " " .. wield:get_count(),
|
||||
count = 0,
|
||||
}
|
||||
|
||||
local old_data = pummeling[player_name]
|
||||
local hash = minetest.hash_node_position
|
||||
if old_data and hash(old_data.pos) == hash(pummel_data.pos)
|
||||
and hash(old_data.pointed.above) == hash(pummel_data.pointed.above)
|
||||
and hash(old_data.pointed.under) == hash(pummel_data.pointed.under)
|
||||
and old_data.wield == pummel_data.wield
|
||||
and old_data.last >= (now - 3)
|
||||
then pummel_data = old_data
|
||||
end
|
||||
|
||||
pummel_data.count = pummel_data.count + 1
|
||||
pummel_data.last = now
|
||||
pummel_data.duration = now - pummel_data.start - 1
|
||||
pummeling[player_name] = pummel_data
|
||||
|
||||
if pummel_data.count < 2 then return end
|
||||
|
||||
if api.pummel_check(pos, wield:get_name(), minetest.get_node(pointed.under)) then
|
||||
pummeling[player_name] = nil
|
||||
end
|
||||
end)
|
||||
load_file("stack")
|
||||
load_file("pummel")
|
||||
|
|
100
mods/bg_crafting/pummel.lua
Normal file
100
mods/bg_crafting/pummel.lua
Normal file
|
@ -0,0 +1,100 @@
|
|||
local api = blockgame.crafting
|
||||
|
||||
-- pummeling is heavily based on nodecore by Warr1024 (both the mechanic itself and the code here implementing it).
|
||||
|
||||
local pummel_recipes = {}
|
||||
|
||||
function api.register_pummel_recipe (def)
|
||||
local def = def or {}
|
||||
|
||||
def.label = def.label or "unnamed pummel recipe"
|
||||
|
||||
-- TODO: throw errors when these defs are invalid instead of just returning.
|
||||
if not def.used_item then return false end
|
||||
if not def.target_node then return false end
|
||||
if not type(def.on_success) == "function" then return false end
|
||||
|
||||
local key = def.used_item
|
||||
def.index_key = key
|
||||
|
||||
def["type"] = "pummel"
|
||||
|
||||
pummel_recipes[key] = pummel_recipes[key] or {}
|
||||
|
||||
table.insert(pummel_recipes[key], def)
|
||||
table.insert(api.registered_recipes, def)
|
||||
end
|
||||
|
||||
-- TODO: add support for pummel recipes using groups instead of just specific node names.
|
||||
function api.pummel_check (pos, used_item, target_node)
|
||||
local key = used_item
|
||||
if not pummel_recipes[key] then return false end
|
||||
|
||||
local potential_recipes = pummel_recipes[key]
|
||||
for _, def in pairs(potential_recipes) do
|
||||
if def.target_node == target_node.name then
|
||||
if type(def.check) == "function" and not def.check(pos, used_item, target_node) then
|
||||
return false
|
||||
end
|
||||
def.on_success(pos, used_item, target_node)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local pummeling = {}
|
||||
|
||||
-- NOTE: might wanna change this to somehow store pummels per-node instead of per-player?
|
||||
blockgame.register_on_dignode(function (_, _, digger)
|
||||
if not (digger and digger:is_player()) then return end
|
||||
pummeling[digger:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
blockgame.register_on_punchnode(function (pos, node, puncher, pointed)
|
||||
if (not puncher:is_player()) or puncher:get_player_control().sneak then return end
|
||||
local player_name = puncher:get_player_name()
|
||||
-- if not minetest.interact(player_name) then return end
|
||||
if not minetest.check_player_privs(player_name, "interact") then return end
|
||||
|
||||
node = node or minetest.get_node(pos)
|
||||
local node_def = minetest.registered_items[node.name] or {}
|
||||
if not node_def.pointable then return end
|
||||
|
||||
local wield = puncher:get_wielded_item()
|
||||
local now = minetest.get_us_time() / 1000000
|
||||
|
||||
local pummel_data = {
|
||||
action = "pummel",
|
||||
crafter = puncher,
|
||||
crafter_name = player_name,
|
||||
pos = pos,
|
||||
pointed = pointed,
|
||||
node = node,
|
||||
node_def = node_def,
|
||||
start = now,
|
||||
wield = wield:get_name() .. " " .. wield:get_count(),
|
||||
count = 0,
|
||||
}
|
||||
|
||||
local old_data = pummeling[player_name]
|
||||
local hash = minetest.hash_node_position
|
||||
if old_data and hash(old_data.pos) == hash(pummel_data.pos)
|
||||
and hash(old_data.pointed.above) == hash(pummel_data.pointed.above)
|
||||
and hash(old_data.pointed.under) == hash(pummel_data.pointed.under)
|
||||
and old_data.wield == pummel_data.wield
|
||||
and old_data.last >= (now - 3)
|
||||
then pummel_data = old_data
|
||||
end
|
||||
|
||||
pummel_data.count = pummel_data.count + 1
|
||||
pummel_data.last = now
|
||||
pummel_data.duration = now - pummel_data.start - 1
|
||||
pummeling[player_name] = pummel_data
|
||||
|
||||
if pummel_data.count < 2 then return end
|
||||
|
||||
if api.pummel_check(pos, wield:get_name(), minetest.get_node(pointed.under)) then
|
||||
pummeling[player_name] = nil
|
||||
end
|
||||
end)
|
50
mods/bg_crafting/stack.lua
Normal file
50
mods/bg_crafting/stack.lua
Normal file
|
@ -0,0 +1,50 @@
|
|||
local api = blockgame.crafting
|
||||
|
||||
local stack_recipes = {}
|
||||
|
||||
function api.register_stack_recipe (top_node, bottom_node, result, consumes_top)
|
||||
local consumes_top = consumes_top
|
||||
if consumes_top == nil then consumes_top = true end
|
||||
|
||||
stack_recipes[top_node] = stack_recipes[top_node] or {}
|
||||
|
||||
local def = {
|
||||
["type"] = "stack_two_nodes",
|
||||
index_key = top_node,
|
||||
top_node = top_node,
|
||||
bottom_node = bottom_node,
|
||||
result = result,
|
||||
consumes_top = consumes_top,
|
||||
}
|
||||
|
||||
table.insert(stack_recipes[top_node], def)
|
||||
table.insert(api.registered_recipes, def)
|
||||
end
|
||||
|
||||
function api.handle_stack_recipe (recipe, pos, top_node)
|
||||
if top_node.name ~= recipe.top_node then return false end
|
||||
|
||||
local down = vector.add(pos, vector.new(0, -1, 0))
|
||||
local below = minetest.get_node(down)
|
||||
if below.name ~= recipe.bottom_node then return false end
|
||||
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(down, recipe.result)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function api.handle_placement (pos, new_node, placer, old_node, itemstack, pointed_thing)
|
||||
if stack_recipes[new_node.name] == nil then return false end
|
||||
|
||||
for _, recipe in pairs(stack_recipes[new_node.name]) do
|
||||
local result = api.handle_stack_recipe(recipe, pos, new_node)
|
||||
if result then return not recipe.consumes_top end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
blockgame.register_on_placenode(function (...)
|
||||
return blockgame.crafting.handle_placement(...)
|
||||
end)
|
Loading…
Reference in a new issue