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]
- 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 14 rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
15 15 -- how many grades of rune quality/power there are
16 16
17 17 amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' };
18 18 -- what kind of amulet each rune grade translates to
19 19
20 20 phial_kinds = {
21 - lesser = {grade = 1; name = 'Lesser'; infusion = 'sorcery:powder_brass'};
22 - simple = {grade = 2; name = 'Simple'; infusion = 'sorcery:powder_silver'};
23 - great = {grade = 3; name = 'Great'; infusion = 'sorcery:powder_gold'};
24 - splendid = {grade = 4; name = 'Splendid'; infusion = 'sorcery:powder_electrum'};
25 - exalted = {grade = 5; name = 'Exalted'; infusion = 'sorcery:powder_levitanium'};
26 - supreme = {grade = 6; name = 'Supreme'; infusion = 'sorcery:essence_force'};
21 + lesser = {grade = 1, name = 'Lesser'; infusion = 'sorcery:powder_brass';
22 + dist = { Fragile = 1, Weak = 0.7, Ordinary = 0.1, Pristine = 0.05, Sublime = 0.01 };
23 + };
24 + simple = {grade = 2, name = 'Simple'; infusion = 'sorcery:powder_silver';
25 + dist = { Fragile = 1, Weak = 0.8, Ordinary = 0.2, Pristine = 0.07, Sublime = 0.015 };
26 + };
27 + great = {grade = 3, name = 'Great'; infusion = 'sorcery:powder_gold';
28 + dist = { Fragile = 1, Weak = 0.9, Ordinary = 0.5, Pristine = 0.1, Sublime = 0.05 };
29 + };
30 + splendid = {grade = 4, name = 'Splendid'; infusion = 'sorcery:powder_electrum';
31 + dist = { Fragile = 1, Weak = 0.95, Ordinary = 0.7, Pristine = 0.3, Sublime = 0.1 };
32 + };
33 + exalted = {grade = 5, name = 'Exalted'; infusion = 'sorcery:powder_iridium';
34 + dist = { Fragile = 0, Weak = 1, Ordinary = 0.9, Pristine = 0.5, Sublime = 0.25 };
35 + };
36 + supreme = {grade = 6, name = 'Supreme'; infusion = 'sorcery:powder_levitanium';
37 + dist = { Fragile = 0, Weak = 0, Ordinary = 1, Pristine = 0.7, Sublime = 0.4 };
38 + };
27 39 };
28 40 }
29 41 local calc_phial_props = function(phial) --> mine interval: float, time factor: float
30 42 local g = phial:get_definition()._proto.data.grade
31 43 local i = constants.rune_mine_interval
32 44 local fac = (g-1) / 5
33 45 return i - ((i*0.5) * fac), 0.5 * fac
................................................................................
53 65 local f = string.format
54 66 local color = sorcery.lib.color(142,232,0)
55 67 local fac = p.grade / 6
56 68 local id = f('phial_%s', name);
57 69 sorcery.register_potion_tbl {
58 70 name = id;
59 71 label = f('%s Phial',p.name);
60 - 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.";
72 + 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.";
61 73 color = color:brighten(1 + fac*0.5);
62 74 imgvariant = (fac >= 5) and 'sparkle' or 'dull';
63 75 glow = 5+p.grade;
64 76 extra = {
65 77 groups = { sorcery_phial = p.grade };
66 78 _proto = { id = name, data = p };
67 79 };
................................................................................
196 208 end
197 209
198 210 sorcery.amulet.getspell = function(stack)
199 211 local m = stack:get_meta()
200 212 local proto = stack:get_definition()._sorcery.amulet
201 213 if not m:contains('amulet_rune') then return nil end
202 214 local rune = m:get_string('amulet_rune')
203 - local rg = m:get_string('amulet_rune_grade')
215 + local rg = m:get_int('amulet_rune_grade')
204 216 local rd = sorcery.data.runes[rune]
205 217 local spell = rd.amulets[proto.base]
206 218 if not spell then return nil end
207 219 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
208 220 local base_spell = true
209 221
210 222 if proto.frame and spell.frame and spell.frame[proto.frame] then
211 223 local sp = spell.frame[proto.frame]
212 - title = sp.name or title
213 - desc = sp.desc or desc
214 - cast = sp.desc or cast
215 - apply = sp.apply or apply
216 - remove = sp.remove or remove
217 - mingrade = sp.mingrade or remove
218 - base_spell = false
224 + if not sp.mingrade or rg >= sp.mingrade then
225 + title = sp.name or title
226 + desc = sp.desc or desc
227 + cast = sp.desc or cast
228 + apply = sp.apply or apply
229 + remove = sp.remove or remove
230 + mingrade = sp.mingrade or mingrade
231 + base_spell = false
232 + end
219 233 end
220 234
221 235 return {
222 236 rune = rune, grade = rg;
223 237 spell = spell, mingrade = mingrade;
224 238 name = title, desc = desc;
225 239 cast = cast, apply = apply, remove = remove;
................................................................................
237 251 local probe = sorcery.spell.probe(pos)
238 252
239 253 local pow_min = l.self.powerdraw >= l.self.minpower
240 254 local pow_max = l.self.powerdraw >= l.self.maxpower
241 255 local has_phial = function() return not i:is_empty('phial') end
242 256
243 257 if time and has_phial() and pow_min and not probe.disjunction then -- roll for runes
244 - local int, powerfac = calc_phial_props(i:get_stack('phial',1))
258 + local phial = i:get_stack('phial',1)
259 + local int, powerfac = calc_phial_props(phial)
245 260 local rolls = math.floor(time/int)
246 261 local newrunes = {}
247 262 for _=1,rolls do
248 263 local choices = {}
249 264 for name,rune in pairs(sorcery.data.runes) do
250 265 -- print('considering',name)
251 266 -- print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
................................................................................
267 282 end
268 283 -- print('rune choices:',dump(choices))
269 284 -- print('me',dump(l.self))
270 285 end
271 286
272 287 for _,r in pairs(newrunes) do
273 288 if i:room_for_item('cache',r) and has_phial() then
274 - local qual = math.random(#constants.rune_grades)
289 + local qual
290 + -- iterate through qualities from highest to lowest, rolling against the phial's
291 + -- distribution for each, and stopping when we find one
292 + local qdist = phial:get_definition()._proto.data.dist
293 + for i=#constants.rune_grades,1,-1 do
294 + local chance = qdist[constants.rune_grades[i]]
295 + if chance == 1 or math.random() <= chance then
296 + qual = i
297 + break
298 + end
299 + end
275 300 rune_set(r,{grade = qual})
276 301 i:add_item('cache',r)
277 302 -- consume a phial
278 303 local ph = i:get_stack('phial',1)
279 - local n = ph:get_name()
280 304 ph:take_item(1) i:set_stack('phial',1,ph)
281 - minetest.add_item(pos,i:add_item('refuse',ItemStack(sorcery.register.residue.db[n])))
305 + minetest.add_item(pos,i:add_item('refuse',ItemStack(sorcery.register.residue.db[ph:get_name()])))
282 306 else break end
283 307 end
284 308 end
285 309
286 310 has_phial = has_phial()
287 311 local spec = string.format([[
288 312 formspec_version[3] size[10.25,8] real_coordinates[true]