init.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. -- Cloaking system for players.
  2. -- Note: admin has special invisibility system in gdac_invis directory.
  3. cloaking = cloaking or {}
  4. cloaking.modpath = minetest.get_modpath("cloaking")
  5. cloaking.players = cloaking.players or {}
  6. function cloaking.do_scan(pname)
  7. -- If player is cloaked, check for reasons to disable the cloak.
  8. if cloaking.players[pname] then
  9. local pref = minetest.get_player_by_name(pname)
  10. if pref then
  11. local pos = pref:get_pos()
  12. local player_count = 0
  13. local mob_count = 0
  14. -- If there are nearby entities, disable the cloak.
  15. local objs = minetest.get_objects_inside_radius(pos, 5)
  16. for i = 1, #objs, 1 do
  17. if objs[i]:is_player() and objs[i]:get_hp() > 0 then
  18. if not gdac.player_is_admin(objs[i]) then
  19. player_count = player_count + 1
  20. end
  21. else
  22. local ent = objs[i]:get_luaentity()
  23. if ent and ent.mob then
  24. mob_count = mob_count + 1
  25. end
  26. end
  27. end
  28. -- There will always be at least one player (themselves).
  29. if player_count > 1 or mob_count > 0 then
  30. cloaking.toggle_cloak(pname)
  31. end
  32. end
  33. end
  34. -- If cloak still enabled for this player, then check again in 1 second.
  35. if cloaking.players[pname] then
  36. minetest.after(1, cloaking.do_scan, pname)
  37. end
  38. end
  39. function cloaking.is_cloaked(pname)
  40. if cloaking.players[pname] then
  41. return true
  42. end
  43. return false
  44. end
  45. function cloaking.toggle_cloak(pname)
  46. local player = minetest.get_player_by_name(pname)
  47. if not player or not player:is_player() then
  48. return
  49. end
  50. if not cloaking.players[pname] then
  51. -- Enable cloak.
  52. cloaking.players[pname] = true
  53. player_labels.disable_nametag(pname)
  54. -- Notify so health gauges can be removed.
  55. gauges.on_teleport()
  56. player:set_properties({
  57. visual_size = {x=0, y=0},
  58. is_visible = false,
  59. pointable = false,
  60. })
  61. minetest.chat_send_player(pname, "# Server: Cloak activated.")
  62. -- Enable scanning for reasons to cancel the cloak.
  63. minetest.after(1, cloaking.do_scan, pname)
  64. else
  65. -- Disable cloak.
  66. cloaking.players[pname] = nil
  67. player_labels.enable_nametag(pname)
  68. -- Restore player properties.
  69. player:set_properties({
  70. visual_size = {x=1, y=1},
  71. is_visible = true,
  72. pointable = true,
  73. })
  74. minetest.chat_send_player(pname, "# Server: Cloak offline.")
  75. end
  76. end
  77. -- Disable cloak if player dies.
  78. function cloaking.on_dieplayer(player, reason)
  79. local pname = player:get_player_name()
  80. if cloaking.is_cloaked(pname) then
  81. -- Ensure cloak is disabled *after* player is dead (and bones spawned), not before!
  82. minetest.after(0, cloaking.toggle_cloak, pname)
  83. end
  84. end
  85. -- Cleanup player info on leave game.
  86. function cloaking.on_leaveplayer(player, timeout)
  87. local pname = player:get_player_name()
  88. cloaking.players[pname] = nil
  89. end
  90. if not cloaking.registered then
  91. minetest.register_on_dieplayer(function(...)
  92. cloaking.on_dieplayer(...)
  93. end)
  94. minetest.register_on_leaveplayer(function(...)
  95. cloaking.on_leaveplayer(...)
  96. end)
  97. local c = "cloaking:core"
  98. local f = cloaking.modpath .. "/init.lua"
  99. reload.register_file(c, f, false)
  100. cloaking.registered = true
  101. end