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: |
3354e2aa299c7c61b777ae0c5bc03033 |
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 60 -- can't mutate table while we're iterating it 61 61 if not minetest.registered_nodes[g] then bad[#bad+1] = g end 62 62 end 63 63 for _, g in ipairs(bad) do god.gifts[g] = nil end 64 64 end 65 65 end) 66 66 67 -local std_god_interval = 70 67 +local std_god_interval = 40 68 68 69 69 for name, god in pairs(sorcery.data.gods) do 70 70 local hitbox = { 71 71 0-(god.idol.width / 2.0), 0-(god.idol.height / 2.0), -0.15, 72 72 god.idol.width / 2.0, god.idol.height / 2.0, 0.15 73 73 } -- {xmin, ymin, zmin, 74 74 -- xmax, ymax, zmax} in nodes from node center. ................................................................................ 76 76 if god.idol.craft then 77 77 minetest.register_craft { 78 78 output = 'sorcery:idol_' .. name; 79 79 recipe = god.idol.craft; 80 80 }; 81 81 end 82 82 local god_interval = std_god_interval * (god.freq or 1) 83 + local add_sparkles = function(pos,divine_favor) 84 + divine_favor = divine_favor or minetest.get_meta(pos):get_int('favor') 85 + if divine_favor > 5 then 86 + local ct = divine_favor / 5 87 + minetest.add_particlespawner { 88 + texture = L.image('sorcery_glitter.png'):glow(L.color(god.color)):render(); 89 + glow = 14; 90 + amount = ct / (1 / god_interval), time = god_interval; 91 + minpos = pos:offset(-0.4, -0.5, -0.4); 92 + maxpos = pos:offset( 0.4,god.idol.height-0.5,0.4); 93 + minvel = vector.new(0, 0.05, 0); 94 + minvel = vector.new(0, 0.1, 0); 95 + minacc = vector.new(0, 0.1, 0); 96 + maxacc = vector.new(0, 0.2, 0); 97 + minexptime = 4, maxexptime = 4; 98 + minsize = 0.3, maxsize = 1; 99 + animation = { 100 + type = 'vertical_frames'; 101 + length = 0.1; 102 + aspect_w = 16, aspect_h = 16; 103 + } 104 + } 105 + end 106 + end 83 107 sorcery.lib.node.reg_autopreserve('sorcery:idol_' .. name, { 84 108 description = god.idol.desc; 85 109 drawtype = "mesh"; 86 110 mesh = 'sorcery-idol-' .. name .. '.obj'; 87 111 paramtype = 'light'; 88 112 paramtype2 = 'facedir'; 89 113 sunlight_propagates = true; 90 114 stack_max = 1; 91 115 tiles = god.idol.tex; 92 116 selection_box = { type = "fixed"; fixed = {hitbox}; }; 93 117 collision_box = { type = "fixed"; fixed = {hitbox}; }; 94 - groups = { cracky = 2, sorcery_idol = 1, heavy = 1, sorcery_worship = 1}; 118 + groups = { cracky = 2, sorcery_idol = 1, heavy = 1, sorcery_worship = 1, sorcery_instantiate = 1}; 119 + _sorcery = { 120 + idol_god = name; 121 + on_load = function(pos) add_sparkles(pos) end; 122 + }; 95 123 96 124 on_construct = function(pos) 97 125 minetest.get_node_timer(pos):start(god_interval) 126 + add_sparkles(pos) 98 127 end; 99 128 100 129 on_timer = function(pos, elapsed) 101 130 local altar = minetest.find_node_near(pos, 3, "sorcery:altar") 102 131 -- TODO even without an altar, an idol with high favor could still be the source of miracles 103 132 -- refills nearby partly empty troughs at cost to favor? 104 133 if not altar then return true end 105 134 106 135 local altarmeta = minetest.get_meta(altar) 107 136 local inv = altarmeta:get_inventory() 108 137 local idolmeta = minetest.get_meta(pos) 109 138 local divine_favor = idolmeta:get_int('favor') 110 - if divine_favor > 5 then 111 - local ct = divine_favor / 5 112 - minetest.add_particlespawner { 113 - texture = L.image('sorcery_glitter.png'):glow(L.color(god.color)):render(); 114 - glow = 14; 115 - amount = ct / (1 / god_interval), time = god_interval; 116 - minpos = pos:offset(-0.4, -0.5, -0.4); 117 - maxpos = pos:offset( 0.4,god.idol.height-0.5,0.4); 118 - minvel = vector.new(0, 0.05, 0); 119 - minvel = vector.new(0, 0.1, 0); 120 - minacc = vector.new(0, 0.1, 0); 121 - maxacc = vector.new(0, 0.2, 0); 122 - minexptime = 4, maxexptime = 4; 123 - minsize = 0.3, maxsize = 1; 124 - animation = { 125 - type = 'vertical_frames'; 126 - length = 0.1; 127 - aspect_w = 16, aspect_h = 16; 128 - } 129 - } 130 - end 139 + add_sparkles(pos,divine_favor) 131 140 local bestow = function(item,color) 132 141 if type(item) == 'string' then 133 142 item = ItemStack(item) 134 143 end 135 144 if color == nil then 136 145 color = sorcery.lib.color(god.color) 137 146 end ................................................................................ 193 202 -- we pick a random gift and roll against its rarity 194 203 -- to determine if the god is feeling generous 195 204 local gift = sorcery.lib.tbl.pick(god.gifts) 196 205 local data = god.gifts[gift] 197 206 local value, rarity = data[1], data[2] 198 207 if value <= divine_favor and math.random(rarity) == 1 then 199 208 bestow(gift) 200 - log.act(god.name .. ' has produced ' .. gift .. ' upon an altar as a gift') 209 + log.act(god.name,'has produced',gift,'upon an altar as a gift') 201 210 if math.random(god.generosity) == 1 then 202 211 -- unappreciated gifts may incur divine 203 212 -- irritation 204 213 divine_favor = divine_favor - 1 205 214 end 206 215 end 207 216 end ................................................................................ 231 240 -- the gods are getting bored 232 241 value = math.floor(value / 2) 233 242 end 234 243 bestow(nil) 235 244 end 236 245 divine_favor = divine_favor + value 237 246 238 - print(god.name.." has accepted a sacrifice of "..s..", raising divine favor by "..value.." points to "..divine_favor) 247 + 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)) 248 + 239 249 idolmeta:set_string('last_sacrifice', s) 240 250 241 251 goto refresh 242 252 end 243 253 end 244 254 245 255 -- loop through the list of things this god will consecrate and
Modified data/gods.lua from [6a04c7ee36] to [39659f8d92].
30 30 {'default:obsidian_shard','stairs:slab_goldblock','default:bronze_ingot'}; 31 31 }; 32 32 }; 33 33 bless = { 34 34 potions = {}; 35 35 tools = {}; 36 36 }; 37 - gifts = {}; 37 + gifts = { 38 + ['sorcery:screw_steel'] = {7,1}; 39 + ['sorcery:pipe'] = {16,2}; 40 + ['sorcery:valve'] = {18,3}; 41 + ['sorcery:fragment_vidrium'] = {20,4}; 42 + ['sorcery:fragment_lithium'] = {23,5}; 43 + ['sorcery:screw_platinum'] = {31,5}; 44 + ['sorcery:screw_tungsten'] = {33,5}; 45 + ['sorcery:powder_firestorm'] = {48,7}; 46 + }; 38 47 consecrate = { 39 48 ["sorcery:dagger"] = {17, "sorcery:dagger_consecrated"}; 40 49 ["sorcery:oil_mystic"] = {9, "sorcery:oil_purifying"}; 41 50 ["sorcery:potion_water"] = {4, "sorcery:holy_water"}; 42 51 ["default:paper"] = function(ctx) 43 52 local stack = ItemStack('sorcery:recipe') 44 - local mode = select(2,L.tbl.pick{'cook','craft','infuse','grind','enchant'}) 53 + local mode = select(2,L.tbl.pick{'cook','craft','grind','enchant'}) 45 54 sorcery.cookbook.setrecipe(stack, mode, nil, { 46 55 pred = function(c) 47 56 local me = ctx.god 57 + local g = function(n) 58 + return minetest.get_item_group(c.item, n) ~= 0 59 + end 48 60 if (mode == 'enchant' or 49 - minetest.get_item_group(c.item, 'sorcery_magical') ~= 0 or 50 - minetest.get_item_group(c.item, 'sorcery_magitech') ~= 0 or 51 - minetest.get_item_group(c.item, 'sorcery_ley_device') ~= 0 or 52 - minetest.get_item_group(c.item, 'sorcery_tech') ~= 0 or 53 - minetest.get_item_group(c.item, 'crafttool') ~= 0 or 54 - me.sacrifice [c.item] or 55 - me.consecrate[c.item]) and 56 - mod ~= 'farming' 61 + (ctx.favor > 35 and (g 'sorcery_magical' 62 + or g 'sorcery_magitech' 63 + or g 'sorcery_ley_device')) 64 + or g 'sorcery_tech' 65 + or g 'crafttool' 66 + or me.sacrifice [c.item] 67 + or me.consecrate[c.item]) 68 + and mod ~= 'farming' 57 69 then return true end 58 70 end; 59 71 }) 60 - return 6, stack 72 + return 3, stack 61 73 end; 62 74 -- ["default:gold_ingot"] = {15, "sorcery:holy_token_magic"}; 63 75 }; 64 76 sacrifice = { 65 - ['sorcery:essence_frost'] = 25; 66 - ['sorcery:essence_flame'] = 25; 67 - ['sorcery:essence_force'] = 30; 77 + ['sorcery:essence_frost'] = 15; 78 + ['sorcery:essence_flame'] = 15; 79 + ['sorcery:essence_force'] = 20; 68 80 69 - ['sorcery:gem_luxite'] = 6; 70 - ['sorcery:gem_ruby'] = 10; 71 - ['sorcery:gem_amethyst'] = 16; 72 - ['sorcery:gem_sapphire'] = 25; 73 - ['sorcery:gem_emerald'] = 34; 74 - ['default:mese_crystal'] = 42; 75 - ['default:diamond'] = 50; 81 + ['sorcery:gem_luxite'] = 4; 82 + ['sorcery:gem_ruby'] = 7; 83 + ['sorcery:gem_amethyst'] = 9; 84 + ['sorcery:gem_sapphire'] = 12; 85 + ['sorcery:gem_emerald'] = 14; 86 + ['default:mese_crystal'] = 18; 87 + ['default:diamond'] = 25; 76 88 77 - ['sorcery:gem_luxite_amulet'] = 20; 78 - ['sorcery:gem_ruby_amulet'] = 35; 79 - ['sorcery:gem_amethyst_amulet'] = 48; 80 - ['sorcery:gem_sapphire_amulet'] = 56; 81 - ['sorcery:gem_emerald_amulet'] = 63; 82 - ['sorcery:gem_mese_amulet'] = 78; 83 - ['sorcery:gem_diamond_amulet'] = 91; 89 + ['sorcery:gem_luxite_amulet'] = 8; 90 + ['sorcery:gem_ruby_amulet'] = 14; 91 + ['sorcery:gem_amethyst_amulet'] = 18; 92 + ['sorcery:gem_sapphire_amulet'] = 23; 93 + ['sorcery:gem_emerald_amulet'] = 14; 94 + ['sorcery:gem_mese_amulet'] = 36; 95 + ['sorcery:gem_diamond_amulet'] = 50; 84 96 85 97 ['sorcery:oil_mystic'] = 2; 86 - ['sorcery:oil_berry'] = 4; 87 - ['sorcery:oil_wind'] = 6; 88 - ['sorcery:oil_bleak'] = 6; 89 - ['sorcery:oil_stone'] = 7; 90 - ['sorcery:oil_mushroom'] = 8; 91 - ['sorcery:oil_flame'] = 8; 92 - ['sorcery:oil_dawn'] = 11; 93 - ['sorcery:oil_luscious'] = 12; 94 - ['sorcery:oil_luck'] = 16; 98 + ['sorcery:oil_berry'] = 3; 99 + ['sorcery:oil_wind'] = 4; 100 + ['sorcery:oil_bleak'] = 4; 101 + ['sorcery:oil_stone'] = 5; 102 + ['sorcery:oil_mushroom'] = 6; 103 + ['sorcery:oil_flame'] = 7; 104 + ['sorcery:oil_dawn'] = 8; 105 + ['sorcery:oil_luscious'] = 9; 106 + ['sorcery:oil_luck'] = 11; 95 107 ['sorcery:oil_sagnuine'] = -15; 96 108 97 - ['sorcery:grease_fog'] = 17; 98 - ['sorcery:grease_pine'] = 18; 99 - ['sorcery:grease_storm'] = 20; 100 - ['sorcery:grease_whisper'] = 21; 101 - ['sorcery:grease_thunder'] = 22; 102 - ['sorcery:grease_enchanting'] = 24; 103 - ['sorcery:grease_lift'] = 32; 109 + ['sorcery:grease_fog'] = 15; 110 + ['sorcery:grease_pine'] = 16; 111 + ['sorcery:grease_storm'] = 18; 112 + ['sorcery:grease_whisper'] = 19; 113 + ['sorcery:grease_thunder'] = 20; 114 + ['sorcery:grease_enchanting'] = 22; 115 + ['sorcery:grease_lift'] = 28; 104 116 ['sorcery:grease_war'] = -5; 105 117 106 - ['sorcery:warding_plate'] = 6; 118 + ['sorcery:warding_plate'] = 5; 107 119 ['sorcery:ley_puncture'] = 8; 108 120 ['sorcery:pulse_rectifier'] = 8; 109 121 ['sorcery:current_felicitator'] = 12; 110 - ['sorcery:infuser_concentrator'] = 15; 111 - ['sorcery:infuser_tube'] = 23; 112 - ['sorcery:inverter_coil'] = 31; 113 - ['sorcery:inversion_matrix'] = 70; 114 - ['sorcery:inferno_crystal'] = 75; 115 - ['sorcery:beam_generator'] = 83; 116 - ['sorcery:field_emitter'] = 92; 117 - ['sorcery:catalytic_converter'] = 95; 118 - ['sorcery:gravity_manipulator'] = 97; 122 + ['sorcery:infuser_concentrator'] = 7; 123 + ['sorcery:infuser_tube'] = 9; 124 + ['sorcery:inverter_coil'] = 10; 125 + ['sorcery:inversion_matrix'] = 22; 126 + ['sorcery:inferno_crystal'] = 24; 127 + ['sorcery:beam_generator'] = 27; 128 + ['sorcery:field_emitter'] = 30; 129 + ['sorcery:catalytic_converter'] = 30; 130 + ['sorcery:gravity_manipulator'] = 50; 119 131 120 - ['sorcery:core_syncretic'] = 64; 121 - ['sorcery:core_mandatic'] = 53; 122 - ['sorcery:core_praxic'] = 72; 123 - ['sorcery:core_counterpraxic'] = 31; 132 + ['sorcery:core_syncretic'] = 25; 133 + ['sorcery:core_mandatic'] = 27; 134 + ['sorcery:core_praxic'] = 29; 135 + ['sorcery:core_counterpraxic'] = 17; 124 136 125 137 ['sorcery:sap'] = 1; 126 138 ['sorcery:sap_apple'] = 2; 127 139 ['sorcery:sap_aspen'] = 3; 128 140 ['sorcery:sap_pine'] = 3; 129 141 ['sorcery:sap_jungle'] = 4; 130 142 ['sorcery:sap_acacia'] = 5;
Added global.lua version [3ad50b0db8].
1 +-- abuses the engine to provide additional generic features useful to multiple units 2 +local log = sorcery.logger 'global' 3 + 4 +minetest.register_lbm { 5 + name = 'sorcery:activate_nodes'; 6 + label = 'trigger instantiation-time callbacks'; 7 + nodenames = { 'group:sorcery_instantiate' }; 8 + run_at_every_load = true; 9 + action = function(pos,node) 10 + local s = minetest.registered_nodes[node.name]._sorcery 11 + if not s or not s.on_load then 12 + log.errf('node type "%s" marked for instantiation-time callback, but no callback specified', node.name) 13 + return 14 + end 15 + 16 + s.on_load(pos,node) 17 + end; 18 +}
Modified init.lua from [3b59932455] to [1fc924b85b].
163 163 end 164 164 end 165 165 sorcery.registry.mk('residue',false) 166 166 end 167 167 168 168 sorcery.stage('startup',data) 169 169 for _,u in pairs { 170 - 'vfx'; 'context'; 'attunement'; 'itemclass'; 'craft'; 'spell'; 170 + 'global'; 'vfx'; 'context'; 'attunement'; 'itemclass'; 'craft'; 'spell'; 171 171 'liquid'; 'tree'; 'potions'; 'metal', 'gems'; 'leylines'; 172 172 'infuser'; 'altar'; 'wands'; 'tools', 'crafttools'; 173 173 'enchanter'; 'harvester'; 'metallurgy-hot', 'metallurgy-cold'; 174 174 'entities'; 'recipes'; 'coins'; 'interop'; 175 175 'tnodes'; 'forcefield'; 'farcaster'; 'portal'; 176 176 'cookbook', 'writing'; 'disassembly'; 'displacer'; 177 177 'gravitator'; 'precipitator'; 'calendar', 'astrolabe';
Modified liquid.lua from [02b94765c1] to [7230727dfc].
132 132 node_box = { type = 'fixed', fixed = mkbox(i) }; 133 133 tiles = { 134 134 top:render(); 135 135 'sorcery_trough_side.png'; 136 136 'sorcery_trough_bottom.png'; 137 137 }; 138 138 _sorcery = { 139 + material = liq == nil and { 140 + metal = true; 141 + name = 'aluminum'; 142 + data = sorcery.data.metals.aluminum; 143 + value = 7*4; 144 + } or nil; 139 145 container = { 140 146 type = 'bucket'; 141 147 hold = 'liquid'; 142 148 has = liq and liq.id; 143 149 charge = liq and Q * i; 144 150 empty = 'sorcery:trough'; 145 151 max = constants.bottles_per_trough * Q;
Modified recipes.lua from [993e34739f] to [22986aed9f].
300 300 groups = { 301 301 sorcery_magitech = 1; 302 302 sorcery_tech_component = 1; 303 303 }; 304 304 }) 305 305 306 306 307 -local regtech = function(id, desc, groups, recipe, qty, replacements) 307 +local regtech = function(id, desc, groups, recipe, qty, replacements, props) 308 308 minetest.register_craftitem('sorcery:' .. id,{ 309 309 description = desc; 310 310 inventory_image = 'sorcery_'..id..'.png'; 311 311 groups = sorcery.lib.tbl.merge({ 312 312 sorcery_magitech = 1; 313 313 sorcery_tech_component = 1; 314 314 }, groups or {}); 315 + _sorcery = props; 315 316 }) 316 317 if recipe then 317 318 minetest.register_craft { 318 319 output = string.format('sorcery:%s %u', id, qty or 1); 319 320 recipe = recipe; 320 321 replacements = replacements; 321 322 } ................................................................................ 322 323 end 323 324 end 324 325 325 326 local regcore = function(core,name) 326 327 regtech('core_'..core, name .. ' Core', {sorcery_magitech_core = 1}) 327 328 end 328 329 330 +local mprop = function(metal, amt) 331 + local gc, gv 332 + amt = amt or 1 333 + if math.floor(amt) ~= amt then 334 + if amt < 1 then 335 + gc = math.floor(1 / amt) 336 + else 337 + local n = 0 338 + for i = 2,10 do 339 + if math.floor(amt * i) == amt * i then 340 + n = i 341 + break 342 + end 343 + end 344 + if n == 0 then error "can't determine metal value for item" end 345 + gc = i 346 + gv = amt * i 347 + end 348 + else 349 + gc = 1 350 + gv = amt 351 + end 352 + return { material = { 353 + metal = true; id = metal; 354 + data = sorcery.data.metals[metal]; 355 + grindcost = gc; 356 + grindvalue = gv; 357 + value = amt; 358 + }} 359 +end 329 360 330 361 regtech('field_emitter', 'Field Emitter', {metal = 1}) 331 362 regtech('leyline_stabilizer', 'Leyline Stabilizer', {metal = 1}) 332 363 regtech('beam_generator', 'Beam Generator', {metal = 1}) 333 364 regtech('inversion_matrix', 'Inversion Matrix', {metal = 1}) 334 365 regtech('inverter_coil', 'Inverter Coil', {metal = 1}) 335 366 regtech('suppression_matrix', 'Suppression Matrix', {metal = 1}) ................................................................................ 336 367 regtech('tuning_disc', 'Tuning Disc', {metal = 1}) 337 368 -- used in constructing devices that are subject to attunement wand 338 369 regtech('gravity_manipulator', 'Gravity Manipulator', {metal = 1}) 339 370 regtech('valve','Valve', {metal = 1}, { 340 371 {'','default:bronze_ingot',''}; 341 372 {'basic_materials:plastic_sheet','basic_materials:steel_bar','basic_materials:plastic_sheet'}; 342 373 {'','default:bronze_ingot',''}; 343 -},3) 374 +},3,nil, mprop('bronze',2*4,1,2*4)) 344 375 regtech('pipe','Pipe', {metal = 1}, { 345 376 {ingot('aluminum'),'',ingot('aluminum')}; 346 377 {ingot('aluminum'),'',ingot('aluminum')}; 347 378 {ingot('aluminum'),'',ingot('aluminum')}; 348 -}, 6) 379 +}, 6, nil, mprop('aluminum', 4)) 349 380 350 381 minetest.register_craft { 351 382 output = 'sorcery:trough'; 352 383 recipe = { 353 384 {ingot('aluminum'),'',ingot('aluminum')}; 354 385 {ingot('aluminum'),'',ingot('aluminum')}; 355 386 {ingot('aluminum'),ingot('aluminum'),ingot('aluminum')};
Modified wands.lua from [bc18a463a6] to [110b3cfc3f].
223 223 if matprops.bond then 224 224 local userct, found = 0, false 225 225 for i=1,matprops.bond do 226 226 local prop = 'bound_user_' .. tostring(i) 227 227 if meta:contains(prop) then 228 228 userct = i 229 229 local name = meta:get_string(prop) 230 - print('wand bound to',name,i) 230 + -- print('wand bound to',name,i) 231 231 if name == user:get_player_name() then found = true break end 232 232 else break end 233 233 end 234 234 235 235 if not found then 236 236 if userct < matprops.bond then 237 - print('binding wand to caster') 237 + -- print('binding wand to caster') 238 238 minetest.sound_play("xdecor_enchanting", { --FIXME make own sounds 239 239 pos = user:get_pos(); 240 240 gain = 0.8; 241 241 }) 242 242 sorcery.vfx.cast_sparkle(user, sorcery.lib.color(25,129,255), 2) 243 243 meta:set_string('bound_user_' .. tostring(userct+1), user:get_player_name()) 244 244 return stack