Implement death animation, but it currently loops constantly after the player dies...
[oweals/minetest_game.git] / mods / default / player.lua
1 -- Minetest 0.4 mod: player
2 -- See README.txt for licensing and other information.
3
4 -- Animation speed
5 animation_speed = 30
6 -- Animation blending
7 -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
8 animation_blend = 0
9
10 -- Default player appearance
11 default_model = "character.x"
12 default_texture = "character.png"
13
14 -- Player states
15 local player_model = {}
16 local player_anim = {}
17 local player_sneak = {}
18 local ANIM_STAND = 0
19 local ANIM_WALK  = 1
20 local ANIM_WALK_MINE = 2
21 local ANIM_MINE = 3
22 local ANIM_DEATH = 4
23
24 -- Frame ranges for each player model
25 function player_get_animations(model)
26         if model == "character.x" then
27                 return {
28                 stand_START = 0,
29                 stand_END = 79,
30                 walk_START = 81,
31                 walk_END = 100,
32                 mine_START = 102,
33                 mine_END = 111,
34                 walk_mine_START = 113,
35                 walk_mine_END = 132,
36                 death_START = 134,
37                 death_END = 153
38                 }
39         end
40 end
41
42 -- Called whenever a player's appearance needs to be updated
43 function player_update_visuals(player)
44         player_model[player:get_player_name()] = default_model
45         player_anim[player:get_player_name()] = ANIM_STAND
46
47         local name = player:get_player_name()
48         local anim = player_get_animations(player_model[name])
49         prop = {
50                 mesh = default_model,
51                 textures = {default_texture, },
52                 visual = "mesh",
53                 visual_size = {x=1, y=1},
54         }
55         player:set_properties(prop)
56         player:set_animation({x=anim.stand_START, y=anim.stand_END}, animation_speed, animation_blend) -- initial animation
57 end
58
59 -- Update appearance when the player joins
60 minetest.register_on_joinplayer(player_update_visuals)
61
62 -- Global environment step function
63 function on_step(dtime)
64         for _, pl in pairs(minetest.get_connected_players()) do
65                 local name = pl:get_player_name()
66                 local anim = player_get_animations(player_model[name])
67                 local controls = pl:get_player_control()
68
69                 local walking = false
70                 if controls.up or controls.down or controls.left or controls.right then
71                         walking = true
72                 end
73
74                 local animation_speed_modified = animation_speed
75                 if controls.sneak and pl:get_hp() ~= 0 and (walking or controls.LMB) then
76                         animation_speed_modified = animation_speed_modified / 2
77                         -- Refresh player animation below
78                         if not player_sneak[name] then
79                                 player_anim[name] = -1
80                                 player_sneak[name] = true
81                         end
82                 else
83                         -- Refresh player animation below
84                         if player_sneak[name] then
85                                 player_anim[name] = -1
86                                 player_sneak[name] = false
87                         end
88                 end
89
90                 if pl:get_hp() == 0 then
91                         if player_anim[name] ~= ANIM_DEATH then
92                                 -- TODO: The death animation currently loops, we must make it play only once then stay at the last frame somehow
93                                 pl:set_animation({x=anim.death_START, y=anim.death_END}, animation_speed_modified, animation_blend)
94                                 player_anim[name] = ANIM_DEATH
95                         end
96                 elseif walking and controls.LMB then
97                         if player_anim[name] ~= ANIM_WALK_MINE then
98                                 pl:set_animation({x=anim.walk_mine_START, y=anim.walk_mine_END}, animation_speed_modified, animation_blend)
99                                 player_anim[name] = ANIM_WALK_MINE
100                         end
101                 elseif walking then
102                         if player_anim[name] ~= ANIM_WALK then
103                                 pl:set_animation({x=anim.walk_START, y=anim.walk_END}, animation_speed_modified, animation_blend)
104                                 player_anim[name] = ANIM_WALK
105                         end
106                 elseif controls.LMB then
107                         if player_anim[name] ~= ANIM_MINE then
108                                 pl:set_animation({x=anim.mine_START, y=anim.mine_END}, animation_speed_modified, animation_blend)
109                                 player_anim[name] = ANIM_MINE
110                         end
111                 elseif player_anim[name] ~= ANIM_STAND then
112                         pl:set_animation({x=anim.stand_START, y=anim.stand_END}, animation_speed_modified, animation_blend)
113                         player_anim[name] = ANIM_STAND
114                 end
115         end
116 end
117 minetest.register_globalstep(on_step)
118
119 -- END