Add new crafting mod for a new crafting method

This commit is contained in:
KaadmY 2017-05-13 10:27:40 -07:00
parent af8e2093be
commit c797a15e8b
14 changed files with 214 additions and 201 deletions

8
mods/crafting/README.txt Normal file
View File

@ -0,0 +1,8 @@
Cratfing mod
============
By Kaadmy, for Pixture
Custom crafting method, uses a list of possible items to craft instead of a grid
recipe.
Source license: LGPLv2.1

203
mods/crafting/init.lua Normal file
View File

@ -0,0 +1,203 @@
--
-- Crafting mod
-- By Kaadmy, for Pixture
--
crafting = {}
crafting.registered_crafts = {}
-- Crafting can only take 4 itemstacks as input for sanity/interface reasons
crafting.max_inputs = 4
-- Default crafting definition values
crafting.default_craftdef = {
output = nil,
description = "",
items = {},
}
function crafting.register_craft(output, def)
-- `output` can be any ItemStack value, but count is NOT used
local itemstack = ItemStack(output)
local itemn = itemstack:get_name()
if crafting.registered_crafts[itemn] ~= nil then
minetest.log("warning",
"Tried to register an existing craft " .. itemn)
return
end
local craftdef = {
output = itemstack,
description = def.description or minetest.registered_items[itemn].description,
items = def.items or default.default_craftdef.items,
}
if #craftdef.items > 4 then
minetest.log("warning",
"Attempting to register craft " .. itemn .." with more than "
.. crafting.max_inputs .. " inputs, keeping")
end
for i = 1, crafting.max_inputs do
craftdef.items[i] = ItemStack(craftdef.items[i])
end
crafting.registered_crafts[itemn] = craftdef
minetest.log("info", "Registered recipe for " .. itemn .. ": " .. dump(crafting.registered_crafts[itemn]))
end
function crafting.craft(output, items)
-- `output` can be any ItemStack value
-- Duplicate items in `items` should work correctly
print(dump(output))
local wanted_itemstack = ItemStack(output)
print(dump(wanted_itemstack:to_string()))
local craftdef = crafting.registered_crafts[wanted_itemstack:get_name()]
if craftdef == nil then
minetest.log("warning",
"Tried to craft an unregistered item " .. wanted_itemstack:get_name())
return nil
end
--print("Craftdef items: " .. dump(craftdef.items))
print("Input before: " .. dump(items))
-- Check for validity
local craft_count = wanted_itemstack:get_count()
for i = 1, crafting.max_inputs do
local required_itemstack = ItemStack(craftdef.items[i])
local itemc = 0
if required_itemstack ~= nil and required_itemstack:get_count() ~= 0 then
for j = 1, crafting.max_inputs do
local input_itemstack = ItemStack(items[j])
if input_itemstack:get_name() == required_itemstack:get_name() then
itemc = itemc + input_itemstack:get_count()
end
end
craft_count = math.min(craft_count, math.floor(itemc / required_itemstack:get_count()))
if craft_count < 1 then
minetest.log("warning",
"Not enough items to craft " .. wanted_itemstack:get_name())
return nil -- Not enough items
end
end
end
--print("Craft count: " .. craft_count .. "/" .. output.count)
-- Iterate through second time to take items used for crafting
local function remove_used_item(itemn, count)
local items_required = count
for i = 1, crafting.max_inputs do
local input_itemstack = ItemStack(items[i])
if items[i] ~= nil and input_itemstack:get_name() == itemn then
local items_left = items_required - input_itemstack:get_count()
print("Taking " .. items_required .. " items from " .. itemn)
input_itemstack:take_item(items_required)
if items_left > 0 then
items_required = items_required - (items_required - items_left)
else
items[i] = input_itemstack:to_table()
break
end
items[i] = input_itemstack:to_table()
end
end
end
for i = 1, crafting.max_inputs do
local required_itemstack = ItemStack(craftdef.items[i])
if craftdef.items[i] ~= nil then
remove_used_item(required_itemstack:get_name(), required_itemstack:get_count() * craft_count)
end
end
print("Input after: " .. dump(items))
return items
end
crafting.register_craft(
"default:stone 4",
{
items = {
{name = "default:stick", count = 3},
{name = "default:fiber", count = 2},
{name = "group:stone", count = 2},
},
})
crafting.craft(
"default:stone 2",
{
{name = "default:stick", count = 4}, -- 0 leftover
{name = "default:stick", count = 5}, -- 3 leftover
{name = "default:fiber", count = 9}, -- 5 leftover
{name = "group:stone", count = 4}, -- 0 leftover
})
local function on_player_recieve_fields(player, form_name, fields)
if form_name ~= "crafting:crafting" or fields.cancel then return end
local inv = player:get_inventory()
if fields.trade then
local item = player:get_wielded_item()
local trade_wanted1 = inv:get_stack("gold_trade_wanted", 1):to_string()
local trade_wanted2 = inv:get_stack("gold_trade_wanted", 2):to_string()
local trade_in1 = inv:get_stack("gold_trade_in", 1):to_string()
local trade_in2 = inv:get_stack("gold_trade_in", 2):to_string()
local matches = trade_wanted1 == trade_in1 and trade_wanted2 == trade_in2
local meta = minetest.deserialize(item:get_metadata())
local trade = {"gold:gold", "gold:gold", "default:stick"}
local trade_type = ""
if meta then
trade = meta.trade
trade_type = meta.trade_type
end
if matches then
if inv:room_for_item("gold_trade_out", trade[3]) then
inv:add_item("gold_trade_out", trade[3])
inv:set_stack("gold_trade_in", 1, "")
inv:set_stack("gold_trade_in", 2, "")
end
end
end
end
minetest.register_on_player_receive_fields(on_player_recieve_fields)
default.log("mod:crafting", "loaded")

View File

@ -1,9 +0,0 @@
Crafting guide mod
==================
By Kaadmy, for Pixture
This mod adds a crafting guide in your inventory.
Asset license: CC BY-SA 4.0
Source license: LGPLv2.1

View File

@ -1 +0,0 @@
default

View File

@ -1,183 +0,0 @@
--
-- Crafting guide mod
-- By Kaadmy, for Pixture
--
craftingguide = {}
craftingguide.items = {}
craftingguide.itemlist = {}
craftingguide.users = {} -- {item = selected item, itemno = recipe no., page = page no.}
local page_size = 8 * 4
function craftingguide.get_formspec(name)
local user = craftingguide.users[name]
local page = user.page
local max_pages = math.floor(#craftingguide.itemlist / page_size) + 1
local form = ""
form = form .. default.ui.get_page("core_craftingguide")
form = form .. "label[0.41,1.74;"..user.itemno.."/"..#craftingguide.items[user.item].."]" -- itemno
form = form .. "label[3.9,8.15;"..page.."/"..max_pages.."]" -- page
form = form .. "label[4.4,2.5;"..minetest.formspec_escape(minetest.registered_items[user.item].description).."]" -- itemname
local method = craftingguide.items[user.item][user.itemno].type
if method == "normal" or method == "crafting" then
form = form .. "image[4.25,1.5;1,1;craftingguide_method_crafting.png]"
elseif method == "cooking" then
form = form .. "image[4.25,1.5;1,1;craftingguide_method_cooking.png]"
-- fuel recipes are different
-- elseif method == "fuel" then
-- form = form .. "image[4.25,1.5;1,1;craftingguide_method_fuel.png]"
else
form = form .. "image[4.25,1.5;1,1;craftingguide_method_unknown.png]"
form = form .. "label[4.1,1.73;"..method.."]"
end
local recipes = craftingguide.items[user.item]
local recipe = recipes[user.itemno]
form = form .. default.ui.fake_itemstack(6.25, 1.5, ItemStack(recipe.output), "guide_craftresult")
-- print(dump(recipe))
for slot_index, itemname in pairs(recipe.items) do
local x = slot_index - 1
local group = string.match(itemname, "group:(.*)")
local w = 3
if recipe.width ~= 0 then
w = recipe.width
end
if group == nil then
form = form .. default.ui.fake_simple_itemstack(1.25 + (x % w), 0.5 + math.floor(x / w), itemname, "guide_craftgrid_"..itemname)
else
form = form .. default.ui.item_group(1.25 + (x % w), 0.5 + math.floor(x / w), group, "guide_craftgrid_"..itemname)
end
end
local page_start = ((page * page_size) - page_size) + 1
local inv_x = 0
local inv_y = 0
for item_index = page_start, (page_start + page_size) - 1 do
local recipes = craftingguide.items[craftingguide.itemlist[item_index]]
if recipes ~= nil then
local itemname = ItemStack(recipes[1].output):get_name()
form = form .. default.ui.fake_simple_itemstack(0.25 + inv_x, 4 + inv_y, itemname, "guide_item_"..itemname)
inv_x = inv_x + 1
if inv_x >= 8 then
inv_x = 0
inv_y = inv_y + 1
end
else
break
end
end
return form
end
local function receive_fields(player, form_name, fields)
if form_name == "core_craftingguide" and not fields.quit then
local name = player:get_player_name()
local user = craftingguide.users[name]
local page = user.page
local recipes = craftingguide.items[user.item]
local itemno = user.itemno
local max_pages = math.floor(#craftingguide.itemlist / page_size) + 1
if fields.guide_next_recipe then
if itemno < #recipes then
itemno = itemno + 1
else
itemno = 1
end
elseif fields.guide_prev_recipe then
if itemno <= 1 then
itemno = #recipes
else
itemno = itemno - 1
end
end
if fields.guide_next and page < max_pages then
page = page + 1
elseif fields.guide_prev and page > 1 then
page = page - 1
end
for fieldname, val in pairs(fields) do
local itemname = string.match(fieldname, "guide_item_(.*)")
if itemname ~= nil then
itemno = 1
craftingguide.users[name].item = itemname
end
end
craftingguide.users[name].page = page
craftingguide.users[name].itemno = itemno
minetest.show_formspec(name, "core_craftingguide", craftingguide.get_formspec(name))
end
end
local function on_joinplayer(player)
local name = player:get_player_name()
craftingguide.users[name] = {page = 1, item = craftingguide.itemlist[1], itemno = 1}
end
local function on_leaveplayer(player)
local name = player:get_player_name()
craftingguide.users[name] = nil
end
local function load_recipes()
for itemname, itemdef in pairs(minetest.registered_items) do
local recipes = minetest.get_all_craft_recipes(itemname)
if recipes ~= nil and itemname ~= "" then
-- print(dump(recipes))
craftingguide.items[itemname] = recipes
table.insert(craftingguide.itemlist, itemname)
end
end
table.sort(craftingguide.itemlist)
print("Got "..#craftingguide.itemlist.." craftable items")
end
minetest.after(0, load_recipes)
minetest.register_on_joinplayer(on_joinplayer)
minetest.register_on_leaveplayer(on_leaveplayer)
minetest.register_on_player_receive_fields(receive_fields)
local form_craftingguide = default.ui.get_page("core")
form_craftingguide = form_craftingguide .. default.ui.get_itemslot_bg(0.25, 4, 8, 4)
form_craftingguide = form_craftingguide .. default.ui.image_button(2.5, 7.9, 1, 1, "guide_prev", "ui_arrow_bg.png^[transformR90")
form_craftingguide = form_craftingguide .. default.ui.image_button(5, 7.9, 1, 1, "guide_next", "ui_arrow_bg.png^[transformR270")
form_craftingguide = form_craftingguide .. default.ui.image_button(0.25, 0.5, 1, 1, "guide_next_recipe", "ui_arrow_bg.png")
form_craftingguide = form_craftingguide .. default.ui.image_button(0.25, 2.5, 1, 1, "guide_prev_recipe", "ui_arrow_bg.png^[transformFY")
form_craftingguide = form_craftingguide .. default.ui.get_itemslot_bg(1.25, 0.5, 3, 3)
form_craftingguide = form_craftingguide .. default.ui.get_itemslot_bg(6.25, 1.5, 1, 1)
form_craftingguide = form_craftingguide .. "image[5.25,1.5;1,1;"..minetest.formspec_escape("ui_arrow.png^[transformR270").."]"
default.ui.register_page("core_craftingguide", form_craftingguide)
default.log("mod:craftingguide", "loaded")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

View File

@ -171,17 +171,14 @@ form_core = form_core .. "size[8.5,9]"
form_core = form_core .. default.ui.core.colors
form_core = form_core .. default.ui.core.bg
form_core = form_core .. default.ui.tab(-0.9, 0.5, "tab_crafting", "ui_icon_crafting.png", "Crafting")
if minetest.get_modpath("craftingguide") ~= nil then
form_core = form_core .. default.ui.tab(-0.9, 1.28, "tab_craftingguide", "ui_icon_craftingguide.png", "Crafting Guide")
end
if minetest.get_modpath("armor") ~= nil then
form_core = form_core .. default.ui.tab(-0.9, 2.06, "tab_armor", "ui_icon_armor.png", "Armor")
form_core = form_core .. default.ui.tab(-0.9, 1.28, "tab_armor", "ui_icon_armor.png", "Armor")
end
if minetest.get_modpath("achievements") ~= nil then
form_core = form_core .. default.ui.tab(-0.9, 2.84, "tab_achievements", "ui_icon_achievements.png", "Achievements")
form_core = form_core .. default.ui.tab(-0.9, 2.06, "tab_achievements", "ui_icon_achievements.png", "Achievements")
end
if minetest.get_modpath("player_skins") ~= nil then
form_core = form_core .. default.ui.tab(-0.9, 3.62, "tab_player_skins", "ui_icon_player_skins.png", "Player Skins")
form_core = form_core .. default.ui.tab(-0.9, 2.84, "tab_player_skins", "ui_icon_player_skins.png", "Player Skins")
end
form_core = form_core .. "background[0,0;8.5,9;ui_formspec_bg_tall.png]"
default.ui.register_page("core", form_core)
@ -238,8 +235,6 @@ function default.ui.receive_fields(player, form_name, fields)
if fields.tab_crafting then
minetest.show_formspec(name, "core_crafting", default.ui.get_page("core_crafting"))
elseif minetest.get_modpath("craftingguide") ~= nil and fields.tab_craftingguide then
minetest.show_formspec(name, "core_craftingguide", craftingguide.get_formspec(name))
elseif minetest.get_modpath("armor") ~= nil and fields.tab_armor then
minetest.show_formspec(name, "core_armor", default.ui.get_page("core_armor"))
elseif minetest.get_modpath("achievements") ~= nil and fields.tab_achievements then