old water removed, some fixes here and there

This commit is contained in:
Perttu Ahola 2011-01-17 14:57:37 +02:00
parent bd26be262d
commit 0fa0e0752a
19 changed files with 276 additions and 277 deletions

@ -201,14 +201,18 @@ public:
{ {
JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
v3s16 blockpos = ((ClientMap&)m_env.getMap()).setTempMod(p, mod); bool changed = false;
v3s16 blockpos = ((ClientMap&)m_env.getMap()).setTempMod(p, mod, &changed);
if(changed)
m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio()); m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
} }
void clearTempMod(v3s16 p) void clearTempMod(v3s16 p)
{ {
JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
v3s16 blockpos = ((ClientMap&)m_env.getMap()).clearTempMod(p); bool changed = false;
v3s16 blockpos = ((ClientMap&)m_env.getMap()).clearTempMod(p, &changed);
if(changed)
m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio()); m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
} }

@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Cross-platform compatibility crap should go in porting.h. Cross-platform compatibility crap should go in porting.h.
*/ */
#define HAXMODE 0 //#define HAXMODE 0
#define APPNAME "minetest" #define APPNAME "minetest"
@ -52,6 +52,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// The absolute working limit is (2^15 - viewing_range). // The absolute working limit is (2^15 - viewing_range).
#define MAP_GENERATION_LIMIT (31000) #define MAP_GENERATION_LIMIT (31000)
// Size of node in rendering units
#define BS 10
#define MAP_BLOCKSIZE 16
/*
This makes mesh updates too slow, as many meshes are updated during
the main loop (related to TempMods and day/night)
*/
//#define MAP_BLOCKSIZE 32
// Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps
#define SECTOR_HEIGHTMAP_SPLIT (MAP_BLOCKSIZE/8)
// Time after building, during which the following limit // Time after building, during which the following limit
// is in use // is in use
//#define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0 //#define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0
@ -61,15 +74,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// is very low // is very low
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1 #define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
// Viewing range stuff // The fps limiter will leave this much free time
//#define FREETIME_RATIO 0.15 //#define FREETIME_RATIO 0.15
//#define FREETIME_RATIO 0.0 //#define FREETIME_RATIO 0.0
#define FREETIME_RATIO 0.05 #define FREETIME_RATIO 0.05
// Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps
#define SECTOR_HEIGHTMAP_SPLIT 2
#define PLAYER_INVENTORY_SIZE (8*4) #define PLAYER_INVENTORY_SIZE (8*4)
#define SIGN_TEXT_MAX_LENGTH 50 #define SIGN_TEXT_MAX_LENGTH 50

@ -40,6 +40,7 @@ void set_default_settings()
// Server stuff // Server stuff
g_settings.setDefault("creative_mode", "false"); g_settings.setDefault("creative_mode", "false");
g_settings.setDefault("haxmode", "false");
/*g_settings.setDefault("heightmap_blocksize", "32"); /*g_settings.setDefault("heightmap_blocksize", "32");
g_settings.setDefault("height_randmax", "constant 45.0"); g_settings.setDefault("height_randmax", "constant 45.0");
g_settings.setDefault("height_randfactor", "constant 0.6"); g_settings.setDefault("height_randfactor", "constant 0.6");
@ -63,7 +64,7 @@ void set_default_settings()
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4"); g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
g_settings.setDefault("water_moves", "true"); g_settings.setDefault("water_moves", "true");
g_settings.setDefault("disable_water_climb", "true"); g_settings.setDefault("disable_water_climb", "true");
g_settings.setDefault("endless_water", "true"); //g_settings.setDefault("endless_water", "true");
g_settings.setDefault("max_block_send_distance", "6"); g_settings.setDefault("max_block_send_distance", "6");
g_settings.setDefault("max_block_generate_distance", "6"); g_settings.setDefault("max_block_generate_distance", "6");
g_settings.setDefault("time_send_interval", "20"); g_settings.setDefault("time_send_interval", "20");

@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "environment.h" #include "environment.h"
#include "main.h" // g_device for timing debug
Environment::Environment(Map *map, std::ostream &dout): Environment::Environment(Map *map, std::ostream &dout):
m_dout(dout) m_dout(dout)
@ -107,7 +106,8 @@ void Environment::step(float dtime)
v3f playerpos = player->getPosition(); v3f playerpos = player->getPosition();
// Apply physics to local player // Apply physics to local player
if(player->isLocal() && HAXMODE == false) bool haxmode = g_settings.getBool("haxmode");
if(player->isLocal() && haxmode == false)
{ {
// Apply gravity to local player // Apply gravity to local player
v3f speed = player->getSpeed(); v3f speed = player->getSpeed();

@ -207,6 +207,8 @@ TODO: Map generator version 2
- Separate points for heightmap, caves, plants and minerals? - Separate points for heightmap, caves, plants and minerals?
- Flat land, mountains, forest, jungle - Flat land, mountains, forest, jungle
- Cliffs, arcs - Cliffs, arcs
- There could be a certain height (to which mountains only reach)
where some minerals are found
Doing now: Doing now:
====================================================================== ======================================================================

@ -35,8 +35,7 @@ Map::Map(std::ostream &dout):
m_camera_position(0,0,0), m_camera_position(0,0,0),
m_camera_direction(0,0,1), m_camera_direction(0,0,1),
m_sector_cache(NULL), m_sector_cache(NULL),
m_hwrapper(this), m_hwrapper(this)
drawoffset(0,0,0)
{ {
m_sector_mutex.Init(); m_sector_mutex.Init();
m_camera_mutex.Init(); m_camera_mutex.Init();
@ -1236,7 +1235,7 @@ void Map::deleteSectors(core::list<v2s16> &list, bool only_blocks)
This disables the existence of caches while locked This disables the existence of caches while locked
*/ */
SharedPtr<JMutexAutoLock> cachelock(m_blockcachelock.waitCaches()); //SharedPtr<JMutexAutoLock> cachelock(m_blockcachelock.waitCaches());
core::list<v2s16>::Iterator j; core::list<v2s16>::Iterator j;
for(j=list.begin(); j!=list.end(); j++) for(j=list.begin(); j!=list.end(); j++)
@ -1723,7 +1722,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
//hm->generateContinued(0.5, 0.2, corners); //hm->generateContinued(0.5, 0.2, corners);
//hm->generateContinued(1.0, 0.2, corners); //hm->generateContinued(1.0, 0.2, corners);
//hm->generateContinued(2.0, 0.2, corners); //hm->generateContinued(2.0, 0.2, corners);
hm->generateContinued(2.0 * avgslope, 0.5, corners); //hm->generateContinued(2.0 * avgslope, 0.5, corners);
hm->generateContinued(avgslope * MAP_BLOCKSIZE/8, 0.5, corners);
//hm->print(); //hm->print();
} }
@ -1735,6 +1735,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
core::map<v3s16, u8> *objects = new core::map<v3s16, u8>; core::map<v3s16, u8> *objects = new core::map<v3s16, u8>;
sector->setObjects(objects); sector->setObjects(objects);
float area = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
/* /*
Plant some trees if there is not much slope Plant some trees if there is not much slope
*/ */
@ -1742,7 +1744,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
// Avgslope is the derivative of a hill // Avgslope is the derivative of a hill
//float t = avgslope * avgslope; //float t = avgslope * avgslope;
float t = avgslope; float t = avgslope;
float a = MAP_BLOCKSIZE * m_params.plants_amount * local_plants_amount; float a = area/16 * m_params.plants_amount * local_plants_amount;
u32 tree_max; u32 tree_max;
//float something = 0.17*0.17; //float something = 0.17*0.17;
float something = 0.3; float something = 0.3;
@ -1770,7 +1772,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
{ {
// Pitness usually goes at around -0.5...0.5 // Pitness usually goes at around -0.5...0.5
u32 bush_max = 0; u32 bush_max = 0;
u32 a = MAP_BLOCKSIZE * 3.0 * m_params.plants_amount * local_plants_amount; u32 a = area/16 * 3.0 * m_params.plants_amount * local_plants_amount;
if(pitness > 0) if(pitness > 0)
bush_max = (pitness*a*4); bush_max = (pitness*a*4);
if(bush_max > a) if(bush_max > a)
@ -1910,9 +1912,10 @@ MapBlock * ServerMap::emergeBlock(
block->unDummify(); block->unDummify();
} }
u8 water_material = CONTENT_WATER; /*u8 water_material = CONTENT_WATER;
if(g_settings.getBool("endless_water")) if(g_settings.getBool("endless_water"))
water_material = CONTENT_OCEAN; water_material = CONTENT_WATERSOURCE;*/
u8 water_material = CONTENT_WATERSOURCE;
s32 lowest_ground_y = 32767; s32 lowest_ground_y = 32767;
s32 highest_ground_y = -32768; s32 highest_ground_y = -32768;
@ -2732,7 +2735,8 @@ continue_generating:
/* /*
Debug mode operation Debug mode operation
*/ */
if(HAXMODE) bool haxmode = g_settings.getBool("haxmode");
if(haxmode)
{ {
// Don't calculate lighting at all // Don't calculate lighting at all
lighting_invalidated_blocks.clear(); lighting_invalidated_blocks.clear();
@ -3624,7 +3628,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
<<", rendered "<<vertex_count<<" vertices."<<std::endl;*/ <<", rendered "<<vertex_count<<" vertices."<<std::endl;*/
} }
v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod) v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod, bool *changed)
{ {
/* /*
Add it to all blocks touching it Add it to all blocks touching it
@ -3648,11 +3652,15 @@ v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod)
continue; continue;
// Relative position of requested node // Relative position of requested node
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
blockref->setTempMod(relpos, mod); if(blockref->setTempMod(relpos, mod))
{
if(changed != NULL)
*changed = true;
}
} }
return getNodeBlockPos(p); return getNodeBlockPos(p);
} }
v3s16 ClientMap::clearTempMod(v3s16 p) v3s16 ClientMap::clearTempMod(v3s16 p, bool *changed)
{ {
v3s16 dirs[7] = { v3s16 dirs[7] = {
v3s16(0,0,0), // this v3s16(0,0,0), // this
@ -3673,7 +3681,11 @@ v3s16 ClientMap::clearTempMod(v3s16 p)
continue; continue;
// Relative position of requested node // Relative position of requested node
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
blockref->clearTempMod(relpos); if(blockref->clearTempMod(relpos))
{
if(changed != NULL)
*changed = true;
}
} }
return getNodeBlockPos(p); return getNodeBlockPos(p);
} }

141
src/map.h

@ -41,110 +41,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h" #include "constants.h"
#include "voxel.h" #include "voxel.h"
class CacheLock
{
public:
CacheLock()
{
m_count = 0;
m_count_mutex.Init();
m_cache_mutex.Init();
m_waitcache_mutex.Init();
}
void cacheCreated()
{
//dstream<<"cacheCreated() begin"<<std::endl;
JMutexAutoLock waitcachelock(m_waitcache_mutex);
JMutexAutoLock countlock(m_count_mutex);
// If this is the first cache, grab the cache lock
if(m_count == 0)
m_cache_mutex.Lock();
m_count++;
//dstream<<"cacheCreated() end"<<std::endl;
}
void cacheRemoved()
{
//dstream<<"cacheRemoved() begin"<<std::endl;
JMutexAutoLock countlock(m_count_mutex);
assert(m_count > 0);
m_count--;
// If this is the last one, release the cache lock
if(m_count == 0)
m_cache_mutex.Unlock();
//dstream<<"cacheRemoved() end"<<std::endl;
}
/*
This lock should be taken when removing stuff that can be
pointed by the cache.
You'll want to grab this in a SharedPtr.
*/
JMutexAutoLock * waitCaches()
{
//dstream<<"waitCaches() begin"<<std::endl;
JMutexAutoLock waitcachelock(m_waitcache_mutex);
JMutexAutoLock *lock = new JMutexAutoLock(m_cache_mutex);
//dstream<<"waitCaches() end"<<std::endl;
return lock;
}
private:
// Count of existing caches
u32 m_count;
JMutex m_count_mutex;
// This is locked always when there are some caches
JMutex m_cache_mutex;
// Locked so that when waitCaches() is called, no more caches are created
JMutex m_waitcache_mutex;
};
#define MAPTYPE_BASE 0 #define MAPTYPE_BASE 0
#define MAPTYPE_SERVER 1 #define MAPTYPE_SERVER 1
#define MAPTYPE_CLIENT 2 #define MAPTYPE_CLIENT 2
class Map : public NodeContainer, public Heightmappish class Map : public NodeContainer, public Heightmappish
{ {
protected:
std::ostream &m_dout;
core::map<v2s16, MapSector*> m_sectors;
JMutex m_sector_mutex;
v3f m_camera_position;
v3f m_camera_direction;
JMutex m_camera_mutex;
// Be sure to set this to NULL when the cached sector is deleted
MapSector *m_sector_cache;
v2s16 m_sector_cache_p;
WrapperHeightmap m_hwrapper;
public: public:
v3s16 drawoffset; // for drawbox()
/*
Used by MapBlockPointerCache.
waitCaches() can be called to remove all caches before continuing
TODO: Remove this, MapBlockPointerCache doesn't exist anymore,
because it doesn't give any speed benefits
*/
CacheLock m_blockcachelock;
Map(std::ostream &dout); Map(std::ostream &dout);
virtual ~Map(); virtual ~Map();
@ -170,23 +74,6 @@ public:
m_camera_direction = dir; m_camera_direction = dir;
} }
/*void StartUpdater()
{
updater.Start();
}
void StopUpdater()
{
updater.setRun(false);
while(updater.IsRunning())
sleep_s(1);
}
bool UpdaterIsRunning()
{
return updater.IsRunning();
}*/
static core::aabbox3d<f32> getNodeBox(v3s16 p) static core::aabbox3d<f32> getNodeBox(v3s16 p)
{ {
return core::aabbox3d<f32>( return core::aabbox3d<f32>(
@ -349,6 +236,30 @@ public:
// For debug printing // For debug printing
virtual void PrintInfo(std::ostream &out); virtual void PrintInfo(std::ostream &out);
/*
Variables
*/
protected:
std::ostream &m_dout;
core::map<v2s16, MapSector*> m_sectors;
JMutex m_sector_mutex;
v3f m_camera_position;
v3f m_camera_direction;
JMutex m_camera_mutex;
// Be sure to set this to NULL when the cached sector is deleted
MapSector *m_sector_cache;
v2s16 m_sector_cache_p;
WrapperHeightmap m_hwrapper;
// Queued transforming water nodes
UniqueQueue<v3s16> m_transforming_liquid;
}; };
// Master heightmap parameters // Master heightmap parameters
@ -572,8 +483,8 @@ public:
drawing. drawing.
Return value is position of changed block. Return value is position of changed block.
*/ */
v3s16 setTempMod(v3s16 p, NodeMod mod); v3s16 setTempMod(v3s16 p, NodeMod mod, bool *changed=NULL);
v3s16 clearTempMod(v3s16 p); v3s16 clearTempMod(v3s16 p, bool *changed=NULL);
// Efficient implementation needs a cache of TempMods // Efficient implementation needs a cache of TempMods
//void clearTempMods(); //void clearTempMods();

@ -570,8 +570,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
} }
#endif #endif
// 4-21ms // 4-21ms for MAP_BLOCKSIZE=16
//TimeTaker timer1("updateMesh()", g_device); // 24-155ms for MAP_BLOCKSIZE=32
//TimeTaker timer1("updateMesh()");
core::array<FastFace> fastfaces_new; core::array<FastFace> fastfaces_new;
@ -691,7 +692,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
// This will lead to infinite memory usage because or irrlicht. // This will lead to infinite memory usage because or irrlicht.
//mesh_new->setHardwareMappingHint(scene::EHM_STATIC); //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces " /*std::cout<<"MapBlock has "<<fastfaces_new.size()<<" faces "
<<"and uses "<<mesh_new->getMeshBufferCount() <<"and uses "<<mesh_new->getMeshBufferCount()
<<" materials (meshbuffers)"<<std::endl;*/ <<" materials (meshbuffers)"<<std::endl;*/
} }
@ -906,12 +907,12 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
else else
{ {
MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z)); MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
if(n.d == CONTENT_WATER || n.d == CONTENT_OCEAN) if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
{ {
no_sunlight = true; no_sunlight = true;
} }
} }
// NOTE: As of now, it just would make everything dark. // NOTE: As of now, this just would make everything dark.
// No sunlight here // No sunlight here
//no_sunlight = true; //no_sunlight = true;
} }

@ -32,8 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblockobject.h" #include "mapblockobject.h"
#include "voxel.h" #include "voxel.h"
#define MAP_BLOCKSIZE 16
// Named by looking towards z+ // Named by looking towards z+
enum{ enum{
FACE_BACK=0, FACE_BACK=0,
@ -64,6 +62,10 @@ struct NodeMod
type = a_type; type = a_type;
param = a_param; param = a_param;
} }
bool operator==(const NodeMod &other)
{
return (type == other.type && param == other.param);
}
enum NodeModType type; enum NodeModType type;
u16 param; u16 param;
}; };
@ -393,8 +395,10 @@ public:
/* /*
Methods for setting temporary modifications to nodes for Methods for setting temporary modifications to nodes for
drawing drawing
returns true if the mod was different last time
*/ */
void setTempMod(v3s16 p, NodeMod mod) bool setTempMod(v3s16 p, NodeMod mod)
{ {
/*dstream<<"setTempMod called on block" /*dstream<<"setTempMod called on block"
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@ -402,7 +406,18 @@ public:
<<", mod.param="<<mod.param <<", mod.param="<<mod.param
<<std::endl;*/ <<std::endl;*/
JMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
// See if old is different, cancel if it is not different.
core::map<v3s16, NodeMod>::Node *n = m_temp_mods.find(p);
if(n)
{
NodeMod old = n->getValue();
if(old == mod)
return false;
}
m_temp_mods[p] = mod; m_temp_mods[p] = mod;
return true;
} }
// Returns true if there was one // Returns true if there was one
bool getTempMod(v3s16 p, struct NodeMod *mod) bool getTempMod(v3s16 p, struct NodeMod *mod)
@ -416,16 +431,23 @@ public:
*mod = n->getValue(); *mod = n->getValue();
return true; return true;
} }
void clearTempMod(v3s16 p) bool clearTempMod(v3s16 p)
{ {
JMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
if(m_temp_mods.find(p)) if(m_temp_mods.find(p))
{
m_temp_mods.remove(p); m_temp_mods.remove(p);
return true;
} }
void clearTempMods() return false;
}
bool clearTempMods()
{ {
JMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
if(m_temp_mods.size() == 0)
return false;
m_temp_mods.clear(); m_temp_mods.clear();
return true;
} }
#endif #endif

@ -42,7 +42,7 @@ u16 g_content_tiles[USEFUL_CONTENT_COUNT][6] =
{TILE_GRASS_FOOTSTEPS,TILE_MUD,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS}, {TILE_GRASS_FOOTSTEPS,TILE_MUD,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS},
{TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE}, {TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE},
{TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD}, {TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
{TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER}, {TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER}, // ocean
{TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD}, {TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD},
{TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE}, {TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE},
{TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD}, {TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD},
@ -63,7 +63,7 @@ const char * g_content_inventory_texture_paths_base[USEFUL_CONTENT_COUNT] =
"grass_footsteps.png", "grass_footsteps.png",
"mese.png", "mese.png",
"mud.png", "mud.png",
"water.png", "water.png", //ocean
"cloud.png", "cloud.png",
"coalstone.png", "coalstone.png",
"wood.png", "wood.png",

@ -28,9 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h" #include "serialization.h"
#include "tile.h" #include "tile.h"
// Size of node in rendering units
#define BS 10
#define MATERIALS_COUNT 256 #define MATERIALS_COUNT 256
/* /*
@ -53,9 +50,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/* /*
Suggested materials: Suggested materials:
GRAVEL - Gravel
- Dynamics of gravel: if there is a drop of more than two - Sand
blocks on any side, it will drop in there. Is this doable?
New naming scheme: New naming scheme:
- Material = irrlicht's Material class - Material = irrlicht's Material class
@ -63,25 +59,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
- Tile = (u16) Material ID at some side of a node - Tile = (u16) Material ID at some side of a node
*/ */
enum Content #define CONTENT_STONE 0
{ #define CONTENT_GRASS 1
CONTENT_STONE, #define CONTENT_WATER 2
CONTENT_GRASS, #define CONTENT_TORCH 3
CONTENT_WATER, #define CONTENT_TREE 4
CONTENT_TORCH, #define CONTENT_LEAVES 5
CONTENT_TREE, #define CONTENT_GRASS_FOOTSTEPS 6
CONTENT_LEAVES, #define CONTENT_MESE 7
CONTENT_GRASS_FOOTSTEPS, #define CONTENT_MUD 8
CONTENT_MESE, #define CONTENT_WATERSOURCE 9
CONTENT_MUD, #define CONTENT_CLOUD 10
CONTENT_OCEAN, #define CONTENT_COALSTONE 11
CONTENT_CLOUD, #define CONTENT_WOOD 12
CONTENT_COALSTONE,
CONTENT_WOOD,
// This is set to the number of the actual values in this enum #define USEFUL_CONTENT_COUNT 13
USEFUL_CONTENT_COUNT
};
extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6]; extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6];
extern const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT]; extern const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT];
@ -94,7 +86,7 @@ void init_content_inventory_texture_paths();
*/ */
inline bool light_propagates_content(u8 m) inline bool light_propagates_content(u8 m)
{ {
return (m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER || m == CONTENT_OCEAN); return (m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
} }
/* /*
@ -118,7 +110,7 @@ inline u8 content_solidness(u8 m)
// As of now, every pseudo node like torches are added to this // As of now, every pseudo node like torches are added to this
if(m == CONTENT_AIR || m == CONTENT_TORCH) if(m == CONTENT_AIR || m == CONTENT_TORCH)
return 0; return 0;
if(m == CONTENT_WATER || m == CONTENT_OCEAN) if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE)
return 1; return 1;
return 2; return 2;
} }
@ -126,29 +118,29 @@ inline u8 content_solidness(u8 m)
// Objects collide with walkable contents // Objects collide with walkable contents
inline bool content_walkable(u8 m) inline bool content_walkable(u8 m)
{ {
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN && m != CONTENT_TORCH); return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE && m != CONTENT_TORCH);
} }
// A liquid resists fast movement // A liquid resists fast movement
inline bool content_liquid(u8 m) inline bool content_liquid(u8 m)
{ {
return (m == CONTENT_WATER || m == CONTENT_OCEAN); return (m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
} }
// Pointable contents can be pointed to in the map // Pointable contents can be pointed to in the map
inline bool content_pointable(u8 m) inline bool content_pointable(u8 m)
{ {
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN); return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
} }
inline bool content_diggable(u8 m) inline bool content_diggable(u8 m)
{ {
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN); return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
} }
inline bool content_buildable_to(u8 m) inline bool content_buildable_to(u8 m)
{ {
return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN); return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
} }
/* /*
@ -164,7 +156,7 @@ inline bool is_ground_content(u8 m)
&& m != CONTENT_TORCH && m != CONTENT_TORCH
&& m != CONTENT_TREE && m != CONTENT_TREE
&& m != CONTENT_LEAVES && m != CONTENT_LEAVES
&& m != CONTENT_OCEAN && m != CONTENT_WATERSOURCE
&& m != CONTENT_CLOUD && m != CONTENT_CLOUD
); );
} }
@ -293,6 +285,54 @@ enum LightBank
LIGHTBANK_NIGHT LIGHTBANK_NIGHT
}; };
#if 0
#define DIR_PX 1 //X+
#define DIR_NX 2 //X-
#define DIR_PZ 4 //Z+
#define DIR_NZ 8 //Z-
#define DIR_PY 16 //Y+
#define DIR_NY 32 //Y-
inline void decode_dirs(u8 b, core::list<v3s16> &dirs)
{
if(b & DIR_PX)
dirs.push_back(v3s16(1,0,0));
if(b & DIR_NX)
dirs.push_back(v3s16(-1,0,0));
if(b & DIR_PZ)
dirs.push_back(v3s16(0,0,1));
if(b & DIR_NZ)
dirs.push_back(v3s16(0,0,-1));
if(b & DIR_PY)
dirs.push_back(v3s16(0,1,0));
if(b & DIR_NY)
dirs.push_back(v3s16(0,-1,0));
}
inline u8 encode_dirs(core::list<v3s16> &dirs)
{
u8 b = 0;
for(core::list<v3s16>::Iterator
i = dirs.begin();
i != dirs.end(); i++)
{
if(*i == v3s16(1,0,0))
b += DIR_PX;
else if(*i == v3s16(-1,0,0))
b += DIR_NX;
else if(*i == v3s16(0,0,1))
b += DIR_PZ;
else if(*i == v3s16(0,0,-1))
b += DIR_NZ;
else if(*i == v3s16(0,1,0))
b += DIR_PY;
else if(*i == v3s16(0,-1,0))
b += DIR_NY;
}
return b;
}
#endif
struct MapNode struct MapNode
{ {
// Content // Content
@ -303,6 +343,7 @@ struct MapNode
- For light_propagates() blocks, this is light intensity, - For light_propagates() blocks, this is light intensity,
stored logarithmically from 0 to LIGHT_MAX. stored logarithmically from 0 to LIGHT_MAX.
Sunlight is LIGHT_SUN, which is LIGHT_MAX+1. Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
- Contains 2 values, day- and night lighting. Each takes 4 bits.
*/ */
s8 param; s8 param;
@ -315,7 +356,7 @@ struct MapNode
/* /*
Direction for torches and other stuff. Direction for torches and other stuff.
If possible, packed with packDir. Format is freeform. e.g. packDir or encode_dirs can be used.
*/ */
u8 dir; u8 dir;
}; };

@ -39,7 +39,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define SECTOR_OBJECT_BUSH_1 2 #define SECTOR_OBJECT_BUSH_1 2
#define SECTOR_OBJECT_RAVINE 3 #define SECTOR_OBJECT_RAVINE 3
#define MAPSECTOR_FIXEDHEIGHTMAPS_MAXCOUNT 4 //#define MAPSECTOR_FIXEDHEIGHTMAPS_MAXCOUNT 4
#define MAPSECTOR_FIXEDHEIGHTMAPS_MAXCOUNT \
(SECTOR_HEIGHTMAP_SPLIT * SECTOR_HEIGHTMAP_SPLIT)
#define MAPSECTOR_SERVER 0 #define MAPSECTOR_SERVER 0
#define MAPSECTOR_CLIENT 1 #define MAPSECTOR_CLIENT 1

@ -223,8 +223,10 @@ void LocalPlayer::move(f32 dtime, Map &map)
position += m_speed * dtime; position += m_speed * dtime;
bool haxmode = g_settings.getBool("haxmode");
// Skip collision detection if player is non-local // Skip collision detection if player is non-local
if(isLocal() == false || HAXMODE) if(isLocal() == false || haxmode)
{ {
setPosition(position); setPosition(position);
return; return;
@ -389,7 +391,9 @@ void LocalPlayer::applyControl(float dtime)
v3f speed = v3f(0,0,0); v3f speed = v3f(0,0,0);
if(HAXMODE) bool haxmode = g_settings.getBool("haxmode");
if(haxmode)
{ {
v3f speed = getSpeed(); v3f speed = getSpeed();
speed.Y = 0; speed.Y = 0;
@ -400,7 +404,7 @@ void LocalPlayer::applyControl(float dtime)
bool superspeed = false; bool superspeed = false;
if(control.superspeed) if(control.superspeed)
{ {
if(HAXMODE) if(haxmode)
{ {
v3f speed = getSpeed(); v3f speed = getSpeed();
speed.Y = -20*BS; speed.Y = -20*BS;
@ -413,7 +417,7 @@ void LocalPlayer::applyControl(float dtime)
} }
} }
if(HAXMODE) if(haxmode)
superspeed = true; superspeed = true;
if(control.up) if(control.up)
@ -434,7 +438,7 @@ void LocalPlayer::applyControl(float dtime)
} }
if(control.jump) if(control.jump)
{ {
if(HAXMODE) if(haxmode)
{ {
v3f speed = getSpeed(); v3f speed = getSpeed();
/*speed.Y += 20.*BS * dtime * 2; /*speed.Y += 20.*BS * dtime * 2;
@ -465,7 +469,7 @@ void LocalPlayer::applyControl(float dtime)
f32 inc = walk_acceleration * BS * dtime; f32 inc = walk_acceleration * BS * dtime;
if(HAXMODE) if(haxmode)
inc = walk_acceleration * BS * dtime * 10; inc = walk_acceleration * BS * dtime * 10;
// Accelerate to target speed with maximum increment // Accelerate to target speed with maximum increment

@ -164,6 +164,7 @@ void * EmergeThread::Thread()
changed_blocks, changed_blocks,
lighting_invalidated_blocks); lighting_invalidated_blocks);
#if 0
/* /*
EXPERIMENTAL: Create a few other blocks too EXPERIMENTAL: Create a few other blocks too
*/ */
@ -179,7 +180,7 @@ void * EmergeThread::Thread()
only_from_disk, only_from_disk,
changed_blocks, changed_blocks,
lighting_invalidated_blocks); lighting_invalidated_blocks);
#endif
} }
// If it is a dummy, block was not found on disk // If it is a dummy, block was not found on disk
@ -211,6 +212,7 @@ void * EmergeThread::Thread()
dout_server<<std::endl; dout_server<<std::endl;
} }
#if 0
/* /*
Update water pressure Update water pressure
*/ */
@ -225,6 +227,7 @@ void * EmergeThread::Thread()
//v3s16 p = i.getNode()->getKey(); //v3s16 p = i.getNode()->getKey();
//m_server->UpdateBlockWaterPressure(p, modified_blocks); //m_server->UpdateBlockWaterPressure(p, modified_blocks);
} }
#endif
/* /*
Collect a list of blocks that have been modified in Collect a list of blocks that have been modified in
@ -318,6 +321,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
} }
} }
bool haxmode = g_settings.getBool("haxmode");
Player *player = server->m_env.getPlayer(peer_id); Player *player = server->m_env.getPlayer(peer_id);
assert(player != NULL); assert(player != NULL);
@ -491,7 +496,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
bool generate = d <= d_max_gen; bool generate = d <= d_max_gen;
if(HAXMODE) if(haxmode)
{ {
// Don't generate above player // Don't generate above player
if(p.Y > center.Y) if(p.Y > center.Y)
@ -523,7 +528,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
continue; continue;
} }
if(HAXMODE) if(haxmode)
{ {
/* /*
Ignore block if it is not at ground surface Ignore block if it is not at ground surface
@ -868,12 +873,12 @@ void RemoteClient::GotBlock(v3s16 p)
void RemoteClient::SentBlock(v3s16 p) void RemoteClient::SentBlock(v3s16 p)
{ {
JMutexAutoLock lock(m_blocks_sending_mutex); JMutexAutoLock lock(m_blocks_sending_mutex);
if(m_blocks_sending.size() > 15) /*if(m_blocks_sending.size() > 15)
{ {
dstream<<"RemoteClient::SentBlock(): " dstream<<"RemoteClient::SentBlock(): "
<<"m_blocks_sending.size()=" <<"m_blocks_sending.size()="
<<m_blocks_sending.size()<<std::endl; <<m_blocks_sending.size()<<std::endl;
} }*/
if(m_blocks_sending.find(p) == NULL) if(m_blocks_sending.find(p) == NULL)
m_blocks_sending.insert(p, 0.0); m_blocks_sending.insert(p, 0.0);
else else
@ -1136,8 +1141,13 @@ void Server::AsyncRunStep()
Do background stuff Do background stuff
*/ */
{
//m_env.getMap().
}
#if 0
/* /*
Flow water Update water
*/ */
if(g_settings.getBool("water_moves") == true) if(g_settings.getBool("water_moves") == true)
{ {
@ -1209,6 +1219,7 @@ void Server::AsyncRunStep()
} // interval counter } // interval counter
} }
#endif
// Periodically print some info // Periodically print some info
{ {
@ -1963,6 +1974,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
*/ */
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks); m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
#if 0
/* /*
Update water Update water
*/ */
@ -1986,6 +1998,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
} }
v.blitBack(modified_blocks); v.blitBack(modified_blocks);
#endif
} }
/* /*
@ -2112,6 +2125,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
} }
#endif #endif
#if 0
/* /*
Update water Update water
*/ */
@ -2135,6 +2149,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
} }
v.blitBack(modified_blocks); v.blitBack(modified_blocks);
#endif
} }
/* /*
Handle other items Handle other items
@ -3160,7 +3175,7 @@ Player *Server::emergePlayer(const char *name, const char *password)
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++) for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
{ {
// Skip some materials // Skip some materials
if(i == CONTENT_OCEAN || i == CONTENT_TORCH) if(i == CONTENT_WATER || i == CONTENT_TORCH)
continue; continue;
InventoryItem *item = new MaterialItem(i, 1); InventoryItem *item = new MaterialItem(i, 1);
@ -3230,6 +3245,7 @@ Player *Server::emergePlayer(const char *name, const char *password)
} }
} }
#if 0
void Server::UpdateBlockWaterPressure(MapBlock *block, void Server::UpdateBlockWaterPressure(MapBlock *block,
core::map<v3s16, MapBlock*> &modified_blocks) core::map<v3s16, MapBlock*> &modified_blocks)
{ {
@ -3251,6 +3267,7 @@ void Server::UpdateBlockWaterPressure(MapBlock *block,
v.blitBack(modified_blocks); v.blitBack(modified_blocks);
} }
#endif
void Server::handlePeerChange(PeerChange &c) void Server::handlePeerChange(PeerChange &c)
{ {

@ -449,8 +449,8 @@ private:
environment has to be locked when calling. environment has to be locked when calling.
*/ */
void UpdateBlockWaterPressure(MapBlock *block, /*void UpdateBlockWaterPressure(MapBlock *block,
core::map<v3s16, MapBlock*> &modified_blocks); core::map<v3s16, MapBlock*> &modified_blocks);*/
// Locks environment and connection by its own // Locks environment and connection by its own
struct PeerChange; struct PeerChange;
@ -481,7 +481,7 @@ private:
BlockEmergeQueue m_emerge_queue; BlockEmergeQueue m_emerge_queue;
// Nodes that are destinations of flowing liquid at the moment // Nodes that are destinations of flowing liquid at the moment
core::map<v3s16, u8> m_flow_active_nodes; //core::map<v3s16, u8> m_flow_active_nodes;
// 0-23999 // 0-23999
MutexedVariable<u32> m_time_of_day; MutexedVariable<u32> m_time_of_day;

@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h" #include "utility.h"
#include "irrlichtwrapper.h" #include "irrlichtwrapper.h"
#include "gettime.h" #include "gettime.h"
#include "mapblock.h"
TimeTaker::TimeTaker(const char *name, u32 *result) TimeTaker::TimeTaker(const char *name, u32 *result)
{ {

@ -1580,6 +1580,47 @@ private:
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range); bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range);
/*
Queue with unique values with fast checking of value existence
*/
template<typename Value>
class UniqueQueue
{
public:
/*
Does nothing if value is already queued.
Return value:
true: value added
false: value already exists
*/
bool push_back(Value value)
{
// Check if already exists
if(m_map.find(value) != NULL)
return false;
// Add
m_map.insert(value, 0);
m_list.push_back(value);
return true;
}
void pop_front()
{
typename core::list<Value>::Iterator i = m_list.begin();
Value value = *i;
m_map.remove(value);
m_list.erase(i);
return value;
}
private:
core::map<Value, u8> m_map;
core::list<Value> m_list;
};
#endif #endif

@ -221,71 +221,6 @@ void VoxelManipulator::copyFrom(MapNode *src, VoxelArea src_area,
} }
} }
void VoxelManipulator::interpolate(VoxelArea area)
{
VoxelArea emerge_area = area;
emerge_area.MinEdge -= v3s16(1,1,1);
emerge_area.MaxEdge += v3s16(1,1,1);
emerge(emerge_area);
SharedBuffer<u8> buf(area.getVolume());
for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
for(s32 y=area.MinEdge.Y; y<=area.MaxEdge.Y; y++)
for(s32 x=area.MinEdge.X; x<=area.MaxEdge.X; x++)
{
v3s16 p(x,y,z);
v3s16 dirs[] = {
v3s16(1,1,0),
v3s16(1,0,1),
v3s16(1,-1,0),
v3s16(1,0,-1),
v3s16(-1,1,0),
v3s16(-1,0,1),
v3s16(-1,-1,0),
v3s16(-1,0,-1),
};
//const v3s16 *dirs = g_26dirs;
s16 total = 0;
s16 airness = 0;
u8 m = CONTENT_IGNORE;
for(s16 i=0; i<8; i++)
//for(s16 i=0; i<26; i++)
{
v3s16 p2 = p + dirs[i];
u8 f = m_flags[m_area.index(p2)];
assert(!(f & VOXELFLAG_NOT_LOADED));
if(f & VOXELFLAG_INEXISTENT)
continue;
MapNode &n = m_data[m_area.index(p2)];
airness += (n.d == CONTENT_AIR) ? 1 : -1;
total++;
if(m == CONTENT_IGNORE && n.d != CONTENT_AIR)
m = n.d;
}
// 1 if air, 0 if not
buf[area.index(p)] = airness > -total/2 ? CONTENT_AIR : m;
//buf[area.index(p)] = airness > -total ? CONTENT_AIR : m;
//buf[area.index(p)] = airness >= -7 ? CONTENT_AIR : m;
}
for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
for(s32 y=area.MinEdge.Y; y<=area.MaxEdge.Y; y++)
for(s32 x=area.MinEdge.X; x<=area.MaxEdge.X; x++)
{
v3s16 p(x,y,z);
m_data[m_area.index(p)].d = buf[area.index(p)];
}
}
void VoxelManipulator::clearFlag(u8 flags) void VoxelManipulator::clearFlag(u8 flags)
{ {
@ -373,7 +308,7 @@ int VoxelManipulator::getWaterPressure(v3s16 p, s16 &highest_y, int recur_count)
int pr; int pr;
// If at ocean surface // If at ocean surface
if(n.pressure == 1 && n.d == CONTENT_OCEAN) if(n.pressure == 1 && n.d == CONTENT_WATERSOURCE)
//if(n.pressure == 1) // Causes glitches but is fast //if(n.pressure == 1) // Causes glitches but is fast
{ {
pr = 1; pr = 1;
@ -718,7 +653,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
u8 m = m_data[m_area.index(p)].d; u8 m = m_data[m_area.index(p)].d;
u8 f = m_flags[m_area.index(p)]; u8 f = m_flags[m_area.index(p)];
if(m == CONTENT_OCEAN) if(m == CONTENT_WATERSOURCE)
from_ocean = true; from_ocean = true;
// Move air bubble if not taking water from ocean // Move air bubble if not taking water from ocean
@ -751,7 +686,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
/* /*
NOTE: This does not work as-is NOTE: This does not work as-is
if(m == CONTENT_OCEAN) if(m == CONTENT_WATERSOURCE)
{ {
// If block was raised to surface, increase pressure of // If block was raised to surface, increase pressure of
// source node // source node

@ -395,8 +395,6 @@ public:
Algorithms Algorithms
*/ */
void interpolate(VoxelArea area);
void clearFlag(u8 flag); void clearFlag(u8 flag);
// VOXELFLAG_CHECKED2s must usually be cleared before calling // VOXELFLAG_CHECKED2s must usually be cleared before calling