2022-01-01 23:14:03 -05:00

266 lines
12 KiB
Lua

--this will allow other mods to see crafts, but not modify the actual data used
--do note that because of this method, crafts can be registered during game play,
--however will not show up in registered_crafts
local registered_anvil_crafts = {}
minetest.register_on_mods_loaded(function()
fl_workshop.registered_anvil_crafts = table.copy(registered_anvil_crafts)
end)
--this could have more protections
function fl_workshop.register_anvil_craft(craft_table)
assert(craft_table, "[fl_workshop:anvil] failure to provide craft table!")
if type(craft_table) ~= "table" then error("[fl_workshop:anvil] value passed is not a table!") end
assert(craft_table.output, "[fl_workshop:anvil] failure to provide craft output!")
if type(craft_table.output) ~= "string" then error("[fl_workshop:anvil] output is not a string!") end
assert(craft_table.recipe, "[fl_workshop:anvil] failure to provide craft recipe!")
if type(craft_table.recipe) ~= "table" then error("[fl_workshop:anvil] recipe is not a table!") end
table.insert(registered_anvil_crafts, craft_table)
end
--[[
--how to use it
fl_workshop.register_anvil_craft({
output = string value of output itemstack,
recipe = {string itemstack, string itemstack}
})
--example registration
fl_workshop.register_anvil_craft({
recipe = {"fl_tools:gold_shovel", "fl_ores:diamond_ore"},
output = "fl_tools:diamond_shovel"
})
--]]
--table containing players currently shown anvil formspec
viewing_anvil = {}
minetest.register_node("fl_workshop:anvil", {
description = "anvil",
paramtype = "light",
paramtype2 = "facedir",
use_texture_alpha = "clip",
drawtype = "mesh",
mesh = "farlands_anvil.obj",
visual_scale = 0.5,
wield_scale = {x=0.5, y=0.5, z=0.5},
selection_box = {
type = "fixed",
fixed = {
{-0.3, -0.5, -0.45, 0.3, -0.2, 0.45}, --base
{-0.25, -0.2, -0.375, 0.25, 0, 0.375}, --middle
{-0.3125, 0, -0.5, 0.3125, 0.5, 0.5}, --top
}
},
collision_box = {
type = "fixed",
fixed = {
{-0.3, -0.5, -0.45, 0.3, -0.2, 0.45}, --base
{-0.25, -0.2, -0.375, 0.25, 0, 0.375}, --middle
{-0.3125, 0, -0.5, 0.3125, 0.5, 0.5}, --top
}
},
tiles = {"farlands_anvil.png"},
on_construct = function(pos)
local inv = minetest.get_meta(pos):get_inventory()
inv:set_size("input", 2)
inv:set_size("output", 1)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
--vars for stuff
--local chName = "chest name"
local iPos = pos.x .. "," .. pos.y .. "," .. pos.z
local cInvSize = clicker:get_inventory():get_size("main")
local rLength = (cInvSize-9)/3
local slotSize
local formSize
if rLength == 12 then slotSize, formSize = 0.725, "10.4,9.475"
elseif rLength == 11 then slotSize, formSize = 0.8, "10.4,9.7"
elseif rLength == 10 then slotSize, formSize = 0.89, "10.4,9.97"
else slotSize, formSize = 1, "10.4,10.3" end
--header of formspec
local formspec = {
"formspec_version[4]",
"size[" .. formSize .. "]",
"no_prepend[]",
"style_type[box;colors=#77777710,#77777710,#777,#777]",
"style_type[list;size=1;spacing=0.1]",
"listcolors[#0000;#ffffff20]",
"bgcolor[black;neither]",
"background9[0,0;" .. formSize .. ";i3_bg_full.png;false;10]",
}
--build anvil part
local anvil_formspec = {
"image[0.25,0.5;2,2;farlands_hammer.png]",
"label[3.25,1;Name & Upgrade]",
--start description input
"box[3.25,1.5;4,0.5;#bababa25]",
"style_type[field;border=false]",
"field[3.3,1.5;3.3,0.5;description;;]",
"field_close_on_enter[description;false]",
"style_type[image_button;border=false]",
"style_type[image_button:hovered;fgimg=i3_export.png^\\[brighten]",
"image_button[6.75,1.55;0.35,0.35;i3_export.png;set_description;]",
--start crafting section
"box[1.7,3.2;1,1;]",
"list[nodemeta:" .. iPos .. ";input;1.7,3.2;1,1;]",
"image[3.3,3.3;0.8,0.8;i3_dash.png^\\(i3_dash.png\\^[transformR90)]",
"box[4.7,3.2;1,1;]",
"list[nodemeta:" .. iPos .. ";input;4.7,3.2;1,1;1]",
"image[6.2,3.2;1,1;i3_arrow.png]",
"box[7.7,3.2;1,1;]",
"list[nodemeta:" .. iPos .. ";output;7.7,3.2;1,1;]",
}
table.insert(formspec, table.concat(anvil_formspec, ""))
--build inventory part of formspec
table.insert(formspec, "label[0.3,5.4;Inventory]")
table.insert(formspec, "style_type[box;colors=#77777710,#77777710,#777,#777]")
for i=0, 8 do
table.insert(formspec, "box[" .. 0.3+i+(i*0.1) ..",5.7;1,1;]")
end
table.insert(formspec, "list[current_player;main;0.3,5.7;9,1;]")
table.insert(formspec, "style_type[list;size=" .. slotSize .. ";spacing=0.1]")
table.insert(formspec, "style_type[box;colors=#666]") -- change bottom 3 rows color
for i=0, 2 do
for j=0, rLength-1 do
table.insert(formspec, "box[" .. 0.3+(j*0.1)+(j*slotSize) .."," .. 6.8+(i*0.1)+(i*slotSize) .. ";"
.. slotSize .. "," .. slotSize .. ";]")
end
table.insert(formspec, "list[current_player;main;0.3," .. 6.8+(i*0.1)+(i*slotSize) .. ";"
.. rLength .. ",1;" .. 9+(rLength*i) .. "]")
end
--enable shiftclicking?
table.insert(formspec, "listring[nodemeta:" .. iPos .. ";input]")
table.insert(formspec, "listring[current_player;main]")
--show formspec
local chest_formspec = table.concat(formspec, "")
minetest.show_formspec(clicker:get_player_name(), "fl_workshop:anvil_formspec", chest_formspec)
viewing_anvil[clicker:get_player_name()] = pos
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if listname == "output" then return 0 else return stack:get_count() end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if to_list == "output" then return 0
elseif from_list == "output" and to_list == "input" then
local inv = minetest.get_meta(pos):get_inventory()
if inv:get_stack(to_list, to_index):is_empty() then return count else return 0 end
else return 0 end
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "input" and inv:get_stack(listname, 1):get_name() == inv:get_stack(listname, 2):get_name() then
if minetest.get_item_group(inv:get_stack(listname, index):get_name(), "tool") ~= 0 then
local out_stack = inv:get_stack(listname, 1)
local out_wear = inv:get_stack(listname, 2):get_wear()
out_stack:set_wear(65535 - ((65535 - inv:get_stack(listname, 1):get_wear()) + (65535 - out_wear)))
inv:set_stack("output", 1, out_stack)
return
end
end
if minetest.get_item_group(inv:get_stack("input", 2):get_name(), "dye") ~= 0
and inv:get_stack("input", 1):get_name() ~= "" then
--minetest.chat_send_all("sucess")
local color
local spltstr = string.split(inv:get_stack("input", 2):get_name(), ":")
for _, drow in pairs(fl_dyes.dyes) do
if drow[1] == string.sub(spltstr[2], 1, -5) then
color = drow[3]
end
end
if inv:get_stack("input", 1):get_meta():get_string("description") ~= "" then
local out_stack = ItemStack(inv:get_stack("input", 1):get_name())
out_stack:get_meta():set_string(
"description",
minetest.colorize(
color,
minetest.strip_colors(inv:get_stack("input", 1):get_meta():get_string("description"))
)
)
inv:set_stack("output", 1, out_stack)
else
if not minetest.registered_items[inv:get_stack("input", 1):get_name()] then return end
local desc = minetest.registered_items[inv:get_stack("input", 1):get_name()].description
local out_stack = ItemStack(inv:get_stack("input", 1):get_name())
out_stack:get_meta():set_string("description", minetest.colorize(color, desc))
inv:set_stack("output", 1, out_stack)
end
end
if not inv:get_stack("input", 1):is_empty() and not inv:get_stack("input", 2):is_empty() then
for _, craft_table in pairs(registered_anvil_crafts) do
if inv:get_stack("input", 1):get_name() == craft_table.recipe[1]
and inv:get_stack("input", 2):get_name() == craft_table.recipe[2] then
inv:set_stack("output", 1, ItemStack(craft_table.output))
end
end
end
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "input" then inv:set_stack("output", 1, ItemStack(""))
elseif listname == "output" then
local one = inv:get_stack("input", 1)
local two = inv:get_stack("input", 2)
one:take_item()
two:take_item()
inv:set_stack("input", 1, one)
inv:set_stack("input", 2, two)
end
end,
on_dig = function(pos, node, digger)
local inv = minetest.get_inventory({type="node", pos=pos})
for _, item in ipairs(inv:get_list("input")) do
local posi = {
x=pos.x + (math.random(-2,2)/5),
y=pos.y + (math.random(0,2)/5),
z=pos.z + (math.random(-2,2)/5),
}
minetest.add_item(posi, item)
end
minetest.node_dig(pos, node, digger)
end,
on_place = minetest.rotate_node,
groups = {oddly_breakable_by_hand = 1},
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "fl_workshop:anvil_formspec" then return end
if fields.quit == "true" then
viewing_anvil[player:get_player_name()] = nil
return
end
--minetest.chat_send_all(dump(fields))
local anvil_inv = minetest.get_inventory({type = "node", pos = viewing_anvil[player:get_player_name()]})
if fields.description and not anvil_inv:get_stack("output", 1):is_empty() and fields.description ~= "" then
local desc = fields.description
local i, j = string.find(anvil_inv:get_stack("output", 1):get_meta():get_string("description"), "%(c@[^)]+%)")
if j then
local ccode = string.sub(anvil_inv:get_stack("output", 1):get_meta():get_string("description"), i, j)
desc = "\27" .. ccode .. fields.description .. "\27(c@#ffffff)"
end
local stack = anvil_inv:get_stack("output", 1)
stack:set_count(1)
stack:get_meta():set_string("description", desc)
anvil_inv:set_stack("output", 1, stack)
elseif anvil_inv:get_stack("output", 1):is_empty()
and not anvil_inv:get_stack("input", 1):is_empty()
and fields.description ~= "" then
local stack = anvil_inv:get_stack("input", 1)
stack:set_count(1)
--testing colorization
--stack:get_meta():set_string("description", minetest.colorize("#000000", fields.description))
stack:get_meta():set_string("description", fields.description)
anvil_inv:set_stack("output", 1, stack)
end
end)