Differences From
Artifact [eabb5d4796]:
- File
wands.lua
— part of check-in
[ea6e475e44]
at
2020-10-19 09:52:11
on branch trunk
— continue dev on celestial mechanics, add melding+division spells (resonance), refine itemclasses, add keypunch and punchcards, add paper pulp, add a shitload of visuals, add convenience scripts for working with the wiki, make the flamebolt spell actually useful instead of just a pretty lightshow, add essences, inferno crystal, and other goodies; iterate on wands, lots of shit i can't remember, various bugfixes
(user:
lexi,
size: 27150)
[annotate]
[blame]
[check-ins using]
100 100 };
101 101 steel = {
102 102 tone = u.color(255,255,255);
103 103 tex = u.image('default_steel_block');
104 104 wandprops = {};
105 105 };
106 106 };
107 - gem = sorcery.lib.tbl.deepmerge(sorcery.data.gems, {
108 - sapphire = {
109 - wandprops = { sturdiness = 0.5 };
110 - };
111 - diamond = {
112 - wandprops = { sturdiness = (1/3) };
113 - };
114 - })
107 + gem = sorcery.data.gems;
115 108 };
116 109 util = {
117 110 baseid = function(wand)
118 111 local elts = {wand.wood}
119 112 if wand.gem ~= nil then elts[#elts + 1] = wand.gem end
120 113 if wand.wire ~= nil then elts[#elts + 1] = wand.wire end
121 114 return 'sorcery:wand_' .. table.concat(elts,'_')
................................................................................
255 248 end
256 249 end
257 250 end
258 251
259 252 local uprops = user:get_properties();
260 253 local context = {
261 254 base = wand;
255 + stats = matprops;
262 256 meta = meta;
263 257 item = stack;
264 258 caster = user;
265 259 target = target;
266 260 today = minetest.get_day_count();
267 261 heading = {
268 262 pos = user:get_pos();
................................................................................
339 333 if kind.gem then
340 334 img.gem = u.image('sorcery_wand_' .. kind.gem .. '_tip.png')
341 335 img.whole = img.gem:blit(img.whole)
342 336 end
343 337 return img
344 338 end
345 339
340 +local update_stand_info = function(pos)
341 + local woodname = minetest.registered_nodes[minetest.get_node(pos).name]._proto.wood
342 + local meta = minetest.get_meta(pos)
343 + local inv = meta:get_inventory()
344 + if inv:is_empty('wand') then
345 + meta:set_string('infotext',u.str.capitalize(woodname) .. ' wand stand')
346 + else
347 + local stack = inv:get_stack('wand',1)
348 + local spell = stack:get_meta():get_string('sorcery_wand_spell')
349 + local color = u.color(127,127,127)
350 + if spell ~= '' then
351 + color = u.color(sorcery.data.spells[spell].color):readable()
352 + end
353 + local wand_proto = sorcery.wands.util.getproto(stack)
354 + meta:set_string('infotext',color:fmt(sorcery.wands.util.fullname(stack) .. ' stand'))
355 + end
356 +end
346 357 local createstand = function(name, wood, desc, tex, extra)
347 358 local hitbox = {
348 359 type = "fixed";
349 360 fixed = {
350 361 -0.5, -0.5, -0.3;
351 362 0.5, -0.1, 0.3;
352 363 };
................................................................................
359 370 mesh = 'sorcery-wand-stand.obj';
360 371 sunlight_propagates = true;
361 372 paramtype = 'light';
362 373 paramtype2 = 'facedir';
363 374 tiles = images;
364 375 selection_box = hitbox;
365 376 collision_box = hitbox;
377 + after_dig_node = sorcery.lib.node.purge_container;
366 378 use_texture_alpha = true;
379 + on_construct = function(pos)
380 + local meta = minetest.get_meta(pos)
381 + local inv = meta:get_inventory()
382 + inv:set_size('wand', 1)
383 + update_stand_info(pos)
384 + end;
367 385 _proto = {
368 386 wood = wood;
369 387 };
370 388 groups = {
371 389 sorcery_wand_stand = 1;
372 390 choppy = 2;
373 391 oddly_breakable_by_hand = 2;
374 392 };
375 393 }
376 394 minetest.register_node(name, u.tbl.merge(auto,extra))
377 395 end
378 -local update_stand_info = function(pos)
379 - local woodname = minetest.registered_nodes[minetest.get_node(pos).name]._proto.wood
396 +local rack_update = function(pos)
380 397 local meta = minetest.get_meta(pos)
381 398 local inv = meta:get_inventory()
382 - if inv:is_empty('wand') then
383 - meta:set_string('infotext',u.str.capitalize(woodname) .. ' wand stand')
384 - else
385 - local stack = inv:get_stack('wand',1)
386 - local spell = stack:get_meta():get_string('sorcery_wand_spell')
387 - local color = u.color(127,127,127)
388 - if spell ~= '' then
389 - color = u.color(sorcery.data.spells[spell].color):readable()
399 + local wandcount = 0
400 + local mkslot = function(slot,x,y)
401 + local stack = inv:get_stack('wands',slot)
402 + local im = stack:get_meta()
403 + local r = string.format([[ list[context;wands;%f,%f;1,1;%u] ]], x, y, slot-1)
404 + if stack:is_empty() then
405 + r = r .. string.format([[ image[%f,%f;1,1;sorcery_ui_ghost_wand.png] ]], x, y)
406 + else
407 + wandcount = wandcount + 1
408 + if im:contains('sorcery_wand_spell') then
409 + local spell = im:get_string('sorcery_wand_spell')
410 + local spname = u.str.capitalize(sorcery.data.spells[spell].name)
411 + local spclr = u.color(sorcery.data.spells[spell].color or {255,255,255})
412 +
413 + r = r .. string.format([[
414 + label[%f,%f;%s]
415 + ]], x + 1.25, y + 0.5, minetest.formspec_escape(spclr:fmt(spname)))
416 + end
390 417 end
391 - local wand_proto = sorcery.wands.util.getproto(stack)
392 - meta:set_string('infotext',color:fmt(sorcery.wands.util.fullname(stack) .. ' stand'))
418 + return r
393 419 end
420 + local spec = [[
421 + formspec_version[3] size[10.25,11.75] real_coordinates[true]
422 + list[current_player;main;0.25,6.75;8,4;]
423 + listring[current_player;main] listring[context;wands]
424 + ]]
425 + for i=1,inv:get_size('wands') do
426 + local yo = ((i-1) % 5) * 1.25
427 + local xo = i > 5 and 5 or 0
428 + spec = spec .. mkslot(i, 0.25 + xo, 0.25 + yo)
429 + end
430 + meta:set_string('formspec',spec)
431 + if wandcount > 0 then
432 + meta:set_string('infotext',string.format('Wand rack with %u wands', wandcount))
433 + else
434 + meta:set_string('infotext','Wand rack')
435 + end
436 +end
437 +
438 +local createrack = function(name, wood, tex, desc)
439 + local hitbox = {
440 + type = "fixed";
441 + fixed = {
442 + -0.5, -0.5, 0.5;
443 + 0.5, 0.5, 0.35;
444 + };
445 + }
446 + local rack = {
447 + description = desc;
448 + drawtype = 'mesh';
449 + mesh = 'sorcery-wand-rack.obj';
450 + sunlight_propagates = true;
451 + paramtype = 'light';
452 + paramtype2 = 'facedir';
453 + tiles = {
454 + u.image('default_diamond_block.png'):
455 + multiply(u.color{50,255,70}):render();
456 + tex:render();
457 + 'default_diamond_block.png';
458 + 'default_copper_block.png';
459 + 'default_pine_wood.png';
460 + 'default_junglewood.png';
461 + };
462 + selection_box = hitbox;
463 + collision_box = hitbox;
464 + use_texture_alpha = true;
465 + after_dig_node = sorcery.lib.node.purge_container;
466 + on_construct = function(pos)
467 + local meta = minetest.get_meta(pos)
468 + local inv = meta:get_inventory()
469 + inv:set_size('wands',10)
470 + rack_update(pos)
471 + end;
472 + allow_metadata_inventory_put = function(pos, lst, idx, stack, user)
473 + if minetest.get_item_group(stack:get_name(), 'sorcery_wand') ~= 0
474 + then return 1
475 + else return 0
476 + end
477 + end;
478 + on_metadata_inventory_move = rack_update;
479 + on_metadata_inventory_take = rack_update;
480 + on_metadata_inventory_put = rack_update;
481 + _proto = { wood = wood; };
482 + groups = {
483 + sorcery_wand_rack = 1;
484 + choppy = 2;
485 + oddly_breakable_by_hand = 2;
486 + };
487 + }
488 + minetest.register_node(name, rack)
394 489 end
395 490 for woodname, wood in pairs(sorcery.wands.materials.wood) do
396 491 local blank = u.image('sorcery_transparent.png'); -- haaaaack
397 492 local name = 'sorcery:wand_stand_' .. woodname
493 + local rackid = 'sorcery:wand_rack_' .. woodname
398 494 createstand(name, woodname,
399 - u.str.capitalize(woodname .. 'wood wand stand'),
495 + u.str.capitalize(woodname) .. 'wood wand stand',
400 496 { wood.tex; blank; blank; blank; }, {
401 - on_construct = function(pos)
402 - local meta = minetest.get_meta(pos)
403 - local inv = meta:get_inventory()
404 - inv:set_size('wand', 1)
405 - update_stand_info(pos)
406 - end;
407 497 on_rightclick = function(pos,node,user,stack)
408 498 local meta = minetest.get_meta(pos)
409 499 local stand = meta:get_inventory()
410 500 local wand_proto = sorcery.wands.util.getproto(stack)
411 501 if minetest.get_item_group(stack:get_name(), 'sorcery_wand') ~= 0 then
412 502 stand:set_stack('wand',1,stack)
413 503 minetest.swap_node(pos, {
................................................................................
417 507 stack = ItemStack(nil)
418 508 end
419 509 update_stand_info(pos)
420 510 return stack
421 511 end
422 512 }
423 513 )
514 + createrack(rackid,woodname,wood.tex,
515 + u.str.capitalize(woodname) .. 'wood wand rack')
516 +
424 517 local plank = wood.plank or 'default:' .. woodname .. '_wood'
425 518 minetest.register_craft {
519 + output = name;
426 520 recipe = {
521 + -- TODO: whittling/carving knife
427 522 {plank, 'default:stick', plank};
428 523 {plank, plank, plank};
429 524 };
430 - output = name
525 + }
526 +
527 + minetest.register_craft {
528 + output = rackid;
529 + recipe = {
530 + {plank,'default:stick',plank};
531 + {'sorcery:screw_steel','screwdriver:screwdriver','sorcery:screw_steel'};
532 + {plank,name,plank};
533 + };
534 + replacements = {
535 + {'screwdriver:screwdriver','screwdriver:screwdriver'};
536 + };
431 537 }
432 538 end
433 539
434 540 sorcery.wands.createstands = function(kind)
435 541 -- big oof
436 542 for woodname, wood in pairs(sorcery.wands.materials.wood) do
437 543 local gemimg = u.image('default_diamond_block.png')
................................................................................
577 683
578 684 -- iterate through every wand in the tank to see if anything
579 685 -- needs to be done
580 686 local success = false
581 687 for i,wand in pairs(wands) do
582 688 local proto = wand.stack:get_definition()._proto
583 689 local wood = sorcery.wands.materials.wood[proto.wood]
584 - --print('considering ' .. proto.wood)
585 690 for spell,def in pairs(sorcery.data.spells) do
586 691 if not def.affinity then goto skip_spell end
587 692 local potions, found = {}, false
588 693 for _,a in pairs(def.affinity) do
589 694 if a == proto.wood then found = true else
590 695 potions[#potions + 1] = a
591 696 end
592 697 end
593 698 if not found then goto skip_spell end
594 - -- for spell,potions in pairs(wood.affinities) do
595 - --print(' + considering spell ' .. spell)
596 699 -- check whether all the necessary philters
597 700 -- are accounted for
598 701 if #potions ~= #philters then goto skip_spell end
599 702 for _,p in pairs(potions) do
600 703 for _,ph in pairs(philters) do
601 704 local def = ph.stack:get_definition()
602 - --print(' - + checking for philter ' .. def._protoname)
603 705 if def._protoname == p then goto found end
604 706 end
605 707 goto skip_spell
606 708 ::found::end
607 709
608 710 success = true
609 711 -- we've confirmed that all the philters for this spell
610 712 -- are present, now we need to apply it to the wand
611 - --print('setting spell')
612 713 wand.stack:get_meta():set_string('sorcery_wand_spell',spell)
613 714 update_wand_description(wand.stack)
614 715 inv:set_stack('tank',wand.idx,wand.stack)
615 716
616 717 do break end -- }:<<<
617 718 ::skip_spell::end
618 719 end
................................................................................
636 737 local slot = function(name,x,y,w,h)
637 738 return string.format('list[nodemeta:%d,%d,%d;%s;%f,%f;%f,%f;]',
638 739 pos.x, pos.y, pos.z,
639 740 name, x,y, w,h
640 741 )
641 742 end
642 743
643 - return 'size[8,6.5]' ..
744 + return 'size[8,6.25]' ..
644 745 slot('tank', 0.5,0, 2,2) ..
645 746 slot('wandparts', 5.5,0, 1,2) ..
646 747 slot('preview', 6.5,0.5, 1,1) ..
647 748 slot('input', 4.5,0.5, 1,1) .. [[
648 749 list[current_player;main;0,2.5;8,4;]
649 750 listring[]
650 751 ]]