sorcery  Check-in [3354e2aa29]

Overview
Comment:add support for instantiation callbacks, god tweaks and bug fixes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3354e2aa299c7c61b777ae0c5bc0303381c95fa066568ffd1b5dac51e8659dc4
User & Date: lexi on 2021-07-05 20:43:40
Other Links: manifest | tags
Context
2021-07-05
23:59
add more recipes and god gifts check-in: 049207a61e user: lexi tags: trunk
20:43
add support for instantiation callbacks, god tweaks and bug fixes check-in: 3354e2aa29 user: lexi tags: trunk
19:17
remove debugging shim oops check-in: d08d3d2bd8 user: lexi tags: trunk
Changes

Modified altar.lua from [e0cdcfa7d5] to [dfbf2cd360].

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
76
77
78
79
80
81
82
























83
84
85
86
87
88
89
90
91
92
93
94




95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
			-- can't mutate table while we're iterating it
			if not minetest.registered_nodes[g] then bad[#bad+1] = g end
		end
		for _, g in ipairs(bad) do god.gifts[g] = nil end
	end
end)

local std_god_interval = 70

for name, god in pairs(sorcery.data.gods) do
	local hitbox = {
		0-(god.idol.width / 2.0), 0-(god.idol.height / 2.0), -0.15,
		   god.idol.width / 2.0,     god.idol.height / 2.0,   0.15
	} -- {xmin, ymin, zmin,
	  -- xmax, ymax, zmax} in nodes from node center.
................................................................................
	if god.idol.craft then
		minetest.register_craft {
			output = 'sorcery:idol_' .. name;
			recipe = god.idol.craft;
		};
	end
	local god_interval = std_god_interval * (god.freq or 1)
























	sorcery.lib.node.reg_autopreserve('sorcery:idol_' .. name, {
		description = god.idol.desc;
		drawtype = "mesh";
		mesh = 'sorcery-idol-' .. name .. '.obj';
		paramtype = 'light';
		paramtype2 = 'facedir';
		sunlight_propagates = true;
		stack_max = 1;
		tiles = god.idol.tex;
		selection_box = { type = "fixed"; fixed = {hitbox}; };
		collision_box = { type = "fixed"; fixed = {hitbox}; };
		groups = { cracky = 2, sorcery_idol = 1, heavy = 1, sorcery_worship = 1};





		on_construct = function(pos)
			minetest.get_node_timer(pos):start(god_interval)

		end;

		on_timer = function(pos, elapsed)
			local altar = minetest.find_node_near(pos, 3, "sorcery:altar")
			-- TODO even without an altar, an idol with high favor could still be the source of miracles
			-- refills nearby partly empty troughs at cost to favor?
			if not altar then return true end

			local altarmeta = minetest.get_meta(altar)
			local inv = altarmeta:get_inventory()
			local idolmeta = minetest.get_meta(pos)
			local divine_favor = idolmeta:get_int('favor')
			if divine_favor > 5 then
				local ct = divine_favor / 5
				minetest.add_particlespawner {
					texture = L.image('sorcery_glitter.png'):glow(L.color(god.color)):render();
					glow = 14;
					amount = ct / (1 / god_interval), time = god_interval;
					minpos = pos:offset(-0.4, -0.5, -0.4);
					maxpos = pos:offset( 0.4,god.idol.height-0.5,0.4);
					minvel = vector.new(0, 0.05, 0);
					minvel = vector.new(0, 0.1, 0);
					minacc = vector.new(0, 0.1, 0);
					maxacc = vector.new(0, 0.2, 0);
					minexptime = 4, maxexptime = 4;
					minsize = 0.3, maxsize = 1;
					animation = {
						type = 'vertical_frames';
						length = 0.1;
						aspect_w = 16, aspect_h = 16;
					}
				}
			end
			local bestow = function(item,color)
				if type(item) == 'string' then
					item = ItemStack(item)
				end
				if color == nil then
					color = sorcery.lib.color(god.color)
				end
................................................................................
					-- we pick a random gift and roll against its rarity
					-- to determine if the god is feeling generous
					local gift = sorcery.lib.tbl.pick(god.gifts)
					local data = god.gifts[gift]
					local value, rarity = data[1], data[2]
					if value <= divine_favor and math.random(rarity) == 1 then
						bestow(gift)
						log.act(god.name .. ' has produced ' .. gift .. ' upon an altar as a gift')
						if math.random(god.generosity) == 1 then
							-- unappreciated gifts may incur divine
							-- irritation
							divine_favor = divine_favor - 1
						end
					end
				end
................................................................................
								-- the gods are getting bored
								value = math.floor(value / 2)
							end
							bestow(nil)
						end
						divine_favor = divine_favor + value
						
						print(god.name.." has accepted a sacrifice of "..s..", raising divine favor by "..value.." points to "..divine_favor)

						idolmeta:set_string('last_sacrifice', s)

						goto refresh
					end
				end

				-- loop through the list of things this god will consecrate and







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
>
>
>
>



>












|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







|
>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139




















140
141
142
143
144
145
146
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
			-- can't mutate table while we're iterating it
			if not minetest.registered_nodes[g] then bad[#bad+1] = g end
		end
		for _, g in ipairs(bad) do god.gifts[g] = nil end
	end
end)

local std_god_interval = 40

for name, god in pairs(sorcery.data.gods) do
	local hitbox = {
		0-(god.idol.width / 2.0), 0-(god.idol.height / 2.0), -0.15,
		   god.idol.width / 2.0,     god.idol.height / 2.0,   0.15
	} -- {xmin, ymin, zmin,
	  -- xmax, ymax, zmax} in nodes from node center.
................................................................................
	if god.idol.craft then
		minetest.register_craft {
			output = 'sorcery:idol_' .. name;
			recipe = god.idol.craft;
		};
	end
	local god_interval = std_god_interval * (god.freq or 1)
	local add_sparkles = function(pos,divine_favor)
		divine_favor = divine_favor or minetest.get_meta(pos):get_int('favor')
		if divine_favor > 5 then
			local ct = divine_favor / 5
			minetest.add_particlespawner {
				texture = L.image('sorcery_glitter.png'):glow(L.color(god.color)):render();
				glow = 14;
				amount = ct / (1 / god_interval), time = god_interval;
				minpos = pos:offset(-0.4, -0.5, -0.4);
				maxpos = pos:offset( 0.4,god.idol.height-0.5,0.4);
				minvel = vector.new(0, 0.05, 0);
				minvel = vector.new(0, 0.1, 0);
				minacc = vector.new(0, 0.1, 0);
				maxacc = vector.new(0, 0.2, 0);
				minexptime = 4, maxexptime = 4;
				minsize = 0.3, maxsize = 1;
				animation = {
					type = 'vertical_frames';
					length = 0.1;
					aspect_w = 16, aspect_h = 16;
				}
			}
		end
	end
	sorcery.lib.node.reg_autopreserve('sorcery:idol_' .. name, {
		description = god.idol.desc;
		drawtype = "mesh";
		mesh = 'sorcery-idol-' .. name .. '.obj';
		paramtype = 'light';
		paramtype2 = 'facedir';
		sunlight_propagates = true;
		stack_max = 1;
		tiles = god.idol.tex;
		selection_box = { type = "fixed"; fixed = {hitbox}; };
		collision_box = { type = "fixed"; fixed = {hitbox}; };
		groups = { cracky = 2, sorcery_idol = 1, heavy = 1, sorcery_worship = 1, sorcery_instantiate = 1};
		_sorcery = {
			idol_god = name;
			on_load = function(pos) add_sparkles(pos) end;
		};

		on_construct = function(pos)
			minetest.get_node_timer(pos):start(god_interval)
			add_sparkles(pos)
		end;

		on_timer = function(pos, elapsed)
			local altar = minetest.find_node_near(pos, 3, "sorcery:altar")
			-- TODO even without an altar, an idol with high favor could still be the source of miracles
			-- refills nearby partly empty troughs at cost to favor?
			if not altar then return true end

			local altarmeta = minetest.get_meta(altar)
			local inv = altarmeta:get_inventory()
			local idolmeta = minetest.get_meta(pos)
			local divine_favor = idolmeta:get_int('favor')
			add_sparkles(pos,divine_favor)




















			local bestow = function(item,color)
				if type(item) == 'string' then
					item = ItemStack(item)
				end
				if color == nil then
					color = sorcery.lib.color(god.color)
				end
................................................................................
					-- we pick a random gift and roll against its rarity
					-- to determine if the god is feeling generous
					local gift = sorcery.lib.tbl.pick(god.gifts)
					local data = god.gifts[gift]
					local value, rarity = data[1], data[2]
					if value <= divine_favor and math.random(rarity) == 1 then
						bestow(gift)
						log.act(god.name,'has produced',gift,'upon an altar as a gift')
						if math.random(god.generosity) == 1 then
							-- unappreciated gifts may incur divine
							-- irritation
							divine_favor = divine_favor - 1
						end
					end
				end
................................................................................
								-- the gods are getting bored
								value = math.floor(value / 2)
							end
							bestow(nil)
						end
						divine_favor = divine_favor + value
						
						log.actf("%s has accepted a sacrifice of %s, raising divine favor by %u points to %u at altar %s", god.name, s, value, divine_favor, minetest.pos_to_string(pos))

						idolmeta:set_string('last_sacrifice', s)

						goto refresh
					end
				end

				-- loop through the list of things this god will consecrate and

Modified data/gods.lua from [6a04c7ee36] to [39659f8d92].

30
31
32
33
34
35
36
37









38
39
40
41
42
43
44
45
46
47



48
49

50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
				{'default:obsidian_shard','stairs:slab_goldblock','default:bronze_ingot'};
			};
		};
		bless = {
			potions = {};
			tools = {};
		};
		gifts = {};









		consecrate = {
			["sorcery:dagger"] = {17, "sorcery:dagger_consecrated"};
			["sorcery:oil_mystic"] = {9, "sorcery:oil_purifying"};
			["sorcery:potion_water"] = {4, "sorcery:holy_water"};
			["default:paper"] = function(ctx)
				local stack = ItemStack('sorcery:recipe')
				local mode = select(2,L.tbl.pick{'cook','craft','infuse','grind','enchant'})
				sorcery.cookbook.setrecipe(stack, mode, nil, {
					pred = function(c)
						local me = ctx.god



						if (mode == 'enchant' or
							minetest.get_item_group(c.item, 'sorcery_magical') ~= 0 or

							minetest.get_item_group(c.item, 'sorcery_magitech') ~= 0 or
							minetest.get_item_group(c.item, 'sorcery_ley_device') ~= 0 or
							minetest.get_item_group(c.item, 'sorcery_tech') ~= 0 or
							minetest.get_item_group(c.item, 'crafttool') ~= 0 or

							me.sacrifice [c.item] or
							me.consecrate[c.item]) and
							mod ~= 'farming'
								then return true end
					end;
				})
				return 6, stack
			end;
			-- ["default:gold_ingot"] = {15, "sorcery:holy_token_magic"};
		};
		sacrifice = {
			['sorcery:essence_frost'] = 25;
			['sorcery:essence_flame'] = 25;
			['sorcery:essence_force'] = 30;

			['sorcery:gem_luxite'] = 6;
			['sorcery:gem_ruby'] = 10;
			['sorcery:gem_amethyst'] = 16;
			['sorcery:gem_sapphire'] = 25;
			['sorcery:gem_emerald'] = 34;
			['default:mese_crystal'] = 42;
			['default:diamond'] = 50;

			['sorcery:gem_luxite_amulet'] = 20;
			['sorcery:gem_ruby_amulet'] = 35;
			['sorcery:gem_amethyst_amulet'] = 48;
			['sorcery:gem_sapphire_amulet'] = 56;
			['sorcery:gem_emerald_amulet'] = 63;
			['sorcery:gem_mese_amulet'] = 78;
			['sorcery:gem_diamond_amulet'] = 91;

			['sorcery:oil_mystic'] = 2;
			['sorcery:oil_berry'] = 4;
			['sorcery:oil_wind'] = 6;
			['sorcery:oil_bleak'] = 6;
			['sorcery:oil_stone'] = 7;
			['sorcery:oil_mushroom'] = 8;
			['sorcery:oil_flame'] = 8;
			['sorcery:oil_dawn'] = 11;
			['sorcery:oil_luscious'] = 12;
			['sorcery:oil_luck'] = 16;
			['sorcery:oil_sagnuine'] = -15;

			['sorcery:grease_fog'] = 17;
			['sorcery:grease_pine'] = 18;
			['sorcery:grease_storm'] = 20;
			['sorcery:grease_whisper'] = 21;
			['sorcery:grease_thunder'] = 22;
			['sorcery:grease_enchanting'] = 24;
			['sorcery:grease_lift'] = 32;
			['sorcery:grease_war'] = -5;

			['sorcery:warding_plate'] = 6;
			['sorcery:ley_puncture'] = 8;
			['sorcery:pulse_rectifier'] = 8;
			['sorcery:current_felicitator'] = 12;
			['sorcery:infuser_concentrator'] = 15;
			['sorcery:infuser_tube'] = 23;
			['sorcery:inverter_coil'] = 31;
			['sorcery:inversion_matrix'] = 70;
			['sorcery:inferno_crystal'] = 75;
			['sorcery:beam_generator'] = 83;
			['sorcery:field_emitter'] = 92;
			['sorcery:catalytic_converter'] = 95;
			['sorcery:gravity_manipulator'] = 97;

			['sorcery:core_syncretic'] = 64;
			['sorcery:core_mandatic'] = 53;
			['sorcery:core_praxic'] = 72;
			['sorcery:core_counterpraxic'] = 31;

			['sorcery:sap'] = 1;
			['sorcery:sap_apple'] = 2;
			['sorcery:sap_aspen'] = 3;
			['sorcery:sap_pine'] = 3;
			['sorcery:sap_jungle'] = 4;
			['sorcery:sap_acacia'] = 5;







|
>
>
>
>
>
>
>
>
>






|



>
>
>

<
>
|
|
|
<
>
|
|
|



|




|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|


|



|
|
|
|
|
|
|
|
|

|
|
|
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
				{'default:obsidian_shard','stairs:slab_goldblock','default:bronze_ingot'};
			};
		};
		bless = {
			potions = {};
			tools = {};
		};
		gifts = {
			['sorcery:screw_steel'] = {7,1};
			['sorcery:pipe'] = {16,2};
			['sorcery:valve'] = {18,3};
			['sorcery:fragment_vidrium'] = {20,4};
			['sorcery:fragment_lithium'] = {23,5};
			['sorcery:screw_platinum'] = {31,5};
			['sorcery:screw_tungsten'] = {33,5};
			['sorcery:powder_firestorm'] = {48,7};
		};
		consecrate = {
			["sorcery:dagger"] = {17, "sorcery:dagger_consecrated"};
			["sorcery:oil_mystic"] = {9, "sorcery:oil_purifying"};
			["sorcery:potion_water"] = {4, "sorcery:holy_water"};
			["default:paper"] = function(ctx)
				local stack = ItemStack('sorcery:recipe')
				local mode = select(2,L.tbl.pick{'cook','craft','grind','enchant'})
				sorcery.cookbook.setrecipe(stack, mode, nil, {
					pred = function(c)
						local me = ctx.god
						local g = function(n)
							return minetest.get_item_group(c.item, n) ~= 0
						end
						if (mode == 'enchant' or

							(ctx.favor > 35 and (g 'sorcery_magical'
											or g 'sorcery_magitech'
											or g 'sorcery_ley_device'))
							or g 'sorcery_tech'

							or g 'crafttool'
							or me.sacrifice [c.item]
							or me.consecrate[c.item])
							and mod ~= 'farming'
								then return true end
					end;
				})
				return 3, stack
			end;
			-- ["default:gold_ingot"] = {15, "sorcery:holy_token_magic"};
		};
		sacrifice = {
			['sorcery:essence_frost'] = 15;
			['sorcery:essence_flame'] = 15;
			['sorcery:essence_force'] = 20;

			['sorcery:gem_luxite'] = 4;
			['sorcery:gem_ruby'] = 7;
			['sorcery:gem_amethyst'] = 9;
			['sorcery:gem_sapphire'] = 12;
			['sorcery:gem_emerald'] = 14;
			['default:mese_crystal'] = 18;
			['default:diamond'] = 25;

			['sorcery:gem_luxite_amulet'] = 8;
			['sorcery:gem_ruby_amulet'] = 14;
			['sorcery:gem_amethyst_amulet'] = 18;
			['sorcery:gem_sapphire_amulet'] = 23;
			['sorcery:gem_emerald_amulet'] = 14;
			['sorcery:gem_mese_amulet'] = 36;
			['sorcery:gem_diamond_amulet'] = 50;

			['sorcery:oil_mystic'] = 2;
			['sorcery:oil_berry'] = 3;
			['sorcery:oil_wind'] = 4;
			['sorcery:oil_bleak'] = 4;
			['sorcery:oil_stone'] = 5;
			['sorcery:oil_mushroom'] = 6;
			['sorcery:oil_flame'] = 7;
			['sorcery:oil_dawn'] = 8;
			['sorcery:oil_luscious'] = 9;
			['sorcery:oil_luck'] = 11;
			['sorcery:oil_sagnuine'] = -15;

			['sorcery:grease_fog'] = 15;
			['sorcery:grease_pine'] = 16;
			['sorcery:grease_storm'] = 18;
			['sorcery:grease_whisper'] = 19;
			['sorcery:grease_thunder'] = 20;
			['sorcery:grease_enchanting'] = 22;
			['sorcery:grease_lift'] = 28;
			['sorcery:grease_war'] = -5;

			['sorcery:warding_plate'] = 5;
			['sorcery:ley_puncture'] = 8;
			['sorcery:pulse_rectifier'] = 8;
			['sorcery:current_felicitator'] = 12;
			['sorcery:infuser_concentrator'] = 7;
			['sorcery:infuser_tube'] = 9;
			['sorcery:inverter_coil'] = 10;
			['sorcery:inversion_matrix'] = 22;
			['sorcery:inferno_crystal'] = 24;
			['sorcery:beam_generator'] = 27;
			['sorcery:field_emitter'] = 30;
			['sorcery:catalytic_converter'] = 30;
			['sorcery:gravity_manipulator'] = 50;

			['sorcery:core_syncretic'] = 25;
			['sorcery:core_mandatic'] = 27;
			['sorcery:core_praxic'] = 29;
			['sorcery:core_counterpraxic'] = 17;

			['sorcery:sap'] = 1;
			['sorcery:sap_apple'] = 2;
			['sorcery:sap_aspen'] = 3;
			['sorcery:sap_pine'] = 3;
			['sorcery:sap_jungle'] = 4;
			['sorcery:sap_acacia'] = 5;

Added global.lua version [3ad50b0db8].





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- abuses the engine to provide additional generic features useful to multiple units
local log = sorcery.logger 'global'

minetest.register_lbm {
	name = 'sorcery:activate_nodes';
	label = 'trigger instantiation-time callbacks';
	nodenames = { 'group:sorcery_instantiate' };
	run_at_every_load = true;
	action = function(pos,node)
		local s = minetest.registered_nodes[node.name]._sorcery
		if not s or not s.on_load then
			log.errf('node type "%s" marked for instantiation-time callback, but no callback specified', node.name)
			return
		end

		s.on_load(pos,node)
	end;
}

Modified init.lua from [3b59932455] to [1fc924b85b].

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
		end
	end
	sorcery.registry.mk('residue',false)
end

sorcery.stage('startup',data)
for _,u in pairs {
	'vfx'; 'context'; 'attunement'; 'itemclass'; 'craft'; 'spell';
	'liquid'; 'tree'; 'potions'; 'metal', 'gems'; 'leylines';
	'infuser'; 'altar'; 'wands'; 'tools', 'crafttools';
	'enchanter'; 'harvester'; 'metallurgy-hot', 'metallurgy-cold';
	'entities'; 'recipes'; 'coins'; 'interop';
	'tnodes'; 'forcefield'; 'farcaster'; 'portal';
	'cookbook', 'writing'; 'disassembly'; 'displacer';
	'gravitator'; 'precipitator'; 'calendar', 'astrolabe';







|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
		end
	end
	sorcery.registry.mk('residue',false)
end

sorcery.stage('startup',data)
for _,u in pairs {
	'global'; 'vfx'; 'context'; 'attunement'; 'itemclass'; 'craft'; 'spell';
	'liquid'; 'tree'; 'potions'; 'metal', 'gems'; 'leylines';
	'infuser'; 'altar'; 'wands'; 'tools', 'crafttools';
	'enchanter'; 'harvester'; 'metallurgy-hot', 'metallurgy-cold';
	'entities'; 'recipes'; 'coins'; 'interop';
	'tnodes'; 'forcefield'; 'farcaster'; 'portal';
	'cookbook', 'writing'; 'disassembly'; 'displacer';
	'gravitator'; 'precipitator'; 'calendar', 'astrolabe';

Modified liquid.lua from [02b94765c1] to [7230727dfc].

132
133
134
135
136
137
138






139
140
141
142
143
144
145
			node_box = { type = 'fixed', fixed = mkbox(i) };
			tiles = {
				top:render();
				'sorcery_trough_side.png';
				'sorcery_trough_bottom.png';
			};
			_sorcery = {






				container = {
					type = 'bucket';
					hold = 'liquid';
					has = liq and liq.id;
					charge = liq and Q * i;
					empty = 'sorcery:trough';
					max = constants.bottles_per_trough * Q;







>
>
>
>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
			node_box = { type = 'fixed', fixed = mkbox(i) };
			tiles = {
				top:render();
				'sorcery_trough_side.png';
				'sorcery_trough_bottom.png';
			};
			_sorcery = {
				material = liq == nil and {
					metal = true;
					name = 'aluminum';
					data = sorcery.data.metals.aluminum;
					value = 7*4;
				} or nil;
				container = {
					type = 'bucket';
					hold = 'liquid';
					has = liq and liq.id;
					charge = liq and Q * i;
					empty = 'sorcery:trough';
					max = constants.bottles_per_trough * Q;

Modified recipes.lua from [993e34739f] to [22986aed9f].

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
...
322
323
324
325
326
327
328






























329
330
331
332
333
334
335
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	groups = {
		sorcery_magitech = 1;
		sorcery_tech_component = 1;
	};
})


local regtech = function(id, desc, groups, recipe, qty, replacements)
	minetest.register_craftitem('sorcery:' .. id,{
		description = desc;
		inventory_image = 'sorcery_'..id..'.png';
		groups = sorcery.lib.tbl.merge({
			sorcery_magitech = 1;
			sorcery_tech_component = 1;
		}, groups or {});

	})
	if recipe then
		minetest.register_craft {
			output = string.format('sorcery:%s %u', id, qty or 1);
			recipe = recipe;
			replacements = replacements;
		}
................................................................................
	end
end

local regcore = function(core,name)
	regtech('core_'..core, name .. ' Core', {sorcery_magitech_core = 1})
end
































regtech('field_emitter', 'Field Emitter', {metal = 1})
regtech('leyline_stabilizer', 'Leyline Stabilizer', {metal = 1})
regtech('beam_generator', 'Beam Generator', {metal = 1})
regtech('inversion_matrix', 'Inversion Matrix', {metal = 1})
regtech('inverter_coil', 'Inverter Coil', {metal = 1})
regtech('suppression_matrix', 'Suppression Matrix', {metal = 1})
................................................................................
regtech('tuning_disc', 'Tuning Disc', {metal = 1})
	-- used in constructing devices that are subject to attunement wand
regtech('gravity_manipulator', 'Gravity Manipulator', {metal = 1})
regtech('valve','Valve', {metal = 1}, {
	{'','default:bronze_ingot',''};
	{'basic_materials:plastic_sheet','basic_materials:steel_bar','basic_materials:plastic_sheet'};
	{'','default:bronze_ingot',''};
},3)
regtech('pipe','Pipe', {metal = 1}, {
	{ingot('aluminum'),'',ingot('aluminum')};
	{ingot('aluminum'),'',ingot('aluminum')};
	{ingot('aluminum'),'',ingot('aluminum')};
}, 6)

minetest.register_craft {
	output = 'sorcery:trough';
	recipe = {
		{ingot('aluminum'),'',ingot('aluminum')};
		{ingot('aluminum'),'',ingot('aluminum')};
		{ingot('aluminum'),ingot('aluminum'),ingot('aluminum')};







|







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|




|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	groups = {
		sorcery_magitech = 1;
		sorcery_tech_component = 1;
	};
})


local regtech = function(id, desc, groups, recipe, qty, replacements, props)
	minetest.register_craftitem('sorcery:' .. id,{
		description = desc;
		inventory_image = 'sorcery_'..id..'.png';
		groups = sorcery.lib.tbl.merge({
			sorcery_magitech = 1;
			sorcery_tech_component = 1;
		}, groups or {});
		_sorcery = props;
	})
	if recipe then
		minetest.register_craft {
			output = string.format('sorcery:%s %u', id, qty or 1);
			recipe = recipe;
			replacements = replacements;
		}
................................................................................
	end
end

local regcore = function(core,name)
	regtech('core_'..core, name .. ' Core', {sorcery_magitech_core = 1})
end

local mprop = function(metal, amt)
	local gc, gv
	amt = amt or 1
	if math.floor(amt) ~= amt then
		if amt < 1 then
			gc = math.floor(1 / amt)
		else
			local n = 0
			for i = 2,10 do
				if math.floor(amt * i) == amt * i then
					n = i
					break
				end
			end
			if n == 0 then error "can't determine metal value for item" end
			gc = i
			gv = amt * i
		end
	else
		gc = 1
		gv = amt
	end
	return { material = {
		metal = true; id = metal;
		data = sorcery.data.metals[metal];
		grindcost = gc;
		grindvalue = gv;
		value = amt;
	}}
end

regtech('field_emitter', 'Field Emitter', {metal = 1})
regtech('leyline_stabilizer', 'Leyline Stabilizer', {metal = 1})
regtech('beam_generator', 'Beam Generator', {metal = 1})
regtech('inversion_matrix', 'Inversion Matrix', {metal = 1})
regtech('inverter_coil', 'Inverter Coil', {metal = 1})
regtech('suppression_matrix', 'Suppression Matrix', {metal = 1})
................................................................................
regtech('tuning_disc', 'Tuning Disc', {metal = 1})
	-- used in constructing devices that are subject to attunement wand
regtech('gravity_manipulator', 'Gravity Manipulator', {metal = 1})
regtech('valve','Valve', {metal = 1}, {
	{'','default:bronze_ingot',''};
	{'basic_materials:plastic_sheet','basic_materials:steel_bar','basic_materials:plastic_sheet'};
	{'','default:bronze_ingot',''};
},3,nil, mprop('bronze',2*4,1,2*4))
regtech('pipe','Pipe', {metal = 1}, {
	{ingot('aluminum'),'',ingot('aluminum')};
	{ingot('aluminum'),'',ingot('aluminum')};
	{ingot('aluminum'),'',ingot('aluminum')};
}, 6, nil, mprop('aluminum', 4))

minetest.register_craft {
	output = 'sorcery:trough';
	recipe = {
		{ingot('aluminum'),'',ingot('aluminum')};
		{ingot('aluminum'),'',ingot('aluminum')};
		{ingot('aluminum'),ingot('aluminum'),ingot('aluminum')};

Modified wands.lua from [bc18a463a6] to [110b3cfc3f].

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
	if matprops.bond then
		local userct, found = 0, false
		for i=1,matprops.bond do
			local prop = 'bound_user_' .. tostring(i)
			if meta:contains(prop) then
				userct = i
				local name = meta:get_string(prop)
				print('wand bound to',name,i)
				if name == user:get_player_name() then found = true break end
			else break end
		end
		
		if not found then
			if userct < matprops.bond then
				print('binding wand to caster')
				minetest.sound_play("xdecor_enchanting", { --FIXME make own sounds
					pos = user:get_pos();
					gain = 0.8;
				})
				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(25,129,255), 2)
				meta:set_string('bound_user_' .. tostring(userct+1), user:get_player_name())
				return stack







|






|







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
	if matprops.bond then
		local userct, found = 0, false
		for i=1,matprops.bond do
			local prop = 'bound_user_' .. tostring(i)
			if meta:contains(prop) then
				userct = i
				local name = meta:get_string(prop)
				-- print('wand bound to',name,i)
				if name == user:get_player_name() then found = true break end
			else break end
		end
		
		if not found then
			if userct < matprops.bond then
				-- print('binding wand to caster')
				minetest.sound_play("xdecor_enchanting", { --FIXME make own sounds
					pos = user:get_pos();
					gain = 0.8;
				})
				sorcery.vfx.cast_sparkle(user, sorcery.lib.color(25,129,255), 2)
				meta:set_string('bound_user_' .. tostring(userct+1), user:get_player_name())
				return stack