public bool CanCactiGrow(IWorld world, IGrainFactory grainFactory, ChunkColumnStorage chunk, Biome biome, Random random, BlockWorldPos pos, int height) { bool result = true; // 检查所有方块可替换 for (int y = pos.Y; y <= pos.Y + 1 + height; ++y) { int xzSize = 1; // 检查这个平面所有方块可替换 for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x) { for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z) { if (y >= 0 && y < 256) { BlockChunkPos chunkPos = new BlockWorldPos(x, y, z).ToBlockChunkPos(); BlockState state = chunk[chunkPos.X, chunkPos.Y, chunkPos.Z]; if (!state.IsAir()) { result = false; } } else { result = false; } } } } return(result); }
protected async virtual Task SetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, int x, int y, int z, BlockState block) { BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z)); if (state.IsAir()) { await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), block); } }
protected async virtual Task RandomSetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState block, Random rand, float freq) { BlockState state = await GetBlock(world, chunkWorldPos, pos); if (rand.NextDouble() < freq && state.IsAir()) { await SetBlock(world, chunkWorldPos, pos, block); } }
protected async virtual Task SetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState block) { BlockState state = await GetBlock(world, chunkWorldPos, pos); if (state.IsAir()) { await SetBlock(world, chunkWorldPos, pos, block); } }
public async Task <bool> CanTreeGrow(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, int height) { bool result = true; // 检查所有方块可替换 for (int y = pos.Y; y <= pos.Y + 1 + height; ++y) { int xzSize = 1; // 底端 if (y == pos.Y) { xzSize = 0; } // 顶端 if (y >= pos.Y + height - 1) { xzSize = 2; } // 检查这个平面所有方块可替换 for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x) { for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z) { if (y >= 0 && y < 256) { var checkPos = new BlockWorldPos(x, y, z); BlockState state = await GetBlock(world, chunkWorldPos, checkPos); if (!state.IsAir() && !state.IsSameId(BlockStates.Leaves()) && !state.IsSameId(BlockStates.Leaves2())) { result = false; } } else { result = false; } } } } return(result); }
public bool CanTreeGrow(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos, int height) { bool result = true; // 检查所有方块可替换 for (int y = pos.Y; y <= pos.Y + 1 + height; ++y) { int xzSize = 1; // 底端 if (y == pos.Y) { xzSize = 0; } // 顶端 if (y >= pos.Y + height - 1) { xzSize = 2; } // 检查这个平面所有方块可替换 for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x) { for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z) { if (y >= 0 && y < 256) { BlockChunkPos chunkPos = pos.ToBlockChunkPos(); BlockState state = chunk[chunkPos.X, chunkPos.Y, chunkPos.Z]; if (!state.IsAir() && state.IsSameId(BlockStates.Leaves()) && state.IsSameId(BlockStates.Leaves2())) { result = false; } } else { result = false; } } } } return(result); }
/** * grow leaves in a circle */ protected async Task GrowLeavesLayer(IWorld world, BlockWorldPos layerCenter, int width) { int i = width * width; for (int j = -width; j <= width; ++j) { for (int k = -width; k <= width; ++k) { if (j * j + k * k <= i) { BlockWorldPos blockpos = BlockWorldPos.Add(layerCenter, j, 0, k); BlockState state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos); if (state.IsAir() || state.IsLeaves()) { await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _leaves); } } } } }
public bool SetBlock(int x, int y, int z, BlockState block) { if (y < 0x00 || y > 0xff) { return(false); } if (x < 0x00 || x > 0x0f || z < 0x00 || z > 0x0f) { return((World is IBlockEditor editor) && editor.SetBlock((X << 4) + x, y, (Z << 4) + z, block)); } if (block.IsAir()) { if (IsTile(x, y, z)) { BlockCount--; } } else if (!IsTile(x, y, z)) { BlockCount++; } _blocks[x | (y << 8) | (z << 4)] = block; return(true); }
public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos) { int height = random.Next(5) + 7; int heightLeaves = height - random.Next(2) - 3; int k = height - heightLeaves; int l = 1 + random.Next(k + 1); if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { bool flag = true; for (int y = pos.Y; y <= pos.Y + 1 + height && flag; ++y) { int xzWidth = 1; if (y - pos.Y < heightLeaves) { xzWidth = 0; } else { xzWidth = l; } for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && flag; ++x) { for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && flag; ++z) { if (y >= 0 && y < 256) { BlockChunkPos chunkpos = new BlockWorldPos(x, y, z).ToBlockChunkPos(); BlockState block = chunk[chunkpos.X, chunkpos.Y, chunkpos.Z]; if (!(block.IsAir() || block.IsLeaves() || block.IsSameId(BlockStates.Vines()))) { flag = false; } } else { flag = false; } } } } if (!flag) { // return false; } else { BlockChunkPos down = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z).ToBlockChunkPos(); BlockState state = chunk[down.X, down.Y, down.Z]; bool isSoil = CanSustainTree(PlantsType.Spruce, state); if (isSoil && pos.Y < 256 - height - 1) { int xzWidth = 0; for (int y = pos.Y + height; y >= pos.Y + heightLeaves; --y) { for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x) { int deltaX = x - pos.X; for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z) { int deltaZ = z - pos.Z; if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0) { BlockChunkPos blockpos = new BlockWorldPos(x, y, z).ToBlockChunkPos(); state = chunk[blockpos.X, blockpos.Y, blockpos.Z]; if (state.IsAir() || state.IsLeaves() || state.IsSameId(BlockStates.Vines())) { chunk[blockpos.X, blockpos.Y, blockpos.Z] = _leaves; } } } } if (xzWidth >= 1 && y == pos.Y + heightLeaves + 1) { --xzWidth; } else if (xzWidth < l) { ++xzWidth; } } for (int y = 0; y < height - 1; ++y) { BlockChunkPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z).ToBlockChunkPos(); state = chunk[upN.X, upN.Y, upN.Z]; if (state.IsAir() || state.IsLeaves()) { chunk[upN.X, upN.Y, upN.Z] = _wood; } } // return true; } else { // return false; } } } else { // return false; } }
protected async Task GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random) { int height = random.Next(3) + _minTreeHeight; // 不超出世界边界 if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { bool canTreeGrow = await CanTreeGrow(world, chunkWorldPos, pos, height); if (canTreeGrow) { BlockWorldPos downPos = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z); BlockState downBlock = await GetBlock(world, chunkWorldPos, downPos); // 是可生成树的土壤 bool isSoil = CanSustainTree(_treeType, downBlock); if (isSoil && pos.Y < 256 - height - 1) { // 生成叶子 for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y) { int restHeight = y - (pos.Y + height); int xzSize = 1 - restHeight / 2; for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x) { int xOffset = x - pos.X; for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z) { int zOffset = z - pos.Z; if (Math.Abs(xOffset) != xzSize || Math.Abs(zOffset) != xzSize || // 不在边缘4个点 (random.Next(2) != 0 && restHeight != 0)) { BlockWorldPos blockpos = new BlockWorldPos(x, y, z); BlockState block = await GetBlock(world, chunkWorldPos, blockpos); if (block.IsAir() || block.IsSameId(BlockStates.Leaves()) || block.IsSameId(BlockStates.Vines())) { await SetBlock(world, chunkWorldPos, blockpos, _leaves); } } } } } // 生成木头 BlockWorldPos upPos = pos; for (int y = 0; y < height; ++y) { BlockState upBlock = await GetBlock(world, chunkWorldPos, upPos); if (upBlock.IsAir() || upBlock.IsSameId(BlockStates.Leaves()) || upBlock.IsSameId(BlockStates.Vines())) { await SetBlock(world, chunkWorldPos, upPos, _wood); } // 生成藤蔓 if (_vines && y > 0) { await RandomSetIfAir(world, chunkWorldPos, upPos.X - 1, upPos.Y, upPos.Z, BlockStates.Vines(VineType.East), random, 0.666f); await RandomSetIfAir(world, chunkWorldPos, upPos.X + 1, upPos.Y, upPos.Z, BlockStates.Vines(VineType.West), random, 0.666f); await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z - 1, BlockStates.Vines(VineType.South), random, 0.666f); await RandomSetIfAir(world, chunkWorldPos, upPos.X, upPos.Y, upPos.Z + 1, BlockStates.Vines(VineType.North), random, 0.666f); } ++upPos.Y; } // 生成藤蔓 if (_vines) { for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y) { int restHeight = y - (pos.Y + height); int xzSize = 2 - restHeight / 2; for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x) { for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z) { if ((await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z))).IsLeaves()) { await RandomSetIfAir(world, chunkWorldPos, x - 1, y, z, BlockStates.Vines(VineType.East), random, 0.25f); await RandomSetIfAir(world, chunkWorldPos, x + 1, y, z, BlockStates.Vines(VineType.West), random, 0.25f); await RandomSetIfAir(world, chunkWorldPos, x, y, z - 1, BlockStates.Vines(VineType.South), random, 0.25f); await RandomSetIfAir(world, chunkWorldPos, x, y, z + 1, BlockStates.Vines(VineType.North), random, 0.25f); } } } } } } } } }
public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Biome biome, Random random, BlockWorldPos pos) { int height = random.Next(3) + _minTreeHeight; // 不超出世界边界 if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { bool canTreeGrow = CanTreeGrow(world, grainFactory, chunk, biome, random, pos, height); if (canTreeGrow) { BlockWorldPos downPos = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z); BlockChunkPos chunkDownPos = downPos.ToBlockChunkPos(); BlockState downBlock = chunk[chunkDownPos.X, chunkDownPos.Y, chunkDownPos.Z]; // 是可生成树的土壤 bool isSoil = CanSustainTree(_treeType, downBlock); if (isSoil && pos.Y < 256 - height - 1) { // 生成叶子 for (int y = pos.Y + height - 3; y <= pos.Y + height; ++y) { int restHeight = y - (pos.Y + height); int xzSize = 1 - restHeight / 2; for (int x = pos.X - xzSize; x <= pos.X + xzSize; ++x) { int xOffset = x - pos.X; for (int z = pos.Z - xzSize; z <= pos.Z + xzSize; ++z) { int zOffset = z - pos.Z; if (Math.Abs(xOffset) != xzSize || Math.Abs(zOffset) != xzSize || // 不在边缘4个点 (random.Next(2) != 0 && restHeight != 0)) { BlockWorldPos blockpos = new BlockWorldPos(x, y, z); BlockChunkPos chunkBlockPos = blockpos.ToBlockChunkPos(); BlockState block = chunk[chunkBlockPos.X, chunkBlockPos.Y, chunkBlockPos.Z]; if (block.IsAir() || block.IsSameId(BlockStates.Leaves()) || block.IsSameId(BlockStates.Vines())) { chunk[chunkBlockPos.X, chunkBlockPos.Y, chunkBlockPos.Z] = _leaves; } } } } } // 生成木头 BlockWorldPos upPos = pos; for (int y = 0; y < height; ++y) { BlockChunkPos chunkUpPos = upPos.ToBlockChunkPos(); BlockState upBlock = chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z]; if (upBlock.IsAir() || upBlock.IsSameId(BlockStates.Leaves()) || upBlock.IsSameId(BlockStates.Vines())) { chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z] = _wood; } // 生成藤蔓 if (_vines && y > 0) { if (random.Next(3) > 0 && chunk[chunkUpPos.X - 1, chunkUpPos.Y, chunkUpPos.Z].IsAir()) { chunk[chunkUpPos.X - 1, chunkUpPos.Y, chunkUpPos.Z] = BlockStates.Vines(VineType.East); } if (random.Next(3) > 0 && chunk[chunkUpPos.X + 1, chunkUpPos.Y, chunkUpPos.Z].IsAir()) { chunk[chunkUpPos.X + 1, chunkUpPos.Y, chunkUpPos.Z] = BlockStates.Vines(VineType.West); } if (random.Next(3) > 0 && chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z - 1].IsAir()) { chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z - 1] = BlockStates.Vines(VineType.South); } if (random.Next(3) > 0 && chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z + 1].IsAir()) { chunk[chunkUpPos.X, chunkUpPos.Y, chunkUpPos.Z + 1] = BlockStates.Vines(VineType.North); } } ++upPos.Y; } // 生成藤蔓 BlockChunkPos chunkPos = pos.ToBlockChunkPos(); if (_vines) { for (int y = chunkPos.Y + height - 3; y <= chunkPos.Y + height; ++y) { int restHeight = y - (chunkPos.Y + height); int xzSize = 2 - restHeight / 2; for (int x = chunkPos.X - xzSize; x <= chunkPos.X + xzSize; ++x) { for (int z = chunkPos.Z - xzSize; z <= chunkPos.Z + xzSize; ++z) { if (chunk[x, y, z].IsLeaves()) { if (random.Next(4) == 0 && chunk[x - 1, y, z].IsAir()) { chunk[x - 1, y, z] = BlockStates.Vines(VineType.East); } if (random.Next(4) == 0 && chunk[x + 1, y, z].IsAir()) { chunk[x + 1, y, z] = BlockStates.Vines(VineType.West); } if (random.Next(4) == 0 && chunk[x, y, z - 1].IsAir()) { chunk[x, y, z - 1] = BlockStates.Vines(VineType.South); } if (random.Next(4) == 0 && chunk[x, y, z + 1].IsAir()) { chunk[x, y, z + 1] = BlockStates.Vines(VineType.North); } } } } } } } } } }
// ��������Ⱥϵ���еķ��� public virtual void GenerateBiomeTerrain(int seaLevel, Random rand, ChunkColumnStorage chunk, int chunk_x, int chunk_z, int x_in_chunk, int z_in_chunk, double noiseVal) { BlockState topBlockstate = _topBlock; BlockState fillerBlockstate = _fillerBlock; int surfaceFlag = -1; int surfaceDepth = (int)(noiseVal / 3.0D + 3.0D + rand.NextDouble() * 0.25D); for (int y = 255; y >= 0; --y) { if (y <= rand.Next(5)) { chunk[x_in_chunk, y, z_in_chunk] = BlockStates.Bedrock(); } else { BlockState iblockstate = chunk[x_in_chunk, y, z_in_chunk]; if (iblockstate.IsAir()) { surfaceFlag = -1; } else if (iblockstate == BlockStates.Stone()) { // ������ʯͷ��������Ⱥϵ�滻 if (surfaceFlag == -1) { if (surfaceDepth <= 0) { topBlockstate = BlockStates.Air(); fillerBlockstate = BlockStates.Stone(); } else if (y >= seaLevel - 4 && y <= seaLevel + 1) { topBlockstate = _topBlock; fillerBlockstate = _fillerBlock; } // TODO �����¶ȱ仯����ˮ��״̬ surfaceFlag = surfaceDepth; if (y >= seaLevel - 1) { chunk[x_in_chunk, y, z_in_chunk] = topBlockstate; } else if (y < seaLevel - 7 - surfaceDepth) { topBlockstate = BlockStates.Air(); fillerBlockstate = BlockStates.Stone(); chunk[x_in_chunk, y, z_in_chunk] = BlockStates.Gravel(); } else { chunk[x_in_chunk, y, z_in_chunk] = fillerBlockstate; } } else if (surfaceFlag > 0) { --surfaceFlag; chunk[x_in_chunk, y, z_in_chunk] = fillerBlockstate; } } } } }
public static bool IsReplaceable(BlockState state) { return(state.IsAir() || state.IsLeaves() || state.IsWood()); }
private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random rand) { int height = rand.Next(3) + rand.Next(3) + 5; bool flag = true; if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { // check if enough space for (int y = pos.Y; y <= pos.Y + 1 + height; ++y) { int xzRange = 1; if (y == pos.Y) { xzRange = 0; } if (y >= pos.Y + 1 + height - 2) { xzRange = 2; } for (int xOffset = pos.X - xzRange; xOffset <= pos.X + xzRange && flag; ++xOffset) { for (int zOffset = pos.Z - xzRange; zOffset <= pos.Z + xzRange && flag; ++zOffset) { if (y >= 0 && y < 256) { var blockState = await world.GetBlockStateUnsafe(this.GrainFactory, new BlockWorldPos(xOffset, y, zOffset)); if (!IsReplaceable(blockState)) { flag = false; } } else { flag = false; } } } } // plant tree if (!flag) { return(false); } else { BlockWorldPos down = pos.Down(); BlockState state = await world.GetBlockStateUnsafe(this.GrainFactory, down); bool isSoil = IsSoil(state); if (isSoil && pos.Y < ChunkConstants.ChunkHeight - height - 1) { // state.getBlock().onPlantGrow(state, world, down, pos); Facing enumfacing = Facing.RadomFacing(rand, Plane.XZ); int bendingPos = height - rand.Next(4) - 1; int l2 = 3 - rand.Next(3); int woodX = pos.X; int woodZ = pos.Z; int branchHeight = 0; for (int yOffset = 0; yOffset < height; ++yOffset) { int curHeight = pos.Y + yOffset; if (yOffset >= bendingPos && l2 > 0) { woodX += enumfacing.ToBlockVector().X; woodZ += enumfacing.ToBlockVector().Z; --l2; } BlockWorldPos blockpos = new BlockWorldPos(woodX, curHeight, woodZ); state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos); if (state.IsAir() || state.IsLeaves()) { await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _wood); branchHeight = curHeight; } } BlockWorldPos blockpos2 = new BlockWorldPos(woodX, branchHeight, woodZ); for (int xOffset = -3; xOffset <= 3; ++xOffset) { for (int zOffset = -3; zOffset <= 3; ++zOffset) { if (Math.Abs(xOffset) != 3 || Math.Abs(zOffset) != 3) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, xOffset, 0, zOffset), _leaves); } } } blockpos2 = blockpos2.Up(); for (int xOffset = -1; xOffset <= 1; ++xOffset) { for (int zOffset = -1; zOffset <= 1; ++zOffset) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, xOffset, 0, zOffset), _leaves); } } await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.East(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.West(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.South(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.North(2), _leaves); woodX = pos.X; woodZ = pos.Z; Facing enumfacing1 = Facing.RadomFacing(rand, Plane.XZ); if (enumfacing1 != enumfacing) { int l3 = bendingPos - rand.Next(2) - 1; int k4 = 1 + rand.Next(3); branchHeight = 0; for (int l4 = l3; l4 < height && k4 > 0; --k4) { if (l4 >= 1) { int j2 = pos.Y + l4; woodX += enumfacing1.ToBlockVector().X; woodZ += enumfacing1.ToBlockVector().Z; BlockWorldPos blockpos1 = new BlockWorldPos(woodX, j2, woodZ); state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos1); if (state.IsAir() || state.IsLeaves()) { await world.SetBlockStateUnsafe(this.GrainFactory, blockpos1, _wood); branchHeight = j2; } } ++l4; } if (branchHeight > 0) { BlockWorldPos blockpos3 = new BlockWorldPos(woodX, branchHeight, woodZ); for (int xOffset = -2; xOffset <= 2; ++xOffset) { for (int zOffset = -2; zOffset <= 2; ++zOffset) { if (Math.Abs(xOffset) != 2 || Math.Abs(zOffset) != 2) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, xOffset, 0, zOffset), _leaves); } } } blockpos3 = blockpos3.Up(); for (int xOffset = -1; xOffset <= 1; ++xOffset) { for (int zOffset = -1; zOffset <= 1; ++zOffset) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, xOffset, 0, zOffset), _leaves); } } } } return(true); } else { return(false); } } } else { return(false); } }
private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random) { int height = random.Next(4) + 6; int j = 1 + random.Next(2); int k = height - j; int l = 2 + random.Next(2); bool canSustainTreeFlag = true; if (pos.Y >= 1 && pos.Y + height + 1 <= 255) { for (int y = pos.Y; y <= pos.Y + 1 + height && canSustainTreeFlag; ++y) { int xzWidth; if (y - pos.Y < j) { xzWidth = 0; } else { xzWidth = l; } for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && canSustainTreeFlag; ++x) { for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && canSustainTreeFlag; ++z) { if (y >= 0 && y < 256) { BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z)); if (!(state.IsAir() || state.IsLeaves())) { canSustainTreeFlag = false; } } else { canSustainTreeFlag = false; } } } } if (!canSustainTreeFlag) { return(false); } else { BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(pos.X, pos.Y - 1, pos.Z)); if (CanSustainTree(PlantsType.Spruce, state) && pos.Y < 256 - height - 1) { int xzWidth = random.Next(2); int j3 = 1; int k3 = 0; for (int l3 = 0; l3 <= k; ++l3) { int y = pos.Y + height - l3; for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x) { int deltaX = x - pos.X; for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z) { int deltaZ = z - pos.Z; if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0) { state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z)); if (state.IsAir() || state.IsLeaves() || state.IsSameId(BlockStates.Vines())) { await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), _leaves); } } } } if (xzWidth >= j3) { xzWidth = k3; k3 = 1; ++j3; if (j3 > l) { j3 = l; } } else { ++xzWidth; } } int heightLeft = random.Next(3); for (int y = 0; y < height - heightLeft; ++y) { BlockWorldPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z); state = await GetBlock(world, chunkWorldPos, upN); if (state.IsAir() || state.IsSameId(BlockStates.Leaves()) || state.IsSameId(BlockStates.Leaves2())) { await SetBlock(world, chunkWorldPos, upN, _wood); } } return(true); } else { return(false); } } } else { return(false); } }
private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random rand) { int height = rand.Next(3) + rand.Next(3) + 5; bool flag = true; if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { for (int y = pos.Y; y <= pos.Y + 1 + height; ++y) { int xzRange = 1; if (y == pos.Y) { xzRange = 0; } if (y >= pos.Y + 1 + height - 2) { xzRange = 2; } for (int xOffset = pos.X - xzRange; xOffset <= pos.X + xzRange && flag; ++xOffset) { for (int zOffset = pos.Z - xzRange; zOffset <= pos.Z + xzRange && flag; ++zOffset) { if (y >= 0 && y < 256) { var blockState = await world.GetBlockStateUnsafe(this.GrainFactory, new BlockWorldPos(xOffset, y, zOffset)); if (!IsReplaceable(blockState)) { flag = false; } } else { flag = false; } } } } if (!flag) { return(false); } else { BlockWorldPos down = pos.Down(); BlockState state = await world.GetBlockStateUnsafe(this.GrainFactory, down); bool isSoil = IsSoil(state); if (isSoil && pos.Y < ChunkConstants.ChunkHeight - height - 1) { // state.getBlock().onPlantGrow(state, world, down, pos); Facing enumfacing = Facing.RadomFacing(rand, Plane.XZ); int k2 = height - rand.Next(4) - 1; int l2 = 3 - rand.Next(3); int i3 = pos.X; int j1 = pos.Z; int k1 = 0; for (int l1 = 0; l1 < height; ++l1) { int i2 = pos.Y + l1; if (l1 >= k2 && l2 > 0) { i3 += enumfacing.ToBlockVector().X; j1 += enumfacing.ToBlockVector().Z; --l2; } BlockWorldPos blockpos = new BlockWorldPos(i3, i2, j1); state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos); if (state.IsAir() || state.IsLeaves()) { await world.SetBlockStateUnsafe(this.GrainFactory, blockpos, _wood); k1 = i2; } } BlockWorldPos blockpos2 = new BlockWorldPos(i3, k1, j1); for (int j3 = -3; j3 <= 3; ++j3) { for (int i4 = -3; i4 <= 3; ++i4) { if (Math.Abs(j3) != 3 || Math.Abs(i4) != 3) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, j3, 0, i4), _leaves); } } } blockpos2 = blockpos2.Up(); for (int k3 = -1; k3 <= 1; ++k3) { for (int j4 = -1; j4 <= 1; ++j4) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos2, k3, 0, j4), _leaves); } } await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.East(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.West(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.South(2), _leaves); await world.SetBlockStateUnsafe(this.GrainFactory, blockpos2.North(2), _leaves); i3 = pos.X; j1 = pos.Z; Facing enumfacing1 = Facing.RadomFacing(rand, Plane.XZ); if (enumfacing1 != enumfacing) { int l3 = k2 - rand.Next(2) - 1; int k4 = 1 + rand.Next(3); k1 = 0; for (int l4 = l3; l4 < height && k4 > 0; --k4) { if (l4 >= 1) { int j2 = pos.Y + l4; i3 += enumfacing1.ToBlockVector().X; j1 += enumfacing1.ToBlockVector().Z; BlockWorldPos blockpos1 = new BlockWorldPos(i3, j2, j1); state = await world.GetBlockStateUnsafe(this.GrainFactory, blockpos1); if (state.IsAir() || state.IsLeaves()) { await world.SetBlockStateUnsafe(this.GrainFactory, blockpos1, _wood); k1 = j2; } } ++l4; } if (k1 > 0) { BlockWorldPos blockpos3 = new BlockWorldPos(i3, k1, j1); for (int i5 = -2; i5 <= 2; ++i5) { for (int k5 = -2; k5 <= 2; ++k5) { if (Math.Abs(i5) != 2 || Math.Abs(k5) != 2) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, i5, 0, k5), _leaves); } } } blockpos3 = blockpos3.Up(); for (int j5 = -1; j5 <= 1; ++j5) { for (int l5 = -1; l5 <= 1; ++l5) { await world.SetBlockStateUnsafe(this.GrainFactory, BlockWorldPos.Add(blockpos3, j5, 0, l5), _leaves); } } } } return(true); } else { return(false); } } } else { return(false); } }
public override void Generate(IWorld world, IGrainFactory grainFactory, ChunkColumnStorage chunk, Biome biome, Random random, BlockWorldPos pos) { int height = random.Next(4) + 6; int j = 1 + random.Next(2); int k = height - j; int l = 2 + random.Next(2); bool flag = true; if (pos.Y >= 1 && pos.Y + height + 1 <= 255) { for (int y = pos.Y; y <= pos.Y + 1 + height && flag; ++y) { int xzWidth; if (y - pos.Y < j) { xzWidth = 0; } else { xzWidth = l; } for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && flag; ++x) { for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && flag; ++z) { if (y >= 0 && y < 256) { BlockChunkPos chunkPos = new BlockWorldPos(x, y, z).ToBlockChunkPos(); BlockState state = chunk[chunkPos.X, chunkPos.Y, chunkPos.Z]; if (!(state.IsAir() || state.IsLeaves())) { flag = false; } } else { flag = false; } } } } if (!flag) { // return false; } else { BlockChunkPos down = new BlockWorldPos(pos.X, pos.Y - 1, pos.Z).ToBlockChunkPos(); BlockState state = chunk[down.X, down.Y, down.Z]; if (CanSustainTree(PlantsType.Spruce, state) && pos.Y < 256 - height - 1) { int xzWidth = random.Next(2); int j3 = 1; int k3 = 0; for (int l3 = 0; l3 <= k; ++l3) { int y = pos.Y + height - l3; for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x) { int deltaX = x - pos.X; for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z) { int deltaZ = z - pos.Z; if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0) { BlockChunkPos blockpos = new BlockWorldPos(x, y, z).ToBlockChunkPos(); state = chunk[blockpos.X, blockpos.Y, blockpos.Z]; if (state.IsAir() || state.IsLeaves() || state.IsSameId(BlockStates.Vines())) { chunk[blockpos.X, blockpos.Y, blockpos.Z] = _leaves; } } } } if (xzWidth >= j3) { xzWidth = k3; k3 = 1; ++j3; if (j3 > l) { j3 = l; } } else { ++xzWidth; } } int heightLeft = random.Next(3); for (int y = 0; y < height - heightLeft; ++y) { BlockChunkPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z).ToBlockChunkPos(); state = chunk[upN.X, upN.Y, upN.Z]; if (state.IsAir() || state.IsSameId(BlockStates.Leaves()) || state.IsSameId(BlockStates.Leaves2())) { chunk[upN.X, upN.Y, upN.Z] = _wood; } } // return true; } else { // return false; } } } else { // return false; } }
private async Task <bool> GenerateImpl(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, Random random) { int height = random.Next(5) + 7; int heightLeaves = height - random.Next(2) - 3; int k = height - heightLeaves; int l = 1 + random.Next(k + 1); if (pos.Y >= 1 && pos.Y + height + 1 <= 256) { bool canSustainTreeFlag = true; for (int y = pos.Y; y <= pos.Y + 1 + height && canSustainTreeFlag; ++y) { int xzWidth = 1; if (y - pos.Y < heightLeaves) { xzWidth = 0; } else { xzWidth = l; } for (int x = pos.X - xzWidth; x <= pos.X + xzWidth && canSustainTreeFlag; ++x) { for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth && canSustainTreeFlag; ++z) { if (y >= 0 && y < 256) { BlockState block = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z)); if (!(block.IsAir() || block.IsLeaves() || block.IsId(BlockId.Vine))) { canSustainTreeFlag = false; } } else { canSustainTreeFlag = false; } } } } if (!canSustainTreeFlag) { return(false); } else { BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(pos.X, pos.Y - 1, pos.Z)); bool isSoil = CanSustainTree(PlantsType.Spruce, state); if (isSoil && pos.Y < 256 - height - 1) { int xzWidth = 0; for (int y = pos.Y + height; y >= pos.Y + heightLeaves; --y) { for (int x = pos.X - xzWidth; x <= pos.X + xzWidth; ++x) { int deltaX = x - pos.X; for (int z = pos.Z - xzWidth; z <= pos.Z + xzWidth; ++z) { int deltaZ = z - pos.Z; if (Math.Abs(deltaX) != xzWidth || Math.Abs(deltaZ) != xzWidth || xzWidth <= 0) { state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z)); if (state.IsAir() || state.IsLeaves() || state.IsId(BlockId.Vine)) { await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), _leaves); } } } } if (xzWidth >= 1 && y == pos.Y + heightLeaves + 1) { --xzWidth; } else if (xzWidth < l) { ++xzWidth; } } for (int y = 0; y < height - 1; ++y) { BlockWorldPos upN = new BlockWorldPos(pos.X, pos.Y + y, pos.Z); state = await GetBlock(world, chunkWorldPos, upN); if (state.IsAir() || state.IsLeaves()) { await SetBlock(world, chunkWorldPos, upN, _wood); } } return(true); } else { return(false); } } } else { return(false); } }