use of net.glowstone.chunk.ChunkSection 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);
// 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.ChunkSection in project Glowstone by GlowstoneMC.
the class AnvilChunkIoService method read.
/**
* Reads a chunk from its region file.
*
* @param chunk The GlowChunk to read into.
* @return Whether the
* @throws IOException if an I/O error occurs.
*/
@Override
public boolean read(GlowChunk chunk) throws IOException {
int x = chunk.getX(), z = chunk.getZ();
RegionFile region = cache.getRegionFile(x, z);
int regionX = x & REGION_SIZE - 1;
int regionZ = z & REGION_SIZE - 1;
if (!region.hasChunk(regionX, regionZ)) {
return false;
}
DataInputStream in = region.getChunkDataInputStream(regionX, regionZ);
CompoundTag levelTag;
try (NBTInputStream nbt = new NBTInputStream(in, false)) {
CompoundTag root = nbt.readCompound();
levelTag = root.getCompound("Level");
}
// read the vertical sections
List<CompoundTag> sectionList = levelTag.getCompoundList("Sections");
ChunkSection[] sections = new ChunkSection[GlowChunk.SEC_COUNT];
for (CompoundTag sectionTag : sectionList) {
int y = sectionTag.getByte("Y");
if (sections[y] != null) {
GlowServer.logger.log(Level.WARNING, "Multiple chunk sections at y " + y + " in " + chunk + "!");
continue;
}
if (y < 0 || y > GlowChunk.SEC_COUNT) {
GlowServer.logger.log(Level.WARNING, "Out of bounds chunk section at y " + y + " in " + chunk + "!");
continue;
}
sections[y] = ChunkSection.fromNBT(sectionTag);
}
// initialize the chunk
chunk.initializeSections(sections);
chunk.setPopulated(levelTag.getBool("TerrainPopulated"));
// read biomes
if (levelTag.isByteArray("Biomes")) {
chunk.setBiomes(levelTag.getByteArray("Biomes"));
}
// read height map
if (levelTag.isIntArray("HeightMap")) {
chunk.setHeightMap(levelTag.getIntArray("HeightMap"));
} else {
chunk.automaticHeightMap();
}
// read entities
if (levelTag.isList("Entities", TagType.COMPOUND)) {
for (CompoundTag entityTag : levelTag.getCompoundList("Entities")) {
try {
// note that creating the entity is sufficient to add it to the world
EntityStorage.loadEntity(chunk.getWorld(), entityTag);
} catch (Exception e) {
String id = entityTag.isString("id") ? entityTag.getString("id") : "<missing>";
if (e.getMessage() != null && e.getMessage().startsWith("Unknown entity type to load:")) {
GlowServer.logger.warning("Unknown entity in " + chunk + ": " + id);
} else {
GlowServer.logger.log(Level.WARNING, "Error loading entity in " + chunk + ": " + id, e);
}
}
}
}
// read block entities
List<CompoundTag> storedBlockEntities = levelTag.getCompoundList("TileEntities");
BlockEntity blockEntity;
for (CompoundTag blockEntityTag : storedBlockEntities) {
int tx = blockEntityTag.getInt("x");
int ty = blockEntityTag.getInt("y");
int tz = blockEntityTag.getInt("z");
blockEntity = chunk.createEntity(tx & 0xf, ty, tz & 0xf, chunk.getType(tx & 0xf, tz & 0xf, ty));
if (blockEntity != null) {
try {
blockEntity.loadNbt(blockEntityTag);
} catch (Exception ex) {
String id = blockEntityTag.isString("id") ? blockEntityTag.getString("id") : "<missing>";
GlowServer.logger.log(Level.SEVERE, "Error loading block entity at " + blockEntity.getBlock() + ": " + id, ex);
}
} else {
String id = blockEntityTag.isString("id") ? blockEntityTag.getString("id") : "<missing>";
GlowServer.logger.warning("Unknown block entity at " + chunk.getWorld().getName() + "," + tx + "," + ty + "," + tz + ": " + id);
}
}
if (levelTag.isList("TileTicks", TagType.COMPOUND)) {
List<CompoundTag> tileTicks = levelTag.getCompoundList("TileTicks");
for (CompoundTag tileTick : tileTicks) {
int tileX = tileTick.getInt("x");
int tileY = tileTick.getInt("y");
int tileZ = tileTick.getInt("z");
String id = tileTick.getString("i");
if (id.startsWith("minecraft:")) {
id = id.replace("minecraft:", "");
if (id.startsWith("flowing_")) {
id = id.replace("flowing_", "");
} else if (id.equals("water") || id.equals("lava")) {
id = "stationary_" + id;
}
}
Material material = Material.getMaterial(id.toUpperCase());
GlowBlock block = chunk.getBlock(tileX, tileY, tileZ);
if (material != block.getType()) {
continue;
}
// TODO tick delay: tileTick.getInt("t");
// TODO ordering: tileTick.getInt("p");
BlockType type = ItemTable.instance().getBlock(material);
if (type == null) {
continue;
}
block.getWorld().requestPulse(block);
}
}
return true;
}
use of net.glowstone.chunk.ChunkSection in project Glowstone by GlowstoneMC.
the class AnvilChunkIoService method write.
/**
* Writes a chunk to its region file.
*
* @param chunk The {@link GlowChunk} to write from.
* @throws IOException if an I/O error occurs.
*/
@Override
public void write(GlowChunk chunk) throws IOException {
int x = chunk.getX(), z = chunk.getZ();
RegionFile region = cache.getRegionFile(x, z);
int regionX = x & REGION_SIZE - 1;
int regionZ = z & REGION_SIZE - 1;
CompoundTag levelTags = new CompoundTag();
// core properties
levelTags.putInt("xPos", chunk.getX());
levelTags.putInt("zPos", chunk.getZ());
levelTags.putBool("TerrainPopulated", chunk.isPopulated());
levelTags.putLong("LastUpdate", 0);
// chunk sections
List<CompoundTag> sectionTags = new ArrayList<>();
GlowChunkSnapshot snapshot = chunk.getChunkSnapshot(true, true, false);
ChunkSection[] sections = snapshot.getRawSections();
for (byte i = 0; i < sections.length; ++i) {
ChunkSection sec = sections[i];
if (sec == null)
continue;
CompoundTag sectionTag = new CompoundTag();
sectionTag.putByte("Y", i);
sec.optimize();
sec.writeToNBT(sectionTag);
sectionTags.add(sectionTag);
}
levelTags.putCompoundList("Sections", sectionTags);
// height map and biomes
levelTags.putIntArray("HeightMap", snapshot.getRawHeightmap());
levelTags.putByteArray("Biomes", snapshot.getRawBiomes());
// entities
List<CompoundTag> entities = new ArrayList<>();
for (GlowEntity entity : chunk.getRawEntities()) {
if (!entity.shouldSave()) {
continue;
}
try {
CompoundTag tag = new CompoundTag();
EntityStorage.save(entity, tag);
entities.add(tag);
} catch (Exception e) {
GlowServer.logger.log(Level.WARNING, "Error saving " + entity + " in " + chunk, e);
}
}
levelTags.putCompoundList("Entities", entities);
// block entities
List<CompoundTag> blockEntities = new ArrayList<>();
for (BlockEntity entity : chunk.getRawBlockEntities()) {
try {
CompoundTag tag = new CompoundTag();
entity.saveNbt(tag);
blockEntities.add(tag);
} catch (Exception ex) {
GlowServer.logger.log(Level.SEVERE, "Error saving block entity at " + entity.getBlock(), ex);
}
}
levelTags.putCompoundList("TileEntities", blockEntities);
List<CompoundTag> tileTicks = new ArrayList<>();
for (Location location : chunk.getWorld().getTickMap()) {
if (location.getChunk().getX() == chunk.getX() && location.getChunk().getZ() == chunk.getZ()) {
int tileX = location.getBlockX();
int tileY = location.getBlockY();
int tileZ = location.getBlockZ();
String type = location.getBlock().getType().name().toLowerCase();
if (type.startsWith("stationary_")) {
type = type.replace("stationary_", "");
} else if (type.equals("water") || type.equals("lava")) {
type = "flowing_" + type;
}
CompoundTag tag = new CompoundTag();
tag.putInt("x", tileX);
tag.putInt("y", tileY);
tag.putInt("z", tileZ);
tag.putString("i", "minecraft:" + type);
tileTicks.add(tag);
}
}
levelTags.putCompoundList("TileTicks", tileTicks);
CompoundTag levelOut = new CompoundTag();
levelOut.putCompound("Level", levelTags);
try (NBTOutputStream nbt = new NBTOutputStream(region.getChunkDataOutputStream(regionX, regionZ), false)) {
nbt.writeTag(levelOut);
}
}
Aggregations