aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2010-11-30 15:35:03 +0200
committerPerttu Ahola <celeron55@gmail.com>2010-11-30 15:35:03 +0200
commit38353751c9f4e03fb6a0b855e6d8b5691af71dc0 (patch)
treefb3b6b96b37704382560ed735d26099338853bae
parent4a8973aeac1d44b78e44efde113e5c47bb3a803b (diff)
downloadminetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.tar.gz
minetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.tar.bz2
minetest-38353751c9f4e03fb6a0b855e6d8b5691af71dc0.zip
better water
-rw-r--r--data/water.pngbin103 -> 214 bytes
-rw-r--r--src/constants.h3
-rw-r--r--src/environment.cpp19
-rw-r--r--src/main.cpp22
-rw-r--r--src/map.cpp62
-rw-r--r--src/mapblockobject.cpp4
-rw-r--r--src/mapnode.h28
-rw-r--r--src/mapsector.h2
-rw-r--r--src/player.cpp34
-rw-r--r--src/player.h1
-rw-r--r--src/server.cpp8
11 files changed, 167 insertions, 16 deletions
diff --git a/data/water.png b/data/water.png
index d4457bcba..98cda2776 100644
--- a/data/water.png
+++ b/data/water.png
Binary files differ
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)