1 local minetest,math,vector,ipairs,tonumber = minetest,math,vector,ipairs,tonumber
3 local state_channels = {} -- holds every player's channel
6 -- creates specific channels for players
9 minetest.register_on_joinplayer(function(player)
10 name = player:get_player_name()
12 state_channels[name] = minetest.mod_channel_join(name..":player_movement_state")
13 player:set_physics_override({
19 temp_pool = pool[name]
21 temp_pool.old_state = 0
22 temp_pool.was_in_water = false
23 temp_pool.swimming = false
24 temp_pool.swim_bumped = minetest.get_us_time()/1000000
27 -- resets the player's state on death
29 minetest.register_on_respawnplayer(function(player)
30 name = player:get_player_name()
32 pool[name].was_in_water = false
33 pool[name].swim_bumped = minetest.get_us_time()/1000000
34 send_running_cancellation(player,false)
35 player:set_properties({
36 collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
41 -- delete data on player leaving
43 minetest.register_on_leaveplayer(function(player)
44 name = player:get_player_name()
48 -- tells the client to stop sending running/bunnyhop data
50 send_running_cancellation = function(player,sneaking)
51 name = player:get_player_name()
52 state_channels[name]:send_all(
60 -- intercept incoming data messages
61 local channel_decyphered
63 minetest.register_on_modchannel_message(function(channel_name, sender, message)
64 channel_decyphered = channel_name:gsub(sender,"")
65 if sender ~= "" and channel_decyphered == ":player_movement_state" then
66 state = tonumber(message)
67 if type(state) == "number" then
68 pool[sender].state = state
76 -- allows other mods to retrieve data for the game to use
78 get_player_state = function(player)
79 name = player:get_player_name()
80 return(pool[name].state)
83 is_player_swimming = function(player)
84 name = player:get_player_name()
85 return(pool[name].swimming)
88 -- controls player states
97 local control_state = function(player)
98 hunger = get_player_hunger(player)
99 name = player:get_player_name()
100 temp_pool = pool[name]
103 -- water movement data
104 head = minetest.get_item_group(get_player_head_env(player),"water") > 0
105 legs = minetest.get_item_group(get_player_legs_env(player),"water") > 0
107 in_water = temp_pool.swimming
112 temp_pool.swimming = true
113 elseif temp_pool.swimming == true then
114 swim_unlock = player_swim_under_check(player)
115 swim_bump = player_swim_check(player)
118 temp_pool.swimming = false
119 temp_pool.swim_bumped = minetest.get_us_time()/1000000
120 elseif swim_bump and minetest.get_us_time()/1000000-temp_pool.swim_bumped > 1 then
121 if player:get_player_velocity().y <= 0 then
122 temp_pool.swim_bumped = minetest.get_us_time()/1000000
123 player:add_player_velocity(vector.new(0,9,0))
127 if (in_water ~= temp_pool.was_in_water) or
128 (temp_pool.state ~= temp_pool.old_state) or
129 ((temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6) then
131 if (not in_water and temp_pool.was_in_water) then
132 player:set_physics_override({
136 force_update_animation(player)
138 player:set_properties({
139 collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
141 elseif in_water and not temp_pool.was_in_water then
143 player:set_physics_override({
147 force_update_animation(player)
149 player:set_properties({
150 collisionbox = {-0.3, 0.8, -0.3, 0.3, 1.6, 0.3},
152 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
155 -- running/swimming fov modifier
156 if hunger > 6 and (temp_pool.state == 1 or temp_pool.state == 2) then
157 player:set_fov(1.25, true, 0.15)
159 if temp_pool.state == 2 then
160 player:set_physics_override({speed=1.75})
161 elseif temp_pool.state == 1 then
162 player:set_physics_override({speed=1.5})
165 elseif (not in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and
166 (temp_pool.old_state == 1 or temp_pool.old_state == 2)) or
167 (in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and temp_pool.state ~= 3 and
168 (temp_pool.old_state == 1 or temp_pool.old_state == 2 or temp_pool.old_state == 3))then
170 player:set_fov(1, true,0.15)
171 player:set_physics_override({speed=1})
173 send_running_cancellation(player,temp_pool.state==3) --preserve network data
175 elseif (temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6 then
176 player:set_fov(1, true,0.15)
177 player:set_physics_override({speed=1})
178 send_running_cancellation(player,false) --preserve network data
182 if temp_pool.state == 3 and in_water then
183 --send_running_cancellation(player,false)
184 elseif not in_water and temp_pool.state == 3 and temp_pool.old_state ~= 3 then
185 player:set_eye_offset({x=0,y=-1,z=0},{x=0,y=0,z=0})
186 elseif not in_water and temp_pool.old_state == 3 and temp_pool.state ~= 3 then
187 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
190 temp_pool.old_state = state
191 temp_pool.was_in_water = in_water
196 if not temp_pool.was_in_water then
197 player:set_physics_override({
201 temp_pool.old_state = temp_pool.old_state
202 temp_pool.was_in_water = in_water
207 minetest.register_globalstep(function(dtime)
208 for _,player in ipairs(minetest.get_connected_players()) do
209 control_state(player)