sorcery  Diff

Differences From Artifact [e97e283f3c]:

To Artifact [c8e0c3ac03]:


     1      1   -- TODO make some kind of disposable "filter" tool that runeforges require 
     2      2   -- to generate runes and that wears down over time, to make amulets more
     3      3   -- expensive than they currently are? the existing system is neat but
     4      4   -- i think amulets are a little overpowered for something that just
     5      5   -- passively consumes ley-current
     6      6   
     7      7   local constants = {
     8         -	rune_mine_interval = 250;
            8  +	rune_mine_interval = 240;
     9      9   	-- how often a powered forge rolls for new runes
    10     10   
    11     11   	rune_cache_max = 4;
    12     12   	-- how many runes a runeforge can hold at a time
    13     13   	
    14     14   	rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
    15     15   	-- how many grades of rune quality/power there are
................................................................................
    23     23   		great    = {grade = 3; name = 'Great';    infusion = 'sorcery:powder_gold'};
    24     24   		splendid = {grade = 4; name = 'Splendid'; infusion = 'sorcery:powder_electrum'};
    25     25   		exalted  = {grade = 5; name = 'Exalted';  infusion = 'sorcery:powder_levitanium'};
    26     26   		supreme  = {grade = 6; name = 'Supreme';  infusion = 'sorcery:essence_force'};
    27     27   	};
    28     28   }
    29     29   local calc_phial_props = function(phial) --> mine interval: float, time factor: float
    30         -	local g = phial:get_definition()._proto.grade
           30  +	local g = phial:get_definition()._proto.data.grade
    31     31   	local i = constants.rune_mine_interval 
    32     32   	local fac = (g-1) / 5
    33     33   	return i - ((i*0.5) * fac), 0.5 * fac
    34     34   end
    35     35   sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune)
    36     36   	local id = 'sorcery:rune_' .. name
    37     37   	rune.image = rune.image or string.format('sorcery_rune_%s.png',name)
................................................................................
    47     47   		};
    48     48   		_proto = { id = name, data = rune; };
    49     49   	})
    50     50   end)
    51     51   
    52     52   for name,p in pairs(constants.phial_kinds) do
    53     53   	local f = string.format
    54         -	local color = sorcery.lib.color(255,27,188)
           54  +	local color = sorcery.lib.color(204,38,235)
    55     55   	local fac = p.grade / 6
    56     56   	local id = f('phial_%s', name);
    57     57   	sorcery.register_potion_tbl {
    58     58   		name = id;
    59     59   		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.";
           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.";
    61     61   		color = color:brighten(1 + fac*0.5);
    62     62   		imgvariant = (fac >= 5) and 'sparkle' or 'dull';
    63     63   		glow = 5+p.grade;
    64     64   		extra = {
    65     65   			groups = { sorcery_phial = p.grade };
    66     66   			_proto = { id = name, data = p };
    67     67   		};
    68     68   	}
    69     69   	sorcery.register.infusions.link {
    70     70   		infuse = p.infusion;
    71     71   		into = 'sorcery:potion_subtle';
    72         -		output = id;
           72  +		output = 'sorcery:'..id;
    73     73   	}
    74     74   end
    75     75   
    76     76   local register_rune_wrench = function(w)
    77     77   	local mp = sorcery.data.metals[w.metal].parts
    78     78   	minetest.register_tool(w.name, {
    79     79   		description = w.desc;
................................................................................
    89     89   		};
    90     90   	})
    91     91   	minetest.register_craft {
    92     92   		output = w.name;
    93     93   		recipe = {
    94     94   			{'',                        mp.fragment,''};
    95     95   			{'',                        mp.ingot,   mp.fragment};
    96         -			{'sorcery:vidrium_fragment','',         ''};
           96  +			{'sorcery:fragment_vidrium','',         ''};
    97     97   		};
    98     98   	}
    99     99   end
   100    100   
   101    101   register_rune_wrench {
   102    102   	name = 'sorcery:rune_wrench', desc = 'Rune Wrench';
   103    103   	img = 'sorcery_rune_wrench.png', metal = 'brass';
................................................................................
   132    132   	if rune then
   133    133   		local rp = rune:get_definition()._proto
   134    134   		local rg = rune:get_meta():get_int('rune_grade')
   135    135   		m:set_string('amulet_rune', rp.id)
   136    136   		m:set_int('amulet_rune_grade', rg)
   137    137   		local spell = sorcery.amulet.getspell(stack)
   138    138   		if not spell then return nil end
   139         -
   140         -		local name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name)
          139  +		local name
          140  +		if spell.minrune then -- indicating quality makes less sense if it's restricted
          141  +			name = string.format('Amulet of %s', spell.name)
          142  +		else
          143  +			name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name)
          144  +		end
   141    145   		m:set_string('description', sorcery.lib.ui.tooltip {
   142    146   			title = name;
   143    147   			color = spell.tone;
   144    148   			desc = spell.desc;
   145    149   		})
   146    150   
   147    151   		if spell.apply then spell.apply {
................................................................................
   196    200   	local proto = stack:get_definition()._sorcery.amulet
   197    201   	if not m:contains('amulet_rune') then return nil end
   198    202   	local rune = m:get_string('amulet_rune')
   199    203   	local rg = m:get_string('amulet_rune_grade')
   200    204   	local rd = sorcery.data.runes[rune]
   201    205   	local spell = rd.amulets[proto.base]
   202    206   	if not spell then return nil end
   203         -	local title,desc,cast,apply,remove = spell.name, spell.desc, spell.cast, spell.apply, spell.remove -- FIXME in serious need of refactoring
          207  +	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
   204    208   	local base_spell = true
   205    209   
   206    210   	if proto.frame and spell.frame and spell.frame[proto.frame] then
   207    211   		local sp = spell.frame[proto.frame]
   208    212   		title = sp.name or title
   209    213   		desc = sp.desc or desc
   210    214   		cast = sp.desc or cast
   211    215   		apply = sp.apply or apply
   212    216   		remove = sp.remove or remove
          217  +		mingrade = sp.mingrade or remove
   213    218   		base_spell = false
   214    219   	end
   215    220   	
   216    221   	return {
   217         -		rune = rune;
   218         -		grade = rg;
   219         -		spell = spell;
          222  +		rune = rune, grade = rg;
          223  +		spell = spell, mingrade = mingrade;
   220    224   		name = title, desc = desc;
   221    225   		cast = cast, apply = apply, remove = remove;
   222    226   		frame = proto.frame;
   223    227   		framestats = proto.frame and sorcery.data.metals[proto.frame].amulet;
   224    228   		tone = sorcery.lib.color(rd.tone);
   225    229   		base_spell = base_spell;
   226    230   	}
................................................................................
   233    237   	local l = sorcery.ley.netcaps(pos,time or 1)
   234    238   
   235    239   	local pow_min = l.self.powerdraw >= l.self.minpower
   236    240   	local pow_max = l.self.powerdraw >= l.self.maxpower
   237    241   	local has_phial = function() return not i:is_empty('phial') end
   238    242   
   239    243   	if time and has_phial() and pow_min then -- roll for runes
   240         -		local rolls = math.floor(time/calc_phial_props(i:get_stack('phial',1)))
          244  +		local int, powerfac = calc_phial_props(i:get_stack('phial',1))
          245  +		local rolls = math.floor(time/int)
   241    246   		local newrunes = {}
   242    247   		for _=1,rolls do
   243    248   			local choices = {}
   244    249   			for name,rune in pairs(sorcery.data.runes) do
   245         -				if rune.minpower*time <= l.self.powerdraw and math.random(rune.rarity) == 1 then
          250  +				print('considering',name)
          251  +				print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
          252  +				if (rune.minpower*powerfac)*time <= l.self.powerdraw and math.random(rune.rarity) == 1 then
   246    253   					local n = ItemStack(rune.item)
   247    254   					choices[#choices + 1] = n
   248    255   				end
   249    256   			end
   250    257   			if #choices > 0 then newrunes[#newrunes + 1] = choices[math.random(#choices)] end
          258  +			print('rune choices:',dump(choices))
          259  +			print('me',dump(l.self))
   251    260   		end
   252    261   
   253    262   		for _,r in pairs(newrunes) do
   254    263   			if i:room_for_item('cache',r) and has_phial() then
   255    264   				local qual = math.random(#constants.rune_grades)
   256    265   				rune_set(r,{grade = qual})
   257    266   				i:add_item('cache',r)
................................................................................
   442    451   	allow_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
   443    452   		local inv = minetest.get_meta(pos):get_inventory()
   444    453   		local wrench if not inv:is_empty('wrench') then
   445    454   			wrench = inv:get_stack('wrench',1):get_definition()._proto
   446    455   		end
   447    456   		if fl == 'cache' then
   448    457   			if tl == 'cache' then return 1 end
   449         -			if tl == 'active' then
          458  +			if tl == 'active' and inv:is_empty('active') then
   450    459   				print(dump(wrench))
   451    460   				if wrench and wrench.powers.imbue and not inv:is_empty('amulet') then
   452    461   					local amulet = inv:get_stack('amulet',1)
   453    462   					local rune = inv:get_stack(fl,fi)
   454         -					if sorcery.data.runes[rune:get_definition()._proto.id].amulets[amulet:get_definition()._sorcery.amulet.base] then
   455         -						return 1
          463  +					local runeid = rune:get_definition()._proto.id
          464  +					local runegrade = rune:get_meta():get_int('rune_grade')
          465  +					if sorcery.data.runes[runeid].amulets[amulet:get_definition()._sorcery.amulet.base] then
          466  +						local spell do -- haaaack
          467  +							local i=ItemStack(amulet:get_name())
          468  +							local im = i:get_meta()
          469  +							im:set_string('amulet_rune',runeid)
          470  +							im:set_int('amulet_rune_grade',runegrade)
          471  +							spell = sorcery.amulet.getspell(i)
          472  +						end
          473  +						if not spell.mingrade or runegrade >= spell.mingrade then
          474  +							return 1
          475  +						end
   456    476   					end
   457    477   				end
   458    478   			end
   459    479   		end
   460    480   		if fl == 'active' then
   461    481   			if tl == 'cache' and wrench and (wrench.powers.extract or wrench.powers.purge) then return 1 end
   462    482   		end