statbars.lua 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. -- cache setting
  2. local enable_damage = core.settings:get_bool("enable_damage")
  3. local health_bar_definition =
  4. {
  5. hud_elem_type = "statbar",
  6. position = { x=0.5, y=1 },
  7. text = "heart.png",
  8. number = core.PLAYER_MAX_HP_DEFAULT,
  9. direction = 0,
  10. size = { x=24, y=24 },
  11. offset = { x=(-10*24)-25, y=-(48+24+16)},
  12. }
  13. local breath_bar_definition =
  14. {
  15. hud_elem_type = "statbar",
  16. position = { x=0.5, y=1 },
  17. text = "bubble.png",
  18. number = core.PLAYER_MAX_BREATH_DEFAULT,
  19. direction = 0,
  20. size = { x=24, y=24 },
  21. offset = {x=25,y=-(48+24+16)},
  22. }
  23. local hud_ids = {}
  24. local function scaleToDefault(player, field)
  25. -- Scale "hp" or "breath" to the default dimensions
  26. local current = player["get_" .. field](player)
  27. local nominal = core["PLAYER_MAX_".. field:upper() .. "_DEFAULT"]
  28. local max_display = math.max(nominal,
  29. math.max(player:get_properties()[field .. "_max"], current))
  30. return current / max_display * nominal
  31. end
  32. local function update_builtin_statbars(player)
  33. local name = player:get_player_name()
  34. if name == "" then
  35. return
  36. end
  37. local flags = player:hud_get_flags()
  38. if not hud_ids[name] then
  39. hud_ids[name] = {}
  40. -- flags are not transmitted to client on connect, we need to make sure
  41. -- our current flags are transmitted by sending them actively
  42. player:hud_set_flags(flags)
  43. end
  44. local hud = hud_ids[name]
  45. if flags.healthbar and enable_damage then
  46. local number = scaleToDefault(player, "hp")
  47. if hud.id_healthbar == nil then
  48. local hud_def = table.copy(health_bar_definition)
  49. hud_def.number = number
  50. hud.id_healthbar = player:hud_add(hud_def)
  51. else
  52. player:hud_change(hud.id_healthbar, "number", number)
  53. end
  54. elseif hud.id_healthbar then
  55. player:hud_remove(hud.id_healthbar)
  56. hud.id_healthbar = nil
  57. end
  58. local breath_max = player:get_properties().breath_max
  59. if flags.breathbar and enable_damage and
  60. player:get_breath() < breath_max then
  61. local number = 2 * scaleToDefault(player, "breath")
  62. if hud.id_breathbar == nil then
  63. local hud_def = table.copy(breath_bar_definition)
  64. hud_def.number = number
  65. hud.id_breathbar = player:hud_add(hud_def)
  66. else
  67. player:hud_change(hud.id_breathbar, "number", number)
  68. end
  69. elseif hud.id_breathbar then
  70. player:hud_remove(hud.id_breathbar)
  71. hud.id_breathbar = nil
  72. end
  73. end
  74. local function cleanup_builtin_statbars(player)
  75. local name = player:get_player_name()
  76. if name == "" then
  77. return
  78. end
  79. hud_ids[name] = nil
  80. end
  81. local function player_event_handler(player,eventname)
  82. assert(player:is_player())
  83. local name = player:get_player_name()
  84. if name == "" or not hud_ids[name] then
  85. return
  86. end
  87. if eventname == "health_changed" then
  88. update_builtin_statbars(player)
  89. if hud_ids[name].id_healthbar then
  90. return true
  91. end
  92. end
  93. if eventname == "breath_changed" then
  94. update_builtin_statbars(player)
  95. if hud_ids[name].id_breathbar then
  96. return true
  97. end
  98. end
  99. if eventname == "hud_changed" then
  100. update_builtin_statbars(player)
  101. return true
  102. end
  103. return false
  104. end
  105. function core.hud_replace_builtin(name, definition)
  106. if type(definition) ~= "table" or
  107. definition.hud_elem_type ~= "statbar" then
  108. return false
  109. end
  110. if name == "health" then
  111. health_bar_definition = definition
  112. for name, ids in pairs(hud_ids) do
  113. local player = core.get_player_by_name(name)
  114. if player and ids.id_healthbar then
  115. player:hud_remove(ids.id_healthbar)
  116. ids.id_healthbar = nil
  117. update_builtin_statbars(player)
  118. end
  119. end
  120. return true
  121. end
  122. if name == "breath" then
  123. breath_bar_definition = definition
  124. for name, ids in pairs(hud_ids) do
  125. local player = core.get_player_by_name(name)
  126. if player and ids.id_breathbar then
  127. player:hud_remove(ids.id_breathbar)
  128. ids.id_breathbar = nil
  129. update_builtin_statbars(player)
  130. end
  131. end
  132. return true
  133. end
  134. return false
  135. end
  136. -- Append "update_builtin_statbars" as late as possible
  137. -- This ensures that the HUD is hidden when the flags are updated in this callback
  138. core.register_on_mods_loaded(function()
  139. core.register_on_joinplayer(update_builtin_statbars)
  140. end)
  141. core.register_on_leaveplayer(cleanup_builtin_statbars)
  142. core.register_playerevent(player_event_handler)