save() calls saveChunks() which saves any chunks found to be modified. But chunk unloading does this anyway, so it's better to unload first and then trigger the save mechanism, to avoid saving chunks twice.
it appears that errors are occurring in the exception handler when handling corrupted regions, leaving regions in the provider index with incomplete location tables. This causes strange-looking errors later down the line.
This moves the region assignment to the end of the condition to avoid leaving incomplete/corrupted regions in the location table when errors occur.
This now removes logging from the level providers (for the most part) and replaces it with exception throws and catches. The implementation using the providers should catch these exceptions if they are thrown.
This code is no longer necessary, because entities are constructed with a Level instead of a Chunk since API 3.0.0-ALPHA4. This means that they will not get allocated in the wrong chunk at runtime after having been saved on the wrong chunk by something else (such as an older version of PM). They will instead be allocated in a chunk selected by bitshifting their coordinates.
This is necessary to be able to fix#1789 without causing entities affected by the infamous bitshift-on-floats bugs to inexplicably vanish.
So this came from a bugfix (795d6c8ddf1148dfe6de8ff5ef38a96aee6124fe) which fixed a memory leak related to entities getting kill()ed on chunk unload.
HOWEVER, me2016 did NOT realize that this code is actually entirely pointless and causes unexpected behaviour.
removeEntity() is used in 2 places in the core code:
1. in Entity->close() (so close() doesn't need to be called again, obviously)
2. in Entity->switchLevel() (which then causes the entirely unexpected behaviour of close()ing the entity on level change.
Conclusion: This code is pointless. This fixes the bugfix.
MOP doesn't make any sense anyway.
RayTraceResult is a container which represents the point at which a line hits a bounding box. No dependence on blocks or entities is wanted or needed.
MovingObjectPosition has API changes to allow it to wrap RayTraceResult, but nothing uses MOP anymore anyway.
This would allow modularisation of the pocketmine\\math namespace.
Fixes#1903Closes#1906, which, while a pretty solution, is very inefficient (see PR discussion). This is an optimization of microscopic proportions, but the point still stands.
This is a rather larger commit than I'm happy with, but oh well.
This kills off the enormously overcomplicated BlockIterator and replaces it with a VoxelRayTrace class containing ray tracing generator functions. These functions are independent of any Level. They yield Vector3 objects with current ray trace positions to allow implementations to handle the intercepted blocks in their own ways.
Living->getLineOfSight() now uses VoxelRayTrace instead of BlockIterator.
This is annoying and it requires that the server must match this precisely to not cause bugs. Additionally, this code shits its pants when the client hits a spot of network lag.
This can be implemented easily as a plugin. There is no reason whatsoever for this to be in the core.
Since chunks are unloaded before changed blocks are processed, there is a small chance that a block might get changed in a chunk, and then get unloaded due to not being in use, before the updates are broadcasted.
This is unlikely to ever happen since chunks usually don't get unloaded unless they don't have loaders anyway, but it could happen (?) if a chunk is forcefully unloaded.
This now removes the need for recursing around for structures comprised of multiple blocks. Instead, override getAffectedBlocks() to return all blocks that need to be deleted when the current block is deleted, and make sure that only one half of the block drops something. When a player breaks one of the blocks, all the blocks affected by that block will also be destroyed, creating particles and sounds where appropriate.
This fixes creative drops for double plants and beds.
Level providers are now cut back to just an interface to a world's data. They don't keep their own chunk registries or any stupid shit like that because the Level already does that.
This furthers the goal of being able to move level I/O off the main thread, and also drastically decreases the complication of implementing level providers.