diff --git a/craftitems.lua b/craftitems.lua new file mode 100644 index 0000000..d981420 --- /dev/null +++ b/craftitems.lua @@ -0,0 +1,20 @@ + +minetest.register_craftitem("magicalities:wand_core", { + description = "Wand Core", + inventory_image = "magicalities_wand_core.png" +}) + +minetest.register_craftitem("magicalities:cap_steel", { + description = "Steel Wand Cap", + inventory_image = "magicalities_cap_iron.png" +}) + +minetest.register_craftitem("magicalities:cap_gold", { + description = "Gold Wand Cap", + inventory_image = "magicalities_cap_gold.png" +}) + +minetest.register_craftitem("magicalities:element_ring", { + description = "Elemental Ring", + inventory_image = "magicalities_element_ring.png" +}) diff --git a/crystals.lua b/crystals.lua index 5107b7d..fa4776c 100644 --- a/crystals.lua +++ b/crystals.lua @@ -1,5 +1,72 @@ -- Magicalities crystals +local randbuff = PcgRandom(os.clock()) + +local function generate_crystal_buffer(pos) + local final = {} + local node = minetest.get_node(pos) + local nodedef = minetest.registered_nodes[node.name] + local self_cnt = randbuff:next(10, 60) + + for name, data in pairs(magicalities.elements) do + if #final > 5 then break end + if not data.inheritance then + if name == nodedef["_element"] then + final[name] = {self_cnt, self_cnt} + else + if randbuff:next(0, 5) == 0 then + local cnt = randbuff:next(0, math.floor(self_cnt / 4)) + final[name] = {cnt, cnt} + end + end + else + if randbuff:next(0, 15) == 0 then + local cnt = randbuff:next(0, math.floor(self_cnt / 8)) + final[name] = {cnt, cnt} + end + end + end + + return final +end + +local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing) + local output = generate_crystal_buffer(pos) + local meta = minetest.get_meta(pos) + + -- Add contents to the crystal + local contents = minetest.deserialize(meta:get_string("contents")) + if not contents then + contents = generate_crystal_buffer(pos) + meta:set_string("contents", minetest.serialize(contents)) + end + + -- Check for wand + if minetest.get_item_group(itemstack:get_name(), "wand") == 0 then + return itemstack + end + + local one_of_each = {} + for name, count in pairs(contents) do + if count[1] > 0 then + one_of_each[name] = 1 + end + end + + local can_put = magicalities.wands.wand_insertable_contents(itemstack, one_of_each) + for name, count in pairs(can_put) do + if count > 0 then + contents[name][1] = contents[name][1] - count + end + end + + itemstack = magicalities.wands.wand_insert_contents(itemstack, can_put) + magicalities.wands.update_wand_desc(itemstack) + meta:set_string("contents", minetest.serialize(contents)) + + return itemstack +end + function magicalities.register_crystal(element, description, color) -- Crystal Item minetest.register_craftitem("magicalities:crystal_"..element, { @@ -53,6 +120,8 @@ function magicalities.register_crystal(element, description, color) sunlight_propagates = true, is_ground_content = false, sounds = default.node_sound_glass_defaults(), + + on_rightclick = crystal_rightclick, }) -- Crystal Block @@ -85,19 +154,6 @@ function magicalities.register_crystal(element, description, color) y_min = -31000, }) - -- Crafting between clusters, shards and blocks - minetest.register_craft({ - type = "shapeless", - output = "magicalities:crystal_cluster_"..element, - recipe = { - "magicalities:crystal_"..element, - "magicalities:crystal_"..element, - "magicalities:crystal_"..element, - "magicalities:crystal_"..element, - "magicalities:crystal_"..element - }, - }) - minetest.register_craft({ type = "shapeless", output = "magicalities:crystal_block_"..element, @@ -123,9 +179,38 @@ function magicalities.register_crystal(element, description, color) }) end --- Register all crystals -for name, data in pairs(magicalities.elements) do - if not data.inheritance then - magicalities.register_crystal(name, data.description, data.color) +-- Register refill ABMs +minetest.register_abm({ + label = "Crystal Elements Refill", + nodenames = {"group:crystal_cluster"}, + interval = 60.0, + chance = 10, + action = function (pos, node, active_object_count, active_object_count_wider) + local meta = minetest.get_meta(pos) + local contents = meta:get_string("contents") + if contents ~= "" then + -- Regenerate some elements + contents = minetest.deserialize(contents) + local count = 0 + for _, v in pairs(contents) do + count = count + 1 + end + + local mcnt = randbuff:next(1, count) + local cnt = 0 + for name, data in pairs(contents) do + if cnt == mcnt then break end + if type(data) ~= 'table' then break end + + if data[1] < data[2] then + data[1] = data[1] + 1 + cnt = cnt + 1 + end + end + + if cnt == 0 then return end + + meta:set_string("contents", minetest.serialize(contents)) + end end -end +}) diff --git a/init.lua b/init.lua index 0d0c40e..baf5e48 100644 --- a/init.lua +++ b/init.lua @@ -6,12 +6,12 @@ magicalities.modpath = modpath magicalities.elements = { -- Base Elements - ["air"] = {color = "#ffff00", description = "Air", inheritance = nil}, ["water"] = {color = "#003cff", description = "Water", inheritance = nil}, - ["fire"] = {color = "#ff2424", description = "Fire", inheritance = nil}, ["earth"] = {color = "#00a213", description = "Earth", inheritance = nil}, ["light"] = {color = "#ffffff", description = "Light", inheritance = nil}, + ["fire"] = {color = "#ff2424", description = "Fire", inheritance = nil}, ["dark"] = {color = "#232323", description = "Dark", inheritance = nil}, + ["air"] = {color = "#ffff00", description = "Air", inheritance = nil}, -- Inherited Elements } @@ -24,3 +24,9 @@ dofile(modpath.."/wands.lua") -- Tables dofile(modpath.."/table.lua") + +-- Items +dofile(modpath.."/craftitems.lua") + +-- Register +dofile(modpath.."/register.lua") diff --git a/register.lua b/register.lua new file mode 100644 index 0000000..b01b6f2 --- /dev/null +++ b/register.lua @@ -0,0 +1,99 @@ +--------------------------- +-- Register all crystals -- +--------------------------- + +for name, data in pairs(magicalities.elements) do + if not data.inheritance then + magicalities.register_crystal(name, data.description, data.color) + end +end + +----------------------------- +-- Arcane crafting recipes -- +----------------------------- + +local recipes = { + { + input = { + {"default:gold_ingot", "default:glass", "default:gold_ingot"}, + {"default:glass", "", "default:glass"}, + {"default:gold_ingot", "default:glass", "default:gold_ingot"}, + }, + output = "magicalities:element_ring", + requirements = { + ["water"] = 15, + ["earth"] = 15, + ["light"] = 15, + ["fire"] = 15, + ["dark"] = 15, + ["air"] = 15, + } + }, + { + input = { + {"", "", "magicalities:cap_gold"}, + {"", "magicalities:wand_core", ""}, + {"group:crystal", "", ""} + }, + output = "magicalities:wand_gold", + requirements = { + ["water"] = 25, + ["earth"] = 25, + ["light"] = 25, + ["fire"] = 25, + ["dark"] = 25, + ["air"] = 25, + } + } +} + +for _, recipe in pairs(recipes) do + magicalities.arcane.register_recipe(recipe) +end + +----------- +-- Wands -- +----------- + +-- Iron +magicalities.wands.register_wand("steel", { + description = "Steel-Capped Wand", + image = "magicalities_wand_iron.png", + wand_cap = 25, +}) + +-- Gold +magicalities.wands.register_wand("gold", { + description = "Gold-Capped Wand", + image = "magicalities_wand_gold.png", + wand_cap = 50, +}) + +-------------------- +-- Basic Crafting -- +-------------------- + +minetest.register_craft({ + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + }, + output = "magicalities:cap_steel", +}) + +minetest.register_craft({ + recipe = { + {"", "default:stick"}, + {"default:stick", ""}, + }, + output = "magicalities:wand_core", +}) + +minetest.register_craft({ + recipe = { + {"", "", "magicalities:cap_steel"}, + {"", "magicalities:wand_core", ""}, + {"group:crystal", "", ""} + }, + output = "magicalities:wand_steel", +}) diff --git a/table.lua b/table.lua index 0f6ba43..9da1d9d 100644 --- a/table.lua +++ b/table.lua @@ -107,7 +107,11 @@ local function compare_find(splitup) local cells = 0 for i, cell in pairs(row) do - if splitup[index][i] == cell then + if cell:find("group:") == 1 then + if minetest.get_item_group(splitup[index][i], cell:gsub("group:", "")) > 0 then + cells = cells + 1 + end + elseif splitup[index][i] == cell then cells = cells + 1 end end @@ -277,24 +281,3 @@ minetest.register_node("magicalities:table", { }, groups = {choppy = 2, oddly_breakable_by_hand = 1, mg_table = 1} }) - --- Basic recipes -local recipes = { - { - input = { - {"default:gold_ingot", "default:glass", "default:gold_ingot"}, - {"default:glass", "", "default:glass"}, - {"default:gold_ingot", "default:glass", "default:gold_ingot"}, - }, - output = "default:diamond", - requirements = { - ["earth"] = 10, - ["light"] = 5, - ["dark"] = 5 - } - } -} - -for _, recipe in pairs(recipes) do - magicalities.arcane.register_recipe(recipe) -end diff --git a/textures/magicalities_cap_gold.png b/textures/magicalities_cap_gold.png new file mode 100644 index 0000000..52c67e6 Binary files /dev/null and b/textures/magicalities_cap_gold.png differ diff --git a/textures/magicalities_cap_iron.png b/textures/magicalities_cap_iron.png new file mode 100644 index 0000000..125560c Binary files /dev/null and b/textures/magicalities_cap_iron.png differ diff --git a/textures/magicalities_element_ring.png b/textures/magicalities_element_ring.png new file mode 100644 index 0000000..1c07184 Binary files /dev/null and b/textures/magicalities_element_ring.png differ diff --git a/textures/magicalities_wand_core.png b/textures/magicalities_wand_core.png new file mode 100644 index 0000000..5ba8eed Binary files /dev/null and b/textures/magicalities_wand_core.png differ diff --git a/textures/magicalities_wand_gold.png b/textures/magicalities_wand_gold.png index 520f565..1151813 100644 Binary files a/textures/magicalities_wand_gold.png and b/textures/magicalities_wand_gold.png differ diff --git a/textures/magicalities_wand_iron.png b/textures/magicalities_wand_iron.png index a7b2fa9..bb7cb42 100644 Binary files a/textures/magicalities_wand_iron.png and b/textures/magicalities_wand_iron.png differ diff --git a/wands.lua b/wands.lua index bc3fd04..d86d79c 100644 --- a/wands.lua +++ b/wands.lua @@ -3,7 +3,7 @@ magicalities.wands = {} local transform_recipes = { - ["mg_table"] = {result = "magicalities:arcane_table", requires = {["earth"] = 5, ["light"] = 5}} + ["mg_table"] = {result = "magicalities:arcane_table", requirements = nil} } local wandcaps = { @@ -43,16 +43,19 @@ function magicalities.wands.update_wand_desc(stack) end end + local elems = {} for elem, amount in pairs(data_table) do local dataelem = magicalities.elements[elem] if amount > 0 then - strbld = strbld.."\n" - strbld = strbld..minetest.colorize(dataelem.color, dataelem.description.." ") - strbld = strbld..align(longest_desc * 2 - #dataelem.description) - strbld = strbld..amount.."/"..capcontents + elems[#elems + 1] = minetest.colorize(dataelem.color, dataelem.description.." ").. + align(longest_desc * 2 - #dataelem.description).. + amount.."/"..capcontents end end + table.sort(elems) + strbld = strbld .. table.concat(elems, "\n") + meta:set_string("description", strbld) end @@ -91,6 +94,48 @@ function magicalities.wands.wand_take_contents(stack, to_take) return stack end +-- Add wand contents +function magicalities.wands.wand_insert_contents(stack, to_put) + local meta = stack:get_meta() + local data_table = minetest.deserialize(meta:get_string("contents")) + local cap = minetest.registered_items[stack:get_name()]["_cap_max"] + local leftover = {} + + for name, count in pairs(to_put) do + if data_table[name] then + if data_table[name] + count > cap then + data_table[name] = cap + leftover[name] = (data_table[name] + count) - cap + else + data_table[name] = data_table[name] + count + end + end + end + + local data_res = minetest.serialize(data_table) + meta:set_string("contents", data_res) + + return stack, leftover +end + +-- Can add wand contents +function magicalities.wands.wand_insertable_contents(stack, to_put) + local meta = stack:get_meta() + local data_table = minetest.deserialize(meta:get_string("contents")) + local cap = minetest.registered_items[stack:get_name()]["_cap_max"] + local insertable = {} + + for name, count in pairs(to_put) do + if data_table[name] then + if data_table[name] + count < cap + 1 then + insertable[name] = count + end + end + end + + return insertable +end + -- Initialize wand metadata local function initialize_wand(stack) local data_table = {} @@ -116,6 +161,7 @@ local function wand_action(itemstack, placer, pointed_thing) magicalities.wands.update_wand_desc(itemstack) end + -- Replacement local to_replace = nil for grp, result in pairs(transform_recipes) do if minetest.get_item_group(node.name, grp) > 0 then @@ -124,10 +170,20 @@ local function wand_action(itemstack, placer, pointed_thing) end end - if not to_replace then return itemstack end - if to_replace.requires then - if not magicalities.wands.wand_has_contents(itemstack, to_replace.requires) then return itemstack end - itemstack = magicalities.wands.wand_take_contents(itemstack, to_replace.requires) + -- Call on_rightclick on the node instead if it cannot be replaced + if not to_replace then + local nodedef = minetest.registered_nodes[node.name] + + if nodedef.on_rightclick then + itemstack = nodedef.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing) + end + + return itemstack + end + + if to_replace.requirements then + if not magicalities.wands.wand_has_contents(itemstack, to_replace.requirements) then return itemstack end + itemstack = magicalities.wands.wand_take_contents(itemstack, to_replace.requirements) magicalities.wands.update_wand_desc(itemstack) end @@ -206,18 +262,3 @@ function magicalities.wands.register_wand(name, data) groups = {wand = 1} }) end - --- Iron -magicalities.wands.register_wand("steel", { - description = "Steel-Capped Wand", - image = "magicalities_wand_iron.png", - wand_cap = 25, -}) - --- Gold -magicalities.wands.register_wand("gold", { - description = "Gold-Capped Wand", - image = "magicalities_wand_gold.png", - wand_cap = 50, -}) -