181 lines
5.0 KiB
Lua
181 lines
5.0 KiB
Lua
mcl_conduits = {}
|
|
local modname = minetest.get_current_modname()
|
|
local S = minetest.get_translator(modname)
|
|
|
|
local check_interval = 5
|
|
local conduit_nodes = { "mcl_ocean:prismarine", "mcl_ocean:prismarine_brick", "mcl_ocean:prismarine_dark", "mcl_ocean:sea_lantern" }
|
|
|
|
local frame_offsets = {
|
|
vector.new(1, 2, 0),
|
|
vector.new(2, 2, 0),
|
|
vector.new(-1, 2, 0),
|
|
vector.new(-2, 2, 0),
|
|
vector.new(0, 2, 0),
|
|
vector.new(0, 2, 1),
|
|
vector.new(0, 2, 2),
|
|
vector.new(0, 2, -1),
|
|
vector.new(0, 2, -2),
|
|
|
|
vector.new(2, 1, 0),
|
|
vector.new(-2, 1, 0),
|
|
vector.new(0, 1, 2),
|
|
vector.new(0, 1, -2),
|
|
|
|
vector.new(2, 0, 0),
|
|
vector.new(2, 0, 1),
|
|
vector.new(2, 0, 2),
|
|
|
|
vector.new(-2, 0, 0),
|
|
vector.new(-2, 0, 1),
|
|
vector.new(-2, 0, 2),
|
|
|
|
vector.new(2, 0, -1),
|
|
vector.new(2, 0, -2),
|
|
vector.new(-2, 0, -1),
|
|
vector.new(-2, 0, -2),
|
|
|
|
vector.new(0, 0, 2),
|
|
vector.new(1, 0, 2),
|
|
|
|
vector.new(0, 0, -2),
|
|
vector.new(1, 0, -2),
|
|
|
|
vector.new(-1, 0, 2),
|
|
vector.new(-1, 0, -2),
|
|
|
|
vector.new(2, -1, 0),
|
|
vector.new(-2, -1, 0),
|
|
vector.new(0, -1, 2),
|
|
vector.new(0, -1, -2),
|
|
|
|
vector.new(1, -2, 0),
|
|
vector.new(2, -2, 0),
|
|
vector.new(-1, -2, 0),
|
|
vector.new(-2, -2, 0),
|
|
vector.new(0, -2, 0),
|
|
vector.new(0, -2, 1),
|
|
vector.new(0, -2, 2),
|
|
vector.new(0, -2, -1),
|
|
vector.new(0, -2, -2),
|
|
}
|
|
|
|
local entity_pos_offset = vector.new(0, -1.25, 0)
|
|
|
|
local function check_conduit(pos)
|
|
local water = minetest.find_nodes_in_area(vector.offset(pos, -1,-1,-1), vector.offset(pos, 1, 1, 1), {"group:water"})
|
|
local cname = minetest.get_node(pos).name
|
|
if #water < 26 or ( cname ~= "mcl_conduits:conduit" and #water < 27 ) then return false end
|
|
local pn = 0
|
|
for _, v in pairs(frame_offsets) do
|
|
if table.indexof(conduit_nodes, minetest.get_node(vector.add(pos, v)).name) ~= -1 then
|
|
pn = pn + 1
|
|
end
|
|
end
|
|
if pn < 16 then return false end
|
|
return math.floor(pn / 7) * 16
|
|
end
|
|
|
|
function mcl_conduits.player_effect(player)
|
|
if minetest.get_item_group(mcl_player.players[player].nodes.feet, "water") == 0 then return end
|
|
mcl_potions.give_effect_by_level ("conduit_power", player, 1, 17)
|
|
end
|
|
|
|
function mcl_conduits.conduit_damage(ent)
|
|
if minetest.get_item_group(minetest.get_node(ent.object:get_pos()).name, "water") == 0 then return end
|
|
mcl_util.deal_damage(ent.object, 4, {type = "magic"})
|
|
end
|
|
|
|
minetest.register_entity("mcl_conduits:conduit", {
|
|
initial_properties = {
|
|
physical = true,
|
|
visual = "mesh",
|
|
visual_size = {x = 4, y = 4},
|
|
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
mesh = "mcl_end_crystal.b3d",
|
|
textures = {"mcl_conduit_conduit.png"},
|
|
collide_with_objects = false,
|
|
},
|
|
on_activate = function(self, staticdata)
|
|
local d = minetest.deserialize(staticdata)
|
|
if d then
|
|
self._pos = d._pos
|
|
end
|
|
self.object:set_armor_groups({immortal = 1})
|
|
self.object:set_animation({x = 0, y = 120}, 3)
|
|
end,
|
|
get_staticdata = function(self)
|
|
return minetest.serialize({ _pos = self._pos })
|
|
end,
|
|
on_step = function(self, dtime)
|
|
self._timer = (self._timer or check_interval) - dtime
|
|
if self._timer > 0 then return end
|
|
self._timer = check_interval
|
|
if not self._pos then
|
|
self.object:remove()
|
|
return
|
|
end
|
|
local lvl = check_conduit(self._pos)
|
|
if not lvl then
|
|
minetest.set_node(self._pos, {name = "mcl_conduits:conduit"})
|
|
self.object:remove()
|
|
return
|
|
end
|
|
|
|
for pl in mcl_util.connected_players(self._pos, lvl * 2) do
|
|
mcl_conduits.player_effect(pl)
|
|
end
|
|
|
|
for _, ent in pairs(minetest.luaentities) do
|
|
if ent.is_mob and ent.type == "monster" and ent.object and ent.object:get_pos() and vector.distance(self._pos, ent.object:get_pos()) < 9 then
|
|
mcl_conduits.conduit_damage(ent)
|
|
end
|
|
end
|
|
end
|
|
})
|
|
local conduit_box = { -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, }
|
|
minetest.register_node("mcl_conduits:conduit", {
|
|
description = S("Conduit"),
|
|
_doc_longdesc = S("A conduit provides certain status effects to nearby players much like a beacon but under water"),
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = conduit_box,
|
|
},
|
|
collisionbox = conduit_box,
|
|
selectionbox = conduit_box,
|
|
groups = { pickaxey = 1, deco_block = 1},
|
|
light_source = minetest.LIGHT_MAX,
|
|
tiles = { "mcl_conduit_conduit_node.png", },
|
|
_mcl_hardness = 3,
|
|
_mcl_blast_resistance = 3,
|
|
})
|
|
|
|
minetest.register_abm({
|
|
label = "Conduit Activation",
|
|
nodenames = { "mcl_conduits:conduit" },
|
|
interval = check_interval,
|
|
chance = 1,
|
|
action = function(pos, _)
|
|
for v in minetest.objects_inside_radius(vector.subtract(pos, entity_pos_offset), 0.5) do
|
|
if v.name == "mcl_conduits:conduit" then return end
|
|
end
|
|
if check_conduit(pos) then
|
|
minetest.remove_node(pos)
|
|
local o = minetest.add_entity(vector.add(pos, entity_pos_offset) , "mcl_conduits:conduit")
|
|
if o then
|
|
local l = o:get_luaentity()
|
|
l._pos = pos
|
|
end
|
|
end
|
|
end
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "mcl_conduits:conduit",
|
|
recipe = {
|
|
{"mcl_mobitems:nautilus_shell", "mcl_mobitems:nautilus_shell", "mcl_mobitems:nautilus_shell"},
|
|
{"mcl_mobitems:nautilus_shell", "mcl_mobitems:heart_of_the_sea", "mcl_mobitems:nautilus_shell"},
|
|
{"mcl_mobitems:nautilus_shell", "mcl_mobitems:nautilus_shell", "mcl_mobitems:nautilus_shell"},
|
|
},
|
|
})
|