sorcery  Diff

Differences From Artifact [c21bb1a7ca]:

To Artifact [c1d9a4ce4b]:


    34     34   	
    35     35   	metal_grindvalue = 4;
    36     36   	-- how many powders an ingot is worth
    37     37   
    38     38   	default_grindvalue = 1;
    39     39   	-- number of items produced when not otherwise
    40     40   	-- specified
           41  +
           42  +	default_grindcost = 1;
           43  +	-- number of items needed to perform a grind when
           44  +	-- not otherwise specified
    41     45   	
    42     46   	default_hardness = 1;
    43     47   	-- difficulty to grind an item when not otherwise
    44     48   	-- specified
    45     49   
    46     50   	metal_grindcost = 1;
    47     51   	-- number of metal items needed to perform a grind
    48     52   }
    49     53   local mill_formspec_update = function(pos,pct,stat1,stat2)
    50     54   	-- eventually we'll want to display available
    51         -	-- energy here, but for now we're just assuming
    52         -	-- max energy available
           55  +	-- energy here
    53     56   
    54     57   	-- local meta = minetest.get_meta(pos)
    55     58   	-- local inv = meta:get_inventory()
    56     59   	-- local torque = 20
    57     60   	stat1 = stat1 or 'off'
    58     61   	minetest.get_meta(pos):set_string('formspec', string.format([[
    59     62   		size[8,7.2]
................................................................................
    79     82   	if slot == 'grinder' then
    80     83   		if minetest.get_item_group(item:get_name(), 'sorcery_mill_grindhead')~=0 
    81     84   			then return 1 end
    82     85   	elseif slot == 'input' then
    83     86   		local metal = sorcery.data.metallookup[item:get_name()]
    84     87   		local mat = sorcery.matreg.lookup[item:get_name()]
    85     88   		local comp = sorcery.data.compat.grindables[item:get_name()]
    86         -		if metal or mat.metal or comp then
           89  +		if metal or (mat and mat.metal) or comp then
    87     90   			return item:get_count()
    88     91   		else
    89         -			local mat = item:get_definition()._matprop
           92  +			mat = item:get_definition()._matprop
    90     93   			if mat and mat.grindvalue then
    91     94   				return item:get_count() 
    92     95   			end
    93     96   		end
    94     97   	end
    95     98   	return 0
    96     99   end
    97    100   local matprops = function(item)
    98    101   	local metal = sorcery.data.metallookup[item:get_name()]
    99    102   	if not metal then
   100    103   		-- allow grinding of armor and tools back to their
   101    104   		-- original components
   102    105   		local mat = sorcery.matreg.lookup[item:get_name()]
   103         -		if mat.metal then
          106  +		if mat and mat.metal then
   104    107   			metal = mat
   105         -		else
   106         -			return nil
   107    108   		end
   108    109   	end
   109    110   	local mp = item:get_definition()._matprop
   110    111   		or sorcery.data.compat.grindables[item:get_name()]
   111    112   		or {}
   112    113   
   113    114   	again = true
   114    115   	if metal then mp = {
   115         -		hardness = metal.data.hardness or mp.hardness or constants.default_hardness;
   116         -		grindvalue = metal.value or mp.grindvalue or (metal and constants.metal_grindvalue) or constants.default_grindvalue;
   117         -		powder = metal.data.parts.powder or mp.powder;
   118         -		grindcost = constants.metal_grindcost or mp.grindcost; -- invariant for metal
          116  +		hardness = mp.hardness or metal.data.hardness;
          117  +		grindvalue = ((mp.grindvalue or metal.value) or (metal and constants.metal_grindvalue));
          118  +		powder = mp.powder or metal.data.parts.powder;
          119  +		grindcost = mp.grindcost or constants.metal_grindcost; -- invariant for metal
   119    120   	} end
   120    121   
   121         -	mp.torque = constants.grind_torque_factor * mp.hardness
          122  +	mp.torque     = constants.grind_torque_factor * mp.hardness
          123  +	mp.grindvalue = mp.grindvalue or constants.default_grindvalue
          124  +	mp.grindcost  = mp.grindcost  or constants.default_grindcost
          125  +	mp.hardness   = mp.hardness   or constants.default_hardness;
   122    126   
   123    127   	if item:get_wear() ~= 0 then
   124    128   		-- prevent cheating by recovering metal from items before they
   125    129   		-- are destroyed
   126    130   		local wearfac = (item:get_wear() / 65535)
   127    131   		mp.grindvalue = math.max(1,math.ceil(mp.grindvalue * wearfac))
   128    132   		mp.hardness = math.max(1,math.ceil(mp.grindcost * wearfac))
................................................................................
   134    138   minetest.register_node('sorcery:mill',{
   135    139   	description = 'Mill';
   136    140   	groups = {
   137    141   		cracky = 2;
   138    142   		sorcery_ley_device = 1;
   139    143   	};
   140    144   	paramtype2 = 'facedir';
          145  +	after_dig_node = sorcery.lib.node.purge_container;
   141    146   	on_construct = function(pos)
   142    147   		local meta = minetest.get_meta(pos)
   143    148   		local inv = meta:get_inventory()
   144    149   		inv:set_size('input',1)
   145    150   		inv:set_size('output',4)
   146    151   		inv:set_size('grinder',2)
   147    152   		meta:set_float('grindtime',0)
................................................................................
   163    168   	on_metadata_inventory_move = function(pos,fl,fi,tl,ti)
   164    169   		if fl == 'input' or tl == 'input' then
   165    170   			minetest.get_meta(pos):set_float('grindtime',0)
   166    171   		end
   167    172   		mill_update(pos)
   168    173   	end;
   169    174   	_sorcery = {
   170         -		ley = { mode = 'consume'; affinity = {'praxic'}};
   171         -		on_leyconnect = mill_update;
   172         -		on_leycalc = function(pos,time)
   173         -			local meta = minetest.get_meta(pos)
   174         -			local active = meta:get_int('active') == 1
   175         -			if not active then return { power = 0; } end
   176         -			local inv = meta:get_inventory()
   177         -			local item = inv:get_stack('input',1)
   178         -			if item:is_empty() then
   179         -				meta:set_int('active', 0)
   180         -				return { power = 0; }
   181         -			end
   182         -			return {
   183         -				power = matprops(item).torque * time;
   184         -			}
   185         -		end;
          175  +		ley = {
          176  +			mode = 'consume', affinity = {'praxic'};
          177  +			power = function(pos,time)
          178  +				local meta = minetest.get_meta(pos)
          179  +				local active = meta:get_int('active') == 1
          180  +				if not active then return 0 end
          181  +				local inv = meta:get_inventory()
          182  +				local item = inv:get_stack('input',1)
          183  +				if item:is_empty() then
          184  +					meta:set_int('active', 0)
          185  +					return 0
          186  +				end
          187  +				return matprops(item).torque * time;
          188  +			end;
          189  +		};
          190  +		on_leychange = mill_update;
   186    191   	};
   187    192   	on_timer = function(pos,delta)
   188    193   		local meta = minetest.get_meta(pos)
   189    194   		local inv = meta:get_inventory()
   190    195   		local elapsed = meta:get_float('grindtime') + delta
   191    196   		local ley = sorcery.ley.netcaps(pos,delta,pos)
   192    197   		local again = false
   193    198   		local active = false
   194    199   		local reqtime -- sigh
   195    200   		local statcolor = 'off'
   196    201   		local grinders_on
   197    202   		if inv:is_empty('input') or inv:is_empty('grinder') then
   198         -			print('empty')
   199    203   			elapsed = 0
   200    204   			mill_formspec_update(pos, 0)
   201    205   		else
   202    206   			local item = inv:get_stack('input',1)
   203    207   			local mp = matprops(item)
   204    208   			if mp.grindcost > item:get_count() then
   205    209   				elapsed = 0
   206    210   				mill_formspec_update(pos, 0)
   207         -				print('bad grindcost')
   208    211   				goto stop
   209    212   			end
   210    213   
   211         -			-- print('power supply',ley.maxpower)
   212         -			-- print('power available',ley.freepower)
   213         -			-- print('power needed',mp.torque*delta)
   214    214   			if ley.maxpower < (mp.torque * delta) then
   215    215   				-- not enough potential energy in the system to grind
   216    216   				-- so don't bother
   217         -				print('not enough power')
   218    217   				statcolor = 'red'
   219    218   				elapsed = 0 goto stop
   220    219   			elseif ley.freepower < (mp.torque * delta) then
   221    220   				-- the net has enough potential energy to supply us,
   222    221   				-- but too much of it is in use right now. give up
   223    222   				-- on this round, but try again in a bit to see if
   224    223   				-- more energy is available
   225         -				print('currently not enough power')
   226    224   				statcolor = 'yellow'
   227    225   				elapsed = 0 again = true goto stop
   228    226   			end
   229    227   
   230    228   			local grinders = 0
   231    229   			local grindpower = 0
   232    230   			local grind_wear = {}
................................................................................
   242    240   					if dif == 0 then
   243    241   						wear = constants.grind_wear
   244    242   					elseif dif < 0 then
   245    243   						wear = constants.grind_wear * ((dif * -1)/constants.grind_range)
   246    244   					elseif dif > 0 then
   247    245   						if dif > constants.grind_grace_range then
   248    246   							wear = 0
   249         -							print('grinder reject')
   250    247   							goto reject
   251    248   						else
   252    249   							wear = constants.grind_wear * (1 + (dif/constants.grind_range)) * constants.grind_grace_penalty
   253    250   						end
   254    251   					end
   255    252   					::accept:: grinders = grinders + 1
   256    253   					           grindpower = grindpower + hh
................................................................................
   269    266   				if grindpower < mp.hardness then
   270    267   					statcolor = 'yellow'
   271    268   				else statcolor='green' end
   272    269   				grindpower = grindpower / grinders
   273    270   				-- if there is more power available than needed,
   274    271   				-- and/or if the blades are stronger than needed,
   275    272   				-- speed up the grind
   276         -				local speedboost = math.max(0.05,((grindpower - mp.hardness)/constants.grind_range) * grinders) * ((mp.torque * delta) / ley.freepower)
          273  +				local speedboost = math.max(0.05,((grindpower - mp.hardness)/constants.grind_range) * grinders)
   277    274   				reqtime = mp.grindvalue * mp.hardness * constants.grind_factor * (1-speedboost)
   278    275   				if elapsed >= reqtime then
   279    276   					item:take_item(mp.grindcost)
   280    277   					inv:set_stack('input',1,item)
   281    278   					local pw = ItemStack{
   282    279   						name=mp.powder;
   283    280   						count=mp.grindvalue;
................................................................................
   345    342   			metal = name;
   346    343   		};
   347    344   	});
   348    345   	minetest.register_craft {
   349    346   		output = id;
   350    347   		recipe = {
   351    348   			{f,i,f};
   352         -			{i,i,i};
          349  +			{i,'',i};
   353    350   			{f,i,f};
   354    351   		};
   355    352   	}
   356    353   end