Permalink
Browse files

Improved Player Physics

  • Loading branch information...
MirceaKitsune authored and darkrose committed Feb 8, 2013
1 parent 86b906d commit df3c925b3ccae3bdba125e6dc3ecc740739baeab
Showing with 296 additions and 110 deletions.
  1. +15 −0 minetest.conf.example
  2. +20 −0 src/client.cpp
  3. +17 −0 src/clientserver.h
  4. +14 −0 src/defaultsettings.cpp
  5. +29 −12 src/environment.cpp
  6. +101 −85 src/localplayer.cpp
  7. +50 −8 src/player.cpp
  8. +20 −5 src/player.h
  9. +29 −0 src/server.cpp
  10. +1 −0 src/server.h
View
@@ -245,6 +245,21 @@
# Files that are not present would be fetched the usual way
#remote_media =
+# Physics stuff
+#movement_acceleration_default = 2
+#movement_acceleration_air = 0.5
+#movement_acceleration_fast = 4
+#movement_speed_walk = 4
+#movement_speed_crouch = 1.35
+#movement_speed_fast = 20
+#movement_speed_climb = 2
+#movement_speed_jump = 6.5
+#movement_speed_descend = 6
+#movement_liquid_fluidity = 1
+#movement_liquid_fluidity_smooth = 0.5
+#movement_liquid_sink = 10
+#movement_gravity = 9.81
+
# Mapgen stuff
#mg_name = v6
#water_level = 1
View
@@ -1514,6 +1514,26 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
}
}
}
+ else if(command == TOCLIENT_MOVEMENT)
+ {
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+ Player *player = m_env.getLocalPlayer();
+ assert(player != NULL);
+
+ player->movement_acceleration_default = readF1000(is) * BS;
+ player->movement_acceleration_air = readF1000(is) * BS;
+ player->movement_acceleration_fast = readF1000(is) * BS;
+ player->movement_speed_walk = readF1000(is) * BS;
+ player->movement_speed_crouch = readF1000(is) * BS;
+ player->movement_speed_fast = readF1000(is) * BS;
+ player->movement_speed_climb = readF1000(is) * BS;
+ player->movement_speed_jump = readF1000(is) * BS;
+ player->movement_liquid_fluidity = readF1000(is) * BS;
+ player->movement_liquid_fluidity_smooth = readF1000(is) * BS;
+ player->movement_liquid_sink = readF1000(is) * BS;
+ player->movement_gravity = readF1000(is) * BS;
+ }
else if(command == TOCLIENT_HP)
{
std::string datastring((char*)&data[2], datasize-2);
View
@@ -364,6 +364,23 @@ enum ToClientCommand
u16 len
u8[len] formname
*/
+
+ TOCLIENT_MOVEMENT = 0x45,
+ /*
+ u16 command
+ f1000 movement_acceleration_default
+ f1000 movement_acceleration_air
+ f1000 movement_acceleration_fast
+ f1000 movement_speed_walk
+ f1000 movement_speed_crouch
+ f1000 movement_speed_fast
+ f1000 movement_speed_climb
+ f1000 movement_speed_jump
+ f1000 movement_liquid_fluidity
+ f1000 movement_liquid_fluidity_smooth
+ f1000 movement_liquid_sink
+ f1000 movement_gravity
+ */
};
enum ToServerCommand
View
@@ -172,6 +172,20 @@ void set_default_settings(Settings *settings)
settings->setDefault("congestion_control_max_rate", "400");
settings->setDefault("congestion_control_min_rate", "10");
settings->setDefault("remote_media", "");
+
+ // physics stuff
+ settings->setDefault("movement_acceleration_default", "2");
+ settings->setDefault("movement_acceleration_air", "0.5");
+ settings->setDefault("movement_acceleration_fast", "8");
+ settings->setDefault("movement_speed_walk", "4");
+ settings->setDefault("movement_speed_crouch", "1.35");
+ settings->setDefault("movement_speed_fast", "20");
+ settings->setDefault("movement_speed_climb", "2");
+ settings->setDefault("movement_speed_jump", "6.5");
+ settings->setDefault("movement_liquid_fluidity", "1");
+ settings->setDefault("movement_liquid_fluidity_smooth", "0.5");
+ settings->setDefault("movement_liquid_sink", "10");
+ settings->setDefault("movement_gravity", "9.81");
//mapgen related things
settings->setDefault("mg_name", "v6");
View
@@ -2065,20 +2065,37 @@ void ClientEnvironment::step(float dtime)
{
// Gravity
v3f speed = lplayer->getSpeed();
- if(lplayer->swimming_up == false)
- speed.Y -= 9.81 * BS * dtime_part * 2;
+ if(lplayer->in_liquid == false)
+ speed.Y -= lplayer->movement_gravity * dtime_part * 2;
- // Water resistance
- if(lplayer->in_water_stable || lplayer->in_water)
- {
- f32 max_down = 2.0*BS;
- if(speed.Y < -max_down) speed.Y = -max_down;
+ // Liquid floating / sinking
+ if(lplayer->in_liquid && !lplayer->swimming_vertical)
+ speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2;
- f32 max = 2.5*BS;
- if(speed.getLength() > max)
- {
- speed = speed / speed.getLength() * max;
- }
+ // Liquid resistance
+ if(lplayer->in_liquid_stable || lplayer->in_liquid)
+ {
+ // How much the node's viscosity blocks movement, ranges between 0 and 1
+ // Should match the scale at which viscosity increase affects other liquid attributes
+ const f32 viscosity_factor = 0.3;
+
+ v3f d_wanted = -speed / lplayer->movement_liquid_fluidity;
+ f32 dl = d_wanted.getLength();
+ if(dl > lplayer->movement_liquid_fluidity_smooth)
+ dl = lplayer->movement_liquid_fluidity_smooth;
+ dl *= (lplayer->liquid_viscosity * viscosity_factor) + (1 - viscosity_factor);
+
+ v3f d = d_wanted.normalize() * dl;
+ speed += d;
+
+#if 0 // old code
+ if(speed.X > lplayer->movement_liquid_fluidity + lplayer->movement_liquid_fluidity_smooth) speed.X -= lplayer->movement_liquid_fluidity_smooth;
+ if(speed.X < -lplayer->movement_liquid_fluidity - lplayer->movement_liquid_fluidity_smooth) speed.X += lplayer->movement_liquid_fluidity_smooth;
+ if(speed.Y > lplayer->movement_liquid_fluidity + lplayer->movement_liquid_fluidity_smooth) speed.Y -= lplayer->movement_liquid_fluidity_smooth;
+ if(speed.Y < -lplayer->movement_liquid_fluidity - lplayer->movement_liquid_fluidity_smooth) speed.Y += lplayer->movement_liquid_fluidity_smooth;
+ if(speed.Z > lplayer->movement_liquid_fluidity + lplayer->movement_liquid_fluidity_smooth) speed.Z -= lplayer->movement_liquid_fluidity_smooth;
+ if(speed.Z < -lplayer->movement_liquid_fluidity - lplayer->movement_liquid_fluidity_smooth) speed.Z += lplayer->movement_liquid_fluidity_smooth;
+#endif
}
lplayer->setSpeed(speed);
Oops, something went wrong.

0 comments on commit df3c925

Please sign in to comment.