1207 lines
38 KiB
Lua
1207 lines
38 KiB
Lua
local debug_enabled=minetest.settings:get('deck_debugmessages')
|
|
-- output to minetest.log if debug messages are enabled in settings
|
|
local function log(txt)
|
|
if debug_enabled then
|
|
minetest.log(txt)
|
|
end
|
|
end
|
|
|
|
-- describe contents of an unknown something. Used for learning minetest lua api.
|
|
local function describe(prefix,stuff)
|
|
local t=type(stuff)
|
|
if(t == "table") then
|
|
for key,value in pairs(stuff) do
|
|
log(prefix.." "..key .. "=".. type(value))
|
|
describe(prefix.." ",value)
|
|
end
|
|
elseif(t=="nil" or t=="userdata") then
|
|
log(prefix.." "..t)
|
|
elseif(t=="number" or t=="string" or t=="boolean") then
|
|
log(prefix.." "..t..": "..stuff)
|
|
else
|
|
log(t)
|
|
end
|
|
end
|
|
|
|
-- Groups given to individual cards. Make cards easy to handle.
|
|
local cardgroups = { crumbly=1, falling_node=1, dig_immediate=3, card=1 }
|
|
-- Groups given to all types of piles of cards.
|
|
local pilegroups = { crumbly=1, dig_immediate=3 }
|
|
|
|
-- Names of card suits
|
|
local suit = { "club","diamond","heart","spade" }
|
|
|
|
-- Used to add colorize to card ranks when creating textures. Diamonds
|
|
-- and hearts get first colorize from suitcolorize array and clubs
|
|
-- and spages get the second.
|
|
local suitcolorizeindex={ 2,1,1,2}
|
|
|
|
-- Colorize rules for red and black card textures.
|
|
local suitcolorize = { "\\^[colorize\\:#ff0000\\:alpha","\\^[colorize\\:#000000\\:alpha" }
|
|
-- Dye colors that are not accepted by colorize must be set explicitly
|
|
local tablecolorize = { dark_grey="#222222",dark_green="#002200" }
|
|
|
|
-- Names of card ranks. These are used in descriptions of cards in inventory.
|
|
local rank = { "Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten",
|
|
"Jack","Queen","King"}
|
|
|
|
-- One character symbol for card ranks. These are used in
|
|
-- card_shortname and png file names in textures.
|
|
local rank_short = { "a","2","3","4","5","6","7","8","9","t","j","q","k" }
|
|
|
|
-- card_shortname is two character name of card: rank and suit, for example "ah"
|
|
local card_shortname = {}
|
|
|
|
-- Array of strings passed to register_node as tiles
|
|
local textures = {}
|
|
|
|
-- Array of strings. Long names of cards, such as "Ace of hearts"
|
|
local descriptions = {}
|
|
|
|
-- Array of minetest node names, such as "deck:card_ah"
|
|
local cardnames = {}
|
|
|
|
-- Prefix of all individual card node names.
|
|
local cardprefix="deck:card_"
|
|
local cardprefixlen=string.len(cardprefix)
|
|
-- Prefix of cardtable types
|
|
local tableprefix="deck:cardtable_"
|
|
local tableprefixlen=string.len(tableprefix)
|
|
|
|
-- Table of card descriptions. Key is minetest node name, value is
|
|
-- verbose card name, for example deck:card_ah -> Ace of hearts
|
|
local carddescriptions = {}
|
|
|
|
-- Array of arrays. Index of outer array is card rank (ace=1, ...,
|
|
-- king=13). Inner arrays contain strings of format "x,y" where x,y
|
|
-- are coordinates where to place the suite symbol on the card
|
|
-- texture.
|
|
local texturepositions = {
|
|
-- These are a bit crowded looking positions for 128x128 texture
|
|
-- {"50,50"}, -- a
|
|
-- {"50,15","50,65"}, -- 2
|
|
-- {"50,2","50,42","50,84"}, -- 3
|
|
-- {"30,12","30,62","70,12","70,62"}, -- 4
|
|
-- {"30,2","80,2","60,40","35,75","85,75"}, -- 5
|
|
-- {"30,2","30,42","30,84","70,2","70,42","70,84"}, -- 6
|
|
-- {"40,2","40,42","40,84","80,2","80,42","80,84","5,62"}, -- 7
|
|
-- {"40,2","40,42","40,84","80,2","80,42","80,84","2,84","2,42"}, -- 8
|
|
-- {"48,2","48,42","48,84","88,2","88,42","88,84","10,84","10,42","10,2"}, -- 9
|
|
-- {"48,2","48,42","48,84","88,2","88,42","88,84","10,84","10,42","20,12","60,52"}, -- 10
|
|
-- {"33,1"}, -- J
|
|
-- {"33,1"}, -- Q
|
|
-- {"33,1"}, -- K
|
|
|
|
{"32,28"}, -- a
|
|
{"32,28"}, -- 2
|
|
{"32,28"}, -- 3
|
|
{"32,28"}, -- 4
|
|
{"32,28"}, -- 5
|
|
{"32,28"}, -- 6
|
|
{"32,28"}, -- 7
|
|
{"32,28"}, -- 8
|
|
{"32,28"}, -- 9
|
|
{"32,28"}, -- 10
|
|
{"32,28"}, -- J
|
|
{"32,28"}, -- Q
|
|
{"32,28"}, -- K
|
|
}
|
|
|
|
-- Fill the following arrays:
|
|
-- card_shortname
|
|
-- descriptions
|
|
-- textures
|
|
local function generate_descriptions()
|
|
local i=1
|
|
local s, r
|
|
for s=1,4,1 do
|
|
for r=1,13,1 do
|
|
descriptions[i]=rank[r].." of "..suit[s].."s"
|
|
card_shortname[i]=rank_short[r]..string.sub(suit[s],1,1)
|
|
textures[i]="deck_white.png^[resize:96x96^[combine:96x96"
|
|
for p=1,table.getn(texturepositions[r]),1 do
|
|
textures[i]=textures[i]..":"..texturepositions[r][p].."=deck_"..suit[s]..".png"
|
|
end
|
|
textures[i]=textures[i]..
|
|
":3,28=deck_"..rank_short[r]..".png"..suitcolorize[suitcolorizeindex[s]]
|
|
log(i.." "..textures[i])
|
|
i=i+1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Add card cardname to main list of pile inventory inv.
|
|
-- Card is placed on the top of the pile.
|
|
-- return true if card was added, false if list was full
|
|
local function pile_add_card(inv,cardname)
|
|
local s=inv:get_size("main")
|
|
local place=s
|
|
local i
|
|
for i=1,s,1 do
|
|
local stack=inv:get_stack("main",i)
|
|
if stack:get_count() > 0 then
|
|
place=i-1
|
|
break
|
|
end
|
|
end
|
|
if place > 0 then
|
|
inv:set_stack("main",place,cardname)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Add card from pos to main list of pile inventory inv
|
|
-- return true if card was added, false if list was full
|
|
local function pile_add_card_from_pos(inv,pos)
|
|
local cardname=ItemStack(minetest.get_node(pos).name)
|
|
return pile_add_card(inv,cardname)
|
|
end
|
|
|
|
-- Convert the card at pos into stockpile or chestpile
|
|
local function flip_card(pos,formname,fields,sender)
|
|
local n=minetest.get_node(pos)
|
|
local pile
|
|
if fields.to_stockpile then
|
|
pile="deck:stockpile"
|
|
elseif fields.to_chestpile then
|
|
pile="deck:chestpile"
|
|
else
|
|
log("not flipped")
|
|
return
|
|
end
|
|
log(n.name.." to "..pile)
|
|
minetest.remove_node(pos)
|
|
minetest.place_node(pos,{name=pile})
|
|
local meta=minetest.get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
pile_add_card(inv,n.name)
|
|
minetest.close_formspec(sender:get_player_name(),"")
|
|
end
|
|
|
|
-- Add formspec to card at pos to enable flipping it. Used as
|
|
-- on_construct function for cards.
|
|
local function on_construct_card(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
meta:set_string("formspec", "size[3,3]"..
|
|
"label[0,0;Flip card to make a]"..
|
|
"button[0,1;2,1;to_stockpile;Stockpile]"..
|
|
"button[0,2;2,1;to_chestpile;Chestpile]")
|
|
end
|
|
|
|
generate_descriptions()
|
|
for i = 1,table.getn(textures),1 do
|
|
local name=cardprefix..card_shortname[i]
|
|
table.insert(cardnames,name)
|
|
carddescriptions[name]=descriptions[i]
|
|
minetest.register_node(name, {
|
|
description = descriptions[i],
|
|
groups = cardgroups,
|
|
palette = "deck_palette.png",
|
|
paramtype2 = "color",
|
|
drawtype = "normal",
|
|
param2 = 4,
|
|
on_construct = on_construct_card,
|
|
on_receive_fields = flip_card,
|
|
tiles = { textures[i] }
|
|
})
|
|
end
|
|
|
|
-- Set inventory size of card pile at pos. Used by on_construct
|
|
-- funtion of card piles.
|
|
local function pile_inv_setup(pos, placer, itemstack, pointed_thing)
|
|
local meta=minetest.get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
local invsize=13*4
|
|
if inv:set_size("main",invsize) then
|
|
inv:set_width("main",13)
|
|
log("deck_setup: size set to "..invsize)
|
|
else
|
|
log("deck_setup: failed to set size")
|
|
end
|
|
end
|
|
|
|
-- Take and return a card from pile inventory inv. Or nil if pile is
|
|
-- empty.
|
|
local function pile_pop(inv)
|
|
local s=inv:get_size("main")
|
|
local i
|
|
for i=1,s,1 do
|
|
local stack=inv:get_stack("main",i)
|
|
if stack:get_count() > 0 then
|
|
local item=stack:take_item(1)
|
|
inv:set_stack("main",i,stack)
|
|
return item
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Return, but do not remove topmost card of pile inventory inv.
|
|
local function pile_peek_first(inv)
|
|
local s=inv:get_size("main")
|
|
for i=1,s,1 do
|
|
local stack=inv:get_stack("main",i)
|
|
if stack:get_count() > 0 then
|
|
return stack:get_name()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Add card to pile inventory inv.
|
|
-- Return true if if card was added or false if pile was full
|
|
local function add_to_inv(inv, cardname)
|
|
local s=inv:get_size("main")
|
|
for i=1,s,1 do
|
|
local stack=inv:get_stack("main",i)
|
|
if stack:get_count() == 0 then
|
|
log(cardname)
|
|
inv:set_stack("main",i,ItemStack(cardname))
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Make card pile dark so players can easily see that it is empty.
|
|
-- This should only be used with already empty piles.
|
|
local function darken_pile(pos)
|
|
local node=minetest.get_node(pos)
|
|
node.param2=1
|
|
minetest.set_node(pos,node)
|
|
end
|
|
|
|
-- Change card pile to normal brightness so players can easily see that it is not empty.
|
|
-- This should be used just before the first card is added to pile.
|
|
local function lighten_pile(pos)
|
|
local node=minetest.get_node(pos)
|
|
node.param2=0
|
|
minetest.set_node(pos,node)
|
|
end
|
|
|
|
-- Move all cards in the pile at pos to end of inventory list. Does
|
|
-- not change the order of the cards.
|
|
local function defragment_pile(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local s=pile_inv:get_size("main")
|
|
local search_start=s-1
|
|
for i=s,1,-1 do
|
|
log("defrag:"..i)
|
|
local stack=pile_inv:get_stack("main",i)
|
|
if stack:is_empty() then
|
|
for j=search_start,1,-1 do
|
|
local st=pile_inv:get_stack("main",j)
|
|
if st:is_empty() then
|
|
log("defrag: empty stack i="..i.." j="..j)
|
|
else
|
|
pile_inv:set_stack("main",i,st)
|
|
pile_inv:set_stack("main",j,ItemStack())
|
|
log("defrag:move"..j.."->"..i)
|
|
search_start=j-1
|
|
if search_start==0 then
|
|
log("defrag:exit at i="..i)
|
|
return
|
|
end
|
|
break
|
|
end
|
|
if j==1 then
|
|
log("defrag:exit at j=1")
|
|
return
|
|
end
|
|
end
|
|
elseif search_start > i-1 then
|
|
search_start=i-1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Takes card from first slot of player's inventory's craft list and places it on top of the pile at pos
|
|
local function put_craft_to_pile(pos,formname,fields,sender)
|
|
local player_inv=minetest.get_inventory({type="player", name=sender:get_player_name()})
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local stack=player_inv:get_stack("craft",1)
|
|
if stack:get_count() > 0 then
|
|
local cardname=stack:get_name()
|
|
if string.sub(cardname,1,cardprefixlen) == cardprefix then
|
|
local item=stack:take_item(1)
|
|
if item ~= nil then
|
|
if pile_peek_first(pile_inv) == nil then
|
|
lighten_pile(pos)
|
|
end
|
|
add_to_inv(pile_inv, cardname)
|
|
player_inv:set_stack("craft",1,stack)
|
|
defragment_pile(pos)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Takes all cards from player main inventory list and places them on the pile at pos
|
|
local function put_all_to_pile(pos,formname,fields,sender)
|
|
local player_inv=minetest.get_inventory({type="player", name=sender:get_player_name()})
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local s=player_inv:get_size("main")
|
|
local i
|
|
if pile_peek_first(pile_inv) == nil then
|
|
lighten_pile(pos)
|
|
end
|
|
for i=1,s,1 do
|
|
local stack=player_inv:get_stack("main",i)
|
|
if stack:get_count() > 0 then
|
|
local cardname=stack:get_name()
|
|
if string.sub(cardname,1,cardprefixlen) == cardprefix then
|
|
local item=stack:take_item(1)
|
|
if item ~= nil then
|
|
add_to_inv(pile_inv, cardname)
|
|
player_inv:set_stack("main",i,stack)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if pile_peek_first(pile_inv) == nil then
|
|
darken_pile(pos)
|
|
else
|
|
defragment_pile(pos)
|
|
end
|
|
end
|
|
|
|
-- Takes one card from pile at pos and adds it to main list of player inventory.
|
|
local function draw_one_card(pos,formname,fields,sender)
|
|
local player_inv=minetest.get_inventory({type="player", name=sender:get_player_name()})
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
if pile_inv == nil then log("pile inv=nil") return end
|
|
local stack=pile_pop(pile_inv)
|
|
if stack == nil then
|
|
log("empty pile")
|
|
darken_pile(pos)
|
|
return false
|
|
else
|
|
player_inv:add_item("main",stack)
|
|
if pile_peek_first(pile_inv) == nil then
|
|
darken_pile(pos)
|
|
else
|
|
defragment_pile(pos)
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function suit_to_number(s)
|
|
local c=string.sub(s,1,1)
|
|
if c == "c" then
|
|
return 1
|
|
elseif c == "d" then
|
|
return 2
|
|
elseif c == "h" then
|
|
return 3
|
|
elseif c == "s" then
|
|
return 4
|
|
end
|
|
end
|
|
|
|
local function rank_to_number(r)
|
|
if r == "a" then
|
|
return 1
|
|
elseif r == "t" then
|
|
return 10
|
|
elseif r == "j" then
|
|
return 11
|
|
elseif r == "q" then
|
|
return 12
|
|
elseif r == "k" then
|
|
return 13
|
|
end
|
|
return tonumber(r)
|
|
end
|
|
|
|
local function card_order(a,b)
|
|
log("comparing "..a.." with "..b)
|
|
-- deck:card_ZZ
|
|
local as=string.sub(a,12,12)
|
|
local bs=string.sub(b,12,12)
|
|
log("as="..as)
|
|
log("bs="..bs)
|
|
if as ~= bs then
|
|
return suit_to_number(as) < suit_to_number(bs)
|
|
end
|
|
local ar=string.sub(a,11,11)
|
|
local br=string.sub(b,11,11)
|
|
return rank_to_number(ar) < rank_to_number(br)
|
|
end
|
|
|
|
-- Sorts card pile at pos
|
|
local function sort_pile(pos,formname,fields,sender)
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local s=pile_inv:get_size("main")
|
|
local places={}
|
|
local stacks={}
|
|
local names={}
|
|
for i=1,s,1 do
|
|
local stack=pile_inv:get_stack("main",i)
|
|
if stack:is_empty() then
|
|
log("empty slot "..i)
|
|
else
|
|
local n=stack:get_name()
|
|
table.insert(places, i)
|
|
stacks[n]=stack
|
|
table.insert(names, n)
|
|
end
|
|
end
|
|
table.sort(names,card_order)
|
|
table.sort(places)
|
|
for i,p in ipairs(places) do
|
|
pile_inv:set_stack("main",p,stacks[names[i]])
|
|
end
|
|
end
|
|
|
|
-- Shuffles card pile at pos.
|
|
local function shuffle_pile(pos,formname,fields,sender)
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local s=pile_inv:get_size("main")
|
|
local newpos={}
|
|
local i
|
|
for i=1,s,1 do
|
|
local try=math.random(s)
|
|
while newpos[try] ~= nil do
|
|
try=try+1
|
|
if try > s then
|
|
try=1
|
|
end
|
|
end
|
|
newpos[try]=pile_inv:get_stack("main",i)
|
|
end
|
|
for i=1,s,1 do
|
|
pile_inv:set_stack("main",i,newpos[i])
|
|
end
|
|
defragment_pile(pos)
|
|
end
|
|
|
|
-- Convert pile of cards at pos to pile type nodename.
|
|
local function convert_pile(pos,nodename)
|
|
local oldmeta=minetest.get_meta(pos)
|
|
local oldinv=oldmeta:get_inventory()
|
|
local s=oldinv:get_size("main")
|
|
local cards={}
|
|
for i=1,s,1 do
|
|
local stack=oldinv:get_stack("main",i)
|
|
cards[i]=stack:get_name()
|
|
end
|
|
minetest.remove_node(pos)
|
|
minetest.place_node(pos,{name=nodename})
|
|
local newmeta=minetest.get_meta(pos)
|
|
local newinv=newmeta:get_inventory()
|
|
local s=oldinv:get_size("main")
|
|
for i=1,s,1 do
|
|
local stack=ItemStack(cards[i])
|
|
newinv:set_stack("main",i,stack)
|
|
end
|
|
defragment_pile(pos)
|
|
end
|
|
|
|
-- return position of the first block of cardtable that spans pos
|
|
local function cardtable_get_main_pos(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
local tmx=meta:get_string("cardtable_main_x")
|
|
local tmz=meta:get_string("cardtable_main_z")
|
|
return {x=tmx,y=pos.y,z=tmz}
|
|
end
|
|
|
|
-- return array of positions that list all blocks in a cardtable
|
|
local function cardtable_get_positions(pos,color)
|
|
local mainpos=cardtable_get_main_pos(pos)
|
|
local mainmeta=minetest.get_meta(mainpos)
|
|
local allpos=minetest.deserialize(mainmeta:get_string("cardtable_positions"))
|
|
if color==nil then
|
|
return allpos
|
|
end
|
|
local colored={}
|
|
local name=tableprefix..color
|
|
for i,p in ipairs(allpos) do
|
|
local n=minetest.get_node(p)
|
|
if n.name == name then
|
|
table.insert(colored,p)
|
|
end
|
|
end
|
|
log(table.getn(colored).." "..color.." cardtable pieces")
|
|
return colored
|
|
end
|
|
|
|
-- Take all cards from cardtable at pos and place them in list of sender
|
|
local function cardtableto(list,pos,sender)
|
|
local tablepositions=cardtable_get_positions(pos)
|
|
for i,p in ipairs(tablepositions) do
|
|
log("checking "..minetest.pos_to_string(p))
|
|
local abovepos={x=p.x, y=p.y+1, z=p.z}
|
|
local abovenode=minetest.get_node(abovepos)
|
|
local n=abovenode.name
|
|
if string.sub(n,1,cardprefixlen) == cardprefix then
|
|
local player_inv=minetest.get_inventory({type="player", name=sender:get_player_name()})
|
|
player_inv:add_item(list,ItemStack(n))
|
|
minetest.remove_node(abovepos)
|
|
else
|
|
log("not card, but "..n)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function cardtable_try_add_card(pos,cardname)
|
|
local node=minetest.get_node(pos)
|
|
if node.name == "air" then
|
|
log("minetest.place_node("..minetest.pos_to_string(pos)..","..cardname..")")
|
|
minetest.place_node(pos,{name=cardname})
|
|
return true
|
|
end
|
|
log("not air but "..node.name.." at "..minetest.pos_to_string(pos)..". Didn't place "..cardname)
|
|
return false
|
|
end
|
|
|
|
-- Adds card to cardtable. Return true if card was added or false if cardtable was full.
|
|
local function cardtable_add_card(pos,cardname,color)
|
|
local above={x=pos.x,y=pos.y+1,z=pos.z}
|
|
local positions=cardtable_get_positions(pos,color)
|
|
if debug_enabled then
|
|
if color == nil then
|
|
log("adding to cardtable, no color set")
|
|
else
|
|
log("adding to color "..color)
|
|
end
|
|
end
|
|
for i,p in ipairs(positions) do
|
|
above={x=p.x,y=p.y+1,z=p.z}
|
|
if cardtable_try_add_card(above,cardname) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- return color of cardtable block at pos
|
|
local function cardtable_get_color(pos)
|
|
local n=minetest.get_node(pos)
|
|
if string.sub(n.name,1,tableprefixlen) == tableprefix then
|
|
return string.sub(n.name,tableprefixlen+1)
|
|
else
|
|
log("not table: "..string.sub(n.name,1,tableprefixlen).." != "..tableprefix)
|
|
end
|
|
end
|
|
|
|
|
|
-- Takes one card from player and places it on cardtable at pos. Return true if card was moved.
|
|
local function player_to_cardtable(player_inv,list,i,pos)
|
|
local stack=player_inv:get_stack(list,i)
|
|
if stack:get_count() > 0 then
|
|
local cardname=stack:get_name()
|
|
if string.sub(cardname,1,cardprefixlen) == cardprefix then
|
|
local item=stack:take_item(1)
|
|
if item ~= nil then
|
|
local color=cardtable_get_color(pos)
|
|
log("adding "..cardname.." to cardtable at "..minetest.pos_to_string(pos).." color "..(color or "nil"))
|
|
if cardtable_add_card(pos,cardname,color) then
|
|
player_inv:set_stack(list,i,stack)
|
|
return true
|
|
end
|
|
else
|
|
log("couldn't take_item "..cardname.." at position "..i.." list "..list)
|
|
end
|
|
else
|
|
log("not a card but "..cardname.." at position "..i.." list "..list)
|
|
end
|
|
else
|
|
log("empty at position "..i.." of list "..list)
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Takes card(s) which of list of sender and place them on cardtable at pos.
|
|
local function inventory_to_cardtable(list,pos,sender,which)
|
|
local player_inv=minetest.get_inventory({type="player", name=sender:get_player_name()})
|
|
local s=player_inv:get_size(list)
|
|
if which == nil then
|
|
log("play all cards from "..list)
|
|
local success=false
|
|
for i=1,s,1 do
|
|
if player_to_cardtable(player_inv,list,i,pos) then success=true end
|
|
end
|
|
return success
|
|
elseif which == 1 then
|
|
log("play first card from "..list)
|
|
for i=1,s,1 do
|
|
if player_to_cardtable(player_inv,list,i,pos) then return true end
|
|
end
|
|
elseif which == -1 then
|
|
log("play last card from "..list)
|
|
for i=s,1,-1 do
|
|
if player_to_cardtable(player_inv,list,i,pos) then return true end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function is_cardtable(pos)
|
|
local n=minetest.get_node(pos)
|
|
if string.sub(n.name,1,string.len(tableprefix)) == tableprefix then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- return true if pos is deal position
|
|
local function is_deal_position(pos)
|
|
local around={
|
|
{x=pos.x-1, y=pos.y, z=pos.z-1},{x=pos.x,y=pos.y,z=pos.z-1},{x=pos.x+1,y=pos.y,z=pos.z-1},
|
|
{x=pos.x-1, y=pos.y, z=pos.z}, {x=pos.x+1,y=pos.y,z=pos.z},
|
|
{x=pos.x-1, y=pos.y, z=pos.z+1},{x=pos.x,y=pos.y,z=pos.z+1},{x=pos.x+1,y=pos.y,z=pos.z+1}
|
|
}
|
|
local tablenodes=0
|
|
for key,p in ipairs(around) do
|
|
if is_cardtable(p) then
|
|
tablenodes=tablenodes+1
|
|
end
|
|
end
|
|
return tablenodes==1
|
|
end
|
|
|
|
-- return list of positions where cards should be dealt
|
|
local function cardtable_get_deal_positions(pos)
|
|
local positions=cardtable_get_positions(pos)
|
|
local dealpositions={}
|
|
for i,p in ipairs(positions) do
|
|
if is_deal_position(p) then
|
|
table.insert(dealpositions,p)
|
|
else
|
|
log(minetest.pos_to_string(p).." is not deal position")
|
|
end
|
|
end
|
|
return dealpositions
|
|
end
|
|
|
|
local function deal_card_to_table(pos,formname,fields,sender,has_color)
|
|
log("deal cards at "..minetest.pos_to_string(pos))
|
|
local below={x=pos.x,y=pos.y-1,z=pos.z}
|
|
local dp
|
|
if is_cardtable(below) then
|
|
log("below is cardtable")
|
|
local from_pile_meta=minetest.get_meta(pos)
|
|
local from_pile_inv=from_pile_meta:get_inventory()
|
|
if from_pile_inv == nil then log("pile inv=nil") return false end
|
|
local stack=pile_pop(from_pile_inv)
|
|
if stack == nil then
|
|
log("out of cards")
|
|
return false
|
|
end
|
|
local color
|
|
if has_color then
|
|
color=fields.deal_to_table
|
|
end
|
|
if cardtable_add_card(below,stack:get_name(),color) then
|
|
if pile_peek_first(from_pile_inv) == nil then
|
|
darken_pile(pos)
|
|
return true
|
|
end
|
|
else
|
|
log("Card did not fit on table.")
|
|
pile_add_card(from_pile_inv,stack:get_name())
|
|
return false
|
|
end
|
|
else
|
|
log("below is not cardtable -> not implemented")
|
|
return
|
|
end
|
|
end
|
|
|
|
-- Deal cards from pile to some other piles on a table
|
|
local function deal_cards(pos,formname,fields,sender)
|
|
log("deal cards at "..minetest.pos_to_string(pos))
|
|
local below={x=pos.x,y=pos.y-1,z=pos.z}
|
|
local dp
|
|
if is_cardtable(below) then
|
|
log("below is cardtable")
|
|
dp=cardtable_get_deal_positions(below)
|
|
else
|
|
log("below is not cardtable -> not implemented")
|
|
dp=cardtable_get_deal_positions(pos)
|
|
end
|
|
for i,p in ipairs(dp) do
|
|
log("deal to "..minetest.pos_to_string(p))
|
|
local from_pile_meta=minetest.get_meta(pos)
|
|
local from_pile_inv=from_pile_meta:get_inventory()
|
|
if from_pile_inv == nil then log("pile inv=nil") return false end
|
|
local stack=pile_pop(from_pile_inv)
|
|
if stack == nil then
|
|
log("out of cards")
|
|
return false
|
|
end
|
|
local target_pos={x=p.x,y=p.y+1,z=p.z}
|
|
local target_node=minetest.get_node(target_pos)
|
|
if target_node.name == "air" then
|
|
minetest.place_node(target_pos,{name="deck:chestpile"})
|
|
target_node=minetest.get_node(target_pos)
|
|
end
|
|
if target_node.name == "deck:chestpile" or target_node.name == "deck:stockpile" then
|
|
local target_pile_meta=minetest.get_meta(target_pos)
|
|
local target_pile_inv=target_pile_meta:get_inventory()
|
|
if pile_peek_first(target_pile_inv) == nil then
|
|
lighten_pile(target_pos)
|
|
target_pile_meta=minetest.get_meta(target_pos)
|
|
target_pile_inv=target_pile_meta:get_inventory()
|
|
end
|
|
pile_add_card(target_pile_inv,stack:get_name())
|
|
else
|
|
log("not pile or air but "..target_node.name.." at "..minetest.pos_to_string(target_pos))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Process form button presses of cardtable
|
|
local function fields_cardtable(pos,formname,fields,sender)
|
|
if fields.cardtabletomain then
|
|
log("take all cards")
|
|
cardtableto("main",pos,sender)
|
|
elseif fields.cardtabletocraft then
|
|
cardtableto("craft",pos,sender)
|
|
elseif fields.main_to_cardtable_all then
|
|
inventory_to_cardtable("main",pos,sender,nil)
|
|
elseif fields.craft_to_cardtable_all then
|
|
inventory_to_cardtable("craft",pos,sender,nil)
|
|
elseif fields.main_to_cardtable_first then
|
|
inventory_to_cardtable("main",pos,sender,1)
|
|
elseif fields.main_to_cardtable_last then
|
|
inventory_to_cardtable("main",pos,sender,-1)
|
|
elseif fields.craft_to_cardtable_first then
|
|
inventory_to_cardtable("craft",pos,sender,1)
|
|
elseif fields.craft_to_cardtable_last then
|
|
inventory_to_cardtable("craft",pos,sender,-1)
|
|
end
|
|
end
|
|
|
|
-- Process form button presses of card pile
|
|
local function draw_card(pos,formname,fields,sender)
|
|
if fields.draw then
|
|
return draw_one_card(pos,formname,fields,sender)
|
|
elseif fields.drawall then
|
|
while draw_one_card(pos,formname,fields,sender) do
|
|
end
|
|
elseif fields.shuffle then
|
|
shuffle_pile(pos,formname,fields,sender)
|
|
elseif fields.sort then
|
|
sort_pile(pos,formname,fields,sender)
|
|
elseif fields.tostock then
|
|
minetest.close_formspec(sender:get_player_name(),"")
|
|
convert_pile(pos,"deck:stockpile")
|
|
elseif fields.alltopile then
|
|
put_all_to_pile(pos,formname,fields,sender)
|
|
elseif fields.crafttopile then
|
|
put_craft_to_pile(pos,formname,fields,sender)
|
|
elseif fields.deal then
|
|
deal_cards(pos,formname,fields,sender)
|
|
elseif fields.deal_to_table then
|
|
deal_card_to_table(pos,formname,fields,sender,true)
|
|
elseif fields.deal_to_table_nocolor then
|
|
deal_card_to_table(pos,formname,fields,sender,false)
|
|
end
|
|
end
|
|
|
|
-- when digging a card pile, place all individual cards to player inventory (not used)
|
|
local function on_dig_pile_getcards(pos,node,digger)
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local player_inv=minetest.get_inventory({type="player", name=digger:get_player_name()})
|
|
local stack=pile_pop(pile_inv)
|
|
while stack ~= nil do
|
|
player_inv:add_item("main",stack)
|
|
stack=pile_pop(pile_inv)
|
|
end
|
|
minetest.remove_node(pos)
|
|
end
|
|
|
|
-- when digging a card pile, place the pile to player inventory
|
|
local function on_dig_pile_getpile(pos,node,digger)
|
|
local meta=minetest.get_meta(pos)
|
|
local pile_inv=meta:get_inventory()
|
|
local player_inv=minetest.get_inventory({type="player", name=digger:get_player_name()})
|
|
local new_chestpile=ItemStack("deck:chestpile")
|
|
local stackmeta=new_chestpile:get_meta()
|
|
local i=1
|
|
local cardstack=pile_pop(pile_inv)
|
|
if cardstack == nil then
|
|
stackmeta:set_string("description","Empty pile")
|
|
minetest.remove_node(pos)
|
|
return
|
|
end
|
|
local descr=""
|
|
while cardstack ~= nil do
|
|
local cardname=cardstack:get_name()
|
|
log("getpile: got "..cardname)
|
|
stackmeta:set_string(i,cardname)
|
|
cardstack=pile_pop(pile_inv)
|
|
descr=descr..", "..(carddescriptions[cardname] or cardname)
|
|
i=i+1
|
|
end
|
|
stackmeta:set_string("description",string.sub(descr,3))
|
|
player_inv:add_item("main",new_chestpile)
|
|
minetest.remove_node(pos)
|
|
end
|
|
|
|
-- Place cards from itemstack inventory to node inventory when player places a pile.
|
|
local function after_place_pile(pos,placer,itemstack,pointed_thing)
|
|
local stackmeta=itemstack:get_meta()
|
|
local i=1
|
|
local card=stackmeta:get_string(i)
|
|
if card == nil then
|
|
stackmeta:set_string("description","Empty pile")
|
|
darken_pile(pos)
|
|
return
|
|
end
|
|
local pilemeta=minetest.get_meta(pos)
|
|
local pile_inv=pilemeta:get_inventory()
|
|
local descr=""
|
|
while card ~= "" do
|
|
log("after_place_pile: i="..i.." card="..card)
|
|
pile_add_card(pile_inv,card)
|
|
descr=descr..", "..(carddescriptions[card] or card)
|
|
i=i+1
|
|
card=stackmeta:get_string(i)
|
|
end
|
|
stackmeta:set_string("description",string.sub(descr,3))
|
|
end
|
|
|
|
-- Log cardtable piece coordinates
|
|
local function describe_cardtable(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
local positions=minetest.deserialize(meta:get_string("cardtable_positions"))
|
|
for key,p in ipairs(positions) do
|
|
log("cardtable piece in "..minetest.pos_to_string(p))
|
|
end
|
|
end
|
|
|
|
-- Connect cardtable blocks together by marking main block (=first
|
|
-- block) position to new block and by adding new block position to
|
|
-- list of positions.
|
|
local function add_node_to_cardtable(main_pos,new_pos)
|
|
log("add "..minetest.pos_to_string(new_pos).." to old cardtable with main pos="..minetest.pos_to_string(main_pos))
|
|
local new_meta=minetest.get_meta(new_pos)
|
|
local main_meta=minetest.get_meta(main_pos)
|
|
local positions=minetest.deserialize(main_meta:get_string("cardtable_positions"))
|
|
table.insert(positions,new_pos)
|
|
main_meta:set_string("cardtable_positions",minetest.serialize(positions))
|
|
new_meta:set_string("cardtable_main_x",main_pos.x)
|
|
new_meta:set_string("cardtable_main_y",main_pos.y)
|
|
new_meta:set_string("cardtable_main_z",main_pos.z)
|
|
describe_cardtable(main_pos)
|
|
end
|
|
|
|
-- When placing a cardtable block, set formspec and check whether this
|
|
-- block starts a new table or is added to old one.
|
|
local function on_construct_cardtable(pos)
|
|
log("construct cardtable")
|
|
local around={
|
|
{x=pos.x-1, y=pos.y, z=pos.z-1},{x=pos.x,y=pos.y,z=pos.z-1},{x=pos.x+1,y=pos.y,z=pos.z-1},
|
|
{x=pos.x-1, y=pos.y, z=pos.z}, {x=pos.x+1,y=pos.y,z=pos.z},
|
|
{x=pos.x-1, y=pos.y, z=pos.z+1},{x=pos.x,y=pos.y,z=pos.z+1},{x=pos.x+1,y=pos.y,z=pos.z+1}
|
|
}
|
|
local meta=minetest.get_meta(pos)
|
|
meta:set_string("formspec", "size[13,12]"..
|
|
"button[0,0;3,1;cardtabletocraft;Take all cards]"..
|
|
"button[3,0;3,1;craft_to_cardtable_all;Play all cards]"..
|
|
"button[6,0;3,1;craft_to_cardtable_first;Play first card]"..
|
|
"button[9,0;3,1;craft_to_cardtable_last;Play last card]"..
|
|
"list[current_player;craft;0,1;13,4;]"..
|
|
"button[0,6;3,1;cardtabletomain;Take all cards]"..
|
|
"button[3,6;3,1;main_to_cardtable_all;Play all cards]"..
|
|
"button[6,6;3,1;main_to_cardtable_first;Play first card]"..
|
|
"button[9,6;3,1;main_to_cardtable_last;Play last card]"..
|
|
"list[current_player;main;0,7;13,5;]"
|
|
|
|
)
|
|
for key,p in ipairs(around) do
|
|
if is_cardtable(p) then
|
|
add_node_to_cardtable(cardtable_get_main_pos(p),pos)
|
|
return
|
|
end
|
|
end
|
|
-- this is a new cardtable
|
|
log("new cardtable")
|
|
meta:set_string("cardtable_main_x",pos.x)
|
|
meta:set_string("cardtable_main_y",pos.y)
|
|
meta:set_string("cardtable_main_z",pos.z)
|
|
meta:set_string("cardtable_positions",minetest.serialize({pos}))
|
|
describe_cardtable(pos)
|
|
end
|
|
|
|
-- Handle removing block from cardtable. Removing main block removes
|
|
-- the whole table.
|
|
local function after_dig_cardtable(pos, oldnode, oldmeta, digger)
|
|
log("after dig")
|
|
describe("after_dig_meta",oldmeta)
|
|
local meta=oldmeta["fields"]
|
|
local tmx=meta["cardtable_main_x"]
|
|
local tmy=meta["cardtable_main_y"]
|
|
local tmz=meta["cardtable_main_z"]
|
|
if(pos.x==tonumber(tmx) and pos.y==tonumber(tmy) and pos.z==tonumber(tmz)) then
|
|
log("digged main node of cardtable at "..minetest.pos_to_string(pos))
|
|
local positions=minetest.deserialize(meta["cardtable_positions"])
|
|
for i,pos in ipairs(positions) do
|
|
minetest.remove_node(pos)
|
|
log("removing at "..minetest.pos_to_string(pos).." too.")
|
|
end
|
|
else
|
|
log("digged non-main node of cardtable. main="..tmx..","..tmy..","..tmz.." digged="..minetest.pos_to_string(pos))
|
|
end
|
|
end
|
|
|
|
-- return array of strings that contain colors of cardtable at pos. Each color is returned only once.
|
|
local function cardtable_get_colors(pos)
|
|
local tablepositions=cardtable_get_positions(pos)
|
|
local colors={}
|
|
local colortable={}
|
|
local offset=tableprefixlen+1
|
|
for i,p in ipairs(tablepositions) do
|
|
local n=minetest.get_node(p)
|
|
local color=string.sub(n.name,offset)
|
|
if colortable[color] == nil then
|
|
table.insert(colors,color)
|
|
colortable[color]=1
|
|
end
|
|
end
|
|
return colors
|
|
end
|
|
|
|
-- Chestpile is a pile of cards that player can use like a chest.
|
|
minetest.register_node("deck:chestpile", {
|
|
description = "Card pile that user has full access to. Works also like a minetest chest.",
|
|
tiles = { "deck_back.png","deck_side.png" },
|
|
palette = "deck_palette.png",
|
|
groups = pilegroups,
|
|
paramtype2 = "color",
|
|
drawtype = "color",
|
|
on_construct = function(pos)
|
|
pile_inv_setup(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
meta:set_string("formspec", "size[13,12]"..
|
|
"list[context;main;0,0;13,8;]"..
|
|
"button[0,4;2,1;draw;Draw one]"..
|
|
"button[2,4;2,1;drawall;Draw all]"..
|
|
"button[0,5;3,1;alltopile;Add all to pile]"..
|
|
"button[4,4;3,1;shuffle;Shuffle cards]"..
|
|
"button[7,4;2,1;sort;Sort cards]"..
|
|
"button[9,4;3,1;tostock;Make stockpile]"..
|
|
"list[current_player;main;0,6;13,5;]")
|
|
end,
|
|
on_dig = on_dig_pile_getpile,
|
|
stack_max = 1,
|
|
after_place_node=after_place_pile,
|
|
on_receive_fields = draw_card
|
|
})
|
|
|
|
-- Stockpile is a pile of cards that players can draw cards from, but not
|
|
-- see which cards are there.
|
|
minetest.register_node("deck:stockpile", {
|
|
description = "Stock pile of cards. Can't be peeked.",
|
|
groups = pilegroups,
|
|
tiles = { "deck_back.png" },
|
|
palette = "deck_palette.png",
|
|
paramtype2 = "color",
|
|
drawtype = "color",
|
|
on_construct = function(pos)
|
|
pile_inv_setup(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
local below={x=pos.x,y=pos.y-1,z=pos.z}
|
|
local colors=cardtable_get_colors(below)
|
|
local dealmenu
|
|
local deallabel
|
|
if table.getn(colors) == 1 then
|
|
deallabel=""
|
|
dealmenu="button[10,0;2,1;deal_to_table_nocolor;Deal to table]"
|
|
else
|
|
deallabel="label[10,0;Deal to table]"
|
|
dealmenu="dropdown[10,1;2;deal_to_table;"
|
|
for key,value in ipairs(colors) do
|
|
dealmenu=dealmenu..value..","
|
|
end
|
|
dealmenu=dealmenu..";1]"
|
|
end
|
|
local add_to_pile_inv=minetest.create
|
|
meta:set_string("formspec","size[13,7]"..
|
|
"button[0,0;2,1;draw;Draw one]"..
|
|
"button[0,1;2,1;drawall;Draw all]"..
|
|
"button[2,0;2,1;crafttopile;Add to pile]"..
|
|
"list[current_player;craft;2,1;1,1;]"..
|
|
"button[4,1;3,1;alltopile;Add all to pile]"..
|
|
"button[4,0;3,1;shuffle;Shuffle cards]"..
|
|
"button[8,0;2,1;deal;Deal cards]"..
|
|
deallabel..dealmenu..
|
|
"list[current_player;main;0,2;13,5;]"
|
|
)
|
|
end,
|
|
on_dig = on_dig_pile_getpile,
|
|
stack_max = 1,
|
|
after_place_node=after_place_pile,
|
|
on_receive_fields = draw_card
|
|
})
|
|
|
|
-- Cardtable is a table building block that should make handling
|
|
-- multiple cards easier.
|
|
log(table.getn(dye.dyes).." cardtable colors")
|
|
for _, row in ipairs(dye.dyes) do
|
|
local color = row[1]
|
|
local name = tableprefix..color
|
|
local colorize = tablecolorize[color]
|
|
if colorize == nil then colorize = color end
|
|
local tile = "deck_table_g.png^[colorize:"..colorize..":127"
|
|
log(name..": "..tile)
|
|
minetest.register_node(name, {
|
|
description = "Table where cards can be easily dealt",
|
|
tiles = { tile },
|
|
on_construct = on_construct_cardtable,
|
|
groups = {cracky=3, cardtable=1},
|
|
after_dig_node = after_dig_cardtable,
|
|
on_receive_fields = fields_cardtable,
|
|
})
|
|
end
|
|
|
|
-- ABM enables adding cards to a pile by placing card on the pile.
|
|
minetest.register_abm({
|
|
label="Drop a card to pile",
|
|
nodenames={"deck:chestpile","deck:stockpile"},
|
|
neighbors=cardnames,
|
|
interval=1.0,
|
|
chance = 1,
|
|
action=function(pos,node,active_object_count,active_object_count_wider)
|
|
local above = {x=pos.x,y=pos.y+1,z=pos.z}
|
|
local abovenode = minetest.get_node(above)
|
|
if string.sub(abovenode.name,1,cardprefixlen) ~= cardprefix then
|
|
return end
|
|
local meta=minetest.get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
if pile_peek_first(inv) == nil then
|
|
lighten_pile(pos)
|
|
end
|
|
if pile_add_card_from_pos(inv,above) then
|
|
minetest.remove_node(above)
|
|
while true do
|
|
above={x=above.x,y=above.y+1,z=above.z}
|
|
abovenode = minetest.get_node(above)
|
|
if string.sub(abovenode.name,1,cardprefixlen) == cardprefix then
|
|
minetest.spawn_falling_node(above)
|
|
else
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
})
|
|
|
|
-- a card can be crafted into a stockpile of one card
|
|
minetest.register_craft({
|
|
output = "deck:stockpile",
|
|
recipe = {{"group:card"}}
|
|
})
|
|
|
|
-- a card can be crafted into a chestpile of one card
|
|
minetest.register_craft({
|
|
output = "deck:chestpile",
|
|
recipe = {{"group:card"}}
|
|
})
|
|
|
|
-- card deck of 52 cards can be crafted from two pieces of paper
|
|
minetest.register_craft({
|
|
output = "deck:chestpile",
|
|
recipe = {{ "default:paper" },{ "default:paper" }}
|
|
})
|
|
|
|
-- card table pieces can be crafted from 2x2 grid of wood
|
|
minetest.register_craft({
|
|
output = tableprefix.."white 99",
|
|
recipe = {{ "group:wood", "group:wood"},{"group:wood","group:wood"}}
|
|
})
|
|
|
|
for _, row in ipairs(dye.dyes) do
|
|
local color = row[1]
|
|
local name = tableprefix..color
|
|
local outputstring = name.." 99"
|
|
local dyetype = "group:dye,color_white"
|
|
log("registering craft for '"..outputstring.."' and dyetype "..dyetype)
|
|
minetest.register_craft({
|
|
type = "shapeless",
|
|
output = outputstring,
|
|
recipe = { "group:dye,color_" .. color, "group:cardtable" }
|
|
})
|
|
end
|
|
|
|
-- Card turns into chestpile or stockpile depending on
|
|
-- the place in the craft grid.
|
|
-- Card deck from paper need to be filled with cards here.
|
|
local function craft_pile(itemstack,player,old_craft_grid,craft_inv,really)
|
|
--describe("craft",old_craft_grid)
|
|
-- local s=craft_inv:get_size("craft")
|
|
local place, cardname
|
|
local onlycards=true
|
|
local onlypaper=true
|
|
for key,value in pairs(old_craft_grid) do
|
|
--local stack=craft_inv:get_stack("craft",i)
|
|
local stack=old_craft_grid[key]
|
|
if stack:is_empty() then
|
|
--log("empty "..key)
|
|
else
|
|
place=key
|
|
cardname=stack:get_name()
|
|
if string.sub(cardname,1,10) ~= cardprefix then
|
|
onlycards=false
|
|
end
|
|
if cardname ~= "default:paper" then
|
|
onlypaper=false
|
|
end
|
|
log("craft:"..key.."="..stack:get_name())
|
|
end
|
|
end
|
|
if (onlycards==false and onlypaper==false) then
|
|
return nil
|
|
end
|
|
if onlypaper then
|
|
local resultname=itemstack:get_name()
|
|
if resultname == "deck:chestpile" then
|
|
local stackmeta=itemstack:get_meta()
|
|
local i
|
|
for i=1,52,1 do
|
|
stackmeta:set_string(i,cardnames[i])
|
|
end
|
|
return itemstack
|
|
end
|
|
return nil
|
|
end
|
|
local pilename
|
|
if place < 5 then
|
|
pilename="deck:chestpile"
|
|
else
|
|
pilename="deck:stockpile"
|
|
end
|
|
log("place="..place.." pilename="..pilename)
|
|
local pilestack=ItemStack(pilename)
|
|
local stackmeta=pilestack:get_meta()
|
|
stackmeta:set_string(1,cardname)
|
|
if really then
|
|
stackmeta:set_string("description",carddescriptions[cardname])
|
|
end
|
|
return pilestack
|
|
end
|
|
|
|
minetest.register_on_craft(function(itemstack,player,old_craft_grid,craft_inv)
|
|
return craft_pile(itemstack,player,old_craft_grid,craft_inv,true)
|
|
end)
|
|
minetest.register_craft_predict(function(itemstack,player,old_craft_grid,craft_inv)
|
|
return craft_pile(itemstack,player,old_craft_grid,craft_inv,false)
|
|
end)
|
|
|
|
-- Enlarge player inventory for easier handling of cards.
|
|
minetest.register_on_joinplayer(function(player)
|
|
--log(player:get_inventory_formspec())
|
|
player:get_inventory():set_size("main", 60)
|
|
player:get_inventory():set_size("craft", 60)
|
|
player:set_inventory_formspec("size[13,11]list[current_player;main;0,3.5;13,5;]list[current_player;craft;3,0;3,3;]listring[]list[current_player;craftpreview;7,1;1,1;]")
|
|
--log(player:get_inventory_formspec())
|
|
end)
|