magicalities/table.lua

336 lines
8.8 KiB
Lua

magicalities.arcane = { recipes = {} }
local fmspecelems = {
["earth"] = {2.98, 0.15},
["water"] = {1, 1},
["air"] = {5, 1},
["fire"] = {2.98, 4.85},
["light"] = {1, 4},
["dark"] = {5, 4}
}
local function arcane_table_formspec(requirements, present)
local spec = ""
local labels = ""
if not requirements then
requirements = {}
end
if not present then
present = {}
end
for name, pos in pairs(fmspecelems) do
local cp = ""
local y = -0.4
if not requirements[name] or not present[name] then
cp = "^[colorize:#2f2f2f:200"
end
if pos[2] > 2.5 then
y = 0.85
end
spec = spec .. "image["..pos[1]..","..pos[2]..";1,1;magicalities_symbol_"..name..".png"..cp.."]"
spec = spec .. "tooltip["..pos[1]..","..pos[2]..";1,1;"..magicalities.elements[name].description.."]"
if requirements[name] then
labels = labels .. "label["..(pos[1] + 0.3)..","..(pos[2] + y)..";"..requirements[name].."]"
end
end
return "size[10,10.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;Arcane Crafting Table]"..
"image[0.98,0.3;6,6;magicalities_symbol_hexagram.png]"..
spec..
"list[context;craft;2,1.5;3,3;]"..
"list[context;craftres;7,2.5;1,1;]"..
"image[7,1;1,1;magicalities_gui_wand_slot.png]"..
"list[context;wand;7,1;1,1;]"..
labels..
"image[6,2.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_player;main;1,6.25;8,1;]"..
"list[current_player;main;1,7.5;8,3;8]"..
"listring[context;wand]"..
"listring[current_player;main]"..
"listring[context;craft]"..
"listring[current_player;main]"..
"listring[context;craftres]"..
"listring[current_player;main]"..
default.get_hotbar_bg(1, 6.25)
end
function magicalities.arcane.register_recipe(data)
if data.learnable then
local recipe_data = { name = data.output }
if type(data.learnable) == "string" then
recipe_data.name = data.learnable
end
if type(data.learnable) == "table" then
recipe_data = table.copy(data.learnable)
if not recipe_data.name then
recipe_data.name = data.output
end
end
if not data.description then
local itm = minetest.registered_items[data.output]
recipe_data.description = itm.description
else
recipe_data.description = data.description .. ""
data.description = nil
end
data.learnable = recipe_data.name
magicalities.register_recipe_learnable(recipe_data)
end
table.insert(magicalities.arcane.recipes, data)
end
local function split_components(items)
local arrays = {}
local temp = {}
local index = 1
for i, k in pairs(items) do
temp[#temp + 1] = k:get_name()
index = index + 1
if index == 4 then
-- Don't add blank rows
local blanks = 0
for _, tmp in pairs(temp) do
if tmp == "" then
blanks = blanks + 1
end
end
if blanks ~= 3 then
arrays[#arrays + 1] = temp
end
temp = {}
index = 1
end
end
return arrays
end
local function compare_find(splitup)
local found = nil
for _,recipe in pairs(magicalities.arcane.recipes) do
-- Don't even bother if it doesnt have the correct amount of rows
if #splitup == #recipe.input then
local rows = 0
for index, row in pairs(recipe.input) do
if not splitup[index] then break end
if #splitup[index] ~= #row then break end
local cells = 0
for i, cell in pairs(row) do
if cell:find("group:") == 1 then
if minetest.get_item_group(splitup[index][i], cell:gsub("group:", "")) > 0 then
cells = cells + 1
end
elseif splitup[index][i] == cell then
cells = cells + 1
end
end
if cells == #row then
rows = rows + 1
end
end
if rows == #recipe.input then
found = recipe
break
end
end
end
return found
end
function magicalities.arcane.get_recipe(items)
local split = split_components(items)
local recipe = compare_find(split)
if not recipe then return nil end
local result = {new_input = {}, output = recipe.output, requirements = recipe.requirements, learnable = recipe.learnable}
for _,stack in pairs(items) do
stack:take_item(1)
result.new_input[#result.new_input + 1] = stack
end
return result
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if (listname == "wand" and minetest.get_item_group(stack:get_name(), "wand") == 0) or listname == "craftres" then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
if from_list == "craftres" and to_list == "craft" then return 0 end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function set_output(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- Check for possible result
local result = magicalities.arcane.get_recipe(inv:get_list("craft"))
if not result then return nil end
-- Check for wand
local wand = inv:get_stack("wand", 1)
if not wand or wand:is_empty() then
return nil, result
end
-- Check requirements
local requirements = result.requirements
if not magicalities.wands.wand_has_contents(wand, requirements) then
return nil, result
end
-- Output fits
local output = ItemStack(result.output)
if not inv:room_for_item("craftres", output) then
return inv:get_stack("craftres", 1), result
end
-- Set output
return output, result
end
local function requirements_present(requirements, wand)
local present = {}
if wand:is_empty() or not requirements then return present end
for req, cnt in pairs(requirements) do
present[req] = magicalities.wands.wand_has_contents(wand, {[req] = cnt})
end
return present
end
local function update_craft(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local out, recipe = set_output(pos)
-- Make sure wand is inserted
-- Check if the recipe has been learned by the player
local wand = inv:get_stack("wand", 1)
if not recipe or wand:is_empty() or
(recipe.learnable ~= nil and not magicalities.player_has_recipe(magicalities.wands.get_wand_owner(wand), recipe.learnable)) then
meta:set_string("formspec", arcane_table_formspec({}))
inv:set_list("craftres", {})
return
end
local present = requirements_present(recipe.requirements, wand)
if recipe.requirements then
meta:set_string("formspec", arcane_table_formspec(recipe.requirements, present))
else
meta:set_string("formspec", arcane_table_formspec({}))
end
inv:set_list("craftres", { out })
end
-- Arcane Crafting Table
minetest.register_node("magicalities:arcane_table", {
description = "Arcane Crafting Table",
tiles = {
"magicalities_table_arcane_top.png", "magicalities_table_arcane.png", "magicalities_table_arcane.png",
"magicalities_table_arcane.png", "magicalities_table_arcane.png", "magicalities_table_arcane.png",
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", arcane_table_formspec())
local inv = meta:get_inventory()
inv:set_size("craft", 9)
inv:set_size("craftres", 1)
inv:set_size("wand", 1)
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "craftres" then
local res = magicalities.arcane.get_recipe(inv:get_list("craft"))
if res then
inv:set_list("craft", res.new_input)
-- Take from wand
local wand = inv:get_stack("wand", 1)
wand = magicalities.wands.wand_take_contents(wand, res.requirements)
magicalities.wands.update_wand_desc(wand)
inv:set_list("wand", {wand})
end
end
update_craft(pos)
end,
on_metadata_inventory_put = update_craft,
on_metadata_inventory_move = update_craft,
groups = {choppy = 2, oddly_breakable_by_hand = 1, arcane_table = 1}
})
-- Base Table
minetest.register_node("magicalities:table", {
description = "Table",
drawtype = "nodebox",
tiles = {
"magicalities_table_wood_top.png", "magicalities_table_wood.png", "magicalities_table_wood.png",
"magicalities_table_wood.png", "magicalities_table_wood.png", "magicalities_table_wood.png",
},
node_box = {
type = "fixed",
fixed = {
{-0.2500, -0.5000, -0.2500, 0.2500, -0.3750, 0.2500},
{-0.1250, -0.3750, -0.1250, 0.1250, 0.3750, 0.1250},
{-0.5000, 0.3750, -0.5000, 0.5000, 0.5000, 0.5000}
}
},
sunlight_propagates = true,
groups = {choppy = 2, oddly_breakable_by_hand = 1, enchanted_table = 1}
})