2018-04-17 09:39:28 +00:00
|
|
|
-- Magicalities Wands
|
|
|
|
|
|
|
|
magicalities.wands = {}
|
|
|
|
|
|
|
|
local transform_recipes = {
|
2018-04-17 14:17:56 +00:00
|
|
|
["mg_table"] = {result = "magicalities:arcane_table", requirements = nil}
|
2018-04-17 09:39:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
local elems = {}
|
2018-04-17 09:39:28 +00:00
|
|
|
for elem, amount in pairs(data_table) do
|
|
|
|
local dataelem = magicalities.elements[elem]
|
|
|
|
if amount > 0 then
|
2018-04-17 14:17:56 +00:00
|
|
|
elems[#elems + 1] = minetest.colorize(dataelem.color, dataelem.description.." ")..
|
|
|
|
align(longest_desc * 2 - #dataelem.description)..
|
|
|
|
amount.."/"..capcontents
|
2018-04-17 09:39:28 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
table.sort(elems)
|
|
|
|
strbld = strbld .. table.concat(elems, "\n")
|
|
|
|
|
2018-04-17 09:39:28 +00:00
|
|
|
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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
-- 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
|
|
|
|
|
2018-04-17 09:39:28 +00:00
|
|
|
-- Initialize wand metadata
|
|
|
|
local function initialize_wand(stack)
|
|
|
|
local data_table = {}
|
|
|
|
|
|
|
|
for name, data in pairs(magicalities.elements) do
|
|
|
|
if not data.inheritance then
|
2018-04-18 09:05:29 +00:00
|
|
|
data_table[name] = 0
|
2018-04-17 09:39:28 +00:00
|
|
|
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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
-- Replacement
|
2018-04-17 09:39:28 +00:00
|
|
|
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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
-- 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)
|
2018-04-17 09:39:28 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
-- 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)
|
|
|
|
|
2018-04-18 09:05:29 +00:00
|
|
|
for i = 1, 16 do
|
2018-04-17 09:39:28 +00:00
|
|
|
-- 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
|