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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73









74
75
76
77
78
79
80
81

82
83
84
85
86
87

88
89
90
91

92
93
94
95

96
97
98







99
100
101
102
103
104
105
...
145
146
147
148
149
150
151


















152
153
154
155
156
157
158
...
182
183
184
185
186
187
188












189
190

























191
192
193
194
195

196
197
198
199
200

201

202

203
204
205
206
207
208
209
...
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
				tree = 'default:jungletree';
				plank = 'default:junglewood';
			};
		};
		core = {
			obsidian = {
				item = 'default:obsidian_shard';
				sturdiness = 1.5;
			};
			diamond = {
				item = 'sorcery:shard_diamond';
				sturdiness = 1.7;
				reliability = 0.75;
			};
			mese = {
				item = 'default:mese_fragment';
				generate = 2;
			};
			cobalt = {
				item = 'sorcery:powder_cobalt';
				power = 1.4;
			};
			iridium = {
				item = 'sorcery:powder_iridium';
				sturdiness = 1.25;
				power = 1.25;
			};
			lithium = {
				item = 'sorcery:powder_lithium';
				power = 1.7;
				reliability = 0.85;
			};
			gold = {
				item = 'sorcery:powder_gold';
				duration = 1.3;
				power = 1.3;
			};
			tungsten = {
				item = 'sorcery:powder_tungsten';
				duration = 1.7;
				sturdiness = 1.25;
			};

			-- add one that only lets the first wielder
			-- ever use the wand









		};
		wire = {
			gold = {
				-- gold limits the amount of wear-and-tear on
				-- the wand, but causes the power to weaken as
				-- it empties
				tone = u.color(255,255,59);
				tex = u.image('default_gold_block.png');

			};
			copper = {
				-- copper causes the wand to recharge more quickly
				-- but power levels are unpredictable
				tone = u.color(255,117,40);
				tex = u.image('default_copper_block.png');

			};
			silver = {
				tone = u.color(215,238,241);
				tex = u.image('default_gold_block'):colorize(u.color(255,238,241), 255);

			};
			steel = {
				tone = u.color(255,255,255);
				tex = u.image('default_steel_block');

			};
		};
		gem = sorcery.data.gems;







	};
	util = {
		baseid = function(wand)
			local elts = {wand.wood}
			if wand.gem  ~= nil then elts[#elts + 1] = wand.gem end
			if wand.wire ~= nil then elts[#elts + 1] = wand.wire end
			return 'sorcery:wand_' .. table.concat(elts,'_')
................................................................................
			local proto = stack:get_definition()._proto
			local core = stack:get_meta():get_string('sorcery_wand_core')
			if core ~= '' then
				proto = table.copy(proto)
				proto.core = core
			end
			return proto


















		end;
		basedesc = function(wand)
			local desc = 'wand fashioned from the wood of the ' .. wand.wood .. ' tree'
			if wand.gem ~= nil then
				desc = wand.gem .. '-tipped ' .. desc
			end
			if wand.wire ~= nil then
................................................................................
local wand_cast = function(stack, user, target)
	local meta = stack:get_meta()
	local wand = sorcery.wands.util.getproto(stack)
	if meta:contains('sorcery_wand_spell') == false then return nil end
	local spell = meta:get_string('sorcery_wand_spell')
	local castfn = sorcery.data.spells[spell].cast
	if castfn == nil then return nil end













	local result = castfn {

























		base = wand;
		meta = meta;
		item = stack;
		caster = user;
		target = target;

		heading = {
			pos   = user:get_pos();
			yaw   = user:get_look_dir();
			pitch = user:get_look_vertical();
			angle = user:get_look_horizontal();

		};

	}

	if result ~= false then
		minetest.sound_play(sorcery.data.spells[spell].sound or "default_item_smoke", { --FIXME make own sounds
			pos = user:get_pos();
			gain = 0.8;
		})
		-- minetest.add_particle {
		-- 	pos = vector.add(vector.add(user:get_pos(), vector.multiply(user:get_look_dir(),1.1)), {y=1.6,z=0,x=0});
................................................................................
		-- 	texture = u.image('sorcery_crackle.png'):multiply(u.color(sorcery.data.spells[spell].color):brighten(1.3)):render();
		-- 	animation = {
		-- 		type = 'vertical_frames';
		-- 		aspect_w = 16, aspect_h = 16;
		-- 		length = 0.6;
		-- 	}
		-- }

		stack:add_wear(sorcery.wands.util.wear(stack))
	end
	return stack
end


sorcery.wands.util.enumerate_kinds = function()
	local addid = function(k)







|



|
<



|



|



|
<



<
|



|
<



<
|

>
|
|
>
>
>
>
>
>
>
>
>








>






>




>




>


|
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>





>

>

>







 







>
|







30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53

54
55
56

57
58
59
60
61

62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
				tree = 'default:jungletree';
				plank = 'default:junglewood';
			};
		};
		core = {
			obsidian = {
				item = 'default:obsidian_shard';
				wandprops = { sturdiness = 1.5 };
			};
			diamond = {
				item = 'sorcery:shard_diamond';
				wandprops = { sturdiness = 1.7, reliability = 0.85 };

			};
			mese = {
				item = 'default:mese_fragment';
				wandprops = { generate = 2 };
			};
			cobalt = {
				item = 'sorcery:powder_cobalt';
				wandprops = { power = 1.4 };
			};
			iridium = {
				item = 'sorcery:powder_iridium';
				wandprops = { sturdiness = 1.25, power = 1.25 };

			};
			lithium = {
				item = 'sorcery:powder_lithium';

				wandprops = { power = 1.7, reliability = 0.70 };
			};
			gold = {
				item = 'sorcery:powder_gold';
				wandprops = { duration = 1.3, power = 1.3 };

			};
			tungsten = {
				item = 'sorcery:powder_tungsten';

				wandprops = { duration = 1.7, sturdiness = 1.25 };
			};
			platinum = {
				item = 'sorcery:powder_platinum';
				wandprops = { bond = 1; }
			};
			vidrium = {
				item = 'sorcery:powder_vidrium';
				wandprops = { bond = 2; }
			};
			impervium = {
				item = 'sorcery:powder_impervium';
				wandprops = { bond = 1, power = 1.5 };
			};
		};
		wire = {
			gold = {
				-- gold limits the amount of wear-and-tear on
				-- the wand, but causes the power to weaken as
				-- it empties
				tone = u.color(255,255,59);
				tex = u.image('default_gold_block.png');
				wandprops = { sturdiness = 1.2, weaken = 1 };
			};
			copper = {
				-- copper causes the wand to recharge more quickly
				-- but power levels are unpredictable
				tone = u.color(255,117,40);
				tex = u.image('default_copper_block.png');
				wandprops = { flux = 0.7, chargetime = 0.5 };
			};
			silver = {
				tone = u.color(215,238,241);
				tex = u.image('default_gold_block'):colorize(u.color(255,238,241), 255);
				wandprops = {};
			};
			steel = {
				tone = u.color(255,255,255);
				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) };
			};
		})
	};
	util = {
		baseid = function(wand)
			local elts = {wand.wood}
			if wand.gem  ~= nil then elts[#elts + 1] = wand.gem end
			if wand.wire ~= nil then elts[#elts + 1] = wand.wire end
			return 'sorcery:wand_' .. table.concat(elts,'_')
................................................................................
			local proto = stack:get_definition()._proto
			local core = stack:get_meta():get_string('sorcery_wand_core')
			if core ~= '' then
				proto = table.copy(proto)
				proto.core = core
			end
			return proto
		end;
		matprops = function(proto)
			local matprops = {}
			for k,v in pairs(proto) do
				if sorcery.wands.materials[k] then
					local mp = sorcery.wands.materials[k].wandprops
					if mp then
						matprops = sorcery.lib.tbl.deepmerge(matprops, mp,
							function(a,b,k)
								if key == 'bond'
									then return a+b
									else return a*b
								end
							end)
					end
				end
			end
			return matprops
		end;
		basedesc = function(wand)
			local desc = 'wand fashioned from the wood of the ' .. wand.wood .. ' tree'
			if wand.gem ~= nil then
				desc = wand.gem .. '-tipped ' .. desc
			end
			if wand.wire ~= nil then
................................................................................
local wand_cast = function(stack, user, target)
	local meta = stack:get_meta()
	local wand = sorcery.wands.util.getproto(stack)
	if meta:contains('sorcery_wand_spell') == false then return nil end
	local spell = meta:get_string('sorcery_wand_spell')
	local castfn = sorcery.data.spells[spell].cast
	if castfn == nil then return nil end
	local matprops = sorcery.wands.util.matprops(wand)
	if matprops.bond then
		local userct, found = 0, false
		for i=1,matprops.bond do
			local prop = 'bound_user_' .. tostring(i)
			if meta:contains(prop) then
				userct = i
				local name = meta:get_string(prop)
				print('wand bound to',name,i)
				if name == user:get_player_name() then found = true break end
			else break end
		end
		

		if not found then
			if userct < matprops.bond then
				print('binding wand to caster')
				minetest.sound_play("xdecor_enchanting", { --FIXME make own sounds
					pos = user:get_pos();
					gain = 0.8;
				})
				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(25,129,255), 2)
				meta:set_string('bound_user_' .. tostring(userct+1), user:get_player_name())
				return stack
			else
				-- user not in table AND no binding slots left. UH OH
				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(255,0,0), 4)
				sorcery.vfx.bloodburst(user:get_pos())
				user:punch(user, 1.0, {
					full_punch_interval = 1.0;
					damage_groups = { fleshy = math.random(1,5) };
				}, nil)
				return stack
			end
		end
	end

	local uprops = user:get_properties();
	local context = {
		base = wand;
		meta = meta;
		item = stack;
		caster = user;
		target = target;
		today = minetest.get_day_count();
		heading = {
			pos   = user:get_pos();
			yaw   = user:get_look_dir();
			pitch = user:get_look_vertical();
			angle = user:get_look_horizontal();
			eyeheight = uprops.eye_height;
		};
		wearmult = 1;
	}
	local result = castfn(context)
	if result ~= false then
		minetest.sound_play(sorcery.data.spells[spell].sound or "default_item_smoke", { --FIXME make own sounds
			pos = user:get_pos();
			gain = 0.8;
		})
		-- minetest.add_particle {
		-- 	pos = vector.add(vector.add(user:get_pos(), vector.multiply(user:get_look_dir(),1.1)), {y=1.6,z=0,x=0});
................................................................................
		-- 	texture = u.image('sorcery_crackle.png'):multiply(u.color(sorcery.data.spells[spell].color):brighten(1.3)):render();
		-- 	animation = {
		-- 		type = 'vertical_frames';
		-- 		aspect_w = 16, aspect_h = 16;
		-- 		length = 0.6;
		-- 	}
		-- }
		local fac = matprops and matprops.sturdiness or 1
		stack:add_wear((sorcery.wands.util.wear(stack) / fac) * context.wearmult)
	end
	return stack
end


sorcery.wands.util.enumerate_kinds = function()
	local addid = function(k)