commit 329bd2de971bd22c1b7b71a11ad1e1f792666274 Author: Evert Date: Tue Apr 17 12:39:28 2018 +0300 first commit diff --git a/crystals.lua b/crystals.lua new file mode 100644 index 0000000..5107b7d --- /dev/null +++ b/crystals.lua @@ -0,0 +1,131 @@ +-- Magicalities crystals + +function magicalities.register_crystal(element, description, color) + -- Crystal Item + minetest.register_craftitem("magicalities:crystal_"..element, { + description = description.." Crystal Shard", + inventory_image = "magicalities_crystal_shard.png^[multiply:"..color, + _element = element, + groups = {crystal = 1, ["elemental_"..element] = 1} + }) + + -- Crystal Cluster + minetest.register_node("magicalities:crystal_cluster_"..element, { + description = description.." Crystal Cluster", + use_texture_alpha = true, + mesh = "crystal.obj", + paramtype = "light", + drawtype = "mesh", + light_source = 4, + _element = element, + collision_box = { + type = "fixed", + fixed = { + {-0.4375, -0.5000, -0.4375, 0.4375, 0.3750, 0.4375} + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.4375, -0.5000, -0.4375, 0.4375, 0.3750, 0.4375} + } + }, + tiles = { + { + name = "magicalities_crystal.png^[multiply:"..color, + backface_culling = true + } + }, + drop = { + max_items = 1, + items = { + { + items = {"magicalities:crystal_"..element.." 4"}, + rarity = 1, + }, + { + items = {"magicalities:crystal_"..element.." 5"}, + rarity = 5, + }, + }, + }, + groups = {cracky = 3, oddly_breakable_by_hand = 3, crystal_cluster = 1, ["elemental_"..element] = 1}, + sunlight_propagates = true, + is_ground_content = false, + sounds = default.node_sound_glass_defaults(), + }) + + -- Crystal Block + minetest.register_node("magicalities:crystal_block_"..element, { + description = description.." Crystal Block", + use_texture_alpha = true, + paramtype = "light", + drawtype = "glasslike", + tiles = { + { + name = "magicalities_crystal.png^[multiply:"..color + } + }, + groups = {cracky = 3, oddly_breakable_by_hand = 3, crystal_block = 1, ["elemental_"..element] = 1}, + sunlight_propagates = true, + is_ground_content = false, + _element = element, + sounds = default.node_sound_glass_defaults(), + }) + + -- Crystal clusters as ores + minetest.register_ore({ + ore_type = "scatter", + ore = "magicalities:crystal_cluster_"..element, + wherein = "default:stone", + clust_scarcity = 19 * 19 * 19, + clust_num_ores = 1, + clust_size = 1, + y_max = -30, + 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, + recipe = { + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element, + "magicalities:crystal_"..element + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = "magicalities:crystal_"..element.." 9", + recipe = { + "magicalities:crystal_block_"..element + }, + }) +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) + end +end diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..0d0c40e --- /dev/null +++ b/init.lua @@ -0,0 +1,26 @@ +-- Magicalities +magicalities = {} + +local modpath = minetest.get_modpath(minetest.get_current_modname()) +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}, + ["dark"] = {color = "#232323", description = "Dark", inheritance = nil}, + + -- Inherited Elements +} + +-- Crystals +dofile(modpath.."/crystals.lua") + +-- Wands +dofile(modpath.."/wands.lua") + +-- Tables +dofile(modpath.."/table.lua") diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..15a7299 --- /dev/null +++ b/mod.conf @@ -0,0 +1,3 @@ +name = magicalities +description = Magic mod. +depends = default diff --git a/models/crystal.obj b/models/crystal.obj new file mode 100644 index 0000000..338e44b --- /dev/null +++ b/models/crystal.obj @@ -0,0 +1,214 @@ +# Blender v2.79 (sub 0) OBJ File: 'crystal.blend' +# www.blender.org +o Circle +v 0.000000 -0.513871 -0.076853 +v -0.072172 -0.525424 -0.023749 +v -0.044605 -0.521011 0.062175 +v 0.044605 -0.506731 0.062175 +v 0.072172 -0.502318 -0.023749 +v -0.112661 0.189941 -0.105862 +v -0.212076 0.174027 -0.032713 +v -0.174103 0.180105 0.085644 +v -0.051219 0.199776 0.085644 +v -0.013246 0.205854 -0.032713 +v -0.144633 0.389677 -0.000000 +v 0.050003 -0.507107 -0.059548 +v -0.001855 -0.489759 -0.015181 +v 0.017953 -0.508363 0.049781 +v 0.082052 -0.537208 0.045563 +v 0.101860 -0.536432 -0.022006 +v 0.279996 -0.003452 -0.008753 +v 0.208564 0.020444 0.052361 +v 0.235849 -0.005181 0.141845 +v 0.324144 -0.044915 0.136035 +v 0.351428 -0.043846 0.042961 +v 0.345267 0.126615 0.093655 +v 0.006559 -0.529833 -0.071262 +v -0.027307 -0.501216 -0.033591 +v 0.003446 -0.492188 0.014964 +v 0.056318 -0.515225 0.007302 +v 0.058242 -0.538491 -0.045988 +v 0.151323 -0.135651 -0.257527 +v 0.104674 -0.096232 -0.205638 +v 0.147036 -0.083796 -0.138754 +v 0.219865 -0.115530 -0.149308 +v 0.222514 -0.147578 -0.222713 +v 0.211547 -0.002344 -0.242770 +v 0.019552 -0.525602 -0.053058 +v -0.018678 -0.525725 -0.027794 +v -0.011679 -0.498792 0.008613 +v 0.030877 -0.482024 0.005850 +v 0.050179 -0.498593 -0.032265 +v -0.102357 -0.248972 -0.251876 +v -0.155018 -0.249141 -0.217076 +v -0.145377 -0.212042 -0.166927 +v -0.086758 -0.188944 -0.170733 +v -0.060170 -0.211768 -0.223235 +v -0.145122 -0.141584 -0.258823 +v -0.018026 -0.520659 0.065952 +v 0.024917 -0.518690 0.081822 +v 0.050201 -0.495533 0.051420 +v 0.022885 -0.483190 0.016761 +v -0.019282 -0.498718 0.025741 +v -0.106777 -0.218207 0.243607 +v -0.047625 -0.215496 0.265468 +v -0.012796 -0.183598 0.223591 +v -0.050423 -0.166595 0.175848 +v -0.108506 -0.187985 0.188219 +v -0.087181 -0.106689 0.267877 +vt 0.036992 0.310017 +vt 0.444154 0.007480 +vt 0.110291 0.000182 +vt 0.272198 0.480906 +vt 0.507409 0.310019 +vt 0.000182 0.315450 +vt 0.265993 0.517594 +vt 0.417569 0.033512 +vt 0.126832 0.033512 +vt 0.540384 0.327257 +vt 0.272201 0.233592 +vt 0.374867 0.726983 +vt 0.000182 0.853181 +vt 0.245908 0.939002 +vt 0.241672 0.543657 +vt 0.026157 0.613683 +vt 0.403461 0.731822 +vt 0.255109 0.517957 +vt 0.026157 0.840286 +vt 0.241672 0.910312 +vt 0.005868 0.592961 +vt 0.182105 0.726985 +vt 0.713394 0.690659 +vt 0.403825 0.794923 +vt 0.606847 0.865829 +vt 0.603346 0.539191 +vt 0.425288 0.597047 +vt 0.737020 0.694655 +vt 0.614450 0.517957 +vt 0.425288 0.784270 +vt 0.603345 0.842126 +vt 0.408523 0.579926 +vt 0.554133 0.690658 +vt 0.557472 0.105466 +vt 0.814742 0.102710 +vt 0.679920 0.000182 +vt 0.603041 0.245712 +vt 0.750502 0.245712 +vt 0.540747 0.096722 +vt 0.589555 0.258915 +vt 0.796071 0.105467 +vt 0.676773 0.018790 +vt 0.758893 0.262617 +vt 0.676771 0.144229 +vt 0.842669 0.536627 +vt 0.996118 0.743142 +vt 0.999818 0.573805 +vt 0.755992 0.655928 +vt 0.842669 0.775227 +vt 0.839912 0.517957 +vt 0.737384 0.652779 +vt 0.982913 0.729658 +vt 0.982913 0.582195 +vt 0.833924 0.791951 +vt 0.881431 0.655927 +vn 0.5853 0.0604 -0.8086 +vn 0.0052 -0.0325 0.9995 +vn -0.5749 -0.1254 -0.8086 +vn 0.9438 0.1177 0.3088 +vn -0.9334 -0.1827 0.3088 +vn -0.0616 0.3850 0.9209 +vn -0.5961 0.2994 -0.7450 +vn 0.8032 0.5234 0.2846 +vn -0.9264 0.2466 0.2846 +vn 0.4728 0.4705 -0.7450 +vn 0.5211 -0.1533 -0.8396 +vn -0.0136 -0.1742 0.9846 +vn -0.5484 0.3280 -0.7692 +vn 0.8516 -0.4637 0.2443 +vn -0.8789 0.3151 0.3582 +vn 0.1614 0.2179 0.9625 +vn -0.3313 0.6807 -0.6534 +vn 0.9586 -0.0488 0.2805 +vn -0.6358 0.6688 0.3854 +vn 0.6541 0.2372 -0.7182 +vn 0.3125 -0.4972 -0.8094 +vn 0.2496 0.2630 0.9319 +vn -0.7552 -0.0320 -0.6547 +vn 0.9336 -0.3149 0.1712 +vn -0.7941 0.4379 0.4215 +vn 0.3670 0.6082 0.7039 +vn -0.5589 0.3364 -0.7580 +vn 0.9971 0.0757 0.0029 +vn -0.5947 0.7693 0.2336 +vn 0.4249 -0.0923 -0.9005 +vn 0.6710 -0.2144 -0.7098 +vn -0.1298 0.4730 0.8715 +vn -0.4202 -0.6444 -0.6389 +vn 0.8504 0.4761 0.2237 +vn -0.9151 -0.2195 0.3383 +vn -0.2637 0.7659 0.5865 +vn -0.5312 -0.2636 -0.8052 +vn 0.6395 0.7688 -0.0104 +vn -0.9872 0.1278 0.0953 +vn 0.4741 0.1325 -0.8704 +vn -0.9689 -0.2288 -0.0946 +vn 0.7805 0.4155 -0.4672 +vn -0.2685 -0.5452 0.7941 +vn -0.3206 0.3650 -0.8741 +vn 0.8127 -0.1471 0.5638 +vn 0.6292 0.7419 -0.2317 +vn -0.3373 -0.1432 0.9304 +vn -0.3853 0.6954 -0.6066 +vn 0.6588 0.2236 0.7183 +vn -0.9826 0.1484 0.1116 +s off +f 1/1/1 6/2/1 10/3/1 5/4/1 +f 4/5/2 9/6/2 8/7/2 3/8/2 +f 2/9/3 7/10/3 6/2/3 1/1/3 +f 5/4/4 10/3/4 9/6/4 4/5/4 +f 3/8/5 8/7/5 7/10/5 2/9/5 +f 8/7/6 9/6/6 11/11/6 +f 6/2/7 7/10/7 11/11/7 +f 9/6/8 10/3/8 11/11/8 +f 7/10/9 8/7/9 11/11/9 +f 10/3/10 6/2/10 11/11/10 +f 12/12/11 17/13/11 21/14/11 16/15/11 +f 15/16/12 20/17/12 19/18/12 14/19/12 +f 13/20/13 18/21/13 17/13/13 12/12/13 +f 16/15/14 21/14/14 20/17/14 15/16/14 +f 14/19/15 19/18/15 18/21/15 13/20/15 +f 19/18/16 20/17/16 22/22/16 +f 17/13/17 18/21/17 22/22/17 +f 20/17/18 21/14/18 22/22/18 +f 18/21/19 19/18/19 22/22/19 +f 21/14/20 17/13/20 22/22/20 +f 23/23/21 28/24/21 32/25/21 27/26/21 +f 26/27/22 31/28/22 30/29/22 25/30/22 +f 24/31/23 29/32/23 28/24/23 23/23/23 +f 27/26/24 32/25/24 31/28/24 26/27/24 +f 25/30/25 30/29/25 29/32/25 24/31/25 +f 30/29/26 31/28/26 33/33/26 +f 28/24/27 29/32/27 33/33/27 +f 31/28/28 32/25/28 33/33/28 +f 29/32/29 30/29/29 33/33/29 +f 32/25/30 28/24/30 33/33/30 +f 34/34/31 39/35/31 43/36/31 38/37/31 +f 37/38/32 42/39/32 41/40/32 36/41/32 +f 35/42/33 40/43/33 39/35/33 34/34/33 +f 38/37/34 43/36/34 42/39/34 37/38/34 +f 36/41/35 41/40/35 40/43/35 35/42/35 +f 41/40/36 42/39/36 44/44/36 +f 39/35/37 40/43/37 44/44/37 +f 42/39/38 43/36/38 44/44/38 +f 40/43/39 41/40/39 44/44/39 +f 43/36/40 39/35/40 44/44/40 +f 45/45/41 50/46/41 54/47/41 49/48/41 +f 48/49/42 53/50/42 52/51/42 47/52/42 +f 46/53/43 51/54/43 50/46/43 45/45/43 +f 49/48/44 54/47/44 53/50/44 48/49/44 +f 47/52/45 52/51/45 51/54/45 46/53/45 +f 52/51/46 53/50/46 55/55/46 +f 50/46/47 51/54/47 55/55/47 +f 53/50/48 54/47/48 55/55/48 +f 51/54/49 52/51/49 55/55/49 +f 54/47/50 50/46/50 55/55/50 diff --git a/table.lua b/table.lua new file mode 100644 index 0000000..0f6ba43 --- /dev/null +++ b/table.lua @@ -0,0 +1,300 @@ + +magicalities.arcane = {} +magicalities.arcane.recipes = {} + +local fmspecelems = { + ["earth"] = {3, 0.15}, + ["water"] = {1, 1}, + ["air"] = {5, 1}, + ["fire"] = {3, 4.85}, + ["light"] = {1, 4}, + ["dark"] = {5, 4} +} + +local function arcane_table_formspec(data) + local spec = "" + local labels = "" + + if not data then + data = {} + end + + for name, pos in pairs(fmspecelems) do + local cp = "" + local y = -0.4 + + if not data[name] then + cp = "^[colorize:#2f2f2f" + end + + if pos[2] > 2.5 then + y = 0.85 + end + + spec = spec .. "image["..pos[1]..","..pos[2]..";1,1;magicalities_symbol_"..name..".png"..cp.."]" + + if data[name] then + labels = labels .. "label["..(pos[1] + 0.3)..","..(pos[2] + y)..";"..data[name].."]" + end + end + + return "size[10,10.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[0,0;Arcane Crafting Table]".. + "image[0.98,0.3;6,6;magicalities_symbol_hexagram.png]".. + spec.. + "list[context;craft;2,1.5;3,3;]".. + "list[context;craftres;7,2.5;1,1;]".. + "list[context;wand;7,1;1,1;]".. + labels.. + "image[6,2.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "list[current_player;main;1,6.25;8,1;]".. + "list[current_player;main;1,7.5;8,3;8]".. + "listring[context;wand]".. + "listring[current_player;main]".. + "listring[context;craft]".. + "listring[current_player;main]".. + "listring[context;craftres]".. + "listring[current_player;main]".. + default.get_hotbar_bg(1, 6.25) +end + +function magicalities.arcane.register_recipe(data) + table.insert(magicalities.arcane.recipes, data) +end + +local function split_components(items) + local arrays = {} + local temp = {} + local index = 1 + + for i, k in pairs(items) do + temp[#temp + 1] = k:get_name() + index = index + 1 + if index == 4 then + -- Don't add blank rows + local blanks = 0 + for _, tmp in pairs(temp) do + if tmp == "" then + blanks = blanks + 1 + end + end + + if blanks ~= 3 then + arrays[#arrays + 1] = temp + end + + temp = {} + index = 1 + end + end + + return arrays +end + +local function compare_find(splitup) + local found = nil + + for _,recipe in pairs(magicalities.arcane.recipes) do + -- Don't even bother if it doesnt have the correct amount of rows + if #splitup == #recipe.input then + local rows = 0 + for index, row in pairs(recipe.input) do + if not splitup[index] then break end + if #splitup[index] ~= #row then break end + + local cells = 0 + for i, cell in pairs(row) do + if splitup[index][i] == cell then + cells = cells + 1 + end + end + + if cells == #row then + rows = rows + 1 + end + end + + if rows == #recipe.input then + found = recipe + break + end + end + end + + return found +end + +function magicalities.arcane.get_recipe(items) + local split = split_components(items) + local recipe = compare_find(split) + + if not recipe then return nil end + local result = {new_input = {}, output = recipe.output, requirements = recipe.requirements} + for _,stack in pairs(items) do + stack:take_item(1) + result.new_input[#result.new_input + 1] = stack + end + + return result +end + +local function allow_metadata_inventory_put (pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + + if (listname == "wand" and minetest.get_item_group(stack:get_name(), "wand") == 0) or listname == "craftres" then + return 0 + end + + return stack:get_count() +end + +local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "craftres" and to_list == "craft" then return 0 end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take (pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function set_output(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + -- Check for possible result + local result = magicalities.arcane.get_recipe(inv:get_list("craft")) + if not result then return nil end + + -- Check for wand + local wand = inv:get_stack("wand", 1) + if not wand or wand:is_empty() then + return nil, result.requirements + end + + -- Check requirements + local requirements = result.requirements + if not magicalities.wands.wand_has_contents(wand, requirements) then + return nil, result.requirements + end + + -- Output fits + local output = ItemStack(result.output) + if not inv:room_for_item("craftres", output) then + return inv:get_stack("craftres", 1), result.requirements + end + + -- Set output + return output, result.requirements +end + +local function update_craft(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local out, reqs = set_output(pos) + + if reqs then + meta:set_string("formspec", arcane_table_formspec(reqs)) + else + meta:set_string("formspec", arcane_table_formspec({})) + end + + inv:set_list("craftres", { out }) +end + +-- Arcane Crafting Table +minetest.register_node("magicalities:arcane_table", { + description = "Arcane Crafting Table", + tiles = { + "magicalities_table_arcane_top.png", "magicalities_table_arcane.png", "magicalities_table_arcane.png", + "magicalities_table_arcane.png", "magicalities_table_arcane.png", "magicalities_table_arcane.png", + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", arcane_table_formspec()) + + local inv = meta:get_inventory() + inv:set_size("craft", 9) + inv:set_size("craftres", 1) + inv:set_size("wand", 1) + end, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + allow_metadata_inventory_move = allow_metadata_inventory_move, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if listname == "craftres" then + local res = magicalities.arcane.get_recipe(inv:get_list("craft")) + if res then + inv:set_list("craft", res.new_input) + + -- Take from wand + local wand = inv:get_stack("wand", 1) + wand = magicalities.wands.wand_take_contents(wand, res.requirements) + magicalities.wands.update_wand_desc(wand) + inv:set_list("wand", {wand}) + end + end + + update_craft(pos) + end, + on_metadata_inventory_put = update_craft, + on_metadata_inventory_move = update_craft, + + groups = {choppy = 2, oddly_breakable_by_hand = 1, arcane_table = 1} +}) + +-- Base Table +minetest.register_node("magicalities:table", { + description = "Table", + drawtype = "nodebox", + tiles = { + "magicalities_table_wood_top.png", "magicalities_table_wood.png", "magicalities_table_wood.png", + "magicalities_table_wood.png", "magicalities_table_wood.png", "magicalities_table_wood.png", + }, + node_box = { + type = "fixed", + fixed = { + {-0.2500, -0.5000, -0.2500, 0.2500, -0.3750, 0.2500}, + {-0.1250, -0.3750, -0.1250, 0.1250, 0.3750, 0.1250}, + {-0.5000, 0.3750, -0.5000, 0.5000, 0.5000, 0.5000} + } + }, + 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_crystal.png b/textures/magicalities_crystal.png new file mode 100644 index 0000000..4b26904 Binary files /dev/null and b/textures/magicalities_crystal.png differ diff --git a/textures/magicalities_crystal_shard.png b/textures/magicalities_crystal_shard.png new file mode 100644 index 0000000..bbba3dc Binary files /dev/null and b/textures/magicalities_crystal_shard.png differ diff --git a/textures/magicalities_gui_arrow.png b/textures/magicalities_gui_arrow.png new file mode 100644 index 0000000..d7dbb28 Binary files /dev/null and b/textures/magicalities_gui_arrow.png differ diff --git a/textures/magicalities_spark.png b/textures/magicalities_spark.png new file mode 100644 index 0000000..4b6435b Binary files /dev/null and b/textures/magicalities_spark.png differ diff --git a/textures/magicalities_symbol_air.png b/textures/magicalities_symbol_air.png new file mode 100644 index 0000000..6790fc4 Binary files /dev/null and b/textures/magicalities_symbol_air.png differ diff --git a/textures/magicalities_symbol_dark.png b/textures/magicalities_symbol_dark.png new file mode 100644 index 0000000..27c458e Binary files /dev/null and b/textures/magicalities_symbol_dark.png differ diff --git a/textures/magicalities_symbol_earth.png b/textures/magicalities_symbol_earth.png new file mode 100644 index 0000000..4ebae9c Binary files /dev/null and b/textures/magicalities_symbol_earth.png differ diff --git a/textures/magicalities_symbol_fire.png b/textures/magicalities_symbol_fire.png new file mode 100644 index 0000000..0356196 Binary files /dev/null and b/textures/magicalities_symbol_fire.png differ diff --git a/textures/magicalities_symbol_hexagram.png b/textures/magicalities_symbol_hexagram.png new file mode 100644 index 0000000..6b6bc65 Binary files /dev/null and b/textures/magicalities_symbol_hexagram.png differ diff --git a/textures/magicalities_symbol_light.png b/textures/magicalities_symbol_light.png new file mode 100644 index 0000000..2087faf Binary files /dev/null and b/textures/magicalities_symbol_light.png differ diff --git a/textures/magicalities_symbol_water.png b/textures/magicalities_symbol_water.png new file mode 100644 index 0000000..f43e090 Binary files /dev/null and b/textures/magicalities_symbol_water.png differ diff --git a/textures/magicalities_table_arcane.png b/textures/magicalities_table_arcane.png new file mode 100644 index 0000000..5e3fb18 Binary files /dev/null and b/textures/magicalities_table_arcane.png differ diff --git a/textures/magicalities_table_arcane_top.png b/textures/magicalities_table_arcane_top.png new file mode 100644 index 0000000..9d9b224 Binary files /dev/null and b/textures/magicalities_table_arcane_top.png differ diff --git a/textures/magicalities_table_wood.png b/textures/magicalities_table_wood.png new file mode 100644 index 0000000..d36a5aa Binary files /dev/null and b/textures/magicalities_table_wood.png differ diff --git a/textures/magicalities_table_wood_top.png b/textures/magicalities_table_wood_top.png new file mode 100644 index 0000000..4b5f4ab Binary files /dev/null and b/textures/magicalities_table_wood_top.png differ diff --git a/textures/magicalities_wand_gold.png b/textures/magicalities_wand_gold.png new file mode 100644 index 0000000..520f565 Binary files /dev/null and b/textures/magicalities_wand_gold.png differ diff --git a/textures/magicalities_wand_iron.png b/textures/magicalities_wand_iron.png new file mode 100644 index 0000000..a7b2fa9 Binary files /dev/null and b/textures/magicalities_wand_iron.png differ diff --git a/wands.lua b/wands.lua new file mode 100644 index 0000000..bc3fd04 --- /dev/null +++ b/wands.lua @@ -0,0 +1,223 @@ +-- Magicalities Wands + +magicalities.wands = {} + +local transform_recipes = { + ["mg_table"] = {result = "magicalities:arcane_table", requires = {["earth"] = 5, ["light"] = 5}} +} + +local wandcaps = { + full_punch_interval = 1.0, + max_drop_level = 0, + groupcaps = {}, + damage_groups = {fleshy = 2}, +} + +local randparticles = PcgRandom(os.clock()) + +local function align(len) + local str = "" + for i = 1, len do + str = str.."\t" + end + return str +end + +-- Update wand's description +function magicalities.wands.update_wand_desc(stack) + local meta = stack:get_meta() + local data_table = minetest.deserialize(meta:get_string("contents")) + + local wanddata = minetest.registered_items[stack:get_name()] + local description = wanddata.description + local capcontents = wanddata["_cap_max"] or 15 + local strbld = description.."\n" + + local longest_desc = 0 + for _,data in pairs(magicalities.elements) do + if not data.inheritance then + local len = #data.description + if len > longest_desc then + longest_desc = len + end + end + end + + 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 + end + end + + meta:set_string("description", strbld) +end + +-- Ensure wand has contents +function magicalities.wands.wand_has_contents(stack, requirements) + local meta = stack:get_meta() + local data_table = minetest.deserialize(meta:get_string("contents")) + + if not data_table then return false end + + for name, count in pairs(requirements) do + if not data_table[name] or data_table[name] < count then + return false + end + end + + return true +end + +-- Take wand contents +function magicalities.wands.wand_take_contents(stack, to_take) + local meta = stack:get_meta() + local data_table = minetest.deserialize(meta:get_string("contents")) + + for name, count in pairs(to_take) do + if not data_table[name] or data_table[name] - count < 0 then + return nil + end + + data_table[name] = data_table[name] - count + end + + local data_res = minetest.serialize(data_table) + meta:set_string("contents", data_res) + + return stack +end + +-- Initialize wand metadata +local function initialize_wand(stack) + local data_table = {} + + for name, data in pairs(magicalities.elements) do + if not data.inheritance then + data_table[name] = 10 + end + end + + local meta = stack:get_meta() + meta:set_string("contents", minetest.serialize(data_table)) +end + +local function wand_action(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" then return itemstack end + local node = minetest.get_node(pointed_thing.under) + local imeta = itemstack:get_meta() + + -- Initialize wand metadata + if imeta:get_string("contents") == nil or imeta:get_string("contents") == "" then + initialize_wand(itemstack) + magicalities.wands.update_wand_desc(itemstack) + end + + local to_replace = nil + for grp, result in pairs(transform_recipes) do + if minetest.get_item_group(node.name, grp) > 0 then + to_replace = result + break + 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) + magicalities.wands.update_wand_desc(itemstack) + end + + minetest.swap_node(pointed_thing.under, {name = to_replace.result, param1 = node.param1, param2 = node.param2}) + + local spec = minetest.registered_nodes[to_replace.result] + if spec.on_construct then + spec.on_construct(pointed_thing.under) + end + + return itemstack +end + +local function use_wand(itemstack, user, pointed_thing) + local imeta = itemstack:get_meta() + + -- Initialize wand metadata + if imeta:get_string("contents") == nil or imeta:get_string("contents") == "" then + initialize_wand(itemstack) + magicalities.wands.update_wand_desc(itemstack) + end + + if not magicalities.wands.wand_has_contents(itemstack, {water = 5}) then + return itemstack + end + + --itemstack = magicalities.wands.wand_take_contents(itemstack, {water = 5}) + + -- Calculate velocity + local dir = user:get_look_dir() + local vel = {x=0,y=0,z=0} + vel.x = dir.x * 16 + vel.y = dir.y * 16 + vel.z = dir.z * 16 + + -- Calculate position + local pos = user:get_pos() + pos.x = pos.x + (dir.x * 2) + pos.y = pos.y + (dir.y * 2) + 1.5 + pos.z = pos.z + (dir.z * 2) + + for i = 1, 8 do + -- Deviation + local relvel = {x=0,y=0,z=0} + relvel.x = vel.x + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000) + relvel.y = vel.y + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000) + relvel.z = vel.z + (randparticles:next((-i/2.5) * 1000, (i/2.5) * 1000) / 1000) + minetest.add_particle({ + pos = pos, + velocity = relvel, + acceleration = relvel, + expirationtime = 1, + size = 4, + collisiondetection = true, + collision_removal = true, + texture = "magicalities_spark.png", + -- animation = {Tile Animation definition}, + glow = 2 + }) + end + + magicalities.wands.update_wand_desc(itemstack) + return itemstack +end + +function magicalities.wands.register_wand(name, data) + local mod = minetest.get_current_modname() + minetest.register_tool(mod..":wand_"..name, { + description = data.description, + inventory_image = data.image, + tool_capabilities = wandcaps, + stack_max = 1, + _cap_max = data.wand_cap, + on_use = use_wand, + on_place = wand_action, + 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, +}) +