public IChunk GenerateChunk(IChunk chunk, int x, int z, bool external) { InitGen(); #if PROFILE Stopwatch watch = new Stopwatch(); watch.Start(); #endif GenerateTerrain(chunk, x, z); GenerateFlora(chunk, x, z); if (!external) { chunk.RecalculateHeight(); chunk.LightToRecalculate = true; #if PROFILE watch.Stop(); _World.Logger.Log(Logger.LogLevel.Info, "Chunk {0} {1}, {2}", false, x, z, watch.ElapsedMilliseconds); #endif _World.AddChunk(chunk); chunk.MarkToSave(); } return chunk; }
public Chunk2D(IChunk[] chunks) { ushort[] blocks = new ushort[Chunk.CHUNKSIZE_X*Chunk.CHUNKSIZE_Y]; float[] heights = new float[Chunk.CHUNKSIZE_X * Chunk.CHUNKSIZE_Y]; int maxHeight = Chunk.CHUNKSIZE_Z*chunks.Length; int index = 0; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { for (int x = 0; x < Chunk.CHUNKSIZE_X; x++,index++) { bool found=false; for (int i=chunks.Length-1;i>=0;i--) { IChunk current = chunks [i]; for (int z = Chunk.CHUNKSIZE_Z - 1; z >= 0; z--) { if ((blocks [index] = current.GetBlock (x, y, z)) != 0) { float percent = (float)(i * Chunk.CHUNKSIZE_Z + z) / maxHeight; heights[index] = percent - 0.5f; found = true; break; } } if (found) break; } } } CreateBitmap(blocks,heights); }
public void SaveChunk(IChunk runtimeChunk) { using (var file = new FileStream(Path.Combine(this.m_Path, this.GetName(runtimeChunk)), FileMode.Create)) { var size = this.m_ChunkSizePolicy.ChunkCellWidth * this.m_ChunkSizePolicy.ChunkCellHeight * this.m_ChunkSizePolicy.ChunkCellDepth; var chunk = new Chunk { X = runtimeChunk.X, Y = runtimeChunk.Y, Z = runtimeChunk.Z, Cells = new Cell[size], Indexes = runtimeChunk.GeneratedIndices, Vertexes = new Vertex[runtimeChunk.GeneratedVertexes.Length] }; chunk.Cells = runtimeChunk.Cells; for (var i = 0; i < runtimeChunk.GeneratedVertexes.Length; i++) { chunk.Vertexes[i] = new Vertex { X = runtimeChunk.GeneratedVertexes[i].Position.X, Y = runtimeChunk.GeneratedVertexes[i].Position.Y, Z = runtimeChunk.GeneratedVertexes[i].Position.Z, U = runtimeChunk.GeneratedVertexes[i].TextureCoordinate.X, V = runtimeChunk.GeneratedVertexes[i].TextureCoordinate.Y, }; } var serializer = new TychaiaDataSerializer(); serializer.Serialize(file, chunk); } }
private void CreateEntraces(IChunk chunk, Coordinates3D location, Random random) { int entrances = 0; var above = location + Coordinates3D.Up; for (int X = location.X; X < location.X + Size.X; X++) { if (entrances >= MaxEntrances) { break; } for (int Z = location.Z; Z < location.Z + Size.Z; Z++) { if (entrances >= MaxEntrances) { break; } if (random.Next(0, 3) == 0 && IsCuboidWall(new Coordinates2D(X, Z), location, Size) && !IsCuboidCorner(new Coordinates2D(X, Z), location, Size)) { var blockLocation = new Coordinates3D(X, above.Y, Z); chunk.SetBlockID(blockLocation, AirBlock.BlockID); chunk.SetBlockID(blockLocation + Coordinates3D.Up, AirBlock.BlockID); entrances++; } } } }
void ScheduleUpdatesForChunk(IWorld world, IChunk chunk) { int _x = chunk.Coordinates.X * Chunk.Width; int _z = chunk.Coordinates.Z * Chunk.Depth; Coordinates3D coords, _coords; for (byte x = 0; x < Chunk.Width; x++) { for (byte z = 0; z < Chunk.Depth; z++) { for (int y = 0; y < chunk.GetHeight(x, z); y++) { _coords.X = x; _coords.Y = y; _coords.Z = z; var id = chunk.GetBlockID(_coords); if (id == 0) { continue; } coords.X = _x + x; coords.Y = y; coords.Z = _z + z; var provider = BlockRepository.GetBlockProvider(id); provider.BlockLoadedFromChunk(coords, this, world); } } } }
public void TransferEntity(IChunk chunk) { if (/*CurrentChunk == chunk ||*/ chunk == null) { return; } CurrentChunk?.UnregisterEntity(this); chunk.RegisterEntity(this); ILogicEvent tempEvent; if (CurrentChunk == null || CurrentChunk.Map != chunk.Map) { tempEvent = new EntityChangesMap { FromHere = CurrentChunk, ToHere = chunk }; } else { tempEvent = new EntityTransferBetweenChunks { FromHere = CurrentChunk, ToHere = chunk }; } EmitEventAsync(tempEvent); CurrentChunk = chunk; }
void IChunk.Deserialize(IChunk parent, Stream input, Endian endian) { var count = input.ReadValueU32(endian); this.Unknown0.Clear(); this.Unknown1.Clear(); for (uint i = 0; i < count; i++) { var unknown = new UnknownData0(); unknown.Unknown00 = input.ReadValueF32(endian); unknown.Unknown04 = input.ReadValueF32(endian); unknown.Unknown08 = input.ReadValueF32(endian); unknown.Unknown0C = input.ReadValueF32(endian); unknown.Unknown10 = input.ReadValueF32(endian); unknown.Unknown14 = input.ReadValueF32(endian); unknown.Unknown18 = input.ReadValueF32(endian); unknown.Unknown1C = input.ReadValueF32(endian); unknown.Unknown20 = input.ReadValueF32(endian); unknown.Unknown24 = input.ReadValueF32(endian); unknown.Unknown28 = input.ReadValueF32(endian); unknown.Unknown2C = input.ReadValueU32(endian); unknown.Unknown30 = input.ReadValueU32(endian); var length = input.ReadValueU32(endian); unknown.Name = input.ReadString(length); input.Seek(1, SeekOrigin.Current); // skip null this.Unknown0.Add(unknown); } }
protected virtual void Execute() { ReadChunksQueue.WaitForInput(); _executing = true; using (var threadPool = new GeneralThreadPool(CancellationToken, Options.MaxBuffers)) { while ((_reading || ReadChunksQueue.Count > 0) && !ErrorOccured) { IChunk chunk = null; if (ReadChunksQueue.TryDequeue(out chunk)) { threadPool.Enqueue(() => { ExecuteChunk(chunk); ExecutedChunksQueue.Enqueue(chunk); }); } else { Thread.Sleep(10); } } threadPool.StopAdding(); threadPool.WaitForCompletion(); } _executing = false; }
private void GenerateHeightMap(IChunk chunk) { Coordinates3D coords; var map = new byte[Chunk.Width, Chunk.Depth]; for (byte x = 0; x < Chunk.Width; x++) { for (byte z = 0; z < Chunk.Depth; z++) { for (byte y = (byte)(chunk.GetHeight(x, z) + 2); y > 0; y--) { if (y >= Chunk.Height) { continue; } coords.X = x; coords.Y = y - 1; coords.Z = z; var id = chunk.GetBlockID(coords); if (id == 0) { continue; } var provider = BlockRepository.GetBlockProvider(id); if (provider.LightOpacity != 0) { map[x, z] = y; break; } } } } HeightMaps[chunk.Coordinates] = map; }
public void LoadChunk(IChunk runtimeChunk) { using (var file = new FileStream(Path.Combine(this.m_Path, this.GetName(runtimeChunk)), FileMode.Open)) { var serializer = new TychaiaDataSerializer(); var chunk = new Chunk(); serializer.Deserialize(file, chunk, typeof(Chunk)); runtimeChunk.Cells = chunk.Cells; runtimeChunk.GeneratedIndices = chunk.Indexes; if (chunk.Vertexes == null) { runtimeChunk.GeneratedVertexes = new VertexPositionTexture[0]; } else { runtimeChunk.GeneratedVertexes = new VertexPositionTexture[chunk.Vertexes.Length]; for (var i = 0; i < chunk.Vertexes.Length; i++) { runtimeChunk.GeneratedVertexes[i] = new VertexPositionTexture( new Vector3(chunk.Vertexes[i].X, chunk.Vertexes[i].Y, chunk.Vertexes[i].Z), new Vector2(chunk.Vertexes[i].U, chunk.Vertexes[i].V)); } } runtimeChunk.Generated = true; } }
private bool CoverIce(IChunk chunk, IBiomeRepository biomes, Coordinates3D location) { const int maxDistance = 4; var adjacent = new[] { location + new Coordinates3D(-maxDistance, 0, 0), location + new Coordinates3D(maxDistance, 0, 0), location + new Coordinates3D(0, 0, maxDistance), location + new Coordinates3D(0, 0, -maxDistance) }; for (var i = 0; i < adjacent.Length; i++) { var check = adjacent[i]; if (check.X < 0 || check.X >= Chunk.Width || check.Z < 0 || check.Z >= Chunk.Depth || check.Y < 0 || check.Y >= Chunk.Height) { return(false); } var biome = biomes.GetBiome(chunk.Biomes[check.X * Chunk.Width + check.Z]); if (chunk.GetBlockID(check).Equals(biome.SurfaceBlock) || chunk.GetBlockID(check).Equals(biome.FillerBlock)) { return(true); } } return(false); }
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) { for (int attempts = 0; attempts < 8; attempts++) { var noise = new Perlin(); noise.Seed = world.Seed - (chunk.Coordinates.X + chunk.Coordinates.Z); var offsetNoise = new ClampNoise(noise); offsetNoise.MaxValue = 3; var x = 0; var z = 0; var offset = 0.0; offset += offsetNoise.Value2D(x, z); int finalX = (int)Math.Floor(x + offset); int finalZ = (int)Math.Floor(z + offset); var y = (int)(10 + offset); var blockX = MathHelper.ChunkToBlockX(finalX, chunk.Coordinates.X); var blockZ = MathHelper.ChunkToBlockZ(finalZ, chunk.Coordinates.Z); var spawnValue = offsetNoise.Value2D(blockX, blockZ); if (spawnValue > 1.95 && spawnValue < 2.09) { var generated = new Dungeon().GenerateAt(world, chunk, new Coordinates3D(blockX, y, blockZ)); if (generated) break; } } }
public IEnumerable <KeyValuePair <ChunkPlaybackInfo, IChunk> > GetChunks() { PMCEInfo lastComponent = null; IChunk lastChunk = null; for (int i = 0; i < ChunkedData.Chunks.Length; i++) { if (ChunkedData?.Chunks[i]?.GetType() == typeof(teEffectChunkComponent)) { teEffectChunkComponent component = ChunkedData.Chunks[i] as teEffectChunkComponent; if (component == null) { continue; } lastComponent = new PMCEInfo { Hardpoint = component.Header.Hardpoint, StartTime = component.StartTime, EndTime = component.EndTime }; // if (effect.Hardpoints == null) continue; // if (effect.Hardpoints.Length <= pmce.Data.Index) continue; continue; } ChunkPlaybackInfo playbackInfo = new ChunkPlaybackInfo(lastComponent, lastChunk); yield return(new KeyValuePair <ChunkPlaybackInfo, IChunk>(playbackInfo, ChunkedData.Chunks[i])); lastComponent = null; lastChunk = ChunkedData.Chunks[i]; } }
public override bool Use(IActor actor, string message, string[] parameters) { //Get systems var SystemsCollection = this.Server.Biomes.GetSystems(); //Get system player is in uint currentSystemID = actor.InstanceID; //Define currentSystems for TryGetValue IBiomeSystem currentSystem; //Find the currentSystem based on its ID SystemsCollection.TryGetValue(currentSystemID, out currentSystem); //Get the chunk's ID that the player is in uint currentChunkID = actor.ConnectedChunk; //Search current system for the chunk based on its ID IChunk currentChunk = currentSystem.ChunkCollection.First(item => item.ID == currentChunkID); int chunkCount = currentSystem.ChunkCollection.Count(); //Align player with local chunk grid Point3D actorPos = new Point3D((int)Math.Round(actor.LocalChunkTransform.X), (int)Math.Round(actor.LocalChunkTransform.Y), (int)Math.Round(actor.LocalChunkTransform.Z)); //Convert local Point to Sector Point Point3D fakeglobalPos = new Point3D((int)currentChunk.Position.X + actorPos.X, (int)currentChunk.Position.Y + actorPos.Y, (int)currentChunk.Position.Z + actorPos.Z); Point3D trueglobalPos = new Point3D((int)currentChunk.Position.X + actorPos.X - 32 / 2, (int)currentChunk.Position.Y + actorPos.Y - 32 / 2, (int)currentChunk.Position.Z + actorPos.Z - 32 / 2); //to get a global pos you can do DoubleVector3.Transform(localPoint, Chunk.World) //Ben Dictionary <Point3D, IChunk> ChunkDictionary = SNScriptUtils._Utils.CreateChunkDictionary(currentSystem); IChunk currChunkByFakeGlobalPos = new Object() as IChunk; Boolean foundChunk = SNScriptUtils._Utils.getChunkObjFromFakeGlobalPos(fakeglobalPos, ChunkDictionary, out currChunkByFakeGlobalPos); int staticCount = 0, shipCount = 0; foreach (IChunk c in currentSystem.ChunkCollection) { if (c.IsStaticChunk) { staticCount++; } else { shipCount++; } } this.Server.ChatManager.SendActorMessage("----------------------------------------------", actor); this.Server.ChatManager.SendActorMessage("# of Chunks in System (System.Chunks.Count): " + chunkCount.ToString(), actor); this.Server.ChatManager.SendActorMessage(string.Format("System Chunks: Static {0} - Ship {1}", staticCount, shipCount), actor); this.Server.ChatManager.SendActorMessage("----------------------------------------------", actor); this.Server.ChatManager.SendActorMessage("Actor Pos:" + actorPos.ToString(), actor); this.Server.ChatManager.SendActorMessage("Chunk Base (conn.chunk):" + currentChunk.Position.ToString(), actor); this.Server.ChatManager.SendActorMessage("Chunk Base(calc.by FglobPos):" + currChunkByFakeGlobalPos.Position.ToString(), actor); this.Server.ChatManager.SendActorMessage("Calculated global Pos: " + fakeglobalPos.ToString(), actor); this.Server.ChatManager.SendActorMessage("calc. True global Pos: " + trueglobalPos.ToString(), actor); this.Server.ChatManager.SendActorMessage("----------------------------------------------", actor); return(true); }
public override bool Use(IActor actor, string message, string[] parameters) { if (!_Utils.checkParameterCount(parameters, 1, actor)) { return(false); } ushort blockID = ushort.Parse(parameters[1]); IBiomeSystem checkSystem = Server.Biomes.GetSystems()[actor.InstanceID]; IChunk checkChunk = checkSystem.ChunkCollection[0]; if (!_Utils.blockTypeExists(checkChunk, blockID, actor)) { return(false); } Point3D pos1 = new Point3D(); Point3D pos2 = new Point3D(); if (!_Utils.checkStoredPositions(actor, out pos1, out pos2)) { return(false); } //calculate absolute distance (absdiff) and direction (valinc) to get from Point1 to Point2 int absdiffx; int valincx; int absdiffy; int valincy; int absdiffz; int valincz; _Utils.calcAbsDiffAndValinc(pos1.X, pos2.X, out absdiffx, out valincx); _Utils.calcAbsDiffAndValinc(pos1.Y, pos2.Y, out absdiffy, out valincy); _Utils.calcAbsDiffAndValinc(pos1.Z, pos2.Z, out absdiffz, out valincz); Dictionary <Point3D, ushort> fakeGlobalPosAndBlockID = new Dictionary <Point3D, ushort>(); for (int y = 0; y <= (absdiffy); y++) { for (int z = 0; z <= (absdiffz); z++) { for (int x = 0; x <= (absdiffx); x++) { //Dictionary contains <fakeGlobalPos, blockID> fakeGlobalPosAndBlockID.Add(new Point3D((pos1.X + (x * valincx)), (pos1.Y + (y * valincy)), (pos1.Z + (z * valincz))), blockID); } } } Dictionary <Point3D, Dictionary <Point3D, ushort> > BlocksToBePlacedInSystem = new Dictionary <Point3D, Dictionary <Point3D, ushort> >(); if (!_Utils.SplitFakeGlobalPosBlocklistIntoChunksAndLocalPos(fakeGlobalPosAndBlockID, out BlocksToBePlacedInSystem)) { return(false); } if (_Utils.PlaceBlocksInSystem(BlocksToBePlacedInSystem, checkSystem)) { return(true); } else { return(false); } }
public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location) { if (!ValidLocation(location)) { return(false); } var random = new Random(world.Seed); var height = random.Next(7, 8); GenerateColumn(chunk, location, height, WoodBlock.BlockId, 0x1); for (var y = 1; y < height; y++) { if (y % 2 == 0) { GenerateVanillaCircle(chunk, location + new Coordinates3D(0, y + 1, 0), LeafRadius - 1, LeavesBlock.BlockId, 0x1); continue; } GenerateVanillaCircle(chunk, location + new Coordinates3D(0, y + 1, 0), LeafRadius, LeavesBlock.BlockId, 0x1); } GenerateTopper(chunk, location + new Coordinates3D(0, height, 0), 0x1); return(true); }
/// <summary> /// Erzeugt eine neue Instanz einer ChunkColumn. /// </summary> /// <param name="chunks">Die Chunks für die Säule</param> /// <param name="planet">Der Index des Planeten</param> /// <param name="columnIndex">Die Position der Säule</param> public ChunkColumn(IChunk[] chunks, int planet, Index2 columnIndex) : this() { Planet = planet; Chunks = chunks; Index = columnIndex; }
public static bool NeighboursBlock(IChunk chunk, Coordinates3D location, byte block, byte meta = 0x0) { var surrounding = new[] { location + Coordinates3D.Left, location + Coordinates3D.Right, location + Coordinates3D.Forwards, location + Coordinates3D.Backwards }; for (var i = 0; i < surrounding.Length; i++) { var toCheck = surrounding[i]; if (toCheck.X < 0 || toCheck.X >= Chunk.Width || toCheck.Z < 0 || toCheck.Z >= Chunk.Depth || toCheck.Y < 0 || toCheck.Y >= Chunk.Height) { return(false); } if (chunk.GetBlockID(toCheck).Equals(block)) { if (meta != 0x0 && chunk.GetMetadata(toCheck) != meta) { return(false); } return(true); } } return(false); }
protected static void GenerateSphere(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0) { for (var i = -radius; i <= radius; i = i + 1) { for (var j = -radius; j <= radius; j = j + 1) { for (var k = -radius; k <= radius; k = k + 1) { var max = (int)Math.Sqrt(i * i + j * j + k * k); if (max <= radius) { var x = location.X + i; var y = location.Y + k; var z = location.Z + j; if (x < 0 || x >= Chunk.Width || z < 0 || z >= Chunk.Depth || y < 0 || y >= Chunk.Height) { continue; } var currentBlock = new Coordinates3D(x, y, z); if (chunk.GetBlockID(currentBlock).Equals(0)) { chunk.SetBlockID(currentBlock, block); chunk.SetMetadata(currentBlock, meta); } } } } } }
/* * Cuboid Modes * 0x0 - Solid cuboid of the specified block * 0x1 - Hollow cuboid of the specified block * 0x2 - Outlines the area of the cuboid using the specified block */ public static void GenerateCuboid(IChunk chunk, Coordinates3D location, Vector3 size, byte block, byte meta = 0x0, byte mode = 0x0) { //If mode is 0x2 offset the size by 2 and change mode to 0x1 if (mode.Equals(0x2)) { size += new Vector3(2, 2, 2); mode = 0x1; } for (int w = location.X; w < location.X + size.X; w++) { for (int l = location.Z; l < location.Z + size.Z; l++) { for (int h = location.Y; h < location.Y + size.Y; h++) { if (w < 0 || w >= Chunk.Width || l < 0 || l >= Chunk.Depth || h < 0 || h >= Chunk.Height) continue; Coordinates3D BlockLocation = new Coordinates3D(w, h, l); if (!h.Equals(location.Y) && !h.Equals(location.Y + (int)size.Y - 1) && !IsCuboidWall(new Coordinates2D(w, l), location, size) && !IsCuboidCorner(new Coordinates2D(w, l), location, size)) continue; chunk.SetBlockID(BlockLocation, block); if (meta != 0x0) chunk.SetMetadata(BlockLocation, meta); } } } }
public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location) { if (!ValidLocation(location)) { return(false); } var random = new Random(world.Seed); //Generate room GenerateCuboid(chunk, location, Size, CobblestoneBlock.BlockID, 0x0, 0x2); //Randomly add mossy cobblestone to floor MossFloor(chunk, location, random); //Place Spawner chunk.SetBlockID(new Coordinates3D((int)(location.X + ((Size.X + 1) / 2)), (int)((location + Coordinates3D.Up).Y), (int)(location.Z + ((Size.Z + 1) / 2))), MonsterSpawnerBlock.BlockID); //Create entrances CreateEntraces(chunk, location, random); //Place Chests PlaceChests(chunk, location, random); return(true); }
/// <summary> /// Adds data /// </summary> /// <param name="chunk">Data</param> /// <returns></returns> public DebugDirectoryEntry Add(IChunk chunk) { var entry = new DebugDirectoryEntry(chunk); entries.Add(entry); return(entry); }
void IChunk.Deserialize(IChunk parent, Stream input, Endian endian) { var count = input.ReadValueU32(endian); this.Items.Clear(); for (uint i = 0; i < count; i++) { var node = new Node(); node.NameHash = input.ReadValueU32(endian); node.NextSiblingIndex = input.ReadValueS32(endian); node.FirstChildIndex = input.ReadValueS32(endian); node.PreviousSiblingIndex = input.ReadValueS32(endian); node.Unknown10 = input.ReadValueF32(endian); node.Unknown14 = input.ReadValueF32(endian); node.Unknown18 = input.ReadValueF32(endian); node.Unknown1C = input.ReadValueF32(endian); node.Unknown20 = input.ReadValueF32(endian); node.Unknown24 = input.ReadValueF32(endian); node.Unknown28 = input.ReadValueF32(endian); node.Unknown2C = input.ReadValueF32(endian); node.Unknown30 = input.ReadValueF32(endian); node.Unknown34 = input.ReadValueF32(endian); node.O2BMIndex = input.ReadValueS32(endian); node.Unknown3C = input.ReadValueF32(endian); node.Unknown40 = input.ReadValueF32(endian); var length = input.ReadValueU32(endian); node.Name = input.ReadString(length); input.Seek(1, SeekOrigin.Current); // skip null this.Items.Add(node); } }
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) { var noise = new Perlin(world.Seed); var chanceNoise = new ClampNoise(noise); chanceNoise.MaxValue = 2; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { var biome = biomes.GetBiome(chunk.Biomes[x * Chunk.Width + z]); var blockX = MathHelper.ChunkToBlockX(x, chunk.Coordinates.X); var blockZ = MathHelper.ChunkToBlockZ(z, chunk.Coordinates.Z); var height = chunk.HeightMap[x * Chunk.Width + z]; if (biome.Plants.Contains(PlantSpecies.Cactus) && chanceNoise.Value2D(blockX, blockZ) > 1.7) { var blockLocation = new Coordinates3D(x, height, z); var cactiPosition = blockLocation + Coordinates3D.Up; if (chunk.GetBlockID(blockLocation).Equals(SandBlock.BlockID)) { var HeightChance = chanceNoise.Value2D(blockX, blockZ); var CactusHeight = (HeightChance < 1.4) ? 2 : 3; Decoration.GenerateColumn(chunk, cactiPosition, CactusHeight, CactusBlock.BlockID); } } } } }
/// <summary> /// Sets the chunk at the specified local position to the given value. /// </summary> public void SetChunk(Coordinates2D position, IChunk chunk) { Chunks[position] = chunk; chunk.IsModified = true; DirtyChunks.Add(position); chunk.ParentRegion = this; }
private void PlaceChests(IChunk chunk, Coordinates3D location, Random random) { var above = location + Coordinates3D.Up; var chests = random.Next(0, 2); for (int i = 0; i < chests; i++) { for (int attempts = 0; attempts < 10; attempts++) { var x = random.Next(location.X, location.X + (int)Size.X); var z = random.Next(location.Z, location.Z + (int)Size.Z); if (!IsCuboidWall(new Coordinates2D(x, z), location, Size) && !IsCuboidCorner(new Coordinates2D(x, z), location, Size)) { if (NeighboursBlock(chunk, new Coordinates3D(x, above.Y, z), CobblestoneBlock.BlockID)) { if (x < 0 || x >= Chunk.Width || z < 0 || z >= Chunk.Depth || above.Y < 0 || above.Y >= Chunk.Height) { continue; } chunk.SetBlockID(new Coordinates3D(x, above.Y, z), ChestBlock.BlockID); break; } } } } }
/// <inheritdoc/> public Task SaveAsync(Point index, IChunk chunk) { if (!_chunks.ContainsKey(index)) _chunks[index] = chunk; return Task.CompletedTask; }
public IChunk[] GenerateChunk(IPlanet planet, Index2 index) { IChunk[] result = new IChunk[planet.Size.Z]; for (int layer = 0; layer < planet.Size.Z; layer++) result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = (int)(z / Chunk.CHUNKSIZE_Z); result[layer].SetBlock(x, y, block, new SandBlock()); } } } } return result; }
public void RegionCreateExistingChunkTest() { IRegion region = new Region(_worldMapMock.Object, 0, 0, _serviceProvider); IChunk chunk = region.AddChunk(0, 0); Assert.Throws <InvalidOperationException>(() => region.AddChunk(0, 0)); }
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) { var noise = new Perlin(); noise.Seed = world.Seed; var chanceNoise = new ClampNoise(noise); chanceNoise.MaxValue = 2; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { var biome = biomes.GetBiome(chunk.Biomes[x * Chunk.Width + z]); var blockX = MathHelper.ChunkToBlockX(x, chunk.Coordinates.X); var blockZ = MathHelper.ChunkToBlockZ(z, chunk.Coordinates.Z); var height = chunk.HeightMap[x * Chunk.Width + z]; if (biome.Plants.Contains(PlantSpecies.Cactus) && chanceNoise.Value2D(blockX, blockZ) > 1.7) { var blockLocation = new Coordinates3D(x, height, z); var cactiPosition = blockLocation + Coordinates3D.Up; if (chunk.GetBlockID(blockLocation).Equals(SandBlock.BlockID)) { var HeightChance = chanceNoise.Value2D(blockX, blockZ); var CactusHeight = (HeightChance < 1.4) ? 2 : 3; Decoration.GenerateColumn(chunk, cactiPosition, CactusHeight, CactusBlock.BlockID); } } } } }
/// <summary> /// /// </summary> /// <param name="chunk"></param> /// <param name="offsetInIni2"></param> /// <param name="pbkIndex"></param> /// <param name="mbkIndex"></param> /// <param name="cbkIndex"></param> /// <returns></returns> private bool SaveIni2Offset(IChunk chunk, out int offsetInIni2, ref int pbkIndex, ref int mbkIndex, ref int cbkIndex) { switch (chunk.Name) { case "PBK1": offsetInIni2 = FindIni2Offset(chunk.Name, pbkIndex); pbkIndex++; break; case "MBK1": offsetInIni2 = FindIni2Offset(chunk.Name, mbkIndex); mbkIndex++; break; case "CBK1": offsetInIni2 = FindIni2Offset(chunk.Name, cbkIndex); cbkIndex++; break; case "GLB1": offsetInIni2 = 0; // Not implemented return(true); default: throw new ApplicationException("Switch error"); } return(false); }
public RiffChunk(ChunkDescriptor chunkDescriptor, BinaryReader binaryReader, Encoding stringEncoding) { Descriptor = chunkDescriptor; Format = Encoding.ASCII.GetString(binaryReader.ReadBytes(4)); Chunks = new Dictionary <string, IChunk>(); if (Descriptor.ChunkSize > 0) { int position = 4; while (position < Descriptor.ChunkSize) { IChunk chunk = NextChunk(binaryReader, stringEncoding); if (chunk == null) { throw new Exception("Unexpected stream end"); } Chunks.Add(chunk.Descriptor.ChunkId, chunk); position += chunk.Descriptor.ChunkSize + 8; } } else { while (true) { IChunk chunk = NextChunk(binaryReader, stringEncoding); if (chunk == null) { break; } Chunks.Add(chunk.Descriptor.ChunkId, chunk); } } }
public void AddChunk(Vector3Int pos, IChunk chunk) { Chunks[pos] = (SmoothChunk)chunk; Chunks[pos].BuildGPU_DataBuffer(true); Vector3Int[] dirs = new Vector3Int[] { new Vector3Int(1, 0, 0), new Vector3Int(-1, 0, 0), new Vector3Int(0, 1, 0), new Vector3Int(0, -1, 0), new Vector3Int(0, 0, 1), new Vector3Int(0, 0, -1), }; foreach (Vector3Int d in dirs) { Vector3Int newPos = pos + d; if (BuilderExists(newPos.x, newPos.y, newPos.z)) { Chunks[newPos].Render(true); Chunks[newPos].BuildGPU_DataBuffer(true); } } }
/// <summary> /// Copies a chunk from one location to another. /// </summary> /// <param name="src_cx">The global X-coordinate of the source chunk.</param> /// <param name="src_cz">The global Z-coordinate of the source chunk.</param> /// <param name="dst_cx">The global X-coordinate of the destination chunk.</param> /// <param name="dst_cz">The global Z-coordinate of the destination chunk.</param> /// <returns>A <see cref="ChunkRef"/> for the destination chunk.</returns> public ChunkRef CopyChunk(int src_cx, int src_cz, int dst_cx, int dst_cz) { IRegion src_r = GetRegion(src_cx, src_cz); if (src_r == null) { return(null); } IRegion dst_r = GetRegion(dst_cx, dst_cz); if (dst_r == null) { int rx = dst_cx >> REGION_XLOG; int rz = dst_cz >> REGION_ZLOG; dst_r = _regionMan.CreateRegion(rx, rz); } IChunk c = src_r.GetChunk(src_cx & REGION_XMASK, src_cz & REGION_ZMASK); c.SetLocation(dst_cx, dst_cz); dst_r.SaveChunk(c); return(dst_r.GetChunkRef(dst_cx & REGION_XMASK, dst_cz & REGION_ZMASK)); }
protected virtual void Write() { ExecutedChunksQueue.WaitForInput(); using (var outputStream = new FileStream(Options.Output, FileMode.Create)) { using (var bufferedSTream = new BufferedStream(outputStream, Options.ReadBufferSize)) { while ((_executing || ExecutedChunksQueue.Count > 0) && !ErrorOccured) { IChunk chunk = null; if (ExecutedChunksQueue.TryDequeue(out chunk)) { bufferedSTream.Write(chunk.Body, 0, chunk.Body.Length); if (Options.VerboseOutput) { Console.WriteLine("AbstractProcessor: chunk " + chunk.Index + " was written"); } } else { Thread.Sleep(10); } } } } }
private void GenerateHeightMap(IChunk chunk) { Coordinates3D coords; var map = new byte[Chunk.Width, Chunk.Depth]; for (byte x = 0; x < Chunk.Width; x++) { for (byte z = 0; z < Chunk.Depth; z++) { for (byte y = (byte)(chunk.GetHeight(x, z) + 2); y > 0; y--) { if (y >= Chunk.Height) continue; coords.X = x; coords.Y = y - 1; coords.Z = z; var id = chunk.GetBlockID(coords); if (id == 0) continue; var provider = BlockRepository.GetBlockProvider(id); if (provider.LightOpacity != 0) { map[x, z] = y; break; } } } } HeightMaps[chunk.Coordinates] = map; }
/// <summary> /// 导出所有支持的贴图 /// </summary> public void ExportTextures() { string exportDir = $"{Path.GetDirectoryName(path)}/Export_{Path.GetFileNameWithoutExtension(path)}"; Directory.CreateDirectory(exportDir); exportDir += "/Textures"; Directory.CreateDirectory(exportDir); foreach (var kv in chunkManager.resourceChunks) { IChunk chunk = kv.Value; if (chunk.name == null || chunk.resourceId == 0) { continue; } string path = $"{exportDir}/{chunk.resourceId}_{chunk.name}"; if (kv.Value is Chunk_CreateTexture2D) { Chunk_CreateTexture2D texChunk = kv.Value as Chunk_CreateTexture2D; D3DTextureConvert.SaveTextureToFile(texChunk, path); } else if (kv.Value is Chunk_CreateSwapBuffer) { Chunk_CreateSwapBuffer swapChunk = kv.Value as Chunk_CreateSwapBuffer; D3DTextureConvert.SaveTextureToFile(swapChunk, path); } } }
public IChunk[] GenerateChunk(IEnumerable<IBlockDefinition> blockDefinitions, IPlanet planet, Index2 index) { IBlockDefinition sandDefinition = blockDefinitions.FirstOrDefault(d => typeof(SandBlockDefinition) == d.GetType()); ushort sandIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), sandDefinition) + 1); IChunk[] result = new IChunk[planet.Size.Z]; for (int layer = 0; layer < planet.Size.Z; layer++) result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = (int)(z / Chunk.CHUNKSIZE_Z); result[layer].SetBlock(x, y, block, sandIndex); } } } } return result; }
public void Use(IActor targetActor) { //get variables IChunk chunk = this.Chunk; int x = this.Position.X; int y = this.Position.Y; int z = this.Position.Z; IActor actor = targetActor; //permission check, is the Player allowed to open the door? Chunk castedChunk = chunk as Chunk; string nationName = castedChunk.NationOwner; if ((!string.IsNullOrEmpty(nationName) && (actor.Nation != nationName))) { return; } //get the index for the Block array from the given x, y and z int index = chunk.GetBlockIndex(x, y, z); //get the specific Block data by its index ushort currentBlock = chunk.Blocks[index]; //get baseDoorID (reason why the doorID has to be a multiple of 10, for this script to properly work) int baseDoorID = ((int)currentBlock / 10) * 10; int offset = (int)currentBlock - baseDoorID; //call ToggleDoors function with variables ToggleDoor(chunk, baseDoorID, offset, x, y, z); }
public void AddChunk(Vector3Int pos, IChunk chunk) { Columns[new Vector2Int(pos.x, pos.z)].AddChunk(pos.y, chunk); Chunks[pos] = (SmoothChunk)chunk; Chunks[pos].BuildGPU_DataBuffer(true); Vector3Int[] dirs = new Vector3Int[] { new Vector3Int(1, 0, 0), new Vector3Int(-1, 0, 0), new Vector3Int(0, 1, 0), new Vector3Int(0, -1, 0), new Vector3Int(0, 0, 1), new Vector3Int(0, 0, -1), }; /*Loom.QueueAsyncTask("ChunkUpdate", () => * { * foreach (Vector3Int d in dirs) * { * Vector3Int newPos = pos + d; * if (BuilderExists(newPos.x, newPos.y, newPos.z)) * { * Chunks[newPos].Render(true); * Chunks[newPos].BuildGPU_DataBuffer(true); * } * } * });*/ }
public ChunkRenderer(IChunk chunk, Func <ITexture2DAtlas> textureAtlasProvider, IMatrixProvider <Matrix4, Vector4> viewMatrix, IMatrixProvider <Matrix4, Vector4> projectionMatrix) { _chunk = chunk; _textureAtlasProvider = textureAtlasProvider; _viewMatrix = viewMatrix; _projectionMatrix = projectionMatrix; }
public MANAGER_ERROR AddChunk(Type chunk) { if (chunk == null) { return(MANAGER_ERROR.E_FAULT); } if (ChunkMap.ContainsValue(chunk)) { return(MANAGER_ERROR.E_DUPLICATE); } IChunk instance = (IChunk)Activator.CreateInstance(chunk); if (instance.RootIdentifier == null || instance.Identifier == null) { return(MANAGER_ERROR.E_SUCCESS); } string identifier = instance.RootIdentifier + instance.Identifier; if (identifier == null) { if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Log(2, "CHUNK", $"Error! {chunk.FullName} has no identifier!\n"); } } ChunkMap.Add(identifier, chunk); return(MANAGER_ERROR.E_SUCCESS); }
/// <summary> /// Writes a data directory /// </summary> /// <param name="writer">Writer</param> /// <param name="chunk">The data</param> internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk) { if (chunk == null || chunk.GetVirtualSize() == 0) writer.Write(0UL); else { writer.Write((uint)chunk.RVA); writer.Write(chunk.GetVirtualSize()); } }
public void Request(IChunk chunk) { lock (_in) { _in.Enqueue(chunk); Monitor.Pulse(_in); } }
public async Task SaveChunk(IChunk chunk) { await ChunkSaver.SaveFile(Destination, chunk.Start, chunk.Data); if (ChunkSaved != null) { ChunkSaved.Invoke(this, chunk); } }
public void Save(int universe, int planet, IChunk chunk) { var root = GetRoot(); string filename = planet.ToString() + "_" + chunk.Index.X + "_" + chunk.Index.Y + "_" + chunk.Index.Z + ".chunk"; using (Stream stream = File.Open(root.FullName + Path.DirectorySeparatorChar + filename, FileMode.Create, FileAccess.Write)) { serializer.Serialize(stream, chunk); } }
/* * Generates the top of the pine/conifer trees. * Type: * 0x0 - two level topper * 0x1 - three level topper */ protected void GenerateTopper(IChunk chunk, Coordinates3D location, byte type = 0x0) { const int sectionRadius = 1; GenerateCircle(chunk, location, sectionRadius, LeavesBlock.BlockID, 0x1); var top = location + Coordinates3D.Up; chunk.SetBlockID(top, LeavesBlock.BlockID); chunk.SetMetadata(top, 0x1); if (type == 0x1 && (top + Coordinates3D.Up).Y < Chunk.Height) GenerateVanillaCircle(chunk, top + Coordinates3D.Up, sectionRadius, LeavesBlock.BlockID, 0x1); }
public void Grow(IStructBlock iBlock, IChunk ichunk) { var chunk = ichunk as Chunk; var block = (StructBlock) iBlock; if (!CanGrow(block, chunk)) return; var blockUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); if (block.World.GetEffectiveLight(blockUp) < 9) return; if (block.World.Server.Rand.Next(29) != 0) return; if ((block.MetaData & 8) == 0) { chunk.SetData(block.Coords, (byte)(block.MetaData | 8)); return; } for (int i = block.Coords.WorldY; i < block.Coords.WorldY + 4; i++) { chunk.SetBlockAndData(block.Coords.BlockX, i, block.Coords.BlockZ, (byte)BlockData.Blocks.Wood, block.MetaData); if(chunk.GetType(block.Coords.BlockX, i + 1, block.Coords.BlockZ) != BlockData.Blocks.Air) break; } // Grow leaves for (int i = block.Coords.WorldY + 2; i < block.Coords.WorldY + 5; i++) for (int j = block.Coords.WorldX - 2; j <= block.Coords.WorldX + 2; j++) for (int k = block.Coords.WorldZ - 2; k <= block.Coords.WorldZ + 2; k++) { var nearbyChunk = block.World.GetChunkFromWorld(i, k) as Chunk; if (nearbyChunk == null || (nearbyChunk.GetType(j & 0xF, i, k & 0xF) != BlockData.Blocks.Air)) continue; nearbyChunk.SetBlockAndData(j & 0xF, i, k & 0xF, (byte)BlockData.Blocks.Leaves, block.MetaData); } for (int i = block.Coords.WorldX - 1; i <= block.Coords.WorldX + 1; i++) for (int j = block.Coords.WorldZ - 1; j <= block.Coords.WorldZ + 1; j++) { var nearbyChunk = block.World.GetChunkFromWorld(i, j) as Chunk; if (nearbyChunk == null || nearbyChunk.GetType(i & 0xF, block.Coords.WorldY + 5, j & 0xF) != BlockData.Blocks.Air) continue; nearbyChunk.SetBlockAndData(i & 0xF, block.Coords.WorldY + 5, j & 0xF, (byte)BlockData.Blocks.Leaves, block.MetaData); } }
public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes) { var noise = new Perlin(); noise.Seed = world.Seed; var chanceNoise = new ClampNoise(noise); chanceNoise.MaxValue = 2; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { var biome = biomes.GetBiome(chunk.Biomes[x * Chunk.Width + z]); var blockX = MathHelper.ChunkToBlockX(x, chunk.Coordinates.X); var blockZ = MathHelper.ChunkToBlockZ(z, chunk.Coordinates.Z); var height = chunk.HeightMap[x * Chunk.Width + z]; if (noise.Value2D(blockX, blockZ) > 0) { var blockLocation = new Coordinates3D(x, height, z); var plantPosition = blockLocation + Coordinates3D.Up; if (chunk.GetBlockID(blockLocation) == biome.SurfaceBlock && plantPosition.Y < Chunk.Height) { var chance = chanceNoise.Value2D(blockX, blockZ); if (chance < 1) { var bushNoise = chanceNoise.Value2D(blockX * 0.7, blockZ * 0.7); var grassNoise = chanceNoise.Value2D(blockX * 0.3, blockZ * 0.3); if (biome.Plants.Contains(PlantSpecies.Deadbush) && bushNoise > 1 && chunk.GetBlockID(blockLocation) == SandBlock.BlockID) { GenerateDeadBush(chunk, plantPosition); continue; } if (biome.Plants.Contains(PlantSpecies.TallGrass) && grassNoise > 0.3 && grassNoise < 0.95) { byte meta = (grassNoise > 0.3 && grassNoise < 0.45 && biome.Plants.Contains(PlantSpecies.Fern)) ? (byte)0x2 : (byte)0x1; GenerateTallGrass(chunk, plantPosition, meta); continue; } } else { var flowerTypeNoise = chanceNoise.Value2D(blockX * 1.2, blockZ * 1.2); if (biome.Plants.Contains(PlantSpecies.Rose) && flowerTypeNoise > 0.8 && flowerTypeNoise < 1.5) { GenerateRose(chunk, plantPosition); } else if (biome.Plants.Contains(PlantSpecies.Dandelion) && flowerTypeNoise <= 0.8) { GenerateDandelion(chunk, plantPosition); } } } } } } }
private void MossFloor(IChunk chunk, Coordinates3D location, Random random) { for (int x = location.X; x < location.X + Size.X; x++) { for (int z = location.Z; z < location.Z + Size.Z; z++) { if (random.Next(0, 3) == 0) chunk.SetBlockID(new Coordinates3D(x, location.Y, z), MossStoneBlock.BlockID); } } }
public static void GenerateColumn(IChunk chunk, Coordinates3D location, int height, byte block, byte meta = 0x0) { for (int offset = 0; offset < height; offset++) { var blockLocation = location + new Coordinates3D(0, offset, 0); if (blockLocation.Y >= Chunk.Height) return; chunk.SetBlockID(blockLocation, block); chunk.SetMetadata(blockLocation, meta); } }
public bool CanGrow(IStructBlock block, IChunk chunk) { if (chunk == null || block.Coords.WorldY > 120) return false; /*UniversalCoords oneUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); byte lightUp = block.World.GetBlockData(oneUp); if (lightUp < 9) return false;*/ return true; }
public void SpawnInitialMobs(IChunk chunk, Dimension dimension) { if (!SpawnRules.ContainsKey(dimension)) return; var rules = SpawnRules[dimension]; foreach (var rule in rules) { if (MathHelper.Random.Next(rule.ChunkSpawnChance) == 0) rule.GenerateMobs(chunk, EntityManager); } }
public static bool blockTypeExists(IChunk chunk, ushort blockID, IActor actor) { if (chunk.GetTileData().Keys.Contains(blockID)) { return true; } else { ((IGameServer)actor.State).ChatManager.SendActorMessage("Invalid Block ID, Blocktype not found.", actor); return false; } }
public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location) { if (!ValidLocation(location)) return false; var random = new Random(world.Seed); int height = random.Next(4, 5); GenerateColumn(chunk, location, height, WoodBlock.BlockID, 0x0); var leafLocation = location + new Coordinates3D(0, height, 0); GenerateSphere(chunk, leafLocation, LeafRadius, LeavesBlock.BlockID, 0x0); return true; }
public void Serialize(Stream stream, IChunk chunk) { using (BinaryWriter bw = new BinaryWriter(stream)) { List<IBlockDefinition> definitions = new List<IBlockDefinition>(); // Types sammeln for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] != 0) { IBlockDefinition definition = BlockDefinitionManager.GetForType(chunk.Blocks[i]); if (!definitions.Contains(definition)) definitions.Add(definition); } } // Schreibe Phase 1 bw.Write(definitions.Count); // Im Falle eines Luft-Chunks... if (definitions.Count == 0) return; foreach (var definition in definitions) { bw.Write(definition.GetType().FullName); } // Schreibe Phase 2 for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] == 0) { // Definition Index (Air) bw.Write((ushort)0); // Meta Data bw.Write(0); } else { // Definition Index IBlockDefinition definition = BlockDefinitionManager.GetForType(chunk.Blocks[i]); bw.Write((ushort)definitions.IndexOf(definition) + 1); // Meta Data bw.Write(chunk.MetaData[i]); } } } }
public bool CanGrow(IStructBlock block, IChunk chunk) { // Crops grow from 0x0 to 0x7 if (chunk == null || block.MetaData == 0x07) return false; if (block.Coords.WorldY == 127) return false; /*byte blockAboveLight = block.World.GetBlockLight(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); if (blockAboveLight < 9) return false;*/ return true; }
private string HtmlizeChunk(IChunk chunk, int i) { if (chunk is AnnotatedCodeChunk) { return new CodeChunkHtmlizer().HtmlizeChunkText(i, (AnnotatedCodeChunk)chunk); } else if (chunk is MarkdownChunk) { return new MarkdownSharp.Markdown().Transform(((MarkdownChunk)chunk).MarkdownSource); } throw new NotSupportedException(); }
public void SetChunk(ILocalChunkCache manager, int x, int y, int z) { var newPosition = new Index3(x, y, z); if (_manager == manager && newPosition == ChunkPosition) return; _manager = manager; ChunkPosition = newPosition; chunk = null; loaded = false; }
public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location) { if (!ValidLocation(location)) return false; var random = new Random(world.Seed); int height = random.Next(7, 8); GenerateColumn(chunk, location, height, WoodBlock.BlockID, 0x1); GenerateCircle(chunk, location + new Coordinates3D(0, height - 2, 0), LeafRadius - 1, LeavesBlock.BlockID, 0x1); GenerateCircle(chunk, location + new Coordinates3D(0, height - 1, 0), LeafRadius, LeavesBlock.BlockID, 0x1); GenerateCircle(chunk, location + new Coordinates3D(0, height, 0), LeafRadius, LeavesBlock.BlockID, 0x1); GenerateTopper(chunk, (location + new Coordinates3D(0, height + 1, 0)), 0x0); return true; }