sorcery  Diff

Differences From Artifact [2dc21e25ed]:

  • File wands.lua — part of check-in [3f6a913e4e] at 2020-09-29 12:40:28 on branch trunk — * remove former hacky registration system, replace with consistent and flexible API; rewrite metal/gem generation to take advantage of this new API; tweaks to init system to enable world-local tweaks to lore and sorcery behavior * initial documentation commit * initial steps towards calendar - add default date format, astrolabe; prepare infra for division/melding/transmutation spells, various tweaks and fixes (user: lexi, size: 24782) [annotate] [blame] [check-ins using]

To 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]

    30     30   				tree = 'default:jungletree';
    31     31   				plank = 'default:junglewood';
    32     32   			};
    33     33   		};
    34     34   		core = {
    35     35   			obsidian = {
    36     36   				item = 'default:obsidian_shard';
    37         -				sturdiness = 1.5;
           37  +				wandprops = { sturdiness = 1.5 };
    38     38   			};
    39     39   			diamond = {
    40     40   				item = 'sorcery:shard_diamond';
    41         -				sturdiness = 1.7;
    42         -				reliability = 0.75;
           41  +				wandprops = { sturdiness = 1.7, reliability = 0.85 };
    43     42   			};
    44     43   			mese = {
    45     44   				item = 'default:mese_fragment';
    46         -				generate = 2;
           45  +				wandprops = { generate = 2 };
    47     46   			};
    48     47   			cobalt = {
    49     48   				item = 'sorcery:powder_cobalt';
    50         -				power = 1.4;
           49  +				wandprops = { power = 1.4 };
    51     50   			};
    52     51   			iridium = {
    53     52   				item = 'sorcery:powder_iridium';
    54         -				sturdiness = 1.25;
    55         -				power = 1.25;
           53  +				wandprops = { sturdiness = 1.25, power = 1.25 };
    56     54   			};
    57     55   			lithium = {
    58     56   				item = 'sorcery:powder_lithium';
    59         -				power = 1.7;
    60         -				reliability = 0.85;
           57  +				wandprops = { power = 1.7, reliability = 0.70 };
    61     58   			};
    62     59   			gold = {
    63     60   				item = 'sorcery:powder_gold';
    64         -				duration = 1.3;
    65         -				power = 1.3;
           61  +				wandprops = { duration = 1.3, power = 1.3 };
    66     62   			};
    67     63   			tungsten = {
    68     64   				item = 'sorcery:powder_tungsten';
    69         -				duration = 1.7;
    70         -				sturdiness = 1.25;
           65  +				wandprops = { duration = 1.7, sturdiness = 1.25 };
           66  +			};
           67  +			platinum = {
           68  +				item = 'sorcery:powder_platinum';
           69  +				wandprops = { bond = 1; }
           70  +			};
           71  +			vidrium = {
           72  +				item = 'sorcery:powder_vidrium';
           73  +				wandprops = { bond = 2; }
    71     74   			};
    72         -			-- add one that only lets the first wielder
    73         -			-- ever use the wand
           75  +			impervium = {
           76  +				item = 'sorcery:powder_impervium';
           77  +				wandprops = { bond = 1, power = 1.5 };
           78  +			};
    74     79   		};
    75     80   		wire = {
    76     81   			gold = {
    77     82   				-- gold limits the amount of wear-and-tear on
    78     83   				-- the wand, but causes the power to weaken as
    79     84   				-- it empties
    80     85   				tone = u.color(255,255,59);
    81     86   				tex = u.image('default_gold_block.png');
           87  +				wandprops = { sturdiness = 1.2, weaken = 1 };
    82     88   			};
    83     89   			copper = {
    84     90   				-- copper causes the wand to recharge more quickly
    85     91   				-- but power levels are unpredictable
    86     92   				tone = u.color(255,117,40);
    87     93   				tex = u.image('default_copper_block.png');
           94  +				wandprops = { flux = 0.7, chargetime = 0.5 };
    88     95   			};
    89     96   			silver = {
    90     97   				tone = u.color(215,238,241);
    91     98   				tex = u.image('default_gold_block'):colorize(u.color(255,238,241), 255);
           99  +				wandprops = {};
    92    100   			};
    93    101   			steel = {
    94    102   				tone = u.color(255,255,255);
    95    103   				tex = u.image('default_steel_block');
          104  +				wandprops = {};
    96    105   			};
    97    106   		};
    98         -		gem = sorcery.data.gems;
          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  +		})
    99    115   	};
   100    116   	util = {
   101    117   		baseid = function(wand)
   102    118   			local elts = {wand.wood}
   103    119   			if wand.gem  ~= nil then elts[#elts + 1] = wand.gem end
   104    120   			if wand.wire ~= nil then elts[#elts + 1] = wand.wire end
   105    121   			return 'sorcery:wand_' .. table.concat(elts,'_')
................................................................................
   145    161   			local proto = stack:get_definition()._proto
   146    162   			local core = stack:get_meta():get_string('sorcery_wand_core')
   147    163   			if core ~= '' then
   148    164   				proto = table.copy(proto)
   149    165   				proto.core = core
   150    166   			end
   151    167   			return proto
          168  +		end;
          169  +		matprops = function(proto)
          170  +			local matprops = {}
          171  +			for k,v in pairs(proto) do
          172  +				if sorcery.wands.materials[k] then
          173  +					local mp = sorcery.wands.materials[k].wandprops
          174  +					if mp then
          175  +						matprops = sorcery.lib.tbl.deepmerge(matprops, mp,
          176  +							function(a,b,k)
          177  +								if key == 'bond'
          178  +									then return a+b
          179  +									else return a*b
          180  +								end
          181  +							end)
          182  +					end
          183  +				end
          184  +			end
          185  +			return matprops
   152    186   		end;
   153    187   		basedesc = function(wand)
   154    188   			local desc = 'wand fashioned from the wood of the ' .. wand.wood .. ' tree'
   155    189   			if wand.gem ~= nil then
   156    190   				desc = wand.gem .. '-tipped ' .. desc
   157    191   			end
   158    192   			if wand.wire ~= nil then
................................................................................
   182    216   local wand_cast = function(stack, user, target)
   183    217   	local meta = stack:get_meta()
   184    218   	local wand = sorcery.wands.util.getproto(stack)
   185    219   	if meta:contains('sorcery_wand_spell') == false then return nil end
   186    220   	local spell = meta:get_string('sorcery_wand_spell')
   187    221   	local castfn = sorcery.data.spells[spell].cast
   188    222   	if castfn == nil then return nil end
          223  +	local matprops = sorcery.wands.util.matprops(wand)
          224  +	if matprops.bond then
          225  +		local userct, found = 0, false
          226  +		for i=1,matprops.bond do
          227  +			local prop = 'bound_user_' .. tostring(i)
          228  +			if meta:contains(prop) then
          229  +				userct = i
          230  +				local name = meta:get_string(prop)
          231  +				print('wand bound to',name,i)
          232  +				if name == user:get_player_name() then found = true break end
          233  +			else break end
          234  +		end
          235  +		
          236  +		if not found then
          237  +			if userct < matprops.bond then
          238  +				print('binding wand to caster')
          239  +				minetest.sound_play("xdecor_enchanting", { --FIXME make own sounds
          240  +					pos = user:get_pos();
          241  +					gain = 0.8;
          242  +				})
          243  +				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(25,129,255), 2)
          244  +				meta:set_string('bound_user_' .. tostring(userct+1), user:get_player_name())
          245  +				return stack
          246  +			else
          247  +				-- user not in table AND no binding slots left. UH OH
          248  +				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(255,0,0), 4)
          249  +				sorcery.vfx.bloodburst(user:get_pos())
          250  +				user:punch(user, 1.0, {
          251  +					full_punch_interval = 1.0;
          252  +					damage_groups = { fleshy = math.random(1,5) };
          253  +				}, nil)
          254  +				return stack
          255  +			end
          256  +		end
          257  +	end
   189    258   
   190         -	local result = castfn {
          259  +	local uprops = user:get_properties();
          260  +	local context = {
   191    261   		base = wand;
   192    262   		meta = meta;
   193    263   		item = stack;
   194    264   		caster = user;
   195    265   		target = target;
          266  +		today = minetest.get_day_count();
   196    267   		heading = {
   197    268   			pos   = user:get_pos();
   198    269   			yaw   = user:get_look_dir();
   199    270   			pitch = user:get_look_vertical();
   200    271   			angle = user:get_look_horizontal();
          272  +			eyeheight = uprops.eye_height;
   201    273   		};
          274  +		wearmult = 1;
   202    275   	}
          276  +	local result = castfn(context)
   203    277   	if result ~= false then
   204    278   		minetest.sound_play(sorcery.data.spells[spell].sound or "default_item_smoke", { --FIXME make own sounds
   205    279   			pos = user:get_pos();
   206    280   			gain = 0.8;
   207    281   		})
   208    282   		-- minetest.add_particle {
   209    283   		-- 	pos = vector.add(vector.add(user:get_pos(), vector.multiply(user:get_look_dir(),1.1)), {y=1.6,z=0,x=0});
................................................................................
   214    288   		-- 	texture = u.image('sorcery_crackle.png'):multiply(u.color(sorcery.data.spells[spell].color):brighten(1.3)):render();
   215    289   		-- 	animation = {
   216    290   		-- 		type = 'vertical_frames';
   217    291   		-- 		aspect_w = 16, aspect_h = 16;
   218    292   		-- 		length = 0.6;
   219    293   		-- 	}
   220    294   		-- }
   221         -		stack:add_wear(sorcery.wands.util.wear(stack))
          295  +		local fac = matprops and matprops.sturdiness or 1
          296  +		stack:add_wear((sorcery.wands.util.wear(stack) / fac) * context.wearmult)
   222    297   	end
   223    298   	return stack
   224    299   end
   225    300   
   226    301   
   227    302   sorcery.wands.util.enumerate_kinds = function()
   228    303   	local addid = function(k)