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