]> git.lizzy.rs Git - Crafter.git/blob - mods/player_api/api.lua
f9ccedf00548d4c562cc719563a86132449526a2
[Crafter.git] / mods / player_api / api.lua
1 -- Minetest 0.4 mod: player
2 -- See README.txt for licensing and other information.
3
4 player_api = {}
5
6 -- Player animation blending
7 -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
8 local animation_blend = 0
9
10 player_api.registered_models = { }
11
12 -- Local for speed.
13 local models = player_api.registered_models
14
15 function player_api.register_model(name, def)
16         models[name] = def
17 end
18
19 -- Player stats and animations
20 local player_model = {}
21 local player_textures = {}
22 local wielded_item = {}
23 local player_anim = {}
24 local player_sneak = {}
25 player_api.player_attached = {}
26
27
28 --modify the player's wielded item
29 function player_api.set_wielded_item(player)
30         local name = player:get_player_name()
31         
32         
33         --local model = models[model_name]
34         if not wielded_item[name] or not wielded_item[name]:get_luaentity() then
35                 wielded_item[name] = nil
36                 --we give the player an item to hold
37                 local itemstring = player:get_wielded_item():get_name()
38                 
39                 local wield_item = minetest.add_entity(player:get_pos(),"player_api:item")
40                 if wield_item then
41                 
42                         wield_item:get_luaentity():set_item(itemstring)
43                         
44                         wield_item:get_luaentity().wielder = player:get_player_name()
45                         
46                         wield_item:set_attach(player, "Right_Hand", vector.new(0,0,0), vector.new(0,0,0))
47                         
48                         wielded_item[name] = wield_item
49                 end
50                 return
51         end
52         
53         
54         local itemstring = wielded_item[name]:get_luaentity().itemstring
55         local player_wield_item = player:get_wielded_item():get_name()
56         
57         if itemstring ~= player_wield_item then
58                 wielded_item[name]:get_luaentity().itemstring = player_wield_item
59                 wielded_item[name]:get_luaentity():set_item(player_wield_item)
60         end
61 end
62
63
64
65 function player_api.get_animation(player)
66         local name = player:get_player_name()
67         return {
68                 model = player_model[name],
69                 textures = player_textures[name],
70                 animation = player_anim[name],
71         }
72 end
73
74 -- Called when a player's appearance needs to be updated
75 function player_api.set_model(player, model_name)
76         local name = player:get_player_name()
77         local model = models[model_name]
78         if player_model[name] == model_name then
79                 return
80         end
81         player:set_properties({
82                 mesh = model_name,
83                 textures = player_textures[name] or model.textures,
84                 visual = "mesh",
85                 visual_size = model.visual_size or {x = 1, y = 1},
86                 collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
87                 stepheight = model.stepheight or 0.6,
88                 eye_height = model.eye_height or 1.47,
89         })
90         player_api.set_animation(player, "stand")
91         player_model[name] = model_name
92 end
93
94 function player_api.set_textures(player, textures)
95         local name = player:get_player_name()
96         local model = models[player_model[name]]
97         local model_textures = model and model.textures or nil
98         player_textures[name] = textures or model_textures
99         player:set_properties({textures = textures or model_textures,})
100 end
101
102 function player_api.set_animation(player, anim_name, speed)
103         local name = player:get_player_name()
104         if player_anim[name] == anim_name then
105                 return
106         end
107         local model = player_model[name] and models[player_model[name]]
108         if not (model and model.animations[anim_name]) then
109                 return
110         end
111         local anim = model.animations[anim_name]
112         
113         
114         --calculate local animation
115         --update player's frame speed
116         
117         local local_player_animation = player:get_local_animation()
118         local idle_animation = {x = 0,   y = 79}
119         local walk_animation = {x = 168, y = 187}
120         local dig_animation =  {x = 189, y = 198}
121         local walk_and_dig =   {x = 200, y = 219}
122         local sneak_speed = nil
123         local opacity = 255
124         if anim_name == "sneak" or anim_name == "sneak_mine_stand" or anim_name == "sneak_walk" or anim_name == "sneak_mine_walk" then
125                 idle_animation = model.animations.sneak
126                 walk_animation = model.animations.sneak_walk
127                 dig_animation =  model.animations.sneak_mine_stand
128                 walk_and_dig =   model.animations.sneak_mine_walk
129                 sneak_speed = 16
130                 opacity = 0
131         end
132         
133         --update the external animation speed that other players see
134         local sneaker_speed = speed
135         if sneak_speed then
136                 sneaker_speed = sneak_speed
137         end
138         
139         player:set_local_animation(
140                 idle_animation,--idle
141                 walk_animation,--walk
142                 dig_animation,--dig
143                 walk_and_dig,--walk and dig
144                 speed
145         )
146         player:set_nametag_attributes(
147         {color = {
148                 r = 255,
149                 b = 255,
150                 a = opacity,
151                 g = 255
152         }
153         })
154         player_api.set_model(player, "character.b3d")
155         player_anim[name] = anim_name
156         player:set_animation(anim, sneaker_speed, animation_blend)
157 end
158
159 minetest.register_on_leaveplayer(function(player)
160         local name = player:get_player_name()
161         player_model[name] = nil
162         player_anim[name] = nil
163         player_textures[name] = nil
164 end)
165
166 -- Localize for better performance.
167 local player_set_animation = player_api.set_animation
168 local player_attached = player_api.player_attached
169
170 -- Prevent knockback for attached players
171 local old_calculate_knockback = minetest.calculate_knockback
172 function minetest.calculate_knockback(player, ...)
173         if player_attached[player:get_player_name()] then
174                 return 0
175         end
176         return old_calculate_knockback(player, ...)
177 end
178
179 --converts yaw to degrees
180 local degrees = function(yaw)
181         return(yaw*180.0/math.pi)
182 end
183
184 -- Check each player and apply animations
185 minetest.register_globalstep(function()
186         for _, player in pairs(minetest.get_connected_players()) do
187                 --update the player wielded item model
188                 player_api.set_wielded_item(player)
189
190                 local name = player:get_player_name()
191                 local model_name = player_model[name]
192                 local model = model_name and models[model_name]
193                 if model and not player_attached[name] then
194                         local controls = player:get_player_control()
195                         local animation_speed_mod = model.animation_speed or 30
196
197                         -- Determine if the player is sneaking, and reduce animation speed if so
198                         --if controls.sneak then
199                         --      animation_speed_mod = 0
200                         --end
201                         
202                         local meta = player:get_meta()
203                         local movement_state = meta:get_string("player.player_movement_state")
204
205                         local pitch = -degrees(player:get_look_vertical())
206                         if movement_state == "3" then
207                                 pitch = pitch + 15
208                         end
209                         player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,0,0))
210
211
212                         -- Apply animations based on what the player is doing
213                         if player:get_hp() == 0 then
214                                 player_set_animation(player, "lay")
215                         elseif movement_state == "0" then
216                                 --walking normal
217                                 if controls.up or controls.down or controls.left or controls.right then
218                                         if controls.LMB or controls.RMB then
219                                                 player_set_animation(player, "walk_mine", animation_speed_mod)
220                                         else
221                                                 player_set_animation(player, "walk", animation_speed_mod)
222                                         end
223                                 else
224                                         if controls.LMB or controls.RMB then
225                                                 player_set_animation(player, "mine", animation_speed_mod)
226                                         else
227                                                 player_set_animation(player, "stand", animation_speed_mod)
228                                         end
229                                 end
230                         elseif movement_state == "1" then
231                                 --running
232                                 if controls.up or controls.down or controls.left or controls.right then
233                                         if controls.LMB or controls.RMB then
234                                                 player_set_animation(player, "walk_mine", animation_speed_mod*1.5)
235                                         else
236                                                 player_set_animation(player, "walk", animation_speed_mod*1.5)
237                                         end
238                                 else
239                                         if controls.LMB or controls.RMB then
240                                                 player_set_animation(player, "mine", animation_speed_mod*1.5)
241                                         else
242                                                 player_set_animation(player, "stand", animation_speed_mod*1.5)
243                                         end
244                                 end
245                         elseif movement_state == "2" then
246                                 --bunnyhopping
247                                 if controls.up or controls.down or controls.left or controls.right then
248                                         if controls.LMB or controls.RMB then
249                                                 player_set_animation(player, "walk_mine", animation_speed_mod*1.75)
250                                         else
251                                                 player_set_animation(player, "walk", animation_speed_mod*1.75)
252                                         end
253                                 else
254                                         if controls.LMB or controls.RMB then
255                                                 player_set_animation(player, "mine", animation_speed_mod*1.75)
256                                         else
257                                                 player_set_animation(player, "stand", animation_speed_mod*1.75)
258                                         end
259                                 end
260                         elseif movement_state == "3" then
261                                 --sneaking
262                                 if controls.up or controls.down or controls.left or controls.right then
263                                         if controls.LMB or controls.RMB then
264                                                 player_set_animation(player, "sneak_mine_walk", 30)
265                                         else
266                                                 player_set_animation(player, "sneak_walk", 30)
267                                         end
268                                 else
269                                         if controls.LMB or controls.RMB then
270                                                 player_set_animation(player, "sneak_mine_stand", 30)
271                                         else
272                                                 player_set_animation(player, "sneak", 30)
273                                         end
274                                 end
275                         --safety catches
276                         elseif controls.LMB or controls.RMB then
277                                 player_set_animation(player, "mine", animation_speed_mod)
278                         else
279                                 player_set_animation(player, "sneak", animation_speed_mod)
280                         end
281                 end
282         end
283 end)