init.lua 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. if not minetest.global_exists("ap") then ap = {} end
  2. ap.modpath = ap.modpath or minetest.get_modpath("ap")
  3. ap.players = ap.players or {}
  4. -- Number of seconds to keep track of player's reported positions.
  5. -- This must be at least 1 (though such a small value is NOT useful).
  6. ap.record_time = 60*10
  7. -- Localize vector.distance() for performance.
  8. local vector_distance = vector.distance
  9. function ap.get_record_time()
  10. return ap.record_time
  11. end
  12. function ap.update_players()
  13. local players = minetest.get_connected_players()
  14. for i=1, #players, 1 do
  15. local pref = players[i]
  16. local pname = pref:get_player_name()
  17. local p = pref:get_pos() -- Note: position is NOT rounded.
  18. local t = ap.players[pname].positions
  19. -- Don't add position to list of last recorded positions if the player
  20. -- hasn't moved since last time.
  21. local add = true
  22. if #t > 0 then
  23. local op = t[#t].pos
  24. if vector_distance(op, p) < 0.5 then
  25. add = false
  26. end
  27. end
  28. -- Insert position into player's record (for this session) and remove old
  29. -- entries from the beginning.
  30. if add then
  31. table.insert(t, {
  32. pos = p,
  33. time = os.time(),
  34. -- Node names.
  35. snode = sky.get_last_walked_node(pname),
  36. wnode = sky.get_last_walked_nodeabove(pname),
  37. })
  38. if #t > ap.record_time then
  39. table.remove(t, 1)
  40. end
  41. end
  42. end
  43. end
  44. -- Returns a list of positions for this player in the last few seconds,
  45. -- or an empty table if that player wasn't loaded.
  46. -- Each entry is a table in the format {pos, time}.
  47. function ap.get_position_list(pname)
  48. local data = ap.players[pname]
  49. if not data then return {} end
  50. return data.positions or {}
  51. end
  52. function ap.on_joinplayer(pref)
  53. -- Don't erase evidence.
  54. local pname = pref:get_player_name()
  55. if not ap.players[pname] then
  56. ap.players[pname] = {
  57. positions = {},
  58. }
  59. end
  60. ap.players[pname].join_time = os.time()
  61. ap.players[pname].exit_time = nil
  62. end
  63. function ap.on_leaveplayer(pref)
  64. -- Don't erase evidence right away.
  65. local pname = pref:get_player_name()
  66. ap.players[pname].exit_time = os.time()
  67. minetest.after(ap.get_record_time() + 5, function()
  68. local data = ap.players[pname]
  69. if data then
  70. if data.exit_time and data.exit_time <= (os.time() - ap.get_record_time()) then
  71. ap.players[pname] = nil
  72. end
  73. end
  74. end)
  75. end
  76. local time = 0
  77. function ap.global_step(dtime)
  78. time = time + dtime
  79. if time < 1 then return end
  80. time = 0
  81. ap.update_players()
  82. end
  83. if not ap.registered then
  84. local c = "ap:core"
  85. local f = ap.modpath .. "/init.lua"
  86. reload.register_file(c, f, false)
  87. minetest.register_on_joinplayer(function(...)
  88. ap.on_joinplayer(...) end)
  89. minetest.register_on_leaveplayer(function(...)
  90. ap.on_leaveplayer(...) end)
  91. minetest.register_globalstep(function(...)
  92. ap.global_step(...) end)
  93. ap.registered = true
  94. end