Comment: | ui tweaks, rework enchantment slightly |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
41fdb5b0b80615f7ccde49d5172525b7 |
User & Date: | lexi on 2021-04-21 01:32:38 |
Other Links: | manifest | tags |
2021-06-23
| ||
09:31 | look i don't fucking remember okay check-in: a08f21c56c user: lexi tags: trunk | |
2021-04-21
| ||
01:32 | ui tweaks, rework enchantment slightly check-in: 41fdb5b0b8 user: lexi tags: trunk | |
2020-10-31
| ||
19:49 | add background noise for condensers (temporary hack, need to write a proper environment sound framework as the fucking env_sounds module is completely impossible to extend), fix a couple of really stupid bugs, make higher-quality phials increase the chance of getting good runes so it's not a complete waste to burn iridium or levitanium powder on making them, add targeted disjunction and some other amulet spells check-in: 15f176a7fe user: lexi tags: trunk | |
Modified cookbook.lua from [604c53eb6c] to [e643a56c3c].
29 29 dye = { caption = 'Any Dye', cnitem = 'dye:black' }; 30 30 bone = { caption = 'Any Bone', cnitem = 'bonemeal:bone' }; 31 31 vessel = { caption = 'Any Bottle', cnitem = 'vessels:glass_bottle' }; 32 32 flower = { caption = 'Any Flower', cnitem = 'flowers:rose' }; 33 33 mushroom = { caption = 'Any Mushroom', cnitem = 'flowers:mushroom_brown' }; 34 34 water_bucket = { caption = 'Water Bucket', cnitem = 'bucket:bucket_water' }; 35 35 sorcery_ley_cable = { caption = 'Cable', cnitem = 'sorcery:cable_vidrium' }; 36 + scissors = { caption = 'Scissors', cnitem = 'sorcery:scissors_steel' }; 36 37 }; 37 38 } 38 39 sorcery.cookbook.constants = constants 39 40 40 41 local slot3x3 = { 41 42 {0,0}, {1,0}, {2,0}; 42 43 {0,1}, {1,1}, {2,1}; ................................................................................ 152 153 desc = string.format("%s (%u)",desc,s:get_count()) 153 154 end 154 155 return desc 155 156 end; 156 157 157 158 local bookadjs = { -- sets are in reverse order! 158 159 {'Celestial', 'Divine', 'Inspired', 'Heavenly'; 159 - 'Mystic', 'Diabolic', 'Luminous', 'Forsaken'}; 160 + 'Mystic', 'Diabolic', 'Luminous', 'Forsaken', 161 + 'Ethereal'}; 160 162 161 163 {'Dark', 'Perfected', 'Flawless', 'Unthinkable'; 162 - 'Impossible', 'Worrisome', 'Unimpeachable'}; 164 + 'Impossible', 'Worrisome', 'Unimpeachable', 'Fulsome', 165 + 'Wise'}; 163 166 164 167 {'Splendid', 'Magnificent', 'Sublime', 'Grand'; 165 168 'Beneficent', 'Mysterious', 'Peculiar', 'Eerie'; 166 169 'Fulsome', 'Fearsome', 'Curious', 'Fascinating'; 167 - 'Notorious', 'Infamous'}; 170 + 'Notorious', 'Infamous', 'Wondrous'}; 168 171 } 169 172 170 173 local cache = { 171 174 populate_grindables = function(cache) 172 175 if not cache.grindables then 173 176 cache.grindables = {} 174 177 for k,v in pairs(minetest.registered_items) do ................................................................................ 312 315 local rec = {} 313 316 local en = sorcery.data.enchants[name] 314 317 if not en then return nil end 315 318 en = en.recipe 316 319 for i,e in pairs(en) do 317 320 if e.lens then 318 321 rec[i] = 'sorcery:lens_' .. e.lens .. '_' .. e.gem 322 + elseif e.item then 323 + rec[i] = e.item 324 + end 325 + if e.consume or (e.item and not e.dmg) then 326 + rec[i] = rec[i] .. ' ' .. tostring(e.consume or 1) -- :/ 319 327 end 320 328 end 321 329 return rec 322 330 end; 323 331 props = function(name) 324 - return sorcery.data.enchants[name].info or {} 332 + local ench = sorcery.data.enchants[name] 333 + local p = ench.info 334 + local desc = '' 335 + if ench.cost ~= 0 then 336 + desc = string.format('%s <b>%i</b> thaum-second%s of charge when tool is used', 337 + ench.cost > 0 and 'Consumes' or 'Generates', 338 + math.abs(ench.cost), 339 + ench.cost ~= 1 and 's' or '' 340 + ) 341 + end 342 + 343 + if p == nil then return {note = desc} end 344 + if p.note then return p end 345 + return sorcery.lib.tbl.proto({note = desc},p) 325 346 end; 326 347 slots = { 327 348 {0.5,0}; 328 349 {0,1}, {1,1} 329 350 }; 330 351 title = function(name) return sorcery.data.enchants[name].name end; 331 352 outdesc = function(name,suffix) 332 353 local e = sorcery.data.enchants[name] 354 + local cap = sorcery.lib.str.capitalize 355 + local aff = sorcery.data.affinities[e.affinity] 333 356 return sorcery.lib.ui.tooltip { 334 357 title = e.name; 335 - desc = sorcery.lib.str.capitalize(e.desc); 336 - color = sorcery.lib.color(e.tone):readable(); 358 + desc = cap(e.desc); 359 + color = sorcery.lib.color(e.tone); 360 + props = { 361 + { 362 + title = string.format('%s affinity', cap(e.affinity)); 363 + desc = aff.desc; 364 + color = sorcery.lib.color(aff.color); 365 + }; 366 + }; 337 367 } 338 368 end; 339 369 }; 340 370 -- spells = { 341 371 -- booksuf = 'Spellbook'; 342 372 -- slots = { 343 373 -- {0,0}, {1,0}; ................................................................................ 398 428 end 399 429 end 400 430 end 401 431 local img, ot 402 432 if props.note then 403 433 local nx, ny, nw, nh 404 434 if notes_right then 405 - nx = 5.25 ny = 0 406 - nw = 4 nh = 3 435 + nx = 5.25 - (3 - k.w) -- :/ 436 + ny = 0 437 + nw = 4 nh = k.h 407 438 else 408 439 nx = 0 ny = 3 409 - nw = 4 nh = 1 440 + nw = 4 nh = k,h 410 441 end 411 442 t = t .. string.format([[ 412 443 hypertext[%f,%f;%f,%f;note;<global valign=middle halign=justify size=20>%s] 413 444 ]], nx,ny,nw,nh, minetest.formspec_escape(props.note)) 414 445 end 415 446 if k.icon then img = k.icon(result) end 416 447 if k.outdesc then ot = k.outdesc(result) else ot = desc_builtin(result) end 417 448 -- image[%f,%f;1,1;gui_furnace_arrow_bg.png^[transformR270] 418 449 return t .. string.format([[ 419 450 item_image[%f,%f;1,1;%s]tooltip[%f,%f;1,1;%s] 420 - ]] --[[box[%f,%f;1,1;#850083A0]] .. [[ 451 + box[%f,%f;1.1,1.1;#1a001650] 421 452 %s[%f,%f;1,1;%s] 422 453 tooltip[%f,%f;1,1;%s] 423 454 ]], k.w, k.h/2 - 0.5, k.node, 424 455 k.w, k.h/2 - 0.5, minetest.formspec_escape(minetest.registered_nodes[k.node].description), 425 - -- k.w+1, k.h/2 - 0.5, 456 + k.w+1.05, k.h/2 - 0.55, 426 457 img and 'image' or 'item_image', 427 458 k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(img or result), 428 459 k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(ot)) 429 460 end; 430 461 431 462 local retrieve_recipe = function(kind,out,notes_right) 432 463 local rec = recipe_kinds[kind]
Modified data/enchants.lua from [5670d710ce] to [f66e8dbb2f].
16 16 cost = 1; 17 17 tone = {232,102,255}; 18 18 desc = 'tools last longer before wearing out'; 19 19 affinity = 'counterpraxic'; 20 20 groups = allgroups; 21 21 recipe = { 22 22 {lens = 'convex', gem = 'amethyst', dmg = 2}; 23 - {lens = 'rectifier', gem = 'emerald', dmg = 4}; 23 + {item = 'default:obsidian_shard'}; 24 24 {lens = 'convex', gem = 'emerald', dmg = 2}; 25 25 }; 26 26 apply = function(stack,power,base) 27 27 local caps = table.copy(stack:get_definition().tool_capabilities) 28 28 for g,v in pairs(caps.groupcaps) do 29 29 local unit = base.groupcaps[g].uses * 0.6 30 30 caps.groupcaps[g].uses = v.uses + unit*power ................................................................................ 42 42 groups = digtools; 43 43 affinity = 'cognic'; 44 44 cost = 1; 45 45 tone = {255,235,195}; 46 46 desc = 'Leave a trail of light hanging in the air as you dig'; 47 47 recipe = { 48 48 {lens = 'convex', gem = 'sapphire', dmg = 2}; 49 - {lens = 'concave', gem = 'ruby', dmg = 1}; 49 + {item = 'sorcery:gem_luxite_shard'}; 50 50 {lens = 'concave', gem = 'sapphire', dmg = 1}; 51 51 }; 52 52 on_dig = function(ctx) 53 53 local chance = 10 -- make dependent on power somehow? 54 54 if math.random(chance) == 1 then 55 55 local lightlevel = math.floor(math.min(minetest.LIGHT_MAX,4*ctx.power)) 56 56 -- spawn a light block ................................................................................ 69 69 cost = 0; -- energy is only depleted when repair takes place 70 70 tone = {255,84,187}; 71 71 affinity = 'syncretic'; 72 72 groups = { 73 73 'pick'; 'pickaxe'; 'sword'; 74 74 }; 75 75 recipe = { 76 - {lens = 'amplifier', gem = 'ruby', dmg = 5}; 77 - {lens = 'concave', gem = 'mese', dmg = 1}; 78 - {lens = 'concave', gem = 'sapphire', dmg = 1}; 76 + {lens = 'amplifier', gem = 'ruby', dmg = 5}; 77 + {item = 'sorcery:powder_tungsten'}; 78 + {item = 'sorcery:extract_rye'}; 79 79 }; 80 80 desc = 'some damage is repaired when used to mine ore or kill an attacker'; 81 + info = { 82 + note = 'Consumes <b>3</b> thaum-seconds of charge when repair takes place'; 83 + }; 81 84 on_dig = function(ctx) 82 85 local orepfx = "stone_with_" -- }:< 83 86 -- local oredrop = ' lump' 84 87 local barename = string.sub(ctx.node.name, string.find(ctx.node.name, ':') + 1) 85 88 if sorcery.itemclass.get(ctx.node.name,'ore') then 86 89 ctx.tool:add_wear(-(sorcery.enchant.strength(ctx.tool,'harvest') * 2000)) 87 90 ctx.cost = 3 ................................................................................ 92 95 name = 'Conserve'; 93 96 tone = {84,255,144}; 94 97 cost = 0; 95 98 desc = 'enchantments last longer before running out of power to sustain them'; 96 99 groups = allgroups; 97 100 affinity = 'syncretic'; 98 101 recipe = { 99 - {lens = 'rectifier', gem = 'mese', dmg = 7}; 102 + {item = 'default:mese_crystal_fragment'}; 100 103 {lens = 'rectifier', gem = 'sapphire', dmg = 2}; 101 104 {lens = 'rectifier', gem = 'amethyst', dmg = 2}; 102 105 }; 103 106 -- implemented in sorcery/enchanter.lua:register_on_dig 104 107 }; 105 108 dowse = { -- send up flare when valuable ores are nearby 106 109 name = 'Dowse'; 107 110 tone = {241,251,113}; 108 111 cost = 1; 109 112 desc = 'strike colored sparks when used to dig near valuable ore.'; 110 113 groups = {'pick','pickaxe'}; 111 114 affinity = 'cognic'; 112 115 recipe = { 113 - {lens = 'concave', gem = 'ruby', dmg = 3}; 116 + {item = 'sorcery:gem_luxite'}; 114 117 {lens = 'concave', gem = 'emerald', dmg = 3}; 115 118 {lens = 'concave', gem = 'sapphire', dmg = 3}; 116 119 }; 117 120 on_dig = function(ctx) 118 121 local range = 4*sorcery.enchant.strength(ctx.tool,'dowse') 119 122 local colors = { 120 123 ['default:stone_with_gold' ] = {255,234,182}; ................................................................................ 150 153 name = 'Glitter'; 151 154 cost = 10; 152 155 tone = {255,50,60}; 153 156 desc = 'dramatically improve your chances of finding gems while mining veins'; 154 157 groups = {'pick','pickaxe'}; 155 158 affinity = 'entropic'; 156 159 recipe = { 160 + {item = 'sorcery:oil_luck'}; 157 161 {lens = 'amplifier', gem = 'diamond', dmg = 12}; 158 162 {lens = 'rectifier', gem = 'sapphire', dmg = 9}; 159 - {lens = 'convex', gem = 'ruby', dmg = 7}; 160 163 }; 161 164 }; 162 165 pierce = { -- faster mining speed 163 166 name = 'Pierce'; 164 167 cost = 3; 165 168 tone = {113,240,251}; 166 169 groups = digtools; 167 - { 168 - 'pick';'pickaxe';'axe';'shovel';'sickle'; 169 - }; 170 170 desc = 'rip through solid stone or wood like a hot knife through butter'; 171 171 recipe = { 172 172 {lens = 'amplifier', gem = 'diamond', dmg = 4}; 173 173 {lens = 'amplifier', gem = 'ruby', dmg = 4}; 174 - {lens = 'rectifier', gem = 'diamond', dmg = 2}; 174 + {item = 'default:flint'}; 175 175 }; 176 176 affinity = 'praxic'; 177 177 apply = function(stack,power,base) 178 178 local caps = table.copy(stack:get_definition().tool_capabilities) 179 179 for g,v in pairs(caps.groupcaps) do 180 180 for i,t in pairs(v.times) do 181 181 local unit = base.groupcaps[g].times[i] * 0.15 ................................................................................ 188 188 }; 189 189 rend = { -- more damage / mine higher level blocks 190 190 name = 'Rend'; 191 191 affinity = 'praxic'; 192 192 tone = {251,203,113}; 193 193 groups = {'sword';'pick';'pickaxe';}; 194 194 recipe = { 195 - {lens = 'convex', gem = 'mese', dmg = 3}; 196 195 {lens = 'amplifier', gem = 'emerald', dmg = 7}; 197 - {lens = 'amplifier', gem = 'diamond', dmg = 7}; 196 + {item = 'flowers:flower_rose'}; 197 + {item = 'sorcery:powder_silver'}; 198 198 }; 199 199 cost = 5; 200 200 desc = 'cleave through sturdy ores and tear mortal flesh with fearsome ease'; 201 201 apply = function(stack,power,base) 202 202 local caps = table.copy(stack:get_definition().tool_capabilities) 203 203 for g,v in pairs(caps.groupcaps) do 204 204 local unit = 2 ................................................................................ 217 217 sanctify = { 218 218 desc = 'prolong the blessings of the heavens'; 219 219 groups = {'sorcery_sanctify'}; 220 220 affinity = 'entropic'; 221 221 tone = {255,255,255}; 222 222 cost = 7; 223 223 recipe = { 224 - {lens = 'amplifier', gem = 'ruby', dmg = 13}; 224 + {item = 'sorcery:holy_water'}; 225 225 {lens = 'amplifier', gem = 'ruby', dmg = 15}; 226 226 {lens = 'amplifier', gem = 'ruby', dmg = 18}; 227 227 }; 228 228 }; 229 229 }
Modified data/metals.lua from [3560b06dd9] to [81e12129e0].
392 392 artificial=true; 393 393 meltpoint = 5; 394 394 cooktime = 120; 395 395 hardness = 8; 396 396 maxconduct = 15; 397 397 sharpness = 5; 398 398 level = 2; 399 - speed = 1.7; 399 + speed = 2.5; 400 400 maxenergy = 2200; 401 401 durability = 1500; 402 402 slots = { 403 403 {affinity={'praxic'},confluence=3}; 404 404 {affinity={'syncretic'},confluence=2}; 405 405 }; 406 406 sinter = {
Modified data/oils.lua from [6619d22587] to [1e67dfd074].
105 105 mix = { 106 106 'sorcery:extract_greengrass'; 107 107 'sorcery:extract_grape'; 108 108 'farming:cocoa_beans'; 109 109 'farming:sugar'; 110 110 'farming:sugar'; 111 111 }; 112 + }; 113 + luck = { 114 + color = {156,54,255}; 115 + style = 'sparkle'; 116 + mix = { 117 + 'sorcery:extract_marram'; 118 + 'farming:hemp_leaf'; 119 + 'farming:hemp_oil'; 120 + 'xdecor:honey'; 121 + 'farming:salt'; 122 + 'farming:salt'; 123 + }; 112 124 }; 113 125 }
Modified data/runes.lua from [56e196edd6] to [92db18c27d].
140 140 cast = function(ctx) 141 141 local target = minetest.get_player_by_name(ctx.meta:get_string('rune_join_target')) 142 142 if not target then return false end 143 143 144 144 local subjects if ctx.amulet.frame == 'cobalt' then 145 145 if ctx.target.type ~= 'object' then return false end 146 146 subjects = {{ref=ctx.target.ref}} 147 + elseif ctx.amulet.frame == 'iridium' then 148 + subjects = {} 149 + for _,o in pairs(minetest.get_objects_inside_radius(ctx.caster:get_pos(), ctx.stats.power)) do 150 + subjects[#subjects+1] = {player = o} 151 + end 147 152 else subjects = {{ref=ctx.caster}} end 148 153 149 154 local delay = math.max(5,11 - ctx.stats.power) + 2.3*(math.random()*2-1) 150 155 local color = sorcery.lib.color(117,38,237) 151 156 teleport(ctx,subjects,delay,target:get_pos(),color) 152 157 if ctx.amulet.frame == 'gold' then 153 158 teleport(ctx,{{ref=target}},delay,ctx.caster:get_pos()) ................................................................................ 864 869 mingrade = 4; 865 870 name = 'Duplication'; 866 871 desc = 'Bring an exact twin of any object or item into existence, no matter how common or rare it might be'; 867 872 cast = function(ctx) 868 873 local color = sorcery.lib.color(255,61,205) 869 874 local dup, sndpos, anchor, sbj, ty 870 875 if ctx.target.type == 'object' and ctx.target.ref:get_luaentity().name == '__builtin:item' then 871 - -- sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems??? 876 + sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems??? 872 877 sndpos = 'subjects' 873 878 sbj = {{player = ctx.target.ref}} 874 879 local item = ItemStack(ctx.target.ref:get_luaentity().itemstring) 875 880 local r = function() return math.random() * 2 - 1 end 876 881 local putpos = vector.offset(ctx.target.ref:get_pos(), r(), 1, r()) 877 882 dup = function() 878 883 item:set_count(1) -- nice try bouge-san
Modified data/spells.lua from [dffc43152b] to [2d770c6227].
27 27 end 28 28 return r[math.random(#r)] 29 29 end 30 30 local anchorwand = function(aff,uses,recipe) 31 31 local affcolor = sorcery.lib.color(sorcery.data.affinities[aff].color) 32 32 return { 33 33 name = aff .. ' anchor'; 34 - desc = 'With an enchanter, anchor ' .. aff .. ' spells into an object to enable it to produce preternatural effects'; 34 + desc = 'Destroy items on an enchanter and channel their essence with enchanting lenses to anchor ' .. aff .. ' spells into an object, enabling it to produce preternatural effects'; 35 35 uses = uses; 36 36 affinity = recipe; 37 37 color = affcolor; 38 38 sound = 'xdecor_enchanting'; -- FIXME make own 39 39 cast = function(ctx) 40 40 local node = target_node(ctx, 'sorcery:enchanter') 41 41 if not node then return false end ................................................................................ 112 112 local proto = stack:get_definition()._proto 113 113 if proto.kind ~= spec.lens or proto.gem ~= spec.gem 114 114 then return false end 115 115 elseif spec.item then 116 116 default_mode = 'consume' 117 117 if stack:get_name() ~= spec.item then 118 118 return false end 119 + if spec.consume and stack:get_count() < spec.consume then 120 + return false end 119 121 else 120 122 return false 121 123 end 122 124 123 125 local mode 124 126 if spec.dmg then mode = 'dmg' 125 127 elseif spec.consume then mode = 'consume' 126 128 else mode = default_mode end 127 129 128 130 if mode == 'dmg' then 129 131 stack:add_wear((spec.dmg or 1) * 1000) 130 132 return stack 131 133 elseif mode == 'consume' then 134 + local r = sorcery.register.residue.db[stack:get_name()] 132 135 stack:take_item(spec.consume or 1) 136 + if r then 137 + local rs = ItemStack(r) 138 + rs:set_count(rs:get_count() * (spec.consume or 1)) 139 + if stack:is_empty() 140 + then stack = rs 141 + else minetest.add_item(ctx.target.above, rs) 142 + end 143 + end 133 144 return stack 134 145 end 135 146 end 136 147 for ench,data in pairs(sorcery.data.enchants) do 137 148 if data.affinity ~= aff or data.recipe == nil then goto skip end 138 149 local newinv = {} 139 150 for s,v in pairs(data.recipe) do ................................................................................ 191 202 bolt:get_luaentity()._blastradius = radius 192 203 bolt:set_velocity(vel) 193 204 end; 194 205 }; 195 206 seal = { 196 207 name = 'sealing'; 197 208 color = {255,238,16}; 198 - uses = 32; 209 + uses = 128; 199 210 desc = 'Bind an object to your spirit such that it will be rendered impregnable to others, or break a sealing created with this same wand'; 200 211 leytype = 'imperic'; 201 212 affinity = {'pine','dark'}; 202 213 cast = function(ctx) 203 214 if ctx.target == nil or ctx.target.type ~= 'node' then return false end 204 215 local meta = minetest.get_meta(ctx.target.under) 205 216 -- first we need to check if the wand has an identifying 'key' yet, ................................................................................ 252 263 uses = 128; 253 264 desc = 'Reveal the strength and affinities of the local leyline'; 254 265 cast = function(ctx) 255 266 local color = ctx.base.gem == 'sapphire'; 256 267 local duration = (ctx.base.gem == 'amethyst' and 4) or 2; 257 268 local ley = sorcery.ley.estimate(ctx.caster:get_pos()) 258 269 259 - local strength = ley.force 270 + local strength = ley.force * 4 * ley.force 260 271 if color then 261 272 strength = strength / #ley.aff 262 273 for _,a in pairs(ley.aff) do 263 - cast_sparkle(ctx,sorcery.lib.color(sorcery.data.affinities[a].color):brighten(1.3), strength, duration * strength) 274 + cast_sparkle(ctx,sorcery.lib.color(sorcery.data.affinities[a].color):brighten(1.3), strength, duration * (strength*0.5)) 264 275 end 265 276 else 266 277 cast_sparkle(ctx,sorcery.lib.color(250,255,185), strength, duration*strength) 267 278 end 268 279 269 280 end; 270 281 }; ................................................................................ 583 594 end 584 595 newenergy = math.min(maxcharge, newenergy * (ctx.stats.power or 1)) 585 596 586 597 sorcery.ley.setcharge(rechargee,charge + newenergy) 587 598 e:set_stack('item',1,rechargee) 588 599 589 600 enchantment_sparkle(ctx, sorcery.lib.color(212,6,63)) 601 + sorcery.enchant.update_enchanter(ctx.target.under) 590 602 end; 591 603 }; 592 604 transfer = { 593 605 name = 'transfer'; 594 606 uses = 65; 595 607 color = {6,212,121}; 596 608 leytype = 'syncretic'; ................................................................................ 624 636 if ctx.base.gem == 'sapphire' 625 637 then e.spells = {} e.energy = 0 626 638 else table.remove(e.spells, math.random(#e.spells)) 627 639 end 628 640 end 629 641 sorcery.enchant.set(item,e) 630 642 ei:set_stack('item',1,item) 643 + sorcery.enchant.update_enchanter(ctx.target.under) 631 644 enchantment_sparkle(ctx,sorcery.lib.color(255,154,44)) 632 645 enchantment_sparkle(ctx,sorcery.lib.color(226,44,255)) 633 646 end; 634 647 }; 635 648 divine = { 636 649 name = 'divining'; 637 650 desc = 'Steal away the secrets of the cosmos';
Modified entities.lua from [9e257faffc] to [5b6d6366ce].
3 3 age = u.marshal.t.u32; 4 4 lastemit = u.marshal.t.u32; 5 5 } 6 6 7 7 minetest.register_entity('sorcery:spell_projectile_flamebolt',{ 8 8 initial_properties = { 9 9 visual = "sprite"; 10 - use_texture_alpha = true; 10 + use_texture_alpha = 'blend'; 11 11 textures = {'sorcery_fireball.png'}; 12 12 visual_size = { x = 2, y = 2, z = 2 }; 13 13 physical = true; 14 14 collide_with_objects = true; 15 15 pointable = false; 16 16 glow = 14; 17 17 static_save = false;
Deleted hotmetallurgy.lua version [ac0bc31ba3].
1 --- alloying furnace 2 --- 3 --- there are several kinds of alloy furnace, with varying 4 --- capabilities. the simplest can alloy two simple metals; 5 --- the most complex can alloy four high-grade metals such 6 --- as titanium, platinum, iridium, or levitanium. 7 --- 8 --- furnace recipes follow a pattern: the number of crucibles 9 --- determines the input slots, the type of crucible determines 10 --- how hot the furnace can get, and various other components 11 --- (like a coolant circulator) can be added to allow the 12 --- creation of exotic metals. 13 --- 14 --- alloy furnaces produce ingots that can later be melted down 15 --- again and cast into a mold to produce items of particular 16 --- shapes. 17 - 18 --- there are five kinds of crucibles: clay, aluminum, platinum, 19 --- duridium, and impervium. clay crucibles are made by molding 20 --- clay into the proper shape and then firing it in a furnace. 21 --- others are made by casting. 22 - 23 -local fragments_per_ingot = 4 24 - 25 -for _, c in pairs { 'clay', 'aluminum', 'platinum', 'duranium' } do 26 - minetest.register_craftitem('sorcery:crucible_' .. c, { 27 - description = sorcery.lib.str.capitalize(c .. ' crucible'); 28 - inventory_image = 'sorcery_crucible_' .. c .. '.png'; 29 - }) 30 -end 31 - 32 -minetest.register_craftitem('sorcery:crucible_clay_molding', { 33 - description = sorcery.lib.str.capitalize('Crucible molding'); 34 - inventory_image = 'sorcery_crucible_clay_molding.png'; 35 -}) 36 - 37 -minetest.register_craft { 38 - recipe = { 39 - { 'default:clay_lump', '', 'default:clay_lump'}; 40 - { 'default:clay_lump', '', 'default:clay_lump'}; 41 - { 'default:clay_lump', 'default:clay_lump', 'default:clay_lump'}; 42 - }; 43 - output = 'sorcery:crucible_clay_molding'; 44 -} 45 -minetest.register_craft { 46 - type = 'shapeless'; 47 - recipe = { 'sorcery:crucible_clay_molding' }; 48 - output = 'default:clay_lump 7'; 49 -} 50 -minetest.register_craft { 51 - type = 'cooking'; 52 - recipe = 'sorcery:crucible_clay_molding'; 53 - cooktime = 40; 54 - output = 'sorcery:crucible_clay'; 55 -} 56 - 57 -local burn_layout = function(v) 58 - local layouts = { 59 - [1] = {w = 1, h = 1}; [2] = {w = 2, h = 1}; [3] = {w = 3, h = 1}; 60 - [4] = {w = 2, h = 2}; [5] = {w = 3, h = 2}; [6] = {w = 3, h = 2}; 61 - [7] = {w = 4, h = 2}; [8] = {w = 4, h = 2}; [9] = {w = 3, h = 3}; 62 - } 63 - local inpos = { x = 2.8, y = 1 } 64 - local insize = layouts[v.in] 65 - local outpos = { x = 5.2, y = 2.4 } 66 - local outsize = layouts[v.out] 67 - local fuelpos = { x = 2.8, y = 3.4 } 68 - local fuelsize = layouts[v.fuel] 69 - return string.format([[ 70 - list[context;input;%f,%f;%f,%f;] 71 - list[context;output;%f,%f;%f,%f;] 72 - list[context;fuel;%f,%f;%f,%f;] 73 - 74 - image[2.3,1.9;1,1;default_furnace_fire_bg.png^[lowpart:%u%%:default_furnace_fire_fg.png] 75 - image[3.2,1.9;1,1;gui_furnace_arrow_bg.png^[lowpart:%u%%:gui_furnace_arrow_fg.png^[transformR270] 76 - 77 - listring[context;output] listring[current_player;main] 78 - listring[context;input] listring[current_player;main] 79 - listring[context;fuel] listring[current_player;main] 80 - ]], 81 - 82 - --input 83 - inpos.x - insize.w/2, -- pos 84 - inpos.y - insize.h/2, 85 - insize.w, insize.h, -- size 86 - --output 87 - outpos.x - outsize.w/2, -- pos 88 - outpos.y - outsize.h/2, 89 - outsize.w, outsize.h, -- size 90 - --fuel 91 - fuelpos.x - fuelsize.w/2, -- pos 92 - fuelpos.y - fuelsize.h/2, 93 - fuelsize.w, fuelsize.h, -- size 94 - 95 - v.burn, v.prog 96 - ) 97 -end 98 - 99 -local kiln_formspec = function(kind, fuel_progress, cook_progress) 100 - return [[ 101 - size[8,8] 102 - list[current_player;main;0,4.2;8,4] 103 - list[context;wax;0,2;1,1] 104 - ]] .. burn_layout{ 105 - in = kind.size^2; 106 - out = kind.outsize; 107 - fuel = kind.fuelsize; 108 - burn = fuel_progress; 109 - prog = cook_progress; 110 - } 111 -end 112 - 113 -local smelter_formspec = function(kind, fuel_progress, smelt_progress) 114 - return [[ 115 - size[8,8] 116 - list[current_player;main;0,4.2;8,4] 117 - ]] .. burn_layout { 118 - in = kind.size; 119 - out = kind.outsize; 120 - fuel = kind.fuelsize; 121 - burn = fuel_progress; 122 - prog = smelt_progress; 123 - } 124 -end 125 - 126 -local find_recipe = function(inv) 127 - local mix = {} 128 - local count = 0 129 - for i=1,inv:get_size('input') do 130 - local m = inv:get_stack('input',i) 131 - if m:is_empty() then goto skip end 132 - local l = sorcery.data.metallookup[m:get_name()] 133 - if not l then return false end 134 - mix[l.id] = (mix[l.id] or 0) + l.value 135 - count = count + l.value 136 - ::skip::end 137 - -- everything is metal, we've finished summing it up. 138 - -- let's see if the assembled items match the ratio 139 - -- specified in any of the smelting recipes. 140 - local matches = 0 141 - for _,rec in pairs(sorcery.data.alloys) do 142 - local fac = nil 143 - local meltpoint = 1 144 - if rec.metals == nil then goto skip_recipe end 145 - for metal, ratio in pairs(rec.metals) do 146 - if mix[metal] and mix[metal] % ratio == 0 then 147 - if fac then 148 - if mix[metal] / ratio ~= fac then goto skip_recipe end 149 - else fac = math.floor(mix[metal] / ratio) end 150 - local m = sorcery.data.metals[metal] 151 - if m.meltpoint then 152 - meltpoint = math.max(meltpoint, m.meltpoint) end 153 - else goto skip_recipe end 154 - end 155 - do return rec, count, fac, meltpoint end 156 - ::skip_recipe::end 157 - return false 158 -end 159 - 160 -local update_smelter = function(pos) 161 - local meta = minetest.get_meta(pos) 162 - local inv = meta:get_inventory() 163 - local proto = minetest.registered_nodes[minetest.get_node(pos).name]._proto 164 - local recipe, count, factor, meltpoint = find_recipe(inv) 165 - if recipe --[[and proto.temp >= meltpoint]] then 166 - minetest.get_node_timer(pos):start(1) 167 - else 168 - meta:set_float('burntime',0) 169 - end 170 -end 171 - 172 -local smelter_step = function(kind,active,pos,delta) 173 - local meta = minetest.get_meta(pos) 174 - local inv = meta:get_inventory() 175 - local recipe, count, factor = find_recipe(inv) 176 - local cooktime 177 - local elapsed = meta:get_float('burntime') + delta 178 - meta:set_float('burnleft',meta:get_float('burnleft') - delta) 179 - if (not active) and (not recipe) then return false end 180 - if meta:get_float('burnleft') <= 0 or not active then 181 - if recipe then 182 - local burn, frep = minetest.get_craft_result { 183 - method = 'fuel', width = 1; 184 - items = { inv:get_stack('fuel',1) }; 185 - } 186 - if burn.time == 0 then goto nofuel end 187 - inv:set_stack('fuel', 1, frep.items[1]) 188 - meta:set_float('burnleft',burn.time) 189 - meta:set_float('burnmax',burn.time) 190 - if not active then 191 - minetest.swap_node(pos, 192 - sorcery.lib.tbl.merge(minetest.get_node(pos), { 193 - name = kind.id .. '_active' 194 - })) 195 - active = true 196 - end 197 - else goto nofuel end 198 - end 199 - 200 - if not recipe then goto update end 201 - 202 - cooktime = ((recipe.cooktime / fragments_per_ingot) * count) / factor 203 - if elapsed >= cooktime then 204 - elapsed = 0 205 - -- remove used items 206 - for i=1,inv:get_size('input') do 207 - local s = inv:get_stack('input',i) 208 - if s:is_empty() then goto skip end 209 - s:take_item(1) inv:set_stack('input',i,s) 210 - ::skip::end 211 - 212 - local outstack 213 - if count % fragments_per_ingot == 0 then 214 - outstack = ItemStack { 215 - name = sorcery.data.metals[recipe.output].ingot or 'sorcery:' .. recipe.output .. '_ingot'; 216 - count = count / fragments_per_ingot; 217 - } 218 - else 219 - outstack = ItemStack { 220 - name = 'sorcery:fragment_' .. recipe.output; 221 - count = count; 222 - } 223 - end 224 - 225 - local leftover = inv:add_item('output',outstack) 226 - if not leftover:is_empty() then 227 - minetest.add_item(pos, leftover) 228 - end 229 - end 230 - 231 - ::update:: 232 - meta:set_float('burntime',elapsed) 233 - meta:set_string('formspec', smelter_formspec(kind, 234 - math.min(1, meta:get_float('burnleft') / 235 - meta:get_float('burnmax') 236 - ) * 100, -- fuel 237 - (cooktime and math.min(1, elapsed / cooktime) * 100) or 0 -- smelt 238 - )) 239 - do return active end 240 - 241 - ::nofuel:: 242 - if active then 243 - minetest.swap_node(pos, 244 - sorcery.lib.tbl.merge(minetest.get_node(pos), { name = kind.id })) 245 - end 246 - meta:set_float('burnleft',0) -- just in case 247 - ::noburn:: 248 - meta:set_float('burntime',0) -- just in case 249 - meta:set_string('formspec', smelter_formspec(kind, 0, 0)) 250 - return false 251 -end 252 -local register_kiln = function(kind) 253 - local box = { 254 - open = { 255 - type = 'fixed'; 256 - fixed = { 257 - -0.5,-0.5,-0.5, 258 - 0.5, 1.6, 0.5 259 - }; 260 - }; 261 - closed = { 262 - type = 'fixed'; 263 - fixed = { 264 - -0.5,-0.5,-0.5, 265 - 0.5, 0.7, 0.5 266 - }; 267 - }; 268 - } 269 - local id = 'sorcery:kiln_' .. kind.material 270 - local metal = sorcery.data.metals[kind.material] 271 - -- use some iffy heuristics to guess the texture 272 - local metaltex 273 - if kind.material == 'clay' then 274 - metaltex = 'default_brick.png'; 275 - else 276 - metaltex = (metal.img and metal.img.block) or 277 - (metal.ingot and 'default_' .. kind.material .. '_block.png') or 278 - sorcery.lib.image('default_steel_block.png'):multiply(sorcery.lib.color(metal.tone)):render(); 279 - end 280 - local tex = { 281 - open = { 282 - 'default_furnace_front.png'; 283 - metaltex; 284 - 'default_copper_block.png'; 285 - 'default_stone.png'; 286 - }; 287 - closed = { 288 - 'default_furnace_front_active.png'; 289 - 'default_copper_block.png'; 290 - metaltex; 291 - 'default_stone.png'; 292 - }; 293 - }; 294 - for _,state in pairs{'open','closed'} do 295 - local id_closed = id .. '_closed' 296 - local id_current = (state == 'closed' and id_closed) or id 297 - local desc = sorcery.lib.str.capitalize(kind.temp_name) .. ' kiln'; 298 - minetest.register_node(id_current, { 299 - _active = (state == 'closed'); 300 - _proto = kind; 301 - description = desc; 302 - drawtype = "mesh"; 303 - mesh = 'sorcery-kiln-' .. state .. '.obj'; 304 - drop = id; 305 - groups = { cracky = 2; sorcery_device_kiln = (state == 'closed') and 1 or 2; } 306 - sunlight_propagates = true; 307 - paramtype1 = 'light'; 308 - paramtype2 = 'facedir'; 309 - selection_box = box[state]; 310 - collision_box = box[state]; 311 - tiles = tex[state]; 312 - light_source = (state == 'closed' and 7) or 0; 313 - on_construct = function(pos) 314 - local meta = minetest.get_meta(pos) 315 - local inv = meta:get_inventory() 316 - inv:set_size('input', kind.size^2) 317 - inv:set_size('output', kind.outsize) 318 - inv:set_size('fuel', kind.fuelsize) 319 - inv:set_size('wax', 1) 320 - 321 - meta:set_float('burnleft',0) 322 - meta:set_float('burnmax',0) 323 - meta:set_float('burntime',0) 324 - 325 - meta:set_string('infotext',desc) 326 - meta:set_string('formspec',kiln_formspec(kind,0,0)) 327 - end; 328 - on_timer = function(pos,delta) 329 - end; 330 - 331 - on_metadata_inventory_put = function(pos) 332 - minetest.get_node_timer(pos):start(1) end; 333 - on_metadata_inventory_move = function(pos) 334 - minetest.get_node_timer(pos):start(1) end; 335 - on_metadata_inventory_take = function(pos) 336 - minetest.get_node_timer(pos):start(1) end; 337 - }) 338 - end 339 - local ingot 340 - if kind.material == 'clay' then 341 - ingot = 'default:clay_brick'; 342 - else 343 - ingot = metal.ingot or 'sorcery:' .. kind.material .. '_ingot' 344 - end 345 - minetest.register_craft = { 346 - output = id_open; 347 - recipe = { 348 - {'default:copper_ingot', 'default:copper_ingot', 'default:copper_ingot'}; 349 - {ingot,'',ingot}; 350 - {ingot,'default:furnace',ingot}; 351 - }; 352 - } 353 -end 354 - 355 -local register_smelter = function(kind) 356 - local recipe = {{},{}; 357 - {'default:stone','default:furnace','default:stone'}; 358 - } do 359 - local on = kind.crucible 360 - local ti = 'default:tin_ingot' 361 - local cu = 'default:copper_ingot' 362 - local crucmap = { 363 - [2] = { {cu,cu,cu}, {on,ti,on} }; 364 - [3] = { {cu,on,cu}, {on,ti,on} }; 365 - [4] = { {on,cu,on}, {on,ti,on} }; 366 - [5] = { {on,cu,on}, {on,on,on} }; 367 - [6] = { {on,on,on}, {on,on,on} }; 368 - }; 369 - for y=1,2 do recipe[y] = crucmap[kind.size][y] end 370 - end 371 - 372 - local desc = 'smelter'; 373 - if kind.temp_name then desc = kind.temp_name .. ' ' .. desc end 374 - if kind.size_name then desc = kind.size_name .. ' ' .. desc end 375 - desc = sorcery.lib.str.capitalize(desc); 376 - local id = 'sorcery:smelter_' .. kind.material .. kind.size_name 377 - kind.id = id 378 - for _, active in pairs {false, true} do 379 - minetest.register_node((active and id .. '_active') or id, { 380 - _proto = kind; 381 - description = desc; 382 - drop = id; 383 - groups = { 384 - cracky = 2; 385 - sorcery_device_smelter = active and 1 or 2; 386 - }; 387 - paramtype2 = 'facedir'; 388 - light_source = (active and 9) or 0; 389 - on_construct = function(pos) 390 - local meta = minetest.get_meta(pos) 391 - local inv = meta:get_inventory() 392 - inv:set_size('input',kind.size) 393 - inv:set_size('output',kind.outsize) 394 - inv:set_size('fuel',kind.fuelsize) 395 - meta:set_string('infotext', desc) 396 - meta:set_string('formspec', smelter_formspec(kind, 0, 0)) 397 - meta:set_float('burnleft',0) 398 - meta:set_float('burnmax',0) 399 - meta:set_float('burntime',0) 400 - end; 401 - on_metadata_inventory_put = update_smelter; 402 - on_metadata_inventory_move = update_smelter; 403 - on_metadata_inventory_take = update_smelter; 404 - on_timer = function(pos,delta) return smelter_step(kind, active, pos, delta) end; 405 - -- allow_metadata_inventory_put = function(pos, listname, index, stack, player) 406 - -- end; 407 - tiles = { 408 - 'sorcery_smelter_top_' .. tostring(kind.size) .. '.png'; 409 - 'sorcery_smelter_bottom.png'; 410 - 'sorcery_smelter_side.png'; 411 - 'sorcery_smelter_side.png'; 412 - 'sorcery_smelter_side.png'; 413 - 'sorcery_smelter_front' .. ((active and '_hot') or '') .. '.png'; 414 - }; 415 - }) 416 - end 417 - minetest.register_craft { 418 - recipe = recipe; 419 - output = id; 420 - } 421 -end 422 - 423 -for _, t in pairs { 424 - {1, nil, 'clay'}; 425 - -- {2, 'hot','aluminum'}; 426 - -- {3, 'volcanic','platinum'}; 427 - -- {4, 'stellar','duridium'}; 428 - -- {5, 'nova','impervium'}; 429 -} do register_kiln { 430 - temp = t[1], temp_name = t[2]; 431 - material = t[3]; 432 - size = 3, outsize = 4, fuelsize = 1; -- future-proofing 433 - } 434 - 435 - for _, s in pairs { 436 - {2, 'small'}; 437 - {3, 'large'}; 438 - {4, 'grand'}; 439 - } do register_smelter { 440 - size = s[1], size_name = s[2]; 441 - temp = t[1], temp_name = t[2]; 442 - material = t[3]; 443 - crucible = 'sorcery:crucible_' .. t[3]; 444 - outsize = 4, fuelsize = 1; -- future-proofing 445 - } end 446 -end
Modified init.lua from [98e23bb4d1] to [b6f042d41b].
99 99 root {'compat','matreg'} 100 100 if not sorcery.stage('loadlore', data, root) then 101 101 data { 102 102 'compat'; 103 103 'affinities'; 'gods'; 104 104 'calendar', 'signs'; 105 105 'resonance'; 106 - 'enchants', 'spells', 'runes'; 107 106 'gems', 'metals'; 107 + 'enchants', 'spells', 'runes'; 108 108 'potions', 'oils', 'greases', 109 109 'draughts', 'elixirs', 110 110 'philters', 'extracts'; 111 111 } 112 112 end 113 113 114 114 sorcery.load('registration') do
Modified leylines.lua from [a8ee2829a5] to [3f1f974e2b].
376 376 name = 'Condenser sound effects'; 377 377 nodenames = {'sorcery:condenser'}; 378 378 neighbors = {'group:sorcery_ley_device'}; 379 379 interval = 5.6, chance = 1, catch_up = false; 380 380 action = function(pos) 381 381 local force = sorcery.ley.estimate(pos).force 382 382 minetest.sound_play('sorcery_condenser_bg', { 383 - pos = pos, max_hear_distance = 5 + 8*force, gain = force*0.3; 383 + pos = pos, max_hear_distance = 5 + 4*force, gain = force*0.3; 384 384 }) 385 385 end; 386 386 } 387 387 end 388 388 389 389 minetest.register_craft { 390 390 output = 'sorcery:condenser';
Modified lib/color.lua from [818d3ded97] to [9a1b399926].
160 160 -- print("r"..self.red.."g"..self.green.."b"..self.blue.." is h"..hue.."s"..saturation.."l"..luminosity) 161 161 local temp = from_hsl({hue=hue,saturation=saturation,luminosity=luminosity},self.alpha) 162 162 -- print("back is r"..temp.red.."g"..temp.green.."b"..temp.blue) 163 163 return { hue = hue, saturation = saturation, luminosity = luminosity } 164 164 end; 165 165 166 166 readable = function(self, target) 167 - target = target or 0.5 167 + target = target or 0.6 168 168 local hsl = self:to_hsl() 169 169 hsl.luminosity = target 170 + local worstHue = 230 171 + local nearness = math.abs(worstHue - hsl.hue) 172 + if nearness <= 70 then 173 + local boost = 1.0 - (nearness / 70) 174 + hsl.luminosity = math.min(1, hsl.luminosity * (1 + (boost*0.4))) 175 + end 176 + 170 177 return from_hsl(hsl, self.alpha) 171 178 end; 172 179 173 180 bg = function(self, text) return 174 181 text .. minetest.get_background_escape_sequence(self:hex()) 175 182 end; 176 183 ................................................................................ 181 188 brighten = function(self, fac) 182 189 -- Use HSL to brighten 183 190 -- To HSL 184 191 local hsl = self:to_hsl() 185 192 -- Do the calculation, clamp to 0-1 instead of the clamp fn 186 193 hsl.luminosity = math.min(math.max(hsl.luminosity * fac, 0), 1) 187 194 -- Turn back into RGB color 188 - local t = from_hsl(hsl, self.alpha) 195 + -- local t = from_hsl(hsl, self.alpha) 196 + -- print("darker is r"..hsl.red.."g"..hsl.green.."b"..hsl.blue) 189 197 -- print("brighten is r"..t.red.."g"..t.green.."b"..t.blue) 190 198 return from_hsl(hsl, self.alpha) 191 199 end; 192 200 193 201 darken = warp(function(new, fac) 194 202 -- TODO: is there any point to this being different than brighten? Probably especially not now. 195 203 new.red = clip(new.red - (new.red * fac))
Added lib/hud.lua version [a485497e38].
1 +-- the HUD library provides an easy-to-use interface for create custom 2 +-- item UIs. the idea is that an item <id> will define one or more UI layouts 3 +-- in its _sorcery.hud property, then call lib.hud.open(id, layout, player, ...) 4 +-- when it wishes to open <layout>, usually from its on_use handler. the library 5 +-- will then iterate through the elements in its definition, transmit them to 6 +-- the user, and store the resulting handles in a user context. it will also 7 +-- register any timer callbacks needed to ensure a timely update of the item. 8 +-- if the item is removed from the hotbar, any UI associated with it will be 9 +-- closed. 10 +-- 11 +-- each UI element can have a function that is called to set its value. if 12 +-- this is present, it will be called at initialization and at update. 13 +-- 14 +-- example: 15 +-- _sorcery = { 16 +-- hud = { 17 +-- powerlevel = { 18 +-- period = 0.1; 19 +-- elements = { 20 +-- {kind = 'text', 21 +-- text = function(ctx) 22 +-- return ctx.stack:get_meta():get_int("power") 23 +-- end; 24 +-- }; 25 +-- }; 26 +-- }; 27 +-- }; 28 +-- };
Modified lib/tbl.lua from [6f943d189b] to [d4f49ab351].
51 51 new[k] = fn.deepcopy(v) 52 52 else 53 53 new[k] = v 54 54 end 55 55 end 56 56 return new 57 57 end 58 + 59 +fn.append = function(r1, r2) 60 + local new = fn.copy(r1) 61 + for i=1,#r2 do 62 + new[#new + 1] = r2[i] 63 + end 64 + return new 65 +end 58 66 59 67 fn.merge = function(base,override) 60 68 local new = fn.copy(base) 61 69 for k,v in pairs(override) do 62 70 new[k] = v 63 71 end 64 72 return new 65 73 end 66 74 67 75 fn.deepmerge = function(base,override,func) 68 76 local new = {} 69 - local keys = fn.merge(fn.keys(base),fn.keys(override)) 77 + local keys = fn.append(fn.keys(base),fn.keys(override)) 70 78 for _,k in pairs(keys) do 71 79 if type(base[k]) == 'table' and 72 80 type(override[k]) == 'table' then 73 81 new[k] = fn.deepmerge(base[k], override[k], func) 74 82 elseif func and override[k] and base[k] then 75 83 new[k] = func(base[k],override[k], k) 76 84 elseif override[k] then 77 85 new[k] = override[k] 78 86 else 79 87 new[k] = base[k] 80 88 end 81 89 end 82 - return new 83 -end 84 - 85 -fn.append = function(r1, r2) 86 - local new = fn.copy(r1) 87 - for i=1,#r2 do 88 - new[#new + 1] = r2[i] 89 - end 90 90 return new 91 91 end 92 92 93 93 fn.has = function(tbl,value,eqfn) 94 94 for k,v in pairs(tbl) do 95 95 if eqfn then 96 96 if eqfn(v,value,tbl) then return true, k end
Modified lib/ui.lua from [a001c55363] to [787cef01b1].
1 1 local l = sorcery.lib 2 2 local dui = sorcery.data.ui 3 3 4 4 return { 5 5 tooltip = function(a) 6 - local color = a.color 6 + local color = a.color and a.color:readable() 7 7 if color == nil then color = l.color(136,158,177) end 8 8 local str = a.title 9 9 if a.desc then 10 10 str = str .. '\n' .. color:fmt(minetest.wrap_text(a.desc,60)) 11 11 end 12 12 if a.props then 13 13 -- str = str .. '\n' 14 14 for _,prop in pairs(a.props) do 15 15 local c 16 16 if prop.color and l.color.id(prop.color) then 17 - c = prop.color 17 + c = prop.color:readable() 18 18 elseif dui.colors[prop.affinity] then 19 19 c = l.color(dui.colors[prop.affinity]) 20 20 else 21 21 c = l.color(dui.colors.neutral) 22 22 end 23 23 24 24 str = str .. '\n ' .. c:fmt('* ') 25 25 26 26 if prop.title then 27 27 str = str .. c:brighten(1.3):fmt(prop.title) .. ': ' 28 28 end 29 29 30 - local lines = minetest.wrap_text(prop.desc, 50, true) 30 + local lines = minetest.wrap_text(prop.desc, 55, true) 31 31 str = str .. c:fmt(lines[1]) 32 32 for i=2,#lines do 33 33 str = str .. '\n' .. string.rep(' ',5) .. c:fmt(lines[i]) 34 34 end 35 35 end 36 36 end 37 - return str 37 + return color:darken(0.8):bg(str) 38 38 end; 39 39 }
Modified metallurgy-cold.lua from [0187673a26] to [3417cf14d8].
129 129 mp.torque = constants.grind_torque_factor * mp.hardness 130 130 mp.grindvalue = mp.grindvalue or constants.default_grindvalue 131 131 mp.grindcost = mp.grindcost or constants.default_grindcost 132 132 133 133 if item:get_wear() ~= 0 then 134 134 -- prevent cheating by recovering metal from items before they 135 135 -- are destroyed 136 - local wearfac = (item:get_wear() / 65535) 136 + local wearfac = 1-(item:get_wear() / 65535) 137 137 mp.grindvalue = math.max(1,math.ceil(mp.grindvalue * wearfac)) 138 138 mp.hardness = math.max(1,math.ceil(mp.grindcost * wearfac)) 139 139 mp.torque = math.max(1,math.ceil(mp.torque * wearfac)) 140 140 end 141 141 142 142 return mp 143 143 end
Modified portal.lua from [12b64fac56] to [149a85d413].
358 358 time = 2; 359 359 amount = 500 * fac; 360 360 minpos = { x = -0.3, y = 0, z = -0.3 }; 361 361 maxpos = { x = 0.3, y = 1.5, z = 0.3 }; 362 362 minvel = { x = -0.3, y = 0.4, z = -0.3 }; 363 363 maxvel = { x = 0.3, y = 0.6, z = 0.3 }; 364 364 maxacc = { x = 0, y = 0.5, z = 0 }; 365 - texture = sorcery.lib.image('sorcery_spark.png'):multiply(sorcery.lib.color(255,144,226)):render(); 365 + texture = sorcery.lib.image('sorcery_sputter.png'):glow(sorcery.lib.color(255,144,226)):render(); 366 366 minexptime = 1.5; 367 367 maxexptime = 2; 368 368 minsize = 0.4; 369 369 maxsize = 1.6 * fac; 370 370 glow = 14; 371 371 attached = u.object; 372 372 animation = {
Modified potions.lua from [f87e1ae861] to [2e6379fa76].
8 8 sorcery.register_potion = function(name,label,desc,color,imgvariant,glow,extra) 9 9 local image = 'sorcery_liquid_'..(imgvariant or 'dull')..'.png' .. 10 10 '^[multiply:'..tostring(color).. 11 11 '^vessels_glass_bottle.png' 12 12 13 13 sorcery.register.residue.link('sorcery:' .. name, 'vessels:glass_bottle') 14 14 local node = { 15 - description = color:darken(0.8):bg( 15 + description = --color:darken(0.8):bg( 16 16 sorcery.lib.ui.tooltip { 17 17 title = label; 18 18 desc = desc; 19 19 color = color:readable(); 20 - } 20 + }; 21 21 -- label .. (desc and ("\n" .. color:readable():fmt(desc)) or '') 22 - ); 22 + --); 23 23 short_description = label; 24 24 drawtype = "plantlike"; 25 25 tiles = {image}; 26 26 inventory_image = image; 27 27 paramtype = "light"; 28 28 is_ground_content = false; 29 29 light_source = glow and math.min(minetest.LIGHT_MAX,glow) or 0;
Modified runeforge.lua from [4e5c236dfa] to [6c2e235473].
1 1 -- TODO make some kind of disposable "filter" tool that runeforges require 2 2 -- to generate runes and that wears down over time, to make amulets more 3 3 -- expensive than they currently are? the existing system is neat but 4 4 -- i think amulets are a little overpowered for something that just 5 5 -- passively consumes ley-current 6 +-- -- are phials & rune-wrenches enough for this now? 6 7 7 8 local constants = { 8 9 rune_mine_interval = 240; 9 10 -- how often a powered forge rolls for new runes 10 11 11 12 rune_cache_max = 4; 12 13 -- how many runes a runeforge can hold at a time ................................................................................ 44 45 local fac = (g-1) / 5 45 46 return i - ((i*0.5) * fac), 0.5 * fac 46 47 end 47 48 sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune) 48 49 local id = 'sorcery:rune_' .. name 49 50 rune.image = rune.image or string.format('sorcery_rune_%s.png',name) 50 51 rune.item = id 52 + local c = sorcery.lib.color(rune.tone) 51 53 minetest.register_craftitem(id, { 52 - description = sorcery.lib.color(rune.tone):readable():fmt(rune.name .. ' Rune'); 54 + description = c:darken(0.7):bg(c:readable():fmt(rune.name .. ' Rune')); 53 55 short_description = rune.name .. ' Rune'; 54 56 inventory_image = rune.image; 55 57 stack_max = 1; 56 58 groups = { 57 59 sorcery_rune = 1; 58 60 not_in_creative_inventory = 1; 59 61 }; ................................................................................ 145 147 local rp = rune:get_definition()._proto 146 148 local rg = rune:get_meta():get_int('rune_grade') 147 149 m:set_string('amulet_rune', rp.id) 148 150 m:set_int('amulet_rune_grade', rg) 149 151 local spell = sorcery.amulet.getspell(stack) 150 152 if not spell then return nil end 151 153 local name 152 - if spell.minrune then -- indicating quality makes less sense if it's restricted 154 + if spell.mingrade and spell.mingrade > 0 then -- indicating quality makes less sense if it's restricted 153 155 name = string.format('Amulet of %s', spell.name) 154 156 else 155 157 name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name) 156 158 end 157 159 m:set_string('description', sorcery.lib.ui.tooltip { 158 160 title = name; 159 161 color = spell.tone; ................................................................................ 403 405 local i = m:get_inventory() 404 406 i:set_size('cache',constants.rune_cache_max) 405 407 i:set_size('wrench',1) i:set_size('phial',1) i:set_size('refuse',1) 406 408 i:set_size('amulet',1) i:set_size('active',1) 407 409 m:set_string('infotext','Rune Forge') 408 410 runeforge_update(pos) 409 411 end; 410 - after_dig_node = sorcery.lib.node.purge_only {'amulet'}; 412 + after_dig_node = sorcery.lib.node.purge_only {'amulet','wrench'}; 411 413 on_timer = runeforge_update; 412 414 on_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user) 413 415 local inv = minetest.get_meta(pos):get_inventory() 414 416 local wrench if not inv:is_empty('wrench') then 415 417 wrench = inv:get_stack('wrench',1):get_definition()._proto 416 418 end 417 419 local wwear = function(cap)
Modified vfx.lua from [423ee7c3cf] to [d0158e43bb].
10 10 and function(x) return vector.add(pos,x) end 11 11 or function(x) return x end 12 12 local height = caster:get_properties().eye_height 13 13 minetest.add_particlespawner { 14 14 amount = 70 * strength; 15 15 time = duration or 1.5; 16 16 attached = caster; 17 - texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render(); 17 + -- texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render(); 18 + texture = sorcery.vfx.glowspark(color):render(); 18 19 minpos = ofs({ x = 0.0, z = 0.6, y = height*0.7}); 19 20 maxpos = ofs({ x = 0.4, z = 0.2, y = height*1.1}); 20 21 minvel = { x = -0.5, z = -0.5, y = -0.5}; 21 22 maxvel = { x = 0.5, z = 0.5, y = 0.5}; 22 23 minacc = { x = 0.0, z = 0.0, y = 0.5}; 23 24 maxacc = { x = 0.0, z = 0.0, y = 0.5}; 24 25 minsize = 0.4, maxsize = 0.8; ................................................................................ 63 64 end 64 65 65 66 sorcery.vfx.enchantment_sparkle = function(tgt,color) 66 67 local minvel, maxvel 67 68 if minetest.get_node(vector.add(tgt.under,{y=1,z=0,x=0})).name == 'air' then 68 69 minvel = {x=0,z=0,y= 0.3} maxvel = {x=0,z=0,y= 1.5}; 69 70 else 70 - local dir = vector.subtract(tgt.under,tgt.above) 71 + local dir = vector.subtract(tgt.above,tgt.under) 71 72 minvel = vector.multiply(dir, 0.3) 72 73 maxvel = vector.multiply(dir, 1.2) 73 74 end 74 75 return minetest.add_particlespawner { 75 76 amount = 50; 76 77 time = 0.5; 77 78 minpos = vector.subtract(tgt.under, 0.5);
Modified wands.lua from [e661ef77a3] to [3776b1d392].
159 159 end 160 160 return proto 161 161 end; 162 162 matprops = function(proto) 163 163 local matprops = {} 164 164 for k,v in pairs(proto) do 165 165 if sorcery.wands.materials[k] then 166 - local mp = sorcery.wands.materials[k].wandprops 166 + local mp = sorcery.wands.materials[k][v].wandprops 167 167 if mp then 168 168 matprops = sorcery.lib.tbl.deepmerge(matprops, mp, 169 - function(a,b,k) 169 + function(a,b,key) 170 170 if key == 'bond' 171 171 then return a+b 172 172 else return a*b 173 173 end 174 174 end) 175 175 end 176 176 end ................................................................................ 272 272 angle = user:get_look_horizontal(); 273 273 eyeheight = uprops.eye_height; 274 274 }; 275 275 wearmult = 1; 276 276 } 277 277 local result = castfn(context) 278 278 if result ~= false then 279 - minetest.sound_play(sorcery.data.spells[spell].sound or "default_item_smoke", { --FIXME make own sounds 279 + minetest.sound_play(sorcery.data.spells[spell].sound or "sorcery_chime", { --FIXME make better sound 280 280 pos = user:get_pos(); 281 281 gain = 0.8; 282 282 }) 283 283 -- minetest.add_particle { 284 284 -- pos = vector.add(vector.add(user:get_pos(), vector.multiply(user:get_look_dir(),1.1)), {y=1.6,z=0,x=0}); 285 285 -- velocity = user:get_velocity(); 286 286 -- expirationtime = 0.5; ................................................................................ 378 378 sunlight_propagates = true; 379 379 paramtype = 'light'; 380 380 paramtype2 = 'facedir'; 381 381 tiles = images; 382 382 selection_box = hitbox; 383 383 collision_box = hitbox; 384 384 after_dig_node = sorcery.lib.node.purge_container; 385 - use_texture_alpha = true; 385 + use_texture_alpha = 'blend'; 386 386 on_construct = function(pos) 387 387 local meta = minetest.get_meta(pos) 388 388 local inv = meta:get_inventory() 389 389 inv:set_size('wand', 1) 390 390 update_stand_info(pos) 391 391 end; 392 392 _proto = {