/// <summary> /// For placement of ruins during worldgen, replaces the topsoil with the area specific soil (e.g. sand) /// </summary> /// <param name="blockAccessor"></param> /// <param name="blocks"></param> /// <param name="startPos"></param> /// <param name="climateUpLeft"></param> /// <param name="climateUpRight"></param> /// <param name="climateBotLeft"></param> /// <param name="climateBotRight"></param> /// <param name="replaceblockids"></param> /// <returns></returns> public int PlaceRespectingBlockLayers(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, ushort[] replaceblockids) { BlockPos curPos = new BlockPos(); int placed = 0; int chunksize = blockAccessor.ChunkSize; for (int x = 0; x < SizeX; x++) { for (int z = 0; z < SizeZ; z++) { curPos.Set(x + startPos.X, startPos.Y, z + startPos.Z); ushort rockblockid = blockAccessor.GetMapChunkAtBlockPos(curPos).TopRockIdMap[(curPos.Z % chunksize) * chunksize + curPos.X % chunksize]; int depth = 0; for (int y = SizeY - 1; y >= 0; y--) { curPos.Set(x + startPos.X, y + startPos.Y, z + startPos.Z); Block newBlock = blocksByPos[x, y, z]; if (newBlock == null) { continue; } if (newBlock.Replaceable < 1000) { if (replaceblockids.Length > depth && newBlock.BlockId == replaceblockids[depth]) { int climate = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); newBlock = GetBlockLayerBlock((climate >> 8) & 0xff, (climate >> 16) & 0xff, startPos.Y, rockblockid, depth, newBlock, worldForCollectibleResolve.Blocks); } depth++; } Block oldBlock = blockAccessor.GetBlock(curPos); placed += handler(blockAccessor, curPos, oldBlock, newBlock); byte[] lightHsv = newBlock.GetLightHsv(blockAccessor, curPos); if (lightHsv[2] > 0 && blockAccessor is IWorldGenBlockAccessor) { int chunkSize = blockAccessor.ChunkSize; ((IWorldGenBlockAccessor)blockAccessor).ScheduleBlockLightUpdate(curPos.Copy(), oldBlock.BlockId, newBlock.BlockId); } } } } foreach (var val in BlockEntities) { uint index = val.Key; int dx = (int)(index & 0x1ff); int dy = (int)((index >> 20) & 0x1ff); int dz = (int)((index >> 10) & 0x1ff); curPos.Set(startPos.X + dx, startPos.Y + dy, startPos.Z + dz); BlockEntity be = blockAccessor.GetBlockEntity(curPos); if (be != null) { be.FromTreeAtributes(DecodeBlockEntityData(val.Value), worldForCollectibleResolve); be.OnLoadCollectibleMappings(worldForCollectibleResolve, BlockCodes, ItemCodes); be.pos = curPos.Copy(); } } return(placed); }