partly working chunk-based map generator (doesn't save properly, spawn is pretty random)
parent
be851871cd
commit
6e196c2ce4
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
|
IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
|
||||||
{
|
{
|
||||||
|
m_running = true;
|
||||||
m_main_thread = get_current_thread_id();
|
m_main_thread = get_current_thread_id();
|
||||||
m_device_mutex.Init();
|
m_device_mutex.Init();
|
||||||
m_device = device;
|
m_device = device;
|
||||||
|
@ -35,6 +36,11 @@ void IrrlichtWrapper::Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IrrlichtWrapper::Shutdown(bool shutdown)
|
||||||
|
{
|
||||||
|
m_running = !shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
textureid_t IrrlichtWrapper::getTextureId(const std::string &name)
|
textureid_t IrrlichtWrapper::getTextureId(const std::string &name)
|
||||||
{
|
{
|
||||||
u32 id = m_namecache.getId(name);
|
u32 id = m_namecache.getId(name);
|
||||||
|
@ -73,6 +79,10 @@ video::ITexture* IrrlichtWrapper::getTexture(const TextureSpec &spec)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If irrlicht has shut down, just return NULL
|
||||||
|
if(m_running == false)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// We're gonna ask the result to be put into here
|
// We're gonna ask the result to be put into here
|
||||||
ResultQueue<TextureSpec, video::ITexture*, u8, u8> result_queue;
|
ResultQueue<TextureSpec, video::ITexture*, u8, u8> result_queue;
|
||||||
|
|
||||||
|
|
|
@ -132,11 +132,15 @@ public:
|
||||||
/*
|
/*
|
||||||
These are called from the main thread
|
These are called from the main thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IrrlichtWrapper(IrrlichtDevice *device);
|
IrrlichtWrapper(IrrlichtDevice *device);
|
||||||
|
|
||||||
// Run queued tasks
|
// Run queued tasks
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
|
// Shutdown wrapper; this disables queued texture fetching
|
||||||
|
void Shutdown(bool shutdown);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These are called from other threads
|
These are called from other threads
|
||||||
*/
|
*/
|
||||||
|
@ -182,6 +186,8 @@ private:
|
||||||
Members
|
Members
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool m_running;
|
||||||
|
|
||||||
// The id of the thread that can (and has to) use irrlicht directly
|
// The id of the thread that can (and has to) use irrlicht directly
|
||||||
threadid_t m_main_thread;
|
threadid_t m_main_thread;
|
||||||
|
|
||||||
|
|
39
src/main.cpp
39
src/main.cpp
|
@ -296,7 +296,10 @@ FEATURE: The map could be generated procedually:
|
||||||
- Lighting would not have to be necessarily calculated until
|
- Lighting would not have to be necessarily calculated until
|
||||||
the blocks are actually needed - it would be quite fast
|
the blocks are actually needed - it would be quite fast
|
||||||
- Something like 64*64*16 MapBlocks?
|
- Something like 64*64*16 MapBlocks?
|
||||||
- TODO: Separate lighting and block generation
|
- No, MapSectors. And as much as it is efficient to do,
|
||||||
|
64x64 might be too much.
|
||||||
|
- FIXME: This is currently halfway done and the generator is
|
||||||
|
fairly broken
|
||||||
* Make the stone level with a heightmap
|
* Make the stone level with a heightmap
|
||||||
* Carve out stuff in the stone
|
* Carve out stuff in the stone
|
||||||
* Dump dirt all around, and simulate it falling off steep
|
* Dump dirt all around, and simulate it falling off steep
|
||||||
|
@ -311,16 +314,25 @@ FEATURE: The map could be generated procedually:
|
||||||
parameter field is free for this.
|
parameter field is free for this.
|
||||||
- Simulate rock falling from cliffs when water has removed
|
- Simulate rock falling from cliffs when water has removed
|
||||||
enough solid rock from the bottom
|
enough solid rock from the bottom
|
||||||
TODO: Lazy lighting updates:
|
|
||||||
- Set updateLighting to ignore MapBlocks with expired lighting,
|
|
||||||
except the blocks specified to it
|
|
||||||
- When a MapBlock is generated, lighting expires in all blocks
|
|
||||||
touching it (26 blocks + self)
|
|
||||||
- When a lighting-wise valid MapBlock is needed and lighting of it
|
|
||||||
has expired, what to do?
|
|
||||||
|
|
||||||
Doing now:
|
Doing now:
|
||||||
----------
|
----------
|
||||||
|
# maybe done
|
||||||
|
* not done
|
||||||
|
|
||||||
|
* Remove all kinds of systems that are made redundant by the new map
|
||||||
|
generator
|
||||||
|
- Sector heightmaps? At least they should be made redundant.
|
||||||
|
- Sector objects
|
||||||
|
* Do something about AttributeDatabase/List being too slow
|
||||||
|
* Save chunk metadata on disk
|
||||||
|
* Change water side textures so that buggy water doesn't look bad
|
||||||
|
* Make server find the spawning place from the real map data, not from
|
||||||
|
the heightmap
|
||||||
|
* only_from_disk doesn't work that well anymore
|
||||||
|
* Make the generator to run in background and not blocking block
|
||||||
|
placement and transfer
|
||||||
|
* Fix the strange mineral occurences
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
@ -1886,6 +1898,9 @@ int main(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// This is set to true at the end of the scope
|
||||||
|
g_irrlicht->Shutdown(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Draw "Loading" screen
|
Draw "Loading" screen
|
||||||
*/
|
*/
|
||||||
|
@ -3017,6 +3032,14 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
delete quick_inventory;
|
delete quick_inventory;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Disable texture fetches and other stuff that is queued
|
||||||
|
to be processed by the main loop.
|
||||||
|
|
||||||
|
This has to be done before client goes out of scope.
|
||||||
|
*/
|
||||||
|
g_irrlicht->Shutdown(true);
|
||||||
|
|
||||||
} // client and server are deleted at this point
|
} // client and server are deleted at this point
|
||||||
|
|
||||||
} //try
|
} //try
|
||||||
|
|
1295
src/map.cpp
1295
src/map.cpp
File diff suppressed because it is too large
Load Diff
33
src/map.h
33
src/map.h
|
@ -93,6 +93,8 @@ public:
|
||||||
MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
|
MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
|
||||||
// On failure throws InvalidPositionException
|
// On failure throws InvalidPositionException
|
||||||
MapSector * getSectorNoGenerate(v2s16 p2d);
|
MapSector * getSectorNoGenerate(v2s16 p2d);
|
||||||
|
// Gets an existing sector or creates an empty one
|
||||||
|
//MapSector * getSectorCreate(v2s16 p2d);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is overloaded by ClientMap and ServerMap to allow
|
This is overloaded by ClientMap and ServerMap to allow
|
||||||
|
@ -104,6 +106,8 @@ public:
|
||||||
MapBlock * getBlockNoCreate(v3s16 p);
|
MapBlock * getBlockNoCreate(v3s16 p);
|
||||||
// Returns NULL if not found
|
// Returns NULL if not found
|
||||||
MapBlock * getBlockNoCreateNoEx(v3s16 p);
|
MapBlock * getBlockNoCreateNoEx(v3s16 p);
|
||||||
|
// Gets an existing block or creates an empty one
|
||||||
|
//MapBlock * getBlockCreate(v3s16 p);
|
||||||
|
|
||||||
// Returns InvalidPositionException if not found
|
// Returns InvalidPositionException if not found
|
||||||
f32 getGroundHeight(v2s16 p, bool generate=false);
|
f32 getGroundHeight(v2s16 p, bool generate=false);
|
||||||
|
@ -382,12 +386,20 @@ public:
|
||||||
|
|
||||||
This is mainly called by generateChunkRaw.
|
This is mainly called by generateChunkRaw.
|
||||||
*/
|
*/
|
||||||
ServerMapSector * generateSector(v2s16 p);
|
//ServerMapSector * generateSector(v2s16 p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get a sector from somewhere.
|
Get a sector from somewhere.
|
||||||
- Check memory
|
- Check memory
|
||||||
- Check disk
|
- Check disk (loads blocks also)
|
||||||
|
- Create blank one
|
||||||
|
*/
|
||||||
|
ServerMapSector * createSector(v2s16 p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get a sector from somewhere.
|
||||||
|
- Check memory
|
||||||
|
- Check disk (loads blocks also)
|
||||||
- Generate chunk
|
- Generate chunk
|
||||||
*/
|
*/
|
||||||
MapSector * emergeSector(v2s16 p);
|
MapSector * emergeSector(v2s16 p);
|
||||||
|
@ -400,6 +412,13 @@ public:
|
||||||
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
|
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get a block from somewhere.
|
||||||
|
- Memory
|
||||||
|
- Create blank
|
||||||
|
*/
|
||||||
|
MapBlock * createBlock(v3s16 p);
|
||||||
|
|
||||||
MapBlock * emergeBlock(
|
MapBlock * emergeBlock(
|
||||||
v3s16 p,
|
v3s16 p,
|
||||||
bool only_from_disk,
|
bool only_from_disk,
|
||||||
|
@ -636,10 +655,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Map *m_map;
|
Map *m_map;
|
||||||
/*
|
/*
|
||||||
NOTE: This might be used or not
|
key = blockpos
|
||||||
bool is dummy value
|
value = block existed when loaded
|
||||||
SUGG: How 'bout an another VoxelManipulator for storing the
|
|
||||||
information about which block is loaded?
|
|
||||||
*/
|
*/
|
||||||
core::map<v3s16, bool> m_loaded_blocks;
|
core::map<v3s16, bool> m_loaded_blocks;
|
||||||
};
|
};
|
||||||
|
@ -654,7 +671,11 @@ public:
|
||||||
|
|
||||||
void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
|
void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
|
||||||
|
|
||||||
|
// This is much faster with big chunks of generated data
|
||||||
|
void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool m_create_area;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1309,10 +1309,21 @@ void MapBlock::copyTo(VoxelManipulator &dst)
|
||||||
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||||
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
||||||
|
|
||||||
|
// Copy from data to VoxelManipulator
|
||||||
dst.copyFrom(data, data_area, v3s16(0,0,0),
|
dst.copyFrom(data, data_area, v3s16(0,0,0),
|
||||||
getPosRelative(), data_size);
|
getPosRelative(), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapBlock::copyFrom(VoxelManipulator &dst)
|
||||||
|
{
|
||||||
|
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||||
|
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
|
||||||
|
|
||||||
|
// Copy from VoxelManipulator to data
|
||||||
|
dst.copyTo(data, data_area, v3s16(0,0,0),
|
||||||
|
getPosRelative(), data_size);
|
||||||
|
}
|
||||||
|
|
||||||
void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
|
void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -426,6 +426,8 @@ public:
|
||||||
|
|
||||||
// Copies data to VoxelManipulator to getPosRelative()
|
// Copies data to VoxelManipulator to getPosRelative()
|
||||||
void copyTo(VoxelManipulator &dst);
|
void copyTo(VoxelManipulator &dst);
|
||||||
|
// Copies data from VoxelManipulator getPosRelative()
|
||||||
|
void copyFrom(VoxelManipulator &dst);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MapBlockObject stuff
|
MapBlockObject stuff
|
||||||
|
|
|
@ -438,6 +438,14 @@ struct MapNode
|
||||||
param2 = a_param2;
|
param2 = a_param2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*MapNode & operator=(const MapNode &other)
|
||||||
|
{
|
||||||
|
d = other.d;
|
||||||
|
param = other.param;
|
||||||
|
param2 = other.param2;
|
||||||
|
return *this;
|
||||||
|
}*/
|
||||||
|
|
||||||
bool operator==(const MapNode &other)
|
bool operator==(const MapNode &other)
|
||||||
{
|
{
|
||||||
return (d == other.d
|
return (d == other.d
|
||||||
|
|
|
@ -570,10 +570,15 @@ ServerMapSector* ServerMapSector::deSerialize(
|
||||||
|
|
||||||
if(n != NULL)
|
if(n != NULL)
|
||||||
{
|
{
|
||||||
dstream<<"deSerializing existent sectors not supported "
|
dstream<<"WARNING: deSerializing existent sectors not supported "
|
||||||
"at the moment, because code hasn't been tested."
|
"at the moment, because code hasn't been tested."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
assert(0);
|
|
||||||
|
//assert(0);
|
||||||
|
MapSector *sector = n->getValue();
|
||||||
|
assert(sector->getId() == MAPSECTOR_SERVER);
|
||||||
|
return (ServerMapSector*)sector;
|
||||||
|
|
||||||
// NOTE: At least hm_split mismatch would have to be checked
|
// NOTE: At least hm_split mismatch would have to be checked
|
||||||
|
|
||||||
//sector = n->getValue();
|
//sector = n->getValue();
|
||||||
|
|
|
@ -606,6 +606,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
{
|
{
|
||||||
block_is_invalid = true;
|
block_is_invalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v2s16 p2d(p.X, p.Z);
|
||||||
|
ServerMap *map = (ServerMap*)(&server->m_env.getMap());
|
||||||
|
v2s16 chunkpos = map->sector_to_chunk(p2d);
|
||||||
|
MapChunk *chunk = map->getChunk(chunkpos);
|
||||||
|
if(chunk == NULL)
|
||||||
|
block_is_invalid = true;
|
||||||
|
else if(chunk->getIsVolatile() == true)
|
||||||
|
block_is_invalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3258,7 +3267,8 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
||||||
|
|
||||||
player->setPosition(intToFloat(v3s16(
|
player->setPosition(intToFloat(v3s16(
|
||||||
nodepos.X,
|
nodepos.X,
|
||||||
groundheight + 1,
|
//groundheight + 1,
|
||||||
|
groundheight + 15,
|
||||||
nodepos.Y
|
nodepos.Y
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,10 @@ public:
|
||||||
{
|
{
|
||||||
return ptr == t;
|
return ptr == t;
|
||||||
}
|
}
|
||||||
|
T & operator[](unsigned int i)
|
||||||
|
{
|
||||||
|
return ptr[i];
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
void drop()
|
void drop()
|
||||||
{
|
{
|
||||||
|
@ -572,6 +576,15 @@ inline bool isInArea(v2s16 p, s16 d)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isInArea(v3s16 p, v3s16 d)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
p.X >= 0 && p.X < d.X &&
|
||||||
|
p.Y >= 0 && p.Y < d.Y &&
|
||||||
|
p.Z >= 0 && p.Z < d.Z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
inline s16 rangelim(s16 i, s16 min, s16 max)
|
inline s16 rangelim(s16 i, s16 min, s16 max)
|
||||||
{
|
{
|
||||||
if(i < min)
|
if(i < min)
|
||||||
|
@ -1459,6 +1472,13 @@ int myrand(void);
|
||||||
void mysrand(unsigned seed);
|
void mysrand(unsigned seed);
|
||||||
#define MYRAND_MAX 32767
|
#define MYRAND_MAX 32767
|
||||||
|
|
||||||
|
inline int myrand_range(int min, int max)
|
||||||
|
{
|
||||||
|
if(min >= max)
|
||||||
|
return max;
|
||||||
|
return (myrand()%(max-min+1))+min;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some kind of a thing that stores attributes related to
|
Some kind of a thing that stores attributes related to
|
||||||
coordinate points
|
coordinate points
|
||||||
|
|
|
@ -41,7 +41,6 @@ VoxelManipulator::VoxelManipulator():
|
||||||
m_data(NULL),
|
m_data(NULL),
|
||||||
m_flags(NULL)
|
m_flags(NULL)
|
||||||
{
|
{
|
||||||
m_disable_water_climb = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelManipulator::~VoxelManipulator()
|
VoxelManipulator::~VoxelManipulator()
|
||||||
|
@ -221,6 +220,22 @@ void VoxelManipulator::copyFrom(MapNode *src, VoxelArea src_area,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelManipulator::copyTo(MapNode *dst, VoxelArea dst_area,
|
||||||
|
v3s16 dst_pos, v3s16 from_pos, v3s16 size)
|
||||||
|
{
|
||||||
|
for(s16 z=0; z<size.Z; z++)
|
||||||
|
for(s16 y=0; y<size.Y; y++)
|
||||||
|
{
|
||||||
|
s32 i_dst = dst_area.index(dst_pos.X, dst_pos.Y+y, dst_pos.Z+z);
|
||||||
|
s32 i_local = m_area.index(from_pos.X, from_pos.Y+y, from_pos.Z+z);
|
||||||
|
memcpy(&dst[i_dst], &m_data[i_local], size.X*sizeof(MapNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Algorithms
|
||||||
|
-----------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
void VoxelManipulator::clearFlag(u8 flags)
|
void VoxelManipulator::clearFlag(u8 flags)
|
||||||
{
|
{
|
||||||
|
@ -541,7 +556,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
|
||||||
Lights neighbors of from_nodes, collects all them and then
|
Lights neighbors of from_nodes, collects all them and then
|
||||||
goes on recursively.
|
goes on recursively.
|
||||||
|
|
||||||
NOTE: This is faster in small areas but will overflow the
|
NOTE: This is faster on small areas but will overflow the
|
||||||
stack on large areas. Thus it is not used.
|
stack on large areas. Thus it is not used.
|
||||||
*/
|
*/
|
||||||
void VoxelManipulator::spreadLight(enum LightBank bank,
|
void VoxelManipulator::spreadLight(enum LightBank bank,
|
||||||
|
|
28
src/voxel.h
28
src/voxel.h
|
@ -263,6 +263,30 @@ public:
|
||||||
return index(p.X, p.Y, p.Z);
|
return index(p.X, p.Y, p.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translate index in the X coordinate
|
||||||
|
void add_x(const v3s16 &extent, u32 &i, s16 a)
|
||||||
|
{
|
||||||
|
i += a;
|
||||||
|
}
|
||||||
|
// Translate index in the Y coordinate
|
||||||
|
void add_y(const v3s16 &extent, u32 &i, s16 a)
|
||||||
|
{
|
||||||
|
i += a * extent.X;
|
||||||
|
}
|
||||||
|
// Translate index in the Z coordinate
|
||||||
|
void add_z(const v3s16 &extent, u32 &i, s16 a)
|
||||||
|
{
|
||||||
|
i += a * extent.X*extent.Y;
|
||||||
|
}
|
||||||
|
// Translate index in space
|
||||||
|
void add_p(const v3s16 &extent, u32 &i, v3s16 a)
|
||||||
|
{
|
||||||
|
i += a.Z*extent.X*extent.Y + a.Y*extent.X + a.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Print method for debugging
|
||||||
|
*/
|
||||||
void print(std::ostream &o) const
|
void print(std::ostream &o) const
|
||||||
{
|
{
|
||||||
v3s16 e = getExtent();
|
v3s16 e = getExtent();
|
||||||
|
@ -395,6 +419,10 @@ public:
|
||||||
void copyFrom(MapNode *src, VoxelArea src_area,
|
void copyFrom(MapNode *src, VoxelArea src_area,
|
||||||
v3s16 from_pos, v3s16 to_pos, v3s16 size);
|
v3s16 from_pos, v3s16 to_pos, v3s16 size);
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
void copyTo(MapNode *dst, VoxelArea dst_area,
|
||||||
|
v3s16 dst_pos, v3s16 from_pos, v3s16 size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Algorithms
|
Algorithms
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue