From b923879b5bb34102a377d2614aab724b8b970f27 Mon Sep 17 00:00:00 2001 From: copygirl Date: Sat, 21 Oct 2023 15:26:03 +0200 Subject: [PATCH] Add HUD indicator for rotating on edges --- hud.lua | 98 ++++++++++++++---- init.lua | 3 +- state.lua | 11 ++ .../nc_extended_rotating_hud_rotate_edge.png | Bin 4976 -> 5443 bytes .../nc_extended_rotating_hud_rotate_face.png | Bin 5007 -> 5212 bytes ...nc_extended_rotating_hud_rotation_axis.png | Bin 0 -> 5191 bytes 6 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 textures/nc_extended_rotating_hud_rotation_axis.png 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 69c2cf5c04cbc337fa8ca72f764466de24e8aeb1..30133ee963d56a6b03f9879c54ff895d28f1ff0f 100644 GIT binary patch delta 1026 zcmeyMc35k|Z6zZ^1w%tCLklZoBL+qW#s$nkk^zi?6hn5XlI_I5GW8BJN8^LNy;oX9 zI37`SF5T4KWpPbQWTDdv(Wp{`onN?TZBfzG>ubtBc(DKIs^;#^>-g3+Dg0o3^y<-) z7fP!C^fkA1e0;D&{{1`KclQ{bR-ZE2tk0OSD>Ws^({OscX!ClGWDdn60uyFN&Y!%* z#OC;Q+nSoa-Jf;d7uWaIZA~z$KcFt89&vX=hj~Z3*;=dTwU0EkPiuX&{Mh0su2T18 z*P~C;&nF#bI^QF8^Nda5ln9-#8!jDQlaq1e@)5((%bM{gcCIP9_h?P1^qOM-e}_CA z<0GG0oef;Fp+nU}VBvyBu2mZZmWQezb!q!HS?-_Uas7$jis7t1GTbX1o8SC6`2RtD z`S!HJtV_OKDvbxabL)E;55_LIyXEcsbJKO( zd$O1l};x|SA6M!G3UMn-8V#)gSTW@(cJIK4o+ z4J@rpfXIAu6GxVcrLkd3T2e}?Zi<1Wg{}!uv2LQVQIf8)d1{hTqH(GP&~Y%0P-hr# zPUXzwV6j)W^`CrQ(5PONQ%LdRy3{GagcsuJ;uunK>+Q9@St5ZF$3FhA-XtN&Dt%kP zH+{9slnG8jQA<28SaU2nQ~E@&h_h+w?A+wZca_ZI8gmx5G`P-FKg*G5xF%X9<-t!= z<2i|O7VnSGZ0zXR@jvH!?h)BLAJycTqqoH~XCDZD!2dzmg4J#9){ngP@88|DTfHjr z{VMgBOP45niqCVtRPOnE(zNs>pPct!*5=B4SxqT<$?Ewlv3ha$=8J3JeoJFfvEBT4 z=c;SzlZ+VmF(fB&=`d>_h<@N4YRkA{mH4*yN#Anw!$cjvu6%pn(`tX%#r2c!oq0LK zeG;F_-&rr)PQUxLF@N)Z&6nGkG`sqh72ej~w*POkj@{Q++83gvJ*)0T&DN_ZvtjUC z_3G-G#jiq{cB%OMFTTut`}P635Bqj4d|%5Xw&Iu21}>h)$9XBMR=s*}Yj9FO(FHp= aA`|{S*@*GDe^o0eQ+vAlxvX-g zjl!b|3#}prL<`r1YB;q9Xm5Fy@ad9$#-#~cc35z&V`Z-wTg|6;ZkN>#uBHe49jm)1 zFY2CB5g(Kx__+D>Z;SVH57&NYblQB#WVJe9M%7s#b>Sql?OJScf=>3K0>Va{dn`S@ z4i?wmJ$(H8Zi(}s_I-c;D)_TlJ#&px;T*}d-iqdmw9RP+_tg6~Oj;u}U$}qv6@`z= z*F~q_w-A>Vt4KR?X36tT%|->!1`dO>I4O? zrW?yHo;u_u==zCA%&tW-^-@>Dd+CU%ThX^}L`bbR+2^n!z(wGT47a$9*y3&XEai2q zt8Yf%DXuR&>jDS=EE#q)gl*#6$NoU_0Pjh^Z3p$4E0TB*WF8Z(H{fC1!yMr+%HYXf zAnIgseh1e!X9j(h=f-UY&!+#4d>_i1ULd*cXxcG`V+-TXN*r)rG2Mvm0^ir{V+^|% z&J&YmXfQh&wzyLL%J!x8pWGPu4z0Am{zLViMlE;AnKuS37s|i4?wS`8YN}VuD)aEN z)JeUD;|9N*=l|Nqb@IU7yPlbRXLC;96@Ptmzxn3PJp1<^&tdrBR`h=RzEI7}|9w9n zxVt`>#o?0ld4tXO;=>#?qaU;wGwfi#klz+^OR>VSC@C!`?wz0U>}%zMaNzltx%!_} UGoxgE6)0DEy85}Sb4q9e0C6{S#Q*>R diff --git a/textures/nc_extended_rotating_hud_rotate_face.png b/textures/nc_extended_rotating_hud_rotate_face.png index b17842b0c92b7a7dcc73865adc5049a319c632d7..c777161e2bd904b39e8961fbf9436ba62ef45033 100644 GIT binary patch delta 1243 zcmYjRc~DY$0RFv)5virNn&z>B$B-7tdw@Jl9C0lVa@#alElWhfE;D5;rDJK`-D##jzUz11PMa0AUXyh0M+6a8T^Mu0l}dK zxW!bYfFLIcC$c-#y*DL}$Ge6la(hVMfBSfXiK(NsV*L;BbHx|d$QmH@vS@@ZX*r*VoiH423__A@jA(5^ONdTbP;OmQmw zg^)%d_1ITbCtXt1F@pOZbB-M8D4AVn6idqTB{%t~mb{XjIHH!by>TXldEqr5^ zbbZnt`c;&@=YGsdADOl!Q&I|b?Wi5OVKAl*@4o~r8M)_q*NJym;%Qc&$LC4fu+Z_c_*45b4ER0 z8w_Lg3zmG4wkM}{yapx!U>CA`tL79ehkZ~iO~|C9A__A-9iuR?Kn4ZFFoYstV04s` z#$=#0wjyLny)DLKvk^8*W73#x#mtfeHYl?7^U{h;y!V$`a}GZTDO5|7eMB^&FrC2` zPy`4~NLe(g6m}rWq+l#m#1;rprcgjvtRqB!(PnF8g#84o;fJ(R#jHIlaay*Lj16ip z0|3*b!ns@Xo*K?_cAaT4NttZDr~8!qX!(bobW)Lh7~y~F zIqFr_L45b;fJ7Ae)5muG!@*{in7o5j4OH;UW-HLXAdpui!zR2orc0WzMT|FDX$LYp z2QBP~*!R0cWWOsa(|N9>GgIU_@TTI$i~5bB60PIVGV^Q9BZBjIGmX{P^Ts>w%+_-@eL3W(an}6Hvewm44ZMFZC~CvE;Z0%uf`0(}+!MzD delta 1209 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 literal 0 HcmV?d00001