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)
|
||||
{
|
||||
m_running = true;
|
||||
m_main_thread = get_current_thread_id();
|
||||
m_device_mutex.Init();
|
||||
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)
|
||||
{
|
||||
u32 id = m_namecache.getId(name);
|
||||
|
@ -73,6 +79,10 @@ video::ITexture* IrrlichtWrapper::getTexture(const TextureSpec &spec)
|
|||
}
|
||||
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
|
||||
ResultQueue<TextureSpec, video::ITexture*, u8, u8> result_queue;
|
||||
|
||||
|
|
|
@ -132,11 +132,15 @@ public:
|
|||
/*
|
||||
These are called from the main thread
|
||||
*/
|
||||
|
||||
IrrlichtWrapper(IrrlichtDevice *device);
|
||||
|
||||
// Run queued tasks
|
||||
void Run();
|
||||
|
||||
// Shutdown wrapper; this disables queued texture fetching
|
||||
void Shutdown(bool shutdown);
|
||||
|
||||
/*
|
||||
These are called from other threads
|
||||
*/
|
||||
|
@ -182,6 +186,8 @@ private:
|
|||
Members
|
||||
*/
|
||||
|
||||
bool m_running;
|
||||
|
||||
// The id of the thread that can (and has to) use irrlicht directly
|
||||
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
|
||||
the blocks are actually needed - it would be quite fast
|
||||
- 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
|
||||
* Carve out stuff in the stone
|
||||
* 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.
|
||||
- Simulate rock falling from cliffs when water has removed
|
||||
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:
|
||||
----------
|
||||
# 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
|
||||
*/
|
||||
|
@ -3017,6 +3032,14 @@ int main(int argc, char *argv[])
|
|||
|
||||
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
|
||||
|
||||
} //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);
|
||||
// On failure throws InvalidPositionException
|
||||
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
|
||||
|
@ -104,6 +106,8 @@ public:
|
|||
MapBlock * getBlockNoCreate(v3s16 p);
|
||||
// Returns NULL if not found
|
||||
MapBlock * getBlockNoCreateNoEx(v3s16 p);
|
||||
// Gets an existing block or creates an empty one
|
||||
//MapBlock * getBlockCreate(v3s16 p);
|
||||
|
||||
// Returns InvalidPositionException if not found
|
||||
f32 getGroundHeight(v2s16 p, bool generate=false);
|
||||
|
@ -382,12 +386,20 @@ public:
|
|||
|
||||
This is mainly called by generateChunkRaw.
|
||||
*/
|
||||
ServerMapSector * generateSector(v2s16 p);
|
||||
//ServerMapSector * generateSector(v2s16 p);
|
||||
|
||||
/*
|
||||
Get a sector from somewhere.
|
||||
- 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
|
||||
*/
|
||||
MapSector * emergeSector(v2s16 p);
|
||||
|
@ -400,6 +412,13 @@ public:
|
|||
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
|
||||
);
|
||||
|
||||
/*
|
||||
Get a block from somewhere.
|
||||
- Memory
|
||||
- Create blank
|
||||
*/
|
||||
MapBlock * createBlock(v3s16 p);
|
||||
|
||||
MapBlock * emergeBlock(
|
||||
v3s16 p,
|
||||
bool only_from_disk,
|
||||
|
@ -636,10 +655,8 @@ public:
|
|||
protected:
|
||||
Map *m_map;
|
||||
/*
|
||||
NOTE: This might be used or not
|
||||
bool is dummy value
|
||||
SUGG: How 'bout an another VoxelManipulator for storing the
|
||||
information about which block is loaded?
|
||||
key = blockpos
|
||||
value = block existed when loaded
|
||||
*/
|
||||
core::map<v3s16, bool> m_loaded_blocks;
|
||||
};
|
||||
|
@ -654,7 +671,11 @@ public:
|
|||
|
||||
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:
|
||||
bool m_create_area;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1309,10 +1309,21 @@ void MapBlock::copyTo(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 data to VoxelManipulator
|
||||
dst.copyFrom(data, data_area, v3s16(0,0,0),
|
||||
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)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -426,6 +426,8 @@ public:
|
|||
|
||||
// Copies data to VoxelManipulator to getPosRelative()
|
||||
void copyTo(VoxelManipulator &dst);
|
||||
// Copies data from VoxelManipulator getPosRelative()
|
||||
void copyFrom(VoxelManipulator &dst);
|
||||
|
||||
/*
|
||||
MapBlockObject stuff
|
||||
|
|
|
@ -438,6 +438,14 @@ struct MapNode
|
|||
param2 = a_param2;
|
||||
}
|
||||
|
||||
/*MapNode & operator=(const MapNode &other)
|
||||
{
|
||||
d = other.d;
|
||||
param = other.param;
|
||||
param2 = other.param2;
|
||||
return *this;
|
||||
}*/
|
||||
|
||||
bool operator==(const MapNode &other)
|
||||
{
|
||||
return (d == other.d
|
||||
|
|
|
@ -570,10 +570,15 @@ ServerMapSector* ServerMapSector::deSerialize(
|
|||
|
||||
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."
|
||||
<<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
|
||||
|
||||
//sector = n->getValue();
|
||||
|
|
|
@ -606,6 +606,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
|||
{
|
||||
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(
|
||||
nodepos.X,
|
||||
groundheight + 1,
|
||||
//groundheight + 1,
|
||||
groundheight + 15,
|
||||
nodepos.Y
|
||||
)));
|
||||
|
||||
|
|
|
@ -207,6 +207,10 @@ public:
|
|||
{
|
||||
return ptr == t;
|
||||
}
|
||||
T & operator[](unsigned int i)
|
||||
{
|
||||
return ptr[i];
|
||||
}
|
||||
private:
|
||||
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)
|
||||
{
|
||||
if(i < min)
|
||||
|
@ -1459,6 +1472,13 @@ int myrand(void);
|
|||
void mysrand(unsigned seed);
|
||||
#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
|
||||
coordinate points
|
||||
|
|
|
@ -41,7 +41,6 @@ VoxelManipulator::VoxelManipulator():
|
|||
m_data(NULL),
|
||||
m_flags(NULL)
|
||||
{
|
||||
m_disable_water_climb = false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -541,7 +556,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
|
|||
Lights neighbors of from_nodes, collects all them and then
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
v3s16 e = getExtent();
|
||||
|
@ -395,6 +419,10 @@ public:
|
|||
void copyFrom(MapNode *src, VoxelArea src_area,
|
||||
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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue