1 local path = minetest.get_modpath(minetest.get_current_modname())
3 -- path for the temporary skins file
4 local temppath = minetest.get_worldpath() .. "/skins_temp.png"
6 local pngimage = dofile(path.."/png_lua/png.lua")
8 --run through all the skins on the skindex and index them all locally
9 --only try to index further than the point in the current list max
11 local http = minetest.request_http_api()
12 local id = "Lua Skins Updater"
13 -- Binary downloads are required
14 if not core.features.httpfetch_binary_data then
15 print("outdated version of MINETEST detected!")
23 print("---------------------------------------------------------------")
24 print("HTTP access is required. Please add this to your minetest.conf:")
25 print("secure.http_mods = skins")
26 print("!!Skins will not work without this!!")
27 print("---------------------------------------------------------------")
31 -- Fancy debug wrapper to download an URL
32 local function fetch_url(url, callback)
38 if result.succeeded then
40 --if result.code ~= 200 then
41 --core.log("warning", ("%s: STATUS=%i URL=%s"):format(
42 -- _ID_, result.code, url))
44 return callback(result.data)
46 core.log("warning", ("%s: Failed to download URL=%s"):format(
51 --https://gist.github.com/marceloCodget/3862929 rgb to hex
53 local function rgbToHex(rgb)
55 local hexadecimal = ""
57 for key, value in pairs(rgb) do
61 local index = math.fmod(value, 16) + 1
62 value = math.floor(value / 16)
63 hex = string.sub('0123456789ABCDEF', index, index) .. hex
66 if(string.len(hex) == 0)then
69 elseif(string.len(hex) == 1)then
73 hexadecimal = hexadecimal .. hex
81 local function file_to_texture(image)
84 --local base_texture = "[combine:"..xmax.."x"..ymax
85 local base_texture = "[combine:" .. xmax .. "x" .. ymax
86 --local base_texture2 = "[combine:"..xmax.."x"..ymax
87 for _,line in pairs(image.pixels) do
88 for _,data in pairs(line) do
89 if x <= 32 or y > 16 then
90 local hex = rgbToHex({data.R,data.G,data.B})
91 --skip transparent pixels
93 --https://github.com/GreenXenith/skinmaker/blob/master/init.lua#L57 Thanks :D
95 base_texture = base_texture .. (":%s,%s=%s"):format(x - 1, y - 1, "(p.png\\^[colorize\\:#" .. hex .. ")")
113 -- Function to fetch a range of pages
114 fetch_function = function(name)
115 fetch_url("https://raw.githubusercontent.com/"..name.."/crafter_skindex/master/skin.png", function(data)
117 local f = io.open(temppath, "wb")
121 local img = pngimage(temppath, nil, false, false)
123 local stored_texture = file_to_texture(img)
125 --print("===============================================================")
126 --print(stored_texture)
127 if stored_texture then
128 --set the player's skin
129 local player = minetest.get_player_by_name(name)
130 player:set_properties({textures = {stored_texture, "blank_skin.png"}})
131 local meta = player:get_meta()
132 meta:set_string("skin",stored_texture)
134 recalculate_armor(player) --redundancy
139 hud_elem_type = "image", -- See HUD element types
140 -- Type of element, can be "image", "text", "statbar", or "inventory"
142 position = {x=0.5, y=0.5},
143 -- Left corner position of element
147 scale = {x = 2, y = 2},
149 text = stored_texture,
156 -- Selected item in inventory. 0 for no item selected.
159 -- Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
161 alignment = {x=0, y=0},
165 size = { x=100, y=100 },
166 -- Size of element in pixels
169 -- Z index : lower z-index HUDs are displayed behind higher z-index HUDs
180 --local img = pngimage(minetest.get_modpath("skins").."/skin_temp/temp.png", nil, false, false)
186 cape.initial_properties = {
189 textures = {"cape_core.png"},
191 collisionbox = {0, 0, 0, 0, 0, 0}
193 cape.degrees = function(yaw)
194 return(yaw*180.0/math.pi)
196 cape.texture_set = false
197 cape.on_step = function(self,dtime)
198 --don't waste any cpu
199 if not self.owner or not self.owner:is_player() then
204 if not self.texture_set and self.texture_type then
205 self.object:set_properties({textures={self.texture_type}})
206 self.texture_set = true
209 local pos = self.object:get_pos()
210 local current_animation,_,_,_ = self.object:get_animation()
211 current_animation = current_animation.x
214 --do not allow cape to flutter if player is moving backwards
215 local body_yaw = self.owner:get_look_horizontal()
216 local cape_yaw = minetest.dir_to_yaw(vector.direction(self.old_pos,pos))
217 cape_yaw = minetest.dir_to_yaw(minetest.yaw_to_dir(cape_yaw))
218 cape_yaw = self.degrees(cape_yaw)-self.degrees(body_yaw)
220 if cape_yaw < -180 then
221 cape_yaw = cape_yaw + 360
222 elseif cape_yaw > 180 then
223 cape_yaw = cape_yaw - 360
225 if cape_yaw >= -90 and cape_yaw <= 90 then
226 --use old position to calculate the "wind"
227 local deg = self.degrees(minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(self.old_pos.x,0,self.old_pos.z)),0,pos.y-self.old_pos.y))+(math.pi/2))*-1
229 self.goal = math.floor(deg+0.5)
234 if vector.distance(pos,self.old_pos) == 0 then
239 if self.goal and current_animation ~= self.goal then
240 if math.abs(current_animation-self.goal) == 1 then --this stops jittering
241 self.object:set_animation({x=self.goal,y=self.goal}, 0, 0, false)
242 elseif current_animation < self.goal then
243 self.object:set_animation({x=current_animation+2,y=current_animation+2}, 0, 0, false)
244 elseif current_animation > self.goal then
245 self.object:set_animation({x=current_animation-2,y=current_animation-2}, 0, 0, false)
250 minetest.register_entity("skins:cape",cape)
252 --function for handling capes
253 local cape_table = {}
255 local add_cape = function(player,cape)
256 local obj = minetest.add_entity(player:get_pos(),"skins:cape")
257 obj:get_luaentity().owner = player
258 obj:set_attach(player, "Cape_bone", vector.new(0,0.25,0.5), vector.new(-90,180,0))
259 obj:get_luaentity().texture_type = cape
260 local name = player:get_player_name()
261 cape_table[name] = obj
264 local function readd_capes()
265 for _,player in ipairs(minetest.get_connected_players()) do
266 local meta = player:get_meta()
267 local cape = meta:get_string("cape")
269 local name = player:get_player_name()
270 if not cape_table[name] or (cape_table[name] and not cape_table[name]:get_luaentity()) then
271 add_cape(player,cape)
276 minetest.after(3,function()
280 minetest.register_on_mods_loaded(function()
281 minetest.after(3,function()
286 local custom = {sfan5=true,appguru=true,tacotexmex=true,oilboi=true,wuzzy=true}
288 local core_devs = {celeron55=true,nore=true,nerzhul=true,paramat=true,sofar=true,rubenwardy=true,smalljoker=true,larsh=true,thetermos=true,krock=true}
290 local patrons = {tacotexmex=true,ufa=true,monte48=true}
293 minetest.register_on_joinplayer(function(player)
294 local meta = player:get_meta()
295 meta:set_string("skin","player.png")
296 local name = string.lower(player:get_player_name())
301 cape = "cape_"..name..".png"
302 elseif core_devs[name] then
303 cape = "cape_core.png"
304 elseif patrons[name] then
305 cape = "cape_patron.png"
309 meta:set_string("cape",cape)
310 add_cape(player,cape)
313 minetest.after(0,function()
314 fetch_function(player:get_player_name())