sorcery  Diff

Differences From Artifact [f2cf52d41a]:

  • File runeforge.lua — part of check-in [147592b8e9] at 2020-10-26 03:58:08 on branch trunk — add over-time spellcasting abstraction to enable metamagic and in particular disjunction, add more animations and sound effects, add excavation spell, possibly some others, forget when the last commit was, edit a bunch of magitech to make it subject to the disjunction mechanism (throw up a disjunction aura and waltz right through those force fields bby, wheee), also illumination spells, tweak runeforge and rune frequence to better the balance and also limit player frustration, move some math functions into their own library category, various tweaks and bugfixes, probably other shit i don't remember (user: lexi, size: 16843) [annotate] [blame] [check-ins using]

To Artifact [4e5c236dfa]:

  • File runeforge.lua — part of check-in [15f176a7fe] at 2020-10-31 19:49:49 on branch trunk — add background noise for condensers (temporary hack, need to write a proper environment sound framework as the fucking env_sounds module is completely impossible to extend), fix a couple of really stupid bugs, make higher-quality phials increase the chance of getting good runes so it's not a complete waste to burn iridium or levitanium powder on making them, add targeted disjunction and some other amulet spells (user: lexi, size: 17874) [annotate] [blame] [check-ins using]

14
15
16
17
18
19
20
21


22


23


24


25


26


27
28
29
30
31
32
33
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218

219
220
221
222
223
224
225
...
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
...
267
268
269
270
271
272
273




274






275
276
277
278
279
280
281
282
283
284
285
286
287
288
	rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
	-- how many grades of rune quality/power there are
	
	amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' };
	-- what kind of amulet each rune grade translates to
	
	phial_kinds = {
		lesser   = {grade = 1; name = 'Lesser';   infusion = 'sorcery:powder_brass'};


		simple   = {grade = 2; name = 'Simple';   infusion = 'sorcery:powder_silver'};


		great    = {grade = 3; name = 'Great';    infusion = 'sorcery:powder_gold'};


		splendid = {grade = 4; name = 'Splendid'; infusion = 'sorcery:powder_electrum'};


		exalted  = {grade = 5; name = 'Exalted';  infusion = 'sorcery:powder_levitanium'};


		supreme  = {grade = 6; name = 'Supreme';  infusion = 'sorcery:essence_force'};


	};
}
local calc_phial_props = function(phial) --> mine interval: float, time factor: float
	local g = phial:get_definition()._proto.data.grade
	local i = constants.rune_mine_interval 
	local fac = (g-1) / 5
	return i - ((i*0.5) * fac), 0.5 * fac
................................................................................
	local f = string.format
	local color = sorcery.lib.color(142,232,0)
	local fac = p.grade / 6
	local id = f('phial_%s', name);
	sorcery.register_potion_tbl {
		name = id;
		label = f('%s Phial',p.name);
		desc = "A powerful liquid consumed in the operation of a rune forge. Its quality determines how fast new runes can be constructed and how much energy is required by the process.";
		color = color:brighten(1 + fac*0.5);
		imgvariant = (fac >= 5) and 'sparkle' or 'dull';
		glow = 5+p.grade;
		extra = {
			groups = { sorcery_phial = p.grade };
			_proto = { id = name, data = p };
		};
................................................................................
end

sorcery.amulet.getspell = function(stack)
	local m = stack:get_meta()
	local proto = stack:get_definition()._sorcery.amulet
	if not m:contains('amulet_rune') then return nil end
	local rune = m:get_string('amulet_rune')
	local rg = m:get_string('amulet_rune_grade')
	local rd = sorcery.data.runes[rune]
	local spell = rd.amulets[proto.base]
	if not spell then return nil end
	local title,desc,cast,apply,remove,mingrade = spell.name, spell.desc, spell.cast, spell.apply, spell.remove, spell.mingrade -- FIXME in serious need of refactoring
	local base_spell = true

	if proto.frame and spell.frame and spell.frame[proto.frame] then
		local sp = spell.frame[proto.frame]

		title = sp.name or title
		desc = sp.desc or desc
		cast = sp.desc or cast
		apply = sp.apply or apply
		remove = sp.remove or remove
		mingrade = sp.mingrade or remove
		base_spell = false

	end
	
	return {
		rune = rune, grade = rg;
		spell = spell, mingrade = mingrade;
		name = title, desc = desc;
		cast = cast, apply = apply, remove = remove;
................................................................................
	local probe = sorcery.spell.probe(pos)

	local pow_min = l.self.powerdraw >= l.self.minpower
	local pow_max = l.self.powerdraw >= l.self.maxpower
	local has_phial = function() return not i:is_empty('phial') end

	if time and has_phial() and pow_min and not probe.disjunction then -- roll for runes

		local int, powerfac = calc_phial_props(i:get_stack('phial',1))
		local rolls = math.floor(time/int)
		local newrunes = {}
		for _=1,rolls do
			local choices = {}
			for name,rune in pairs(sorcery.data.runes) do
				-- print('considering',name)
				-- print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
................................................................................
			end
			-- print('rune choices:',dump(choices))
			-- print('me',dump(l.self))
		end

		for _,r in pairs(newrunes) do
			if i:room_for_item('cache',r) and has_phial() then




				local qual = math.random(#constants.rune_grades)






				rune_set(r,{grade = qual})
				i:add_item('cache',r)
				-- consume a phial
				local ph = i:get_stack('phial',1)
				local n = ph:get_name()
				ph:take_item(1) i:set_stack('phial',1,ph)
				minetest.add_item(pos,i:add_item('refuse',ItemStack(sorcery.register.residue.db[n])))
			else break end
		end
	end

	has_phial = has_phial()
	local spec = string.format([[
		formspec_version[3] size[10.25,8] real_coordinates[true]







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







 







|







 







|








>
|
|
|
|
|
|
|
>







 







>
|







 







>
>
>
>
|
>
>
>
>
>
>




<

|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
	rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
	-- how many grades of rune quality/power there are
	
	amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' };
	-- what kind of amulet each rune grade translates to
	
	phial_kinds = {
		lesser   = {grade = 1, name = 'Lesser';   infusion = 'sorcery:powder_brass';
			dist = { Fragile = 1, Weak = 0.7,  Ordinary = 0.1, Pristine = 0.05, Sublime = 0.01 };
		};
		simple   = {grade = 2, name = 'Simple';   infusion = 'sorcery:powder_silver';
			dist = { Fragile = 1, Weak = 0.8,  Ordinary = 0.2, Pristine = 0.07, Sublime = 0.015 };
		};
		great    = {grade = 3, name = 'Great';    infusion = 'sorcery:powder_gold';
			dist = { Fragile = 1, Weak = 0.9,  Ordinary = 0.5, Pristine = 0.1,  Sublime = 0.05 };
		};
		splendid = {grade = 4, name = 'Splendid'; infusion = 'sorcery:powder_electrum';
			dist = { Fragile = 1, Weak = 0.95, Ordinary = 0.7, Pristine = 0.3,  Sublime = 0.1 };
		};
		exalted  = {grade = 5, name = 'Exalted';  infusion = 'sorcery:powder_iridium';
			dist = { Fragile = 0, Weak = 1,    Ordinary = 0.9, Pristine = 0.5,  Sublime = 0.25 };
		};
		supreme  = {grade = 6, name = 'Supreme';  infusion = 'sorcery:powder_levitanium';
			dist = { Fragile = 0, Weak = 0,    Ordinary = 1,   Pristine = 0.7,  Sublime = 0.4 };
		};
	};
}
local calc_phial_props = function(phial) --> mine interval: float, time factor: float
	local g = phial:get_definition()._proto.data.grade
	local i = constants.rune_mine_interval 
	local fac = (g-1) / 5
	return i - ((i*0.5) * fac), 0.5 * fac
................................................................................
	local f = string.format
	local color = sorcery.lib.color(142,232,0)
	local fac = p.grade / 6
	local id = f('phial_%s', name);
	sorcery.register_potion_tbl {
		name = id;
		label = f('%s Phial',p.name);
		desc = "A powerful liquid consumed in the operation of a rune forge. Its quality determines how fast new runes can be constructed and how much energy is required by the process, and affects your odds of getting a high-quality rune.";
		color = color:brighten(1 + fac*0.5);
		imgvariant = (fac >= 5) and 'sparkle' or 'dull';
		glow = 5+p.grade;
		extra = {
			groups = { sorcery_phial = p.grade };
			_proto = { id = name, data = p };
		};
................................................................................
end

sorcery.amulet.getspell = function(stack)
	local m = stack:get_meta()
	local proto = stack:get_definition()._sorcery.amulet
	if not m:contains('amulet_rune') then return nil end
	local rune = m:get_string('amulet_rune')
	local rg = m:get_int('amulet_rune_grade')
	local rd = sorcery.data.runes[rune]
	local spell = rd.amulets[proto.base]
	if not spell then return nil end
	local title,desc,cast,apply,remove,mingrade = spell.name, spell.desc, spell.cast, spell.apply, spell.remove, spell.mingrade -- FIXME in serious need of refactoring
	local base_spell = true

	if proto.frame and spell.frame and spell.frame[proto.frame] then
		local sp = spell.frame[proto.frame]
		if not sp.mingrade or rg >= sp.mingrade then
			title = sp.name or title
			desc = sp.desc or desc
			cast = sp.desc or cast
			apply = sp.apply or apply
			remove = sp.remove or remove
			mingrade = sp.mingrade or mingrade
			base_spell = false
		end
	end
	
	return {
		rune = rune, grade = rg;
		spell = spell, mingrade = mingrade;
		name = title, desc = desc;
		cast = cast, apply = apply, remove = remove;
................................................................................
	local probe = sorcery.spell.probe(pos)

	local pow_min = l.self.powerdraw >= l.self.minpower
	local pow_max = l.self.powerdraw >= l.self.maxpower
	local has_phial = function() return not i:is_empty('phial') end

	if time and has_phial() and pow_min and not probe.disjunction then -- roll for runes
		local phial = i:get_stack('phial',1)
		local int, powerfac = calc_phial_props(phial)
		local rolls = math.floor(time/int)
		local newrunes = {}
		for _=1,rolls do
			local choices = {}
			for name,rune in pairs(sorcery.data.runes) do
				-- print('considering',name)
				-- print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
................................................................................
			end
			-- print('rune choices:',dump(choices))
			-- print('me',dump(l.self))
		end

		for _,r in pairs(newrunes) do
			if i:room_for_item('cache',r) and has_phial() then
				local qual
				-- iterate through qualities from highest to lowest, rolling against the phial's
				-- distribution for each, and stopping when we find one
				local qdist = phial:get_definition()._proto.data.dist
				for i=#constants.rune_grades,1,-1 do
					local chance = qdist[constants.rune_grades[i]]
					if chance == 1 or math.random() <= chance then
						qual = i
						break
					end
				end
				rune_set(r,{grade = qual})
				i:add_item('cache',r)
				-- consume a phial
				local ph = i:get_stack('phial',1)

				ph:take_item(1) i:set_stack('phial',1,ph)
				minetest.add_item(pos,i:add_item('refuse',ItemStack(sorcery.register.residue.db[ph:get_name()])))
			else break end
		end
	end

	has_phial = has_phial()
	local spec = string.format([[
		formspec_version[3] size[10.25,8] real_coordinates[true]