Skip to content

Commit 4c0c7ae

Browse files
committedNov 9, 2013
Rewrite player.lua
1 parent 4bd6bce commit 4c0c7ae

File tree

1 file changed

+161
-103
lines changed

1 file changed

+161
-103
lines changed
 

‎mods/default/player.lua

+161-103
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,190 @@
11
-- Minetest 0.4 mod: player
22
-- See README.txt for licensing and other information.
33

4-
--
5-
-- Start of configuration area:
6-
--
4+
--[[
75
8-
-- Player animation speed
9-
animation_speed = 30
6+
API
7+
---
8+
9+
default.player_register_model(name, def)
10+
^ Register a new model to be used by players.
11+
^ <name> is the model filename such as "character.x", "foo.b3d", etc.
12+
^ See Model Definition below for format of <def>.
13+
14+
default.registered_player_models[name]
15+
^ See Model Definition below for format.
16+
17+
default.player_set_model(player, model_name)
18+
^ <player> is a PlayerRef.
19+
^ <model_name> is a model registered with player_register_model.
20+
21+
default.player_set_animation(player, anim_name [, speed])
22+
^ <player> is a PlayerRef.
23+
^ <anim_name> is the name of the animation.
24+
^ <speed> is in frames per second. If nil, default from the model is used
25+
26+
default.player_set_textures(player, textures)
27+
^ <player> is a PlayerRef.
28+
^ <textures> is an array of textures
29+
^ If <textures> is nil, the default textures from the model def are used
30+
31+
default.player_get_animation(player)
32+
^ <player> is a PlayerRef.
33+
^ Returns a table containing fields "model", "textures" and "animation".
34+
^ Any of the fields of the returned table may be nil.
35+
36+
Model Definition
37+
----------------
38+
39+
model_def = {
40+
animation_speed = 30, -- Default animation speed, in FPS.
41+
textures = {"character.png", }, -- Default array of textures.
42+
visual_size = {x=1, y=1,}, -- Used to scale the model.
43+
animations = {
44+
-- <anim_name> = { x=<start_frame>, y=<end_frame>, },
45+
foo = { x= 0, y=19, },
46+
bar = { x=20, y=39, },
47+
-- ...
48+
},
49+
}
50+
51+
]]
1052

1153
-- Player animation blending
1254
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
13-
animation_blend = 0
55+
local animation_blend = 0
1456

15-
-- Default player appearance
16-
default_model = "character.x"
17-
default_textures = {"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-
sit_START = 81,
26-
sit_END = 160,
27-
lay_START = 162,
28-
lay_END = 166,
29-
walk_START = 168,
30-
walk_END = 187,
31-
mine_START = 189,
32-
mine_END = 198,
33-
walk_mine_START = 200,
34-
walk_mine_END = 219
35-
}
36-
end
57+
default.registered_player_models = { }
58+
59+
-- Local for speed.
60+
local models = default.registered_player_models
61+
62+
function default.player_register_model(name, def)
63+
models[name] = def
3764
end
3865

39-
--
40-
-- End of configuration area.
41-
--
66+
-- Default player appearance
67+
default.player_register_model("character.x", {
68+
animation_speed = 30,
69+
textures = {"character.png", },
70+
animations = {
71+
-- Standard animations.
72+
stand = { x= 0, y= 79, },
73+
lay = { x=162, y=166, },
74+
walk = { x=168, y=187, },
75+
mine = { x=189, y=198, },
76+
walk_mine = { x=200, y=219, },
77+
-- Extra animations (not currently used by the game).
78+
sit = { x= 81, y=160, },
79+
},
80+
})
4281

4382
-- Player stats and animations
4483
local player_model = {}
84+
local player_textures = {}
4585
local player_anim = {}
4686
local player_sneak = {}
47-
local ANIM_STAND = 1
48-
local ANIM_SIT = 2
49-
local ANIM_LAY = 3
50-
local ANIM_WALK = 4
51-
local ANIM_WALK_MINE = 5
52-
local ANIM_MINE = 6
5387

54-
-- Called when a player's appearance needs to be updated
55-
function player_update_visuals(pl)
56-
local name = pl:get_player_name()
57-
58-
player_model[name] = default_model
59-
player_anim[name] = 0 -- Animation will be set further below immediately
60-
player_sneak[name] = false
61-
prop = {
62-
mesh = default_model,
63-
textures = default_textures,
64-
visual = "mesh",
65-
visual_size = {x=1, y=1},
88+
function default.player_get_animation(player)
89+
local name = player:get_player_name()
90+
return {
91+
model = player_model[name],
92+
textures = player_textures[name],
93+
animation = player_anim[name],
6694
}
67-
pl:set_properties(prop)
95+
end
96+
97+
-- Called when a player's appearance needs to be updated
98+
function default.player_set_model(player, model_name)
99+
local name = player:get_player_name()
100+
local model = models[model_name]
101+
if model then
102+
if player_model[name] == model_name then
103+
return
104+
end
105+
player:set_properties({
106+
mesh = model_name,
107+
textures = player_textures[name] or model.textures,
108+
visual = "mesh",
109+
visual_size = model.visual_size or {x=1, y=1},
110+
})
111+
default.player_set_animation(player, "stand")
112+
else
113+
player:set_properties({
114+
textures = { "player.png", "player_back.png", },
115+
visual = "upright_sprite",
116+
})
117+
end
118+
player_model[name] = model_name
119+
end
120+
121+
function default.player_set_textures(player, textures)
122+
local name = player:get_player_name()
123+
player_textures[name] = textures
124+
player:set_properties({textures = textures,})
125+
end
126+
127+
function default.player_set_animation(player, anim_name, speed)
128+
local name = player:get_player_name()
129+
if player_anim[name] == anim_name then
130+
return
131+
end
132+
local model = player_model[name] and models[player_model[name]]
133+
if not (model and model.animations[anim_name]) then
134+
return
135+
end
136+
local anim = model.animations[anim_name]
137+
player_anim[name] = anim_name
138+
player:set_animation(anim, speed or model.animation_speed, animation_blend)
68139
end
69140

70141
-- Update appearance when the player joins
71-
minetest.register_on_joinplayer(player_update_visuals)
142+
minetest.register_on_joinplayer(function(player)
143+
default.player_set_model(player, "character.x")
144+
end)
145+
146+
-- Localize for better performance.
147+
local player_set_animation = default.player_set_animation
72148

73149
-- Check each player and apply animations
74-
function player_step(dtime)
75-
for _, pl in pairs(minetest.get_connected_players()) do
76-
local name = pl:get_player_name()
77-
local anim = player_get_animations(player_model[name])
78-
local controls = pl:get_player_control()
79-
local walking = false
80-
local animation_speed_mod = animation_speed
81-
82-
-- Determine if the player is walking
83-
if controls.up or controls.down or controls.left or controls.right then
84-
walking = true
85-
end
150+
minetest.register_globalstep(function(dtime)
151+
for _, player in pairs(minetest.get_connected_players()) do
152+
local name = player:get_player_name()
153+
local model_name = player_model[name]
154+
local model = model_name and models[model_name]
155+
if model then
156+
local controls = player:get_player_control()
157+
local walking = false
158+
local animation_speed_mod = model.animation_speed or 30
86159

87-
-- Determine if the player is sneaking, and reduce animation speed if so
88-
if controls.sneak and pl:get_hp() ~= 0 and (walking or controls.LMB) then
89-
animation_speed_mod = animation_speed_mod / 2
90-
-- Refresh player animation below if sneak state changed
91-
if not player_sneak[name] then
92-
player_anim[name] = 0
93-
player_sneak[name] = true
94-
end
95-
else
96-
-- Refresh player animation below if sneak state changed
97-
if player_sneak[name] then
98-
player_anim[name] = 0
99-
player_sneak[name] = false
160+
-- Determine if the player is walking
161+
if controls.up or controls.down or controls.left or controls.right then
162+
walking = true
100163
end
101-
end
102164

103-
-- Apply animations based on what the player is doing
104-
if pl:get_hp() == 0 then
105-
if player_anim[name] ~= ANIM_LAY then
106-
pl:set_animation({x=anim.lay_START, y=anim.lay_END}, animation_speed_mod, animation_blend)
107-
player_anim[name] = ANIM_LAY
108-
end
109-
elseif walking and controls.LMB then
110-
if player_anim[name] ~= ANIM_WALK_MINE then
111-
pl:set_animation({x=anim.walk_mine_START, y=anim.walk_mine_END}, animation_speed_mod, animation_blend)
112-
player_anim[name] = ANIM_WALK_MINE
165+
-- Determine if the player is sneaking, and reduce animation speed if so
166+
if controls.sneak then
167+
animation_speed_mod = animation_speed_mod / 2
113168
end
114-
elseif walking then
115-
if player_anim[name] ~= ANIM_WALK then
116-
pl:set_animation({x=anim.walk_START, y=anim.walk_END}, animation_speed_mod, animation_blend)
117-
player_anim[name] = ANIM_WALK
118-
end
119-
elseif controls.LMB then
120-
if player_anim[name] ~= ANIM_MINE then
121-
pl:set_animation({x=anim.mine_START, y=anim.mine_END}, animation_speed_mod, animation_blend)
122-
player_anim[name] = ANIM_MINE
169+
170+
-- Apply animations based on what the player is doing
171+
if player:get_hp() == 0 then
172+
player_set_animation(player, "lay")
173+
elseif walking then
174+
if player_sneak[name] ~= controls.sneak then
175+
player_anim[name] = nil
176+
player_sneak[name] = controls.sneak
177+
end
178+
if controls.LMB then
179+
player_set_animation(player, "walk_mine", animation_speed_mod)
180+
else
181+
player_set_animation(player, "walk", animation_speed_mod)
182+
end
183+
elseif controls.LMB then
184+
player_set_animation(player, "mine")
185+
else
186+
player_set_animation(player, "stand", animation_speed_mod)
123187
end
124-
elseif player_anim[name] ~= ANIM_STAND then
125-
pl:set_animation({x=anim.stand_START, y=anim.stand_END}, animation_speed_mod, animation_blend)
126-
player_anim[name] = ANIM_STAND
127188
end
128189
end
129-
end
130-
minetest.register_globalstep(player_step)
131-
132-
-- END
190+
end)

0 commit comments

Comments
 (0)