You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
3.2 KiB
89 lines
3.2 KiB
local minetest, vector, math_rad, math_random |
|
= minetest, vector, math.rad, math.random |
|
|
|
local get_node_active_selection_box = nc_extended_rotating.utility.get_node_active_selection_box; |
|
|
|
local TAU = math.pi * 2 |
|
|
|
local MOD_NAME = minetest.get_current_modname() |
|
local ARROWS_FACE = MOD_NAME .. ":arrows_face" |
|
local ARROWS_EDGE = MOD_NAME .. ":arrows_edge" |
|
local ARROWS_CORNER = MOD_NAME .. ":arrows_corner" |
|
|
|
local entities_per_player = {} |
|
|
|
local function register_entity(name, mesh, rot_speed) |
|
minetest.register_entity(name, { |
|
initial_properties = { |
|
visual = "mesh", |
|
mesh = mesh, |
|
textures = { "nc_extended_rotating_arrows.png^[opacity:192" }, |
|
use_texture_alpha = true, |
|
pointable = false, -- Can't be interacted with. |
|
static_save = false, -- Doesn't get saved. |
|
automatic_rotate = math_rad(rot_speed), -- Rotation in degrees per second. |
|
}, |
|
on_deactivate = function(self, removal) |
|
if not self.player_name then return end |
|
entities_per_player[self.player_name] = nil |
|
end, |
|
}) |
|
end |
|
|
|
register_entity(ARROWS_FACE , "nc_extended_rotating_face.obj" , 120) |
|
register_entity(ARROWS_EDGE , "nc_extended_rotating_edge.obj" , 60) |
|
register_entity(ARROWS_CORNER, "nc_extended_rotating_corner.obj", 120) |
|
|
|
minetest.register_on_leaveplayer(function(player, timed_out) |
|
local name = player:get_player_name() |
|
local arrows = entities_per_player[name] |
|
if arrows then arrows.object:remove() end |
|
end) |
|
|
|
local entity = {} |
|
|
|
function entity.update_entity_hint(player, state) |
|
local name = player:get_player_name() |
|
local arrows = entities_per_player[name] |
|
|
|
if state then |
|
if arrows then |
|
if state.pos == arrows.prev_pos and state.axis == arrows.prev_axis and state.invert == arrows.prev_invert then |
|
-- No changes were made, so skip creating a new entity. |
|
return |
|
else |
|
-- Changes were made, delete the old entity. |
|
-- We do this to avoid rotation interpolation from `set_rotation`. |
|
arrows.object:remove() |
|
arrows = nil |
|
end |
|
end |
|
|
|
local ent, off |
|
if state.mode == "face" then ent, off = ARROWS_FACE , state.axis / 1.85 |
|
elseif state.mode == "edge" then ent, off = ARROWS_EDGE , vector.new(0, 0, 0) |
|
elseif state.mode == "corner" then ent, off = ARROWS_CORNER, state.axis / 2.65 |
|
end |
|
|
|
local box = get_node_active_selection_box(state.node) |
|
local max = box.max - box.min |
|
local pos = state.pos + off:multiply(max) |
|
local rot = vector.dir_to_rotation(state.axis) |
|
rot.x = rot.x + (state.invert and -TAU/4 or TAU/4) |
|
|
|
arrows = minetest.add_entity(pos, ent):get_luaentity() |
|
arrows.object:set_properties({ visual_size = max }) |
|
arrows.object:set_rotation(rot) |
|
|
|
arrows.player_name = name |
|
arrows.prev_pos = state.pos |
|
arrows.prev_axis = state.axis |
|
arrows.prev_invert = state.invert |
|
entities_per_player[name] = arrows |
|
|
|
elseif arrows then |
|
arrows.object:remove() |
|
end |
|
end |
|
|
|
return entity
|
|
|