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 = false
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 = false
34 send_running_cancellation(player,false)
38 -- delete data on player leaving
40 minetest.register_on_leaveplayer(function(player)
41 name = player:get_player_name()
45 -- tells the client to stop sending running/bunnyhop data
47 send_running_cancellation = function(player,sneaking)
48 name = player:get_player_name()
49 state_channels[name]:send_all(
57 -- intercept incoming data messages
58 local channel_decyphered
60 minetest.register_on_modchannel_message(function(channel_name, sender, message)
61 channel_decyphered = channel_name:gsub(sender,"")
62 if sender ~= "" and channel_decyphered == ":player_movement_state" then
63 state = tonumber(message)
64 if type(state) == "number" then
65 pool[sender].state = state
73 -- allows other mods to retrieve data for the game to use
75 get_player_state = function(player)
76 name = player:get_player_name()
77 return(pool[name].state)
80 is_player_swimming = function(player)
81 name = player:get_player_name()
82 return(pool[name].swimming)
85 -- controls player states
94 local control_state = function(player)
95 hunger = get_player_hunger(player)
96 name = player:get_player_name()
97 temp_pool = pool[name]
99 -- water movement data
100 head = minetest.get_item_group(get_player_head_env(player),"water") > 0
101 legs = minetest.get_item_group(get_player_legs_env(player),"water") > 0
106 temp_pool.swimming = true
107 elseif temp_pool.swimming == true then
108 swim_unlock = player_swim_under_check(player)
109 swim_bump = player_swim_check(player)
112 temp_pool.swimming = false
113 elseif swim_bump then
114 if player:get_player_velocity().y <= 0 then
115 player:add_player_velocity(vector.new(0,9,0))
120 if (in_water ~= temp_pool.was_in_water) or
121 (temp_pool.state ~= temp_pool.old_state) or
122 ((temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6) then
124 if (not in_water and temp_pool.was_in_water) then
125 player:set_physics_override({
129 force_update_animation(player)
131 player:set_properties({
132 collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
134 elseif in_water and not temp_pool.was_in_water then
136 player:set_physics_override({
140 force_update_animation(player)
142 player:set_properties({
143 collisionbox = {-0.3, 0.8, -0.3, 0.3, 1.6, 0.3},
145 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
148 -- running/swimming fov modifier
149 if hunger > 6 and (temp_pool.state == 1 or temp_pool.state == 2) then
150 player:set_fov(1.25, true, 0.15)
152 if temp_pool.state == 2 then
153 player:set_physics_override({speed=1.75})
154 elseif temp_pool.state == 1 then
155 player:set_physics_override({speed=1.5})
158 elseif (not in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and
159 (temp_pool.old_state == 1 or temp_pool.old_state == 2)) or
160 (in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and temp_pool.state ~= 3 and
161 (temp_pool.old_state == 1 or temp_pool.old_state == 2 or temp_pool.old_state == 3))then
163 player:set_fov(1, true,0.15)
164 player:set_physics_override({speed=1})
166 send_running_cancellation(player,temp_pool.state==3) --preserve network data
168 elseif (temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6 then
169 player:set_fov(1, true,0.15)
170 player:set_physics_override({speed=1})
171 send_running_cancellation(player,false) --preserve network data
175 if temp_pool.state == 3 and in_water then
176 send_running_cancellation(player,false)
177 elseif not in_water and temp_pool.state == 3 and temp_pool.old_state ~= 3 then
178 player:set_eye_offset({x=0,y=-1,z=0},{x=0,y=-1,z=0})
179 elseif not in_water and temp_pool.old_state == 3 and temp_pool.state ~= 3 then
180 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
183 temp_pool.old_state = state
184 temp_pool.was_in_water = in_water
188 if not temp_pool.was_in_water then
189 player:set_physics_override({
193 temp_pool.old_state = temp_pool.old_state
194 temp_pool.was_in_water = in_water
198 minetest.register_globalstep(function(dtime)
199 for _,player in ipairs(minetest.get_connected_players()) do
200 control_state(player)