Overview
Comment: | add cool and informative visuals for taps, add more capacity to rune forge, many bug fixes, fixed some bugs, and fixed some bugs |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
94064fe5c99fad4567c598b2e72cf80a |
User & Date: | lexi on 2021-07-04 20:27:42 |
Other Links: | manifest | tags |
Context
2021-07-05
| ||
00:59 | add Mundanity spell, bug fixes check-in: 1276138728 user: lexi tags: trunk | |
2021-07-04
| ||
20:27 | add cool and informative visuals for taps, add more capacity to rune forge, many bug fixes, fixed some bugs, and fixed some bugs check-in: 94064fe5c9 user: lexi tags: trunk | |
2021-07-03
| ||
02:25 | many bug fixers, some minor refactoring, allow non-drinkable potions to be empowered in various ways, allow gods to be petitioned for recipes (next up: cookbooks!) check-in: c71731cf58 user: lexi tags: trunk | |
Changes
Modified altar.lua from [080406f8d2] to [7e265da854].
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 ... 234 235 236 237 238 239 240 241 242 243 244 245 246 247 ... 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
local props = object:get_properties() local node = minetest.get_node(pos) props.wield_item = itemstring object:set_properties(props) object:set_yaw(math.pi*2 - node.param2*(math.pi / 2)) end end 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. paramtype = "light"; minetest.register_node('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}; after_place_node = function(pos, placer, stack, pointat) local meta = minetest.get_meta(pos) local stackmeta = stack:get_meta() meta:set_int('favor', stackmeta:get_int('favor')) meta:set_string('last_sacrifice', stackmeta:get_string('last_sacrifice')) minetest.get_node_timer(pos):start(1) end; drop = { -- for some idiot reason this is necessary for -- preserve_metadata to work right max_items = 1; items = { { items = {'sorcery:idol_' .. name} } }; }; preserve_metadata = function(pos, node, meta, newstack) newstack[1]:get_meta():from_table(meta) 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 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') local bestow = function(item,color) ................................................................................ } end -- preserve wear local gift if type(tx) == 'string' then gift = ItemStack(tx) else gift = tx end local wear = stack:get_wear() if wear > 0 then gift:set_wear(wear) end -- preserve meta local gm = gift:get_meta() gm:from_table( ................................................................................ if divine_favor >= cost then bestow(gift) divine_favor = divine_favor - cost log.act(god.name, 'has consecrated', s, 'into', tx, 'for the cost of', cost, 'points of divine favor') goto refresh end end end end ::refresh:: idolmeta:set_int('favor', divine_favor) update_altar(altar,nil) return true end; |
> > > > > > > > > > > > | | < < < < < < < < < < < < < < < < < < > > | |
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 ... 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 ... 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
local props = object:get_properties() local node = minetest.get_node(pos) props.wield_item = itemstring object:set_properties(props) object:set_yaw(math.pi*2 - node.param2*(math.pi / 2)) end end -- remove unknown gifts minetest.register_on_mods_loaded(function() for name, god in pairs(sorcery.data.gods) do local bad = {} for g in pairs(god.gifts) do -- 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) 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. paramtype = "light"; 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(1) 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') local bestow = function(item,color) ................................................................................ } end -- preserve wear local gift if type(tx) == 'string' then gift = ItemStack(tx) else gift = tx end if not gift:is_known() then goto skip end local wear = stack:get_wear() if wear > 0 then gift:set_wear(wear) end -- preserve meta local gm = gift:get_meta() gm:from_table( ................................................................................ if divine_favor >= cost then bestow(gift) divine_favor = divine_favor - cost log.act(god.name, 'has consecrated', s, 'into', tx, 'for the cost of', cost, 'points of divine favor') goto refresh end end ::skip::end end ::refresh:: idolmeta:set_int('favor', divine_favor) update_altar(altar,nil) return true end; |
Modified astrolabe.lua from [cc031237ac] to [21ab3e0c25].
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
drawtype = 'mesh'; mesh = 'sorcery-astrolabe.obj'; groups = { cracky = 2, choppy = 2; dig_immediate = 2; sorcery_tech = 1; }; selection_box = albox, collision_box = albox; after_dig_node = sorcery.lib.node.purge_containers; tiles = { 'default_steel_block.png'; 'default_bronze_block.png'; 'default_copper_block.png'; 'default_aspen_wood.png'; |
> > |
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
drawtype = 'mesh'; mesh = 'sorcery-astrolabe.obj'; groups = { cracky = 2, choppy = 2; dig_immediate = 2; sorcery_tech = 1; }; sunlight_propagates = true; paramtype = 'light'; selection_box = albox, collision_box = albox; after_dig_node = sorcery.lib.node.purge_containers; tiles = { 'default_steel_block.png'; 'default_bronze_block.png'; 'default_copper_block.png'; 'default_aspen_wood.png'; |
Modified data/elixirs.lua from [ba37716134] to [c432830d8f].
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
end; infusion = 'sorcery:grease_pine'; }; Rapidity = { color = {183,28,238}; qual = 'speed'; apply = inc('speed'); describe = function(potion) return 'good', 'Quickened', 'This potion will take effect more quiclkly and easily' end; infusion = 'sorcery:liquid_sap_acacia_bottle'; }; Purity = { color = {244,255,255}; qual = 'purity'; apply = inc('purity'); describe = function(potion) return 'good', 'purified', 'This potion\'s impurities and undesirable side effects are diminished or eliminated' end; infusion = 'sorcery:oil_purifying'; }; Beauty = { color = {255,20,226}; qual = 'beauty'; apply = inc('beauty'); describe = function(potion) |
| | |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
end; infusion = 'sorcery:grease_pine'; }; Rapidity = { color = {183,28,238}; qual = 'speed'; apply = inc('speed'); describe = function(potion) return 'good', 'quickened', 'This potion will take effect more quickly and easily' end; infusion = 'sorcery:liquid_sap_acacia_bottle'; }; Purity = { color = {244,255,255}; qual = 'purity'; apply = inc('purity'); describe = function(potion) return 'good', 'purified', 'This potion\'s impurities and undesirable qualities are diminished or eliminated' end; infusion = 'sorcery:oil_purifying'; }; Beauty = { color = {255,20,226}; qual = 'beauty'; apply = inc('beauty'); describe = function(potion) |
Modified gems.lua from [68440cd05e] to [12e0882fa3].
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
end if not gem.foreign_amulet then local img = sorcery.lib.image local img_stone = img('sorcery_amulet.png'):multiply(sorcery.lib.color(gem.tone)) local img_sparkle = img('sorcery_amulet_sparkle.png') local useamulet = function(stack,user,target) local sp = sorcery.amulet.getspell(stack) if not sp or not sp.cast then return nil end local usedamulet if stack:get_count() == 1 then usedamulet = stack else usedamulet = ItemStack(stack) usedamulet:set_count(1) |
> |
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
end
if not gem.foreign_amulet then
local img = sorcery.lib.image
local img_stone = img('sorcery_amulet.png'):multiply(sorcery.lib.color(gem.tone))
local img_sparkle = img('sorcery_amulet_sparkle.png')
local useamulet = function(stack,user,target)
local sp = sorcery.amulet.getspell(stack)
print('got spell',dump(sp))
if not sp or not sp.cast then return nil end
local usedamulet if stack:get_count() == 1 then
usedamulet = stack
else
usedamulet = ItemStack(stack)
usedamulet:set_count(1)
|
Modified infuser.lua from [0b21397e89] to [fedc837bad].
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
local inv = meta:get_inventory() local infusion = inv:get_list('infusion') local potions = inv:get_list('potions') local elixir = infusion[1]:get_definition() local probe = sorcery.spell.probe(pos) local fx = infuser_mods(pos) if probe.disjunction then return true end local potionct = 0 do local ingredient -- *eyeroll* if infusion[1]:is_empty() then goto cancel end ingredient = infusion[1]:get_name() for i = 1,#potions do if potions[i]:is_empty() then goto skip end potionct = potionct + 1 local base = potions[i]:get_name() local potion = potions[i]:get_definition() if elixir_can_apply(elixir._proto,potion) then -- at least one combination makes a valid potion; -- we can start the infuser goto start end for _,v in pairs(sorcery.register.infusions.db) do if v.infuse == ingredient and v.into == base then -- at least one combination makes a valid -- potion; we can start the infuser goto start end end ::skip:: end ::cancel:: do infuser_stop(pos) return false end ::start:: end ................................................................................ type = "vertical_frames"; aspect_h = 16; aspect_w = 16; length = 4.1; }; } end -- for i=0,4 do spawn('sorcery_spark.png^[multiply:#FF8FDD', 1, 32 * 4) -- end -- for i=0,4 do spawn('sorcery_spark.png^[multiply:#FFB1F6', 0.5, 64 * 4) -- end local discharge = sorcery.lib.node.discharger(pos) if newtime >= infusion_time then -- finished local ingredient = infusion[1]:get_name() local result, residue = sorcery.alchemy.infuse(infusion[1], potions) for i, r in pairs(result) do |
>
>
|
>
>
>
|
>
>
>
|
|
|
|
|
|
>
>
|
|
|
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
local inv = meta:get_inventory() local infusion = inv:get_list('infusion') local potions = inv:get_list('potions') local elixir = infusion[1]:get_definition() local probe = sorcery.spell.probe(pos) local fx = infuser_mods(pos) local sparkle_color = {sorcery.lib.color(255, 0, 145)}; if probe.disjunction then return true end local potionct = 0 local cancel = true do local ingredient -- *eyeroll* if infusion[1]:is_empty() then goto cancel end ingredient = infusion[1]:get_name() for i = 1,#potions do if potions[i]:is_empty() then goto skip end potionct = potionct + 1 local base = potions[i]:get_name() local potion = potions[i]:get_definition() if elixir_can_apply(elixir._proto,potion) then -- at least one combination makes a valid potion; -- we can start the infuser if elixir._proto.color then sparkle_color[#sparkle_color+1] = sorcery.lib.color(elixir._proto.color) end cancel = false end for _,v in pairs(sorcery.register.infusions.db) do if v.infuse == ingredient and v.into == base then -- at least one combination makes a valid -- potion; we can start the infuser if v.output.data and v.output.data.color then sparkle_color[#sparkle_color+1] = sorcery.lib.color(v.output.data.color) end cancel = false end end ::skip:: end ::cancel:: if cancel then infuser_stop(pos) return false end ::start:: end ................................................................................ type = "vertical_frames"; aspect_h = 16; aspect_w = 16; length = 4.1; }; } end local spark = sorcery.lib.image('sorcery_spark.png') for i = 1,4 do local fac = 1 / i local _, spc = sorcery.lib.tbl.pick(sparkle_color) local sp = spark:glow(spc) spawn(sp:render(), fac, (32/fac) * 4) end local discharge = sorcery.lib.node.discharger(pos) if newtime >= infusion_time then -- finished local ingredient = infusion[1]:get_name() local result, residue = sorcery.alchemy.infuse(infusion[1], potions) for i, r in pairs(result) do |
Modified keg.lua from [5c653d450d] to [59c6df911a].
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 ... 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 ... 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
m:set_int('charge',0) else m:set_int('charge', amtleft) end sorcery.liquid.sound_dip(chg,avail,pos) update() -- fancy visuals local color = sorcery.lib.color(liq.color or {255,255,255}) local spritz = sorcery.lib.image('sorcery_droplet.png') local drop = sorcery.lib.image('sorcery_drop.png') spritz = spritz:blit(spritz:multiply(color)) drop = drop:blit (drop:multiply (color)) local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2) local noz = vector.add(pos, vector.rotate( vector.new(0.0,0,-0.48), vector.dir_to_rotation(facing) )) local minnoz = vector.offset(noz, -0.03, -0.32, -0.03); local maxnoz = vector.offset(noz, 0.03, -0.32, 0.03); ................................................................................ minsize = 0.4, maxsize = 1; glow = 14; -- FIXME liquid glow prop minexptime = 0.5, maxexptime = 0.5; animation = { type = 'sheet_2d'; frames_w = 14; frames_h = 1; frame_length = 0.5/14; } } minetest.after(0.2, function() minetest.add_particlespawner { amount = math.random(5,11) * chg, time = 0.13 * chg; texture = drop:render(); minpos = vector.offset(minnoz, 0,-0.05,0); ................................................................................ minsize = 0.3, maxsize = 0.5; glow = 14; -- FIXME liquid glow prop minexptime = 1, maxexptime = 1.5; animation = { type = 'sheet_2d'; frames_w = 10; frames_h = 1; frame_length = 1.5/10; } } end) return filled end end |
| | < < | | |
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 ... 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 ... 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
m:set_int('charge',0) else m:set_int('charge', amtleft) end sorcery.liquid.sound_dip(chg,avail,pos) update() -- fancy visuals local color = sorcery.lib.color(liq.color or {255,255,255}) local spritz = sorcery.lib.image('sorcery_droplet.png'):glow(color) local drop = sorcery.lib.image('sorcery_drop.png'):glow(color) local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2) local noz = vector.add(pos, vector.rotate( vector.new(0.0,0,-0.48), vector.dir_to_rotation(facing) )) local minnoz = vector.offset(noz, -0.03, -0.32, -0.03); local maxnoz = vector.offset(noz, 0.03, -0.32, 0.03); ................................................................................ minsize = 0.4, maxsize = 1; glow = 14; -- FIXME liquid glow prop minexptime = 0.5, maxexptime = 0.5; animation = { type = 'sheet_2d'; frames_w = 14; frames_h = 1; frame_length = (0.5/14) + 0.02; } } minetest.after(0.2, function() minetest.add_particlespawner { amount = math.random(5,11) * chg, time = 0.13 * chg; texture = drop:render(); minpos = vector.offset(minnoz, 0,-0.05,0); ................................................................................ minsize = 0.3, maxsize = 0.5; glow = 14; -- FIXME liquid glow prop minexptime = 1, maxexptime = 1.5; animation = { type = 'sheet_2d'; frames_w = 10; frames_h = 1; frame_length = (1.5/10) + 0.02; } } end) return filled end end |
Modified lib/node.lua from [087023acf7] to [3dbeb921b1].
358 359 360 361 362 363 364 365 |
end
return i, false
end
else
return function(i) return i, false end
end
end;
}
|
| > > > > > > > > > > > > > > > > > > > > > > > |
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 387 388 |
end return i, false end else return function(i) return i, false end end end; autopreserve = function(id, tbl) tbl.drop = tbl.drop or { max_items = 1; items = { { items = {id} }; }; } local next_apn = tbl.after_place_node tbl.after_place_node = function(...) local pos, who, stack = ... minetest.get_meta(pos):from_table(stack:get_meta():to_table()) if next_apn then return next_apn(...) end end local next_pm = tbl.preserve_metadata tbl.preserve_metadata = function(...) local pos, node, meta, drops = ... drops[1]:get_meta():from_table({fields = meta}) if next_pm then return next_pm(...) end end return tbl end; reg_autopreserve = function(id, tbl) minetest.register_node(id, sorcery.lib.node.autopreserve(id, tbl)) end; } |
Modified liquid.lua from [6a40bd16e3] to [02b94765c1].
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 ... 244 245 246 247 248 249 250 251 252 253 254 255 256 257 ... 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
L.image(fmt('sorcery_liquid_%s.png', liq.imgvariant or 'dull')) :multiply(L.color(liq.color))):render() -- local img_glass = L.image('vessels_drinking_glass.png'):blit( -- L.image(fmt('sorcery_liquid_glass_%s.png', liq.imgvariant or 'dull')) -- :multiply(L.color(liq.color))) minetest.register_node(':'..bottle, { description = liq.desc_bottle or fmt('%s Bottle', L.str.capitalize(liq.name)); inventory_image = img_bottle; drawtype = 'plantlike', tiles = {img_bottle}; is_ground_content = false, walkable = false; sunlight_propagates = true, paramtype = 'light'; light_source = liq.glow or 0; selection_box = { type = 'fixed', fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }; ................................................................................ pos = pos; }, true) end; sorcery.liquid.sound_dip = function(amt_output, amt_basin, pos) sorcery.liquid.sound_pour(amt_output, amt_basin, pos) end; -- pre-register basic liquids used in Sorcery and common ones sorcery depends on sorcery.liquid.register{ id = 'default:water'; name = 'water'; kind = 'default:drink'; ................................................................................ ['vessels:glass_bottle'] = 'sorcery:blood'; }; } minetest.register_abm { label = 'Rainfall'; nodenames = {'group:sorcery_collect_rainwater'}; interval = 230; chance = 40; min_y = -400; catch_up = true; action = function(pos, node) -- TODO vary by season and biome? if minetest.get_natural_light(vector.offset(pos,0,1,0), 0.5) >= 15 then if node.name == 'sorcery:trough' then node.name = 'default:trough_water_1' |
| > | | |
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 ... 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 ... 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
L.image(fmt('sorcery_liquid_%s.png', liq.imgvariant or 'dull')) :multiply(L.color(liq.color))):render() -- local img_glass = L.image('vessels_drinking_glass.png'):blit( -- L.image(fmt('sorcery_liquid_glass_%s.png', liq.imgvariant or 'dull')) -- :multiply(L.color(liq.color))) sorcery.lib.node.reg_autopreserve(':'..bottle, { description = liq.desc_bottle or fmt('%s Bottle', L.str.capitalize(liq.name)); inventory_image = img_bottle; drawtype = 'plantlike', tiles = {img_bottle}; is_ground_content = false, walkable = false; sunlight_propagates = true, paramtype = 'light'; light_source = liq.glow or 0; selection_box = { type = 'fixed', fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }; ................................................................................ pos = pos; }, true) end; sorcery.liquid.sound_dip = function(amt_output, amt_basin, pos) sorcery.liquid.sound_pour(amt_output, amt_basin, pos) end; -- pre-register basic liquids used in Sorcery and common ones sorcery depends on sorcery.liquid.register{ id = 'default:water'; name = 'water'; kind = 'default:drink'; ................................................................................ ['vessels:glass_bottle'] = 'sorcery:blood'; }; } minetest.register_abm { label = 'Rainfall'; nodenames = {'group:sorcery_collect_rainwater'}; interval = 120; chance = 27; min_y = -400; catch_up = true; action = function(pos, node) -- TODO vary by season and biome? if minetest.get_natural_light(vector.offset(pos,0,1,0), 0.5) >= 15 then if node.name == 'sorcery:trough' then node.name = 'default:trough_water_1' |
Modified potions.lua from [0b54227d82] to [1dfd3579b4].
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
drawtype = "plantlike"; tiles = {image}; inventory_image = image; paramtype = "light"; is_ground_content = false; light_source = glow and math.min(minetest.LIGHT_MAX,glow) or 0; drop = 'sorcery:' .. name; preserve_metadata = function(pos,node,meta,newstack) newstack[1]:get_meta():from_table(meta) end; walkable = false; selection_box = { type = "fixed", fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }; on_construct = function(pos) minetest.get_meta(pos):set_string('infotext',label) ................................................................................ } if extra then for k,v in pairs(extra) do node[k] = v end end if not node.groups then node.groups = {} end node.groups.dig_immediate = 3; node.groups.attached_node = 1; node.groups.vessel = 1; node.groups.not_in_creative_inventory = 1; minetest.register_node("sorcery:"..name, node) end sorcery.register_oil = function(name,label,desc,color,imgvariant,extra) local image = 'xdecor_bowl.png^(sorcery_oil_' .. (imgvariant or 'dull') .. '.png^[colorize:'..tostring(color)..':140)' sorcery.register.residue.link('sorcery:' .. name, 'xdecor:bowl') extra.description = label; extra.inventory_image = image; |
<
<
<
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
drawtype = "plantlike"; tiles = {image}; inventory_image = image; paramtype = "light"; is_ground_content = false; light_source = glow and math.min(minetest.LIGHT_MAX,glow) or 0; drop = 'sorcery:' .. name; walkable = false; selection_box = { type = "fixed", fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} }; on_construct = function(pos) minetest.get_meta(pos):set_string('infotext',label) ................................................................................ } if extra then for k,v in pairs(extra) do node[k] = v end end if not node.groups then node.groups = {} end node.groups.dig_immediate = 3; node.groups.attached_node = 1; node.groups.vessel = 1; node.groups.not_in_creative_inventory = 1; sorcery.lib.node.reg_autopreserve("sorcery:"..name, node) end sorcery.register_oil = function(name,label,desc,color,imgvariant,extra) local image = 'xdecor_bowl.png^(sorcery_oil_' .. (imgvariant or 'dull') .. '.png^[colorize:'..tostring(color)..':140)' sorcery.register.residue.link('sorcery:' .. name, 'xdecor:bowl') extra.description = label; extra.inventory_image = image; |
Modified runeforge.lua from [65aa0a1ed6] to [b7d5d6135c].
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 .. 89 90 91 92 93 94 95 96 97 98 99 100 101 102 ... 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 ... 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 ... 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
-- passively consumes ley-current -- -- are phials & rune-wrenches enough for this now? local constants = { rune_mine_interval = 240; -- how often a powered forge rolls for new runes rune_cache_max = 4; -- how many runes a runeforge can hold at a time rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'}; -- how many grades of rune quality/power there are amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' }; -- what kind of amulet each rune grade translates to ................................................................................ dist = { Fragile = 0, Weak = 1, Ordinary = 0.9, Pristine = 0.5, Sublime = 0.25 }; }; supreme = {grade = 6, name = 'Supreme'; infusion = 'sorcery:powder_levitanium'; dist = { Fragile = 0, Weak = 0, Ordinary = 1, Pristine = 0.7, Sublime = 0.4 }; }; }; } local calc_phial_props = function(phial) --> mine interval: float, time factor: float local m = phial:get_meta() local g = phial:get_definition()._proto.data.grade local i = constants.rune_mine_interval local fac = (g-1) / 5 fac = fac + 0.4 * m:get_int('speed') return i - ((i*0.5) * fac), 0.5 * fac end sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune) local id = 'sorcery:rune_' .. name rune.image = rune.image or string.format('sorcery_rune_%s.png',name) rune.item = id local c = sorcery.lib.color(rune.tone) minetest.register_craftitem(id, { ................................................................................ _proto = { id = name, desc = desc, name = p.name, kind = phkind, data = p, quals = {force = true, speed = true}, color = color }; }; } sorcery.register.infusions.link { infuse = p.infusion; into = 'sorcery:potion_subtle'; output = 'sorcery:'..id; } end local register_rune_wrench = function(w) local mp = sorcery.data.metals[w.metal].parts minetest.register_tool(w.name, { description = w.desc; ................................................................................ local base_spell = true if proto.frame and spell.frame and spell.frame[proto.frame] then local sp = spell.frame[proto.frame] if not sp.mingrade or rg >= sp.mingrade then title = sp.name or title desc = sp.desc or desc cast = sp.desc or cast apply = sp.apply or apply remove = sp.remove or remove mingrade = sp.mingrade or mingrade base_spell = false end end ................................................................................ else break end end end has_phial = has_phial() local spec = string.format([[ formspec_version[3] size[10.25,8] real_coordinates[true] list[context;cache;%f,0.25;%u,1;] list[context;amulet;3.40,1.50;1,1;] list[context;active;5.90,1.50;1,1;] list[context;wrench;1.25,1.75;1,1;] list[context;phial;7.25,1.75;1,1;] list[context;refuse;8.50,1.75;1,1;] list[current_player;main;0.25,3;8,4;] image[0.25,0.50;1,1;sorcery_statlamp_%s.png] ]], (10.5 - constants.rune_cache_max*1.25)/2, constants.rune_cache_max, ((not (has_phial and pow_min)) and 'off' ) or ( probe.disjunction and 'blue' ) or ((has_phial and pow_max) and 'green') or 'yellow') local ghost = function(slot,x,y,img) if i:is_empty(slot) then spec = spec .. string.format([[ image[%f,%f;1,1;%s.png] ................................................................................ local max,min = 0 for _,r in pairs(sorcery.data.runes) do if r.minpower > max then max = r.minpower end if min == nil or r.minpower < min then min = r.minpower end end -- high-quality phials reduce power usage local fac = select(2, calc_phial_props(phial)) min = min * fac max = max * fac return min*time,max*time end; }; on_leychange = runeforge_update; recipe = { note = 'Periodically creates runes when sufficiently powered and can be used to imbue them into an amulet, giving it a powerful magical effect'; }; |
| | | | > > > | < > > > | | |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 .. 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 ... 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 ... 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 ... 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
-- passively consumes ley-current -- -- are phials & rune-wrenches enough for this now? local constants = { rune_mine_interval = 240; -- how often a powered forge rolls for new runes rune_cache_max = 6; -- how many runes a runeforge can hold at a time rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'}; -- how many grades of rune quality/power there are amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' }; -- what kind of amulet each rune grade translates to ................................................................................ dist = { Fragile = 0, Weak = 1, Ordinary = 0.9, Pristine = 0.5, Sublime = 0.25 }; }; supreme = {grade = 6, name = 'Supreme'; infusion = 'sorcery:powder_levitanium'; dist = { Fragile = 0, Weak = 0, Ordinary = 1, Pristine = 0.7, Sublime = 0.4 }; }; }; } local calc_phial_props = function(phial) --> mine interval: float, power factor: float local m = phial:get_meta() local g = phial:get_definition()._proto.data.grade local i = constants.rune_mine_interval local fac = (g-1) / 5 fac = fac + 0.2 * m:get_int('speed') return math.max(3,i - ((i*0.5) * fac)), 0.5 * fac end sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune) local id = 'sorcery:rune_' .. name rune.image = rune.image or string.format('sorcery_rune_%s.png',name) rune.item = id local c = sorcery.lib.color(rune.tone) minetest.register_craftitem(id, { ................................................................................ _proto = { id = name, desc = desc, name = p.name, kind = phkind, data = p, quals = {force = true, speed = true}, color = color }; }; } sorcery.register.infusions.link { infuse = p.infusion; into = 'sorcery:potion_subtle'; output = 'sorcery:'..id; _proto = { data = { color = color }; }; } end local register_rune_wrench = function(w) local mp = sorcery.data.metals[w.metal].parts minetest.register_tool(w.name, { description = w.desc; ................................................................................ local base_spell = true if proto.frame and spell.frame and spell.frame[proto.frame] then local sp = spell.frame[proto.frame] if not sp.mingrade or rg >= sp.mingrade then title = sp.name or title desc = sp.desc or desc cast = sp.cast or cast apply = sp.apply or apply remove = sp.remove or remove mingrade = sp.mingrade or mingrade base_spell = false end end ................................................................................ else break end end end has_phial = has_phial() local spec = string.format([[ formspec_version[3] size[10.25,8] real_coordinates[true] list[context;amulet;3.40,1.50;1,1;] list[context;active;5.90,1.50;1,1;] list[context;wrench;1.25,1.75;1,1;] list[context;phial;7.25,1.75;1,1;] list[context;refuse;8.50,1.75;1,1;] list[current_player;main;0.25,3;8,4;] style_type[list;size=0.8] list[context;cache;%f,0.25;%u,1;] image[0.25,0.50;1,1;sorcery_statlamp_%s.png] ]], (10.5 - 0.8*(constants.rune_cache_max*1.25))/2, constants.rune_cache_max, ((not (has_phial and pow_min)) and 'off' ) or ( probe.disjunction and 'blue' ) or ((has_phial and pow_max) and 'green') or 'yellow') local ghost = function(slot,x,y,img) if i:is_empty(slot) then spec = spec .. string.format([[ image[%f,%f;1,1;%s.png] ................................................................................ local max,min = 0 for _,r in pairs(sorcery.data.runes) do if r.minpower > max then max = r.minpower end if min == nil or r.minpower < min then min = r.minpower end end -- high-quality phials reduce power usage local fac = select(2, calc_phial_props(phial)) min = min / fac max = max / fac return min*time,max*time end; }; on_leychange = runeforge_update; recipe = { note = 'Periodically creates runes when sufficiently powered and can be used to imbue them into an amulet, giving it a powerful magical effect'; }; |
Modified tap.lua from [17fb78473a] to [9cfe073fce].
1 2 3 4 5 6 7 8 .. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 .. 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 ... 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
local log = sorcery.logger('tap') minetest.register_node('sorcery:tap',{ description = 'Tree Tap'; drawtype = 'mesh'; mesh = 'sorcery-tap.obj'; inventory_image = 'sorcery_tap_inv.png'; tiles = { 'default_copper_block.png'; ................................................................................ paramtype = 'light', paramtype2 = 'wallmounted'; selection_box = { type='fixed', fixed = {-0.2,-0.5,-0.35; 0.3,0.1,0.4} }; collision_box = { type='fixed', fixed = {-0.2,-0.5,-0.35; 0.3,0.1,0.4} }; node_placement_prediction = ''; on_place = function(stack,who,where) if where.type ~= 'node' then return end local bl = minetest.get_node(where.under) -- FIXME prevent tapping 'dead' non-tree wood blocks local tree = sorcery.tree.get(where.under) if not tree or tree.sap == false then return end; -- disallow vertical attachment if vector.subtract(where.under,where.above).y ~= 0 then return end minetest.set_node(where.above, { name = 'sorcery:tap'; param2 = minetest.dir_to_wallmounted(vector.subtract(where.under,where.above)) }) stack:take_item(1) return stack end; _sorcery = { recipe = { note = 'Extract syrups and oils from trees'; }; }; }) ................................................................................ recipe = { {'','sorcery:screw_steel','basic_materials:steel_bar'}; {'sorcery:pipe','sorcery:valve','sorcery:screw_steel'}; {'','sorcery:pipe',''}; }; } local sap_interval = 60; local abm_cache local abm_cache_time minetest.register_abm { label = 'Sap drip'; nodenames = {'sorcery:tap'}; neighbors = {'group:tree'}; interval = sap_interval; chance = 7; catch_up = true; action = function(pos, node) local now = os.time() if abm_cache_time == nil or now > abm_cache_time + (sap_interval-1) then abm_cache = { treehash = {} } abm_cache_time = now end ................................................................................ end end if (not live) or tree.sap == false or not tree.sapliq then return end if mass_trunk < 12*3 then return end -- too small local mass = mass_leaves + mass_trunk local max_mass = 400 local ltratio = mass_leaves / mass_trunk local mratio = mass / max_mass local outof = 15 / mratio local chance = math.max(1, math.floor(outof - (25 * ltratio))) / 3 |
> > > > > > < | | > > > > > > < | > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 .. 22 23 24 25 26 27 28 29 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 .. 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ... 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
local log = sorcery.logger('tap') local sap_interval = 20; local function tapdrip(liq, pos) return sorcery.vfx.drip(liq, vector.offset(pos, 0, -0.3, 0), math.random(5,12), sap_interval, 2) end minetest.register_node('sorcery:tap',{ description = 'Tree Tap'; drawtype = 'mesh'; mesh = 'sorcery-tap.obj'; inventory_image = 'sorcery_tap_inv.png'; tiles = { 'default_copper_block.png'; ................................................................................ paramtype = 'light', paramtype2 = 'wallmounted'; selection_box = { type='fixed', fixed = {-0.2,-0.5,-0.35; 0.3,0.1,0.4} }; collision_box = { type='fixed', fixed = {-0.2,-0.5,-0.35; 0.3,0.1,0.4} }; node_placement_prediction = ''; on_place = function(stack,who,where) if where.type ~= 'node' then return end local bl = minetest.get_node(where.under) local tree = sorcery.tree.get(where.under) if not tree or tree.def.sap == false then return end; -- disallow vertical attachment, bc that makes no sense if vector.subtract(where.under,where.above).y ~= 0 then return end minetest.set_node(where.above, { name = 'sorcery:tap'; param2 = minetest.dir_to_wallmounted(vector.subtract(where.under,where.above)) }) if sorcery.lib.node.tree_is_live(where.under) then -- start dripping immediately to indicate the tree is alive tapdrip(tree.def.sapliq, where.above) end stack:take_item(1) return stack end; on_screwdriver = function() return false end; _sorcery = { recipe = { note = 'Extract syrups and oils from trees'; }; }; }) ................................................................................ recipe = { {'','sorcery:screw_steel','basic_materials:steel_bar'}; {'sorcery:pipe','sorcery:valve','sorcery:screw_steel'}; {'','sorcery:pipe',''}; }; } local abm_cache local abm_cache_time minetest.register_abm { label = 'Sap drip'; nodenames = {'sorcery:tap'}; neighbors = {'group:tree'}; interval = sap_interval; chance = 4; catch_up = true; action = function(pos, node) local now = os.time() if abm_cache_time == nil or now > abm_cache_time + (sap_interval-1) then abm_cache = { treehash = {} } abm_cache_time = now end ................................................................................ end end if (not live) or tree.sap == false or not tree.sapliq then return end if mass_trunk < 12*3 then return end -- too small tapdrip(tree.sapliq,pos) local mass = mass_leaves + mass_trunk local max_mass = 400 local ltratio = mass_leaves / mass_trunk local mratio = mass / max_mass local outof = 15 / mratio local chance = math.max(1, math.floor(outof - (25 * ltratio))) / 3 |
Modified vfx.lua from [8567a33693] to [48046fb0bd].
148 149 150 151 152 153 154 |
animation = { type = 'vertical_frames', length = far/vel; aspect_w = 16, aspect_h = 16; }; } end end |
> > > > > > > > > > > > > > > > > > > > > > > > > > |
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
animation = { type = 'vertical_frames', length = far/vel; aspect_w = 16, aspect_h = 16; }; } end end function sorcery.vfx.drip(liquid, noz, amt, time, exp) if type(liquid) == 'string' then liquid = sorcery.register.liquid.db[liquid] end local minnoz = vector.offset(noz, -0.03, 0.0, -0.03); local maxnoz = vector.offset(noz, 0.03, 0.0, 0.03); local drop = sorcery.lib.image('sorcery_drop.png'):multiply(liquid.color) return minetest.add_particlespawner { amount = amt, time = time; texture = drop:render(); minpos = minnoz, maxpos = maxnoz; minvel = vector.new(0,0,0); maxvel = vector.new(0,-0.2,0); minacc = vector.new(0,-0.2,0); maxacc = vector.new(0,-0.23,0); minsize = 0.4, maxsize = 1; glow = liquid.glow or 2; minexptime = exp, maxexptime = exp; animation = { type = 'sheet_2d'; frames_w = 10; frames_h = 1; frame_length = (exp/10) + 0.01; }; vertical = true; } end |