private void updateObserver() { // Player view distance is handled in the network synchronizer if (controllerLive.get() instanceof PlayerController) { return; } int viewDistance = (getViewDistance() + 15) / Chunk.CHUNK_SIZE; // round up World w = transform.getPosition().getWorld(); int cx = chunkLive.get().getX(); int cy = chunkLive.get().getY(); int cz = chunkLive.get().getZ(); HashSet<SpoutChunk> observing = new HashSet<SpoutChunk>(viewDistance * viewDistance * viewDistance); for (int dx = -viewDistance; dx < viewDistance; dx++) { for (int dy = -viewDistance; dy < viewDistance; dy++) { for (int dz = -viewDistance; dz < viewDistance; dz++) { Chunk chunk = w.getChunk(cx + dx, cy + dy, cz + dz, true); chunk.refreshObserver(this); observing.add((SpoutChunk) chunk); } } } observingChunks.removeAll(observing); for (SpoutChunk chunk : observingChunks) { if (chunk.isLoaded()) { chunk.removeObserver(this); } } observingChunks.clear(); observingChunks.addAll(observing); }
@Override public void populate(Chunk source, Random random) { if (source.getY() < 4) { return; } if (random.nextInt(100) > chance) { return; } int x = source.getBlockX(); int z = source.getBlockZ(); int y; int numSteps = random.nextInt(maxSteps - minSteps + 1) + minSteps; for (int i = 0; i < numSteps; i++) { x += random.nextInt(3) - 1; z += random.nextInt(3) - 1; y = source.getBlockY() + 15; Block b = source.getWorld().getBlock(x, y, z); while (b.getMaterial() == VanillaMaterials.AIR) { b = b.translate(BlockFace.BOTTOM); if (--y < 0) { return; } } if (b.getMaterial() == VanillaMaterials.GRASS) { b = b.translate(BlockFace.TOP).setMaterial(VanillaMaterials.TALL_GRASS); } } }
@Override public void populate(Chunk source, Random random) { World world = source.getWorld(); int[] iterations = new int[] {10, 20, 20, 2, 8, 1, 1, 1}; int[] amount = new int[] {32, 16, 8, 8, 7, 7, 6}; BlockMaterial[] type = new BlockMaterial[] { VanillaMaterials.GRAVEL, VanillaMaterials.COAL_ORE, VanillaMaterials.IRON_ORE, VanillaMaterials.GOLD_ORE, VanillaMaterials.REDSTONE_ORE, VanillaMaterials.DIAMOND_ORE, VanillaMaterials.LAPIS_LAZULI_ORE }; int[] maxHeight = new int[] {128, 128, 128, 128, 128, 64, 32, 16, 16, 32}; for (int i = 0; i < type.length; i++) { for (int j = 0; j < iterations[i]; j++) { generateOre( world, random, source.getX() * 16 + random.nextInt(16), random.nextInt(maxHeight[i]), source.getZ() * 16 + random.nextInt(16), amount[i], type[i]); } } }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } if (random.nextInt(odd) != 0) { return; } final World world = chunk.getWorld(); final int amount = getAmount(random); for (byte count = 0; count < amount; count++) { final int x = chunk.getBlockX(random); final int y = random.nextInt(NetherGenerator.HEIGHT); final int z = chunk.getBlockZ(random); final Mushroom mushroom = random.nextInt(4) == 0 ? VanillaMaterials.RED_MUSHROOM : VanillaMaterials.BROWN_MUSHROOM; for (byte size = 6; size > 0; size--) { final int xx = x - 7 + random.nextInt(15); final int zz = z - 7 + random.nextInt(15); final int yy = getHighestWorkableBlock(world, xx, y, zz); if (yy != -1 && world.getBlockMaterial(xx, yy, zz) == VanillaMaterials.AIR && mushroom.isValidPosition(world.getBlock(xx, yy, zz), BlockFace.BOTTOM, false)) { world.setBlockMaterial(xx, yy, zz, mushroom, (short) 0, null); } } } }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } final World world = chunk.getWorld(); final OreObject[] ores = new OreObject[] { new OreObject(OreType.DIRT), new OreObject(OreType.GRAVEL), new OreObject(OreType.COAL), new OreObject(OreType.IRON), new OreObject(OreType.REDSTONE), new OreObject(OreType.GOLD), new OreObject(OreType.LAPIS_LAZULI), new OreObject(OreType.DIAMOND) }; for (OreObject ore : ores) { ore.setRandom(random); for (byte i = 0; i < ore.getAmount(); i++) { final int x = chunk.getBlockX(random); final int y = random.nextInt(ore.getMaxHeight()); final int z = chunk.getBlockZ(random); if (ore.canPlaceObject(world, x, y, z)) { ore.placeObject(world, x, y, z); } } } }
@Override public <T extends CuboidLightBuffer> T getLightBuffer( LightingManager<T> manager, int x, int y, int z, LoadOption loadopt) { Chunk c = getChunk(x, y, z, loadopt); if (c == null) { return null; } return c.getLightBuffer(manager); }
@Override public void updateBlock(Chunk chunk, int x, int y, int z, BlockMaterial material, short data) { short id = getMinecraftId(material); x += chunk.getBlockX(); y += chunk.getBlockY(); z += chunk.getBlockZ(); BlockChangeMessage BCM = new BlockChangeMessage( x, y, z, id, getMinecraftData(material, data), getRepositionManager()); session.send(false, BCM); }
@Override public void updateBlock(Chunk chunk, int x, int y, int z, BlockMaterial material, short data) { short id = getMinecraftId(material); x += chunk.getBlockX(); y += chunk.getBlockY(); z += chunk.getBlockZ(); if (y >= 0 && y < chunk.getWorld().getHeight()) { BlockChangeMessage BCM = new BlockChangeMessage(x, y, z, id, getMinecraftData(material, data)); session.send(false, BCM); } }
public Collection<Chunk> getChunks(Chunk c) { if (this.sendColumn()) { int x = c.getX(); int z = c.getZ(); int height = c.getWorld().getHeight() >> Chunk.BLOCKS.BITS; List<Chunk> chunks = new ArrayList<Chunk>(height); for (int y = 0; y < height; y++) { chunks.add(c.getWorld().getChunk(x, y, z)); } return chunks; } else { List<Chunk> chunks = new ArrayList<Chunk>(1); chunks.add(c); return chunks; } }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } final World world = chunk.getWorld(); for (OreObject object : ORES) { object.setRandom(random); for (byte i = 0; i < object.getCount(); i++) { final int x = chunk.getBlockX(random); final int y = random.nextInt(object.getMaxHeight()); final int z = chunk.getBlockZ(random); object.placeObject(world, x, y, z); } } }
public SpoutBlock(World world, int x, int y, int z, Chunk chunk, Source source) { this.x = x; this.y = y; this.z = z; this.world = world; this.source = source == null ? world : source; this.chunk = chunk != null && chunk.containsBlock(x, y, z) ? chunk : null; }
@Override protected boolean canSendChunk(Chunk c, Set<Chunk> unsendable) { if (!c.canSend()) { if (unsendable != null) { unsendable.add(c); } c.populate(true, true, true); return false; } if (activeChunks.contains(c.getX(), c.getZ())) { return true; } boolean canSend = true; Collection<Chunk> chunks = chunkInit.getChunks(c); for (Chunk cc : chunks) { if (!cc.canSend()) { if (unsendable != null) { unsendable.add(c); } canSend = false; cc.populate(true, true, true); } } return canSend; }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } if (random.nextInt(ODD) != 0) { return; } final World world = chunk.getWorld(); final int x = chunk.getBlockX(random); final int z = chunk.getBlockZ(random); final int y = getHighestWorkableBlock(world, x, z); if (y == -1) { return; } if (well.canPlaceObject(world, x, y, z)) { well.placeObject(world, x, y, z); } }
public static byte[] getChunkFullData(Chunk c, List<ProtocolEvent> updateEvents) { VanillaContainer container = new VanillaContainer(); c.fillBlockContainer(container); container.setLightMode(true); c.fillBlockLightContainer(container); container.setLightMode(false); c.fillSkyLightContainer(container); c.fillBlockComponentContainer(container); int[] componentX = container.getXArray(); int[] componentY = container.getYArray(); int[] componentZ = container.getZArray(); for (int i = 0; i < container.getBlockComponentCount(); i++) { BlockMaterial bm = c.getBlockMaterial(componentX[i], componentY[i], componentZ[i]); if (bm instanceof VanillaComplexMaterial) { ProtocolEvent event = ((VanillaComplexMaterial) bm) .getUpdate(c.getWorld(), componentX[i], componentY[i], componentZ[i]); if (event != null) { updateEvents.add(event); } } } return container.getChunkFullData(); }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } final World world = chunk.getWorld(); if (random.nextInt(WATER_ODD) == 0) { final int x = chunk.getBlockX(random); final int z = chunk.getBlockZ(random); final int y = random.nextInt(128); WATER_POND.setRandom(random); WATER_POND.randomize(); if (WATER_POND.canPlaceObject(world, x, y, z)) { WATER_POND.placeObject(world, x, y, z); } } if (random.nextInt(LAVA_ODD) == 0) { final int x = chunk.getBlockX(random); final int z = chunk.getBlockZ(random); final int y = random.nextInt(120) + 8; if (y >= 63 && random.nextInt(LAVA_SURFACE_ODD) != 0) { return; } LAVA_POND.setRandom(random); LAVA_POND.randomize(); if (LAVA_POND.canPlaceObject(world, x, y, z)) { LAVA_POND.placeObject(world, x, y, z); } } }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } final World world = chunk.getWorld(); for (byte count = 0; count < amount; count++) { final int x = chunk.getBlockX(random); final int z = chunk.getBlockZ(random); for (byte size = 5; size > 0; size--) { final int xx = x - 7 + random.nextInt(15); final int zz = z - 7 + random.nextInt(15); final int yy = getHighestWorkableBlock(world, xx, zz); if (yy != -1 && world.getBlockMaterial(xx, yy, zz) == VanillaMaterials.AIR && VanillaMaterials.LILY_PAD.canAttachTo( world.getBlock(xx, yy - 1, zz, world), BlockFace.TOP)) { world.setBlockMaterial(xx, yy, zz, VanillaMaterials.LILY_PAD, (short) 0, world); } } } }
@Override public void populate(Chunk chunk, Random random) { if (chunk.getY() != 4) { return; } final int size = Chunk.BLOCKS.SIZE; final int x = chunk.getBlockX(); final int z = chunk.getBlockZ(); final World world = chunk.getWorld(); final int seed = (int) (world.getSeed() * 73); SHIELD_BASE.setSeed(seed); SHIELD.setSeed(seed); final double[][] noise = WorldGeneratorUtils.fastNoise(SHIELD, size, size, 4, x, 63, z); for (int xx = 0; xx < size; xx++) { for (int zz = 0; zz < size; zz++) { if (noise[xx][zz] > 0.92) { final int y = world.getSurfaceHeight(x + xx, z + zz); for (int yy = 0; yy >= -7; yy--) { if (yy == 0) { final Block block = world.getBlock(x + xx, y + yy, z + zz, world); if (!canReplace(block.getMaterial())) { continue; } block.setMaterial( block.getY() <= NormalGenerator.SEA_LEVEL ? VanillaMaterials.STATIONARY_WATER : VanillaMaterials.AIR); } else { if (canReplace(world.getBlockMaterial(x + xx, y + yy, z + zz))) { world.setBlockMaterial( x + xx, y + yy, z + zz, VanillaMaterials.STONE, (short) 0, world); } } } } } } }
public static byte[] getChunkFullData(Chunk c) { ChunkSnapshot snapshot = c.getSnapshot(SnapshotType.BOTH, EntityType.NO_ENTITIES, ExtraData.NO_EXTRA_DATA); short[] rawBlockIdArray = snapshot.getBlockIds(); short[] rawBlockData = snapshot.getBlockData(); byte[] rawBlockLight = snapshot.getBlockLight(); byte[] rawSkyLight = snapshot.getSkyLight(); byte[] fullChunkData = new byte[Chunk.BLOCKS.HALF_VOLUME * 5]; int arrIndex = 0; BlockMaterial material1, material2; for (int i = 0; i < rawBlockIdArray.length; i += 2) { material1 = BlockMaterial.get(rawBlockIdArray[i]); material2 = BlockMaterial.get(rawBlockIdArray[i + 1]); // data fullChunkData[arrIndex + rawBlockIdArray.length] = (byte) ((getMinecraftData(material2, rawBlockData[i + 1]) << 4) | (getMinecraftData(material1, rawBlockData[i]))); // id fullChunkData[i] = (byte) (getMinecraftId(material1) & 0xFF); fullChunkData[i + 1] = (byte) (getMinecraftId(material2) & 0xFF); arrIndex++; } arrIndex = rawBlockIdArray.length + (rawBlockData.length >> 1); // The old method which doesn't use the Minecraft data conversion function /* for (int i = 0; i < rawBlockData.length; i += 2) { fullChunkData[arrIndex++] = (byte) ((rawBlockData[i + 1] << 4) | (rawBlockData[i] & 0xF)); } */ System.arraycopy(rawBlockLight, 0, fullChunkData, arrIndex, rawBlockLight.length); arrIndex += rawBlockLight.length; System.arraycopy(rawSkyLight, 0, fullChunkData, arrIndex, rawSkyLight.length); arrIndex += rawSkyLight.length; return fullChunkData; }
private SpoutChunk[][][] getChunks(int x, int y, int z, CuboidBlockMaterialBuffer buffer) { Vector3 size = buffer.getSize(); int startX = x; int startY = y; int startZ = z; int endX = x + size.getFloorX(); int endY = y + size.getFloorY(); int endZ = z + size.getFloorZ(); Chunk start = getChunkFromBlock(startX, startY, startZ); Chunk end = getChunkFromBlock(endX - 1, endY - 1, endZ - 1); int chunkStartX = start.getX(); int chunkStartY = start.getY(); int chunkStartZ = start.getZ(); int chunkEndX = end.getX(); int chunkEndY = end.getY(); int chunkEndZ = end.getZ(); int chunkSizeX = chunkEndX - chunkStartX + 1; int chunkSizeY = chunkEndY - chunkStartY + 1; int chunkSizeZ = chunkEndZ - chunkStartZ + 1; SpoutChunk[][][] chunks = new SpoutChunk[chunkSizeX][chunkSizeY][chunkSizeZ]; for (int dx = chunkStartX; dx <= chunkEndX; dx++) { for (int dy = chunkStartY; dy <= chunkEndY; dy++) { for (int dz = chunkStartZ; dz <= chunkEndZ; dz++) { SpoutChunk chunk = getChunk(dx, dy, dz, LoadOption.LOAD_GEN); if (chunk == null) { throw new IllegalStateException("Null chunk loaded with LoadOption.LOAD_GEN"); } chunks[dx - chunkStartX][dy - chunkStartY][dz - chunkStartZ] = chunk; } } } return chunks; }
/** * Gets a vertical column of chunks * * @param middle chunk * @return list of chunks in the column */ public static List<Chunk> getChunkColumn(Chunk middle) { Chunk top = middle; Chunk tmp; while (true) { tmp = top.getRelative(BlockFace.TOP, LoadOption.NO_LOAD); if (tmp != null && tmp.isLoaded()) { top = tmp; } else { break; } } List<Chunk> rval = new ArrayList<Chunk>(); while (top != null && top.isLoaded()) { rval.add(top); top = top.getRelative(BlockFace.BOTTOM, LoadOption.NO_LOAD); } return rval; }
public int loadChunks(int max_to_load) { long t0 = System.nanoTime(); int cnt = 0; if (iterator == null) iterator = chunks.listIterator(); DynmapCore.setIgnoreChunkLoads(true); // Load the required chunks. while ((cnt < max_to_load) && iterator.hasNext()) { DynmapChunk chunk = iterator.next(); boolean vis = true; if (visible_limits != null) { vis = false; for (VisibilityLimit limit : visible_limits) { if ((chunk.x >= limit.x0) && (chunk.x <= limit.x1) && (chunk.z >= limit.z0) && (chunk.z <= limit.z1)) { vis = true; break; } } } if (vis && (hidden_limits != null)) { for (VisibilityLimit limit : hidden_limits) { if ((chunk.x >= limit.x0) && (chunk.x <= limit.x1) && (chunk.z >= limit.z0) && (chunk.z <= limit.z1)) { vis = false; break; } } } chunks_attempted++; int rx = chunk.x >> Region.CHUNKS.BITS; int ry = 0; int rz = chunk.z >> Region.CHUNKS.BITS; Region r = null; /* Loop through chunks in Y axis */ for (int yy = 0; yy <= y_max; yy++) { int nry = yy >> Region.CHUNKS.BITS; if (nry != ry) { r = null; ry = nry; } if (r == null) { r = w.getRegion(rx, ry, rz, LoadOption.LOAD_ONLY); } if (r == null) continue; Chunk c = r.getChunk(chunk.x & 0xF, yy & 0xF, chunk.z & 0xF, LoadOption.LOAD_ONLY); ChunkSnapshot b = null; if (c != null) { b = c.getSnapshot(SnapshotType.BOTH, EntityType.NO_ENTITIES, ExtraData.NO_EXTRA_DATA); // if(!loaded) { // w.unloadChunk(chunk.x, yy, chunk.z, false); // } /* Test if chunk is empty */ if (b != null) { short[] bids = b.getBlockIds(); byte[] blight = b.getBlockLight(); byte[] slight = b.getSkyLight(); if (Arrays.equals(bids, zero) && Arrays.equals(blight, zerobyte) && Arrays.equals(slight, ffbyte)) { b = EMPTY; } } } snaparray[(chunk.x - x_min) + (chunk.z - z_min) * x_dim + (yy * xz_dim)] = b; } cnt++; } DynmapCore.setIgnoreChunkLoads(false); if (iterator.hasNext() == false) { /* If we're done */ isempty = true; /* Fill missing chunks with empty dummy chunk */ for (int i = 0; i < snaparray.length; i++) { if (snaparray[i] == null) snaparray[i] = EMPTY; else if (snaparray[i] != EMPTY) isempty = false; } } total_loadtime += System.nanoTime() - t0; return cnt; }
@Override public void populate(Chunk chunk, Random random) { if (random.nextInt(PROBABILITY) == 0) { final int width = random.nextBoolean() ? 9 : 7; final int height = random.nextBoolean() ? 9 : 7; int cx = chunk.getX() * 16 + random.nextInt(16); int cy = chunk.getY() * 16 + random.nextInt(16); int cz = chunk.getZ() * 16 + random.nextInt(16); if (chunk.getWorld().getBlockId(cx, cy, cz) == 0) { return; // No dungeons in the air, plox! } for (int x = cx; x < cx + width; x++) { for (int y = cy; y < cy + HEIGHT; y++) { for (int z = cz; z < cz + height; z++) { short id = 0; if (x == cx || x == cx + width - 1 || z == cz || z == cz + height - 1) { id = VanillaMaterials.COBBLESTONE.getId(); } if (y == cy || y == cy + HEIGHT - 1) { id = random.nextBoolean() ? VanillaMaterials.COBBLESTONE.getId() : VanillaMaterials.MOSS_STONE.getId(); } chunk.getWorld().setBlockId(x, y, z, id, chunk.getWorld()); } } } chunk .getWorld() .setBlockMaterial( cx + width / 2, cy + 1, cz + height / 2, VanillaMaterials.MONSTER_SPAWNER, chunk.getWorld()); chunk .getWorld() .setBlockMaterial( cx + 1, cy + 1, cz + height / 2, VanillaMaterials.CHEST, chunk.getWorld()); chunk .getWorld() .setBlockMaterial( cx + width / 2, cy + 1, cz + 1, VanillaMaterials.CHEST, chunk.getWorld()); // TODO Fill Chests with stuff, kinda waiting for inventories in worlds. } }
@Override public void sendChunk(Chunk c) { int x = c.getX(); int y = c.getY(); // + SEALEVEL_CHUNK; int z = c.getZ(); if (y < 0 || y >= c.getWorld().getHeight() >> Chunk.BLOCKS.BITS) { return; } initChunk(c.getBase()); if (activeChunks.add(x, z)) { Point p = c.getBase(); int[][] heights = getColumnHeights(p); BlockMaterial[][] materials = getColumnTopmostMaterials(p); byte[][] packetChunkData = new byte[16][]; for (int cube = 0; cube < 16; cube++) { packetChunkData[cube] = getChunkHeightMap(heights, materials, cube); } Chunk chunk = p.getWorld().getChunkFromBlock(p); byte[] biomeData = new byte[Chunk.BLOCKS.AREA]; for (int dx = x; dx < x + Chunk.BLOCKS.SIZE; ++dx) { for (int dz = z; dz < z + Chunk.BLOCKS.SIZE; ++dz) { Biome biome = chunk.getBiomeType(dx & Chunk.BLOCKS.MASK, 0, dz & Chunk.BLOCKS.MASK); if (biome instanceof VanillaBiome) { biomeData[(dz & Chunk.BLOCKS.MASK) << 4 | (dx & Chunk.BLOCKS.MASK)] = (byte) ((VanillaBiome) biome).getBiomeId(); } } } CompressedChunkMessage CCMsg = new CompressedChunkMessage(x, z, true, new boolean[16], packetChunkData, biomeData); owner.getSession().send(false, CCMsg); } ChunkSnapshot snapshot = c.getSnapshot(SnapshotType.BOTH, EntityType.NO_ENTITIES, ExtraData.NO_EXTRA_DATA); short[] rawBlockIdArray = snapshot.getBlockIds(); short[] rawBlockData = snapshot.getBlockData(); byte[] rawBlockLight = snapshot.getBlockLight(); byte[] rawSkyLight = snapshot.getSkyLight(); byte[] fullChunkData = new byte[Chunk.BLOCKS.HALF_VOLUME * 5]; int arrIndex = 0; for (int i = 0; i < rawBlockIdArray.length; i++) { short convert = getMinecraftId(rawBlockIdArray[i]); fullChunkData[arrIndex++] = (byte) (convert & 0xFF); } for (int i = 0; i < rawBlockData.length; i += 2) { fullChunkData[arrIndex++] = (byte) ((rawBlockData[i + 1] << 4) | (rawBlockData[i] & 0xF)); } System.arraycopy(rawBlockLight, 0, fullChunkData, arrIndex, rawBlockLight.length); arrIndex += rawBlockLight.length; System.arraycopy(rawSkyLight, 0, fullChunkData, arrIndex, rawSkyLight.length); arrIndex += rawSkyLight.length; byte[][] packetChunkData = new byte[16][]; packetChunkData[y] = fullChunkData; CompressedChunkMessage CCMsg = new CompressedChunkMessage(x, z, false, new boolean[16], packetChunkData, null); owner.getSession().send(false, CCMsg); }
@Override public void resetDynamicBlocks(Chunk c) { c.resetDynamicBlocks(c); }
@Override public Collection<Chunk> sendChunk(Chunk c) { int x = c.getX(); int y = c.getY(); // + SEALEVEL_CHUNK; int z = c.getZ(); if (y < 0 || y >= c.getWorld().getHeight() >> Chunk.BLOCKS.BITS) { return null; } initChunk(c.getBase()); Collection<Chunk> chunks = null; if (activeChunks.add(x, z)) { Point p = c.getBase(); int[][] heights = getColumnHeights(p); BlockMaterial[][] materials = getColumnTopmostMaterials(p); byte[][] packetChunkData = new byte[16][]; for (int cube = 0; cube < 16; cube++) { Point pp = new Point( c.getWorld(), x << Chunk.BLOCKS.BITS, cube << Chunk.BLOCKS.BITS, z << Chunk.BLOCKS.BITS); packetChunkData[cube] = chunkInit.getChunkData(heights, materials, pp); } Chunk chunk = p.getWorld().getChunkFromBlock(p); byte[] biomeData = new byte[Chunk.BLOCKS.AREA]; for (int dx = x; dx < x + Chunk.BLOCKS.SIZE; ++dx) { for (int dz = z; dz < z + Chunk.BLOCKS.SIZE; ++dz) { Biome biome = chunk.getBiome(dx & Chunk.BLOCKS.MASK, 0, dz & Chunk.BLOCKS.MASK); if (biome instanceof VanillaBiome) { biomeData[(dz & Chunk.BLOCKS.MASK) << 4 | (dx & Chunk.BLOCKS.MASK)] = (byte) ((VanillaBiome) biome).getBiomeId(); } } } ChunkDataMessage CCMsg = new ChunkDataMessage( x, z, true, new boolean[16], packetChunkData, biomeData, player.getSession()); player.getSession().send(false, CCMsg); chunks = chunkInit.getChunks(c); } byte[] fullChunkData = ChunkInit.getChunkFullData(c); byte[][] packetChunkData = new byte[16][]; packetChunkData[y] = fullChunkData; ChunkDataMessage CCMsg = new ChunkDataMessage( x, z, false, new boolean[16], packetChunkData, null, player.getSession()); player.getSession().send(false, CCMsg); return chunks; }
@Override protected Collection<Chunk> sendChunk(Chunk c, boolean force) { if (!force) { return sendChunk(c); } int x = c.getX(); int y = c.getY(); // + SEALEVEL_CHUNK; int z = c.getZ(); RepositionManager rm = getRepositionManager(); int cY = rm.convertChunkY(y); if (cY < 0 || cY >= c.getWorld().getHeight() >> Chunk.BLOCKS.BITS) { return null; } initChunkRaw(c.getBase()); Collection<Chunk> chunks = null; List<ProtocolEvent> events = new ArrayList<ProtocolEvent>(); if (activeChunks.add(x, z)) { Point p = c.getBase(); int[][] heights = getColumnHeights(p); BlockMaterial[][] materials = getColumnTopmostMaterials(p); byte[][] packetChunkData = new byte[16][]; for (int cube = 0; cube < 16; cube++) { int serverCube = rm.getInverse().convertChunkY(cube); Point pp = new Point( c.getWorld(), x << Chunk.BLOCKS.BITS, serverCube << Chunk.BLOCKS.BITS, z << Chunk.BLOCKS.BITS); packetChunkData[cube] = chunkInit.getChunkData(heights, materials, pp, events); } Chunk chunk = p.getWorld().getChunkFromBlock(p); byte[] biomeData = new byte[Chunk.BLOCKS.AREA]; for (int dx = x; dx < x + Chunk.BLOCKS.SIZE; ++dx) { for (int dz = z; dz < z + Chunk.BLOCKS.SIZE; ++dz) { Biome biome = chunk.getBiome(dx & Chunk.BLOCKS.MASK, 0, dz & Chunk.BLOCKS.MASK); if (biome instanceof VanillaBiome) { biomeData[(dz & Chunk.BLOCKS.MASK) << 4 | (dx & Chunk.BLOCKS.MASK)] = (byte) ((VanillaBiome) biome).getBiomeId(); } } } ChunkDataMessage CCMsg = new ChunkDataMessage( x, z, true, new boolean[16], packetChunkData, biomeData, player.getSession(), getRepositionManager()); player.getSession().send(false, CCMsg); chunks = chunkInit.getChunks(c); } if (chunks == null || !chunks.contains(c)) { byte[] fullChunkData = ChunkInit.getChunkFullData(c, events); byte[][] packetChunkData = new byte[16][]; packetChunkData[cY] = fullChunkData; ChunkDataMessage CCMsg = new ChunkDataMessage( x, z, false, new boolean[16], packetChunkData, null, player.getSession(), getRepositionManager()); player.getSession().send(false, CCMsg); if (chunks == null) { chunks = new ArrayList<Chunk>(1); } chunks.add(c); } for (ProtocolEvent e : events) { this.callProtocolEvent(e); } return chunks; }
@Override public void finalizeRun() { // Moving from one region to another if (entityManager != null) { if (entityManager != entityManagerLive.get()) { // Deallocate entity if (entityManager.getRegion() != null) { entityManager.getRegion().removeEntity(this); } else { entityManager.deallocate(this); } } } if (entityManagerLive.get() != null) { if (entityManager != entityManagerLive.get()) { // Allocate entity entityManagerLive.get().allocate(this); } } // Could be 1 of 3 scenarios: // 1.) Entity is dead (ControllerLive == null) // 2.) Entity is swapping controllers (ControllerLive != Controller, niether is null) // 3.) Entity has just spawned and has never executed copy snapshot, Controller == null, // ControllerLive != null if (controller != controllerLive.get()) { // 1.) Entity is dead if (controller != null && controllerLive.get() == null) { // Sanity check if (!isDead()) throw new IllegalStateException("ControllerLive is null, but entity is not dead!"); // Kill old controller controller.onDeath(); if (controller instanceof PlayerController) { Player p = ((PlayerController) controller).getPlayer(); if (p != null) { p.getNetworkSynchronizer().onDeath(); } } } // 2.) Entity is changing controllers else if (controller != null && controllerLive.get() != null) { // Kill old controller controller.onDeath(); if (controller instanceof PlayerController) { Player p = ((PlayerController) controller).getPlayer(); if (p != null) { p.getNetworkSynchronizer().onDeath(); } } // Allocate new controller if (entityManagerLive.get() != null) { entityManagerLive.get().allocate(this); } } // 3.) Entity was just spawned, has not copied snapshots yet else if (controller == null && controllerLive.get() != null) { // Sanity check if (!this.justSpawned()) throw new IllegalStateException( "Controller is null, ControllerLive is not-null, and the entity did not just spawn."); } } if (chunkLive.get() != chunk) { if (observer) { if (!isDead()) { updateObserver(); } else { removeObserver(); } } if (chunkLive.get() != null) { ((SpoutChunk) chunkLive.get()).addEntity(this); } if (chunk != null && chunk.isLoaded()) { ((SpoutChunk) chunk).removeEntity(this); } if (chunkLive.get() == null) { if (chunk != null && chunk.isLoaded()) { ((SpoutChunk) chunk).removeEntity(this); } if (entityManagerLive.get() != null) { entityManagerLive.get().deallocate(this); } } } if (observerLive.get() != observer) { observer = !observer; if (observer) { updateObserver(); } else { removeObserver(); } } }