Index: cookbook.lua
==================================================================
--- cookbook.lua
+++ cookbook.lua
@@ -31,10 +31,11 @@
vessel = { caption = 'Any Bottle', cnitem = 'vessels:glass_bottle' };
flower = { caption = 'Any Flower', cnitem = 'flowers:rose' };
mushroom = { caption = 'Any Mushroom', cnitem = 'flowers:mushroom_brown' };
water_bucket = { caption = 'Water Bucket', cnitem = 'bucket:bucket_water' };
sorcery_ley_cable = { caption = 'Cable', cnitem = 'sorcery:cable_vidrium' };
+ scissors = { caption = 'Scissors', cnitem = 'sorcery:scissors_steel' };
};
}
sorcery.cookbook.constants = constants
local slot3x3 = {
@@ -154,19 +155,21 @@
return desc
end;
local bookadjs = { -- sets are in reverse order!
{'Celestial', 'Divine', 'Inspired', 'Heavenly';
- 'Mystic', 'Diabolic', 'Luminous', 'Forsaken'};
+ 'Mystic', 'Diabolic', 'Luminous', 'Forsaken',
+ 'Ethereal'};
{'Dark', 'Perfected', 'Flawless', 'Unthinkable';
- 'Impossible', 'Worrisome', 'Unimpeachable'};
+ 'Impossible', 'Worrisome', 'Unimpeachable', 'Fulsome',
+ 'Wise'};
{'Splendid', 'Magnificent', 'Sublime', 'Grand';
'Beneficent', 'Mysterious', 'Peculiar', 'Eerie';
'Fulsome', 'Fearsome', 'Curious', 'Fascinating';
- 'Notorious', 'Infamous'};
+ 'Notorious', 'Infamous', 'Wondrous'};
}
local cache = {
populate_grindables = function(cache)
if not cache.grindables then
@@ -314,28 +317,55 @@
if not en then return nil end
en = en.recipe
for i,e in pairs(en) do
if e.lens then
rec[i] = 'sorcery:lens_' .. e.lens .. '_' .. e.gem
+ elseif e.item then
+ rec[i] = e.item
+ end
+ if e.consume or (e.item and not e.dmg) then
+ rec[i] = rec[i] .. ' ' .. tostring(e.consume or 1) -- :/
end
end
return rec
end;
props = function(name)
- return sorcery.data.enchants[name].info or {}
+ local ench = sorcery.data.enchants[name]
+ local p = ench.info
+ local desc = ''
+ if ench.cost ~= 0 then
+ desc = string.format('%s %i thaum-second%s of charge when tool is used',
+ ench.cost > 0 and 'Consumes' or 'Generates',
+ math.abs(ench.cost),
+ ench.cost ~= 1 and 's' or ''
+ )
+ end
+
+ if p == nil then return {note = desc} end
+ if p.note then return p end
+ return sorcery.lib.tbl.proto({note = desc},p)
end;
slots = {
{0.5,0};
{0,1}, {1,1}
};
title = function(name) return sorcery.data.enchants[name].name end;
outdesc = function(name,suffix)
local e = sorcery.data.enchants[name]
+ local cap = sorcery.lib.str.capitalize
+ local aff = sorcery.data.affinities[e.affinity]
return sorcery.lib.ui.tooltip {
title = e.name;
- desc = sorcery.lib.str.capitalize(e.desc);
- color = sorcery.lib.color(e.tone):readable();
+ desc = cap(e.desc);
+ color = sorcery.lib.color(e.tone);
+ props = {
+ {
+ title = string.format('%s affinity', cap(e.affinity));
+ desc = aff.desc;
+ color = sorcery.lib.color(aff.color);
+ };
+ };
}
end;
};
-- spells = {
-- booksuf = 'Spellbook';
@@ -400,15 +430,16 @@
end
local img, ot
if props.note then
local nx, ny, nw, nh
if notes_right then
- nx = 5.25 ny = 0
- nw = 4 nh = 3
+ nx = 5.25 - (3 - k.w) -- :/
+ ny = 0
+ nw = 4 nh = k.h
else
nx = 0 ny = 3
- nw = 4 nh = 1
+ nw = 4 nh = k,h
end
t = t .. string.format([[
hypertext[%f,%f;%f,%f;note;%s]
]], nx,ny,nw,nh, minetest.formspec_escape(props.note))
end
@@ -415,16 +446,16 @@
if k.icon then img = k.icon(result) end
if k.outdesc then ot = k.outdesc(result) else ot = desc_builtin(result) end
-- image[%f,%f;1,1;gui_furnace_arrow_bg.png^[transformR270]
return t .. string.format([[
item_image[%f,%f;1,1;%s]tooltip[%f,%f;1,1;%s]
- ]] --[[box[%f,%f;1,1;#850083A0]] .. [[
+ box[%f,%f;1.1,1.1;#1a001650]
%s[%f,%f;1,1;%s]
tooltip[%f,%f;1,1;%s]
]], k.w, k.h/2 - 0.5, k.node,
k.w, k.h/2 - 0.5, minetest.formspec_escape(minetest.registered_nodes[k.node].description),
- -- k.w+1, k.h/2 - 0.5,
+ k.w+1.05, k.h/2 - 0.55,
img and 'image' or 'item_image',
k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(img or result),
k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(ot))
end;
Index: data/enchants.lua
==================================================================
--- data/enchants.lua
+++ data/enchants.lua
@@ -18,11 +18,11 @@
desc = 'tools last longer before wearing out';
affinity = 'counterpraxic';
groups = allgroups;
recipe = {
{lens = 'convex', gem = 'amethyst', dmg = 2};
- {lens = 'rectifier', gem = 'emerald', dmg = 4};
+ {item = 'default:obsidian_shard'};
{lens = 'convex', gem = 'emerald', dmg = 2};
};
apply = function(stack,power,base)
local caps = table.copy(stack:get_definition().tool_capabilities)
for g,v in pairs(caps.groupcaps) do
@@ -44,11 +44,11 @@
cost = 1;
tone = {255,235,195};
desc = 'Leave a trail of light hanging in the air as you dig';
recipe = {
{lens = 'convex', gem = 'sapphire', dmg = 2};
- {lens = 'concave', gem = 'ruby', dmg = 1};
+ {item = 'sorcery:gem_luxite_shard'};
{lens = 'concave', gem = 'sapphire', dmg = 1};
};
on_dig = function(ctx)
local chance = 10 -- make dependent on power somehow?
if math.random(chance) == 1 then
@@ -71,15 +71,18 @@
affinity = 'syncretic';
groups = {
'pick'; 'pickaxe'; 'sword';
};
recipe = {
- {lens = 'amplifier', gem = 'ruby', dmg = 5};
- {lens = 'concave', gem = 'mese', dmg = 1};
- {lens = 'concave', gem = 'sapphire', dmg = 1};
+ {lens = 'amplifier', gem = 'ruby', dmg = 5};
+ {item = 'sorcery:powder_tungsten'};
+ {item = 'sorcery:extract_rye'};
};
desc = 'some damage is repaired when used to mine ore or kill an attacker';
+ info = {
+ note = 'Consumes 3 thaum-seconds of charge when repair takes place';
+ };
on_dig = function(ctx)
local orepfx = "stone_with_" -- }:<
-- local oredrop = ' lump'
local barename = string.sub(ctx.node.name, string.find(ctx.node.name, ':') + 1)
if sorcery.itemclass.get(ctx.node.name,'ore') then
@@ -94,11 +97,11 @@
cost = 0;
desc = 'enchantments last longer before running out of power to sustain them';
groups = allgroups;
affinity = 'syncretic';
recipe = {
- {lens = 'rectifier', gem = 'mese', dmg = 7};
+ {item = 'default:mese_crystal_fragment'};
{lens = 'rectifier', gem = 'sapphire', dmg = 2};
{lens = 'rectifier', gem = 'amethyst', dmg = 2};
};
-- implemented in sorcery/enchanter.lua:register_on_dig
};
@@ -108,11 +111,11 @@
cost = 1;
desc = 'strike colored sparks when used to dig near valuable ore.';
groups = {'pick','pickaxe'};
affinity = 'cognic';
recipe = {
- {lens = 'concave', gem = 'ruby', dmg = 3};
+ {item = 'sorcery:gem_luxite'};
{lens = 'concave', gem = 'emerald', dmg = 3};
{lens = 'concave', gem = 'sapphire', dmg = 3};
};
on_dig = function(ctx)
local range = 4*sorcery.enchant.strength(ctx.tool,'dowse')
@@ -152,28 +155,25 @@
tone = {255,50,60};
desc = 'dramatically improve your chances of finding gems while mining veins';
groups = {'pick','pickaxe'};
affinity = 'entropic';
recipe = {
+ {item = 'sorcery:oil_luck'};
{lens = 'amplifier', gem = 'diamond', dmg = 12};
{lens = 'rectifier', gem = 'sapphire', dmg = 9};
- {lens = 'convex', gem = 'ruby', dmg = 7};
};
};
pierce = { -- faster mining speed
name = 'Pierce';
cost = 3;
tone = {113,240,251};
groups = digtools;
- {
- 'pick';'pickaxe';'axe';'shovel';'sickle';
- };
desc = 'rip through solid stone or wood like a hot knife through butter';
recipe = {
{lens = 'amplifier', gem = 'diamond', dmg = 4};
{lens = 'amplifier', gem = 'ruby', dmg = 4};
- {lens = 'rectifier', gem = 'diamond', dmg = 2};
+ {item = 'default:flint'};
};
affinity = 'praxic';
apply = function(stack,power,base)
local caps = table.copy(stack:get_definition().tool_capabilities)
for g,v in pairs(caps.groupcaps) do
@@ -190,13 +190,13 @@
name = 'Rend';
affinity = 'praxic';
tone = {251,203,113};
groups = {'sword';'pick';'pickaxe';};
recipe = {
- {lens = 'convex', gem = 'mese', dmg = 3};
{lens = 'amplifier', gem = 'emerald', dmg = 7};
- {lens = 'amplifier', gem = 'diamond', dmg = 7};
+ {item = 'flowers:flower_rose'};
+ {item = 'sorcery:powder_silver'};
};
cost = 5;
desc = 'cleave through sturdy ores and tear mortal flesh with fearsome ease';
apply = function(stack,power,base)
local caps = table.copy(stack:get_definition().tool_capabilities)
@@ -219,11 +219,11 @@
groups = {'sorcery_sanctify'};
affinity = 'entropic';
tone = {255,255,255};
cost = 7;
recipe = {
- {lens = 'amplifier', gem = 'ruby', dmg = 13};
+ {item = 'sorcery:holy_water'};
{lens = 'amplifier', gem = 'ruby', dmg = 15};
{lens = 'amplifier', gem = 'ruby', dmg = 18};
};
};
}
Index: data/metals.lua
==================================================================
--- data/metals.lua
+++ data/metals.lua
@@ -394,11 +394,11 @@
cooktime = 120;
hardness = 8;
maxconduct = 15;
sharpness = 5;
level = 2;
- speed = 1.7;
+ speed = 2.5;
maxenergy = 2200;
durability = 1500;
slots = {
{affinity={'praxic'},confluence=3};
{affinity={'syncretic'},confluence=2};
Index: data/oils.lua
==================================================================
--- data/oils.lua
+++ data/oils.lua
@@ -107,7 +107,19 @@
'sorcery:extract_grape';
'farming:cocoa_beans';
'farming:sugar';
'farming:sugar';
};
+ };
+ luck = {
+ color = {156,54,255};
+ style = 'sparkle';
+ mix = {
+ 'sorcery:extract_marram';
+ 'farming:hemp_leaf';
+ 'farming:hemp_oil';
+ 'xdecor:honey';
+ 'farming:salt';
+ 'farming:salt';
+ };
};
}
Index: data/runes.lua
==================================================================
--- data/runes.lua
+++ data/runes.lua
@@ -142,10 +142,15 @@
if not target then return false end
local subjects if ctx.amulet.frame == 'cobalt' then
if ctx.target.type ~= 'object' then return false end
subjects = {{ref=ctx.target.ref}}
+ elseif ctx.amulet.frame == 'iridium' then
+ subjects = {}
+ for _,o in pairs(minetest.get_objects_inside_radius(ctx.caster:get_pos(), ctx.stats.power)) do
+ subjects[#subjects+1] = {player = o}
+ end
else subjects = {{ref=ctx.caster}} end
local delay = math.max(5,11 - ctx.stats.power) + 2.3*(math.random()*2-1)
local color = sorcery.lib.color(117,38,237)
teleport(ctx,subjects,delay,target:get_pos(),color)
@@ -866,11 +871,11 @@
desc = 'Bring an exact twin of any object or item into existence, no matter how common or rare it might be';
cast = function(ctx)
local color = sorcery.lib.color(255,61,205)
local dup, sndpos, anchor, sbj, ty
if ctx.target.type == 'object' and ctx.target.ref:get_luaentity().name == '__builtin:item' then
- -- sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems???
+ sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems???
sndpos = 'subjects'
sbj = {{player = ctx.target.ref}}
local item = ItemStack(ctx.target.ref:get_luaentity().itemstring)
local r = function() return math.random() * 2 - 1 end
local putpos = vector.offset(ctx.target.ref:get_pos(), r(), 1, r())
Index: data/spells.lua
==================================================================
--- data/spells.lua
+++ data/spells.lua
@@ -29,11 +29,11 @@
end
local anchorwand = function(aff,uses,recipe)
local affcolor = sorcery.lib.color(sorcery.data.affinities[aff].color)
return {
name = aff .. ' anchor';
- desc = 'With an enchanter, anchor ' .. aff .. ' spells into an object to enable it to produce preternatural effects';
+ 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';
uses = uses;
affinity = recipe;
color = affcolor;
sound = 'xdecor_enchanting'; -- FIXME make own
cast = function(ctx)
@@ -114,10 +114,12 @@
then return false end
elseif spec.item then
default_mode = 'consume'
if stack:get_name() ~= spec.item then
return false end
+ if spec.consume and stack:get_count() < spec.consume then
+ return false end
else
return false
end
local mode
@@ -127,11 +129,20 @@
if mode == 'dmg' then
stack:add_wear((spec.dmg or 1) * 1000)
return stack
elseif mode == 'consume' then
+ local r = sorcery.register.residue.db[stack:get_name()]
stack:take_item(spec.consume or 1)
+ if r then
+ local rs = ItemStack(r)
+ rs:set_count(rs:get_count() * (spec.consume or 1))
+ if stack:is_empty()
+ then stack = rs
+ else minetest.add_item(ctx.target.above, rs)
+ end
+ end
return stack
end
end
for ench,data in pairs(sorcery.data.enchants) do
if data.affinity ~= aff or data.recipe == nil then goto skip end
@@ -193,11 +204,11 @@
end;
};
seal = {
name = 'sealing';
color = {255,238,16};
- uses = 32;
+ uses = 128;
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';
leytype = 'imperic';
affinity = {'pine','dark'};
cast = function(ctx)
if ctx.target == nil or ctx.target.type ~= 'node' then return false end
@@ -254,15 +265,15 @@
cast = function(ctx)
local color = ctx.base.gem == 'sapphire';
local duration = (ctx.base.gem == 'amethyst' and 4) or 2;
local ley = sorcery.ley.estimate(ctx.caster:get_pos())
- local strength = ley.force
+ local strength = ley.force * 4 * ley.force
if color then
strength = strength / #ley.aff
for _,a in pairs(ley.aff) do
- cast_sparkle(ctx,sorcery.lib.color(sorcery.data.affinities[a].color):brighten(1.3), strength, duration * strength)
+ cast_sparkle(ctx,sorcery.lib.color(sorcery.data.affinities[a].color):brighten(1.3), strength, duration * (strength*0.5))
end
else
cast_sparkle(ctx,sorcery.lib.color(250,255,185), strength, duration*strength)
end
@@ -585,10 +596,11 @@
sorcery.ley.setcharge(rechargee,charge + newenergy)
e:set_stack('item',1,rechargee)
enchantment_sparkle(ctx, sorcery.lib.color(212,6,63))
+ sorcery.enchant.update_enchanter(ctx.target.under)
end;
};
transfer = {
name = 'transfer';
uses = 65;
@@ -626,10 +638,11 @@
else table.remove(e.spells, math.random(#e.spells))
end
end
sorcery.enchant.set(item,e)
ei:set_stack('item',1,item)
+ sorcery.enchant.update_enchanter(ctx.target.under)
enchantment_sparkle(ctx,sorcery.lib.color(255,154,44))
enchantment_sparkle(ctx,sorcery.lib.color(226,44,255))
end;
};
divine = {
Index: entities.lua
==================================================================
--- entities.lua
+++ entities.lua
@@ -5,11 +5,11 @@
}
minetest.register_entity('sorcery:spell_projectile_flamebolt',{
initial_properties = {
visual = "sprite";
- use_texture_alpha = true;
+ use_texture_alpha = 'blend';
textures = {'sorcery_fireball.png'};
visual_size = { x = 2, y = 2, z = 2 };
physical = true;
collide_with_objects = true;
pointable = false;
DELETED hotmetallurgy.lua
Index: hotmetallurgy.lua
==================================================================
--- hotmetallurgy.lua
+++ hotmetallurgy.lua
@@ -1,446 +0,0 @@
--- alloying furnace
---
--- there are several kinds of alloy furnace, with varying
--- capabilities. the simplest can alloy two simple metals;
--- the most complex can alloy four high-grade metals such
--- as titanium, platinum, iridium, or levitanium.
---
--- furnace recipes follow a pattern: the number of crucibles
--- determines the input slots, the type of crucible determines
--- how hot the furnace can get, and various other components
--- (like a coolant circulator) can be added to allow the
--- creation of exotic metals.
---
--- alloy furnaces produce ingots that can later be melted down
--- again and cast into a mold to produce items of particular
--- shapes.
-
--- there are five kinds of crucibles: clay, aluminum, platinum,
--- duridium, and impervium. clay crucibles are made by molding
--- clay into the proper shape and then firing it in a furnace.
--- others are made by casting.
-
-local fragments_per_ingot = 4
-
-for _, c in pairs { 'clay', 'aluminum', 'platinum', 'duranium' } do
- minetest.register_craftitem('sorcery:crucible_' .. c, {
- description = sorcery.lib.str.capitalize(c .. ' crucible');
- inventory_image = 'sorcery_crucible_' .. c .. '.png';
- })
-end
-
-minetest.register_craftitem('sorcery:crucible_clay_molding', {
- description = sorcery.lib.str.capitalize('Crucible molding');
- inventory_image = 'sorcery_crucible_clay_molding.png';
-})
-
-minetest.register_craft {
- recipe = {
- { 'default:clay_lump', '', 'default:clay_lump'};
- { 'default:clay_lump', '', 'default:clay_lump'};
- { 'default:clay_lump', 'default:clay_lump', 'default:clay_lump'};
- };
- output = 'sorcery:crucible_clay_molding';
-}
-minetest.register_craft {
- type = 'shapeless';
- recipe = { 'sorcery:crucible_clay_molding' };
- output = 'default:clay_lump 7';
-}
-minetest.register_craft {
- type = 'cooking';
- recipe = 'sorcery:crucible_clay_molding';
- cooktime = 40;
- output = 'sorcery:crucible_clay';
-}
-
-local burn_layout = function(v)
- local layouts = {
- [1] = {w = 1, h = 1}; [2] = {w = 2, h = 1}; [3] = {w = 3, h = 1};
- [4] = {w = 2, h = 2}; [5] = {w = 3, h = 2}; [6] = {w = 3, h = 2};
- [7] = {w = 4, h = 2}; [8] = {w = 4, h = 2}; [9] = {w = 3, h = 3};
- }
- local inpos = { x = 2.8, y = 1 }
- local insize = layouts[v.in]
- local outpos = { x = 5.2, y = 2.4 }
- local outsize = layouts[v.out]
- local fuelpos = { x = 2.8, y = 3.4 }
- local fuelsize = layouts[v.fuel]
- return string.format([[
- list[context;input;%f,%f;%f,%f;]
- list[context;output;%f,%f;%f,%f;]
- list[context;fuel;%f,%f;%f,%f;]
-
- image[2.3,1.9;1,1;default_furnace_fire_bg.png^[lowpart:%u%%:default_furnace_fire_fg.png]
- image[3.2,1.9;1,1;gui_furnace_arrow_bg.png^[lowpart:%u%%:gui_furnace_arrow_fg.png^[transformR270]
-
- listring[context;output] listring[current_player;main]
- listring[context;input] listring[current_player;main]
- listring[context;fuel] listring[current_player;main]
- ]],
-
- --input
- inpos.x - insize.w/2, -- pos
- inpos.y - insize.h/2,
- insize.w, insize.h, -- size
- --output
- outpos.x - outsize.w/2, -- pos
- outpos.y - outsize.h/2,
- outsize.w, outsize.h, -- size
- --fuel
- fuelpos.x - fuelsize.w/2, -- pos
- fuelpos.y - fuelsize.h/2,
- fuelsize.w, fuelsize.h, -- size
-
- v.burn, v.prog
- )
-end
-
-local kiln_formspec = function(kind, fuel_progress, cook_progress)
- return [[
- size[8,8]
- list[current_player;main;0,4.2;8,4]
- list[context;wax;0,2;1,1]
- ]] .. burn_layout{
- in = kind.size^2;
- out = kind.outsize;
- fuel = kind.fuelsize;
- burn = fuel_progress;
- prog = cook_progress;
- }
-end
-
-local smelter_formspec = function(kind, fuel_progress, smelt_progress)
- return [[
- size[8,8]
- list[current_player;main;0,4.2;8,4]
- ]] .. burn_layout {
- in = kind.size;
- out = kind.outsize;
- fuel = kind.fuelsize;
- burn = fuel_progress;
- prog = smelt_progress;
- }
-end
-
-local find_recipe = function(inv)
- local mix = {}
- local count = 0
- for i=1,inv:get_size('input') do
- local m = inv:get_stack('input',i)
- if m:is_empty() then goto skip end
- local l = sorcery.data.metallookup[m:get_name()]
- if not l then return false end
- mix[l.id] = (mix[l.id] or 0) + l.value
- count = count + l.value
- ::skip::end
- -- everything is metal, we've finished summing it up.
- -- let's see if the assembled items match the ratio
- -- specified in any of the smelting recipes.
- local matches = 0
- for _,rec in pairs(sorcery.data.alloys) do
- local fac = nil
- local meltpoint = 1
- if rec.metals == nil then goto skip_recipe end
- for metal, ratio in pairs(rec.metals) do
- if mix[metal] and mix[metal] % ratio == 0 then
- if fac then
- if mix[metal] / ratio ~= fac then goto skip_recipe end
- else fac = math.floor(mix[metal] / ratio) end
- local m = sorcery.data.metals[metal]
- if m.meltpoint then
- meltpoint = math.max(meltpoint, m.meltpoint) end
- else goto skip_recipe end
- end
- do return rec, count, fac, meltpoint end
- ::skip_recipe::end
- return false
-end
-
-local update_smelter = function(pos)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- local proto = minetest.registered_nodes[minetest.get_node(pos).name]._proto
- local recipe, count, factor, meltpoint = find_recipe(inv)
- if recipe --[[and proto.temp >= meltpoint]] then
- minetest.get_node_timer(pos):start(1)
- else
- meta:set_float('burntime',0)
- end
-end
-
-local smelter_step = function(kind,active,pos,delta)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- local recipe, count, factor = find_recipe(inv)
- local cooktime
- local elapsed = meta:get_float('burntime') + delta
- meta:set_float('burnleft',meta:get_float('burnleft') - delta)
- if (not active) and (not recipe) then return false end
- if meta:get_float('burnleft') <= 0 or not active then
- if recipe then
- local burn, frep = minetest.get_craft_result {
- method = 'fuel', width = 1;
- items = { inv:get_stack('fuel',1) };
- }
- if burn.time == 0 then goto nofuel end
- inv:set_stack('fuel', 1, frep.items[1])
- meta:set_float('burnleft',burn.time)
- meta:set_float('burnmax',burn.time)
- if not active then
- minetest.swap_node(pos,
- sorcery.lib.tbl.merge(minetest.get_node(pos), {
- name = kind.id .. '_active'
- }))
- active = true
- end
- else goto nofuel end
- end
-
- if not recipe then goto update end
-
- cooktime = ((recipe.cooktime / fragments_per_ingot) * count) / factor
- if elapsed >= cooktime then
- elapsed = 0
- -- remove used items
- for i=1,inv:get_size('input') do
- local s = inv:get_stack('input',i)
- if s:is_empty() then goto skip end
- s:take_item(1) inv:set_stack('input',i,s)
- ::skip::end
-
- local outstack
- if count % fragments_per_ingot == 0 then
- outstack = ItemStack {
- name = sorcery.data.metals[recipe.output].ingot or 'sorcery:' .. recipe.output .. '_ingot';
- count = count / fragments_per_ingot;
- }
- else
- outstack = ItemStack {
- name = 'sorcery:fragment_' .. recipe.output;
- count = count;
- }
- end
-
- local leftover = inv:add_item('output',outstack)
- if not leftover:is_empty() then
- minetest.add_item(pos, leftover)
- end
- end
-
- ::update::
- meta:set_float('burntime',elapsed)
- meta:set_string('formspec', smelter_formspec(kind,
- math.min(1, meta:get_float('burnleft') /
- meta:get_float('burnmax')
- ) * 100, -- fuel
- (cooktime and math.min(1, elapsed / cooktime) * 100) or 0 -- smelt
- ))
- do return active end
-
- ::nofuel::
- if active then
- minetest.swap_node(pos,
- sorcery.lib.tbl.merge(minetest.get_node(pos), { name = kind.id }))
- end
- meta:set_float('burnleft',0) -- just in case
- ::noburn::
- meta:set_float('burntime',0) -- just in case
- meta:set_string('formspec', smelter_formspec(kind, 0, 0))
- return false
-end
-local register_kiln = function(kind)
- local box = {
- open = {
- type = 'fixed';
- fixed = {
- -0.5,-0.5,-0.5,
- 0.5, 1.6, 0.5
- };
- };
- closed = {
- type = 'fixed';
- fixed = {
- -0.5,-0.5,-0.5,
- 0.5, 0.7, 0.5
- };
- };
- }
- local id = 'sorcery:kiln_' .. kind.material
- local metal = sorcery.data.metals[kind.material]
- -- use some iffy heuristics to guess the texture
- local metaltex
- if kind.material == 'clay' then
- metaltex = 'default_brick.png';
- else
- metaltex = (metal.img and metal.img.block) or
- (metal.ingot and 'default_' .. kind.material .. '_block.png') or
- sorcery.lib.image('default_steel_block.png'):multiply(sorcery.lib.color(metal.tone)):render();
- end
- local tex = {
- open = {
- 'default_furnace_front.png';
- metaltex;
- 'default_copper_block.png';
- 'default_stone.png';
- };
- closed = {
- 'default_furnace_front_active.png';
- 'default_copper_block.png';
- metaltex;
- 'default_stone.png';
- };
- };
- for _,state in pairs{'open','closed'} do
- local id_closed = id .. '_closed'
- local id_current = (state == 'closed' and id_closed) or id
- local desc = sorcery.lib.str.capitalize(kind.temp_name) .. ' kiln';
- minetest.register_node(id_current, {
- _active = (state == 'closed');
- _proto = kind;
- description = desc;
- drawtype = "mesh";
- mesh = 'sorcery-kiln-' .. state .. '.obj';
- drop = id;
- groups = { cracky = 2; sorcery_device_kiln = (state == 'closed') and 1 or 2; }
- sunlight_propagates = true;
- paramtype1 = 'light';
- paramtype2 = 'facedir';
- selection_box = box[state];
- collision_box = box[state];
- tiles = tex[state];
- light_source = (state == 'closed' and 7) or 0;
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- inv:set_size('input', kind.size^2)
- inv:set_size('output', kind.outsize)
- inv:set_size('fuel', kind.fuelsize)
- inv:set_size('wax', 1)
-
- meta:set_float('burnleft',0)
- meta:set_float('burnmax',0)
- meta:set_float('burntime',0)
-
- meta:set_string('infotext',desc)
- meta:set_string('formspec',kiln_formspec(kind,0,0))
- end;
- on_timer = function(pos,delta)
- end;
-
- on_metadata_inventory_put = function(pos)
- minetest.get_node_timer(pos):start(1) end;
- on_metadata_inventory_move = function(pos)
- minetest.get_node_timer(pos):start(1) end;
- on_metadata_inventory_take = function(pos)
- minetest.get_node_timer(pos):start(1) end;
- })
- end
- local ingot
- if kind.material == 'clay' then
- ingot = 'default:clay_brick';
- else
- ingot = metal.ingot or 'sorcery:' .. kind.material .. '_ingot'
- end
- minetest.register_craft = {
- output = id_open;
- recipe = {
- {'default:copper_ingot', 'default:copper_ingot', 'default:copper_ingot'};
- {ingot,'',ingot};
- {ingot,'default:furnace',ingot};
- };
- }
-end
-
-local register_smelter = function(kind)
- local recipe = {{},{};
- {'default:stone','default:furnace','default:stone'};
- } do
- local on = kind.crucible
- local ti = 'default:tin_ingot'
- local cu = 'default:copper_ingot'
- local crucmap = {
- [2] = { {cu,cu,cu}, {on,ti,on} };
- [3] = { {cu,on,cu}, {on,ti,on} };
- [4] = { {on,cu,on}, {on,ti,on} };
- [5] = { {on,cu,on}, {on,on,on} };
- [6] = { {on,on,on}, {on,on,on} };
- };
- for y=1,2 do recipe[y] = crucmap[kind.size][y] end
- end
-
- local desc = 'smelter';
- if kind.temp_name then desc = kind.temp_name .. ' ' .. desc end
- if kind.size_name then desc = kind.size_name .. ' ' .. desc end
- desc = sorcery.lib.str.capitalize(desc);
- local id = 'sorcery:smelter_' .. kind.material .. kind.size_name
- kind.id = id
- for _, active in pairs {false, true} do
- minetest.register_node((active and id .. '_active') or id, {
- _proto = kind;
- description = desc;
- drop = id;
- groups = {
- cracky = 2;
- sorcery_device_smelter = active and 1 or 2;
- };
- paramtype2 = 'facedir';
- light_source = (active and 9) or 0;
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- inv:set_size('input',kind.size)
- inv:set_size('output',kind.outsize)
- inv:set_size('fuel',kind.fuelsize)
- meta:set_string('infotext', desc)
- meta:set_string('formspec', smelter_formspec(kind, 0, 0))
- meta:set_float('burnleft',0)
- meta:set_float('burnmax',0)
- meta:set_float('burntime',0)
- end;
- on_metadata_inventory_put = update_smelter;
- on_metadata_inventory_move = update_smelter;
- on_metadata_inventory_take = update_smelter;
- on_timer = function(pos,delta) return smelter_step(kind, active, pos, delta) end;
- -- allow_metadata_inventory_put = function(pos, listname, index, stack, player)
- -- end;
- tiles = {
- 'sorcery_smelter_top_' .. tostring(kind.size) .. '.png';
- 'sorcery_smelter_bottom.png';
- 'sorcery_smelter_side.png';
- 'sorcery_smelter_side.png';
- 'sorcery_smelter_side.png';
- 'sorcery_smelter_front' .. ((active and '_hot') or '') .. '.png';
- };
- })
- end
- minetest.register_craft {
- recipe = recipe;
- output = id;
- }
-end
-
-for _, t in pairs {
- {1, nil, 'clay'};
- -- {2, 'hot','aluminum'};
- -- {3, 'volcanic','platinum'};
- -- {4, 'stellar','duridium'};
- -- {5, 'nova','impervium'};
-} do register_kiln {
- temp = t[1], temp_name = t[2];
- material = t[3];
- size = 3, outsize = 4, fuelsize = 1; -- future-proofing
- }
-
- for _, s in pairs {
- {2, 'small'};
- {3, 'large'};
- {4, 'grand'};
- } do register_smelter {
- size = s[1], size_name = s[2];
- temp = t[1], temp_name = t[2];
- material = t[3];
- crucible = 'sorcery:crucible_' .. t[3];
- outsize = 4, fuelsize = 1; -- future-proofing
- } end
-end
Index: init.lua
==================================================================
--- init.lua
+++ init.lua
@@ -101,12 +101,12 @@
data {
'compat';
'affinities'; 'gods';
'calendar', 'signs';
'resonance';
- 'enchants', 'spells', 'runes';
'gems', 'metals';
+ 'enchants', 'spells', 'runes';
'potions', 'oils', 'greases',
'draughts', 'elixirs',
'philters', 'extracts';
}
end
Index: leylines.lua
==================================================================
--- leylines.lua
+++ leylines.lua
@@ -378,11 +378,11 @@
neighbors = {'group:sorcery_ley_device'};
interval = 5.6, chance = 1, catch_up = false;
action = function(pos)
local force = sorcery.ley.estimate(pos).force
minetest.sound_play('sorcery_condenser_bg', {
- pos = pos, max_hear_distance = 5 + 8*force, gain = force*0.3;
+ pos = pos, max_hear_distance = 5 + 4*force, gain = force*0.3;
})
end;
}
end
Index: lib/color.lua
==================================================================
--- lib/color.lua
+++ lib/color.lua
@@ -162,13 +162,20 @@
-- print("back is r"..temp.red.."g"..temp.green.."b"..temp.blue)
return { hue = hue, saturation = saturation, luminosity = luminosity }
end;
readable = function(self, target)
- target = target or 0.5
+ target = target or 0.6
local hsl = self:to_hsl()
hsl.luminosity = target
+ local worstHue = 230
+ local nearness = math.abs(worstHue - hsl.hue)
+ if nearness <= 70 then
+ local boost = 1.0 - (nearness / 70)
+ hsl.luminosity = math.min(1, hsl.luminosity * (1 + (boost*0.4)))
+ end
+
return from_hsl(hsl, self.alpha)
end;
bg = function(self, text) return
text .. minetest.get_background_escape_sequence(self:hex())
@@ -183,11 +190,12 @@
-- To HSL
local hsl = self:to_hsl()
-- Do the calculation, clamp to 0-1 instead of the clamp fn
hsl.luminosity = math.min(math.max(hsl.luminosity * fac, 0), 1)
-- Turn back into RGB color
- local t = from_hsl(hsl, self.alpha)
+ -- local t = from_hsl(hsl, self.alpha)
+ -- print("darker is r"..hsl.red.."g"..hsl.green.."b"..hsl.blue)
-- print("brighten is r"..t.red.."g"..t.green.."b"..t.blue)
return from_hsl(hsl, self.alpha)
end;
darken = warp(function(new, fac)
ADDED lib/hud.lua
Index: lib/hud.lua
==================================================================
--- lib/hud.lua
+++ lib/hud.lua
@@ -0,0 +1,28 @@
+-- the HUD library provides an easy-to-use interface for create custom
+-- item UIs. the idea is that an item will define one or more UI layouts
+-- in its _sorcery.hud property, then call lib.hud.open(id, layout, player, ...)
+-- when it wishes to open , usually from its on_use handler. the library
+-- will then iterate through the elements in its definition, transmit them to
+-- the user, and store the resulting handles in a user context. it will also
+-- register any timer callbacks needed to ensure a timely update of the item.
+-- if the item is removed from the hotbar, any UI associated with it will be
+-- closed.
+--
+-- each UI element can have a function that is called to set its value. if
+-- this is present, it will be called at initialization and at update.
+--
+-- example:
+-- _sorcery = {
+-- hud = {
+-- powerlevel = {
+-- period = 0.1;
+-- elements = {
+-- {kind = 'text',
+-- text = function(ctx)
+-- return ctx.stack:get_meta():get_int("power")
+-- end;
+-- };
+-- };
+-- };
+-- };
+-- };
Index: lib/tbl.lua
==================================================================
--- lib/tbl.lua
+++ lib/tbl.lua
@@ -53,10 +53,18 @@
new[k] = v
end
end
return new
end
+
+fn.append = function(r1, r2)
+ local new = fn.copy(r1)
+ for i=1,#r2 do
+ new[#new + 1] = r2[i]
+ end
+ return new
+end
fn.merge = function(base,override)
local new = fn.copy(base)
for k,v in pairs(override) do
new[k] = v
@@ -64,11 +72,11 @@
return new
end
fn.deepmerge = function(base,override,func)
local new = {}
- local keys = fn.merge(fn.keys(base),fn.keys(override))
+ local keys = fn.append(fn.keys(base),fn.keys(override))
for _,k in pairs(keys) do
if type(base[k]) == 'table' and
type(override[k]) == 'table' then
new[k] = fn.deepmerge(base[k], override[k], func)
elseif func and override[k] and base[k] then
@@ -77,18 +85,10 @@
new[k] = override[k]
else
new[k] = base[k]
end
end
- return new
-end
-
-fn.append = function(r1, r2)
- local new = fn.copy(r1)
- for i=1,#r2 do
- new[#new + 1] = r2[i]
- end
return new
end
fn.has = function(tbl,value,eqfn)
for k,v in pairs(tbl) do
Index: lib/ui.lua
==================================================================
--- lib/ui.lua
+++ lib/ui.lua
@@ -1,11 +1,11 @@
local l = sorcery.lib
local dui = sorcery.data.ui
return {
tooltip = function(a)
- local color = a.color
+ local color = a.color and a.color:readable()
if color == nil then color = l.color(136,158,177) end
local str = a.title
if a.desc then
str = str .. '\n' .. color:fmt(minetest.wrap_text(a.desc,60))
end
@@ -12,11 +12,11 @@
if a.props then
-- str = str .. '\n'
for _,prop in pairs(a.props) do
local c
if prop.color and l.color.id(prop.color) then
- c = prop.color
+ c = prop.color:readable()
elseif dui.colors[prop.affinity] then
c = l.color(dui.colors[prop.affinity])
else
c = l.color(dui.colors.neutral)
end
@@ -25,15 +25,15 @@
if prop.title then
str = str .. c:brighten(1.3):fmt(prop.title) .. ': '
end
- local lines = minetest.wrap_text(prop.desc, 50, true)
+ local lines = minetest.wrap_text(prop.desc, 55, true)
str = str .. c:fmt(lines[1])
for i=2,#lines do
str = str .. '\n' .. string.rep(' ',5) .. c:fmt(lines[i])
end
end
end
- return str
+ return color:darken(0.8):bg(str)
end;
}
Index: metallurgy-cold.lua
==================================================================
--- metallurgy-cold.lua
+++ metallurgy-cold.lua
@@ -131,11 +131,11 @@
mp.grindcost = mp.grindcost or constants.default_grindcost
if item:get_wear() ~= 0 then
-- prevent cheating by recovering metal from items before they
-- are destroyed
- local wearfac = (item:get_wear() / 65535)
+ local wearfac = 1-(item:get_wear() / 65535)
mp.grindvalue = math.max(1,math.ceil(mp.grindvalue * wearfac))
mp.hardness = math.max(1,math.ceil(mp.grindcost * wearfac))
mp.torque = math.max(1,math.ceil(mp.torque * wearfac))
end
Index: portal.lua
==================================================================
--- portal.lua
+++ portal.lua
@@ -360,11 +360,11 @@
minpos = { x = -0.3, y = 0, z = -0.3 };
maxpos = { x = 0.3, y = 1.5, z = 0.3 };
minvel = { x = -0.3, y = 0.4, z = -0.3 };
maxvel = { x = 0.3, y = 0.6, z = 0.3 };
maxacc = { x = 0, y = 0.5, z = 0 };
- texture = sorcery.lib.image('sorcery_spark.png'):multiply(sorcery.lib.color(255,144,226)):render();
+ texture = sorcery.lib.image('sorcery_sputter.png'):glow(sorcery.lib.color(255,144,226)):render();
minexptime = 1.5;
maxexptime = 2;
minsize = 0.4;
maxsize = 1.6 * fac;
glow = 14;
Index: potions.lua
==================================================================
--- potions.lua
+++ potions.lua
@@ -10,18 +10,18 @@
'^[multiply:'..tostring(color)..
'^vessels_glass_bottle.png'
sorcery.register.residue.link('sorcery:' .. name, 'vessels:glass_bottle')
local node = {
- description = color:darken(0.8):bg(
+ description = --color:darken(0.8):bg(
sorcery.lib.ui.tooltip {
title = label;
desc = desc;
color = color:readable();
- }
+ };
-- label .. (desc and ("\n" .. color:readable():fmt(desc)) or '')
- );
+ --);
short_description = label;
drawtype = "plantlike";
tiles = {image};
inventory_image = image;
paramtype = "light";
Index: runeforge.lua
==================================================================
--- runeforge.lua
+++ runeforge.lua
@@ -1,10 +1,11 @@
-- TODO make some kind of disposable "filter" tool that runeforges require
-- to generate runes and that wears down over time, to make amulets more
-- expensive than they currently are? the existing system is neat but
-- i think amulets are a little overpowered for something that just
-- 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
@@ -46,12 +47,13 @@
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, {
- description = sorcery.lib.color(rune.tone):readable():fmt(rune.name .. ' Rune');
+ description = c:darken(0.7):bg(c:readable():fmt(rune.name .. ' Rune'));
short_description = rune.name .. ' Rune';
inventory_image = rune.image;
stack_max = 1;
groups = {
sorcery_rune = 1;
@@ -147,11 +149,11 @@
m:set_string('amulet_rune', rp.id)
m:set_int('amulet_rune_grade', rg)
local spell = sorcery.amulet.getspell(stack)
if not spell then return nil end
local name
- if spell.minrune then -- indicating quality makes less sense if it's restricted
+ if spell.mingrade and spell.mingrade > 0 then -- indicating quality makes less sense if it's restricted
name = string.format('Amulet of %s', spell.name)
else
name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name)
end
m:set_string('description', sorcery.lib.ui.tooltip {
@@ -405,11 +407,11 @@
i:set_size('wrench',1) i:set_size('phial',1) i:set_size('refuse',1)
i:set_size('amulet',1) i:set_size('active',1)
m:set_string('infotext','Rune Forge')
runeforge_update(pos)
end;
- after_dig_node = sorcery.lib.node.purge_only {'amulet'};
+ after_dig_node = sorcery.lib.node.purge_only {'amulet','wrench'};
on_timer = runeforge_update;
on_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
local inv = minetest.get_meta(pos):get_inventory()
local wrench if not inv:is_empty('wrench') then
wrench = inv:get_stack('wrench',1):get_definition()._proto
Index: vfx.lua
==================================================================
--- vfx.lua
+++ vfx.lua
@@ -12,11 +12,12 @@
local height = caster:get_properties().eye_height
minetest.add_particlespawner {
amount = 70 * strength;
time = duration or 1.5;
attached = caster;
- texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render();
+ -- texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render();
+ texture = sorcery.vfx.glowspark(color):render();
minpos = ofs({ x = 0.0, z = 0.6, y = height*0.7});
maxpos = ofs({ x = 0.4, z = 0.2, y = height*1.1});
minvel = { x = -0.5, z = -0.5, y = -0.5};
maxvel = { x = 0.5, z = 0.5, y = 0.5};
minacc = { x = 0.0, z = 0.0, y = 0.5};
@@ -65,11 +66,11 @@
sorcery.vfx.enchantment_sparkle = function(tgt,color)
local minvel, maxvel
if minetest.get_node(vector.add(tgt.under,{y=1,z=0,x=0})).name == 'air' then
minvel = {x=0,z=0,y= 0.3} maxvel = {x=0,z=0,y= 1.5};
else
- local dir = vector.subtract(tgt.under,tgt.above)
+ local dir = vector.subtract(tgt.above,tgt.under)
minvel = vector.multiply(dir, 0.3)
maxvel = vector.multiply(dir, 1.2)
end
return minetest.add_particlespawner {
amount = 50;
Index: wands.lua
==================================================================
--- wands.lua
+++ wands.lua
@@ -161,14 +161,14 @@
end;
matprops = function(proto)
local matprops = {}
for k,v in pairs(proto) do
if sorcery.wands.materials[k] then
- local mp = sorcery.wands.materials[k].wandprops
+ local mp = sorcery.wands.materials[k][v].wandprops
if mp then
matprops = sorcery.lib.tbl.deepmerge(matprops, mp,
- function(a,b,k)
+ function(a,b,key)
if key == 'bond'
then return a+b
else return a*b
end
end)
@@ -274,11 +274,11 @@
};
wearmult = 1;
}
local result = castfn(context)
if result ~= false then
- minetest.sound_play(sorcery.data.spells[spell].sound or "default_item_smoke", { --FIXME make own sounds
+ minetest.sound_play(sorcery.data.spells[spell].sound or "sorcery_chime", { --FIXME make better sound
pos = user:get_pos();
gain = 0.8;
})
-- minetest.add_particle {
-- pos = vector.add(vector.add(user:get_pos(), vector.multiply(user:get_look_dir(),1.1)), {y=1.6,z=0,x=0});
@@ -380,11 +380,11 @@
paramtype2 = 'facedir';
tiles = images;
selection_box = hitbox;
collision_box = hitbox;
after_dig_node = sorcery.lib.node.purge_container;
- use_texture_alpha = true;
+ use_texture_alpha = 'blend';
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size('wand', 1)
update_stand_info(pos)