]> git.lizzy.rs Git - nametags.git/blob - init.lua
Initial commit
[nametags.git] / init.lua
1 nametags = {
2         nametag_cache = {},
3         item_texture_cache = {},
4         armor_cache = {},
5 }
6
7 function nametags.get_wield_entity(player)
8         for _, child in pairs(minetest.get_objects_inside_radius(player:get_pos(), 1)) do
9                 if child:get_attach() == player then
10                         local child_prop = child:get_properties()
11                         if child_prop.visual == "wielditem" then
12                                 return child
13                         end
14                 end
15         end
16 end
17
18 function nametags.resize_image(image)
19         return image .. "^[resize:32x32"
20 end
21
22 function nametags.colorize_tiledef(tile, node_color)
23         if tile.name == "" then
24                 return
25         end
26
27         local color = tile.color or node_color
28         if color then
29                 return "(" .. tile.name .. ")^[multiply:" .. minetest.rgba(color.r, color.g, color.b, color.a)
30         else
31                 return tile.name
32         end
33 end
34
35 function nametags.render_tile(nodedef, n)
36         local img = nametags.colorize_tiledef(nodedef.tiles[n], nodedef.color)
37         local overlay = nametags.colorize_tiledef(nodedef.overlay_tiles[n], nodedef.color)
38
39         if overlay then
40                 img = img .. "^(" .. overlay .. ")"
41         end
42
43         return img
44 end
45
46 function nametags.create_item_texture(itemname)
47         local itemdef = minetest.get_item_def(itemname)
48         local nodedef = minetest.get_node_def(itemname)
49         if itemdef then
50                 if itemdef.inventory_image ~= "" then
51                         return itemdef.inventory_image
52                 elseif nodedef then
53                         if nodedef.drawtype == "mesh" or nodedef.drawtype == "nodebox" then
54                                 return nodedef.tiles[1].name
55                         else
56                                 return minetest.inventorycube(
57                                         nametags.render_tile(nodedef, 1),
58                                         nametags.render_tile(nodedef, 6),
59                                         nametags.render_tile(nodedef, 5)
60                                 )
61                         end
62                 end
63         end
64 end
65
66 function nametags.get_item_texture(itemname)
67         local cached_texture = nametags.item_texture_cache[itemname]
68         if cached_texture then
69                 return cached_texture
70         end
71         local texture = nametags.create_item_texture(itemname)
72         nametags.item_texture_cache[itemname] = texture
73         return texture
74 end
75
76 function nametags.parse_armor_texture(armor_texture)
77         if armor_texture == "blank.png" then
78                 return {}
79         end
80         local armor_pieces = {}
81         local armor_textures = armor_texture:sub(2, #armor_texture - 1):split(")^(")
82         for _, texture in ipairs(armor_textures) do
83                 local itemname = nametags.armor_cache[texture]
84                 if not itemname then
85                         local piece_textures = texture:split("^")
86                         local enchanted = false
87                         if #piece_textures > 1 and piece_textures[2] == "[colorize:purple:50" then
88                                 enchanted = true
89                         end
90                         local components = (piece_textures[1] or ""):split("_")
91                         local modname = table.remove(components, 1) or ""
92                         if modname then
93                                 if modname == "mcl" then
94                                         modname = modname .. "_" .. (table.remove(components, 1) or "")
95                                 end
96                                 local subname = table.concat(components, "_"):split(".")[1]
97                                 itemname = modname .. ":" .. subname
98                                 if enchanted then
99                                         itemname = itemname .. "_enchanted"
100                                 end
101                         end
102                         nametags.armor_cache[texture] = itemname
103                 end
104                 table.insert(armor_pieces, 1, itemname)
105         end
106         return armor_pieces
107 end
108
109 function nametags.wield_entity_get_itemname(obj)
110         local prop = obj and obj:get_properties()
111         return prop and prop.textures[1] or ""
112 end
113
114 local blank_resized = nametags.resize_image("blank.png")
115
116 function nametags.update_nametag(player)
117         if player:is_player() and not player:is_local_player() then
118                 local props = player:get_properties()
119
120                 local nametag = props.nametag
121                 local hp = player:get_hp()
122
123                 local idx = nametag:find("♥")
124
125                 if idx then
126                         nametag = nametag:sub(1, idx + 2) .. hp
127                 else
128                         nametag = nametag .. minetest.get_color_escape_sequence("#FF0000") .. " ♥" .. hp
129                 end
130
131                 player:set_properties({
132                         nametag = nametag,
133                         nametag_bgcolor = {a = 128, r = 0, g = 0, b = 0}
134                 })
135
136                 local cache = nametags.nametag_cache[player]
137
138                 if not cache then
139                         cache = {
140                                 armor_texture = "blank.png",
141                                 armor_textures = {},
142                                 wield_texture = "blank.png",
143                                 wield_texture_resized = blank_resized,
144                                 wield_entity_itemname = "",
145                                 wield_entity = nametags.get_wield_entity(player),
146                                 nametag_images = {blank_resized},
147                         }
148                         nametags.nametag_cache[player] = cache
149                 end
150
151                 local wield_texture = props.textures[3]
152                 local wield_texture_blank = wield_texture == "blank.png"
153                 local wield_entity_itemname = ""
154                 local wield_cached = cache.wield_texture == wield_texture
155
156                 if wield_texture_blank then
157                         wield_entity_itemname = nametags.wield_entity_get_itemname(cache.wield_entity)
158                         wield_cached = wield_cached and cache.wield_entity_itemname == wield_entity_itemname
159                 end
160
161                 local armor_texture = props.textures[2]
162                 local armor_cached = cache.armor_texture == armor_texture
163
164                 local nametag_images
165
166                 if wield_cached and armor_cached then
167                         nametag_images = cache.nametag_images
168                 else
169                         local wield_texture_resized
170
171                         if wield_cached then
172                                 wield_texture_resized = cache.wield_texture_resized
173                         else
174                                 if wield_texture_blank then
175                                         if wield_entity_itemname ~= "" then
176                                                 wield_texture = nametags.get_item_texture(wield_entity_itemname) or "blank.png"
177                                         end
178                                 end
179                                 wield_texture_resized = nametags.resize_image(wield_texture)
180                                 cache.wield_texture = wield_texture
181                                 cache.wield_texture_resized = wield_texture_resized
182                         end
183
184                         local armor_textures
185
186                         if armor_cached then
187                                 armor_textures = cache.armor_textures
188                         else
189                                 armor_textures = {}
190                                 for _, piece in ipairs(nametags.parse_armor_texture(armor_texture)) do
191                                         local texture = nametags.get_item_texture(piece)
192                                         if texture then
193                                                 table.insert(armor_textures, nametags.resize_image(texture))
194                                         end
195                                 end
196                                 cache.armor_texture = armor_texture
197                                 cache.armor_textures = armor_textures
198                         end
199
200                         nametag_images = {wield_texture_resized}
201                         for _, texture in ipairs(armor_textures) do
202                                 table.insert(nametag_images, texture)
203                         end
204                         cache.nametag_images = nametag_images
205                 end
206
207                 player:set_nametag_images(nametag_images)
208         end
209 end
210
211 minetest.register_on_object_properties_change(nametags.update_nametag)
212 minetest.register_on_object_hp_change(nametags.update_nametag)
213
214 minetest.register_on_object_add(function(obj)
215         local attach = obj:get_attach()
216         if attach and attach:is_player() and not attach:is_local_player() then
217                 local cache = nametags.nametag_cache[attach]
218
219                 if cache then
220                         cache.wield_entity = obj
221                 end
222         end
223 end)