121 lines
4.1 KiB
Lua
121 lines
4.1 KiB
Lua
local ns = artifact
|
|
|
|
minetest.register_entity(":artifact:burst", {
|
|
initial_properties = {
|
|
visual = "sprite",
|
|
textures = {"blank.png"},
|
|
pointable = false,
|
|
physical = true,
|
|
collide_with_objects = false,
|
|
collisionbox = {
|
|
-0.2, -0.2, -0.2,
|
|
0.2, 0.2, 0.2
|
|
},
|
|
static_save = false,
|
|
},
|
|
on_activate = function(e, rot)
|
|
e.object:set_armor_groups{immortal = 1}
|
|
end,
|
|
on_deactivate = function(e)
|
|
for _, x in ipairs(e._particles) do
|
|
minetest.delete_particlespawner(x)
|
|
end
|
|
end,
|
|
on_step = function(e, dtime, movement)
|
|
-- Minetest's collision is rather bad, but we also shouldn't collide with players,
|
|
-- hence we must implement our own rudimentary collision detection.
|
|
-- In this case, any intersection on the segment betwee our last position and our
|
|
-- current one should be considered a collision and result in detonation (and
|
|
-- at the exact intersection point, if available).
|
|
local collision
|
|
for x in minetest.raycast(e.old_pos or e.object:get_pos(), e.object:get_pos(), true, true, {nodes = {}, objects = {playser = false}}) do
|
|
collision = x
|
|
break
|
|
end
|
|
if collision or movement.collides then
|
|
if collision then
|
|
e.object:set_pos(collision.intersection_point)
|
|
end
|
|
minetest.add_particlespawner {
|
|
pos = e.object:get_pos(),
|
|
radius = 0.1,
|
|
texture = {
|
|
name = "artifact_light.png",
|
|
alpha_tween = {1, 0}
|
|
},
|
|
glow = 8,
|
|
size_tween = {
|
|
{min = 2, max = 3},
|
|
{min = 4, max = 5}
|
|
},
|
|
attract = {
|
|
kind = "point",
|
|
strength = {
|
|
min = -50,
|
|
max = -20,
|
|
},
|
|
origin = e.object:get_pos()
|
|
},
|
|
amount = 25,
|
|
exptime = 0.5,
|
|
drag = 1,
|
|
time = 0.1,
|
|
}
|
|
e.object:remove()
|
|
if movement and movement.collisions[1] and movement.collisions[1].type == "node" then
|
|
local pos = movement.collisions[1].node_pos
|
|
local name = minetest.get_node(pos).name
|
|
if minetest.registered_nodes[name].on_impact then
|
|
minetest.registered_nodes[name].on_impact(pos)
|
|
end
|
|
end
|
|
return
|
|
end
|
|
e.old_pos = e.object:get_pos()
|
|
end,
|
|
impulse = function(e, vel)
|
|
-- The documentation said that `vel` is relative to the parent entity...
|
|
-- I guess the documentation is wrong?
|
|
local rot = vel:normalize():dir_to_rotation()
|
|
local min, max = vector.sort(vector.new(-1,-1,-1):rotate(rot), vector.new(1,1,0):rotate(rot))
|
|
e._particles = {
|
|
-- Tail
|
|
minetest.add_particlespawner {
|
|
attached = e.object,
|
|
pos = {
|
|
min = vector.new(-1,-1,-1) *0.2,
|
|
max = vector.new(1,1,1) *0.2
|
|
},
|
|
vel = {
|
|
min = min,
|
|
max = max
|
|
},
|
|
texture = {
|
|
name = "artifact_light.png",
|
|
alpha_tween = {1, 0}
|
|
},
|
|
size = 0.4,
|
|
glow = 10,
|
|
amount = 450,
|
|
time = 0
|
|
},
|
|
-- Head
|
|
minetest.add_particlespawner {
|
|
attached = e.object,
|
|
pos = vector.zero(),
|
|
vel = vel,
|
|
texture = "[fill:16x16:0,0:#fff",
|
|
size_tween = {3, 0},
|
|
glow = 14,
|
|
amount = 150,
|
|
time = 0,
|
|
exptime = 0.1
|
|
}
|
|
}
|
|
e.object:set_velocity(vel)
|
|
end
|
|
})
|
|
|
|
function ns.do_shoot(m)
|
|
minetest.add_entity(m.pos +m.dir, "artifact:burst", tostring(m.yaw)):get_luaentity():impulse(m.dir *30)
|
|
end
|