minetest-mm/mods/cards/init.lua

702 lines
22 KiB
Lua
Raw Normal View History

2020-11-15 20:25:38 +01:00
math.randomseed(os.time())
local STACK_FORM = "size[2,6]"..
"button_exit[0,0;2,1;draw_turned;draw turned]"..
"button_exit[0,1;2,1;shuffle;shuffle]"..
"button_exit[0,2;2,1;flip;flip]"..
"button_exit[0,3;2,1;remove;delete stack]"..
"button_exit[0,4;2,1;quit;quit]"
local CARD_FORM = "size[3,5]"..
"button_exit[0,0;3,1;flip;flip]"..
"button_exit[0,1;3,1;shuffle;shuffle]"..
"button_exit[0,2;3,1;delete;not show again]"..
"button_exit[0,3;3,1;quit;quit]"
local box_form = "size[10,4]"
local CARDS_PER_BOX = 500
minetest.register_node("cards:turned_card", {
description = "a turned card",
inventory_image = "cards_back_2.png",
wield_image = "cards_back_2.png",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4375 , 0.5}}
},
tiles = {"cards_back_2.png", "cards_back_2.png",
"cards_side.png", "cards_side.png",
"cards_side.png", "cards_side.png"
},
paramtype = "light",
paramtype2 = "facedir",
after_place_node = function(pos, placer, itemstack, pointed_thing)
local card = itemstack:get_metadata()
local deckname = string.sub(card, 12, string.find(card, "_", 12) - 1)
minetest.swap_node(pos, {name = "cards:stack_"..deckname})
local meta = minetest.get_meta(pos)
meta:set_int("count", 0)
meta:set_string(0, card)
meta:set_string("infotext", 1)
meta:set_string("formspec", STACK_FORM)
end,
groups = {oddly_breakable_by_hand = 3, card = 3, not_in_creative_inventory = 1},
})
local num_decks = 0
local function register_deck(deckname, data)
local name = "cards:deck_"..deckname
local cardname = data.cardname
local stackname = "cards:stack_"..cardname
local size = data.number_of_suits * data.number_of_values
box_form = box_form..
"item_image_button["..num_decks..",2;1,1;"..name..";"..name.."#"..size..";]"..
"label["..num_decks..",1;"..deckname.."]"..
"label["..num_decks..",3;"..size.."]"
num_decks = num_decks + 1
minetest.register_craftitem(name, {
description = "set of playing cards ("..deckname..")",
inventory_image = data.inventory_image,
wield_image = data.inventory_image,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local new_stack = true
if minetest.get_item_group(node.name, "card") == 2 then
new_stack = false
elseif not minetest.registered_nodes[node.name].buildable_to then
pos = pointed_thing.above
node = minetest.get_node(pos)
if not minetest.registered_nodes[node.name].buildable_to then
return
end
end
if minetest.is_protected(pos, placer:get_player_name())then
return
end
if new_stack then
node.name = stackname
minetest.set_node(pos, node)
end
itemstack:take_item()
-- set cards
local meta = minetest.get_meta(pos)
local old_count = 0
if not new_stack then
old_count = meta:get_int("count") + 1
end
local count = size
local set = {}
for s = 1, data.number_of_suits do
for v = 1, data.number_of_values do
local r = math.random(1, count)
local i = -1
while r > 0 do
i = i + 1
if not set[i] then
r = r - 1
end
end
set[i] = true
meta:set_string(i + old_count, "cards:card_"..cardname.."_"..data.suits[s].."_"..data.values[v])
count = count - 1
end
end
meta:set_int("count", old_count + size - 1)
meta:set_string("infotext", old_count + size)
meta:set_string("formspec", STACK_FORM)
return itemstack
end,
})
minetest.register_craft({
output = "cards:card_box "..size,
recipe = {{name}},
})
if not minetest.registered_nodes[stackname] then
minetest.register_node(stackname, {
description = "set of playing cards ("..cardname..")",
inventory_image = data.back_texture,
wield_image = data.back_texture,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, -0.25 , 0.5}}
},
tiles = {data.back_texture, data.back_texture,
"cards_side.png", "cards_side.png",
"cards_side.png", "cards_side.png"
},
paramtype = "light",
paramtype2 = "facedir",
on_dig = function(pos, node, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
local top = meta:get_string(count)
player:get_inventory():add_item("main", top)
if count == 0 then
node.name = "air"
minetest.set_node(pos, node)
return
else
meta:set_int("count", count - 1)
meta:set_string("infotext", count)
end
end,
on_receive_fields = function(pos, formname, fields, player)
if fields.flip then
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
for i = 0, count / 2 do
local a = meta:get_string(i)
local b = meta:get_string(count - i)
meta:set_string(i, b)
meta:set_string(count - i, a)
end
meta:set_string("formspec", CARD_FORM)
minetest.swap_node(pos, {name = meta:get_string(count)})
elseif fields.draw_turned then
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
local top = meta:get_string(count)
player:get_inventory():add_item("main", {name="cards:turned_card", count=1, wear=0, metadata= top})
if count == 0 then
minetest.set_node(pos, {name = "air"})
return
else
meta:set_int("count", count - 1)
meta:set_string("infotext", count)
end
elseif fields.remove then
minetest.set_node(pos, {name = "air"})
elseif fields.shuffle then
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
for i = 0, count do
local j = math.random(i, count)
local a = meta:get_string(i)
local b = meta:get_string(j)
meta:set_string(i, b)
meta:set_string(j, a)
end
end
end,
groups = {oddly_breakable_by_hand = 3, card = 2},
})
end
for s = 1, data.number_of_suits do
for v = 1, data.number_of_values do
local name = "cards:card_"..cardname.."_"..data.suits[s].."_"..data.values[v]
if not minetest.registered_nodes[name] then
local texture = data.value_textures[v].."^"..data.suit_textures[s].."^[colorize:"..data.colors[s].."^[noalpha"
if data.not_colorize_suit then
texture = data.value_textures[v].."^[colorize:"..data.colors[s].."^"..data.suit_textures[s].."^[noalpha"
end
minetest.register_node(name, {
description = data.suits[s].." "..data.values[v],
inventory_image = texture,
wield_image = data.back_texture,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4375 , 0.5}}
},
tiles = {texture, data.back_texture,
"cards_side.png", "cards_side.png",
"cards_side.png", "cards_side.png"
},
paramtype = "light",
paramtype2 = "facedir",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local stack_type = minetest.get_node_group(node.name, "card")
if stack_type == 0 then
return minetest.item_place(itemstack, placer, pointed_thing) -- default
end
if minetest.is_protected(pos, placer:get_player_name()) then
return
end
-- add card to stack
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
if count == 0 then
meta:set_string(count, node.name)
meta:set_string("formspec", CARD_FORM)
end
count = count + 1
meta:set_string(count, name)
meta:set_int("count", count)
meta:set_string("infotext", count + 1)
if stack_type == 1 then
node.name = name
minetest.swap_node(pos, node)
end
itemstack:take_item()
return itemstack
end,
on_dig = function(pos, node, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
if count == 0 then
minetest.node_dig(pos, node, player)
return
end
local top = meta:get_string(count)
player:get_inventory():add_item("main", top)
count = count - 1
node.name = meta:get_string(count)
meta:set_int("count", count)
meta:set_string("infotext", count + 1)
minetest.swap_node(pos, node)
end,
on_receive_fields = function(pos, formname, fields, player)
if fields.collect then
local meta = minetest.get_meta(pos)
if meta:get_int("count") == size then
player:get_inventory():add_item("main",
"cards:stack_"..deckname)
minetest.set_node(pos, {name = "air"})
else
minetest.chat_send_player(player:get_player_name(),
"[cards] stack not complete!")
end
elseif fields.flip then
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
for i = 0, count / 2 do
local a = meta:get_string(i)
local b = meta:get_string(count - i)
meta:set_string(i, b)
meta:set_string(count - i, a)
end
meta:set_string("formspec", STACK_FORM)
minetest.swap_node(pos, {name = "cards:stack_"..deckname})
elseif fields.shuffle then
local meta = minetest.get_meta(pos)
local count = meta:get_int("count")
for i = 0, count do
local j = math.random(i, count)
local a = meta:get_string(i)
local b = meta:get_string(j)
meta:set_string(i, b)
meta:set_string(j, a)
end
minetest.swap_node(pos, {name = meta:get_string(count)})
elseif fields.delete then
local meta = minetest.get_meta(pos)
meta:set_string("formspec", nil)
end
end,
groups = {oddly_breakable_by_hand = 3, card = 1},
})
end
end
end
end
register_deck("32", {
cardname = "green",
number_of_suits = 4,
number_of_values = 8,
colors = {"#F00", "#F00", "#000", "#000"},
suits = {"tiles", "hearts", "pikes", "clovers"},
suit_textures = {
"cards_tile.png",
"cards_heart.png",
"cards_pike.png",
"cards_clover.png"
},
values = {"7", "8", "9", "10", "J", "Q", "K", "A"},
value_textures = {
"cards_7.png",
"cards_8.png",
"cards_9.png",
"cards_10.png",
"cards_J.png",
"cards_Q.png",
"cards_K.png",
"cards_A.png"
},
back_texture = "cards_back_3.png",
inventory_image = "cards_deck_32.png",
})
register_deck("52", {
cardname = "blue",
number_of_suits = 4,
number_of_values = 13,
colors = {"#FA0", "#F00", "#0B0", "#000"},
suits = {"tiles", "hearts", "pikes", "clovers"},
suit_textures = {
"cards_tile.png",
"cards_heart.png",
"cards_pike.png",
"cards_clover.png"
},
values = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"},
value_textures = {
"cards_2.png",
"cards_3.png",
"cards_4.png",
"cards_5.png",
"cards_6.png",
"cards_7.png",
"cards_8.png",
"cards_9.png",
"cards_10.png",
"cards_J.png",
"cards_Q.png",
"cards_K.png",
"cards_A.png"
},
back_texture = "cards_back.png",
inventory_image = "cards_deck_52.png",
})
--[[
register_deck("104", {
cardname = "blue",
number_of_suits = 8,
number_of_values = 13,
colors = {"#FA0", "#F00", "#0B0", "#000"},
suits = {"tiles", "hearts", "pikes", "clovers", "tiles", "hearts", "pikes", "clovers"},
suit_textures = {
"cards_tile.png",
"cards_heart.png",
"cards_pike.png",
"cards_clover.png"
},
values = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"},
value_textures = {
"cards_2.png",
"cards_3.png",
"cards_4.png",
"cards_5.png",
"cards_6.png",
"cards_7.png",
"cards_8.png",
"cards_9.png",
"cards_10.png",
"cards_J.png",
"cards_Q.png",
"cards_K.png",
"cards_A.png"
},
back_texture = "cards_back.png",
inventory_image = "cards_deck_104.png",
})]]--
register_deck("Joker", {
cardname = "Joker",
number_of_suits = 3,
number_of_values = 2,
colors = {"#000", "#F00", "#800"},
suits = {"black", "red", "dark"},
suit_textures = {
"cards_joker.png",
"cards_joker.png",
"cards_joker.png"
},
values = { "joker", "joker"},
value_textures = {
"cards_J.png",
},
back_texture = "cards_back.png",
inventory_image = "cards_deck_joker.png",
})
register_deck("Minetest", {
cardname = "Minetest",
number_of_suits = 4,
number_of_values = 13,
not_colorize_suit = true,
colors = {"#FA0", "#F00", "#11B", "#000"},
suits = {"mese", "apples", "swords", "coal"},
suit_textures = {
"cards_mese_crystal.png",
"cards_apple.png",
"cards_tool_diamondsword.png",
"cards_coal_lump.png"
},
values = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"},
value_textures = {
"cards_2.png",
"cards_3.png",
"cards_4.png",
"cards_5.png",
"cards_6.png",
"cards_7.png",
"cards_8.png",
"cards_9.png",
"cards_10.png",
"cards_J.png",
"cards_Q.png",
"cards_K.png",
"cards_A.png"
},
back_texture = "cards_back_mese.png",
inventory_image = "cards_deck_minetest_52.png",
})
------
-- Box
local show_box_formspec = function(itemstack, player, pointed_thing, formpart)
if player:is_player() then
if not formpart then
formpart = ""
end
minetest.show_formspec(player:get_player_name(), "cards:card_box",
box_form..formpart.."button[6,0;4,1;collect;collect from inventory]".."label[0,0;Parts left:"..
math.floor(itemstack:get_count()).."]")
end
end
local show_box_formspec_open = function(itemstack, player, pointed_thing)
return show_box_formspec(itemstack, player, pointed_thing, "button_exit[4,0;2,1;close;close]")
end
local show_box_formspec_closed = function(itemstack, player, pointed_thing)
return show_box_formspec(itemstack, player, pointed_thing, "button_exit[4,0;2,1;open;open]")
end
minetest.register_node("cards:card_box_open", {
description = "Box which spawns card decks",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{0.5, -0.5, -0.5, -0.125, 0 , 0.5},
{-0.125, 0, -0.5, -0.25, 0.625 , 0.5},}
},
tiles = {"default_wood.png^cards_card_box_top.png","default_wood.png",
"default_wood.png", "default_wood.png",
"default_wood.png", "default_wood.png"
},
paramtype = "light",
stack_max = CARDS_PER_BOX,
on_place = show_box_formspec_open,
on_secondary_use = show_box_formspec_open,
on_use = function(itemstack, player, pointed_thing) --leftclick
if pointed_thing.type ~= "node" then
return nil
end
local pos = pointed_thing.under
if minetest.is_protected(pos, player:get_player_name()) then
return nil
end
local node = minetest.get_node(pos)
if minetest.get_node_group(node.name, "card") == 0 and
minetest.get_node_group(node.name, "jeton") == 0 then
return nil
end
local meta = minetest.get_meta(pos)
local count = meta:get_int("infotext")
if count == 0 then
count = 1
end
itemstack:set_count(itemstack:get_count() + count)
minetest.remove_node(pos)
return itemstack
end,
})
minetest.register_node("cards:card_box", {
description = "Box which spawns card decks",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{0.5, -0.5, -0.5, -0.125, 0.125 , 0.5}}
},
tiles = {"default_wood.png","default_wood.png",
"default_wood.png", "default_wood.png",
"default_wood.png", "default_wood.png"
},
paramtype = "light",
stack_max = CARDS_PER_BOX,
on_place = show_box_formspec_closed,
on_secondary_use = show_box_formspec_closed,
on_use = function(itemstack, player, pointed_thing) --leftclick
if pointed_thing.type ~= "node" then
return nil
end
local pos = pointed_thing.under
if minetest.is_protected(pos, player:get_player_name()) then
return nil
end
local node = minetest.get_node(pos)
if minetest.get_node_group(node.name, "card") == 0 and
minetest.get_node_group(node.name, "jeton") == 0 then
return nil
end
minetest.chat_send_player(player:get_player_name(), "Open in menu to collect pieces")
return nil
end,
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "cards:card_box" then
return false
end
local itemstack = player:get_wielded_item()
if fields.open then
itemstack:set_name("cards:card_box_open")
player:set_wielded_item(itemstack)
return true
end
if fields.close then
itemstack:set_name("cards:card_box")
player:set_wielded_item(itemstack)
return true
end
if fields.quit then
return true
end
local inv = player:get_inventory()
if fields.collect then
local collected = 0
local list = inv:get_list("main")
for i, stack in ipairs(list) do
local name = stack:get_name()
if minetest.get_item_group(name, "card") > 0 or
minetest.get_item_group(name, "jeton") > 0 then
collected = collected + stack:get_count()
stack:clear()
list[i]=stack
end
end
inv:set_list("main", list)
itemstack:set_count(itemstack:get_count() + collected)
player:set_wielded_item(itemstack)
show_box_formspec(itemstack, player)
return true
end
for key,value in pairs(fields) do
local d = string.find(key,"#")
local itemname = string.sub(key,1,d-1)
local cost = tonumber(string.sub(key, d+1))
local count = itemstack:get_count()
if cost < count then
inv:add_item("main", itemname.." "..value)
itemstack:set_count(count-cost)
end
end
player:set_wielded_item(itemstack)
show_box_formspec(itemstack, player)
return true
end)
---------
-- Jetons
local function set_count(pos, placer, itemstack, pointed_thing)
minetest.chat_send_all("hello")
local stack_count = itemstack:get_count()
local meta = minetest.get_meta(pos)
local count = meta:get_int("infotext")
meta:set_int("infotext", count + stack_count)
itemstack:clear()
return itemstack
end
local function register_jeton(name, color)
local texture = "cards_jeton.png^[colorize:"..color.."^[noalpha"
local node_name = "cards:jeton_"..name
box_form = box_form..
"item_image_button["..num_decks..",2;1,1;"..node_name..";"..node_name.."#1;1]"..
"label["..num_decks..",1;"..name.."]"..
"button["..(num_decks)..",3;0.5,1;".. node_name.."#10;10]"..
"button["..(num_decks + 0.5)..",3;0.5,1;".. node_name.."#99;99]"
num_decks = num_decks + 1
minetest.register_node(node_name, {
description = "jeton "..name,
inventory_image = texture,
wield_image = texture,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4375 , 0.5}}
},
tiles = {texture},
paramtype = "light",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
local node = minetest.get_node(pos)
if node.name ~= node_name then
pos = pointed_thing.above
return minetest.item_place(itemstack, placer, pointed_thing)
end
if minetest.is_protected(pos, placer:get_player_name()) then
return
end
itemstack = set_count(pos, placer, itemstack, pointed_thing) -- add jetons to stack
return itemstack
end,
after_place_node = set_count,
on_dig = function(pos, node, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local count = meta:get_int("infotext")
minetest.node_dig(pos, node, player)
node = minetest.get_node(pos)
if node.name == node_name then return end
player:get_inventory():add_item("main", {
name = node_name,
count = count - 1, -- 1 item is added by minetest.node_dig(...)
wear = 0,
metadata = ""
})
end,
groups = {oddly_breakable_by_hand = 3, jeton = 1},
})
end
register_jeton("blue", "#00F:224")
register_jeton("red", "#F00:224")
register_jeton("black", "#000:224")
register_jeton("green", "#0A0:224")
register_jeton("yellow", "#FF0:224")
---------
-- Crafts
minetest.register_craft({
output = "cards:card_box "..CARDS_PER_BOX,
recipe = {{"default:chest", "dye:black", "dye:green"},
{"default:clay_lump","dye:red" , "dye:blue"},
{"default:paper", "default:paper", "default:paper"},}
})
minetest.register_craft({
output = "cards:card_box",
recipe = {{"group:jeton"}},
})
minetest.register_craft({
output = "cards:card_box",
recipe = {{"group:card"}},
})