public bool Decorade(Chunk chunk, int x, int y, int z, IMTBRandom random) { if (chunk.GetBlock(x, y, z, true).BlockType == BlockType.Air) { setBlock(chunk, x, y, z, GetDecoration()); return(true); } return(false); }
private bool CheckCanGenerator(Chunk chunk, int treeTrunkStartHeight, int treeTrunkNextHeight, int treeLeaveStartHeight, int treeLeaveNextHeight, int trunkWidthStartX, int trunkWidthStartZ, int trunkWidthNextX, int trunkWidthNextZ, int leaveWidthStartX, int leaveWidthStartZ, int leaveWidthNextX, int leaveWidthNextZ) { for (int cx = trunkWidthStartX; cx <= trunkWidthNextX; cx++) { for (int cz = trunkWidthStartZ; cz <= trunkWidthNextZ; cz++) { if (chunk.GetBlock(cx, treeTrunkStartHeight - 1, cz).BlockType == BlockType.Air) { return(false); } } } for (int cy = treeTrunkStartHeight; cy < treeLeaveNextHeight; cy++) { if (cy < treeLeaveStartHeight) { for (int cx = trunkWidthStartX; cx <= trunkWidthNextX; cx++) { for (int cz = trunkWidthStartZ; cz <= trunkWidthNextZ; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } continue; } for (int cx = leaveWidthStartX; cx <= leaveWidthNextX; cx++) { for (int cz = leaveWidthStartZ; cz <= leaveWidthNextZ; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } } return(true); }
private bool CheckCanGenerator(int x, int y, int z, Chunk chunk, int treeTrunkWidth, int treeTrunkHeight, int treeHalfLeaveWidth, int treeLeaveHeight, int treeLeaveOffset) { int treeHeight = treeTrunkHeight + treeLeaveHeight + treeLeaveOffset; int treeCrownStartHeight = treeTrunkHeight + treeLeaveOffset; for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { if (chunk.GetBlock(cx, y - 1, cz).BlockType == BlockType.Air) { return(false); } } } for (int cy = y; cy < y + treeHeight; cy++) { if (cy - y < treeCrownStartHeight) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } continue; } for (int cx = x - treeHalfLeaveWidth; cx <= x + treeHalfLeaveWidth + 1; cx++) { for (int cz = z - treeHalfLeaveWidth; cz <= z + treeHalfLeaveWidth + 1; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } } return(true); }
public bool Decorade(Chunk chunk, int x, int y, int z, IMTBRandom random) { int height = random.Range(3, 8); int width = 2; for (int cx = 0; cx < width; cx++) { for (int cz = 0; cz < width; cz++) { if (chunk.GetBlock(cx + x, y - 1, cz + z).BlockType == BlockType.Air) { return(false); } } } for (int cy = y; cy < y + height; cy++) { for (int cx = 0; cx < width; cx++) { for (int cz = 0; cz < width; cz++) { if (chunk.GetBlock(x + cx, cy, z + cz).BlockType != BlockType.Air) { return(false); } } } } for (int cy = y; cy < y + height; cy++) { for (int cx = 0; cx < width; cx++) { for (int cz = 0; cz < width; cz++) { if (chunk.GetBlock(x + cx, cy, z + cz).BlockType == BlockType.Air) { setBlock(chunk, x + cx, cy, z + cz, new Block(BlockType.Block_31)); } } } } return(true); }
private void ShrinkHorizontalInPos(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel) { //当前光照强度为最大值时不收缩 if (curLightLevel >= WorldConfig.Instance.maxLightLevel) { return; } //当前高度大于光照高度,不再收缩,直接从旁边扩散 if (y >= chunk.GetHeight(x, z, true)) { int lightLevel = chunk.GetSunLight(x, y, z); int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk)); return; } Block b = chunk.GetBlock(x, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int lightDamp = calculator.LightDamp(b.ExtendId); if (lightDamp < WorldConfig.Instance.maxLightLevel) { int lightLevel = chunk.GetSunLight(x, y, z); if (lightLevel > 0) { int temp = prevLightLevel - lightDamp; //如果前一个物块比当前物块的太阳光亮,那么减弱当前物块的亮度 if (temp > lightLevel) { int nextLightLevel = curLightLevel - lightDamp - 1; if (nextLightLevel < 0) { nextLightLevel = 0; } //如果最终结果没有发生改变,那么不收缩 if (nextLightLevel == lightLevel) { return; } chunk.SetSunLight(x, y, z, nextLightLevel, true); if (!_changedList.Contains(chunk)) { _changedList.Add(chunk); } int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk)); } //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度 else if (temp < lightLevel) { int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk)); } } } }
private void SpreadInPosDown(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel) { if (curLightLevel >= WorldConfig.Instance.maxLightLevel) { return; } //当前高度大于光照高度,往下收缩,不管亮度是否大于自己 if (y >= chunk.GetHeight(x, z, true)) { return; } Block b = chunk.GetBlock(x, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int lightDamp = calculator.LightDamp(b.ExtendId); if (lightDamp < WorldConfig.Instance.maxLightLevel) { int lightLevel = chunk.GetSunLight(x, y, z); if (lightLevel > 0) { int temp = prevLightLevel - lightDamp; //向下收缩,考虑到都为15的情况,相等的情况下也收缩掉 if (temp > lightLevel || (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel)) { int nextLightLevel = curLightLevel - lightDamp - 1; if (nextLightLevel < 0) { nextLightLevel = 0; } if (nextLightLevel == lightLevel) { return; } chunk.SetSunLight(x, y, z, nextLightLevel, true); if (!_changedList.Contains(chunk)) { _changedList.Add(chunk); } int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; if (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel) { lightLevel = nextLightLevel; } _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk)); } //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度 else if (temp < lightLevel) { int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk)); } } } }
public bool Decorade(Chunk chunk, int x, int y, int z, IMTBRandom random) { // int height = random.Range(1,3); // int i = 0; // for (i = 0; i < height; i++) { // if(chunk.GetBlock(x,y + i,z,true).BlockType != BlockType.Air) // { // break; // } // } // if(i == height) // { // for (i = 0; i < height; i++) { // chunk.SetBlock(x,y + i,z,new Block(BlockType.Block_50)); // } // return true; // } // return false; Vector3[] posData = totalData[random.Range(0, totalData.Length)][random.Range(0, 4)]; for (int i = 0; i < posData.Length; i++) { if (chunk.GetBlock(x + (int)posData[i].x, y + (int)posData[i].y, z + (int)posData[i].z).BlockType != BlockType.Air) { return(false); } if (posData[i].y == 0) { if (chunk.GetBlock(x + (int)posData[i].x, y + (int)posData[i].y - 1, z + (int)posData[i].z).BlockType == BlockType.Air) { return(false); } } } for (int i = 0; i < posData.Length; i++) { chunk.SetBlock(x + (int)posData[i].x, y + (int)posData[i].y, z + (int)posData[i].z, new Block(BlockType.Block_50)); } return(false); }
private bool CheckCanGenerator(int x, int y, int z, Chunk chunk, int treeHeight, int treeWidth) { if (chunk.GetBlock(x, y, z).BlockType != BlockType.Air) { return(false); } for (int cy = y + 1; cy < y + treeHeight; cy++) { for (int cx = x - treeWidth; cx <= x + treeWidth; cx++) { for (int cz = z - treeWidth; cz <= z + treeWidth; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } } return(true); }
public virtual MeshData FaceDataFront (Chunk chunk, int x, int y, int z, MeshData meshData, byte extendId) { Block centerBlock = chunk.GetBlock(x, y, z); Block leftBlock = chunk.GetBlock(x - 1, y, z); Block rightBlock = chunk.GetBlock(x + 1, y, z); Block frontBlock = chunk.GetBlock(x, y, z + 1); Block leftFront = chunk.GetBlock(x - 1, y, z + 1); Block rightFront = chunk.GetBlock(x + 1, y, z + 1); float rightBackHeight = GetAverageHeight(frontBlock, centerBlock, rightFront, rightBlock); float leftBackHeight = GetAverageHeight(frontBlock, centerBlock, leftFront, leftBlock); float leftFrontHeight = 0; float rightFrontHeight = 0; meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x, y + leftFrontHeight, z + 1f)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x + 1f, y + rightFrontHeight, z + 1f)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x + 1f, y + rightBackHeight, z + 1f)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x, y + leftBackHeight, z + 1f)); meshData.AddQuadTriangles(); // AddSpecialUV(meshData,extendId,Direction.front); Vector2 dic = GetRotate(leftFrontHeight, rightFrontHeight, rightBackHeight, leftBackHeight); AddUVRotate(meshData, extendId, Direction.front, dic.y, dic.x); AddSpecialColorAndSpeed(chunk, x, y, z + 1, meshData, 2); return(meshData); }
private int CheckAroundNum(Chunk chunk, int x, int y, int z) { int num = 0; if (chunk.GetBlock(x - 1, y, z).BlockType != BlockType.Air) { num++; } if (chunk.GetBlock(x + 1, y, z).BlockType != BlockType.Air) { num++; } if (chunk.GetBlock(x, y, z - 1).BlockType != BlockType.Air) { num++; } if (chunk.GetBlock(x, y, z + 1).BlockType != BlockType.Air) { num++; } if (chunk.GetBlock(x, y - 1, z).BlockType != BlockType.Air) { num++; } if (chunk.GetBlock(x, y + 1, z).BlockType != BlockType.Air) { num++; } return(num); }
public virtual MeshData FaceDataUp (Chunk chunk, int x, int y, int z, MeshData meshData, byte extendId) { Block centerBlock = chunk.GetBlock(x, y, z); Block leftBlock = chunk.GetBlock(x - 1, y, z); Block rightBlock = chunk.GetBlock(x + 1, y, z); Block frontBlock = chunk.GetBlock(x, y, z + 1); Block backBlock = chunk.GetBlock(x, y, z - 1); Block leftFront = chunk.GetBlock(x - 1, y, z + 1); Block leftBack = chunk.GetBlock(x - 1, y, z - 1); Block rightFront = chunk.GetBlock(x + 1, y, z + 1); Block rightBack = chunk.GetBlock(x + 1, y, z - 1); float leftFrontHeight = GetAverageHeight(leftBlock, centerBlock, leftFront, frontBlock); float rightFrontHeight = GetAverageHeight(rightBlock, centerBlock, rightFront, frontBlock); float rightBackHeight = GetAverageHeight(rightBlock, centerBlock, rightBack, backBlock); float leftBackHeight = GetAverageHeight(leftBlock, centerBlock, leftBack, backBlock); // //计算流体流动方向 // float dicX = 2 * (leftBackHeight + leftFrontHeight - rightBackHeight - rightFrontHeight); // float dicZ = 2 * (leftBackHeight + rightBackHeight - leftFrontHeight - rightFrontHeight); // Vector2 dic = new Vector2(dicX,dicZ); // dic.Normalize(); // if(dic.x == 0 && dic.y == 0)dic.x = 1; // float sinDic = dic.y; // float cosDic = dic.x; meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x, y + leftFrontHeight, z + 1f)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x + 1f, y + rightFrontHeight, z + 1f)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x + 1f, y + rightBackHeight, z)); meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(x, y + leftBackHeight, z)); meshData.AddQuadTriangles(); // AddSpecialUV(meshData,extendId,Direction.up); Vector2 dic = GetRotate(leftFrontHeight, rightFrontHeight, rightBackHeight, leftBackHeight); AddUVRotate(meshData, extendId, Direction.up, dic.y, dic.x); float speed = dic.magnitude == 0 ? 0 : 0.5f; AddSpecialColorAndSpeed(chunk, x, y, z, meshData, speed); return(meshData); }
public bool Decorade(Chunk chunk, int x, int y, int z, IMTBRandom random) { int treeTrunkWidth = random.Range(1, 3); int treeTrunkHeight = random.Range(2, 5); for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { if (chunk.GetBlock(cx, y - 1, cz).BlockType == BlockType.Air) { return(false); } } } for (int cy = y; cy < y + treeTrunkHeight; cy++) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } } for (int cy = y; cy < y + treeTrunkHeight; cy++) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_19, 6)); } } } return(true); }
public Block GetBlock(int x, int y, int z) { Chunk chunk = GetChunk(x, y, z); if (chunk != null && chunk.isTerrainDataPrepared) { Block block = chunk.GetBlock(x - chunk.worldPos.x, y - chunk.worldPos.y, z - chunk.worldPos.z, true); return(block); } else { return(new Block(BlockType.Null)); } }
private bool CheckConditionMeet(Chunk chunk, List <CheckCondition> conditions, int x, int y, int z) { if (conditions.Count > 0) { for (int i = 0; i < conditions.Count; i++) { Block conditionBlock = chunk.GetBlock(x + conditions[i].offsetX, y + 1 + conditions[i].offsetY, z + conditions[i].offsetZ); for (int j = 0; j < conditions[i].conditionBlocks.Count; j++) { if (!conditionBlock.EqualOther(conditions[i].conditionBlocks[j])) { return(false); } } } } return(true); }
private bool CreateTree(int x, int y, int z, Chunk chunk, int treeTrunkWidth, int treeTrunkHeight, int treeLeaveWidth, int treeLeaveHeight, int treeLeaveOffset, IMTBRandom random) { int halfTreeLeaveWidth = treeLeaveWidth / 2; int treeLeaveTopY = treeLeaveHeight + treeLeaveOffset + treeTrunkHeight - 1 + y; int treeLeaveStartY = treeLeaveTopY - halfTreeLeaveWidth; _spreadQueue.Clear(); Block curBlock = chunk.GetBlock(x, treeLeaveStartY, z); if (curBlock.BlockType == BlockType.Air) { setBlock(chunk, x, treeLeaveStartY, z, new Block(BlockType.Block_41, 2)); } WorldPos startPos = new WorldPos(x, treeLeaveStartY, z); _spreadQueue.Enqueue(startPos); while (_spreadQueue.Count > 0) { WorldPos pos = _spreadQueue.Dequeue(); TreeLeaveSpread(chunk, pos.x + 1, pos.y, pos.z, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); TreeLeaveSpread(chunk, pos.x - 1, pos.y, pos.z, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); TreeLeaveSpread(chunk, pos.x, pos.y + 1, pos.z, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); TreeLeaveSpread(chunk, pos.x, pos.y - 1, pos.z, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); TreeLeaveSpread(chunk, pos.x, pos.y, pos.z + 1, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); TreeLeaveSpread(chunk, pos.x, pos.y, pos.z - 1, _spreadQueue, halfTreeLeaveWidth, treeLeaveTopY, treeLeaveHeight, startPos); } bool hasFaceBlock = random.Range(0, 100) < 50; int faceBlock = random.Range(0, treeTrunkHeight); for (int i = 0; i < treeTrunkHeight; i++) { if (hasFaceBlock && faceBlock == i) { setBlock(chunk, x, y + i, z, new Block(BlockType.Block_75, (byte)random.Range(0, 4)), true); } else { setBlock(chunk, x, y + i, z, new Block(BlockType.Block_19, 2), true); } } return(true); }
private void TreeLeaveSpread(Chunk chunk, int x, int y, int z, Queue <WorldPos> queue, int radius, int treeTopY, int treeLeaveHeight, WorldPos startPos) { if (treeTopY - y < treeLeaveHeight) { int dis = Math.Abs(x - startPos.x) + Math.Abs(y - startPos.y) + Math.Abs(z - startPos.z); Block curBlock = chunk.GetBlock(x, y, z); if (curBlock.BlockType == BlockType.Air) { setBlock(chunk, x, y, z, new Block(BlockType.Block_41, 2)); } else { return; } if (dis >= radius) { return; } queue.Enqueue(new WorldPos(x, y, z)); } }
////把植物种植到场景中 public void buildPlant(Vector3 position, DecorationType type = DecorationType.FaceTree, int aoId = 0, float growTime = 0) { MTBPlantData data = MTBPlantDataManager.Instance.getData((int)type); GrowDecorationParam paras = new GrowDecorationParam(data); if (aoId == 0) { paras.aoId = AoIdManager.instance.getAoId(); } else { paras.aoId = aoId; } paras.growedTime = 0; paras.pos = position; paras.random = _random; int x = ((int)position.x); int z = ((int)position.z); int localx = x % Chunk.chunkWidth; int localz = z % Chunk.chunkDepth; localx = localx < 0 ? localx + Chunk.chunkWidth : localx; localz = localz < 0 ? localz + Chunk.chunkDepth : localz; Chunk chunk = World.world.GetChunk(x, (int)position.y, z); for (int y = (int)position.y + 5; y >= (int)position.y - 5; y--) { BlockType curType = chunk.GetBlock(localx, y, localz).BlockType; if (curType != BlockType.Air && curType != BlockType.StillWater) { paras.loacalPos = new Vector3(localx, y + 1, localz); GrowDecoration decoration = new GrowDecoration(paras); World.world.CheckAndRecalculateMesh(x, y, z, World.world.GetBlock(x, y, z)); _plantMap.Add(paras.aoId, decoration); AddToChunkMap(decoration); return; } } }
private void NormalSunLightFill(Chunk chunk) { int sunLightLevel; bool isLight; for (int x = 0; x < Chunk.chunkWidth; x++) { for (int z = 0; z < Chunk.chunkDepth; z++) { sunLightLevel = WorldConfig.Instance.maxLightLevel; isLight = true; for (int y = Chunk.chunkHeight - 1; y >= 0; y--) { Block b = chunk.GetBlock(x, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int lightDamp = calculator.LightDamp(b.ExtendId); if (lightDamp != 0 && isLight) { chunk.SetHeight(x, z, y + 1); isLight = false; } sunLightLevel -= lightDamp; if (sunLightLevel > 0) { chunk.SetSunLight(x, y, z, sunLightLevel); } else { break; } } } } }
private void DispatchEntity(Chunk chunk, int x, int z, EntityParam entityParam) { int height = entityParam.maxEntityHeight < heightCap ? entityParam.maxEntityHeight : heightCap; for (int y = height - 1; y >= entityParam.minEntityHeight; y--) { BlockType curType = chunk.GetBlock(x, y, z).BlockType; if (curType != BlockType.Air && curType != BlockType.StillWater) { List <CheckCondition> conditions = entityParam.checkConditions; bool canDecorate = CheckConditionMeet(chunk, conditions, x, y, z); //bool lightCondiciont = CheckLightCondition(chunk, entityParam.lightCondition, x, y, z); if (canDecorate) { EntityData data = new EntityData(); data.id = entityParam.entityId; data.type = EntityType.MONSTER; data.pos = new Vector3(chunk.worldPos.x + x, chunk.worldPos.y + y + 1, chunk.worldPos.z + z); chunk.AddEntityData(data); return; } } } }
public bool Decorade(Chunk chunk, int x, int y, int z, IMTBRandom random) { int width = random.Range(1, 3); int height = 6; for (int cy = y; cy < y + height; cy++) { for (int cx = -width; cx <= width; cx++) { for (int cz = -width; cz <= width; cz++) { if (chunk.GetBlock(cx, cy, cz).BlockType != BlockType.Air) { return(false); } } } } _spreadQueue.Clear(); setBlock(chunk, x, y, z, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(x, y, z)); int spreadRate = 10; int heightSpreadRate = 40; int nextX; int nextY; int nextZ; while (_spreadQueue.Count > 0) { WorldPos pos = _spreadQueue.Dequeue(); nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextX -= 1; if (nextX >= x - width && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < spreadRate) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextX += 1; if (nextX <= x + width && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < spreadRate) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextY -= 1; if (nextY >= y && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < spreadRate) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextY += 1; if (nextY < y + height && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < heightSpreadRate) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextZ -= 1; if (nextZ >= z - width && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < spreadRate) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } nextX = pos.x; nextY = pos.y; nextZ = pos.z; nextZ += 1; if (nextZ <= z + width && chunk.GetBlock(nextX, nextY, nextZ).BlockType == BlockType.Air) { if (random.Range(0, 100) < 60) { setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_11)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } } return(true); }
private bool CreateTree(int x, int y, int z, Chunk chunk, int treeTrunkWidth, int treeTrunkHeight, int treeHalfLeaveWidth, int treeLeaveHeight, int treeLeaveOffset, IMTBRandom random) { int treeLeaveStartHeight = y + treeTrunkHeight + treeLeaveOffset - 1; int treeTopHeight = treeLeaveStartHeight + treeLeaveHeight; _spreadQueue.Clear(); for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { setBlock(chunk, cx, treeLeaveStartHeight, cz, new Block(BlockType.Block_28)); } } setBlock(chunk, x - 1, treeLeaveStartHeight, z, new Block(BlockType.Block_28)); _spreadQueue.Enqueue(new WorldPos(x - 1, treeLeaveStartHeight, z)); setBlock(chunk, x + 1, treeLeaveStartHeight, z - 1, new Block(BlockType.Block_28)); _spreadQueue.Enqueue(new WorldPos(x + 1, treeLeaveStartHeight, z - 1)); setBlock(chunk, x + 2, treeLeaveStartHeight, z + 1, new Block(BlockType.Block_28)); _spreadQueue.Enqueue(new WorldPos(x + 2, treeLeaveStartHeight, z + 1)); setBlock(chunk, x, treeLeaveStartHeight, z + 2, new Block(BlockType.Block_28)); _spreadQueue.Enqueue(new WorldPos(x, treeLeaveStartHeight, z + 2)); int nextX; int nextY; int nextZ; while (_spreadQueue.Count > 0) { WorldPos pos = _spreadQueue.Dequeue(); int spreadNum = random.Range(0, 4); for (int i = 0; i < spreadNum; i++) { int direct = random.Range(0, 6); switch (direct) { case 0: nextX = pos.x - 1; nextY = pos.y; nextZ = pos.z; break; case 1: nextX = pos.x + 1; nextY = pos.y; nextZ = pos.z; break; case 2: nextX = pos.x; nextY = pos.y; nextZ = pos.z - 1; break; case 3: nextX = pos.x; nextY = pos.y; nextZ = pos.z + 1; break; default: nextX = pos.x; nextY = pos.y + 1; nextZ = pos.z; break; } if (nextX < x - treeHalfLeaveWidth || nextX > x + treeHalfLeaveWidth || nextZ < z - treeHalfLeaveWidth || nextZ > z + treeHalfLeaveWidth || nextY >= treeTopHeight || chunk.GetBlock(nextX, nextY, nextZ).BlockType != BlockType.Air) { continue; } // int num = CheckAroundNum(chunk,nextX,nextY,nextZ); // if(num > 2)continue; setBlock(chunk, nextX, nextY, nextZ, new Block(BlockType.Block_28)); _spreadQueue.Enqueue(new WorldPos(nextX, nextY, nextZ)); } } for (int cy = y; cy < y + treeTrunkHeight - 1; cy++) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_28)); } } } return(true); }
private bool CreateTree(int x, int y, int z, Chunk chunk, int treeTrunkWidth, int treeTrunkHeight, int treeLeaveWidth, int treeLeaveHeight, int treeLeaveOffset, IMTBRandom random) { int treeLeaveStartHeight = y + treeTrunkHeight + treeLeaveOffset - 1; int halfTreeLeaveWidth = treeLeaveWidth / 2; int treeTopHeight = treeLeaveStartHeight + treeLeaveHeight; int leaveWidth = halfTreeLeaveWidth; int baseRate = 15; for (int cy = treeLeaveStartHeight; cy < treeTopHeight; cy++) { int nextXWidth = x + leaveWidth + 1; int nextZWidth = z + leaveWidth + 1; int startXWidth = x - leaveWidth; int startZWidth = z - leaveWidth; for (int cx = startXWidth; cx <= nextXWidth; cx++) { for (int cz = startZWidth; cz <= nextZWidth; cz++) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_41, 3)); } } int rate = (int)(baseRate * (1f + ((float)leaveWidth * 2.5f) / halfTreeLeaveWidth)); if (leaveWidth > 0) { for (int cx = startXWidth; cx <= nextXWidth; cx++) { if (chunk.GetBlock(cx, cy, startZWidth).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, cx, cy, startZWidth, new Block(BlockType.Air)); } else { break; } } for (int cx = startXWidth; cx <= nextXWidth; cx++) { if (chunk.GetBlock(cx, cy, nextZWidth).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, cx, cy, nextZWidth, new Block(BlockType.Air)); } else { break; } } for (int cx = nextXWidth; cx >= startXWidth; cx--) { if (chunk.GetBlock(cx, cy, startZWidth).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, cx, cy, startZWidth, new Block(BlockType.Air)); } else { break; } } for (int cx = nextXWidth; cx >= startXWidth; cx--) { if (chunk.GetBlock(cx, cy, nextZWidth).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, cx, cy, nextZWidth, new Block(BlockType.Air)); } else { break; } } for (int cz = startZWidth; cz <= nextZWidth; cz++) { if (chunk.GetBlock(startXWidth, cy, cz).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, startXWidth, cy, cz, new Block(BlockType.Air)); } else { break; } } for (int cz = startZWidth; cz <= nextZWidth; cz++) { if (chunk.GetBlock(nextXWidth, cy, cz).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, nextXWidth, cy, cz, new Block(BlockType.Air)); } else { break; } } for (int cz = nextZWidth; cz >= startZWidth; cz--) { if (chunk.GetBlock(startXWidth, cy, cz).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, startXWidth, cy, cz, new Block(BlockType.Air)); } else { break; } } for (int cz = nextZWidth; cz >= startZWidth; cz--) { if (chunk.GetBlock(nextXWidth, cy, cz).BlockType == BlockType.Air) { continue; } if (random.Range(0, 100) < rate) { setBlock(chunk, nextXWidth, cy, cz, new Block(BlockType.Air)); } else { break; } } } if (random.Range(0, 100) > 20) { leaveWidth--; } if (leaveWidth < 0) { break; } } for (int cy = y; cy < y + treeTrunkHeight - 1; cy++) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_19, 3)); } } } return(true); }
private void SpreadFromOtherChunk(Chunk chunk) { Chunk otherChunk; //curChunk_X - 1 otherChunk = _world.GetChunk(chunk.worldPos.x - Chunk.chunkWidth, 0, chunk.worldPos.z); if (otherChunk != null && otherChunk.isLightDataPrepared) { for (int z = 0; z < Chunk.chunkDepth; z++) { for (int y = Chunk.chunkHeight - 1; y >= 0; y--) { Block curBlock = chunk.GetBlock(0, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType); int lightDamp = calculator.LightDamp(curBlock.ExtendId); if (lightDamp < 15) { int curLightLevel = chunk.GetSunLight(0, y, z, true); int otherLightLevel = otherChunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true); int nextLightLevel = otherLightLevel - lightDamp - 1; if (nextLightLevel > curLightLevel) { chunk.SetSunLight(0, y, z, nextLightLevel, true); int nextIndex = (0 * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk)); } } } } } //curChunk_x + Chunk.chunkWidth otherChunk = _world.GetChunk(chunk.worldPos.x + Chunk.chunkWidth, 0, chunk.worldPos.z); if (otherChunk != null && otherChunk.isLightDataPrepared) { for (int z = 0; z < Chunk.chunkDepth; z++) { for (int y = Chunk.chunkHeight - 1; y >= 0; y--) { Block curBlock = chunk.GetBlock(Chunk.chunkWidth - 1, y, z, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType); int lightDamp = calculator.LightDamp(curBlock.ExtendId); if (lightDamp < 15) { int curLightLevel = chunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true); int otherLightLevel = otherChunk.GetSunLight(0, y, z, true); int nextLightLevel = otherLightLevel - lightDamp - 1; if (nextLightLevel > curLightLevel) { chunk.SetSunLight(Chunk.chunkWidth - 1, y, z, nextLightLevel, true); int nextIndex = ((Chunk.chunkWidth - 1) * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk)); } } } } } //curChunk_z - Chunk.chunkDepth otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z - Chunk.chunkDepth); if (otherChunk != null && otherChunk.isLightDataPrepared) { for (int x = 0; x < Chunk.chunkDepth; x++) { for (int y = Chunk.chunkHeight - 1; y >= 0; y--) { Block curBlock = chunk.GetBlock(x, y, 0, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType); int lightDamp = calculator.LightDamp(curBlock.ExtendId); if (lightDamp < 15) { int curLightLevel = chunk.GetSunLight(x, y, 0, true); int otherLightLevel = otherChunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true); int nextLightLevel = otherLightLevel - lightDamp - 1; if (nextLightLevel > curLightLevel) { chunk.SetSunLight(x, y, 0, nextLightLevel, true); int nextIndex = (x * Chunk.chunkDepth + 0) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk)); } } } } } //curChunk_z + Chunk.chunkDepth otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z + Chunk.chunkDepth); if (otherChunk != null && otherChunk.isLightDataPrepared) { for (int x = 0; x < Chunk.chunkDepth; x++) { for (int y = Chunk.chunkHeight - 1; y >= 0; y--) { Block curBlock = chunk.GetBlock(x, y, Chunk.chunkDepth - 1, true); BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType); int lightDamp = calculator.LightDamp(curBlock.ExtendId); if (lightDamp < 15) { int curLightLevel = chunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true); int otherLightLevel = otherChunk.GetSunLight(x, y, 0, true); int nextLightLevel = otherLightLevel - lightDamp - 1; if (nextLightLevel > curLightLevel) { chunk.SetSunLight(x, y, Chunk.chunkDepth - 1, nextLightLevel, true); int nextIndex = (x * Chunk.chunkDepth + Chunk.chunkDepth - 1) * Chunk.chunkHeight + y; _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk)); } } } } } }
private bool CreateTree(int x, int y, int z, Chunk chunk, int treeTrunkWidth, int treeTrunkHeight, int treeHalfLeaveWidth, int treeLeaveHeight, int treeLeaveOffset, IMTBRandom random) { int treeLeaveStartHeight = y + treeTrunkHeight + treeLeaveOffset - 1; int treeTopHeight = treeLeaveStartHeight + treeLeaveHeight; int startXWidth = x - treeHalfLeaveWidth; int startZWidth = z - treeHalfLeaveWidth; int nextXWidth = x + treeHalfLeaveWidth + 1; int nextZWidth = z + treeHalfLeaveWidth + 1; for (int cy = treeLeaveStartHeight; cy < treeTopHeight; cy++) { for (int cx = startXWidth; cx <= nextXWidth; cx++) { for (int cz = startZWidth; cz <= nextZWidth; cz++) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_41, 7)); } } } int randomNum = random.Range(1, treeHalfLeaveWidth * treeHalfLeaveWidth * 2); int maxHeight = treeTrunkHeight + treeLeaveOffset; if (maxHeight > 1) { for (int i = 0; i < randomNum; i++) { int randX = random.Range(startXWidth, nextXWidth + 1); int randZ = random.Range(startZWidth, nextZWidth + 1); if ((randX < x - 1 || randX > x + 2) || (randZ < z - 1 || randZ > z + 2)) { if (chunk.GetBlock(randX, treeLeaveStartHeight - 1, randZ).BlockType != BlockType.Air) { continue; } int num = random.Range(0, maxHeight - 1); for (int j = 0; j < num; j++) { setBlock(chunk, randX, treeLeaveStartHeight - 1 - j, randZ, new Block(BlockType.Block_41, 7)); } } } } for (int cy = y; cy < y + treeTrunkHeight - 1; cy++) { for (int cx = x; cx < x + treeTrunkWidth; cx++) { for (int cz = z; cz < z + treeTrunkWidth; cz++) { if (y < treeLeaveStartHeight && random.Range(0, 100) < 5) { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_84)); } else { setBlock(chunk, cx, cy, cz, new Block(BlockType.Block_19, 7)); } } } } return(true); }
private void AddBiomeBlocks(Chunk chunk) { int dryBlocksOnSurface = 256; int chunkX = chunk.worldPos.x; int chunkZ = chunk.worldPos.z; for (int x = 0; x < Chunk.chunkWidth; x++) { for (int z = 0; z < Chunk.chunkDepth; z++) { BiomeConfig biomeConfig = WorldConfig.Instance.GetBiomeConfigById(this.biomeArray[x + Chunk.chunkDepth * z]); // int surfaceBlocksNoise = (int)_surfaceNoiseGen.GetValue(chunkX + x,chunkZ + z); int surfaceBlocksNoise = 1; Block currentSurfaceBlock = biomeConfig.surfaceBlock; Block currentGroundBlock = biomeConfig.groundBlock; int surfaceBlocksCount = int.MinValue; int currentWaterLevel = this.waterLevel[x * Chunk.chunkDepth + z]; for (int y = heightCap - 1; y >= 0; y--) { Block curBlock = chunk.GetBlock(x, y, z, true); if (curBlock.BlockType == BlockType.Air) { surfaceBlocksCount = int.MinValue; } else if (curBlock.EqualOther(biomeConfig.stoneBlock)) { if (surfaceBlocksCount == int.MinValue) { if (surfaceBlocksNoise <= 0 && biomeConfig.removeSurfaceStone) { currentSurfaceBlock = air; currentGroundBlock = biomeConfig.groundBlock; } /*else if((y > currentWaterLevel - 3) && (y < currentWaterLevel + 2)) * { * currentSurfaceBlock = biomeConfig.surfaceBlock; * currentGroundBlock = biomeConfig.groundBlock; * } */ if ((y < currentWaterLevel) && (y > biomeConfig.waterLevelMin) && currentSurfaceBlock.BlockType == BlockType.Air) { currentSurfaceBlock = biomeConfig.waterBlock; } surfaceBlocksCount = surfaceBlocksNoise; if (surfaceBlocksNoise <= 0) { surfaceBlocksCount += 3; } if (y > currentWaterLevel - 2) { chunk.SetBlock(x, y, z, currentSurfaceBlock, true); } else { chunk.SetBlock(x, y, z, currentGroundBlock, true); } } else if (surfaceBlocksCount > 0) { surfaceBlocksCount--; chunk.SetBlock(x, y, z, currentGroundBlock, true); } } } } } }
private List <Chunk> GetSunLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list) { List <Chunk> spreadList = null; List <Chunk> shrinkList = null; BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int lightDamp = calculator.LightDamp(b.ExtendId); int height = chunk.GetHeight(x, z); int lightLevel = chunk.GetSunLight(x, y, z, true); int curLightLevel; if (y >= height - 1) { for (int ty = y; ty >= height; ty--) { Block nextBlock = chunk.GetBlock(x, ty, z); BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType); int nextLightDamp = nextCalculator.LightDamp(nextBlock.ExtendId); if (nextLightDamp > 0) { height = ty + 1; //更新高度 chunk.SetHeight(x, z, height, true); break; } } curLightLevel = WorldConfig.Instance.maxLightLevel - lightDamp; if (curLightLevel < 0) { curLightLevel = 0; } } else { int leftSunLight = chunk.GetSunLight(x - 1, y, z); int rightSunLight = chunk.GetSunLight(x + 1, y, z); int topSunLight = chunk.GetSunLight(x, y + 1, z); int bottomSunLight = chunk.GetSunLight(x, y - 1, z); int frontSunLight = chunk.GetSunLight(x, y, z + 1); int backSunLight = chunk.GetSunLight(x, y, z - 1); int maxSunLight = GetMax(leftSunLight, rightSunLight, topSunLight, bottomSunLight, frontSunLight, backSunLight); curLightLevel = maxSunLight - lightDamp - 1; if (curLightLevel < 0) { curLightLevel = 0; } } if (curLightLevel < lightLevel) { chunk.SetSunLight(x, y, z, curLightLevel, true); int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightShrinkNode node = NodeCache.Instance.GetShrinkNode(index, lightLevel, curLightLevel, chunk); _sunLightShrink.AddShrinkNode(node); shrinkList = _sunLightShrink.ShrinkInChunk(chunk); } else if (curLightLevel > lightLevel) { chunk.SetSunLight(x, y, z, curLightLevel, true); int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightSpreadNode node = NodeCache.Instance.GetSpreadNode(index, curLightLevel, chunk); _sunLightSpread.AddSpreadNode(node); spreadList = _sunLightSpread.SpreadInChunk(chunk); } if (spreadList != null) { for (int i = 0; i < spreadList.Count; i++) { if (!list.Contains(spreadList[i])) { list.Add(spreadList[i]); } } } if (shrinkList != null) { for (int i = 0; i < shrinkList.Count; i++) { if (!list.Contains(shrinkList[i])) { list.Add(shrinkList[i]); } } } return(list); }