public int[] GenerateChunkImage(Vec2i chunkPos, IMapChunk mc, bool withSnow = true) { ICoreClientAPI capi = api as ICoreClientAPI; //capi.Logger.Notification("GenImg @{0}/{1}", chunkPos.X, chunkPos.Y); BlockPos tmpPos = new BlockPos(); Vec2i localpos = new Vec2i(); // Prefetch chunks for (int cy = 0; cy < chunksTmp.Length; cy++) { chunksTmp[cy] = capi.World.BlockAccessor.GetChunk(chunkPos.X, cy, chunkPos.Y); if (chunksTmp[cy] == null) { return(null); } } // Prefetch map chunks IMapChunk[] mapChunks = new IMapChunk[] { capi.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y - 1), capi.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y), capi.World.BlockAccessor.GetMapChunk(chunkPos.X, chunkPos.Y - 1) }; int[] texDataTmp = new int[chunksize * chunksize]; for (int i = 0; i < texDataTmp.Length; i++) { int y = mc.RainHeightMap[i]; int cy = y / chunksize; if (cy >= chunksTmp.Length) { continue; } MapUtil.PosInt2d(i, chunksize, localpos); int lx = localpos.X; int lz = localpos.Y; float b = 1; int leftTop, rightTop, leftBot; IMapChunk leftTopMapChunk = mc; IMapChunk rightTopMapChunk = mc; IMapChunk leftBotMapChunk = mc; int topX = lx - 1; int botX = lx; int leftZ = lz - 1; int rightZ = lz; if (topX < 0 && leftZ < 0) { leftTopMapChunk = mapChunks[0]; rightTopMapChunk = mapChunks[1]; leftBotMapChunk = mapChunks[2]; } else { if (topX < 0) { leftTopMapChunk = mapChunks[1]; rightTopMapChunk = mapChunks[1]; } if (leftZ < 0) { leftTopMapChunk = mapChunks[2]; leftBotMapChunk = mapChunks[2]; } } topX = GameMath.Mod(topX, chunksize); leftZ = GameMath.Mod(leftZ, chunksize); leftTop = leftTopMapChunk == null ? 0 : Math.Sign(y - leftTopMapChunk.RainHeightMap[leftZ * chunksize + topX]); rightTop = rightTopMapChunk == null ? 0 : Math.Sign(y - rightTopMapChunk.RainHeightMap[rightZ * chunksize + topX]); leftBot = leftBotMapChunk == null ? 0 : Math.Sign(y - leftBotMapChunk.RainHeightMap[leftZ * chunksize + botX]); float slopeness = (leftTop + rightTop + leftBot); if (slopeness > 0) { b = 1.18f; } if (slopeness < 0) { b = 0.82f; } chunksTmp[cy].Unpack(); int blockId = chunksTmp[cy].Blocks[MapUtil.Index3d(localpos.X, y % chunksize, localpos.Y, chunksize, chunksize)]; Block block = api.World.Blocks[blockId]; /*if (i == 0) * { * capi.Logger.Notification("GenImg @{0}/{1}, first block is {2}", chunkPos.X, chunkPos.Y, block.Code); * }*/ if (!withSnow && block.BlockMaterial == EnumBlockMaterial.Snow) { y--; cy = y / chunksize; chunksTmp[cy].Unpack(); blockId = chunksTmp[cy].Blocks[MapUtil.Index3d(localpos.X, y % chunksize, localpos.Y, chunksize, chunksize)]; block = api.World.Blocks[blockId]; } tmpPos.Set(chunksize * chunkPos.X + localpos.X, y, chunksize * chunkPos.Y + localpos.Y); int avgCol = block.GetColor(capi, tmpPos); int rndCol = block.GetRandomColor(capi, tmpPos, BlockFacing.UP); // Add a bit of randomness to each pixel int col = ColorUtil.ColorOverlay(avgCol, rndCol, 0.2f); texDataTmp[i] = ColorUtil.ColorMultiply3Clamped(col, b) | 255 << 24; } for (int cy = 0; cy < chunksTmp.Length; cy++) { chunksTmp[cy] = null; } return(texDataTmp); }
public int[] GenerateChunkImage(Vec2i chunkPos, IMapChunk mc, bool withSnow = true) { ICoreClientAPI capi = api as ICoreClientAPI; BlockPos tmpPos = new BlockPos(); Vec2i localpos = new Vec2i(); // Prefetch chunks for (int cy = 0; cy < chunksTmp.Length; cy++) { chunksTmp[cy] = capi.World.BlockAccessor.GetChunk(chunkPos.X, cy, chunkPos.Y); if (chunksTmp[cy] == null || !(chunksTmp[cy] as IClientChunk).LoadedFromServer) { return(null); } } // Prefetch map chunks IMapChunk[] mapChunks = new IMapChunk[] { capi.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y - 1), capi.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y), capi.World.BlockAccessor.GetMapChunk(chunkPos.X, chunkPos.Y - 1) }; int[] texDataTmp = new int[chunksize * chunksize]; for (int i = 0; i < texDataTmp.Length; i++) { int y = mc.RainHeightMap[i]; int cy = y / chunksize; if (cy >= chunksTmp.Length) { continue; } MapUtil.PosInt2d(i, chunksize, localpos); int lx = localpos.X; int lz = localpos.Y; float b = 1; int leftTop, rightTop, leftBot; IMapChunk leftTopMapChunk = mc; IMapChunk rightTopMapChunk = mc; IMapChunk leftBotMapChunk = mc; int topX = lx - 1; int botX = lx; int leftZ = lz - 1; int rightZ = lz; if (topX < 0 && leftZ < 0) { leftTopMapChunk = mapChunks[0]; rightTopMapChunk = mapChunks[1]; leftBotMapChunk = mapChunks[2]; } else { if (topX < 0) { leftTopMapChunk = mapChunks[1]; rightTopMapChunk = mapChunks[1]; } if (leftZ < 0) { leftTopMapChunk = mapChunks[2]; leftBotMapChunk = mapChunks[2]; } } topX = GameMath.Mod(topX, chunksize); leftZ = GameMath.Mod(leftZ, chunksize); leftTop = leftTopMapChunk == null ? 0 : Math.Sign(y - leftTopMapChunk.RainHeightMap[leftZ * chunksize + topX]); rightTop = rightTopMapChunk == null ? 0 : Math.Sign(y - rightTopMapChunk.RainHeightMap[rightZ * chunksize + topX]); leftBot = leftBotMapChunk == null ? 0 : Math.Sign(y - leftBotMapChunk.RainHeightMap[leftZ * chunksize + botX]); float slopeness = (leftTop + rightTop + leftBot); if (slopeness > 0) { b = 1.18f; } if (slopeness < 0) { b = 0.82f; } int blockId = chunksTmp[cy].Unpack_AndReadBlock(MapUtil.Index3d(localpos.X, y % chunksize, localpos.Y, chunksize, chunksize)); Block block = api.World.Blocks[blockId]; if (!withSnow && block.BlockMaterial == EnumBlockMaterial.Snow) { y--; cy = y / chunksize; blockId = chunksTmp[cy].Unpack_AndReadBlock(MapUtil.Index3d(localpos.X, y % chunksize, localpos.Y, chunksize, chunksize)); block = api.World.Blocks[blockId]; } tmpPos.Set(chunksize * chunkPos.X + localpos.X, y, chunksize * chunkPos.Y + localpos.Y); int avgCol = block.GetColor(capi, tmpPos); int rndCol = block.GetRandomColor(capi, tmpPos, BlockFacing.UP, GameMath.MurmurHash3Mod(tmpPos.X, tmpPos.Y, tmpPos.Z, 30)); // Why the eff is r and b flipped rndCol = ((rndCol & 0xff) << 16) | (((rndCol >> 8) & 0xff) << 8) | (((rndCol >> 16) & 0xff) << 0); // Add a bit of randomness to each pixel int col = ColorUtil.ColorOverlay(avgCol, rndCol, 0.6f); texDataTmp[i] = ColorUtil.ColorMultiply3Clamped(col, b) | 255 << 24; } for (int cy = 0; cy < chunksTmp.Length; cy++) { chunksTmp[cy] = null; } return(texDataTmp); }