{
JMutexAutoLock envlock(m_env_mutex);
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
- v3s16 blockpos = ((ClientMap&)m_env.getMap()).setTempMod(p, mod);
- m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
+ bool changed = false;
+ v3s16 blockpos = ((ClientMap&)m_env.getMap()).setTempMod(p, mod, &changed);
+ if(changed)
+ m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
}
void clearTempMod(v3s16 p)
{
JMutexAutoLock envlock(m_env_mutex);
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
- v3s16 blockpos = ((ClientMap&)m_env.getMap()).clearTempMod(p);
- m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
+ bool changed = false;
+ v3s16 blockpos = ((ClientMap&)m_env.getMap()).clearTempMod(p, &changed);
+ if(changed)
+ m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
}
float getAvgRtt()
Cross-platform compatibility crap should go in porting.h.
*/
-#define HAXMODE 0
+//#define HAXMODE 0
#define APPNAME "minetest"
// The absolute working limit is (2^15 - viewing_range).
#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
// is in use
//#define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0
// is very low
#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.0
#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 SIGN_TEXT_MAX_LENGTH 50
// Server stuff
g_settings.setDefault("creative_mode", "false");
+ g_settings.setDefault("haxmode", "false");
/*g_settings.setDefault("heightmap_blocksize", "32");
g_settings.setDefault("height_randmax", "constant 45.0");
g_settings.setDefault("height_randfactor", "constant 0.6");
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
g_settings.setDefault("water_moves", "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_generate_distance", "6");
g_settings.setDefault("time_send_interval", "20");
*/
#include "environment.h"
-#include "main.h" // g_device for timing debug
Environment::Environment(Map *map, std::ostream &dout):
m_dout(dout)
v3f playerpos = player->getPosition();
// 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
v3f speed = player->getSpeed();
- Separate points for heightmap, caves, plants and minerals?\r
- Flat land, mountains, forest, jungle\r
- Cliffs, arcs\r
+ - There could be a certain height (to which mountains only reach)\r
+ where some minerals are found\r
\r
Doing now:\r
======================================================================\r
m_camera_position(0,0,0),
m_camera_direction(0,0,1),
m_sector_cache(NULL),
- m_hwrapper(this),
- drawoffset(0,0,0)
+ m_hwrapper(this)
{
m_sector_mutex.Init();
m_camera_mutex.Init();
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;
for(j=list.begin(); j!=list.end(); j++)
//hm->generateContinued(0.5, 0.2, corners);
//hm->generateContinued(1.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();
}
core::map<v3s16, u8> *objects = new core::map<v3s16, u8>;
sector->setObjects(objects);
+ float area = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
+
/*
Plant some trees if there is not much slope
*/
// Avgslope is the derivative of a hill
//float t = avgslope * 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;
//float something = 0.17*0.17;
float something = 0.3;
{
// Pitness usually goes at around -0.5...0.5
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)
bush_max = (pitness*a*4);
if(bush_max > a)
block->unDummify();
}
- u8 water_material = CONTENT_WATER;
+ /*u8 water_material = CONTENT_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 highest_ground_y = -32768;
/*
Debug mode operation
*/
- if(HAXMODE)
+ bool haxmode = g_settings.getBool("haxmode");
+ if(haxmode)
{
// Don't calculate lighting at all
lighting_invalidated_blocks.clear();
<<", 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
continue;
// Relative position of requested node
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
- blockref->setTempMod(relpos, mod);
+ if(blockref->setTempMod(relpos, mod))
+ {
+ if(changed != NULL)
+ *changed = true;
+ }
}
return getNodeBlockPos(p);
}
-v3s16 ClientMap::clearTempMod(v3s16 p)
+v3s16 ClientMap::clearTempMod(v3s16 p, bool *changed)
{
v3s16 dirs[7] = {
v3s16(0,0,0), // this
continue;
// Relative position of requested node
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
- blockref->clearTempMod(relpos);
+ if(blockref->clearTempMod(relpos))
+ {
+ if(changed != NULL)
+ *changed = true;
+ }
}
return getNodeBlockPos(p);
}
#include "constants.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_SERVER 1
#define MAPTYPE_CLIENT 2
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:
- 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);
virtual ~Map();
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)
{
return core::aabbox3d<f32>(
// For debug printing
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
drawing.
Return value is position of changed block.
*/
- v3s16 setTempMod(v3s16 p, NodeMod mod);
- v3s16 clearTempMod(v3s16 p);
+ v3s16 setTempMod(v3s16 p, NodeMod mod, bool *changed=NULL);
+ v3s16 clearTempMod(v3s16 p, bool *changed=NULL);
// Efficient implementation needs a cache of TempMods
//void clearTempMods();
}
#endif
- // 4-21ms
- //TimeTaker timer1("updateMesh()", g_device);
+ // 4-21ms for MAP_BLOCKSIZE=16
+ // 24-155ms for MAP_BLOCKSIZE=32
+ //TimeTaker timer1("updateMesh()");
core::array<FastFace> fastfaces_new;
// This will lead to infinite memory usage because or irrlicht.
//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()
<<" materials (meshbuffers)"<<std::endl;*/
}
else
{
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;
}
}
- // 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 = true;
}
#include "mapblockobject.h"
#include "voxel.h"
-#define MAP_BLOCKSIZE 16
-
// Named by looking towards z+
enum{
FACE_BACK=0,
type = a_type;
param = a_param;
}
+ bool operator==(const NodeMod &other)
+ {
+ return (type == other.type && param == other.param);
+ }
enum NodeModType type;
u16 param;
};
/*
Methods for setting temporary modifications to nodes for
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"
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<", mod.param="<<mod.param
<<std::endl;*/
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;
+ return true;
}
// Returns true if there was one
bool getTempMod(v3s16 p, struct NodeMod *mod)
*mod = n->getValue();
return true;
}
- void clearTempMod(v3s16 p)
+ bool clearTempMod(v3s16 p)
{
JMutexAutoLock lock(m_temp_mods_mutex);
if(m_temp_mods.find(p))
+ {
m_temp_mods.remove(p);
+ return true;
+ }
+ return false;
}
- void clearTempMods()
+ bool clearTempMods()
{
JMutexAutoLock lock(m_temp_mods_mutex);
+ if(m_temp_mods.size() == 0)
+ return false;
m_temp_mods.clear();
+ return true;
}
#endif
{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_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_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE},
{TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD},
"grass_footsteps.png",
"mese.png",
"mud.png",
- "water.png",
+ "water.png", //ocean
"cloud.png",
"coalstone.png",
"wood.png",
#include "serialization.h"
#include "tile.h"
-// Size of node in rendering units
-#define BS 10
-
#define MATERIALS_COUNT 256
/*
/*
Suggested materials:
- GRAVEL
- - Dynamics of gravel: if there is a drop of more than two
- blocks on any side, it will drop in there. Is this doable?
+ - Gravel
+ - Sand
New naming scheme:
- Material = irrlicht's Material class
- Tile = (u16) Material ID at some side of a node
*/
-enum Content
-{
- CONTENT_STONE,
- CONTENT_GRASS,
- CONTENT_WATER,
- CONTENT_TORCH,
- CONTENT_TREE,
- CONTENT_LEAVES,
- CONTENT_GRASS_FOOTSTEPS,
- CONTENT_MESE,
- CONTENT_MUD,
- CONTENT_OCEAN,
- CONTENT_CLOUD,
- CONTENT_COALSTONE,
- CONTENT_WOOD,
+#define CONTENT_STONE 0
+#define CONTENT_GRASS 1
+#define CONTENT_WATER 2
+#define CONTENT_TORCH 3
+#define CONTENT_TREE 4
+#define CONTENT_LEAVES 5
+#define CONTENT_GRASS_FOOTSTEPS 6
+#define CONTENT_MESE 7
+#define CONTENT_MUD 8
+#define CONTENT_WATERSOURCE 9
+#define CONTENT_CLOUD 10
+#define CONTENT_COALSTONE 11
+#define CONTENT_WOOD 12
- // This is set to the number of the actual values in this enum
- USEFUL_CONTENT_COUNT
-};
+#define USEFUL_CONTENT_COUNT 13
extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6];
extern const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT];
*/
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);
}
/*
// As of now, every pseudo node like torches are added to this
if(m == CONTENT_AIR || m == CONTENT_TORCH)
return 0;
- if(m == CONTENT_WATER || m == CONTENT_OCEAN)
+ if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE)
return 1;
return 2;
}
// Objects collide with walkable contents
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
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
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)
{
- 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)
{
- return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN);
+ return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
}
/*
&& m != CONTENT_TORCH
&& m != CONTENT_TREE
&& m != CONTENT_LEAVES
- && m != CONTENT_OCEAN
+ && m != CONTENT_WATERSOURCE
&& m != CONTENT_CLOUD
);
}
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
{
// Content
- For light_propagates() blocks, this is light intensity,
stored logarithmically from 0 to LIGHT_MAX.
Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
+ - Contains 2 values, day- and night lighting. Each takes 4 bits.
*/
s8 param;
/*
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;
};
#define SECTOR_OBJECT_BUSH_1 2
#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_CLIENT 1
position += m_speed * dtime;
+ bool haxmode = g_settings.getBool("haxmode");
+
// Skip collision detection if player is non-local
- if(isLocal() == false || HAXMODE)
+ if(isLocal() == false || haxmode)
{
setPosition(position);
return;
v3f speed = v3f(0,0,0);
- if(HAXMODE)
+ bool haxmode = g_settings.getBool("haxmode");
+
+ if(haxmode)
{
v3f speed = getSpeed();
speed.Y = 0;
bool superspeed = false;
if(control.superspeed)
{
- if(HAXMODE)
+ if(haxmode)
{
v3f speed = getSpeed();
speed.Y = -20*BS;
}
}
- if(HAXMODE)
+ if(haxmode)
superspeed = true;
if(control.up)
}
if(control.jump)
{
- if(HAXMODE)
+ if(haxmode)
{
v3f speed = getSpeed();
/*speed.Y += 20.*BS * dtime * 2;
f32 inc = walk_acceleration * BS * dtime;
- if(HAXMODE)
+ if(haxmode)
inc = walk_acceleration * BS * dtime * 10;
// Accelerate to target speed with maximum increment
only_from_disk,
changed_blocks,
lighting_invalidated_blocks);
-
+
+#if 0
/*
EXPERIMENTAL: Create a few other blocks too
*/
only_from_disk,
changed_blocks,
lighting_invalidated_blocks);
-
+#endif
}
// If it is a dummy, block was not found on disk
dout_server<<std::endl;
}
+#if 0
/*
Update water pressure
*/
//v3s16 p = i.getNode()->getKey();
//m_server->UpdateBlockWaterPressure(p, modified_blocks);
}
+#endif
/*
Collect a list of blocks that have been modified in
}
}
+ bool haxmode = g_settings.getBool("haxmode");
+
Player *player = server->m_env.getPlayer(peer_id);
assert(player != NULL);
bool generate = d <= d_max_gen;
- if(HAXMODE)
+ if(haxmode)
{
// Don't generate above player
if(p.Y > center.Y)
continue;
}
- if(HAXMODE)
+ if(haxmode)
{
/*
Ignore block if it is not at ground surface
void RemoteClient::SentBlock(v3s16 p)
{
JMutexAutoLock lock(m_blocks_sending_mutex);
- if(m_blocks_sending.size() > 15)
+ /*if(m_blocks_sending.size() > 15)
{
dstream<<"RemoteClient::SentBlock(): "
<<"m_blocks_sending.size()="
<<m_blocks_sending.size()<<std::endl;
- }
+ }*/
if(m_blocks_sending.find(p) == NULL)
m_blocks_sending.insert(p, 0.0);
else
Do background stuff
*/
+ {
+ //m_env.getMap().
+ }
+
+#if 0
/*
- Flow water
+ Update water
*/
if(g_settings.getBool("water_moves") == true)
{
} // interval counter
}
+#endif
// Periodically print some info
{
(this takes some time so it is done after the quick stuff)
*/
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
-
+
+#if 0
/*
Update water
*/
}
v.blitBack(modified_blocks);
+#endif
}
/*
}
}
#endif
-
+
+#if 0
/*
Update water
*/
}
v.blitBack(modified_blocks);
+#endif
}
/*
Handle other items
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
{
// Skip some materials
- if(i == CONTENT_OCEAN || i == CONTENT_TORCH)
+ if(i == CONTENT_WATER || i == CONTENT_TORCH)
continue;
InventoryItem *item = new MaterialItem(i, 1);
}
}
+#if 0
void Server::UpdateBlockWaterPressure(MapBlock *block,
core::map<v3s16, MapBlock*> &modified_blocks)
{
v.blitBack(modified_blocks);
}
+#endif
void Server::handlePeerChange(PeerChange &c)
{
environment has to be locked when calling.
*/
- void UpdateBlockWaterPressure(MapBlock *block,
- core::map<v3s16, MapBlock*> &modified_blocks);
+ /*void UpdateBlockWaterPressure(MapBlock *block,
+ core::map<v3s16, MapBlock*> &modified_blocks);*/
// Locks environment and connection by its own
struct PeerChange;
BlockEmergeQueue m_emerge_queue;
// 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
MutexedVariable<u32> m_time_of_day;
#include "utility.h"
#include "irrlichtwrapper.h"
#include "gettime.h"
-#include "mapblock.h"
TimeTaker::TimeTaker(const char *name, u32 *result)
{
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
}
}
-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)
{
int pr;
// 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
{
pr = 1;
u8 m = m_data[m_area.index(p)].d;
u8 f = m_flags[m_area.index(p)];
- if(m == CONTENT_OCEAN)
+ if(m == CONTENT_WATERSOURCE)
from_ocean = true;
// Move air bubble if not taking water from ocean
/*
NOTE: This does not work as-is
- if(m == CONTENT_OCEAN)
+ if(m == CONTENT_WATERSOURCE)
{
// If block was raised to surface, increase pressure of
// source node
Algorithms
*/
- void interpolate(VoxelArea area);
-
void clearFlag(u8 flag);
// VOXELFLAG_CHECKED2s must usually be cleared before calling