hud.lua 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. if not minetest.global_exists("protector") then protector = {} end
  2. protector.hud = protector.hud or {}
  3. -- Localize.
  4. local hud = protector.hud
  5. hud.players = hud.players or {}
  6. -- Localize for performance.
  7. local vector_distance = vector.distance
  8. local vector_round = vector.round
  9. function protector.update_nearby_players(pos)
  10. local players = minetest.get_connected_players()
  11. for _, player in ipairs(players) do
  12. local p1 = player:get_pos()
  13. if vector_distance(pos, p1) <= 6 then
  14. local pname = player:get_player_name()
  15. hud.players[pname].moved = true -- Will trigger a HUD update.
  16. end
  17. end
  18. end
  19. local gs_timer = 0.0
  20. local gs_timestep = 0.5
  21. function hud.globalstep(dtime)
  22. gs_timer = gs_timer + dtime
  23. if gs_timer < gs_timestep then return end
  24. gs_timer = 0.0
  25. local allplayers = minetest.get_connected_players()
  26. for _, player in ipairs(allplayers) do
  27. local control = player:get_player_control()
  28. local pname = player:get_player_name()
  29. -- Is the player currently moving?
  30. local moving = (control.sneak or control.jump or control.left or control.right or control.up or control.down)
  31. local timer = hud.players[pname].timer
  32. -- Detect if the player moved through some other means.
  33. local pos = vector_round(player:get_pos())
  34. if not vector.equals(hud.players[pname].pos, pos) then
  35. moving = true
  36. end
  37. hud.players[pname].pos = pos
  38. local owner_str = hud.players[pname].owner
  39. -- Advance clock if player is not moving.
  40. if moving then
  41. timer = 0
  42. owner_str = "Pending"
  43. hud.players[pname].moved = true
  44. else
  45. if hud.players[pname].moved then
  46. timer = timer + gs_timestep
  47. owner_str = "Checking"
  48. end
  49. end
  50. if timer > 1 then
  51. -- Player position has already been obtained.
  52. -- Note: 'owner' will be nil if area is unprotected by an owner.
  53. local owner = protector.get_node_owner(pos)
  54. local cblock = city_block:nearest_named_region(pos, owner)
  55. local city = ""
  56. if cblock and cblock[1] and cblock[1].area_name then
  57. city = cblock[1].area_name .. " / "
  58. end
  59. if owner and owner ~= "" then
  60. owner_str = city .. "<" .. rename.gpn(owner) .. ">"
  61. else
  62. owner_str = "Nobody"
  63. end
  64. timer = 0
  65. hud.players[pname].moved = false
  66. end
  67. local coord_str = ""
  68. if passport.player_has_key(pname, player) then
  69. coord_str = "\nCoords: " .. rc.pos_to_string(pos):gsub(",", ", ")
  70. end
  71. local hud_text = "Realm: " .. rc.pos_to_name(pos) ..
  72. coord_str ..
  73. "\nClaim: " .. owner_str
  74. if hud_text ~= hud.players[pname].text then
  75. if not hud.players[pname].id then
  76. hud.players[pname].id = player:hud_add({
  77. hud_elem_type = "text",
  78. name = "Protector Area",
  79. number = 0xFFFFFF, --0xFFFF22,
  80. position = {x=0, y=1},
  81. offset = {x=16, y=-130},
  82. text = hud_text,
  83. alignment = {x=1, y=1},
  84. })
  85. else
  86. player:hud_change(hud.players[pname].id, "text", hud_text)
  87. end
  88. hud.players[pname].text = hud_text
  89. hud.players[pname].owner = owner_str
  90. end
  91. local dir_text = ""
  92. if passport.player_has_key(pname, player) then
  93. local yaw = (player:get_look_horizontal() * 180.0) / math.pi
  94. local div = 360 / 8
  95. local dir = "N/A"
  96. yaw = yaw + (360 / 16)
  97. if yaw > 360 then
  98. yaw = yaw - 360
  99. end
  100. if yaw < div*1 then
  101. dir = "N [+Z]"
  102. elseif yaw < div*2 then
  103. dir = "NW [-X +Z]"
  104. elseif yaw < div*3 then
  105. dir = "W [-X]"
  106. elseif yaw < div*4 then
  107. dir = "SW [-X -Z]"
  108. elseif yaw < div*5 then
  109. dir = "S [-Z]"
  110. elseif yaw < div*6 then
  111. dir = "SE [+X -Z]"
  112. elseif yaw < div*7 then
  113. dir = "E [+X]"
  114. elseif yaw < div*8 then
  115. dir = "NE [+X +Z]"
  116. elseif yaw < div*9 then
  117. dir = "N [+Z]"
  118. end
  119. dir_text = "Facing: " .. dir
  120. end
  121. if dir_text ~= hud.players[pname].dir then
  122. if not hud.players[pname].id2 then
  123. hud.players[pname].id2 = player:hud_add({
  124. hud_elem_type = "text",
  125. number = 0xFFFFFF,
  126. position = {x=1, y=1},
  127. offset = {x=-16, y=-130 + 18*2},
  128. text = dir_text,
  129. alignment = {x=-1, y=1},
  130. })
  131. else
  132. player:hud_change(hud.players[pname].id2, "text", dir_text)
  133. end
  134. hud.players[pname].dir = dir_text
  135. end
  136. -- Store timer.
  137. hud.players[pname].timer = timer
  138. end
  139. end
  140. function hud.joinplayer(player)
  141. local pname = player:get_player_name()
  142. hud.players[pname] = {
  143. timer = 0,
  144. text = "", -- Keep track of last displayed text.
  145. owner = "",
  146. dir = "",
  147. moved = true,
  148. pos = {x=0, y=0, z=0},
  149. }
  150. end
  151. function hud.leaveplayer(player, timedout)
  152. local pname = player:get_player_name()
  153. hud.players[pname] = nil
  154. end
  155. if not hud.registered then
  156. minetest.register_globalstep(function(...) return hud.globalstep(...) end)
  157. minetest.register_on_joinplayer(function(...) return hud.joinplayer(...) end)
  158. minetest.register_on_leaveplayer(function(...) return hud.leaveplayer(...) end)
  159. local c = "protector:hud"
  160. local f = protector.modpath .. "/hud.lua"
  161. reload.register_file(c, f, false)
  162. hud.registered = true
  163. end