f64303def2153c1f9b3153d800b7f8fdd76b02e6
[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 --
5 -- Start of configuration area:
6 --
7
8 -- Player animation speed
9 animation_speed = 30
10
11 -- Player animation blending
12 -- Note: This is currently broken due to a bug in Irrlicht, leave at 0
13 animation_blend = 0
14
15 -- Default player appearance
16 default_model = "character.x"
17 default_texture = "character.png"
18
19 -- Frame ranges for each player model
20 function player_get_animations(model)
21         if model == "character.x" then
22                 return {
23                 stand_START = 0,
24                 stand_END = 79,
25                 walk_START = 81,
26                 walk_END = 100,
27                 mine_START = 102,
28                 mine_END = 111,
29                 walk_mine_START = 113,
30                 walk_mine_END = 132,
31                 death_START = 134,
32                 death_END = 153
33                 }
34         end
35 end
36
37 --
38 -- End of configuration area.
39 --
40
41 -- Player stats and animations
42 local player_model = {}
43 local player_anim = {}
44 local player_sneak = {}
45 local ANIM_STAND = 1
46 local ANIM_WALK  = 2
47 local ANIM_WALK_MINE = 3
48 local ANIM_MINE = 4
49 local ANIM_DEATH = 5
50
51 -- Called when a player's appearance needs to be updated
52 function player_update_visuals(pl)
53         local name = pl:get_player_name()
54
55         player_model[name] = default_model
56         player_anim[name] = 0 -- Animation will be set further below immediately
57         player_sneak[name] = false
58         prop = {
59                 mesh = default_model,
60                 textures = {default_texture, },
61                 visual = "mesh",
62                 visual_size = {x=1, y=1},
63         }
64         pl:set_properties(prop)
65 end
66
67 -- Update appearance when the player joins
68 minetest.register_on_joinplayer(player_update_visuals)
69
70 -- Check each player and apply animations
71 function player_step(dtime)
72         for _, pl in pairs(minetest.get_connected_players()) do
73                 local name = pl:get_player_name()
74                 local anim = player_get_animations(player_model[name])
75                 local controls = pl:get_player_control()
76                 local walking = false
77                 local animation_speed_modified = animation_speed
78
79                 -- Determine if the player is walking
80                 if controls.up or controls.down or controls.left or controls.right then
81                         walking = true
82                 end
83
84                 -- Determine if the player is sneaking, and reduce animation speed if so
85                 if controls.sneak and pl:get_hp() ~= 0 and (walking or controls.LMB) then
86                         animation_speed_modified = animation_speed_modified / 2
87                         -- Refresh player animation below if sneak state changed
88                         if not player_sneak[name] then
89                                 player_anim[name] = 0
90                                 player_sneak[name] = true
91                         end
92                 else
93                         -- Refresh player animation below if sneak state changed
94                         if player_sneak[name] then
95                                 player_anim[name] = 0
96                                 player_sneak[name] = false
97                         end
98                 end
99
100                 -- Apply animations based on what the player is doing
101                 if pl:get_hp() == 0 then
102                         if player_anim[name] ~= ANIM_DEATH then
103                                 -- TODO: The death animation currently loops, we must make it play only once then stay at the last frame somehow
104                                 pl:set_animation({x=anim.death_START, y=anim.death_END}, animation_speed_modified, animation_blend)
105                                 player_anim[name] = ANIM_DEATH
106                         end
107                 elseif walking and controls.LMB then
108                         if player_anim[name] ~= ANIM_WALK_MINE then
109                                 pl:set_animation({x=anim.walk_mine_START, y=anim.walk_mine_END}, animation_speed_modified, animation_blend)
110                                 player_anim[name] = ANIM_WALK_MINE
111                         end
112                 elseif walking then
113                         if player_anim[name] ~= ANIM_WALK then
114                                 pl:set_animation({x=anim.walk_START, y=anim.walk_END}, animation_speed_modified, animation_blend)
115                                 player_anim[name] = ANIM_WALK
116                         end
117                 elseif controls.LMB then
118                         if player_anim[name] ~= ANIM_MINE then
119                                 pl:set_animation({x=anim.mine_START, y=anim.mine_END}, animation_speed_modified, animation_blend)
120                                 player_anim[name] = ANIM_MINE
121                         end
122                 elseif player_anim[name] ~= ANIM_STAND then
123                         pl:set_animation({x=anim.stand_START, y=anim.stand_END}, animation_speed_modified, animation_blend)
124                         player_anim[name] = ANIM_STAND
125                 end
126         end
127 end
128 minetest.register_globalstep(player_step)
129
130 -- END