use of net.glowstone.chunk.GlowChunk in project Glowstone by GlowstoneMC.
the class GlowWorld method updateBlocksInActiveChunks.
private void updateBlocksInActiveChunks() {
for (Key key : activeChunksSet) {
int cx = key.getX();
int cz = key.getZ();
// check the chunk is loaded
if (isChunkLoaded(cx, cz)) {
GlowChunk chunk = getChunkAt(cx, cz);
// thunder
maybeStrikeLightningInChunk(cx, cz);
// chunk tick
chunk.addTick();
// block ticking
// we will choose 3 blocks per chunk's section
ChunkSection[] sections = chunk.getSections();
for (int i = 0; i < sections.length; i++) {
updateBlocksInSection(chunk, sections[i], i);
}
}
}
}
use of net.glowstone.chunk.GlowChunk in project Glowstone by GlowstoneMC.
the class GlowPlayer method streamBlocks.
/**
* Streams chunks to the player's client.
*/
private void streamBlocks() {
Set<Key> previousChunks = null;
ArrayList<Key> newChunks = new ArrayList<>();
int centralX = location.getBlockX() >> 4;
int centralZ = location.getBlockZ() >> 4;
int radius = Math.min(server.getViewDistance(), 1 + settings.getViewDistance());
if (firstStream) {
firstStream = false;
for (int x = centralX - radius; x <= centralX + radius; x++) {
for (int z = centralZ - radius; z <= centralZ + radius; z++) {
newChunks.add(GlowChunk.Key.of(x, z));
}
}
} else if (Math.abs(centralX - prevCentralX) > radius || Math.abs(centralZ - prevCentralZ) > radius) {
knownChunks.clear();
for (int x = centralX - radius; x <= centralX + radius; x++) {
for (int z = centralZ - radius; z <= centralZ + radius; z++) {
newChunks.add(GlowChunk.Key.of(x, z));
}
}
} else if (forceStream || prevCentralX != centralX || prevCentralZ != centralZ) {
previousChunks = new HashSet<>(knownChunks);
for (int x = centralX - radius; x <= centralX + radius; x++) {
for (int z = centralZ - radius; z <= centralZ + radius; z++) {
Key key = GlowChunk.Key.of(x, z);
if (knownChunks.contains(key)) {
previousChunks.remove(key);
} else {
newChunks.add(key);
}
}
}
} else {
// early end if there's no changes
return;
}
prevCentralX = centralX;
prevCentralZ = centralZ;
// sort chunks by distance from player - closer chunks sent first
newChunks.sort((a, b) -> {
double dx = 16 * a.getX() + 8 - location.getX();
double dz = 16 * a.getZ() + 8 - location.getZ();
double da = dx * dx + dz * dz;
dx = 16 * b.getX() + 8 - location.getX();
dz = 16 * b.getZ() + 8 - location.getZ();
double db = dx * dx + dz * dz;
return Double.compare(da, db);
});
// populate then send chunks to the player
// done in two steps so that all the new chunks are finalized before any of them are sent
// this prevents sending a chunk then immediately sending block changes in it because
// one of its neighbors has populated
// first step: force population then acquire lock on each chunk
newChunks.forEach(newChunk -> {
try {
world.getChunkManager().forcePopulation(newChunk.getX(), newChunk.getZ());
} catch (IllegalArgumentException e) {
// The show must go on, so catch it here!
logger.log(Level.SEVERE, "", e);
}
knownChunks.add(newChunk);
chunkLock.acquire(newChunk);
});
boolean skylight = world.getEnvironment() == Environment.NORMAL;
ByteBufAllocator alloc = session.getChannel() == null ? null : session.getChannel().alloc();
for (GlowChunk.Key key : newChunks) {
GlowChunk chunk = world.getChunk(key);
ChunkDataMessage message = chunk.toMessage(skylight, true, alloc);
if (message == null || message.getData() == null) {
// allocator failed
break;
}
session.sendAndRelease(message, message.getData());
}
// send visible block entity data
newChunks.stream().flatMap(key -> world.getChunkAt(key.getX(), key.getZ()).getRawBlockEntities().stream()).forEach(entity -> entity.update(this));
// and remove old chunks
if (previousChunks != null) {
previousChunks.forEach(key -> {
session.send(new UnloadChunkMessage(key.getX(), key.getZ()));
knownChunks.remove(key);
chunkLock.release(key);
});
previousChunks.clear();
}
}
use of net.glowstone.chunk.GlowChunk in project Glowstone by GlowstoneMC.
the class EntityManager method move.
/**
* Notes that an entity has moved from one location to another for physics and storage purposes.
*
* @param entity The entity.
* @param newLocation The new location.
*/
void move(GlowEntity entity, Location newLocation) {
Chunk prevChunk = entity.location.getChunk();
Chunk newChunk = newLocation.getChunk();
if (prevChunk != newChunk) {
((GlowChunk) prevChunk).getRawEntities().remove(entity);
((GlowChunk) newChunk).getRawEntities().add(entity);
}
}
use of net.glowstone.chunk.GlowChunk in project Glowstone by GlowstoneMC.
the class GlowBlock method setTypeIdAndData.
@Deprecated
public boolean setTypeIdAndData(int type, byte data, boolean applyPhysics) {
Material oldTypeId = getType();
byte oldData = getData();
GlowChunk chunk = (GlowChunk) world.getChunkAt(this);
Material material = ((GlowServer) Bukkit.getServer()).getBlockDataManager().convertToBlockData(type).getMaterial();
chunk.setType(x & 0xf, z & 0xf, y, material);
chunk.setMetaData(x & 0xf, z & 0xf, y, data);
if (applyPhysics) {
applyPhysics(oldTypeId, material, oldData, data);
}
GlowChunk.Key key = GlowChunk.Key.of(x >> 4, z >> 4);
BlockChangeMessage bcmsg = new BlockChangeMessage(x, y, z, type, data);
world.broadcastBlockChangeInRange(key, bcmsg);
return true;
}
use of net.glowstone.chunk.GlowChunk in project Glowstone by GlowstoneMC.
the class BlockPiston method setType.
// update block server side without sending block change packets
private void setType(Block block, Material type, int data) {
World world = block.getWorld();
int x = block.getX();
int y = block.getY();
int z = block.getZ();
GlowChunk chunk = (GlowChunk) world.getChunkAt(block);
chunk.setType(x & 0xf, z & 0xf, y, type);
chunk.setMetaData(x & 0xf, z & 0xf, y, data);
}
Aggregations