diff --git a/hud.lua b/hud.lua index 7ca00ae..c6d28bf 100644 --- a/hud.lua +++ b/hud.lua @@ -1,37 +1,97 @@ -local nodecore - = nodecore +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_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 function crosshair_hud_element(texture) - return { - label = LABEL_ROTATION_HINT, + 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, + 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 - } + quick = true, + } else return { + label = label, + ttl = 0, + } end end - local mode = state and state.mode - if mode == "face" then - local texture = TEX_ROTATE_FACE - if state.invert then texture = texture .. "^[transformFX" end - texture = texture .. "^[opacity:" .. 192 - nodecore.hud_set(player, crosshair_hud_element(texture)) - else - nodecore.hud_set(player, { label = LABEL_ROTATION_HINT, ttl = 0 }) - 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 diff --git a/init.lua b/init.lua index 2038823..e203a2e 100755 --- a/init.lua +++ b/init.lua @@ -16,7 +16,8 @@ local update_rotating_state = nc_extended_rotating.state.update_rotating_state local get_rotating_state = nc_extended_rotating.state.get_rotating_state -- TODO: Fix HUD showing rotation hint when we wouldn't / can't rotate. --- TODO: Add crosshair indicators for rotating around edges. +-- TODO: Add crosshair indicators for rotating around corners. +-- TODO: Use Aux1 control to use NodeCore's built-in rotation? -- TODO: Add some more comments. -- TODO: Add particles to preview rotation? diff --git a/state.lua b/state.lua index c093013..b3663c2 100755 --- a/state.lua +++ b/state.lua @@ -19,6 +19,16 @@ local rotating_state = {} -- This state contains information about how the player would rotate a block. local function calculate_rotating_state(player, data) local state = {} + -- { + -- pos = position of the node to be rotated + -- node = the node being rotated + -- face = a vector pointing away from the face looked at + -- edge = a vector pointing to the face, edge or corner looked at + -- axis = calculated axis to rotate around + -- invert = whether the rotation was inverted due to holding sneak + -- facedir = the facedir value to set the node to on rotation + -- success = whether rotating would be successful + -- } local pointed_thing = data.raycast() if (not pointed_thing) or pointed_thing.type ~= "node" then return nil end @@ -36,6 +46,7 @@ local function calculate_rotating_state(player, data) local degrees = 90 local r = rotation_vector_from_lookat(state.node, pointed_thing, EDGE_DISTANCE) + state.edge = r state.axis = r local num = math_round(r.x * r.x + r.y * r.y + r.z * r.z) -- Squared length. diff --git a/textures/nc_extended_rotating_hud_rotate_edge.png b/textures/nc_extended_rotating_hud_rotate_edge.png index 69c2cf5..30133ee 100644 Binary files a/textures/nc_extended_rotating_hud_rotate_edge.png and b/textures/nc_extended_rotating_hud_rotate_edge.png differ diff --git a/textures/nc_extended_rotating_hud_rotate_face.png b/textures/nc_extended_rotating_hud_rotate_face.png index b17842b..c777161 100644 Binary files a/textures/nc_extended_rotating_hud_rotate_face.png and b/textures/nc_extended_rotating_hud_rotate_face.png differ diff --git a/textures/nc_extended_rotating_hud_rotation_axis.png b/textures/nc_extended_rotating_hud_rotation_axis.png new file mode 100644 index 0000000..6ccc0d4 Binary files /dev/null and b/textures/nc_extended_rotating_hud_rotation_axis.png differ