/// Place a block data in a position and get out the created block public ChunkSection PlaceBlock(Coord3 localPos, BlockData data, out Block block, bool updateChunk = true) { if (InRange(localPos)) { DestroyBlock(blocks[localPos.x][localPos.y][localPos.z]); CreateBlock(localPos, data, ref blocks[localPos.x][localPos.y][localPos.z]); if (data != null) { chunk.IsAllAir = false; if (data.id != stoneID) { chunk.IsAllStone = false; } } chunk.SetDirty(); if (updateChunk) { chunk.Render(); chunk.UpdateNeighbors(localPos); } block = blocks[localPos.x][localPos.y][localPos.z]; return(chunk); } else { return(chunk.world.PlaceBlock(ToWorldSpace(localPos), data, out block, updateChunk)); } }
/// <summary> /// 获取几何对象的坐标点信息 /// </summary> /// <param name="feature"></param> /// <param name="type"></param> /// <returns></returns> internal static dynamic GetCoordinates(this IFeature feature, GeoJSONType type) { dynamic coords = null; switch (type) { case GeoJSONType.Point: Coord1 coord1 = new Coord1(); coords = coord1.GetCoords(feature); break; case GeoJSONType.MultiPoint: case GeoJSONType.LineString: Coord2 coord2 = new Coord2(); coords = coord2.GetCoords(feature); break; case GeoJSONType.MultiLineString: Coord3 coord31 = new Coord3(); coords = coord31.GetCoords(feature); break; case GeoJSONType.Polygon: Coord3 coord32 = new Coord3(); coords = coord32.GetClosedCoords(feature); break; default: return(null); } return(coords); }
private void AddDecalHashVerts(Coord3 pos) { float x = pos.x, y = pos.y, z = pos.z; for (int i = 0; i < 2; i++) { verts.Add(new Vector3(x + F, y + F, z + T)); verts.Add(new Vector3(x - F, y + F, z + T)); verts.Add(new Vector3(x - F, y - F, z + T)); verts.Add(new Vector3(x + F, y - F, z + T)); } for (int i = 0; i < 2; i++) { verts.Add(new Vector3(x + F, y + F, z - T)); verts.Add(new Vector3(x - F, y + F, z - T)); verts.Add(new Vector3(x - F, y - F, z - T)); verts.Add(new Vector3(x + F, y - F, z - T)); } for (int i = 0; i < 2; i++) { verts.Add(new Vector3(x - T, y + F, z + F)); verts.Add(new Vector3(x - T, y + F, z - F)); verts.Add(new Vector3(x - T, y - F, z - F)); verts.Add(new Vector3(x - T, y - F, z + F)); } for (int i = 0; i < 2; i++) { verts.Add(new Vector3(x + T, y + F, z - F)); verts.Add(new Vector3(x + T, y + F, z + F)); verts.Add(new Vector3(x + T, y - F, z + F)); verts.Add(new Vector3(x + T, y - F, z - F)); } }
protected override void GenerateChunk(ChunkSection chunk, int x, int z) { var localPos = new Coord3(x, 0, z); var pos = localPos.BlockToWorld(chunk.worldPosition); var height = baseHeight + GetNoise(pos.x, 0, pos.z, noiseFreq, noiseHeight); for (int y = 0; y < ChunkSection.Size; y++) { localPos.y = y; pos = localPos.BlockToWorld(chunk.worldPosition); if (chanceNoise) { if (noise3d || pos.y == 0) { var chance = GetChance(pos.x, pos.y, pos.z, freq, dens); if (chance) { SetBlock(chunk, localPos, dirt); SetBlock(chunk, new Coord3(localPos.x, localPos.y + 1, localPos.z), stone); } } } } }
private bool NotCave(Coord3 wpos) { int caveNoise = GetNoiseFloored(wpos.y, wpos.x, wpos.z, caveNoiseScale1, 10 / 3); caveNoise += GetNoiseFloored(wpos.x, wpos.y, wpos.z, caveNoiseScale2, 10 / 3); caveNoise += GetNoiseFloored(wpos.x, wpos.z, wpos.y, caveNoiseScale3, 10 / 3); return(caveNoise < 5); }
public void AddDecalCross(Coord3 position, int textureIndex, int subMesh) { AddDecalCrossVerts(position); AddDecalCrossTris((int)subMesh); for (int i = 0; i < 4; i++) { AddQuadUV(textureIndex, 0); } }
/// Loads custom actions of a block public void LoadBlock(Coord3 pos, BlockData data, CustomBlock block) { block.Setup(data, chunk, pos); block.OnLoad(); if (block is ITickable tickable) { chunk.world.OnTick -= tickable.OnTick; } }
private void AddDecalFlatVerts(Coord3 pos) { float x = pos.x, y = pos.y, z = pos.z; verts.Add(new Vector3(x + F, y - F + O, z - F)); verts.Add(new Vector3(x - F, y - F + O, z - F)); verts.Add(new Vector3(x - F, y - F + O, z + F)); verts.Add(new Vector3(x + F, y - F + O, z + F)); }
protected virtual void GenerateChunk(ChunkSection chunk, int x, int z) { var stone = ResourceStore.Blocks["stone"]; for (int y = 0; y < ChunkSection.Size; y++) { var pos = new Coord3(x, y, z); SetBlock(chunk, pos, stone); } }
/// Run the update event on all neighbors of a block position public void UpdateBlockNeighbors(Coord3 pos) { foreach (var dir in Coord3.Directions) { var block = GetBlock(pos + dir); if (block is CustomBlock custom) { custom?.OnNeighborUpdate(); } } }
void UpdateShape() { bool[] solid = new bool[6]; for (int i = 0; i < 6; i++) { Coord3 pos = position + Coord3.Directions[i]; var block = chunk.blocks.GetBlock(pos); solid[i] = block != null && block.id == id; } ChangeShape(solid); }
protected Block SetBlock(ChunkSection chunk, Coord3 localPos, BlockData data, bool replace = false) { var b = chunk.blocks.GetBlock(localPos); if (replace || b == null) { Block outb; chunk.blocks.PlaceBlock(localPos, data, out outb, false); return(outb); } return(null); }
public void AddBoundingBox(Coord3 position, float size, int down = 3, bool cullDown = false) { for (int i = 0; i < 6; i++) { if (cullDown && i == down) { continue; } AddCubeFaceVerts(i, position, size, down); AddQuadTris(0); } }
private void AddCubeFaceVerts(int dir, Coord3 pos, float s, int down) { float x = pos.x, y = pos.y, z = pos.z; if (down != 3) { Debug.LogError("Directional Bounding Boxes Not Implemented"); } switch (dir) { case BlockFace.front: verts.Add(new Vector3(x + (F * s), y + (F * s), z + (F * s))); verts.Add(new Vector3(x - (F * s), y + (F * s), z + (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z + (F * s))); verts.Add(new Vector3(x + (F * s), (y - F), z + (F * s))); break; case BlockFace.back: verts.Add(new Vector3(x - (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x + (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x + (F * s), (y - F), z - (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z - (F * s))); break; case BlockFace.top: verts.Add(new Vector3(x + (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x - (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x - (F * s), y + (F * s), z + (F * s))); verts.Add(new Vector3(x + (F * s), y + (F * s), z + (F * s))); break; case BlockFace.bottom: verts.Add(new Vector3(x + (F * s), (y - F), z + (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z + (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z - (F * s))); verts.Add(new Vector3(x + (F * s), (y - F), z - (F * s))); break; case BlockFace.right: verts.Add(new Vector3(x - (F * s), y + (F * s), z + (F * s))); verts.Add(new Vector3(x - (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z - (F * s))); verts.Add(new Vector3(x - (F * s), (y - F), z + (F * s))); break; case BlockFace.left: verts.Add(new Vector3(x + (F * s), y + (F * s), z - (F * s))); verts.Add(new Vector3(x + (F * s), y + (F * s), z + (F * s))); verts.Add(new Vector3(x + (F * s), (y - F), z + (F * s))); verts.Add(new Vector3(x + (F * s), (y - F), z - (F * s))); break; } }
/// Get a block from this manager public Block GetBlock(Coord3 pos) { if (!chunk.IsBuilt) { return(null); } if (InRange(pos)) { return(blocks[pos.x][pos.y][pos.z]); } return(chunk.world.GetBlock(ToWorldSpace(pos))); }
private void AddCubeFaceNormalVerts(int dir, Coord3 pos) { float x = pos.x, y = pos.y, z = pos.z; switch (dir) { case BlockFace.front: verts.Add(new Vector3(x + F, y + F, z + F)); verts.Add(new Vector3(x - F, y + F, z + F)); verts.Add(new Vector3(x - F, y - F, z + F)); verts.Add(new Vector3(x + F, y - F, z + F)); break; case BlockFace.back: verts.Add(new Vector3(x - F, y + F, z - F)); verts.Add(new Vector3(x + F, y + F, z - F)); verts.Add(new Vector3(x + F, y - F, z - F)); verts.Add(new Vector3(x - F, y - F, z - F)); break; case BlockFace.top: verts.Add(new Vector3(x + F, y + F, z - F)); verts.Add(new Vector3(x - F, y + F, z - F)); verts.Add(new Vector3(x - F, y + F, z + F)); verts.Add(new Vector3(x + F, y + F, z + F)); break; case BlockFace.bottom: verts.Add(new Vector3(x + F, y - F, z + F)); verts.Add(new Vector3(x - F, y - F, z + F)); verts.Add(new Vector3(x - F, y - F, z - F)); verts.Add(new Vector3(x + F, y - F, z - F)); break; case BlockFace.right: verts.Add(new Vector3(x - F, y + F, z + F)); verts.Add(new Vector3(x - F, y + F, z - F)); verts.Add(new Vector3(x - F, y - F, z - F)); verts.Add(new Vector3(x - F, y - F, z + F)); break; case BlockFace.left: verts.Add(new Vector3(x + F, y + F, z - F)); verts.Add(new Vector3(x + F, y + F, z + F)); verts.Add(new Vector3(x + F, y - F, z + F)); verts.Add(new Vector3(x + F, y - F, z - F)); break; } }
protected override void GenerateChunk(ChunkSection chunk, int x, int z) { var localPos = new Coord3(x, 0, z); void Set(BlockData block) { SetBlock(chunk, localPos, block); } for (localPos.y = 0; localPos.y < ChunkSection.Size; localPos.y++) { var pos = localPos.BlockToWorld(chunk.worldPosition); bool isCave = GetChance(pos.x, pos.y, pos.z, caveFrequency, caveDensity) || GetChance(pos.y, pos.z, pos.x, caveFrequency + 0.02f, caveDensity + 4) || GetChance(-pos.x, -pos.y, -pos.z, caveFrequency - 0.02f, caveDensity - 4); if (pos.y <= stoneHeight && !isCave) { for (int i = 0; i < ores.Length; i++) { if (GetChance(pos.x, pos.y, pos.z, ores[i].spawnFrequency, ores[i].spawnDensity)) { Set(ores[i]); } else { Set(stone); } } } else if (pos.y < stoneHeight + dirtHeight && !isCave) { Set(dirt); } else if (pos.y == stoneHeight + dirtHeight && !isCave) { if (GetChance(pos.x, 0, pos.z, treeFrequency, treeDensity)) { GenerateStructure(chunk, localPos.x, localPos.y + 1, localPos.z, "tree"); } else if (GetChance(pos.x, 0, pos.z, grassFrequency, grassDensity)) { SetBlock(chunk, new Coord3(localPos.x, localPos.y + 1, localPos.z), grass_decal); } Set(grass); } } }
protected void FillWithAir(ChunkSection chunk) { var air = ResourceStore.Blocks["air"]; for (int x = 0; x < ChunkSection.Size; x++) { for (int y = 0; y < ChunkSection.Size; y++) { for (int z = 0; z < ChunkSection.Size; z++) { var pos = new Coord3(x, y, z); SetBlock(chunk, pos, air); } } } }
protected void GenerateStructure(ChunkSection chunk, int x, int y, int z, string id) { var s = ResourceStore.Structures[id]; for (int l = 0; l < s.height; l++) { for (int xi = 0; xi < s.size.x; xi++) { for (int zi = 0; zi < s.size.y; zi++) { var val = s[l][zi * s.size.y + xi]; var block = s.blocks[val]; var pos = new Coord3(x + xi, y + l, z + zi) - (Coord3)s.origin + Coord3.one; SetBlock(chunk, pos, block, s.cutout); } } } }
/// Setup this chunk pulled from the pool public void Setup(Coord2 position) { this.position = position; IsBuilt = false; IsGenerated = false; IsRendered = false; IsDirty = false; transform.parent = world.transform; transform.localPosition = (Coord3)position * ChunkSection.Size; name = "Chunk " + position; for (int i = 0; i < chunks.Length; i++) { var pos = new Coord3(position.x, i, position.y); chunks[i].Setup(pos); } }
protected override void GenerateChunk(ChunkSection chunk, int x, int z) { if (chunk.position != Coord3.zero) { return; } for (int y = 0; y < 4; y++) { if (x >= 0 && x <= 3 && z >= 0 && z <= 3) { var pos = new Coord3(8 * x, 8 * y, 8 * z); var block = SetBlock(chunk, pos, proto); chunk.blocks.GetCustomBlock <RotatedBlock>(block, b => b.SetRotation(new Coord3(x, y, z))); var block_obj = SetBlock(chunk, new Coord3(8 * x, 8 * y + 2, 8 * z), proto_obj); chunk.blocks.GetCustomBlock <StandaloneBlock>(block_obj, b => b.gameObject.transform.localEulerAngles = new Vector3(x * 90, y * 90, z * 90)); } } }
/// When a new block it placed, setup custom actions void CreateBlock(Coord3 pos, BlockData data, ref Block block) { UpdateBlockNeighbors(pos); if (data == null) { block = null; return; } if (!data.IsCustomType && !data.IsStandalone) { block = new Block(data.id); return; } var type = data.IsCustomType ? data.dataType : BlockDataType.StandaloneBlock; block = CustomBlock.Convert(data.id, type); var customBlock = (CustomBlock)block; LoadBlock(pos, data, customBlock); customBlock.OnPlace(); }
/// Apples load to all blocks public void LoadAll() { for (int x = 0; x < ChunkSection.Size; x++) { for (int y = 0; y < ChunkSection.Size; y++) { for (int z = 0; z < ChunkSection.Size; z++) { var block = blocks[x][y][z]; if (block == null) { continue; } var pos = new Coord3(x, y, z); var data = ResourceStore.Blocks[block.id]; if (data.IsCustomType || data.IsStandalone) { var customBlock = (CustomBlock)block; LoadBlock(pos, data, customBlock); } } } } }
private void AddDecalRampVerts(Coord3 pos, int rot) { float x = pos.x, y = pos.y, z = pos.z; var dir = Coord2.TileCorners[rot]; // (-1, 1), (1, 1), (1, -1), (-1, -1) switch (rot) { case 0: verts.Add(new Vector3(x + F, y + F + O, z - F)); verts.Add(new Vector3(x - F, y + F + O, z - F)); verts.Add(new Vector3(x - F, y + O, z + F)); verts.Add(new Vector3(x + F, y + O, z + F)); break; case 1: verts.Add(new Vector3(x - F, y + F + O, z - F)); verts.Add(new Vector3(x - F, y + F + O, z + F)); verts.Add(new Vector3(x + F, y + O, z + F)); verts.Add(new Vector3(x + F, y + O, z - F)); break; case 2: verts.Add(new Vector3(x - F, y + F + O, z + F)); verts.Add(new Vector3(x + F, y + F + O, z + F)); verts.Add(new Vector3(x + F, y + O, z - F)); verts.Add(new Vector3(x - F, y + O, z - F)); break; case 3: verts.Add(new Vector3(x + F, y + F + O, z + F)); verts.Add(new Vector3(x + F, y + F + O, z - F)); verts.Add(new Vector3(x - F, y + O, z - F)); verts.Add(new Vector3(x - F, y + O, z + F)); break; } }
public void SetType(PipeBlock.PipeType type, Coord3 rotation) { if (current != null) { Destroy(current); } if (type == PipeBlock.PipeType.Straight) { current = PipeStraight; } else if (type == PipeBlock.PipeType.Corner) { current = PipeCorner; } else if (type == PipeBlock.PipeType.End) { current = PipeEnd; } current = Instantiate(current, transform); current.transform.rotation = Quaternion.Euler(rotation * 90); current.transform.localPosition = Vector3.zero; }
public override void OnPlace() { miningLocation = position - new Coord3(2, 1, 2); mining = true; }
public void UpdateObjectPosition(ulong guid, Coord3 coord3, uint time) { Core.UpdateObjectPosition(guid, coord3.X, coord3.Y, coord3.Z, 0f, time, OpcodeName); }
Coord3 TransformChunk(Coord3 blockPos, Coord3 newWorldPosition) => blockPos + chunk.worldPosition - newWorldPosition;
bool InRange(Coord3 blockPos) => blockPos.InRange(0, ChunkSection.Size);
Coord3 ToBlockSpace(Coord3 worldPos) => worldPos - chunk.worldPosition;
Coord3 ToWorldSpace(Coord3 blockPos) => blockPos + chunk.worldPosition;