sorcery  Diff

Differences From Artifact [b7d5d6135c]:

To Artifact [dd6f797d8b]:


     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   --  -- are phials & rune-wrenches enough for this now?
     7      7   
     8      8   local constants = {
     9         -	rune_mine_interval = 240;
            9  +	rune_mine_interval = 180;
    10     10   	-- how often a powered forge rolls for new runes
    11     11   
    12     12   	rune_cache_max = 6;
    13     13   	-- how many runes a runeforge can hold at a time
    14     14   	
    15     15   	rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
    16     16   	-- how many grades of rune quality/power there are
................................................................................
    40     40   	};
    41     41   }
    42     42   local calc_phial_props = function(phial) --> mine interval: float, power factor: float
    43     43   	local m = phial:get_meta()
    44     44   	local g = phial:get_definition()._proto.data.grade
    45     45   	local i = constants.rune_mine_interval 
    46     46   	local fac = (g-1) / 5
    47         -	fac = fac + 0.2 * m:get_int('speed')
           47  +	fac = fac + 0.1 * m:get_int('speed')
    48     48   	return math.max(3,i - ((i*0.5) * fac)), 0.5 * fac
    49     49   end
    50     50   sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune)
    51     51   	local id = 'sorcery:rune_' .. name
    52     52   	rune.image = rune.image or string.format('sorcery_rune_%s.png',name)
    53     53   	rune.item = id
    54     54   	local c = sorcery.lib.color(rune.tone)
................................................................................
   226    226   	local proto = stack:get_definition()._sorcery.amulet
   227    227   	if not m:contains('amulet_rune') then return nil end
   228    228   	local rune = m:get_string('amulet_rune')
   229    229   	local rg = m:get_int('amulet_rune_grade')
   230    230   	local rd = sorcery.data.runes[rune]
   231    231   	local spell = rd.amulets[proto.base]
   232    232   	if not spell then return nil end
   233         -	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
          233  +	local title,desc,cast,apply,remove,mingrade,sound = spell.name, spell.desc, spell.cast, spell.apply, spell.remove, spell.mingrade,spell.sound -- FIXME in serious need of refactoring
   234    234   	local base_spell = true
   235    235   
   236    236   	if proto.frame and spell.frame and spell.frame[proto.frame] then
   237    237   		local sp = spell.frame[proto.frame]
   238    238   		if not sp.mingrade or rg >= sp.mingrade then
   239    239   			title = sp.name or title
   240    240   			desc = sp.desc or desc
   241    241   			cast = sp.cast or cast
   242    242   			apply = sp.apply or apply
   243    243   			remove = sp.remove or remove
   244    244   			mingrade = sp.mingrade or mingrade
          245  +			sound = sp.sound or sound
   245    246   			base_spell = false
   246    247   		end
   247    248   	end
   248    249   	
          250  +	-- PLEASE, GOD, REFACTOR ME
   249    251   	return {
   250    252   		rune = rune, grade = rg;
   251    253   		spell = spell, mingrade = mingrade;
   252         -		name = title, desc = desc;
          254  +		name = title, desc = desc, sound = sound;
   253    255   		cast = cast, apply = apply, remove = remove;
   254    256   		frame = proto.frame;
   255    257   		framestats = proto.frame and sorcery.data.metals[proto.frame].amulet;
   256    258   		tone = sorcery.lib.color(rd.tone);
   257    259   		base_spell = base_spell;
   258    260   	}
   259    261   end
................................................................................
   271    273   	if time and has_phial() and pow_min and not probe.disjunction then -- roll for runes
   272    274   		local phial = i:get_stack('phial',1)
   273    275   		local int, powerfac = calc_phial_props(phial)
   274    276   		local pf = phial:get_meta():get_int('force')
   275    277   		local rolls = math.floor(time/int)
   276    278   		local newrunes = {}
   277    279   		for _=1,rolls do
          280  +			print('--- rune roll',_,'pf',pf)
   278    281   			local choices = {}
   279    282   			for name,rune in pairs(sorcery.data.runes) do
   280         -				-- print('considering',name)
   281         -				-- print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
   282         -				if (rune.minpower*powerfac)*time <= l.self.powerdraw and math.random(rune.rarity - pf) == 1 then
          283  +				local powreq = (rune.minpower*powerfac)*time 
          284  +				print('- rune', name)
          285  +				print('powreq',powreq)
          286  +				print('power draw',l.self.powerdraw)
          287  +				if powreq <= l.self.powerdraw then
          288  +					print(' ! sufficient power for rune')
   283    289   					choices[#choices + 1] = rune
   284    290   				end
   285    291   			end
          292  +			for k,v in pairs(choices) do print(' * choice',k,v.item) end
   286    293   			if #choices > 0 then
   287         -				-- if multiple runes were rolled up, be nice to the player
   288         -				-- and pick the rarest one to give them
   289         -				local rare, choice = 0
   290         -				for i,c in pairs(choices) do
   291         -					if c.rarity > rare then
   292         -						rare = c.rarity
   293         -						choice = c
          294  +				for try = 1,#choices do
          295  +					print(' -- try',try)
          296  +					local _, choice = sorcery.lib.tbl.pick(choices)
          297  +					local adjrare = math.max(2, choice.rarity - pf)
          298  +					print(choice.item,'rarity',choice.rarity, 'adjusted', adjrare)
          299  +					if math.random(adjrare) == 1 then
          300  +						print(' ! picking ', choice.item)
          301  +						newrunes[#newrunes + 1] = ItemStack(choice.item)
          302  +						break
   294    303   					end
   295    304   				end
   296         -				newrunes[#newrunes + 1] = ItemStack(choice.item)
   297    305   			end
   298    306   			-- print('rune choices:',dump(choices))
   299    307   			-- print('me',dump(l.self))
   300    308   		end
   301    309   
   302    310   		for _,r in pairs(newrunes) do
   303    311   			if i:room_for_item('cache',r) and has_phial() then
................................................................................
   420    428   		local i = m:get_inventory()
   421    429   		i:set_size('cache',constants.rune_cache_max)
   422    430   		i:set_size('wrench',1) i:set_size('phial',1) i:set_size('refuse',1)
   423    431   		i:set_size('amulet',1) i:set_size('active',1)
   424    432   		m:set_string('infotext','Rune Forge')
   425    433   		runeforge_update(pos)
   426    434   	end;
   427         -	after_dig_node = sorcery.lib.node.purge_only {'amulet','wrench'};
          435  +	after_dig_node = sorcery.lib.node.purge_only {'amulet','wrench','refuse','phial'};
   428    436   	on_timer = runeforge_update;
   429    437   	on_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
   430    438   		local inv = minetest.get_meta(pos):get_inventory()
   431    439   		local wrench if not inv:is_empty('wrench') then
   432    440   			wrench = inv:get_stack('wrench',1):get_definition()._proto
   433    441   		end
   434    442   		local wwear = function(cap)