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.
90 lines
3.2 KiB
90 lines
3.2 KiB
1 year ago
|
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
|