]> git.lizzy.rs Git - Crafter.git/blob - mods/skins/init.lua
Update init.lua
[Crafter.git] / mods / skins / init.lua
1 local
2 minetest,math,io,vector,table,pairs
3 =
4 minetest,math,io,vector,table,pairs
5
6 local http = minetest.request_http_api()
7 local id = "Lua Skins Updater"
8
9 -- binary downloads are required
10 if not core.features.httpfetch_binary_data then    
11     minetest.log("error","Outdated Minetest Engine detected. Skins mod will not load. This crashes armor.")
12     return(nil)
13 end
14
15 if not http then        
16     minetest.log("error","---------------------------------------------------------------")
17     minetest.log("error","HTTP access is required. Please add this to your minetest.conf:")
18     minetest.log("error","secure.http_mods = skins")
19     minetest.log("error","Skins will not work without this")
20     minetest.log("error","---------------------------------------------------------------")
21     return(nil)
22 end
23
24 -- only create classes if requirements are met
25 local pool = {}
26 local temppath = minetest.get_worldpath()
27
28 local name
29 function get_skin(player)
30     name = player:get_player_name()
31     return(pool[name] or "player.png")
32 end
33
34 -- Fancy debug wrapper to download an URL
35 local function fetch_url(url, callback)
36         http.fetch({
37         url = url,
38         timeout = 3,
39     }, function(result)
40         if result.succeeded then
41             if result.code == 404 then
42                 return(nil)
43             end
44                         if result.code ~= 200 then
45                 return(nil)
46             end
47             return callback(result.data)
48         else
49             return(nil)
50         end
51         return(nil)
52         end)
53 end
54
55 -- gets github raw data of skin
56 local new_temp_path
57 local file
58 local player
59 local fetch_function = function(name)
60     fetch_url("https://raw.githubusercontent.com/"..name.."/crafter_skindex/master/skin.png", function(data)
61         if data then
62
63             if not minetest.get_player_by_name(name) then
64                 return
65             end
66             new_temp_path = temppath .. DIR_DELIM .. "/skin_"..name..".png"
67
68             file = io.open(new_temp_path, "wb")
69             file:write(data)
70             file:close()
71             
72             
73             minetest.dynamic_add_media(new_temp_path)
74             
75             file = "skin_"..name..".png" -- reuse the data
76
77             player = minetest.get_player_by_name(name)
78
79             player:set_properties({textures = {file, "blank_skin.png"}})
80
81             pool[name] = file
82             
83             recalculate_armor(player)
84                 
85         end
86     end)
87 end
88
89
90
91
92
93
94 local pi = math.pi
95
96 -- simple degrees calculation
97 local degrees = function(yaw)
98     return(yaw*180.0/pi)
99 end
100
101 -- built in engine trigonometry
102 local pitch = function(pos,pos2)
103     return(
104         math.floor(
105             degrees(
106                 minetest.dir_to_yaw(
107                     vector.new(
108                         vector.distance(
109                             vector.new(
110                                 pos.x,
111                                 0,
112                                 pos.z
113                             ),
114                             vector.new(
115                                 pos2.x,
116                                 0,
117                                 pos2.z
118                             )
119                         ),
120                         0,
121                         pos.y - pos2.y
122                     )
123                 )
124                 + pi
125             )
126         )
127     )
128 end
129
130 -- calculation to calculate the yaw of the old position
131 local cape_yaw_calculation = function(pos,pos2)
132     return(
133         minetest.dir_to_yaw(
134             vector.direction(
135                 vector.new(
136                     pos2.x,
137                     0     ,
138                     pos2.z
139                 ),
140                 vector.new(
141                     pos.x,
142                     0    ,
143                     pos.z
144                 )
145             )
146         )
147     )
148 end
149
150 -- corrects degrees
151 yaw_correction = function(yaw)
152     if yaw < -180 then
153         yaw = yaw + 360
154     elseif yaw > 180 then
155         yaw = yaw - 360
156     end
157     return(yaw)
158 end
159
160 -- returns if the cape can be "blown"
161 local cape_yaw
162 local move_cape = function(yaw,yaw2)
163     cape_yaw = yaw_correction(degrees(yaw-yaw2))
164     return(cape_yaw >= -90 and cape_yaw <= 90)
165 end
166
167 -- applies movement to the cape
168 local cape_smoothing = function(object,current,cape_goal)
169     if current ~= cape_goal then
170         if math.abs(current-cape_goal) <= 3 then --this stops jittering
171             object:set_animation({x=cape_goal,y=cape_goal}, 0, 0, false)
172         elseif current < cape_goal then
173             object:set_animation({x=current+3,y=current+3}, 0, 0, false)
174         elseif current > cape_goal then
175             object:set_animation({x=current-3,y=current-3}, 0, 0, false)
176         end
177     end
178 end
179
180 local cape_object = {}
181 cape_object.initial_properties = {
182         visual = "mesh",
183         mesh = "cape.x",
184         textures = {"cape_core.png"},
185     pointable = false,
186     collisionbox = {0, 0, 0, 0, 0, 0}
187 }
188 cape_object.texture_set = false
189 cape_object.on_activate = function(self)
190     minetest.after(0,function()
191          --don't waste any cpu
192         if not self.owner or not self.owner:is_player() then
193             self.object:remove()
194             return
195         end
196
197         --set cape texture
198         if self.texture_type and not self.texture_set then
199             self.object:set_properties({textures={self.texture_type}})
200             self.texture_type = nil
201             self.texture_set  = nil
202             return
203         end
204     end)
205 end
206
207 local object
208 local pos
209 local current_animation
210 local current_animation
211 local cape_yaw
212 local body_yaw
213 local goal
214 cape_object.on_step = function(self,dtime)
215     object            = self.object
216     pos               = object:get_pos()
217     current_animation = object:get_animation() -- if fails assign other values to nil
218     current_animation = current_animation.x
219     goal              = nil
220     if minetest.is_player(self.owner) and self.old_pos then
221         --do not allow cape to flutter if player is moving backwards
222         cape_yaw = cape_yaw_calculation(pos,self.old_pos)
223         body_yaw = self.owner:get_look_horizontal()
224         
225         if move_cape(cape_yaw,body_yaw) then
226             goal = pitch(pos,self.old_pos)
227         else
228             goal = 160
229         end
230
231         cape_smoothing(object,current_animation,goal)
232     elseif not minetest.is_player(self.owner) then
233         object:remove()
234     end
235
236     self.old_pos = pos
237 end
238
239 minetest.register_entity("skins:cape",cape_object)
240
241
242 local pool2 = {}
243
244
245 local custom    = {
246     sfan5      = true,
247     appguru    = true,
248     tacotexmex = true,
249     oilboi     = true,
250     wuzzy      = true,
251 }
252 local core_devs = {
253     celeron55  = true,
254     nore       = true,
255     nerzhul    = true,
256     paramat    = true,
257     sofar      = true,
258     rubenwardy = true,
259     smalljoker = true,
260     larsh      = true,
261     thetermos  = true,
262     krock      = true,
263 }
264 local patrons   = {
265     tacotexmex = true,
266     ufa        = true,
267     monte48    = true,
268 }
269
270
271 -- simple check if has cape
272 local name
273 local temp_cape
274 local get_texture = function(player)
275     name = string.lower(player:get_player_name())
276
277     temp_cape = nil
278
279     if custom[name] then
280         temp_cape = "cape_"..name..".png"
281     elseif core_devs[name] then
282         temp_cape = "cape_core.png"
283     elseif patrons[name] then
284         temp_cape = "cape_patron.png"
285     end
286     return(temp_cape)
287 end
288
289 -- adds cape to player
290 local name
291 local temp_pool
292 local texture
293 local object
294 local lua_entity
295 local add_cape = function(player)
296     if get_texture(player) then
297         texture = get_texture(player)
298         if texture then
299             name = player:get_player_name()
300             temp_pool = pool2[name]
301
302             object = minetest.add_entity(player:get_pos(),"skins:cape")
303
304             lua_entity = object:get_luaentity()
305
306             lua_entity.owner = player
307             lua_entity.texture_type = texture
308             object:set_attach(player, "Cape_bone", vector.new(0,0,0), vector.new(0,0,0))
309             pool2[name] = object
310         end
311     end
312 end
313
314 -- looping check to see if cape deleted
315 local player
316 local function readd_capes()
317     for name,def in pairs(pool2) do
318         player = minetest.get_player_by_name(name)
319         if pool2[name] and not pool2[name]:get_luaentity() then
320             add_cape(player)
321         elseif not minetest.is_player(name) then
322             pool2[name] = nil
323         end
324     end
325     minetest.after(3,function()
326         readd_capes()
327     end)
328 end
329
330 minetest.register_on_mods_loaded(function()
331     minetest.after(3,function()
332         readd_capes()
333     end)
334 end)
335
336
337 minetest.register_on_joinplayer(function(player)
338     add_cape(player)
339
340     minetest.after(0,function()
341         fetch_function(player:get_player_name())
342         recalculate_armor(player)
343     end)
344 end)