@@ -103,16 +103,9 @@ tex = u.image('default_steel_block'); wandprops = {}; }; }; - gem = sorcery.lib.tbl.deepmerge(sorcery.data.gems, { - sapphire = { - wandprops = { sturdiness = 0.5 }; - }; - diamond = { - wandprops = { sturdiness = (1/3) }; - }; - }) + gem = sorcery.data.gems; }; util = { baseid = function(wand) local elts = {wand.wood} @@ -258,8 +251,9 @@ local uprops = user:get_properties(); local context = { base = wand; + stats = matprops; meta = meta; item = stack; caster = user; target = target; @@ -342,8 +336,25 @@ end return img end +local update_stand_info = function(pos) + local woodname = minetest.registered_nodes[minetest.get_node(pos).name]._proto.wood + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:is_empty('wand') then + meta:set_string('infotext',u.str.capitalize(woodname) .. ' wand stand') + else + local stack = inv:get_stack('wand',1) + local spell = stack:get_meta():get_string('sorcery_wand_spell') + local color = u.color(127,127,127) + if spell ~= '' then + color = u.color(sorcery.data.spells[spell].color):readable() + end + local wand_proto = sorcery.wands.util.getproto(stack) + meta:set_string('infotext',color:fmt(sorcery.wands.util.fullname(stack) .. ' stand')) + end +end local createstand = function(name, wood, desc, tex, extra) local hitbox = { type = "fixed"; fixed = { @@ -362,9 +373,16 @@ paramtype2 = 'facedir'; tiles = images; selection_box = hitbox; collision_box = hitbox; + after_dig_node = sorcery.lib.node.purge_container; use_texture_alpha = true; + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('wand', 1) + update_stand_info(pos) + end; _proto = { wood = wood; }; groups = { @@ -374,37 +392,109 @@ }; } minetest.register_node(name, u.tbl.merge(auto,extra)) end -local update_stand_info = function(pos) - local woodname = minetest.registered_nodes[minetest.get_node(pos).name]._proto.wood +local rack_update = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - if inv:is_empty('wand') then - meta:set_string('infotext',u.str.capitalize(woodname) .. ' wand stand') - else - local stack = inv:get_stack('wand',1) - local spell = stack:get_meta():get_string('sorcery_wand_spell') - local color = u.color(127,127,127) - if spell ~= '' then - color = u.color(sorcery.data.spells[spell].color):readable() + local wandcount = 0 + local mkslot = function(slot,x,y) + local stack = inv:get_stack('wands',slot) + local im = stack:get_meta() + local r = string.format([[ list[context;wands;%f,%f;1,1;%u] ]], x, y, slot-1) + if stack:is_empty() then + r = r .. string.format([[ image[%f,%f;1,1;sorcery_ui_ghost_wand.png] ]], x, y) + else + wandcount = wandcount + 1 + if im:contains('sorcery_wand_spell') then + local spell = im:get_string('sorcery_wand_spell') + local spname = u.str.capitalize(sorcery.data.spells[spell].name) + local spclr = u.color(sorcery.data.spells[spell].color or {255,255,255}) + + r = r .. string.format([[ + label[%f,%f;%s] + ]], x + 1.25, y + 0.5, minetest.formspec_escape(spclr:fmt(spname))) + end end - local wand_proto = sorcery.wands.util.getproto(stack) - meta:set_string('infotext',color:fmt(sorcery.wands.util.fullname(stack) .. ' stand')) + return r end + local spec = [[ + formspec_version[3] size[10.25,11.75] real_coordinates[true] + list[current_player;main;0.25,6.75;8,4;] + listring[current_player;main] listring[context;wands] + ]] + for i=1,inv:get_size('wands') do + local yo = ((i-1) % 5) * 1.25 + local xo = i > 5 and 5 or 0 + spec = spec .. mkslot(i, 0.25 + xo, 0.25 + yo) + end + meta:set_string('formspec',spec) + if wandcount > 0 then + meta:set_string('infotext',string.format('Wand rack with %u wands', wandcount)) + else + meta:set_string('infotext','Wand rack') + end +end + +local createrack = function(name, wood, tex, desc) + local hitbox = { + type = "fixed"; + fixed = { + -0.5, -0.5, 0.5; + 0.5, 0.5, 0.35; + }; + } + local rack = { + description = desc; + drawtype = 'mesh'; + mesh = 'sorcery-wand-rack.obj'; + sunlight_propagates = true; + paramtype = 'light'; + paramtype2 = 'facedir'; + tiles = { + u.image('default_diamond_block.png'): + multiply(u.color{50,255,70}):render(); + tex:render(); + 'default_diamond_block.png'; + 'default_copper_block.png'; + 'default_pine_wood.png'; + 'default_junglewood.png'; + }; + selection_box = hitbox; + collision_box = hitbox; + use_texture_alpha = true; + after_dig_node = sorcery.lib.node.purge_container; + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('wands',10) + rack_update(pos) + end; + allow_metadata_inventory_put = function(pos, lst, idx, stack, user) + if minetest.get_item_group(stack:get_name(), 'sorcery_wand') ~= 0 + then return 1 + else return 0 + end + end; + on_metadata_inventory_move = rack_update; + on_metadata_inventory_take = rack_update; + on_metadata_inventory_put = rack_update; + _proto = { wood = wood; }; + groups = { + sorcery_wand_rack = 1; + choppy = 2; + oddly_breakable_by_hand = 2; + }; + } + minetest.register_node(name, rack) end for woodname, wood in pairs(sorcery.wands.materials.wood) do local blank = u.image('sorcery_transparent.png'); -- haaaaack local name = 'sorcery:wand_stand_' .. woodname + local rackid = 'sorcery:wand_rack_' .. woodname createstand(name, woodname, - u.str.capitalize(woodname .. 'wood wand stand'), + u.str.capitalize(woodname) .. 'wood wand stand', { wood.tex; blank; blank; blank; }, { - on_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - inv:set_size('wand', 1) - update_stand_info(pos) - end; on_rightclick = function(pos,node,user,stack) local meta = minetest.get_meta(pos) local stand = meta:get_inventory() local wand_proto = sorcery.wands.util.getproto(stack) @@ -420,15 +510,31 @@ return stack end } ) + createrack(rackid,woodname,wood.tex, + u.str.capitalize(woodname) .. 'wood wand rack') + local plank = wood.plank or 'default:' .. woodname .. '_wood' minetest.register_craft { + output = name; recipe = { + -- TODO: whittling/carving knife {plank, 'default:stick', plank}; {plank, plank, plank}; }; - output = name + } + + minetest.register_craft { + output = rackid; + recipe = { + {plank,'default:stick',plank}; + {'sorcery:screw_steel','screwdriver:screwdriver','sorcery:screw_steel'}; + {plank,name,plank}; + }; + replacements = { + {'screwdriver:screwdriver','screwdriver:screwdriver'}; + }; } end sorcery.wands.createstands = function(kind) @@ -580,9 +686,8 @@ local success = false for i,wand in pairs(wands) do local proto = wand.stack:get_definition()._proto local wood = sorcery.wands.materials.wood[proto.wood] - --print('considering ' .. proto.wood) for spell,def in pairs(sorcery.data.spells) do if not def.affinity then goto skip_spell end local potions, found = {}, false for _,a in pairs(def.affinity) do @@ -590,17 +695,14 @@ potions[#potions + 1] = a end end if not found then goto skip_spell end - -- for spell,potions in pairs(wood.affinities) do - --print(' + considering spell ' .. spell) -- check whether all the necessary philters -- are accounted for if #potions ~= #philters then goto skip_spell end for _,p in pairs(potions) do for _,ph in pairs(philters) do local def = ph.stack:get_definition() - --print(' - + checking for philter ' .. def._protoname) if def._protoname == p then goto found end end goto skip_spell ::found::end @@ -607,9 +709,8 @@ success = true -- we've confirmed that all the philters for this spell -- are present, now we need to apply it to the wand - --print('setting spell') wand.stack:get_meta():set_string('sorcery_wand_spell',spell) update_wand_description(wand.stack) inv:set_stack('tank',wand.idx,wand.stack) @@ -639,9 +740,9 @@ name, x,y, w,h ) end - return 'size[8,6.5]' .. + return 'size[8,6.25]' .. slot('tank', 0.5,0, 2,2) .. slot('wandparts', 5.5,0, 1,2) .. slot('preview', 6.5,0.5, 1,1) .. slot('input', 4.5,0.5, 1,1) .. [[