api.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. panel_lib.panels = {} -- KEY: p_name; VALUE: {{"panel name" = panel}, {"panel name 2" = panel2}, ...}
  2. local function clone_table() end
  3. local function add_sub_elem() end
  4. local function update_sub_elems() end
  5. Panel = {
  6. name = "",
  7. -- player to show the panel to
  8. player_name = "",
  9. -- ids of the hud of the player
  10. hud_id = {},
  11. -- text values of the huds, to retrieve on :show()
  12. hud_text = {},
  13. -- because the panel is composed by a background and a text we need to
  14. -- define the two HUD to use later
  15. background_def = {
  16. hud_elem_type = "image",
  17. position = { x = 1, y = 0.5 },
  18. scale = { x = 1, y = 1 },
  19. alignment = { x = -1, y = 0 },
  20. offset = {x = 0, y = 0},
  21. text = "panel_bg.png",
  22. },
  23. title_def = {
  24. hud_elem_type = "text",
  25. position = {x = 1, y = 0.5},
  26. alignment = {x = 0, y = 0},
  27. offset = {x = 0, y = 0},
  28. size = { x = 1 },
  29. number = 0xFFFFFF,
  30. text = ""
  31. },
  32. sub_img_elems = {},
  33. sub_txt_elems = {},
  34. visible = true
  35. }
  36. function Panel:new(name, def)
  37. local panel = {}
  38. local metapanel = clone_table(Panel)
  39. setmetatable(panel, metapanel)
  40. metapanel.__index = metapanel
  41. --v------------------ LEGACY UPDATE, to remove in 3.0 -------------------v
  42. if type(name) == "table" and def == nil then
  43. minetest.log("warning", "[PANEL_LIB] Panel declaration deprecated. Please put the panel name outside of the def table as it follows -> Panel:new(name, def)")
  44. def = clone_table(name)
  45. name = def.name
  46. end
  47. if def.is_shown ~= nil then
  48. minetest.log("warning", "[PANEL_LIB] `is_shown` is deprecated. Use `visible` instead")
  49. def.visible = def.is_shown
  50. end
  51. --^------------------ LEGACY UPDATE, to remove in 3.0 -------------------^
  52. if not name or type(name) ~= "string" then
  53. minetest.log("warning", "[PANEL_LIB] Can't create a panel without a proper name, aborting")
  54. return
  55. else
  56. panel.name = name
  57. end
  58. if def.position then
  59. panel.background_def.position = def.position
  60. panel.title_def.position = def.position
  61. end
  62. if def.alignment then
  63. panel.background_def.alignment = def.alignment
  64. end
  65. if def.offset then
  66. panel.background_def.offset = def.offset
  67. panel.title_def.offset = def.offset
  68. end
  69. if def.bg then
  70. panel.background_def.text = def.bg
  71. end
  72. if def.bg_scale then
  73. panel.background_def.scale = def.bg_scale
  74. end
  75. if def.title then
  76. panel.title_def.text = def.title
  77. end
  78. if def.title_alignment then
  79. panel.title_def.alignment = def.title_alignment
  80. end
  81. if def.title_offset then
  82. if not def.offset then
  83. panel.title_def.offset = def.title_offset
  84. else
  85. panel.title_def.offset = {x = panel.title_def.offset.x + (def.title_offset.x or 0), y = panel.title_def.offset.y + (def.title_offset.y or 0)}
  86. end
  87. end
  88. if def.title_color then
  89. panel.title_def.number = def.title_color
  90. end
  91. if def.title_size then
  92. panel.title_def.size = def.title_size
  93. end
  94. if def.player then
  95. panel.player_name = def.player
  96. end
  97. if def.visible ~= nil and type(def.visible) == "boolean" then
  98. panel.visible = def.visible
  99. end
  100. panel.hud_text.bg_hud_txt = panel.background_def.text
  101. panel.hud_text.text_hud_txt = panel.title_def.text
  102. -- se il pannello non è mostrato di base, svuoto sfondo e titolo
  103. if panel.visible == false then
  104. panel.background_def.text = ""
  105. panel.title_def.text = ""
  106. end
  107. local player = minetest.get_player_by_name(def.player)
  108. -- assegno sfondo e titolo
  109. panel.hud_id.bg_hud_id = player:hud_add(panel.background_def)
  110. panel.hud_id.text_hud_id = player:hud_add(panel.title_def)
  111. -- controllo sottoelementi
  112. if def.sub_img_elems then
  113. for subname, HUD_elem in pairs(def.sub_img_elems) do
  114. add_sub_elem(panel, "image", subname, HUD_elem)
  115. end
  116. end
  117. if def.sub_txt_elems then
  118. for subname, HUD_elem in pairs(def.sub_txt_elems) do
  119. add_sub_elem(panel, "text", subname, HUD_elem)
  120. end
  121. end
  122. -- salvo in memoria
  123. if not panel_lib.panels[def.player] then
  124. panel_lib.panels[def.player] = {}
  125. end
  126. panel_lib.panels[def.player][name] = panel
  127. return panel
  128. end
  129. function Panel:show()
  130. local player = minetest.get_player_by_name(self.player_name)
  131. if self.hud_text.bg_hud_txt ~= "" then
  132. player:hud_change(self.hud_id.bg_hud_id, "text", self.hud_text.bg_hud_txt)
  133. end
  134. if self.hud_text.text_hud_txt ~= "" then
  135. player:hud_change(self.hud_id.text_hud_id, "text", self.hud_text.text_hud_txt)
  136. end
  137. --check for custom elements
  138. for _, name in pairs(self.sub_img_elems) do
  139. player:hud_change(self.hud_id[name], "text", self.hud_text[name])
  140. end
  141. for _, name in pairs(self.sub_txt_elems) do
  142. player:hud_change(self.hud_id[name], "text", self.hud_text[name])
  143. end
  144. self.visible = true
  145. end
  146. function Panel:hide()
  147. if (self.hud_id) then
  148. local player = minetest.get_player_by_name(self.player_name)
  149. for k, v in pairs(self.hud_id) do
  150. player:hud_change(self.hud_id[k], "text", "")
  151. end
  152. end
  153. self.visible = false
  154. end
  155. function Panel:update(def, txt_elems, img_elems)
  156. if def ~= nil then
  157. local player = minetest.get_player_by_name(self.player_name)
  158. for k, v in pairs(def) do
  159. -- aggiorno eventuale posizione, che tratto a parte perché influisce sia su sfondo che titolo,
  160. -- influenzando anche tutti i sottoelementi del pannello
  161. if k == "position" then
  162. self.background_def.position = v
  163. self.title_def.position = v
  164. for _, elem in pairs(self.sub_img_elems) do
  165. local HUD_ID = self.hud_id[elem]
  166. player:hud_change(HUD_ID, k, v)
  167. end
  168. for _, elem in pairs(self.sub_txt_elems) do
  169. local HUD_ID = self.hud_id[elem]
  170. player:hud_change(HUD_ID, k, v)
  171. end
  172. player:hud_change(self.hud_id.bg_hud_id, k, v)
  173. player:hud_change(self.hud_id.text_hud_id, k, v)
  174. -- aggiorno eventuale sfondo
  175. elseif k == "bg" then
  176. self.hud_text.bg_hud_txt = v
  177. self.background_def.text = v
  178. if self.is_visible then
  179. player:hud_change(self.hud_id.bg_hud_id, "text", v)
  180. end
  181. -- aggiorno eventuali proprietà titolo
  182. elseif k == "title" or k == "title_color" then
  183. if k == "title" then
  184. self.hud_text.text_hud_txt = v
  185. self.title_def.text = v
  186. if self.is_visible then
  187. player:hud_change(self.hud_id.text_hud_id, "text", v)
  188. end
  189. else
  190. self.title_def.number = v
  191. player:hud_change(self.hud_id.text_hud_id, "number", v)
  192. end
  193. else
  194. error("[PANEL_LIB] Invalid or unsupported element type, check DOCS and spelling")
  195. return
  196. end
  197. end
  198. end
  199. if txt_elems ~= nil then
  200. update_sub_elems(self, txt_elems)
  201. end
  202. if img_elems ~= nil then
  203. update_sub_elems(self, img_elems)
  204. end
  205. end
  206. function Panel:remove()
  207. panel_lib.panels[self.player_name][self.name] = nil
  208. local player = minetest.get_player_by_name(self.player_name)
  209. for k, v in pairs(self.hud_id) do
  210. player:hud_remove(self.hud_id[k])
  211. end
  212. self = nil
  213. end
  214. function Panel:is_visible()
  215. return self.visible
  216. end
  217. function Panel:add_sub_elem(type, name, HUD_elem)
  218. add_sub_elem(self, type, name, HUD_elem)
  219. end
  220. function Panel:remove_sub_elem(name)
  221. self.sub_txt_elems[name] = nil
  222. self.sub_img_elems[name] = nil
  223. if self.visible then
  224. minetest.get_player_by_name(self.player_name):hud_remove(self.hud_id[name])
  225. end
  226. self.hud_id[name] = nil
  227. self.hud_text[name] = nil
  228. self[name] = nil
  229. end
  230. ----------------------------------------------
  231. -----------------GETTERS----------------------
  232. ----------------------------------------------
  233. function panel_lib.get_panel(p_name, panel_name)
  234. return panel_lib.panels[p_name][panel_name]
  235. end
  236. ----------------------------------------------
  237. ---------------FUNZIONI LOCALI----------------
  238. ----------------------------------------------
  239. -- code from => http://lua-users.org/wiki/CopyTable
  240. function clone_table(orig)
  241. local orig_type = type(orig)
  242. local copy
  243. if orig_type == 'table' then
  244. copy = {}
  245. for orig_key, orig_value in pairs(orig) do
  246. copy[clone_table(orig_key)] = clone_table(orig_value)
  247. end
  248. setmetatable(copy, clone_table(getmetatable(orig)))
  249. else -- number, string, boolean, etc
  250. copy = orig
  251. end
  252. return copy
  253. end
  254. function add_sub_elem(panel, type, name, HUD_elem)
  255. local sub_elems
  256. local mould
  257. if type == "text" then
  258. sub_elems = panel.sub_txt_elems
  259. mould = panel.title_def
  260. elseif type == "image" then
  261. sub_elems = panel.sub_img_elems
  262. mould = panel.background_def
  263. else
  264. error("[PANEL_LIB] type must be either 'text' or 'image'!")
  265. end
  266. if panel[name] then
  267. minetest.log("error", "[PANEL_LIB] Attempt to create a sub element with the same name of another. Aborting")
  268. return end
  269. sub_elems[#sub_elems +1] = name
  270. panel[name] = clone_table(mould)
  271. for k, v in pairs(HUD_elem) do
  272. panel[name][k] = v
  273. end
  274. -- mantengo la stessa posizione del corpo del panel, costringendo
  275. -- l'utente a modificare gli offset se vuole spostare gli elementi
  276. panel[name].position = mould.position
  277. -- se il pannello ha gli offset personalizzati e il sottoelemento pure, li sommo
  278. if HUD_elem.offset and (panel.background_def.offset.x ~= 0 or panel.background_def.offset.y ~= 0) then
  279. panel[name].offset = {x = panel.background_def.offset.x + (HUD_elem.offset.x or 0), y = panel.background_def.offset.y + (HUD_elem.offset.y or 0)}
  280. end
  281. -- mostro l'elemento se il pannello era già visibile
  282. panel[name].text = panel:is_visible() and panel[name].text or ""
  283. panel.hud_id[name] = minetest.get_player_by_name(panel.player_name):hud_add(panel[name])
  284. panel.hud_text[name] = HUD_elem.text
  285. end
  286. function update_sub_elems(panel, elems)
  287. local player = minetest.get_player_by_name(panel.player_name)
  288. for elem, _ in pairs(elems) do
  289. for k, v in pairs(elems[elem]) do
  290. if k == "offset" and (panel.background_def.offset.x ~= 0 or panel.background_def.offset.y ~= 0) then
  291. panel[elem][k] = { x = panel.background_def.offset.x + (v.x or 0), y = panel.background_def.offset.y + (v.y or 0)}
  292. else
  293. panel[elem][k] = v
  294. end
  295. if k == "text" then
  296. panel.hud_text[elem] = v
  297. -- aggiorno il testo solo se visibile
  298. if panel:is_visible() then
  299. player:hud_change(panel.hud_id[elem], k, v)
  300. end
  301. else
  302. player:hud_change(panel.hud_id[elem], k, v)
  303. end
  304. end
  305. end
  306. end
  307. ----------------------------------------------
  308. ------------------DEPRECATED------------------
  309. ----------------------------------------------
  310. -- to remove in 3.0
  311. function Panel:is_shown()
  312. minetest.log("warning", "[PANEL_LIB] `is_shown()` is deprecated. Use `is_visible()` instead")
  313. return self:is_visible()
  314. end