Fixed objects being sometimes not able to be stored statically in a block when block has been unloaded

This commit is contained in:
Perttu Ahola 2011-07-01 21:04:40 +03:00
parent 282912caa0
commit 71f5d4b344
5 changed files with 77 additions and 51 deletions

@ -1177,7 +1177,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
block->setChangedFlag();
}
else{
dstream<<"WARNING: Server: Could not find a block for "
dstream<<"WARNING: ServerEnv: Could not find a block for "
<<"storing newly added static active object"<<std::endl;
}
@ -1349,7 +1349,20 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
StaticObject s_obj(obj->getType(), objectpos, staticdata);
// Add to the block where the object is located in
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
// Get or generate the block
MapBlock *block = m_map->emergeBlock(blockpos);
/*MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
if(block == NULL)
{
// Block not found. Is the old block still ok?
if(oldblock)
block = oldblock;
// Load from disk or generate
else
block = m_map->emergeBlock(blockpos);
}*/
if(block)
{
block->m_static_objects.insert(0, s_obj);
@ -1357,17 +1370,9 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
obj->m_static_exists = true;
obj->m_static_block = block->getPos();
}
// If not possible, add back to previous block
else if(oldblock)
{
oldblock->m_static_objects.insert(0, s_obj);
oldblock->setChangedFlag();
obj->m_static_exists = true;
obj->m_static_block = oldblock->getPos();
}
else{
dstream<<"WARNING: Server: Could not find a block for "
<<"storing static object"<<std::endl;
dstream<<"WARNING: ServerEnv: Could not find or generate "
<<"a block for storing static object"<<std::endl;
obj->m_static_exists = false;
continue;
}

@ -126,6 +126,16 @@ SUGG: Erosion simulation at map generation time
- Simulate rock falling from cliffs when water has removed
enough solid rock from the bottom
SUGG: For non-mapgen FarMesh: Add a per-sector database to store surface
stuff as simple flags/values
- Light?
- A building?
And at some point make the server send this data to the client too,
instead of referring to the noise functions
- Ground height
- Surface ground type
- Trees?
Gaming ideas:
-------------
@ -199,12 +209,13 @@ SUGG: Make fetching sector's blocks more efficient when rendering
sectors that have very large amounts of blocks (on client)
- Is this necessary at all?
TODO: Flowing water animation
SUGG: Draw cubes in inventory directly with 3D drawing commands, so that
animating them is easier.
SUGG: Option for enabling proper alpha channel for textures
TODO: Flowing water animation
TODO: A setting for enabling bilinear filtering for textures
TODO: Better control of draw_control.wanted_max_blocks
@ -321,15 +332,6 @@ TODO: Think about using same bits for material for fences and doors, for
TODO: Move mineral to param2, increment map serialization version, add
conversion
TODO: Add a per-sector database to store surface stuff as simple flags/values
- Light?
- A building?
And at some point make the server send this data to the client too,
instead of referring to the noise functions
- Ground height
- Surface ground type
- Trees?
TODO: Restart irrlicht completely when coming back to main menu from game.
- This gets rid of everything that is stored in irrlicht's caches.

@ -2442,23 +2442,51 @@ MapBlock * ServerMap::createBlock(v3s16 p)
return block;
}
#if 0
MapBlock * ServerMap::emergeBlock(
v3s16 p,
bool only_from_disk,
core::map<v3s16, MapBlock*> &changed_blocks,
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
)
MapBlock * ServerMap::emergeBlock(v3s16 p, bool allow_generate)
{
DSTACKF("%s: p=(%d,%d,%d), only_from_disk=%d",
DSTACKF("%s: p=(%d,%d,%d), allow_generate=%d",
__FUNCTION_NAME,
p.X, p.Y, p.Z, only_from_disk);
p.X, p.Y, p.Z, allow_generate);
{
MapBlock *block = getBlockNoCreateNoEx(p);
if(block)
return block;
}
{
MapBlock *block = loadBlock(p);
if(block)
return block;
}
if(allow_generate)
{
core::map<v3s16, MapBlock*> modified_blocks;
MapBlock *block = generateBlock(p, modified_blocks);
if(block)
{
MapEditEvent event;
event.type = MEET_OTHER;
event.p = p;
// Copy modified_blocks to event
for(core::map<v3s16, MapBlock*>::Iterator
i = modified_blocks.getIterator();
i.atEnd()==false; i++)
{
event.modified_blocks.insert(i.getNode()->getKey(), false);
}
// Queue event
dispatchEvent(&event);
return block;
}
}
// This has to be redone or removed
assert(0);
return NULL;
}
#endif
#if 0
/*

@ -57,7 +57,7 @@ enum MapEditEventType{
// Node metadata of block changed (not knowing which node exactly)
// p stores block coordinate
MEET_BLOCK_NODE_METADATA_CHANGED,
// Anything else
// Anything else (modified_blocks are set unsent)
MEET_OTHER
};
@ -338,24 +338,13 @@ public:
*/
MapBlock * createBlock(v3s16 p);
#if 0
/*
NOTE: This comment might be outdated
Forcefully get a block from somewhere.
InvalidPositionException possible if only_from_disk==true
Parameters:
changed_blocks: Blocks that have been modified
- Memory
- Load from disk
- Generate
*/
MapBlock * emergeBlock(
v3s16 p,
bool only_from_disk,
core::map<v3s16, MapBlock*> &changed_blocks,
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
);
#endif
MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
// Helper for placing objects on ground level
s16 findGroundLevel(v2s16 p2d);

@ -1739,6 +1739,7 @@ void Server::AsyncRunStep()
*/
if(far_players.size() > 0)
{
// Convert list format to that wanted by SetBlocksNotSent
core::map<v3s16, MapBlock*> modified_blocks2;
for(core::map<v3s16, bool>::Iterator
i = event->modified_blocks.getIterator();
@ -1748,6 +1749,7 @@ void Server::AsyncRunStep()
modified_blocks2.insert(p,
m_env.getMap().getBlockNoCreateNoEx(p));
}
// Set blocks not sent
for(core::list<u16>::Iterator
i = far_players.begin();
i != far_players.end(); i++)