Compare commits

...

9 Commits

Author SHA1 Message Date
E 7f938b985e items/mcl_crafting_table: upgrade to formspec v3
The crafting table formspec can now support overlaying items over top of
the craft prediction slot, including banners.
2021-05-03 04:51:26 -04:00
E 842cc6d1e4 hud/mcl_formspec: add formspec V2 conversion utilities
Formspecs come in different versions. While maintaining the same basic
syntax, version 1->2 changed (among other things) how coordinates work
by eliminating some (previously) built-in spacing and padding. This
commit adds a number of utility functions that can be used to upgrade
a formspec in-place.

- `size2r` returns a string with the provided w,h coordinates converted
  for use with `size[]` in formspec versions 2+
- `i2r` converts a single coordinate from the V1 coordinates system to
  the V2+ "Real" coordinates
- `xy2r` returns a string suitable for use with other elements that
  accept a coordinate pair. It is a simple wrapper for `i2r`.

The formulas used reflect those specified by the Minetest Lua API docs.
2021-05-02 00:54:52 -04:00
E 32172676f3 items/mcl_banners: make previews items compatible with side preview
The newly-added preview items (#40) didn't play nice with the side
preview image, mostly because the "layers" metadata wasn't generated,
and they didn't record the base color of the actual banner being crafted.

This commit re-adds that (and other) metadata.
2021-05-02 00:42:12 -04:00
E 164b65a2ca items/mcl_banners: reuse `escape` across functions 2021-05-02 00:42:12 -04:00
E 412c1ac5d6 items/mcl_banners: fix preview masking
The `layer` string was inherited from the old patch, which I frankly
don't understand. I restructured it to `follow make_banner_texture` more
closely, with the addition of the mcl_banners_front mask, which
prevents the rear portions of the patterns from showing up.

The numbers in the final `[combine` and `[resize` steps are arbitrary,
and were derived by trial-and-error.
2021-05-02 00:42:12 -04:00
E 5d0c9c77cd items/mcl_banners: make `escape` local 2021-05-02 00:42:10 -04:00
E ccc1ce566f items/mcl_crafting_table: remove reference to "mcl_colors" mod
This patch was technically backported from a later version of
MineClone2. Between the point where Mineclonia forked, and the point
where this patch was developed, MineClone2 introduced a "mcl_colors"
mod which, presumably just lists some colors. This commit removes
references to that mod, as it doesn't exist in our history.
2021-05-02 00:41:53 -04:00
E 519c3814aa mcl_banners, mcl_crafting_table: show banner crafting preview
A preview of a crafted banner is now shown next to the craft result box
to help players visualize what they're crafting. Due to the formspec
version, the preview can't be shown over top of the actual result slot.
A utility function (mcl_banners.get_overlay) is added to generate
formspec-able texture strings for arbitrary banners.
2021-05-02 00:41:37 -04:00
E 5255c0e6d0 Cherry pick 3ef10cfb30 2021-05-01 21:46:09 -04:00
8 changed files with 172 additions and 69 deletions

View File

@ -9,3 +9,31 @@ function mcl_formspec.get_itemslot_bg(x, y, w, h)
end
return out
end
-- From the Minetest Lua API doc, "Migrating to Real Coordinates"
local padding, spacing = 3/8, 5/4
function mcl_formspec.size2r(w, h)
return (((w-1)*spacing) + (padding*2) + 1)..","..(((h-1)*spacing) + (padding*2) + 1)
end
local function i2r(i)
return (i*spacing)+padding
end
mcl_formspec.i2r=i2r
function mcl_formspec.xy2r(x, y)
return i2r(x)..","..i2r(y)
end
function mcl_formspec.get_itemslot_bgv2(x, y, w, h)
local out = ""
x=i2r(x)-padding
y=i2r(y)-padding
for i = 0, w - 1, 1 do
for j = 0, h - 1, 1 do
out = out .."image["..x+i2r(i)..","..y+i2r(j)..";1,1;mcl_formspec_itemslot.png]"
end
end
return out
end

View File

@ -144,6 +144,47 @@ local on_destruct_hanging_banner = function(pos)
return on_destruct_banner(pos, true)
end
local function escape(text)
return text:gsub("%^", "\\%^"):gsub(":", "\\:") -- :gsub("%(", "\\%("):gsub("%)", "\\%)")
end
local make_banner_overlay = function(base_color, layers)
local colorize = mcl_banners.colors[base_color][4]
-- Base texture with base color
local base = "(mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..":"..base_color_ratio..")^[resize:32x32)"
-- Optional pattern layers
if layers then
local lovl = ""
for l=1, #layers do
local layerinfo = layers[l]
local pattern = "mcl_banners_" .. layerinfo.pattern .. ".png"
local color = mcl_banners.colors[layerinfo.color][4]
-- Generate layer texture
local layer = "((("..pattern.."^[mask:mcl_banners_front.png)^[colorize:"..color..":"..layer_ratio..")^[mask:"..pattern..")"
lovl = (lovl ~= "" and (lovl .. "^") or "") .. layer
end
return "[combine:32x32:0,0=" .. escape(base) .. ":7,3=" .. escape("("..lovl.."^[resize:50x38)")
end
return base
end
function mcl_banners.get_overlay(istk)
local imeta = istk:get_meta()
local layers_raw = imeta:get_string("layers")
if not layers_raw or layers_raw == "" then
return
end
local basec = imeta:get("fake_base") or istk:get_definition()._base_color
if not basec then
basec="unicolor_white"
end
return make_banner_overlay(basec, minetest.deserialize(layers_raw))
end
local make_banner_texture = function(base_color, layers)
local colorize
if mcl_banners.colors[base_color] then
@ -389,10 +430,6 @@ for colorid, colortab in pairs(mcl_banners.colors) do
local layer = "(([combine:20x40:-2,-2="..pattern.."^[resize:16x24^[colorize:"..color..":"..layer_ratio.."))"
function escape(text)
return text:gsub("%^", "\\%^"):gsub(":", "\\:") -- :gsub("%(", "\\%("):gsub("%)", "\\%)")
end
finished_banner = "[combine:32x32:0,0=" .. escape(base) .. ":8,4=" .. escape(layer)
end
@ -420,6 +457,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do
groups = groups,
stack_max = 16,
_base_color=colorid,
on_place = function(itemstack, placer, pointed_thing)
local above = pointed_thing.above
local under = pointed_thing.under

View File

@ -485,11 +485,12 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i
local imeta = itemstack:get_meta()
imeta:set_string("layers", minetest.serialize(layers))
local idef=itemstack:get_definition()
local mname = ometa:get_string("name")
-- Only change description if banner does not have a name
if mname == "" then
local odesc = itemstack:get_definition().description
local odesc = idef.description
local description = mcl_banners.make_advanced_banner_description(odesc, layers)
imeta:set_string("description", description)
else
@ -500,10 +501,13 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i
if craft_predict then
local itemid_prefix = "mcl_banners:banner_preview"
local coloritemid = dye_to_itemid_mapping[dye]
return ItemStack(itemid_prefix .. "_" .. matching_pattern .. "_" .. coloritemid)
else
return itemstack
local is=ItemStack(itemid_prefix .. "_" .. matching_pattern .. "_" .. coloritemid)
local im=is:get_meta()
im:from_table(imeta:to_table())
im:set_string("fake_base", idef._base_color)
return is
end
return itemstack
end
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,3 +0,0 @@
mcl_init
mcl_formspec
mcl_sounds

View File

@ -1 +0,0 @@
Adds a crafting table.

View File

@ -1,57 +1,91 @@
local S = minetest.get_translator("mcl_crafting_table")
minetest.register_node("mcl_crafting_table:crafting_table", {
description = S("Crafting Table"),
_tt_help = S("3×3 crafting grid"),
_doc_items_longdesc = S("A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts."),
_doc_items_usagehelp = S("Rightclick the crafting table to access the 3×3 crafting grid."),
_doc_items_hidden = false,
is_ground_content = false,
tiles = {"crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png",
"crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png"},
paramtype2 = "facedir",
groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1},
on_rightclick = function(pos, node, player, itemstack)
player:get_inventory():set_width("craft", 3)
player:get_inventory():set_size("craft", 9)
local form = "size[9,8.75]"..
"image[4.7,1.5;1.5,1;gui_crafting_arrow.png]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[1.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Crafting"))).."]"..
"list[current_player;craft;1.75,0.5;3,3;]"..
mcl_formspec.get_itemslot_bg(1.75,0.5,3,3)..
"list[current_player;craftpreview;6.1,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(6.1,1.5,1,1)..
"image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]"..
"tooltip[__mcl_craftguide;"..minetest.formspec_escape(S("Recipe book")).."]"..
"listring[current_player;main]"..
"listring[current_player;craft]"
minetest.show_formspec(player:get_player_name(), "main", form)
end,
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 2.5,
_mcl_hardness = 2.5,
})
minetest.register_craft({
output = "mcl_crafting_table:crafting_table",
recipe = {
{"group:wood", "group:wood"},
{"group:wood", "group:wood"}
}
})
minetest.register_craft({
type = "fuel",
recipe = "mcl_crafting_table:crafting_table",
burntime = 15,
})
minetest.register_alias("crafting:workbench", "mcl_crafting_table:crafting_table")
minetest.register_alias("mcl_inventory:workbench", "mcl_crafting_table:crafting_table")
local S = minetest.get_translator("mcl_crafting_table")
local formspec_escape = minetest.formspec_escape
local show_formspec = minetest.show_formspec
local C = minetest.colorize
local text_color = "#313131"
local itemslot_bg, size2r, xy2r = mcl_formspec.get_itemslot_bgv2, mcl_formspec.size2r, mcl_formspec.xy2r
mcl_crafting_table = {
last_table={}
}
function mcl_crafting_table.show_crafting_form(player, overlay)
player:get_inventory():set_width("craft", 3)
player:get_inventory():set_size("craft", 9)
show_formspec(player:get_player_name(), "mcl_crafting_table:main",
"formspec_version[3]"..
"size["..size2r(9,8.75).."]"..
"image["..xy2r(4.7,1.5)..";1.5,1;gui_crafting_arrow.png]"..
"label["..xy2r(0,4)..";"..formspec_escape(C(text_color, S("Inventory"))).."]".. --"#313131"
itemslot_bg(0,4.5,9,3)..
"list[current_player;main;"..xy2r(0,4.5)..";9,3;9]"..
itemslot_bg(0,7.74,9,1)..
"list[current_player;main;"..xy2r(0,7.74)..";9,1;]"..
"label["..xy2r(1.75,0)..";"..formspec_escape(C(text_color, S("Crafting"))).."]"..
itemslot_bg(1.75,0.5,3,3)..
"list[current_player;craft;"..xy2r(1.75,0.5)..";3,3;]"..
itemslot_bg(6.1,1.5,1,1)..
"list[current_player;craftpreview;"..xy2r(6.1,1.5)..";1,1;]"..
"image_button["..xy2r(0.75,1.5)..";1,1;craftguide_book.png;__mcl_craftguide;]"..
"tooltip[__mcl_craftguide;"..formspec_escape(S("Recipe book")).."]"..
"listring[current_player;main]"..
"listring[current_player;craft]"..
(overlay and "image["..xy2r(6.1,1.5)..";1,1;"..formspec_escape(overlay).."]" or "")
)
end
if minetest.get_modpath("mcl_banners") then
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
if mcl_crafting_table.last_table[player:get_player_name()] then
local ovl=mcl_banners.get_overlay(itemstack)
mcl_crafting_table.show_crafting_form(player, ovl)
end
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "mcl_crafting_table:main" then
return false
end
if fields["quit"] then
mcl_crafting_table.last_table[player:get_player_name()]=nil
minetest.close_formspec(player:get_player_name(), formname)
end
end)
end
local show_crafting_form = mcl_crafting_table.show_crafting_form --cache function for better performances
minetest.register_node("mcl_crafting_table:crafting_table", {
description = S("Crafting Table"),
_tt_help = S("3×3 crafting grid"),
_doc_items_longdesc = S("A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts."),
_doc_items_usagehelp = S("Rightclick the crafting table to access the 3×3 crafting grid."),
_doc_items_hidden = false,
is_ground_content = false,
tiles = {"crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png",
"crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png"},
paramtype2 = "facedir",
groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1},
on_rightclick = function(pos, node, player, itemstack)
mcl_crafting_table.last_table[player:get_player_name()]=node
show_crafting_form(player)
end,
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 2.5,
_mcl_hardness = 2.5,
})
minetest.register_craft({
output = "mcl_crafting_table:crafting_table",
recipe = {
{"group:wood", "group:wood"},
{"group:wood", "group:wood"}
}
})
minetest.register_craft({
type = "fuel",
recipe = "mcl_crafting_table:crafting_table",
burntime = 15,
})
minetest.register_alias("crafting:workbench", "mcl_crafting_table:crafting_table")
minetest.register_alias("mcl_inventory:workbench", "mcl_crafting_table:crafting_table")

View File

@ -1 +1,4 @@
name = mcl_crafting_table
description = Adds a crafting table.
depends = mcl_init, mcl_formspec, mcl_sounds
optional_depends = mcl_banners