// XXX: Consider revising foreign lookup support /// <summary> /// Gets a <see cref="ChunkRef"/> for a chunk at the given local coordinates relative to this region. /// </summary> /// <param name="lcx">The local X-coordinate of a chunk relative to this region.</param> /// <param name="lcz">The local Z-coordinate of a chunk relative to this region.</param> /// <returns>A <see cref="ChunkRef"/> at the given local coordinates, or null if no chunk exists.</returns> /// <remarks>The local coordinates do not strictly need to be within the bounds of the region. If coordinates are detected /// as being out of bounds, the lookup will be delegated to the correct region and the lookup will be performed there /// instead. This allows any <see cref="Region"/> to perform a similar task to <see cref="BetaChunkManager"/>, but with a /// region-local frame of reference instead of a global frame of reference.</remarks> public ChunkRef GetChunkRef(int lcx, int lcz) { if (!LocalBoundsCheck(lcx, lcz)) { Region alt = GetForeignRegion(lcx, lcz); return((alt == null) ? null : alt.GetChunkRef(ForeignX(lcx), ForeignZ(lcz))); } int cx = lcx + _rx * XDIM; int cz = lcz + _rz * ZDIM; ChunkKey k = new ChunkKey(cx, cz); ChunkRef c = _cache.Fetch(k); if (c != null) { return(c); } c = ChunkRef.Create(this, lcx, lcz); if (c != null) { _cache.Insert(c); } return(c); }
/// <summary> /// Saves all chunks within this region that have been marked as dirty. /// </summary> /// <returns>The number of chunks that were saved.</returns> public int Save() { _cache.SyncDirty(); int saved = 0; IEnumerator <ChunkRef> en = _cache.GetDirtyEnumerator(); while (en.MoveNext()) { ChunkRef chunk = en.Current; if (!ChunkExists(chunk.LocalX, chunk.LocalZ)) { throw new MissingChunkException(); } if (chunk.Save(GetChunkOutStream(chunk.LocalX, chunk.LocalZ))) { saved++; } } _cache.ClearDirty(); return(saved); }
private static void FlatChunk(ChunkRef chunk, int height) { // Create bedrock for (int y = 0; y < 2; y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { chunk.Blocks.SetID(x, y, z, (int)BlockType.BEDROCK); } } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { chunk.Biomes.SetBiome(x,z, BiomeType.Plains); } } // Create stone for (int y = 2; y < height - 5; y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { chunk.Blocks.SetID(x, y, z, (int)BlockType.STONE); } } } // Create dirt for (int y = height - 5; y < height - 1; y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { chunk.Blocks.SetID(x, y, z, (int)BlockType.DIRT); } } } // Create grass for (int y = height - 1; y < height; y++) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { chunk.Blocks.SetID(x, y, z, (int)BlockType.GRASS); } } } }
/// <summary> /// Updates a block with values from a <see cref="AlphaBlock"/> object. /// </summary> /// <param name="x">Global X-coordinate of a block.</param> /// <param name="y">Global Y-coordinate of a block.</param> /// <param name="z">Global Z-coordinate of a block.</param> /// <param name="block">A <see cref="AlphaBlock"/> object to copy block data from.</param> public void SetBlock(int x, int y, int z, AlphaBlock block) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetBlock(x & chunkXMask, y & chunkYMask, z & chunkZMask, block); }
/// <summary> /// Returns a new <see cref="AlphaBlock"/> object from global coordinates. /// </summary> /// <param name="x">Global X-coordinate of block.</param> /// <param name="y">Global Y-coordinate of block.</param> /// <param name="z">Global Z-coordiante of block.</param> /// <returns>A new <see cref="AlphaBlock"/> object representing context-independent data of a single block.</returns> /// <remarks>Context-independent data excludes data such as lighting. <see cref="AlphaBlock"/> object actually contain a copy /// of the data they represent, so changes to the <see cref="AlphaBlock"/> will not affect this container, and vice-versa.</remarks> public AlphaBlock GetBlock(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return(null); } return(cache.Blocks.GetBlock(x & chunkXMask, y & chunkYMask, z & chunkZMask)); }
/// <inheritdoc/> public void SetBlock(int x, int y, int z, IActiveBlock block) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetBlock(x, y, z, block); }
/// <inheritdoc/> public int GetSkyLight(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null) { return(0); } return(cache.Blocks.GetSkyLight(x & chunkXMask, y & chunkYMask, z & chunkZMask)); }
/// <inheritdoc/> public void CreateTileTick(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.CreateTileTick(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
/// <inheritdoc/> public int GetTileTickValue(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return(0); } return(cache.Blocks.GetTileTickValue(x & chunkXMask, y & chunkYMask, z & chunkZMask)); }
/// <inheritdoc/> public void SetTileTickValue(int x, int y, int z, int tickValue) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetTileTickValue(x & chunkXMask, y & chunkYMask, z & chunkZMask, tickValue); }
/// <inheritdoc/> public int GetHeight(int x, int z) { cache = GetChunk(x, 0, z); if (cache == null || !Check(x, 0, z)) { return(0); } return(cache.Blocks.GetHeight(x & chunkXMask, z & chunkZMask)); }
/// <inheritdoc/> public void SetSkyLight(int x, int y, int z, int light) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetSkyLight(x & chunkXMask, y & chunkYMask, z & chunkZMask, light); }
/// <inheritdoc/> public void UpdateSkyLight(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.UpdateBlockLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
/// <inheritdoc/> public void SetHeight(int x, int z, int height) { cache = GetChunk(x, 0, z); if (cache == null || !Check(x, 0, z)) { return; } cache.Blocks.SetHeight(x & chunkXMask, z & chunkZMask, height); }
/// <inheritdoc/> public TileEntity GetTileEntity(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return(null); } return(cache.Blocks.GetTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask)); }
/// <inheritdoc/> public void SetData(int x, int y, int z, int data) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetData(x & chunkXMask, y & chunkYMask, z & chunkZMask, data); }
/// <inheritdoc/> public void SetTileEntity(int x, int y, int z, TileEntity te) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.SetTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask, te); }
/// <inheritdoc/> public void ClearTileEntity(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } cache.Blocks.ClearTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
/// <summary> /// Callback function to return the block collection of a ChunkRef at a relative offset to this one. /// </summary> /// <param name="relx">Relative offset from the X-coordinate.</param> /// <param name="rely">Relative offset from the Y-coordinate.</param> /// <param name="relz">Relative offset from the Z-coordinate.</param> /// <returns>Another ChunkRef's underlying block collection, or null if the ChunkRef cannot be found.</returns> private AlphaBlockCollection ResolveNeighborHandler(int relx, int rely, int relz) { ChunkRef cr = _container.GetChunkRef(_cx + relx, _cz + relz); if (cr != null) { return(cr.Blocks); } return(null); }
public void SetLocation(int x, int z) { int relX = LocalX + (x - X); int relZ = LocalZ + (z - Z); ChunkRef c = _container.SetChunk(relX, relZ, GetChunk()); _container = c._container; _cx = c._cx; _cz = c._cz; }
/// <inheritdoc/> public ChunkRef SetChunk(int cx, int cz, Chunk chunk) { DeleteChunk(cx, cz); chunk.SetLocation(cx, cz); chunk.Save(GetChunkOutStream(cx, cz)); ChunkRef cr = ChunkRef.Create(this, cx, cz); ChunkKey k = new ChunkKey(cx, cz); _cache[k] = cr; return(cr); }
/// <inheritdoc/> public ChunkRef CreateChunk(int cx, int cz) { DeleteChunk(cx, cz); Chunk c = Chunk.Create(cx, cz); c.Save(GetChunkOutStream(cx, cz)); ChunkRef cr = ChunkRef.Create(this, cx, cz); ChunkKey k = new ChunkKey(cx, cz); _cache[k] = cr; return(cr); }
/// <summary> /// Create a reference to a chunk stored in a chunk container. /// </summary> /// <param name="container">Chunk container</param> /// <param name="cx">Local X-coordinate of chunk within container.</param> /// <param name="cz">Local Z-coordinate of chunk within container.</param> /// <returns>ChunkRef representing a reference to a physical chunk at the specified location within the container.</returns> public static ChunkRef Create(IChunkContainer container, int cx, int cz) { if (!container.ChunkExists(cx, cz)) { return(null); } ChunkRef c = new ChunkRef(); c._container = container; c._cx = cx; c._cz = cz; return(c); }
/// <inheritdoc/> public void SetID(int x, int y, int z, int id) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } bool autolight = cache.Blocks.AutoLight; bool autofluid = cache.Blocks.AutoFluid; cache.Blocks.AutoLight = _autoLight; cache.Blocks.AutoFluid = _autoFluid; cache.Blocks.SetID(x & chunkXMask, y & chunkYMask, z & chunkZMask, id); cache.Blocks.AutoFluid = autofluid; cache.Blocks.AutoLight = autolight; }
/// <summary> /// Saves an existing <see cref="Chunk"/> to the region at the given local coordinates. /// </summary> /// <param name="lcx">The local X-coordinate of a chunk relative to this region.</param> /// <param name="lcz">The local Z-coordinate of a chunk relative to this region.</param> /// <param name="chunk">A <see cref="Chunk"/> to save to the given location.</param> /// <returns>A <see cref="ChunkRef"/> represneting the <see cref="Chunk"/> at its new location.</returns> /// <remarks>If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region /// transparently. The <see cref="Chunk"/>'s internal global coordinates will be updated to reflect the new location.</remarks> public ChunkRef SetChunk (int lcx, int lcz, Chunk chunk) { if (!LocalBoundsCheck(lcx, lcz)) { Region alt = GetForeignRegion(lcx, lcz); return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz)); } DeleteChunk(lcx, lcz); int cx = lcx + _rx * XDIM; int cz = lcz + _rz * ZDIM; chunk.SetLocation(cx, cz); chunk.Save(GetChunkOutStream(lcx, lcz)); ChunkRef cr = ChunkRef.Create(this, lcx, lcz); _cache.Insert(cr); return cr; }
/// <inheritdoc/> public ChunkRef GetChunkRef(int cx, int cz) { ChunkKey k = new ChunkKey(cx, cz); ChunkRef c = null; //WeakReference chunkref = null; if (_cache.TryGetValue(k, out c)) { return(c); } c = ChunkRef.Create(this, cx, cz); if (c != null) { _cache[k] = c; } return(c); }
private static void CreateFlatChunk(ChunkRef chunk, int[, ,] intUndergroundTerrain) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 2; y++) { chunk.Blocks.SetID(x, y, z, BlockType.BEDROCK); } for (int y = 2; y < 63; y++) { chunk.Blocks.SetID(x, y, z, intUndergroundTerrain[(chunk.X * 16) + x, y, (chunk.Z * 16) + z]); } for (int y = 63; y < 64; y++) { chunk.Blocks.SetID(x, y, z, BlockType.GRASS); } } } }
public void ApplyChunk(NbtWorld world, ChunkRef chunk) { IBlockFilter opt_b = opt.GetBlockFilter(); int xBase = chunk.X * chunk.Blocks.XDim; int zBase = chunk.Z * chunk.Blocks.ZDim; // Determine X range int xmin = 0; int xmax = 15; if (opt_b.XAboveEq != null) { xmin = (int)opt_b.XAboveEq - xBase; } if (opt_b.XBelowEq != null) { xmax = (int)opt_b.XBelowEq - xBase; } xmin = (xmin < 0) ? 0 : xmin; xmax = (xmax > 15) ? 15 : xmax; if (xmin > 15 || xmax < 0 || xmin > xmax) { return; } // Determine Y range int ymin = 0; int ymax = 127; if (opt_b.YAboveEq != null) { ymin = (int)opt_b.YAboveEq; } if (opt_b.YBelowEq != null) { ymax = (int)opt_b.YBelowEq; } if (ymin > ymax) { return; } // Determine X range int zmin = 0; int zmax = 15; if (opt_b.ZAboveEq != null) { zmin = (int)opt_b.ZAboveEq - zBase; } if (opt_b.ZBelowEq != null) { zmax = (int)opt_b.ZBelowEq - zBase; } zmin = (zmin < 0) ? 0 : zmin; zmax = (zmax > 15) ? 15 : zmax; if (zmin > 15 || zmax < 0 || zmin > zmax) { return; } int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; // Bin blocks for (int y = ymin; y <= ymax; y++) { for (int x = xmin; x <= xmax; x++) { for (int z = zmin; z <= zmax; z++) { int id = chunk.Blocks.GetID(x, y, z); _sort[id].Add(new BlockKey(x, y, z)); } } } // Process bins for (int i = 0; i < 256; i++) { if (_sort[i].Count == 0) { continue; } if (opt_b.IncludedBlockCount > 0 & !opt_b.IncludedBlocksContains(i)) { continue; } if (opt_b.ExcludedBlockCount > 0 & opt_b.ExcludedBlocksContains(i)) { continue; } foreach (BlockKey key in _sort[i]) { chunk.Blocks.SetID(key.x, key.y, key.z, (int)opt.OPT_AFTER); if (opt.OPT_VV) { int gx = chunk.X * xdim + key.x; int gz = chunk.Z * zdim + key.z; Console.WriteLine("Replaced block {0} at {1},{2},{3}", i, gx, key.y, gz); } if (opt.OPT_DATA != null) { chunk.Blocks.SetData(key.x, key.y, key.z, (int)opt.OPT_DATA); } } } // Reset bins for (int i = 0; i < 256; i++) { _sort[i].Clear(); } // Process Chunk /*for (int y = ymin; y <= ymax; y++) { for (int x = xmin; x <= xmax; x++) { for (int z = zmin; z <= zmax; z++) { // Probability test if (opt_b.ProbMatch != null) { double c = rand.NextDouble(); if (c > opt_b.ProbMatch) { continue; } } int lx = x % xdim; int ly = y % ydim; int lz = z % zdim; // Get the old block int oldBlock = chunk.Blocks.GetID(lx , ly, lz); // Skip block if it doesn't match the inclusion list if (opt_b.IncludedBlockCount > 0) { bool match = false; foreach (int ib in opt_b.IncludedBlocks) { if (oldBlock == ib) { match = true; break; } } if (!match) { continue; } } // Skip block if it does match the exclusion list if (opt_b.ExcludedBlockCount > 0) { bool match = false; foreach (int xb in opt_b.ExcludedBlocks) { if (oldBlock == xb) { match = true; break; } } if (match) { continue; } } // Replace the block chunk.Blocks.SetID(lx, ly, lz, (int)opt.OPT_AFTER); if (opt.OPT_VV) { int gx = chunk.X * xdim + lx; int gz = chunk.Z * zdim + lz; Console.WriteLine("Replaced block at {0},{1},{2}", gx, ly, gz); } if (opt.OPT_DATA != null) { chunk.Blocks.SetData(lx, ly, lz, (int)opt.OPT_DATA); } } } }*/ }
public void LoadLevel() { int verticalOffset = 85; Debug.Log("About to load level folder: " + _fullMapPath + "."); Substrate.AnvilWorld mcWorld = Substrate.AnvilWorld.Create(_fullMapPath); Substrate.AnvilRegionManager mcAnvilRegionManager = mcWorld.GetRegionManager(); OpenCog.BlockSet.OCBlockSet blockSet = _map.GetBlockSet(); //_map.GetSunLightmap().SetSunHeight(20, 4, 4); int createCount = 0; System.Collections.Generic.Dictionary <int, int> unmappedBlockTypes = new System.Collections.Generic.Dictionary <int, int>(); //Debug.Log("In LoadLevel, there are " + blockSet.BlockCount + " blocks available."); foreach (Substrate.AnvilRegion mcAnvilRegion in mcAnvilRegionManager) { // Loop through x-axis of chunks in this region for (int iMCChunkX = 0; iMCChunkX < mcAnvilRegion.XDim; iMCChunkX++) { // Loop through z-axis of chunks in this region. for (int iMCChunkZ = 0; iMCChunkZ < mcAnvilRegion.ZDim; iMCChunkZ++) { // Retrieve the chunk at the current position in our 2D loop... Substrate.ChunkRef mcChunkRef = mcAnvilRegion.GetChunkRef(iMCChunkX, iMCChunkZ); if (mcChunkRef != null) { if (mcChunkRef.IsTerrainPopulated) { // Ok...now to stick the blocks in... int iMCChunkY = 0; OCChunk chunk = null; //new OCChunk(_map, new Vector3i(iMCChunkX, iMCChunkY, iMCChunkZ)); OCChunk lastChunk = null; Vector3i chunkPos = new Vector3i(mcAnvilRegion.ChunkGlobalX(iMCChunkX), iMCChunkY + verticalOffset, mcAnvilRegion.ChunkGlobalZ(iMCChunkZ)); Vector3i lastChunkPos = Vector3i.zero; chunk = _map.GetChunkInstance(chunkPos); for (int iMCChunkInternalY = 0; iMCChunkInternalY < mcChunkRef.Blocks.YDim; iMCChunkInternalY++) { if (iMCChunkInternalY / OCChunk.SIZE_Y > iMCChunkY) { lastChunk = chunk; lastChunkPos = chunkPos; chunkPos = new Vector3i(mcAnvilRegion.ChunkGlobalX(iMCChunkX), (iMCChunkInternalY + verticalOffset) / OCChunk.SIZE_Y, mcAnvilRegion.ChunkGlobalZ(iMCChunkZ)); chunk = _map.GetChunkInstance(chunkPos); } for (int iMCChunkInternalX = 0; iMCChunkInternalX < mcChunkRef.Blocks.XDim; iMCChunkInternalX++) { for (int iMCChunkInternalZ = 0; iMCChunkInternalZ < mcChunkRef.Blocks.ZDim; iMCChunkInternalZ++) { int iBlockID = mcChunkRef.Blocks.GetID(iMCChunkInternalX, iMCChunkInternalY, iMCChunkInternalZ); if (iBlockID != 0) { Vector3i blockPos = new Vector3i(iMCChunkInternalX, iMCChunkInternalY % OCChunk.SIZE_Y, iMCChunkInternalZ); int ourBlockID = -1; // switch (iBlockID) // { // case 3: // Dirt to first grass // ourBlockID = 1; // break; // case 12: // Grass to grass // ourBlockID = 1; // break; // case 13: // Gravel to stone // ourBlockID = 4; // break; // case 1: // Stone to second stone // ourBlockID = 5; // break; // case 16: // Coal ore to fungus // ourBlockID = 17; // break; // case 15: // Iron ore to pumpkin // ourBlockID = 20; // break; // case 9: // Water to water // ourBlockID = 8; // //Debug.Log ("Creating some water at [" + blockPos.x + ", " + blockPos.y + ", " + blockPos.z + "]"); // break; //// case 2: //// iBlockID = 16; //// break; //// case 4: //// iBlockID = 16; //// break; //// case 18: //// iBlockID = 16; //// break; // default: // { // //Debug.Log ("Unmapped BlockID: " + iBlockID); // // if (!unmappedBlockTypes.ContainsKey (iBlockID)) // { // unmappedBlockTypes.Add (iBlockID, 1); // } // else // { // unmappedBlockTypes[iBlockID] += 1; // } // // break; // } // } if (mcToOCBlockDictionary.ContainsKey(iBlockID)) { ourBlockID = mcToOCBlockDictionary[iBlockID]; } else { if (!unmappedBlockTypes.ContainsKey(iBlockID)) { unmappedBlockTypes.Add(iBlockID, 1); } else { unmappedBlockTypes[iBlockID] += 1; } } if (ourBlockID != -1) { OCBlock newBlock = blockSet.GetBlock(ourBlockID); //OCBlockData block = new OpenCog.Map.OCBlockData(newBlock, blockPos); OCBlockData block = (OCBlockData)OCScriptableObject.CreateInstance <OCBlockData>(); block.Init(newBlock, blockPos); chunk.SetBlock(block, blockPos); OpenCog.Map.Lighting.OCLightComputer.RecomputeLightAtPosition(_map, blockPos); if (block.block.GetName() == "Battery") { GameObject batteryPrefab = OCMap.Instance.BatteryPrefab; if (batteryPrefab == null) { UnityEngine.Debug.Log("OCBuilder::Update, batteryPrefab == null"); } else { GameObject battery = (GameObject)GameObject.Instantiate(batteryPrefab); battery.transform.position = blockPos; battery.name = "Battery"; battery.transform.parent = OCMap.Instance.BatteriesSceneObject.transform; } } if (block.block.GetName() == "Hearth") { GameObject hearthPrefab = OCMap.Instance.HearthPrefab; if (hearthPrefab == null) { UnityEngine.Debug.Log("OCBuilder::Update, hearthPrefab == null"); } else { GameObject hearth = (GameObject)GameObject.Instantiate(hearthPrefab); hearth.transform.position = blockPos; hearth.name = "Hearth"; hearth.transform.parent = OCMap.Instance.HearthsSceneObject.transform; } } createCount += 1; } } } // End for (int iMCChunkInternalZ = 0; iMCChunkInternalZ < mcChunkRef.Blocks.ZDim; iMCChunkInternalZ++) } // End for (int iMCChunkInternalY = 0; iMCChunkInternalY < mcChunkRef.Blocks.YDim; iMCChunkInternalY++) string chunkCoord = chunkPos.x + ", " + chunkPos.z; if (!chunkList.ContainsKey(chunkCoord)) { chunkList.Add(chunkCoord, chunkPos); } if (iMCChunkY < iMCChunkInternalY / OCChunk.SIZE_Y) { _map.Chunks.AddOrReplace(lastChunk, lastChunkPos); _map.UpdateChunkLimits(lastChunkPos); _map.SetDirty(lastChunkPos); iMCChunkY = iMCChunkInternalY / OCChunk.SIZE_Y; } } // End for (int iMCChunkInternalX = 0; iMCChunkInternalX < mcChunkRef.Blocks.XDim; iMCChunkInternalX++) } // End if (mcChunkRef.IsTerrainPopulated) } // End if (mcChunkRef != null) } // End for (int iMCChunkZ = 0; iMCChunkZ < mcAnvilRegion.ZDim; iMCChunkZ++) } // End for (int iMCChunkX = 0; iMCChunkX < mcAnvilRegion.XDim; iMCChunkX++) } // End foreach( Substrate.AnvilRegion mcAnvilRegion in mcAnvilRegionManager ) foreach (Vector3i chunkToLight in chunkList.Values) { OpenCog.Map.Lighting.OCChunkSunLightComputer.ComputeRays(_map, chunkToLight.x, chunkToLight.z); OpenCog.Map.Lighting.OCChunkSunLightComputer.Scatter(_map, null, chunkToLight.x, chunkToLight.z); } foreach (System.Collections.Generic.KeyValuePair <int, int> unmappedBlockData in unmappedBlockTypes) { UnityEngine.Debug.Log("Unmapped BlockID '" + unmappedBlockData.Key + "' found " + unmappedBlockData.Value + " times."); } Debug.Log("Loaded level: " + _fullMapPath + ", created " + createCount + " blocks."); _map.AddColliders(); } // End public void LoadLevel()
public void ApplyChunk (NbtWorld world, ChunkRef chunk) { if (opt.OPT_V) { Console.WriteLine("Generating {0} size {1} deposits of {2} between {3} and {4}", opt.OPT_ROUNDS, opt.OPT_SIZE, opt.OPT_ID, opt.OPT_MIN, opt.OPT_MAX); } IGenerator generator; if (opt.OPT_DATA == null) { generator = new NativeGenOre((int)opt.OPT_ID, (int)opt.OPT_SIZE); ((NativeGenOre)generator).MathFix = opt.OPT_MATHFIX; } else { generator = new NativeGenOre((int)opt.OPT_ID, (int)opt.OPT_DATA, (int)opt.OPT_SIZE); ((NativeGenOre)generator).MathFix = opt.OPT_MATHFIX; } IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); IBlockManager bm = new GenOreBlockManager(cm, opt); for (int i = 0; i < opt.OPT_ROUNDS; i++) { if (opt.OPT_VV) { Console.WriteLine("Generating round {0}...", i); } int x = chunk.X * chunk.Blocks.XDim + rand.Next(chunk.Blocks.XDim); int y = (int)opt.OPT_MIN + rand.Next((int)opt.OPT_MAX - (int)opt.OPT_MIN); int z = chunk.Z * chunk.Blocks.ZDim + rand.Next(chunk.Blocks.ZDim); generator.Generate(bm, rand, x, y, z); } }
/// <inheritdoc/> public int GetTileTickValue(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return 0; } return cache.Blocks.GetTileTickValue(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
public int[] FindFreeAir(ChunkRef chunk, RegionChunkManager chunkMan, int x, int y, int z) { int cx = chunk.X; int cz = chunk.Z; int[] position = { -9999, -9999, cx, cz }; int xdim = chunk.Blocks.XDim; int zdim = chunk.Blocks.ZDim; int xt; int zt; int cxt; int czt; for (int a = 0; a <= 8; a++) { xt = x + (-fallSpread + rand.Next(((1 + fallSpread) * 2))); zt = z + (-fallSpread + rand.Next(((1 + fallSpread) * 2))); cxt = cx; czt = cz; // Jump into neighboring chunks if needed if (xt < 0) { cxt--; xt = xt + xdim; } else if (xt >= xdim) { cxt++; xt = xt - xdim; } if (zt < 0) { czt--; zt = zt + zdim; } else if (zt >= zdim) { czt++; zt = zt - zdim; } ChunkRef tchunk = chunkMan.GetChunkRef(cxt, czt); if (tchunk == null) continue; int resBlock = tchunk.Blocks.GetID(xt, y, zt); if (resBlock == 0 || smashBlock.Contains(resBlock)) { position[0] = xt; position[1] = zt; position[2] = cxt; position[3] = czt; break; } } return position; }
/// <inheritdoc/> public int GetHeight(int x, int z) { cache = GetChunk(x, 0, z); if (cache == null || !Check(x, 0, z)) { return 0; } return cache.Blocks.GetHeight(x & chunkXMask, z & chunkZMask); }
public int[] FindFreeLight(ChunkRef chunk, RegionChunkManager chunkMan, int x, int y, int z) { int[] position = { -9999, -9999, -9999, -999, -999 }; int cx = chunk.X; int cz = chunk.Z; int xdim = chunk.Blocks.XDim; int zdim = chunk.Blocks.ZDim; int xt = x; int zt = z; int chance = rand.Next(4); if (chance == 0) xt = x + 1; else if (chance == 1) xt = x - 1; else if (chance == 2) zt = z + 1; else zt = z - 1; int xtt = xt; int ztt = zt; int cxt = cx; int czt = cz; for (int a = 0; a <= 4; a++) { xt = x; zt = z; cxt = cx; czt = cz; if (a == 4) { y--; } else if ((xtt == x + 1) && (ztt == z)) { xt = x; zt = z + 1; } else if ((xtt == x) && (ztt == z + 1)) { xt = x - 1; zt = z; } else if ((xtt == x - 1) && (ztt == z)) { xt = x; zt = z - 1; } else if ((xtt == x) && (ztt == z - 1)) { xt = x + 1; zt = z; } xtt = xt; ztt = zt; // Jump into neighboring chunks if needed if (xt < 0) { cxt--; xt = xt + xdim; } else if (xt >= xdim) { cxt++; xt = xt - xdim; } if (zt < 0) { czt--; zt = zt + zdim; } else if (zt >= zdim) { czt++; zt = zt - zdim; } ChunkRef tchunk = chunkMan.GetChunkRef(cxt, czt); if (tchunk == null) { continue; } int resBlock = tchunk.Blocks.GetID(xt, y, zt); if (resBlock == 0 || smashBlock.Contains(resBlock)) { position[0] = xt; position[1] = zt; position[2] = y; position[3] = cxt; position[4] = czt; break; } } return position; }
public void LoadLevel() { int verticalOffset = 85; Debug.Log("About to load level folder: " + _fullMapPath + "."); Substrate.AnvilWorld mcWorld = Substrate.AnvilWorld.Create(_fullMapPath); Substrate.AnvilRegionManager mcAnvilRegionManager = mcWorld.GetRegionManager(); BlockSet blockSet = _map.GetBlockSet(); _map.GetSunLightmap().SetSunHeight(3, 3, 3); foreach (Substrate.AnvilRegion mcAnvilRegion in mcAnvilRegionManager) { // Loop through x-axis of chunks in this region for (int iMCChunkX = 0; iMCChunkX < mcAnvilRegion.XDim; iMCChunkX++) { // Loop through z-axis of chunks in this region. for (int iMCChunkZ = 0; iMCChunkZ < mcAnvilRegion.ZDim; iMCChunkZ++) { // Retrieve the chunk at the current position in our 2D loop... Substrate.ChunkRef mcChunkRef = mcAnvilRegion.GetChunkRef(iMCChunkX, iMCChunkZ); if (mcChunkRef != null) { if (mcChunkRef.IsTerrainPopulated) { // Ok...now to stick the blocks in... for (int iMCChunkInternalX = 0; iMCChunkInternalX < mcChunkRef.Blocks.XDim; iMCChunkInternalX++) { for (int iMCChunkInternalY = 0; iMCChunkInternalY < mcChunkRef.Blocks.YDim; iMCChunkInternalY++) { for (int iMCChunkInternalZ = 0; iMCChunkInternalZ < mcChunkRef.Blocks.ZDim; iMCChunkInternalZ++) { int iBlockID = mcChunkRef.Blocks.GetID(iMCChunkInternalX, iMCChunkInternalY, iMCChunkInternalZ); Vector3i blockPos = new Vector3i(iMCChunkInternalX, iMCChunkInternalY + verticalOffset, iMCChunkInternalZ); if (iBlockID != 0) { switch (iBlockID) { case 3: // Dirt to first grass iBlockID = 1; break; case 12: // Grass to grass iBlockID = 1; break; case 13: // Gravel to stone iBlockID = 4; break; case 1: // Stone to second stone iBlockID = 5; break; case 16: // Coal ore to fungus iBlockID = 17; break; case 15: // Iron ore to pumpkin iBlockID = 20; break; case 9: // Water to water iBlockID = 8; break; default: Debug.Log("Unmapped BlockID: " + iBlockID); break; } Block newBlock = blockSet.GetBlock(iBlockID); _map.SetBlock(new BlockData(newBlock), blockPos); Vector3i chunkPos = Chunk.ToChunkPosition(blockPos); _map.SetDirty(chunkPos); } } // End for (int iMCChunkInternalZ = 0; iMCChunkInternalZ < mcChunkRef.Blocks.ZDim; iMCChunkInternalZ++) } // End for (int iMCChunkInternalY = 0; iMCChunkInternalY < mcChunkRef.Blocks.YDim; iMCChunkInternalY++) } // End for (int iMCChunkInternalX = 0; iMCChunkInternalX < mcChunkRef.Blocks.XDim; iMCChunkInternalX++) } // End if (mcChunkRef.IsTerrainPopulated) } // End if (mcChunkRef != null) } // End for (int iMCChunkZ = 0; iMCChunkZ < mcAnvilRegion.ZDim; iMCChunkZ++) } // End for (int iMCChunkX = 0; iMCChunkX < mcAnvilRegion.XDim; iMCChunkX++) } // End foreach( Substrate.AnvilRegion mcAnvilRegion in mcAnvilRegionManager ) Debug.Log("Loaded level: " + _fullMapPath + "."); _map.AddColliders(); // List3D<Chunk> chunkList = _map.GetChunks (); // // for (int minX = chunkList.GetMinX(); minX < chunkList.GetMaxX(); minX++) // { // for (int minY = chunkList.GetMinY(); minY < chunkList.GetMaxY(); minY++) // { // for (int minZ = chunkList.GetMinZ(); minZ < chunkList.GetMaxZ(); minZ++) // { // Vector3i chunkPos = new Vector3i(minX, minY, minZ); // // Chunk mapChunk = _map.GetChunk (chunkPos); // // Debug.Log ("LOL [" + minX + ", " + minY + ", " + minZ + "]."); // } // } // } // // foreach (Chunk loadedChunk in _map.Get // { // Vector3i loadedChunkPos = loadedChunk.GetPosition(); // Debug.Log ("MOG A CHUNK!!! [" + loadedChunkPos.x + ", " + loadedChunkPos.y + ", " + loadedChunkPos.z + "]."); // } } // End public void LoadLevel()
/// <inheritdoc/> public int GetSkyLight(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null) { return 0; } return cache.Blocks.GetSkyLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
/// <summary> /// Returns a new <see cref="AlphaBlockRef"/> object from global coordaintes. /// </summary> /// <param name="x">Global X-coordinate of block.</param> /// <param name="y">Global Y-coordinate of block.</param> /// <param name="z">Global Z-coordinate of block.</param> /// <returns>A new <see cref="AlphaBlockRef"/> object representing context-dependent data of a single block.</returns> /// <remarks>Context-depdendent data includes all data associated with this block. Since a <see cref="AlphaBlockRef"/> represents /// a view of a block within this container, any updates to data in the container will be reflected in the <see cref="AlphaBlockRef"/>, /// and vice-versa for updates to the <see cref="AlphaBlockRef"/>.</remarks> public AlphaBlockRef GetBlockRef(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return new AlphaBlockRef(); } return cache.Blocks.GetBlockRef(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
private AlphaBlockRef GetNeighborBlock(ChunkRef chunk, int x, int y, int z) { if (chunk == null) return new AlphaBlockRef(); ChunkRef target = chunk; if (x < 0) { target = chunk.GetNorthNeighbor(); x += chunk.Blocks.XDim; } else if (x >= chunk.Blocks.XDim) { target = chunk.GetSouthNeighbor(); x -= chunk.Blocks.XDim; } else if (z < 0) { target = chunk.GetEastNeighbor(); z += chunk.Blocks.ZDim; } else if (z >= chunk.Blocks.ZDim) { target = chunk.GetWestNeighbor(); z -= chunk.Blocks.ZDim; } else return target.Blocks.GetBlockRef(x, y, z); return GetNeighborBlock(target, x, y, z); }
/// <inheritdoc/> public BlockInfo GetInfo(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return null; } return cache.Blocks.GetInfo(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
public void ApplyChunk(NbtWorld world, ChunkRef chunk) { IBlockFilter opt_b = opt.GetBlockFilter(); //chunk.Blocks.AutoLight = false; //chunk.Blocks.AutoTileTick = false; int xBase = chunk.X * chunk.Blocks.XDim; int zBase = chunk.Z * chunk.Blocks.ZDim; // Determine X range int xmin = 0; int xmax = 15; if (opt_b.XAboveEq != null) { xmin = (int)opt_b.XAboveEq - xBase; } if (opt_b.XBelowEq != null) { xmax = (int)opt_b.XBelowEq - xBase; } xmin = (xmin < 0) ? 0 : xmin; xmax = (xmax > 15) ? 15 : xmax; if (xmin > 15 || xmax < 0 || xmin > xmax) { return; } // Determine Y range int ymin = 0; int ymax = 127; if (opt_b.YAboveEq != null) { ymin = (int)opt_b.YAboveEq; } if (opt_b.YBelowEq != null) { ymax = (int)opt_b.YBelowEq; } if (ymin > ymax) { return; } // Determine X range int zmin = 0; int zmax = 15; if (opt_b.ZAboveEq != null) { zmin = (int)opt_b.ZAboveEq - zBase; } if (opt_b.ZBelowEq != null) { zmax = (int)opt_b.ZBelowEq - zBase; } zmin = (zmin < 0) ? 0 : zmin; zmax = (zmax > 15) ? 15 : zmax; if (zmin > 15 || zmax < 0 || zmin > zmax) { return; } int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; // Bin blocks for (int y = ymin; y <= ymax; y++) { for (int x = xmin; x <= xmax; x++) { for (int z = zmin; z <= zmax; z++) { int id = chunk.Blocks.GetID(x, y, z); if (!_sort.ContainsKey(id)) _sort[id] = new List<BlockKey>(); _sort[id].Add(new BlockKey(x, y, z)); } } } // Process bins //for (int i = 0; i < maxBin; i++) { foreach (var kv in _sort) { if (kv.Value.Count == 0) { continue; } if (opt_b.IncludedBlockCount > 0 & !opt_b.IncludedBlocksContains(kv.Key)) { continue; } if (opt_b.ExcludedBlockCount > 0 & opt_b.ExcludedBlocksContains(kv.Key)) { continue; } foreach (BlockKey key in kv.Value) { // Probability test if (opt_b.ProbMatch != null) { double c = rand.NextDouble(); if (c > opt_b.ProbMatch) continue; } if (opt_b.BlocksAboveCount > 0 && key.y < ydim - 1) { int neighborId = chunk.Blocks.GetID(key.x, key.y + 1, key.z); if (!opt_b.BlocksAboveContains(neighborId)) continue; } if (opt_b.BlocksBelowCount > 0 && key.y > 0) { int neighborId = chunk.Blocks.GetID(key.x, key.y - 1, key.z); if (!opt_b.BlocksBelowContains(neighborId)) continue; } if (opt_b.BlocksSideCount > 0) { bool validNeighbor = false; AlphaBlockRef block1 = GetNeighborBlock(chunk, key.x - 1, key.y, key.z); if (block1.IsValid && opt_b.BlocksSideContains(block1.ID) && !validNeighbor) validNeighbor = true; AlphaBlockRef block2 = GetNeighborBlock(chunk, key.x + 1, key.y, key.z); if (block2.IsValid && opt_b.BlocksSideContains(block2.ID) && !validNeighbor) validNeighbor = true; AlphaBlockRef block3 = GetNeighborBlock(chunk, key.x, key.y, key.z - 1); if (block3.IsValid && opt_b.BlocksSideContains(block3.ID) && !validNeighbor) validNeighbor = true; AlphaBlockRef block4 = GetNeighborBlock(chunk, key.x, key.y, key.z + 1); if (block4.IsValid && opt_b.BlocksSideContains(block4.ID) && !validNeighbor) validNeighbor = true; if (!validNeighbor) continue; } if (opt_b.BlocksNAboveCount > 0 && key.y < ydim - 1) { int neighborId = chunk.Blocks.GetID(key.x, key.y + 1, key.z); if (opt_b.BlocksNAboveContains(neighborId)) continue; } if (opt_b.BlocksNBelowCount > 0 && key.y > 0) { int neighborId = chunk.Blocks.GetID(key.x, key.y - 1, key.z); if (opt_b.BlocksNBelowContains(neighborId)) continue; } if (opt_b.BlocksNSideCount > 0) { AlphaBlockRef block1 = GetNeighborBlock(chunk, key.x - 1, key.y, key.z); if (block1.IsValid && opt_b.BlocksNSideContains(block1.ID)) continue; AlphaBlockRef block2 = GetNeighborBlock(chunk, key.x + 1, key.y, key.z); if (block2.IsValid && opt_b.BlocksNSideContains(block2.ID)) continue; AlphaBlockRef block3 = GetNeighborBlock(chunk, key.x, key.y, key.z - 1); if (block3.IsValid && opt_b.BlocksNSideContains(block3.ID)) continue; AlphaBlockRef block4 = GetNeighborBlock(chunk, key.x, key.y, key.z + 1); if (block4.IsValid && opt_b.BlocksNSideContains(block4.ID)) continue; } if (opt_b.IncludedDataCount > 0 || opt_b.ExcludedDataCount > 0) { int data = chunk.Blocks.GetData(key.x, key.y, key.z); if (opt_b.IncludedDataCount > 0 && !opt_b.IncludedDataContains(data)) { continue; } if (opt_b.ExcludedDataCount > 0 && opt_b.ExcludedDataContains(data)) { continue; } } chunk.Blocks.SetID(key.x, key.y, key.z, (int)opt.OPT_AFTER); if (opt.OPT_VV) { int gx = chunk.X * xdim + key.x; int gz = chunk.Z * zdim + key.z; Console.WriteLine("Replaced block {0} at {1},{2},{3}", kv.Key, gx, key.y, gz); } if (opt.OPT_DATA != null) { chunk.Blocks.SetData(key.x, key.y, key.z, (int)opt.OPT_DATA); } } } // Reset bins _sort.Clear(); // Process Chunk /*for (int y = ymin; y <= ymax; y++) { for (int x = xmin; x <= xmax; x++) { for (int z = zmin; z <= zmax; z++) { // Probability test if (opt_b.ProbMatch != null) { double c = rand.NextDouble(); if (c > opt_b.ProbMatch) { continue; } } int lx = x % xdim; int ly = y % ydim; int lz = z % zdim; // Get the old block int oldBlock = chunk.Blocks.GetID(lx , ly, lz); // Skip block if it doesn't match the inclusion list if (opt_b.IncludedBlockCount > 0) { bool match = false; foreach (int ib in opt_b.IncludedBlocks) { if (oldBlock == ib) { match = true; break; } } if (!match) { continue; } } // Skip block if it does match the exclusion list if (opt_b.ExcludedBlockCount > 0) { bool match = false; foreach (int xb in opt_b.ExcludedBlocks) { if (oldBlock == xb) { match = true; break; } } if (match) { continue; } } // Replace the block chunk.Blocks.SetID(lx, ly, lz, (int)opt.OPT_AFTER); if (opt.OPT_VV) { int gx = chunk.X * xdim + lx; int gz = chunk.Z * zdim + lz; Console.WriteLine("Replaced block at {0},{1},{2}", gx, ly, gz); } if (opt.OPT_DATA != null) { chunk.Blocks.SetData(lx, ly, lz, (int)opt.OPT_DATA); } } } }*/ }
/// <inheritdoc/> public TileEntity GetTileEntity(int x, int y, int z) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return null; } return cache.Blocks.GetTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask); }
/// <summary> /// Create a reference to a chunk stored in a chunk container. /// </summary> /// <param name="container">Chunk container</param> /// <param name="cx">Local X-coordinate of chunk within container.</param> /// <param name="cz">Local Z-coordinate of chunk within container.</param> /// <returns>ChunkRef representing a reference to a physical chunk at the specified location within the container.</returns> public static ChunkRef Create(IChunkContainer container, int cx, int cz) { if (!container.ChunkExists(cx, cz)) { return null; } ChunkRef c = new ChunkRef(); c._container = container; c._cx = cx; c._cz = cz; return c; }
public int CheckAir(ChunkRef chunk, RegionChunkManager chunkMan, int x, int y, int z) { int cx = chunk.X; int cz = chunk.Z; int xdim = chunk.Blocks.XDim; int zdim = chunk.Blocks.ZDim; int result = 0; if (x < 0) { cx--; x = x + xdim; } else if (x >= xdim) { cx++; x = x - xdim; } if (z < 0) { cz--; z = z + zdim; } else if (z >= zdim) { cz++; z = z - zdim; } ChunkRef tchunk = chunkMan.GetChunkRef(cx, cz); if (tchunk != null) { int resBlock = tchunk.Blocks.GetID(x, y, z); if (resBlock != 0) { result = resBlock; } } return result; }
/// <inheritdoc/> public void SetID(int x, int y, int z, int id) { cache = GetChunk(x, y, z); if (cache == null || !Check(x, y, z)) { return; } bool autolight = cache.Blocks.AutoLight; bool autofluid = cache.Blocks.AutoFluid; bool autoTileTick = cache.Blocks.AutoTileTick; cache.Blocks.AutoLight = _autoLight; cache.Blocks.AutoFluid = _autoFluid; cache.Blocks.AutoTileTick = _autoTileTick; cache.Blocks.SetID(x & chunkXMask, y & chunkYMask, z & chunkZMask, id); cache.Blocks.AutoFluid = autofluid; cache.Blocks.AutoLight = autolight; cache.Blocks.AutoTileTick = autoTileTick; }
// Function for falling and toppling blocks public void AgeChunk(ChunkRef chunk, RegionChunkManager chunkMan, Bitmap perlinMask, int perlinResolution, int[] minXZ) { int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; double c = 0; int xp; int yp; int zp; float fallChanceMin = (float)fallChance[0] / 100f; // Some lazy coding on my side float fallChanceMax = (float)fallChance[1] / 100f - fallChanceMin; float fallKillChanceMin = (float)fallKillChance[0] / 100f; float fallKillChanceMax = (float)fallKillChance[1] / 100f - fallKillChanceMin; float sidewaysFallChanceMin = (float)sidewaysFallChance[0] / 100f; float sidewaysFallChanceMax = (float)sidewaysFallChance[1] / 100f - sidewaysFallChanceMin; float stoneFallChanceMin = (float)stoneFallChance[0] / 100f; float stoneFallChanceMax = (float)stoneFallChance[1] / 100f - stoneFallChanceMin; float stoneFallKillChanceMin = (float)stoneFallKillChance[0] / 100f; float stoneFallKillChanceMax = (float)stoneFallKillChance[1] / 100f - stoneFallKillChanceMin; float stoneSidewaysFallChanceMin = (float)stoneSidewaysFallChance[0] / 100f; float stoneSidewaysFallChanceMax = (float)stoneSidewaysFallChance[1] / 100f - stoneSidewaysFallChanceMin; int[] airPos = { -9999, -9999, -999, -999 }; for (int pass = 1; pass <= passN; pass++) { // Check all blocks in the chunk for (int x = 0; x < xdim; x++) { for (int z = 0; z < zdim; z++) { if (chunk.Blocks.GetHeight(x, z) > 0 && chunk.Blocks.GetHeight(x, z) < 256) { // Reset the algorithm limiter int bottomY = ydim - 2; // Get the perlin mask multiplier int px = Math.Abs(minXZ[0] / perlinResolution) + (chunk.X * 16 / perlinResolution) + (x / perlinResolution); int py = Math.Abs(minXZ[1] / perlinResolution) + (chunk.Z * 16 / perlinResolution) + (z / perlinResolution); px = Math.Min(Math.Max(px, 0), perlinMask.Width - 1); py = Math.Min(Math.Max(py, 0), perlinMask.Height - 1); Color perlinCol = perlinMask.GetPixel(px, py); double perlinMulti = (double)perlinCol.R / 255f; int oldBlock; if (stoneAdvanced && pass <= stonePassN) // Stone displacement - advanced method { for (int y = chunk.Blocks.GetHeight(x, z); y > 1; y--) { bottomY = y; // Get the checked block's ID oldBlock = chunk.Blocks.GetID(x, y, z); if (oldBlock == 2 || oldBlock == 3 || oldBlock == 12 || oldBlock == 13) // Stop if encountered grass or dirt, should stop random underground space break; if (oldBlock == 1) { airPos = FindFreeLight(chunk, chunkMan, x, y, z); // Set the most bottom stone to be eroded, stop on grass if (((airPos[0] == -9999) && (airPos[1] == -9999))) { break; } } } for (int y = bottomY; y < ydim - 2; y++) { // Don't even try if out of limits if (y >= ydim - 2 || y <= 1) { continue; } // Get the checked block's ID oldBlock = chunk.Blocks.GetID(x, y, z); // Probability test c = rand.NextDouble(); if (c < stoneFallChanceMin + (stoneFallChanceMax * perlinMulti)) { if (oldBlock == 1) { // Random chance to destroy the block in fall c = rand.NextDouble(); if ((c < fallKillChanceMin + (fallKillChanceMax * perlinMulti)) && pass == 1) { // Kill the initial block chunk.Blocks.SetID(x, y, z, 0); continue; } airPos = FindFreeAir(chunk, chunkMan, x, y, z); // Skip to another column if we don't see light anymore if ((airPos[0] == -9999) && (airPos[1] == -9999)) { continue; } int xf = x; int zf = z; ChunkRef tchunk = chunk; // Random chance to topple c = rand.NextDouble(); if ((c < sidewaysFallChanceMin + (sidewaysFallChanceMax * perlinMulti)) && pass == 1) { xf = airPos[0]; zf = airPos[1]; if (((airPos[2] != chunk.X) || (airPos[3] != chunk.Z)) && ((airPos[2] != -999) && (airPos[3] != -999))) { tchunk = chunkMan.GetChunkRef(airPos[2], airPos[3]); } } // Kill the initial block chunk.Blocks.SetID(x, y, z, 0); for (int yf = y; yf > 1; yf--) { // Incoming! int destBlock = tchunk.Blocks.GetID(xf, yf - 1, zf); if (destBlock == 0 || fallThroughBlock.Contains(destBlock)) { continue; } // Smash weak blocks in the way if (smashBlock.Contains(destBlock)) { tchunk.Blocks.SetID(xf, yf - 1, zf, 0); continue; } tchunk.Blocks.SetID(xf, yf, zf, 1); break; } } } } } else // Stone displacement - simple method { for (int y = chunk.Blocks.GetHeight(x, z); y > 1; y--) { // Don't even try if out of limits if (y >= ydim - 2 || y <= 1) { continue; } // Get the checked block's ID oldBlock = chunk.Blocks.GetID(x, y, z); if (oldBlock == 2 || oldBlock == 3) // Stop if encountered grass or dirt, should stop random underground space break; if (oldBlock == 1) { // Probability test c = rand.NextDouble(); if (c < stoneFallChanceMin + (stoneFallChanceMax * perlinMulti)) { // Random chance to destroy the block in fall c = rand.NextDouble(); if ((c < stoneFallKillChanceMin + (stoneFallKillChanceMax * perlinMulti)) && pass == 1) { // Kill the initial block chunk.Blocks.SetID(x, y, z, 0); continue; } airPos = FindFreeLight(chunk, chunkMan, x, y, z); // Skip to another column if we don't see light anymore if ((airPos[0] == -9999) && (airPos[1] == -9999)) { break; } int xf = x; int yf = y; int zf = z; ChunkRef tchunk = chunk; // Random chance to topple c = rand.NextDouble(); if ((c < stoneSidewaysFallChanceMin + (stoneSidewaysFallChanceMin * perlinMulti)) && pass == 1) { xf = airPos[0]; zf = airPos[1]; yf = airPos[2]; if (((airPos[3] != chunk.X) || (airPos[4] != chunk.Z)) && ((airPos[3] != -999) && (airPos[4] != -999))) { tchunk = chunkMan.GetChunkRef(airPos[3], airPos[4]); } } // Kill the initial block chunk.Blocks.SetID(x, y, z, 0); for (yf = y; yf > 1; yf--) { // Incoming! int destBlock = tchunk.Blocks.GetID(xf, yf - 1, zf); if (destBlock == 0 || fallThroughBlock.Contains(destBlock)) { continue; } // Smash weak blocks in the way if (smashBlock.Contains(destBlock)) { tchunk.Blocks.SetID(xf, yf - 1, zf, 0); continue; } tchunk.Blocks.SetID(xf, yf, zf, 1); break; } } } } } for (int y = 1; y < ydim - 2; y++) // Manmade blocks displacement { // Get the checked block's ID oldBlock = chunk.Blocks.GetID(x, y, z); xp = x; yp = y; zp = z; // Try to look if (pass == 1) { // Loop through all entries in the mutateBlock array for (int i = 0; i < mutateBlock.GetUpperBound(0); i++) { if (oldBlock == 0) { break; } // If the checked block is not the what we want, jump to the next mutateBlock entry if (oldBlock != mutateBlock[i, 0]) { continue; } // Have a random chance of letting the block live float pMin = (mutateBlock[i, 2]) / 100f; float pMax = (mutateBlock[i, 3]) / 100f; c = rand.NextDouble(); if (c > pMin + (pMax * perlinMulti)) { break; } chunk.Blocks.SetID(x, y, z, mutateBlock[i, 1]); oldBlock = mutateBlock[i, 1]; break; } } foreach (int i in fallBlock) { if (oldBlock == i) { // Probability test c = rand.NextDouble(); if (c < fallChanceMin + (fallChanceMax * perlinMulti)) { int xtemp = x; int ztemp = z; // Random chance to destroy the block in fall c = rand.NextDouble(); if ((c < fallKillChanceMin + (fallKillChanceMin * perlinMulti)) && pass == 1) { chunk.Blocks.SetID(x, y, z, 0); break; } ChunkRef tchunk = chunk; // If we push blocks sideways if (pass <= sidewaysPassN) { // Look if the block has empty space below it int supportBlock = chunk.Blocks.GetID(x, y - 1, z); if (supportBlock != 0) { c = rand.NextDouble(); if (c < sidewaysFallChanceMin + (sidewaysFallChanceMin * perlinMulti)) { //Try to move the block sideways airPos = FindFreeAir(chunk, chunkMan, x, y, z); if ((airPos[0] == -9999) && (airPos[1] == -9999)) { break; } xtemp = airPos[0]; ztemp = airPos[1]; if (((airPos[2] != chunk.X) || (airPos[3] != chunk.Z)) && ((airPos[2] != -999) && (airPos[3] != -999))) { tchunk = chunkMan.GetChunkRef(airPos[2], airPos[3]); } } else { break; } } } int fallData = chunk.Blocks.GetData(x, y, z); TileEntity fallTE = chunk.Blocks.GetTileEntity(x, y, z); chunk.Blocks.SetID(x, y, z, 0); tchunk.Blocks.ClearTileEntity(x, y, z); for (int yf = y; yf > 1; yf--) { // It's raining blocks, halelujah, it's raining blocks... int destBlock = tchunk.Blocks.GetID(xtemp, yf - 1, ztemp); if (destBlock == 0 || fallThroughBlock.Contains(destBlock)) { continue; } // Smash weak blocks in the way if (smashBlock.Contains(destBlock)) { tchunk.Blocks.SetID(xtemp, yf - 1, ztemp, 0); tchunk.Blocks.ClearTileEntity(xtemp, yf - 1, ztemp); continue; } tchunk.Blocks.SetID(xtemp, yf, ztemp, i); tchunk.Blocks.SetData(xtemp, yf, ztemp, fallData); if (fallTE != null && fallTE.ID != "Sign" && AcceptsTileEntities(i)) { tchunk.Blocks.SetTileEntity(xtemp, yf, ztemp, fallTE); } xp = xtemp; yp = yf; zp = ztemp; break; } } } } } } } } } }
// Function for cleaning clutter left by AgeChunk public void CleanChunk(ChunkRef chunk, RegionChunkManager chunkMan, Bitmap perlinMask, int perlinResolution, int[] minXZ) { int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; int checkx = 0; int checky = 0; int checkz = 0; int oldBlock; float natureKillChanceMin = (float)natureKillChance[0] / 100f; float natureKillChanceMax = (float)natureKillChance[1] / 100f - natureKillChanceMin; // Check all blocks in the chunk for (int x = 0; x < xdim; x++) { for (int z = 0; z < zdim; z++) { int px = Math.Abs(minXZ[0]) + (chunk.X * 16) + (x / perlinResolution); int py = Math.Abs(minXZ[1]) + (chunk.Z * 16) + (z / perlinResolution); px = Math.Min(Math.Max(px, 0), perlinMask.Width - 1); py = Math.Min(Math.Max(py, 0), perlinMask.Height - 1); Color perlinCol = perlinMask.GetPixel(px, py); double perlinMulti = (double)perlinCol.R / 255f; bool eroded = false; bool foundLeaves = false; for (int y = ydim - 2; y > 1; y--) { checkx = x; checky = y; checkz = z; // Attempt to replace block oldBlock = chunk.Blocks.GetID(x, y, z); int oldData = chunk.Blocks.GetData(x, y, z); // Destroy old trees if (natureRepopulation) { if (oldBlock == 18) { foundLeaves = true; } if (foundLeaves && oldBlock == 17) { chunk.Blocks.SetID(x, y, z, 0); } } if (oldBlock != 0 && !eroded && natureKillBlock.Length != 0) { foreach (int i in natureKillBlock) { if (oldBlock == i) { double c = rand.NextDouble(); if (c < natureKillChanceMin + (natureKillChanceMax * perlinMulti)) { chunk.Blocks.SetID(x, y, z, natureKillTo); } eroded = true; break; } } } // Check signs, ladders if (oldBlock == 65 || oldBlock == 68) { if (oldData == 2) { checkz = z + 1; } else if (oldData == 3) { checkz = z - 1; } else if (oldData == 4) { checkx = x + 1; } else if (oldData == 5) { checkx = x - 1; } int airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); continue; } } // Check buttons if (oldBlock == 77) { if (oldData == 1) { checkx = x - 1; } else if (oldData == 2) { checkx = x + 1; } else if (oldData == 3) { checkz = z - 1; } else if (oldData == 4) { checkz = z + 1; } int airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); continue; } } // Check torches and levers if (oldBlock == 50 || oldBlock == 69 || oldBlock == 75 || oldBlock == 76) { if (oldData == 1) { checkx = x - 1; } else if (oldData == 2) { checkx = x + 1; } else if (oldData == 3) { checkz = z - 1; } else if (oldData == 4) { checkz = z + 1; } else if (oldData == 5 || oldData == 6) { checky = y - 1; } int airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); continue; } } // Check trapdoors if (oldBlock == 96) { if (oldData == 0) { checkz = z + 1; } else if (oldData == 1) { checkz = z - 1; } else if (oldData == 2) { checkx = x + 1; } else if (oldData == 3) { checkx = x - 1; } int airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); continue; } } // Check doors if (oldBlock == 64 || oldBlock == 71) { int tchecky = y; if (oldData >= 8) { tchecky = y - 1; checky = y - 2; int airCheck = CheckAir(chunk, chunkMan, checkx, tchecky, checkz); if (airCheck != 64 && airCheck != 71) { chunk.Blocks.SetID(x, y, z, 0); continue; } airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); chunk.Blocks.SetID(x, y - 1, z, 0); continue; } } else { tchecky = y + 1; checky = y - 1; int airCheck = CheckAir(chunk, chunkMan, checkx, tchecky, checkz); if (airCheck != 64 && airCheck != 71) { chunk.Blocks.SetID(x, y, z, 0); continue; } airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); continue; } } } // Check the rest of supported blocks foreach (int i in supportedBlocks) { if (oldBlock == i) { checky = y - 1; int airCheck = CheckAir(chunk, chunkMan, checkx, checky, checkz); if (airCheck == 0) { chunk.Blocks.SetID(x, y, z, 0); } } } } } } }
void HeightMapChunk(ChunkRef chunk, double mapXMin, double mapXMax, double mapYMin, double mapYMax) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { double mux = (mapXMax - mapXMin) * x / 16.0 + mapXMin; double muy = (mapYMax - mapYMin) * z / 16.0 + mapYMin; int height = (int)currentDwarfMap.getElevation(mux, muy) + shift; int waterLevel = currentDwarfMap.getWaterbodyLevel((int)Math.Floor(mux + 0.5), (int)Math.Floor(muy + 0.5)) + shift; int riverLevel = currentDwarfMap.getRiverLevel((int)Math.Floor(mux + 0.5), (int)Math.Floor(muy + 0.5)) + shift; if (height > maxHeight) maxHeight = height; if (height < minHeight) minHeight = height; int biomeIndex = currentDwarfMap.getBiome((int)Math.Floor(mux + 0.5), (int)Math.Floor(muy + 0.5)); chunk.Biomes.SetBiome(x, z, BiomeList.biomes[biomeIndex].mineCraftBiome); //create bedrock for (int y = 0; y < 2; y++) { chunk.Blocks.SetID(x, y, z, BlockType.BEDROCK); } ////deal with rivers //if (riverLevel >= 0) //{ // chunk.Biomes.SetBiome(x, z, BiomeType.River); // height = riverLevel; // for (int y = 0; y < height - 2; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.STONE); // } // for (int y = height - 2; y < height - 1; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.GRAVEL); // } // for (int y = height - 1; y < height; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.WATER); // } //} //else if (BiomeList.biomes[biomeIndex].mineCraftBiome == BiomeID.DeepOcean && waterLevel <= height) //{ // //make beaches // chunk.Biomes.SetBiome(x, z, BiomeType.Beach); // height = 98 + shift; // for (int y = 0; y < height - 4; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.STONE); // } // for (int y = height - 4; y < height - 3; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.SANDSTONE); // } // for (int y = height - 3; y < height; y++) // { // chunk.Blocks.SetID(x, y, z, BlockType.SAND); // } //} //else //{ // // Create the rest, according to biome // for (int y = 2; y < height; y++) // { // if (y >= chunk.Blocks.YDim) break; // chunk.Blocks.SetID(x, y, z, BiomeList.biomes[biomeIndex].getBlockID(height - y, x + (chunk.X * 16), z + (chunk.Z * 16))); // } //} //// Create Oceans and lakes //for (int y = height; y < waterLevel; y++) //{ // if (y < 2) continue; // if (y >= chunk.Blocks.YDim) break; // chunk.Blocks.SetID(x, y, z, BlockType.STATIONARY_WATER); //} // Fill caves for (int y = 2; y < height; y++) { if (y >= chunk.Blocks.YDim) break; int caveID = currentCaveMap.getCaveBlock(mux, y - shift, muy); if (caveID == -2) break; if (caveID >= 0) chunk.Blocks.SetID(x, y, z, caveID); } } } }