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