From 21f97b52f9bbd44a0a8f8b11d755dbbc648ee3bb Mon Sep 17 00:00:00 2001 From: Evert Date: Thu, 19 Apr 2018 17:46:36 +0300 Subject: [PATCH] wand focus of teleportation, particles --- crystals.lua | 25 +++- focuses.lua | 41 ++++++ init.lua | 3 + scanner.lua | 16 ++- textures/magicalities_focus_teleport.png | Bin 0 -> 604 bytes textures/magicalities_spark.png | Bin 233 -> 241 bytes wands.lua | 167 ++++++++++++++++++++++- 7 files changed, 242 insertions(+), 10 deletions(-) create mode 100644 focuses.lua create mode 100644 textures/magicalities_focus_teleport.png diff --git a/crystals.lua b/crystals.lua index 2c33aa6..b40347e 100644 --- a/crystals.lua +++ b/crystals.lua @@ -72,7 +72,6 @@ function magicalities.crystals.generate_crystal_buffer(pos) end local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing) - local output = magicalities.crystals.generate_crystal_buffer(pos) local meta = minetest.get_meta(pos) -- Add contents to the crystal @@ -101,6 +100,30 @@ local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing) end end + -- Take - Particles + local cpls = clicker:get_pos() + cpls.y = cpls.y + 1 + for name in pairs(can_put) do + local ecolor = magicalities.elements[name].color + local dist = vector.distance(cpls, pos) + local normal = vector.normalize(vector.subtract(cpls, pos)) + local spawn = vector.add(normal, pos) + local vel = vector.multiply(normal, 4) + local extime = dist / 4 + + minetest.add_particle({ + pos = spawn, + velocity = vel, + acceleration = vel, + expirationtime = extime, + size = 4, + collisiondetection = true, + collision_removal = true, + texture = "magicalities_spark.png^[multiply:"..ecolor.."", + glow = 2 + }) + end + itemstack = magicalities.wands.wand_insert_contents(itemstack, can_put) magicalities.wands.update_wand_desc(itemstack) meta:set_string("contents", minetest.serialize(contents)) diff --git a/focuses.lua b/focuses.lua new file mode 100644 index 0000000..ad9dac0 --- /dev/null +++ b/focuses.lua @@ -0,0 +1,41 @@ +-- Wand Focuses + +minetest.register_craftitem("magicalities:focus_teleport", { + description = "Wand Focus of Teleportation", + groups = {wand_focus = 1}, + inventory_image = "magicalities_focus_teleport.png", + stack_max = 1, + _wand_requirements = { + ["air"] = 1 + }, + _wand_use = function (itemstack, user, pointed_thing) + local dir = user:get_look_dir() + local dest = vector.multiply(dir, 20) + dest = vector.add(dest, user:get_pos()) + + 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) + + local ray = Raycast(pos, dest, true, false) + local targ = ray:next() + local can_go = targ == nil + + if targ and targ.type == "node" then + local abv = minetest.get_node(targ.above) + if not abv or abv.name == "air" then + dest = targ.above + can_go = true + end + end + + if can_go then + itemstack = magicalities.wands.wand_take_contents(itemstack, {air = 1}) + magicalities.wands.update_wand_desc(itemstack) + user:set_pos(dest) + end + + return itemstack + end +}) diff --git a/init.lua b/init.lua index 013dd6f..413d5f0 100644 --- a/init.lua +++ b/init.lua @@ -22,6 +22,9 @@ dofile(modpath.."/crystals.lua") -- Wands dofile(modpath.."/wands.lua") +-- Wand focuses +dofile(modpath.."/focuses.lua") + -- Tables dofile(modpath.."/table.lua") diff --git a/scanner.lua b/scanner.lua index 2c90b9f..7e2ac21 100644 --- a/scanner.lua +++ b/scanner.lua @@ -1,12 +1,12 @@ -- Scans crystals for their contents local fmspecelems = { - ["earth"] = {2, 0.15}, - ["water"] = {0, 1}, - ["air"] = {4, 1}, - ["fire"] = {2, 4.85}, - ["light"] = {0, 4}, - ["dark"] = {4, 4} + ["earth"] = {2, 0.3}, + ["water"] = {0, 1.25}, + ["air"] = {4, 1.25}, + ["fire"] = {2, 5.1}, + ["light"] = {0, 4.25}, + ["dark"] = {4, 4.25} } local function create_formspec(elements, desc) @@ -42,7 +42,7 @@ local function create_formspec(elements, desc) default.gui_bg.. default.gui_bg_img.. "label[0,0;"..desc.."]".. - "image[0,0.3;6,6;magicalities_symbol_hexagram.png]".. + "image[0,0.55;6,6;magicalities_symbol_hexagram.png]".. spec.. labels end @@ -60,6 +60,7 @@ local function show_spec(i, placer, pointed_thing) local contents = minetest.deserialize(meta:get_string("contents")) if not contents then contents = magicalities.crystals.generate_crystal_buffer(pos) + meta:set_string("contents", minetest.serialize(contents)) end minetest.show_formspec(placer:get_player_name(), "magicalities:crystal_scanner", create_formspec(contents, nodedef.description)) @@ -70,5 +71,6 @@ minetest.register_craftitem("magicalities:element_ring", { description = "Elemental Ring\nShows contents of crystals", inventory_image = "magicalities_element_ring.png", on_place = show_spec, + stack_max = 1, }) diff --git a/textures/magicalities_focus_teleport.png b/textures/magicalities_focus_teleport.png new file mode 100644 index 0000000000000000000000000000000000000000..bbea96dd44f34dd55e726c32ed0e9a98d190c300 GIT binary patch literal 604 zcmV-i0;BzjP)WFU8GbZ8()Nlj2>E@cM*00F>BL_t(I%e9l=YEwZF z#(%TB=cKKFY7;G?S}Ay;7oq4A1QC2FF%YPTFC`M6K!Ow$1f^D^A*qeYNqVxo<3&!B z6k8O;x!mFVF*Dz{@Q)=IH6Go6uHNTp3<#FiepCJm@c6+C4GM$Npy*lv)|>^C(t7(u zE(AQ>eWt_lXz9gKE$?6@rPKca!0JlMtM&pS%i{4QBLFCDT)tHxEaD8t7!pbO(tl5B zr9`X!Q~=B=Ai`W+E#Dz=3C>vhqb|MU4#7vJnzL2Di$Tw>P_ON2mXEPmD(kl~CIN)r z(Z}KjN(3NKS-(kQ6OOV2TJ46oQ?;YUTEblNJf2Y-Mo^?TEz)Ap=?#~01DIsJ; zoy^3dAdrZ~nDqQ0)oTqs$pb+PKj-b4czg36$HPNjzBwmI%d21l*~EiN0fM#F65!?m q`r~J+?>3YOItu`=_xFVVQNIBG2gVfyaC?0K0000pmfmZ1nk90LOvV`n=90|RG)M`SSr1Gg{;GcwGYBLNg-FY)wsWq-sX%%>%) z5#t>=Fvf&^=`%p9xISN1n&>BsH)@&E4b^8fO7H67Ol)N-1*#dLn? zD=HpT(9k$>;MlQa8**+MU5YLG^W)=xkmCC1=VU+a-B|hg+5g3wjeHCY7k()PtlC>S Q5ojrcr>mdKI;Vst0A>|G<^TWy delta 158 zcmey!_>ysgmSH?YCPV&B?tEqj1_sUokH}&M25w;xW@MN(M*=9wUgGKN%KnIjmq&@| zg2;xLiP1VqzMd|QAr_~T6C_xhWmo9`_TQIwxA(uKRQ=!d4Lh5z3#hGG6vX;pGDJs0 zVp4>JL<@_AM9QfX1)a~D{_`~I|1*w|S$;s;EBC*w%Urc)I$z JtaD0e0s!q4Gt&S7 diff --git a/wands.lua b/wands.lua index 880f63c..f134a36 100644 --- a/wands.lua +++ b/wands.lua @@ -23,6 +23,52 @@ local function align(len) return str end +function magicalities.wands.get_wand_focus(stack) + local meta = stack:get_meta() + if meta:get_string("focus") == "" then + return nil + end + + local focus = meta:get_string("focus") + local itemdef = minetest.registered_items[focus] + if not itemdef then return nil end + + return focus, itemdef +end + +local function focus_requirements(stack, fdef) + if fdef["_wand_requirements"] then + return magicalities.wands.wand_has_contents(stack, fdef["_wand_requirements"]) + end + + return true +end + +local function focuses_formspec(available, focusname) + local x = 0 + local fsp = "" + for focus in pairs(available) do + fsp = fsp .. "item_image_button["..x..",2.8;1,1;"..focus..";"..focus..";]" + x = x + 1 + end + + local current = "" + if not focusname then + current = "label[2,1;No Focus]" + else + current = "item_image_button[2,0.5;1,1;"..focusname..";remove;Remove]".. + "label[0,1.5;Current: "..minetest.registered_items[focusname].description.."]" + end + + return "size[5,3.5]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;Wand Focuses]".. + current.. + "label[0,2.4;Available]".. + fsp +end + -- Update wand's description function magicalities.wands.update_wand_desc(stack) local meta = stack:get_meta() @@ -53,8 +99,17 @@ function magicalities.wands.update_wand_desc(stack) end end - table.sort(elems) - strbld = strbld .. table.concat(elems, "\n") + local focus, def = magicalities.wands.get_wand_focus(stack) + local focusstr = "No Wand Focus" + if focus then + focusstr = def.description + end + + strbld = strbld .. focusstr + if #elems > 0 then + table.sort(elems) + strbld = strbld .. "\n" .. table.concat(elems, "\n") + end meta:set_string("description", strbld) end @@ -170,6 +225,16 @@ local function wand_action(itemstack, placer, pointed_thing) end end + -- Call rightclick on the wand focus + local focus, fdef = magicalities.wands.get_wand_focus(itemstack) + if focus then + if fdef["_wand_node"] and focus_requirements(itemstack, fdef) then + itemstack = fdef["_wand_node"](pointed_thing.under, node, placer, itemstack, pointed_thing) + + return itemstack + end + end + -- Call on_rightclick on the node instead if it cannot be replaced if not to_replace then local nodedef = minetest.registered_nodes[node.name] @@ -206,6 +271,16 @@ local function use_wand(itemstack, user, pointed_thing) magicalities.wands.update_wand_desc(itemstack) end + -- Call use on the wand focus + local focus, fdef = magicalities.wands.get_wand_focus(itemstack) + if focus then + if fdef["_wand_use"] and focus_requirements(itemstack, fdef) then + itemstack = fdef["_wand_use"](itemstack, user, pointed_thing) + + return itemstack + end + end + -- Calculate velocity local dir = user:get_look_dir() local vel = {x=0,y=0,z=0} @@ -243,6 +318,93 @@ local function use_wand(itemstack, user, pointed_thing) return itemstack end +local function wand_focuses(itemstack, user, pointed_thing) + local focuses_found = {} + local inv = user:get_inventory() + local list = inv:get_list("main") + + local focusname, focusdef = magicalities.wands.get_wand_focus(itemstack) + local meta = itemstack:get_meta() + + for _, stack in pairs(list) do + if minetest.get_item_group(stack:get_name(), "wand_focus") > 0 then + focuses_found[stack:get_name()] = true + end + end + + minetest.show_formspec(user:get_player_name(), "magicalities:wand_focuses", focuses_formspec(focuses_found, focusname)) + minetest.register_on_player_receive_fields(function (player, formname, fields) + if formname ~= "magicalities:wand_focuses" then + return false + end + + -- Make sure field is a valid item + local f = "" + if not fields["quit"] then + if fields["remove"] then + f = nil + else + for v in pairs(fields) do + if minetest.registered_items[v] then + f = v + break + end + end + end + else + return true + end + + local was + + was = meta:get_string("focus") + if was == "" and not f then + return true + elseif was ~= "" then + was = ItemStack(was) + if not inv:room_for_item("main", was) then + return true + end + end + + minetest.close_formspec(player:get_player_name(), "magicalities:wand_focuses") + + local removed_focus = false + local set = false + + -- Update itemstack + for i, stack in pairs(list) do + if set and (removed_focus or not f) then break end + if not removed_focus and stack:get_name() == f then + inv:set_stack("main", i, ItemStack(nil)) + removed_focus = true -- Make sure to only remove one + end + + if stack:get_name() == itemstack:get_name() and stack:get_meta() == itemstack:get_meta() and not set then + if not f then + meta:set_string("focus", "") + magicalities.wands.update_wand_desc(itemstack) + elseif f ~= "" then + meta:set_string("focus", f) + magicalities.wands.update_wand_desc(itemstack) + end + + inv:set_stack("main", i, itemstack) + set = true + end + end + + -- Give the removed focus back + if was then + inv:add_item("main", was) + end + + return true + end) + + return itemstack +end + function magicalities.wands.register_wand(name, data) local mod = minetest.get_current_modname() minetest.register_tool(mod..":wand_"..name, { @@ -253,6 +415,7 @@ function magicalities.wands.register_wand(name, data) _cap_max = data.wand_cap, on_use = use_wand, on_place = wand_action, + on_secondary_use = wand_focuses, groups = {wand = 1} }) end