local nodecore, vector, math_round = nodecore, vector, math.round local TAU = math.pi * 2 -- The real circle constant. local QUARTER_CIRCLE = TAU / 4 local LABEL_ROTATION_HINT = "rotation hint" local LABEL_AXIS_HINT = "axis hint" local TEX_ROTATE_FACE = "nc_extended_rotating_hud_rotate_face.png" local TEX_ROTATE_EDGE = "nc_extended_rotating_hud_rotate_edge.png" local TEX_ROTATION_AXIS = "nc_extended_rotating_hud_rotation_axis.png" local hud = {} function hud.update_player_hud(player, state) local rotation_texture = nil local axis_texture = nil local mode = state and state.mode if mode == "face" then local tex = TEX_ROTATE_FACE if state.invert then tex = tex .. "^[transformFX" end rotation_texture = tex elseif mode == "edge" then local tex = TEX_ROTATE_EDGE if state.invert then tex = tex .. "^[transformFX" end local face = state.face -- Face looked at. local edge = state.edge -- Face, edge or corner looked at. local axis = state.axis -- Actual axis of rotation. local look = player:get_look_dir() -- Player look vector. -- Transform a vertical face to an equivalent horizontal one, -- to make the following comparisons work in either case. if state.face.y ~= 0 then local player_yaw = math_round(player:get_look_horizontal() / QUARTER_CIRCLE) * QUARTER_CIRCLE local playing_facing = vector.new(0, 0, 1):rotate_around_axis(vector.new(0, 1, 0), player_yaw) local rotation_axis = face:cross(playing_facing) face = face:rotate_around_axis(rotation_axis, QUARTER_CIRCLE) edge = edge:rotate_around_axis(rotation_axis, QUARTER_CIRCLE) axis = axis:rotate_around_axis(rotation_axis, QUARTER_CIRCLE) look = look:rotate_around_axis(rotation_axis, QUARTER_CIRCLE) end if edge.y == 0 then -- Looking at left or right edge. if axis.y > 0 then tex = tex .. "^[transformFX" -- left else -- right end -- Flip side the arrow is on depending on look vector. if look.y < 0 then tex = tex .. "^[transformFY" end -- Vertical axis rotation texture. axis_texture = TEX_ROTATION_AXIS else -- Looking at top or bottom edge. if edge.y > 0 then tex = tex .. "^[transformR90" -- top else tex = tex .. "^[transformFXR90" -- bottom end -- Flip side the arrow is on depending on look vector. if face:cross(look).y < 0 then tex = tex .. "^[transformFX" end -- Horizontal axis rotation texture. axis_texture = TEX_ROTATION_AXIS .. "^[transformR270" end rotation_texture = tex elseif mode == "corner" then -- TODO: Handle corners. end local function crosshair_hud_element(label, texture) if texture then return { label = label, hud_elem_type = "image", text = texture .. "^[opacity:" .. 192, position = { x = 0.5, y = 0.5 }, offset = { x = 0, y = 0 }, alignment = { x = 0, y = 0 }, scale = { x = 1, y = 1 }, quick = true, } else return { label = label, ttl = 0, } end end -- Actually update the HUD elements. nodecore.hud_set(player, crosshair_hud_element(LABEL_ROTATION_HINT, rotation_texture)) nodecore.hud_set(player, crosshair_hud_element(LABEL_AXIS_HINT, axis_texture)) end return hud