]> git.lizzy.rs Git - Crafter.git/blob - mods/skins/init.lua
Add in capes
[Crafter.git] / mods / skins / init.lua
1 local path = minetest.get_modpath(minetest.get_current_modname())
2
3 -- path for the temporary skins file
4 local temppath = minetest.get_worldpath() .. "/skins_temp.png"
5
6 local pngimage = dofile(path.."/png_lua/png.lua")
7
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
10
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!")
16     return(nil)
17 end
18
19 if not http then
20     for i = 1,5 do
21         print("!WARNING!")
22     end
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("---------------------------------------------------------------")
28     return(nil)
29 end
30
31 -- Fancy debug wrapper to download an URL
32 local function fetch_url(url, callback)
33         http.fetch({
34         url = url,
35         timeout = 3,
36     }, function(result)
37         --print(dump(result))
38         if result.succeeded then
39             
40                         --if result.code ~= 200 then
41                                 --core.log("warning", ("%s: STATUS=%i URL=%s"):format(
42                                 --      _ID_, result.code, url))
43                         --end
44                         return callback(result.data)
45                 end
46                 core.log("warning", ("%s: Failed to download URL=%s"):format(
47                         id, url))
48         end)
49 end
50
51 --https://gist.github.com/marceloCodget/3862929 rgb to hex
52
53 local function rgbToHex(rgb)
54
55         local hexadecimal = ""
56
57         for key, value in pairs(rgb) do
58                 local hex = ''
59
60                 while(value > 0)do
61                         local index = math.fmod(value, 16) + 1
62                         value = math.floor(value / 16)
63                         hex = string.sub('0123456789ABCDEF', index, index) .. hex                       
64                 end
65
66                 if(string.len(hex) == 0)then
67                         hex = '00'
68
69                 elseif(string.len(hex) == 1)then
70                         hex = '0' .. hex
71                 end
72
73                 hexadecimal = hexadecimal .. hex
74         end
75
76         return hexadecimal
77 end
78
79 local xmax = 64
80 local ymax = 32
81 local function file_to_texture(image)
82     local x = 1
83     local y = 1
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
92                 if data.A > 0 then 
93                     --https://github.com/GreenXenith/skinmaker/blob/master/init.lua#L57 Thanks :D
94
95                     base_texture = base_texture .. (":%s,%s=%s"):format(x - 1, y - 1, "(p.png\\^[colorize\\:#" .. hex .. ")")
96                 end
97             --else
98             --    print(dump(data))
99             end
100             x = x + 1
101             if x > xmax then
102                 x = 1
103                 y = y + 1
104             end
105             if y > ymax then
106                 break
107             end
108         end
109     end
110     return(base_texture)
111 end
112
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)
116         if data then
117             local f = io.open(temppath, "wb")
118             f:write(data)
119             f:close()
120
121             local img = pngimage(temppath, nil, false, false)
122             if img then
123                 local stored_texture = file_to_texture(img)
124
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)
133
134                     recalculate_armor(player) --redundancy
135                     
136                     --[[
137                     player:hud_add(
138                         {
139                             hud_elem_type = "image",  -- See HUD element types
140                             -- Type of element, can be "image", "text", "statbar", or "inventory"
141                     
142                             position = {x=0.5, y=0.5},
143                             -- Left corner position of element
144                     
145                             name = "<name>",
146                     
147                             scale = {x = 2, y = 2},
148                     
149                             text = stored_texture,
150                     
151                             text2 = "<text>",
152                     
153                             number = 2,
154                     
155                             item = 3,
156                             -- Selected item in inventory. 0 for no item selected.
157                     
158                             direction = 0,
159                             -- Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
160                     
161                             alignment = {x=0, y=0},
162                     
163                             offset = {x=0, y=0},
164                     
165                             size = { x=100, y=100 },
166                             -- Size of element in pixels
167                     
168                             z_index = 0,
169                             -- Z index : lower z-index HUDs are displayed behind higher z-index HUDs
170                         }
171                     )
172                     ]]--
173                 end
174             end
175
176         end
177     end)
178 end
179
180 --local img = pngimage(minetest.get_modpath("skins").."/skin_temp/temp.png", nil, false, false)
181 --print(dump(img))
182
183
184
185 local cape = {}
186 cape.initial_properties = {
187         visual = "mesh",
188         mesh = "cape.x",
189         textures = {"cape_core.png"},
190     pointable = false,
191     collisionbox = {0, 0, 0, 0, 0, 0}
192 }
193 cape.degrees = function(yaw)
194     return(yaw*180.0/math.pi)
195 end
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
200         self.object:remove()
201         return
202     end
203     --set cape texture
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
207     end
208
209     local pos = self.object:get_pos()
210     local current_animation,_,_,_ = self.object:get_animation()
211     current_animation = current_animation.x
212
213     if self.old_pos then
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)
219
220                 if cape_yaw < -180 then
221                         cape_yaw = cape_yaw + 360
222                 elseif cape_yaw > 180 then
223                         cape_yaw = cape_yaw - 360
224         end
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
228             deg = deg + 90
229             self.goal = math.floor(deg+0.5)
230         else
231             self.goal = 0
232         end
233
234         if vector.distance(pos,self.old_pos) == 0 then
235             self.goal = 25
236         end
237     end
238     --cape smoothing
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)
246         end
247     end
248     self.old_pos = pos
249 end
250 minetest.register_entity("skins:cape",cape)
251
252 --function for handling capes
253 local cape_table = {}
254
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
262 end
263
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")
268         if cape ~= "" then
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)
272                 print("adding cape")
273             end
274         end
275     end
276     minetest.after(3,function()
277         readd_capes()
278     end)
279 end
280 minetest.register_on_mods_loaded(function()
281     minetest.after(3,function()
282         readd_capes()
283     end)
284 end)
285
286 local custom = {sfan5=true,appguru=true,tacotexmex=true,oilboi=true,wuzzy=true}
287
288 local core_devs = {celeron55=true,nore=true,nerzhul=true,paramat=true,sofar=true,rubenwardy=true,smalljoker=true,larsh=true,thetermos=true,krock=true}
289
290 local patrons = {tacotexmex=true,ufa=true,monte48=true}
291
292
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())
297
298     --cape handling
299     local cape = false
300     if custom[name] then
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"
306     end
307
308     if cape then
309         meta:set_string("cape",cape)
310         add_cape(player,cape)
311     end
312
313     minetest.after(0,function()
314         fetch_function(player:get_player_name())
315     end)
316 end)