diff options
author | Perttu Ahola <celeron55@gmail.com> | 2010-11-30 15:35:03 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2010-11-30 15:35:03 +0200 |
commit | 38353751c9f4e03fb6a0b855e6d8b5691af71dc0 (patch) | |
tree | fb3b6b96b37704382560ed735d26099338853bae | |
parent | 4a8973aeac1d44b78e44efde113e5c47bb3a803b (diff) | |
download | minetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.tar.gz minetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.tar.bz2 minetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.zip |
better water
-rw-r--r-- | data/water.png | bin | 103 -> 214 bytes | |||
-rw-r--r-- | src/constants.h | 3 | ||||
-rw-r--r-- | src/environment.cpp | 19 | ||||
-rw-r--r-- | src/main.cpp | 22 | ||||
-rw-r--r-- | src/map.cpp | 62 | ||||
-rw-r--r-- | src/mapblockobject.cpp | 4 | ||||
-rw-r--r-- | src/mapnode.h | 28 | ||||
-rw-r--r-- | src/mapsector.h | 2 | ||||
-rw-r--r-- | src/player.cpp | 34 | ||||
-rw-r--r-- | src/player.h | 1 | ||||
-rw-r--r-- | src/server.cpp | 8 |
11 files changed, 167 insertions, 16 deletions
diff --git a/data/water.png b/data/water.png Binary files differindex d4457bcba..98cda2776 100644 --- a/data/water.png +++ b/data/water.png diff --git a/src/constants.h b/src/constants.h index 84adfa79c..d59597774 100644 --- a/src/constants.h +++ b/src/constants.h @@ -85,5 +85,8 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #define MAX_OBJECTDATA_SIZE 450 +//#define WATER_LEVEL (-5) +#define WATER_LEVEL (0) + #endif diff --git a/src/environment.cpp b/src/environment.cpp index c76721a77..2d7590f1a 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -101,11 +101,28 @@ void Environment::step(float dtime) { Player *player = *i; - // Apply gravity to local player + // Apply physics to local player if(player->isLocal()) { + // Apply gravity to local player v3f speed = player->getSpeed(); speed.Y -= 9.81 * BS * dtime_part * 2; + + /* + Apply water resistance + */ + if(player->in_water) + { + f32 max_down = 1.0*BS; + if(speed.Y < -max_down) speed.Y = -max_down; + + f32 max = 2.0*BS; + if(speed.getLength() > max) + { + speed = speed / speed.getLength() * max; + } + } + player->setSpeed(speed); } diff --git a/src/main.cpp b/src/main.cpp index a2185450f..677f03843 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -167,6 +167,12 @@ TODO: Check what goes wrong with caching map to disk (Kray) TODO: Remove LazyMeshUpdater. It is not used as supposed.
+FIXME: Rats somehow go underground sometimes (you can see it in water)
+ - Does their position get saved to a border value or something?
+
+TODO: MovingObject::move and Player::move are basically the same.
+ combine them.
+
Doing now:
======================================================================
@@ -1013,6 +1019,19 @@ int main(int argc, char *argv[]) */
std::cout<<std::endl<<std::endl;
+
+ std::cout
+ <<" .__ __ __ "<<std::endl
+ <<" _____ |__| ____ _____/ |_ ____ _______/ |_ "<<std::endl
+ <<" / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\"<<std::endl
+ <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl
+ <<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl
+ <<" \\/ \\/ \\/ \\/ \\/ "<<std::endl
+ <<std::endl
+ <<"Now with more waterish water!"
+ <<std::endl;
+
+ std::cout<<std::endl;
char templine[100];
// Dedicated?
@@ -1830,9 +1849,8 @@ int main(int argc, char *argv[]) for(s16 x = xstart; x <= xend; x++)
{
try{
- if(client.getNode(v3s16(x,y,z)).d == MATERIAL_AIR){
+ if(material_pointable(client.getNode(v3s16(x,y,z)).d) == false)
continue;
- }
}catch(InvalidPositionException &e){
continue;
}
diff --git a/src/map.cpp b/src/map.cpp index 900c1e98c..050299bc9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1046,7 +1046,67 @@ void Map::removeNodeAndUpdate(v3s16 p, bool node_under_sunlight = true; v3s16 toppos = p + v3s16(0,1,0); + + // Node will be replaced with this + u8 replace_material = MATERIAL_AIR; + { + /* + Find out with what material the node will be replaced. + It will be replaced with the mostly seen buildable_to. + */ + + v3s16 dirs[6] = { + v3s16(0,0,1), // back + v3s16(0,1,0), // top + v3s16(1,0,0), // right + v3s16(0,0,-1), // front + v3s16(0,-1,0), // bottom + v3s16(-1,0,0), // left + }; + + core::map<u8, u16> neighbor_rankings; + + for(u32 i=0; i<sizeof(dirs)/sizeof(dirs[0]); i++) + { + try{ + MapNode n2 = getNode(p + dirs[i]); + + if(material_buildable_to(n2.d)) + { + if(neighbor_rankings.find(n2.d) == NULL) + neighbor_rankings[n2.d] = 1; + else + neighbor_rankings[n2.d] + = neighbor_rankings[n2.d] + 1; + } + } + catch(InvalidPositionException &e) + { + } + } + + u16 highest_ranking = 0; + + for(core::map<u8, u16>::Iterator + i = neighbor_rankings.getIterator(); + i.atEnd() == false; i++) + { + u8 m = i.getNode()->getKey(); + u8 c = i.getNode()->getValue(); + if( + c > highest_ranking || + // Prefer something else than air + (c >= highest_ranking && m != MATERIAL_AIR) + + ) + { + replace_material = m; + highest_ranking = c; + } + } + } + /* If there is a node at top and it doesn't have sunlight, there will be no sunlight going down. @@ -1073,7 +1133,7 @@ void Map::removeNodeAndUpdate(v3s16 p, Remove the node */ MapNode n; - n.d = MATERIAL_AIR; + n.d = replace_material; n.setLight(0); setNode(p, n); diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp index 1fda9baed..3a28e2250 100644 --- a/src/mapblockobject.cpp +++ b/src/mapblockobject.cpp @@ -145,9 +145,9 @@ void MovingObject::move(float dtime, v3f acceleration) for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++) { try{ - if(m_block->getNodeParent(v3s16(x,y,z)).d == MATERIAL_AIR){ + if(material_walkable(m_block->getNodeParent(v3s16(x,y,z)).d) + == false) continue; - } } catch(InvalidPositionException &e) { diff --git a/src/mapnode.h b/src/mapnode.h index 910239136..789cedb27 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -133,6 +133,34 @@ inline u8 material_solidness(u8 m) return 2; } +// Objects collide with walkable materials +inline bool material_walkable(u8 m) +{ + return (m != MATERIAL_AIR && m != MATERIAL_WATER); +} + +// A liquid resists fast movement +inline bool material_liquid(u8 m) +{ + return (m == MATERIAL_WATER); +} + +// Pointable materials can be pointed to in the map +inline bool material_pointable(u8 m) +{ + return (m != MATERIAL_AIR && m != MATERIAL_WATER); +} + +inline bool material_diggable(u8 m) +{ + return (m != MATERIAL_AIR && m != MATERIAL_WATER); +} + +inline bool material_buildable_to(u8 m) +{ + return (m == MATERIAL_AIR || m == MATERIAL_WATER); +} + /* Nodes make a face if materials differ and solidness differs. Return value: diff --git a/src/mapsector.h b/src/mapsector.h index ad6161bdf..d5ffa7f1d 100644 --- a/src/mapsector.h +++ b/src/mapsector.h @@ -34,8 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., This is an Y-wise stack of MapBlocks. */ -#define WATER_LEVEL (-5) - #define SECTOR_OBJECT_TEST 0 #define SECTOR_OBJECT_TREE_1 1 #define SECTOR_OBJECT_BUSH_1 2 diff --git a/src/player.cpp b/src/player.cpp index c3e14fc90..5e838bf7a 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Player::Player(): touching_ground(false), + in_water(false), inventory(PLAYER_INVENTORY_SIZE), peer_id(PEER_ID_NEW), m_speed(0,0,0), @@ -64,6 +65,26 @@ void Player::move(f32 dtime, Map &map) v3s16 pos_i = floatToInt(position); + /* + Check if player is in water + */ + try{ + if(in_water) + { + v3s16 pp = floatToInt(position + v3f(0,0,0)); + in_water = material_liquid(map.getNode(pp).d); + } + else + { + v3s16 pp = floatToInt(position + v3f(0,BS/2,0)); + in_water = material_liquid(map.getNode(pp).d); + } + } + catch(InvalidPositionException &e) + { + in_water = false; + } + // The frame length is limited to the player going 0.1*BS per call f32 d = (float)BS * 0.15; @@ -100,10 +121,8 @@ void Player::move(f32 dtime, Map &map) for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++){ for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++){ for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++){ - //std::cout<<"with ("<<x<<","<<y<<","<<z<<"): "; try{ - if(map.getNode(v3s16(x,y,z)).d == MATERIAL_AIR){ - //std::cout<<"air."<<std::endl; + if(material_walkable(map.getNode(v3s16(x,y,z)).d) == false){ continue; } } @@ -355,11 +374,18 @@ void LocalPlayer::applyControl(float dtime) } if(control.jump) { - if(touching_ground){ + if(touching_ground) + { v3f speed = getSpeed(); speed.Y = 6.5*BS; setSpeed(speed); } + else if(in_water) + { + v3f speed = getSpeed(); + speed.Y = 2.0*BS; + setSpeed(speed); + } } // The speed of the player (Y is ignored) diff --git a/src/player.h b/src/player.h index 82ed92649..91ad99911 100644 --- a/src/player.h +++ b/src/player.h @@ -95,6 +95,7 @@ public: virtual bool isLocal() const = 0; bool touching_ground; + bool in_water; Inventory inventory; diff --git a/src/server.cpp b/src/server.cpp index 2d2e9e22d..f8248acb4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1419,8 +1419,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) { // Get material at position material = m_env.getMap().getNode(p_under).d; - // If it's air, do nothing - if(material == MATERIAL_AIR) + // If it's not diggable, do nothing + if(material_diggable(material) == false) { return; } @@ -1484,9 +1484,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) n.d = mitem->getMaterial(); try{ - // Don't add a node if there isn't air + // Don't add a node if this is not a free space MapNode n2 = m_env.getMap().getNode(p_over); - if(n2.d != MATERIAL_AIR) + if(material_buildable_to(n2.d) == false) return; } catch(InvalidPositionException &e) |