2018-04-17 09:39:28 +00:00
|
|
|
-- Magicalities crystals
|
|
|
|
|
2018-04-18 09:05:29 +00:00
|
|
|
magicalities.crystals = {}
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
local randbuff = PcgRandom(os.clock())
|
|
|
|
|
2018-04-18 09:05:29 +00:00
|
|
|
local function compare(a,b)
|
|
|
|
return a[2] > b[2]
|
|
|
|
end
|
|
|
|
|
|
|
|
local function crystal_infotext(pos, data)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local nodedef = minetest.registered_nodes[node.name]
|
|
|
|
if not data then
|
|
|
|
data = minetest.deserialize(meta:get_string("contents"))
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Sort
|
|
|
|
local sortable = {}
|
|
|
|
for name, v in pairs(data) do
|
|
|
|
sortable[#sortable + 1] = {name, v[1]}
|
|
|
|
end
|
|
|
|
table.sort(sortable, compare)
|
|
|
|
|
|
|
|
-- Create string
|
|
|
|
local str = nodedef.description.. "\n\n"
|
|
|
|
local datastrs = {}
|
|
|
|
for _, v in pairs(sortable) do
|
|
|
|
local elemdesc = magicalities.elements[v[1]].description
|
|
|
|
datastrs[#datastrs + 1] = v[2].."x "..elemdesc
|
|
|
|
end
|
|
|
|
str = str .. table.concat( datastrs, "\n")
|
|
|
|
|
|
|
|
meta:set_string("infotext", str)
|
|
|
|
end
|
|
|
|
|
|
|
|
function magicalities.crystals.generate_crystal_buffer(pos)
|
2018-04-17 14:17:56 +00:00
|
|
|
local final = {}
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local nodedef = minetest.registered_nodes[node.name]
|
|
|
|
local self_cnt = randbuff:next(10, 60)
|
2018-04-18 09:05:29 +00:00
|
|
|
local added = 0
|
2018-04-17 14:17:56 +00:00
|
|
|
|
|
|
|
for name, data in pairs(magicalities.elements) do
|
2018-04-18 09:05:29 +00:00
|
|
|
if added > 5 then break end
|
2018-04-17 14:17:56 +00:00
|
|
|
if not data.inheritance then
|
|
|
|
if name == nodedef["_element"] then
|
|
|
|
final[name] = {self_cnt, self_cnt}
|
2018-04-18 09:05:29 +00:00
|
|
|
added = added + 1
|
2018-04-17 14:17:56 +00:00
|
|
|
else
|
|
|
|
if randbuff:next(0, 5) == 0 then
|
|
|
|
local cnt = randbuff:next(0, math.floor(self_cnt / 4))
|
2018-04-18 09:05:29 +00:00
|
|
|
if cnt > 0 then
|
|
|
|
final[name] = {cnt, cnt}
|
|
|
|
added = added + 1
|
|
|
|
end
|
2018-04-17 14:17:56 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if randbuff:next(0, 15) == 0 then
|
|
|
|
local cnt = randbuff:next(0, math.floor(self_cnt / 8))
|
2018-04-18 09:05:29 +00:00
|
|
|
if cnt > 0 then
|
|
|
|
final[name] = {cnt, cnt}
|
|
|
|
added = added + 1
|
|
|
|
end
|
2018-04-17 14:17:56 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return final
|
|
|
|
end
|
|
|
|
|
|
|
|
local function crystal_rightclick(pos, node, clicker, itemstack, pointed_thing)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
|
|
|
|
-- Add contents to the crystal
|
|
|
|
local contents = minetest.deserialize(meta:get_string("contents"))
|
|
|
|
if not contents then
|
2018-04-18 09:05:29 +00:00
|
|
|
contents = magicalities.crystals.generate_crystal_buffer(pos)
|
2018-04-17 14:17:56 +00:00
|
|
|
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
|
|
|
|
|
2018-04-19 14:46:36 +00:00
|
|
|
-- 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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
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
|
|
|
|
|
2018-04-17 09:39:28 +00:00
|
|
|
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",
|
2018-09-30 16:14:40 +00:00
|
|
|
paramtype2 = "wallmounted",
|
2018-04-17 09:39:28 +00:00
|
|
|
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(),
|
2018-04-17 14:17:56 +00:00
|
|
|
|
|
|
|
on_rightclick = crystal_rightclick,
|
2019-08-20 18:54:48 +00:00
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local imeta = itemstack:get_meta()
|
|
|
|
meta:set_string("contents", imeta:get_string("contents"))
|
|
|
|
end
|
2018-04-17 09:39:28 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
-- 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(),
|
|
|
|
})
|
|
|
|
|
2018-09-30 16:14:40 +00:00
|
|
|
-- Register cave crystal appearances
|
|
|
|
minetest.register_decoration({
|
|
|
|
deco_type = "simple",
|
|
|
|
place_on = "default:stone",
|
|
|
|
sidelen = 16,
|
|
|
|
y_max = -30,
|
|
|
|
y_min = -31000,
|
2018-10-02 09:31:42 +00:00
|
|
|
flags = "all_ceilings",
|
|
|
|
fill_ratio = 0.0004,
|
|
|
|
decoration = "magicalities:crystal_cluster_"..element,
|
|
|
|
})
|
2018-09-30 16:14:40 +00:00
|
|
|
|
2018-10-02 09:31:42 +00:00
|
|
|
minetest.register_decoration({
|
|
|
|
deco_type = "simple",
|
|
|
|
place_on = "default:stone",
|
|
|
|
sidelen = 16,
|
|
|
|
y_max = -30,
|
|
|
|
y_min = -31000,
|
|
|
|
flags = "all_floors",
|
|
|
|
fill_ratio = 0.0004,
|
2018-09-30 16:14:40 +00:00
|
|
|
decoration = "magicalities:crystal_cluster_"..element,
|
2018-04-17 09:39:28 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2018-04-17 14:17:56 +00:00
|
|
|
-- Register refill ABMs
|
|
|
|
minetest.register_abm({
|
|
|
|
label = "Crystal Elements Refill",
|
|
|
|
nodenames = {"group:crystal_cluster"},
|
2019-08-20 18:54:48 +00:00
|
|
|
interval = 30.0,
|
|
|
|
chance = 2,
|
2018-04-17 14:17:56 +00:00
|
|
|
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
|
2018-04-17 09:39:28 +00:00
|
|
|
end
|
2018-04-17 14:17:56 +00:00
|
|
|
})
|
2018-09-30 16:14:40 +00:00
|
|
|
|
|
|
|
minetest.register_on_generated(function (minp, maxp)
|
|
|
|
local clusters = minetest.find_nodes_in_area(minp, maxp, "group:crystal_cluster")
|
|
|
|
for _, pos in pairs(clusters) do
|
|
|
|
local stone = minetest.find_node_near(pos, 1, "default:stone")
|
|
|
|
if stone then
|
|
|
|
local param2 = minetest.dir_to_wallmounted(vector.direction(pos, stone))
|
|
|
|
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
node.param2 = param2
|
|
|
|
minetest.set_node(pos, node)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|