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 if get_if_player_attached(player) then
101 hunger = get_player_hunger(player)
102 name = player:get_player_name()
103 temp_pool = pool[name]
106 -- water movement data
107 head = minetest.get_item_group(get_player_head_env(player),"water") > 0
108 legs = minetest.get_item_group(get_player_legs_env(player),"water") > 0
110 in_water = temp_pool.swimming
115 temp_pool.swimming = true
116 elseif temp_pool.swimming == true then
117 swim_unlock = player_swim_under_check(player)
118 swim_bump = player_swim_check(player)
121 temp_pool.swimming = false
122 temp_pool.swim_bumped = minetest.get_us_time()/1000000
123 elseif swim_bump and minetest.get_us_time()/1000000-temp_pool.swim_bumped > 1 then
124 if player:get_player_velocity().y <= 0 then
125 temp_pool.swim_bumped = minetest.get_us_time()/1000000
126 player:add_player_velocity(vector.new(0,9,0))
130 if (in_water ~= temp_pool.was_in_water) or
131 (temp_pool.state ~= temp_pool.old_state) or
132 ((temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6) then
134 if (not in_water and temp_pool.was_in_water) then
135 player:set_physics_override({
139 force_update_animation(player)
141 player:set_properties({
142 collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
144 elseif in_water and not temp_pool.was_in_water then
146 player:set_physics_override({
150 force_update_animation(player)
152 player:set_properties({
153 collisionbox = {-0.3, 0.8, -0.3, 0.3, 1.6, 0.3},
155 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
158 -- running/swimming fov modifier
159 if hunger > 6 and (temp_pool.state == 1 or temp_pool.state == 2) then
160 player:set_fov(1.25, true, 0.15)
162 if temp_pool.state == 2 then
163 player:set_physics_override({speed=1.75})
164 elseif temp_pool.state == 1 then
165 player:set_physics_override({speed=1.5})
168 elseif (not in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and
169 (temp_pool.old_state == 1 or temp_pool.old_state == 2)) or
170 (in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and temp_pool.state ~= 3 and
171 (temp_pool.old_state == 1 or temp_pool.old_state == 2 or temp_pool.old_state == 3))then
173 player:set_fov(1, true,0.15)
174 player:set_physics_override({speed=1})
176 send_running_cancellation(player,temp_pool.state==3) --preserve network data
178 elseif (temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6 then
179 player:set_fov(1, true,0.15)
180 player:set_physics_override({speed=1})
181 send_running_cancellation(player,false) --preserve network data
185 if temp_pool.state == 3 and in_water then
186 --send_running_cancellation(player,false)
187 elseif not in_water and temp_pool.state == 3 and temp_pool.old_state ~= 3 then
188 player:set_eye_offset({x=0,y=-1,z=0},{x=0,y=0,z=0})
189 elseif not in_water and temp_pool.old_state == 3 and temp_pool.state ~= 3 then
190 player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
193 temp_pool.old_state = state
194 temp_pool.was_in_water = in_water
199 if not temp_pool.was_in_water then
200 player:set_physics_override({
204 temp_pool.old_state = temp_pool.old_state
205 temp_pool.was_in_water = in_water
210 minetest.register_globalstep(function(dtime)
211 for _,player in ipairs(minetest.get_connected_players()) do
212 control_state(player)