Vanessa Ezekowitz da66780a56 copy all standard Dreambuilder mods in from the old subgame
(exactly as last supplied there, updates to these mods will follow later)
2016-04-01 21:09:33 -04:00

246 lines
7.0 KiB
Lua

--------------------------------------------------------
-- supporting junk
function min(a,b)
if a < b then
return a
else
return b
end
end
if not string.starts then
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
end
--------------------------------------------------------
function sortInventory(inv,sorter)
local tabl = inv:get_list("main")
if(tabl == nil) then
-- we don't sort furnaces!
return false
end
table.sort(tabl,sorter)
-- note take_item will set the name to '' when empty
-- NEVER reduce the inventory array size for chests
inv:set_list('main',tabl)
return true
end
sorters = {
wise = function(a,b)
-- XXX: this needs to have stricter ordering!
-- (why is air scoring higher than the end?)
if(a == nil) then
if b == nil then
return true
else
return false
end
elseif b == nil then
return true
end
local aname = a:get_name()
local bname = b:get_name()
-- make sure empty slots go at the end
if(string.len(aname) == 0) then
return false
end
if(string.len(bname) == 0) then
return true
end
-- if the nodes are entirely different, sorted
if (aname ~= bname) then
return aname < bname
end
-- same node types
-- may need to collapse the two together!
local bothmax = a:get_stack_max()
if bothmax == 1 then
-- it's unstackable
local awear = a:get_wear()
local bwear = b:get_wear()
return awear < bwear
end
local acount = a:get_count()
local bcount = b:get_count()
if(acount == bothmax) then
--print('same?',acount,bcount,bothmax)
return bcount ~= bothmax
elseif (bcount == bothmax) then
--print('bcount bothmax derp')
return false
end
local num = min(bcount,bothmax-acount)
a:add_item(b:take_item(num))
-- nothing can have both count AND wear, right?
-- now a:count > b:count so a should go first
--print('numnum',num)
return true
end,
amount = function(a,b)
return a:get_count() > b:get_count()
end,
wear = function(a,b)
return a:get_wear() < b:get_wear()
end,
-- etc...
}
function registerWand(method,sorter)
if method == nil then
name = "inventory_sorter:wand"
sorter = sorters.wise
assert(sorter ~= nil)
desc = 'Chest Sorter'
image = 'inventory_sorter_wand.png'
else
name = "inventory_sorter:wand_"..method
desc = "Chest Sorter ("..method..')'
image = 'inventory_sorter_wand_'..method..'.png'
end
minetest.register_tool(name, {
description = desc,
inventory_image = image,
wield_image = image,
stack_max = 1,
tool_capabilities = {
full_punch_interval=0,
max_drop_level=0
},
on_use = function(self,user,punched)
local pos = minetest.get_pointed_thing_position(punched)
if pos==nil then
return
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if(inv == nil) then
minetest.chat_send_player(user:get_player_name(),"That can't be sorted.","Sorter -!-")
return
end
-- this isn't exported, but default locked chest does this
local owner = meta:get_string("owner")
if(owner ~= nil and string.len(owner) ~= 0 and user:get_player_name() ~= owner) then
minetest.chat_send_player(user:get_player_name(),"That's not yours!","Sorter -!-")
return
end
-- Sokomine's shared chest locks
if locks ~= nil then
if punched == nil or punched.name == nil then
punched = minetest.get_node(pos)
end
if punched and punched.name:starts('locks:') and not locks:lock_allow_use(pos,user) then
-- the error has already been reported (yay side effects)
return
end
end
if(sortInventory(inv,sorter)) then
minetest.chat_send_player(user:get_player_name(),"Chest sorted.","Sorter -!-")
end
end
})
end
function debugSorter(a,b)
result = sorters.wise(a,b)
function derp(a)
return a:get_name()..":"..a:get_count()..":"..a:get_wear()
end
if a then
a = derp(a)
end
if b then
b = derp(b)
end
if result then
print('a goes first',a,b)
else
print('b goes first',a,b)
end
return result
end
function test()
function thingy(name,stack_max)
return {
get_name=function(self) return name end,
get_stack_max=function(self) return stack_max end,
get_count=function(self) return stack_max end,
get_wear=function(self) return 1/stack_max end,
take_item=function() end,
add_item=function() end,
derp=function()
return name..', '..tostring(stack_max)
end
}
end
tabl = {thingy('thing1',1),thingy('hting2',1),nil,thingy('thing1',2),thingy('thing1',4),thingy('thing1',10)}
table.sort(tabl,sorter)
for n,v in pairs(tabl) do
print(n,v:get_name(),v:get_count())
end
end
-- test()
-- print('yay')
-- error('...')
for name,sorter in pairs(sorters) do
registerWand(name,sorter)
end
registerWand()
minetest.register_craft({
output = 'inventory_sorter:wand',
recipe = {
{'default:stick','default:stick',''},
{'default:stick','default:stick',''},
{'','default:stick',''}
}
})
-- is this one automatic...?
minetest.register_craft({
output = 'inventory_sorter:wand',
recipe = {
{'','default:stick','default:stick'},
{'','default:stick','default:stick'},
{'','','default:stick'}
}
})
minetest.register_chatcommand('sort',{
params = '[optional algorithm: amount,wear]',
description = 'Sort your inventory! No takebacks.',
privs={interact=true},
func = function(name,param)
local sorter = sorters.wise;
if string.len(param) > 0 then
sorter = sorters[param];
if sorter == nil then
minetest.chat_send_player(name,"/sort [algorithm]","Sorter -!-")
minetest.chat_send_player(name,"Valid algorithms:","Sorter -!-")
for n,v in pairs(sorters) do
minetest.chat_send_player(name,' '..n,"Sorter -!-")
end
return;
end
end
if(sortInventory(minetest.get_player_by_name(name):get_inventory(),sorter)) then
minetest.chat_send_player(name,"Sorted.","Sorter -!-")
end
end
})