Пример #1
0
        /// <summary>
        /// Directions of faces which are revealed due to ViewGrid
        /// </summary>
        Direction GetVoxelSliceDirections(IntVector3 p, ref IntGrid3 viewGrid)
        {
            Direction d = 0;

            // Note: we never draw the bottommost layer in the map, so we don't check for Z1

            if (p.Z == viewGrid.Z2)
            {
                d |= Direction.Up;
            }

            if (p.X == viewGrid.X1)
            {
                d |= Direction.West;
            }

            if (p.X == viewGrid.X2)
            {
                d |= Direction.East;
            }

            if (p.Y == viewGrid.Y1)
            {
                d |= Direction.North;
            }

            if (p.Y == viewGrid.Y2)
            {
                d |= Direction.South;
            }

            return(d);
        }
Пример #2
0
        /// <summary>
        /// Directions of faces which are revealed due to ViewGrid
        /// </summary>
        Direction GetGridSliceDirections(ref IntGrid3 grid, ref IntGrid3 viewGrid)
        {
            Direction d = 0;

            // Note: we never draw the bottommost layer in the map, so we don't check for Z1

            if (grid.Z2 == viewGrid.Z2)
            {
                d |= Direction.Up;
            }

            if (grid.X1 == viewGrid.X1)
            {
                d |= Direction.West;
            }

            if (grid.X2 == viewGrid.X2)
            {
                d |= Direction.East;
            }

            if (grid.Y1 == viewGrid.Y1)
            {
                d |= Direction.North;
            }

            if (grid.Y2 == viewGrid.Y2)
            {
                d |= Direction.South;
            }

            return(d);
        }
Пример #3
0
        public void AddArea(IntGrid3 area, DesignationType type)
        {
            int origCount = m_map.Count;

            var locations = area.Range().Where(this.Environment.Contains);

            foreach (var p in locations)
            {
                if (GetTileValid(p, type) == false)
                    continue;

                DesignationData oldData;

                if (m_map.TryGetValue(p, out oldData))
                {
                    if (oldData.Type == type)
                        continue;

                    RemoveJob(p);
                }

                var data = new DesignationData(type);
                data.Reachable = GetTileReachable(p, type);
                m_map[p] = data;

                this.Environment.OnTileExtraChanged(p);
            }

            if (origCount == 0 && m_map.Count > 0)
            {
                this.Environment.MapTileTerrainChanged += OnEnvironmentMapTileTerrainChanged;
                this.Environment.World.TickStarting += OnTickStartEvent;
            }
        }
Пример #4
0
        public static void Calculate3(IntVector3 viewerLocation, int visionRange, VisionMap visibilityMap, IntSize3 mapSize,
				Func<IntVector3, bool> blockerDelegate)
        {
            visibilityMap.Clear();

            if (blockerDelegate(viewerLocation) == true)
                return;

            var g = new IntGrid3(new IntVector3(), mapSize);
            g = g.Offset(-viewerLocation.X, -viewerLocation.Y, -viewerLocation.Z);
            var vr = new IntVector3(visionRange, visionRange, visionRange);
            g = g.Intersect(new IntGrid3(vr, -vr));

            int visionRangeSquared = (visionRange + 1) * (visionRange + 1);	// +1 to get a bit bigger view area

            foreach (var dst in g.Range())
            {
                if (dst.LengthSquared > visionRangeSquared)
                    continue;

                bool vis = FindLos3(viewerLocation, dst, blockerDelegate);
                visibilityMap[dst] = vis;

                // XXX Cheat a bit so that the floor will be visible
                if (vis && dst.Z == 0 && viewerLocation.Z > 1)
                {
                    visibilityMap[dst.SetZ(dst.Z - 1)] = true;
                }
            }
        }
Пример #5
0
        void UpdateNearList()
        {
            m_nearList.Clear();

            var eye     = m_camera.Position;
            var frustum = m_camera.Frustum;

            var farCorner = GetFrustumFarthestCorner(ref frustum);

            float camRadius = (farCorner - eye).Length();

            float chunkRadius = (float)Math.Sqrt(3) * Chunk.CHUNK_SIZE / 2;

            var viewGrid = m_viewGridProvider.ViewGrid;

            // XXX grid can be reduced to be inside camradius, but we need to somehow free the chunks that go outside near list
            //var grid = new IntGrid3(viewGrid.Corner1 / Chunk.CHUNK_SIZE, (viewGrid.Corner2 + Chunk.CHUNK_SIZE - 1) / Chunk.CHUNK_SIZE);
            var grid = this.Size;

            foreach (var cp in grid.Range())
            {
                var chunk = GetChunk(cp);

                IntVector3 chunkOffset = cp * Chunk.CHUNK_SIZE;

                var chunkGrid = new IntGrid3(chunkOffset, Chunk.ChunkSize);

                var containment = viewGrid.ContainsExclusive(ref chunkGrid);

                if (containment == Containment.Disjoint)
                {
                    // the chunk is outside the view area
                    if (chunk != null)
                    {
                        FreeChunk(chunk);
                    }
                    continue;
                }

                var chunkCenter = chunkOffset.ToVector3() + new Vector3(Chunk.CHUNK_SIZE / 2);

                if (Vector3.Distance(eye, chunkCenter) - chunkRadius > camRadius)
                {
                    if (chunk != null)
                    {
                        FreeChunk(chunk);
                    }
                    continue;
                }

                if (chunk == null)
                {
                    chunk = CreateChunk(cp);
                }

                m_nearList.Add(chunk);
            }

            m_forceDrawListUpdate = true;
        }
Пример #6
0
 static void SetArea(EnvironmentObject env, IntGrid3 area, TileData data)
 {
     foreach (var p in area.Range())
     {
         env.SetTileData(p, data);
     }
 }
Пример #7
0
        public FellTreeParallelJob(IEnvironmentObject env, IntGrid3 area)
            : base(null)
        {
            m_environment = env;
            m_area = area;

            AddNewJobs();
        }
Пример #8
0
        public FellTreeParallelJob(IEnvironmentObject env, IntGrid3 area)
            : base(null)
        {
            m_environment = env;
            m_area        = area;

            AddNewJobs();
        }
Пример #9
0
        IEnumerable <IntVector3> GetVisibleLocationsSimpleFOV()
        {
            var g = new IntGrid3(this.Location - this.VisionRange, this.Location + this.VisionRange);

            g = g.Intersect(new IntGrid3(this.Environment.Size));

            return(g.Range());
        }
Пример #10
0
        public void RemoveArea(IntGrid3 area)
        {
            var removes = m_map.Where(kvp => area.Contains(kvp.Key)).ToArray();

            foreach (var kvp in removes)
            {
                RemoveDesignation(kvp.Key);
            }
        }
Пример #11
0
        public Map(int width, int height, int depth)
        {
            this.Grid = new AStarMapTile[depth, height, width];

            this.Bounds = new IntGrid3(0, 0, 0, width, height, depth);

            for (int y = 0; y < 350; ++y)
            {
                SetBlocked(new IntVector3(5, y, 0), true);
            }

            for (int y = 2; y < 22; ++y)
            {
                SetBlocked(new IntVector3(14, y, 0), true);
            }

            for (int y = 6; y < 11; ++y)
            {
                SetWeight(new IntVector3(10, y, 0), 40);
            }


            for (int y = 6; y < 18; ++y)
            {
                SetBlocked(new IntVector3(3, y, 1), true);
            }

            for (int y = 6; y < 11; ++y)
            {
                SetWeight(new IntVector3(5, y, 1), 40);
            }


            SetStairs(new IntVector3(10, 10, 0), Stairs.Up);
            SetStairs(new IntVector3(10, 10, 1), Stairs.Down);

            SetStairs(new IntVector3(15, 12, 0), Stairs.Up);
            SetStairs(new IntVector3(15, 12, 1), Stairs.Down);

            var r      = new Random(4);
            var bounds = new IntGrid2Z(16, 0, 30, 30, 0);

            foreach (var p in bounds.Range())
            {
                var v = r.Next(100);
                if (v < 30)
                {
                    SetBlocked(p, true);
                }
                else if (v < 60)
                {
                    SetWeight(p, v);
                }
            }
        }
Пример #12
0
        void UpdateVertexBuffer()
        {
            if (m_env == null)
            {
                RemoveAndDispose(ref m_vertexBuffer);
                m_vertexList = null;
                return;
            }

            var envContents = m_env.Contents;

            if (m_vertexList != null && envContents.Count > m_vertexList.Count)
            {
                m_vertexList = null;
            }

            if (m_vertexList == null)
            {
                m_vertexList = new VertexList <SceneryVertex>(envContents.Count * 2);
            }

            IntGrid3 viewGrid = m_viewGridProvider.ViewGrid;

            m_vertexList.Clear();

            foreach (var ob in envContents.OfType <ConcreteObject>())
            {
                if (viewGrid.Contains(ob.Location) == false)
                {
                    continue;
                }

                var c = ob.Color;
                if (c == GameColor.None)
                {
                    c = ob.Material.Color;
                }

                m_vertexList.Add(new SceneryVertex(ob.Location.ToVector3(), ToColor(c), (uint)ob.SymbolID));
            }

            if (m_vertexList.Count > 0)
            {
                if (m_vertexBuffer == null || m_vertexBuffer.ElementCount < m_vertexList.Count)
                {
                    RemoveAndDispose(ref m_vertexBuffer);
                    m_vertexBuffer = ToDispose(SharpDX.Toolkit.Graphics.Buffer.Vertex.New <SceneryVertex>(this.GraphicsDevice, m_vertexList.Count));
                }

                m_vertexBuffer.SetData(m_vertexList.Data, 0, m_vertexList.Count);
            }
        }
Пример #13
0
        public Rect MapCubeToRenderPointRect(IntGrid3 grid)
        {
            var p1 = MapLocationToScreenTile(grid.Corner1);
            var p2 = MapLocationToScreenTile(grid.Corner2);

            var r = new Rect(p1, p2);
            r.Inflate(0.5, 0.5);

            p1 = ScreenToRenderPoint(r.TopLeft);
            p2 = ScreenToRenderPoint(r.BottomRight);

            return new Rect(p1, p2);
        }
Пример #14
0
 public MapSelection(IntGrid3 box)
     : this()
 {
     if (box.Columns == 0 || box.Rows == 0 || box.Depth == 0)
     {
         this.IsSelectionValid = false;
     }
     else
     {
         this.SelectionStart   = box.Corner1;
         this.SelectionEnd     = box.Corner2;
         this.IsSelectionValid = true;
     }
 }
Пример #15
0
        public Rect MapCubeToRenderPointRect(IntGrid3 grid)
        {
            var p1 = MapLocationToScreenTile(grid.Corner1);
            var p2 = MapLocationToScreenTile(grid.Corner2);

            var r = new Rect(p1, p2);

            r.Inflate(0.5, 0.5);

            p1 = ScreenToRenderPoint(r.TopLeft);
            p2 = ScreenToRenderPoint(r.BottomRight);

            return(new Rect(p1, p2));
        }
Пример #16
0
 public MapSelection(IntGrid3 box)
     : this()
 {
     if (box.Columns == 0 || box.Rows == 0 || box.Depth == 0)
     {
         this.IsSelectionValid = false;
     }
     else
     {
         this.SelectionStart = box.Corner1;
         this.SelectionEnd = box.Corner2;
         this.IsSelectionValid = true;
     }
 }
Пример #17
0
        void SendMapTiles(IPlayer player)
        {
            var visionTracker = player.GetVisionTracker(this);

            int w = this.Width;
            int h = this.Height;
            int d = this.Depth;

            var size = new IntSize3(w, h, 1);

            var arr = new ulong[w * h];

            for (int z = 0; z < d; ++z)
            {
                var bounds = new IntGrid3(new IntVector3(0, 0, z), size);

                Parallel.For(0, h, y =>
                {
                    for (int x = 0; x < w; ++x)
                    {
                        var p = new IntVector3(x, y, z);

                        ulong v;

                        if (!visionTracker.Sees(p))
                        {
                            v = 0;
                        }
                        else
                        {
                            v = GetTileData(p).Raw;
                        }

                        arr[y * w + x] = v;
                    }
                });

                var msg = new Messages.MapDataTerrainsMessage()
                {
                    Environment = this.ObjectID,
                    Bounds      = bounds,
                    TerrainData = arr,
                };

                player.Send(msg);
                //Trace.TraceError("Sent {0}", z);
            }
        }
Пример #18
0
        public void SetTarget(EnvironmentObject env, IntGrid3 box)
        {
            if (env == m_environment && m_box == box)
            {
                return;
            }

            if (env != m_environment)
            {
                if (m_environment != null)
                {
                    m_environment.MapTileTerrainChanged -= OnMapTerrainChanged;
                    m_environment.MapTileObjectChanged  -= OnMapObjectChanged;
                }

                m_environment = env;

                if (m_environment != null)
                {
                    m_environment.MapTileTerrainChanged += OnMapTerrainChanged;
                    m_environment.MapTileObjectChanged  += OnMapObjectChanged;
                }

                Notify("Environment");
                NotifyTileObjectChanges();
            }

            if (box != m_box)
            {
                var old = m_box;

                m_box = box;
                if (m_box.IsNull || m_environment == null)
                {
                    m_adjustedBox = m_box;
                }
                else
                {
                    m_adjustedBox = m_box.Intersect(new IntGrid3(m_environment.Size));
                }

                Notify("Box");
                NotifyTileObjectChanges(old, m_box);
            }

            NotifyTileTerrainChanges();
            Notify("IsNotEmpty");
        }
Пример #19
0
        public void SetTileDataRange(ulong[] tileData, IntGrid3 bounds)
        {
            int i = 0;

            for (int z = bounds.Z; z < bounds.Z + bounds.Depth; ++z)
            {
                for (int y = bounds.Y; y < bounds.Y + bounds.Rows; ++y)
                {
                    for (int x = bounds.X; x < bounds.X + bounds.Columns; ++x)
                    {
                        ulong v = tileData[i++];
                        m_grid[z, y, x].Raw = v;
                    }
                }
            }
        }
Пример #20
0
        public void SetTerrains(IntGrid3 bounds, ulong[] tileData)
        {
            this.Version += 1;

            m_tileGrid.Grow(bounds.Corner2);

            //Trace.TraceError("Recv {0}", bounds.Z);

            m_tileGrid.SetTileDataRange(tileData, bounds);

            if (this.MapTileTerrainChanged != null)
            {
                foreach (var p in bounds.Range())
                {
                    MapTileTerrainChanged(p);
                }
            }
        }
Пример #21
0
        static void CreateOreSphere(TerrainData terrain, Random random, IntVector3 center, int r, MaterialID oreMaterialID, double probIn, double probOut)
        {
            // adjust r, so that r == 1 gives sphere of one tile
            r -= 1;

            // XXX split the sphere into 8 parts, and mirror

            var bb = new IntGrid3(center.X - r, center.Y - r, center.Z - r, r * 2 + 1, r * 2 + 1, r * 2 + 1);

            var rs = MyMath.Square(r);

            foreach (var p in bb.Range())
            {
                var y = p.Y;
                var x = p.X;
                var z = p.Z;

                var v = MyMath.Square(x - center.X) + MyMath.Square(y - center.Y) + MyMath.Square(z - center.Z);

                if (rs >= v)
                {
                    var rr = Math.Sqrt(v);

                    double rel;

                    if (r == 0)
                    {
                        rel = 1;
                    }
                    else
                    {
                        rel = 1 - rr / r;
                    }

                    var prob = (probIn - probOut) * rel + probOut;

                    if (random.NextDouble() <= prob)
                    {
                        CreateOre(terrain, p, oreMaterialID);
                    }
                }
            }
        }
Пример #22
0
        void HandleVoxel(IntVector3 p, ref Voxel vox, ref IntGrid3 viewGrid, Direction visibleChunkFaces,
                         VertexList <TerrainVertex> vertexList)
        {
            // Faces that are visible due to viewgrid
            Direction sliceFaces = GetVoxelSliceDirections(p, ref viewGrid) & visibleChunkFaces;

            // Faces that are drawn (if there's something to draw)
            Direction visibleFaces = (vox.VisibleFaces | sliceFaces) & visibleChunkFaces;

            if (visibleFaces == 0)
            {
                return;
            }

            FaceTexture baseTexture, topTexture;

            GetTextures(p, ref vox, out baseTexture, out topTexture, sliceFaces);

            CreateCube(p, visibleFaces, ref baseTexture, ref topTexture, vertexList,
                       sliceFaces);
        }
Пример #23
0
        public void GenerateVertices(ref IntGrid3 viewGrid, IntVector3 cameraChunkPos,
                                     VertexList <TerrainVertex> terrainVertexList, VertexList <SceneryVertex> sceneryVertexList)
        {
            terrainVertexList.Clear();
            sceneryVertexList.Clear();

            var diff = cameraChunkPos - this.ChunkPosition;

            Direction visibleChunkFaces = 0;

            if (diff.X >= 0)
            {
                visibleChunkFaces |= Direction.PositiveX;
            }
            if (diff.X <= 0)
            {
                visibleChunkFaces |= Direction.NegativeX;
            }
            if (diff.Y >= 0)
            {
                visibleChunkFaces |= Direction.PositiveY;
            }
            if (diff.Y <= 0)
            {
                visibleChunkFaces |= Direction.NegativeY;
            }
            if (diff.Z >= 0)
            {
                visibleChunkFaces |= Direction.PositiveZ;
            }
            if (diff.Z <= 0)
            {
                visibleChunkFaces |= Direction.NegativeZ;
            }

            GenerateVertices(ref viewGrid, visibleChunkFaces, terrainVertexList, sceneryVertexList);

            this.VertexCount        = terrainVertexList.Count;
            this.SceneryVertexCount = sceneryVertexList.Count;
        }
Пример #24
0
        public void AddArea(IntGrid3 area, DesignationType type)
        {
            int origCount = m_map.Count;

            var locations = area.Range().Where(this.Environment.Contains);

            foreach (var p in locations)
            {
                if (GetTileValid(p, type) == false)
                {
                    continue;
                }

                DesignationData oldData;

                if (m_map.TryGetValue(p, out oldData))
                {
                    if (oldData.Type == type)
                    {
                        continue;
                    }

                    RemoveJob(p);
                }

                var data = new DesignationData(type);
                data.ReachableSimple = GetTileReachableSimple(p, type);
                m_map[p]             = data;

                this.Environment.OnTileExtraChanged(p);
            }

            if (origCount == 0 && m_map.Count > 0)
            {
                this.Environment.MapTileTerrainChanged += OnEnvironmentMapTileTerrainChanged;
                this.Environment.World.TickStarted     += OnTickStartEvent;
            }
        }
Пример #25
0
        void NotifyTileObjectChanges(IntGrid3 oldGrid, IntGrid3 newGrid)
        {
            if (m_environment == null)
            {
                m_objects.Clear();
                return;
            }

            var rm = oldGrid.Range().Except(newGrid.Range())
                     .SelectMany(p => m_environment.GetContents(p));

            foreach (var ob in rm)
            {
                m_objects.Remove(ob);
            }

            var add = newGrid.Range().Except(oldGrid.Range())
                      .SelectMany(p => m_environment.GetContents(p));

            foreach (var ob in add)
            {
                m_objects.Add(ob);
            }
        }
Пример #26
0
        public static bool PickVoxel(EnvironmentObject env, GameSurfaceView view, IntVector2 screenPos, IntGrid3 cropGrid,
                                     MapControlPickMode pickMode, out IntVector3 pos, out Direction face)
        {
            var camera = view.Camera;

            var ray = Ray.GetPickRay(screenPos.X, screenPos.Y, view.ViewPort, view.Camera.View * view.Camera.Projection);

            IntVector3 outpos = new IntVector3();
            Direction  outdir = Direction.None;

            var corner = cropGrid.Corner2;
            var size   = new IntSize3(corner.X + 1, corner.Y + 1, corner.Z + 1);

            IntVector3 prevoutpos = new IntVector3();
            Direction  prevoutdir = Direction.None;

            VoxelRayCast.RunRayCast(size, ray.Position, ray.Direction, view.Camera.FarZ,
                                    (x, y, z, dir) =>
            {
                var p = new IntVector3(x, y, z);

                if (cropGrid.Contains(p) == false)
                {
                    return(false);
                }

                var td = env.GetTileData(p);

                switch (pickMode)
                {
                case MapControlPickMode.Underground:
                    if (!td.IsUndefined && !td.IsWall)
                    {
                        return(false);
                    }

                    outpos = p;
                    outdir = dir;
                    return(true);

                case MapControlPickMode.AboveGround:
                    if (!td.IsUndefined && !td.IsWall)
                    {
                        prevoutpos = p;
                        prevoutdir = dir;
                        return(false);
                    }

                    if (prevoutpos.IsNull)
                    {
                        outpos = p;
                        outdir = dir;
                    }
                    else
                    {
                        outpos = prevoutpos;
                        outdir = prevoutdir;
                    }
                    return(true);

                case MapControlPickMode.Constant:
                    if (p.Z > cropGrid.Z2)
                    {
                        return(false);
                    }

                    outpos = p;
                    outdir = dir;
                    return(true);

                default:
                    throw new NotImplementedException();
                }
            });

            pos  = outpos;
            face = outdir;
            return(face != Direction.None);
        }
Пример #27
0
        void GenerateVertices(ref IntGrid3 viewGrid, Direction visibleChunkFaces,
			VertexList<TerrainVertex> terrainVertexList,
			VertexList<SceneryVertex> sceneryVertexList)
        {
            IntGrid3 chunkGrid = viewGrid.Intersect(new IntGrid3(this.ChunkOffset, Chunk.ChunkSize));

            // is the chunk inside frustum, but outside the viewgrid?
            if (chunkGrid.IsNull)
                return;

            if (m_scanned == false)
                ScanForAllEmptyOrUndefined();

            if (this.IsAllEmpty)
                return;

            if (this.IsAllUndefined)
            {
                CreateUndefinedChunk(ref viewGrid, ref chunkGrid, terrainVertexList, visibleChunkFaces);
                return;
            }

            if (m_voxelMap == null)
                FillVoxelMap();

            // Draw from up to down to avoid overdraw
            for (int z = chunkGrid.Z2; z >= chunkGrid.Z1; --z)
            {
                for (int y = chunkGrid.Y1; y <= chunkGrid.Y2; ++y)
                {
                    for (int x = chunkGrid.X1; x <= chunkGrid.X2; ++x)
                    {
                        var p = new IntVector3(x, y, z);

                        var td = m_map.GetTileData(p);

                        if (td.WaterLevel == 0)
                        {
                            if (td.IsEmpty)
                                continue;
                        }

                        var pos = p - this.ChunkOffset;

                        if (td.HasTree)
                        {
                            // Add tree as scenery vertex
                            HandleTree(sceneryVertexList, td, ref pos);
                            continue;
                        }

                        if (td.IsGreen) // XXX
                            continue;

                        var vox = m_voxelMap.Grid[pos.Z, pos.Y, pos.X];

                        HandleVoxel(p, ref vox, ref viewGrid, visibleChunkFaces, terrainVertexList);
                    }
                }
            }
        }
Пример #28
0
 public void RemoveArea(IntGrid3 area)
 {
     var removes = m_map.Where(kvp => area.Contains(kvp.Key)).ToArray();
     foreach (var kvp in removes)
         RemoveDesignation(kvp.Key);
 }
Пример #29
0
 public void SetContext(EnvironmentObject env, IntGrid3 area)
 {
     this.Environment = env;
     this.Area = area;
 }
Пример #30
0
        void ProcessRebuildList(IntVector3 cameraChunkPos)
        {
            if (m_rebuildList.Count == 0)
            {
                return;
            }

            var task = Task.Run(() =>
            {
                IntGrid3 viewGrid = m_viewGridProvider.ViewGrid;

                Parallel.ForEach(m_rebuildList, chunk =>
                {
                    var cacheItem = m_vertexCacheStack.Take();

                    chunk.GenerateVertices(ref viewGrid, cameraChunkPos, cacheItem.TerrainVertexList, cacheItem.SceneryVertexList);

                    if (chunk.VertexCount == 0 && chunk.SceneryVertexCount == 0)
                    {
                        // nothing more to do, mark as valid and add back to stack
                        chunk.IsValid = true;
                        m_vertexCacheStack.Return(cacheItem);
                    }
                    else
                    {
                        cacheItem.Chunk = chunk;
                        m_vertexCacheQueue.Add(cacheItem);
                    }
                });

                m_vertexCacheQueue.Add(null);
            });

            while (true)
            {
                var cacheItem = m_vertexCacheQueue.Take();

                if (cacheItem == null)
                {
                    break;
                }

                var chunk = cacheItem.Chunk;

                chunk.UpdateVertexBuffer(m_scene.GraphicsDevice, cacheItem.TerrainVertexList);
                chunk.UpdateSceneryVertexBuffer(m_scene.GraphicsDevice, cacheItem.SceneryVertexList);

                chunk.IsValid = true;

                cacheItem.Chunk = null;
                m_vertexCacheStack.Return(cacheItem);
            }

            task.Wait();
            task.Dispose();

            System.Diagnostics.Trace.Assert(m_vertexCacheStack.Count == VERTEX_CACHE_COUNT);
            System.Diagnostics.Trace.Assert(m_vertexCacheQueue.Count == 0);

            this.ChunkRecalcs = m_rebuildList.Count;

            m_rebuildList.Clear();
        }
Пример #31
0
 public HaulToAreaAssignment(IJobObserver parent, IEnvironmentObject environment, IntGrid3 destination, DirectionSet positioning, IItemObject hauledItem)
     : base(parent, environment, positioning, hauledItem)
 {
     m_dest = destination;
 }
Пример #32
0
        IEnumerable<IntVector3> GetVisibleLocationsSimpleFOV()
        {
            var g = new IntGrid3(this.Location - this.VisionRange, this.Location + this.VisionRange);
            g = g.Intersect(new IntGrid3(this.Environment.Size));

            return g.Range();
        }
Пример #33
0
        void CreateUndefinedChunk(ref IntGrid3 viewGrid, ref IntGrid3 chunkGrid, VertexList <TerrainVertex> vertexList,
                                  Direction visibleChunkFaces)
        {
            // Faces that are visible due to viewgrid
            Direction sliceFaces = GetGridSliceDirections(ref chunkGrid, ref viewGrid) & visibleChunkFaces;

            // Only faces revealed by viewgrid are visible
            Direction visibleFaces = sliceFaces;

            if (visibleFaces == 0)
            {
                return;
            }

            int sides = (int)visibleFaces;

            FaceTexture tex = Chunk.UndefinedFaceTexture;

            const int occlusion = 0;
            var       offset    = chunkGrid.Corner1 - this.ChunkOffset;
            var       size      = new IntVector3(chunkGrid.Size.Width, chunkGrid.Size.Height, chunkGrid.Size.Depth);

            // All faces are revealed by viewgrid
            byte sliceHack = (byte)1;

            if (Chunk.UseBigUnknownChunk)
            {
                /* Note: Using chunk sized quads causes t-junction problems */

                for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1)
                {
                    if ((sides & 1) == 0)
                    {
                        continue;
                    }

                    var vertices = s_cubeFaceInfo[side].Vertices;

                    IntVector3 v0 = vertices[0] * size + offset;
                    IntVector3 v1 = vertices[1] * size + offset;
                    IntVector3 v2 = vertices[2] * size + offset;
                    IntVector3 v3 = vertices[3] * size + offset;

                    var vd = new TerrainVertex(v0, v1, v2, v3, occlusion, occlusion, occlusion, occlusion, tex, sliceHack);
                    vertexList.Add(vd);
                }
            }
            else
            {
                for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1)
                {
                    if ((sides & 1) == 0)
                    {
                        continue;
                    }

                    int d0 = side / 2;
                    int d1 = (d0 + 1) % 3;
                    int d2 = (d0 + 2) % 3;

                    bool posFace = (side & 1) == 1;

                    var vertices = s_cubeFaceInfo[side].Vertices;

                    IntVector3 v0 = vertices[0] + offset;
                    IntVector3 v1 = vertices[1] + offset;
                    IntVector3 v2 = vertices[2] + offset;
                    IntVector3 v3 = vertices[3] + offset;

                    var vec1 = new IntVector3();
                    vec1[d1] = 1;

                    var vec2 = new IntVector3();
                    vec2[d2] = 1;

                    for (int v = 0; v < size[d1]; ++v)
                    {
                        for (int u = 0; u < size[d2]; ++u)
                        {
                            var off = vec1 * v + vec2 * u;
                            if (posFace)
                            {
                                off[d0] = size[d0] - 1;
                            }

                            var vd = new TerrainVertex(v0 + off, v1 + off, v2 + off, v3 + off,
                                                       occlusion, occlusion, occlusion, occlusion, tex, sliceHack);
                            vertexList.Add(vd);
                        }
                    }
                }
            }
        }
Пример #34
0
 public MoveToAreaAssignment(IJobObserver parent, IEnvironmentObject environment, IntGrid3 destination, DirectionSet positioning)
     : base(parent, environment, positioning)
 {
     m_dest = destination;
 }
Пример #35
0
        void HandleVoxel(IntVector3 p, ref Voxel vox, ref IntGrid3 viewGrid, Direction visibleChunkFaces,
			VertexList<TerrainVertex> vertexList)
        {
            // Faces that are visible due to viewgrid
            Direction sliceFaces = GetVoxelSliceDirections(p, ref viewGrid) & visibleChunkFaces;

            // Faces that are drawn (if there's something to draw)
            Direction visibleFaces = (vox.VisibleFaces | sliceFaces) & visibleChunkFaces;

            if (visibleFaces == 0)
                return;

            FaceTexture baseTexture, topTexture;

            GetTextures(p, ref vox, out baseTexture, out topTexture, sliceFaces);

            CreateCube(p, visibleFaces, ref baseTexture, ref topTexture, vertexList,
                sliceFaces);
        }
Пример #36
0
        void UpdateNearList()
        {
            m_nearList.Clear();

            var eye = m_camera.Position;
            var frustum = m_camera.Frustum;

            var farCorner = GetFrustumFarthestCorner(ref frustum);

            float camRadius = (farCorner - eye).Length();

            float chunkRadius = (float)Math.Sqrt(3) * Chunk.CHUNK_SIZE / 2;

            var viewGrid = m_viewGridProvider.ViewGrid;

            // XXX grid can be reduced to be inside camradius, but we need to somehow free the chunks that go outside near list
            //var grid = new IntGrid3(viewGrid.Corner1 / Chunk.CHUNK_SIZE, (viewGrid.Corner2 + Chunk.CHUNK_SIZE - 1) / Chunk.CHUNK_SIZE);
            var grid = this.Size;

            foreach (var cp in grid.Range())
            {
                var chunk = GetChunk(cp);

                IntVector3 chunkOffset = cp * Chunk.CHUNK_SIZE;

                var chunkGrid = new IntGrid3(chunkOffset, Chunk.ChunkSize);

                var containment = viewGrid.ContainsExclusive(ref chunkGrid);

                if (containment == Containment.Disjoint)
                {
                    // the chunk is outside the view area
                    if (chunk != null)
                        FreeChunk(chunk);
                    continue;
                }

                var chunkCenter = chunkOffset.ToVector3() + new Vector3(Chunk.CHUNK_SIZE / 2);

                if (Vector3.Distance(eye, chunkCenter) - chunkRadius > camRadius)
                {
                    if (chunk != null)
                        FreeChunk(chunk);
                    continue;
                }

                if (chunk == null)
                    chunk = CreateChunk(cp);

                m_nearList.Add(chunk);
            }

            m_forceDrawListUpdate = true;
        }
Пример #37
0
        public static bool PickVoxel(EnvironmentObject env, GameSurfaceView view, IntVector2 screenPos, IntGrid3 cropGrid,
			MapControlPickMode pickMode, out IntVector3 pos, out Direction face)
        {
            var camera = view.Camera;

            var ray = Ray.GetPickRay(screenPos.X, screenPos.Y, view.ViewPort, view.Camera.View * view.Camera.Projection);

            IntVector3 outpos = new IntVector3();
            Direction outdir = Direction.None;

            var corner = cropGrid.Corner2;
            var size = new IntSize3(corner.X + 1, corner.Y + 1, corner.Z + 1);

            IntVector3 prevoutpos = new IntVector3();
            Direction prevoutdir = Direction.None;

            VoxelRayCast.RunRayCast(size, ray.Position, ray.Direction, view.Camera.FarZ,
                (x, y, z, dir) =>
                {
                    var p = new IntVector3(x, y, z);

                    if (cropGrid.Contains(p) == false)
                        return false;

                    var td = env.GetTileData(p);

                    switch (pickMode)
                    {
                        case MapControlPickMode.Underground:
                            if (!td.IsUndefined && !td.IsWall)
                                return false;

                            outpos = p;
                            outdir = dir;
                            return true;

                        case MapControlPickMode.AboveGround:
                            if (!td.IsUndefined && !td.IsWall)
                            {
                                prevoutpos = p;
                                prevoutdir = dir;
                                return false;
                            }

                            if (prevoutpos.IsNull)
                            {
                                outpos = p;
                                outdir = dir;
                            }
                            else
                            {
                                outpos = prevoutpos;
                                outdir = prevoutdir;
                            }
                            return true;

                        case MapControlPickMode.Constant:
                            if (p.Z > cropGrid.Z2)
                                return false;

                            outpos = p;
                            outdir = dir;
                            return true;

                        default:
                            throw new NotImplementedException();
                    }
                });

            pos = outpos;
            face = outdir;
            return face != Direction.None;
        }
Пример #38
0
 public AStarAreaTarget(IEnvironmentObject env, IntGrid3 destination)
     : base(env)
 {
     m_destination = destination;
 }
Пример #39
0
        /// <summary>
        /// Directions of faces which are revealed due to ViewGrid
        /// </summary>
        Direction GetGridSliceDirections(ref IntGrid3 grid, ref IntGrid3 viewGrid)
        {
            Direction d = 0;

            // Note: we never draw the bottommost layer in the map, so we don't check for Z1

            if (grid.Z2 == viewGrid.Z2)
                d |= Direction.Up;

            if (grid.X1 == viewGrid.X1)
                d |= Direction.West;

            if (grid.X2 == viewGrid.X2)
                d |= Direction.East;

            if (grid.Y1 == viewGrid.Y1)
                d |= Direction.North;

            if (grid.Y2 == viewGrid.Y2)
                d |= Direction.South;

            return d;
        }
Пример #40
0
 public void Add(IntGrid3 box)
 {
     m_boxs.Add(box);
 }
Пример #41
0
        /// <summary>
        /// Directions of faces which are revealed due to ViewGrid
        /// </summary>
        Direction GetVoxelSliceDirections(IntVector3 p, ref IntGrid3 viewGrid)
        {
            Direction d = 0;

            // Note: we never draw the bottommost layer in the map, so we don't check for Z1

            if (p.Z == viewGrid.Z2)
                d |= Direction.Up;

            if (p.X == viewGrid.X1)
                d |= Direction.West;

            if (p.X == viewGrid.X2)
                d |= Direction.East;

            if (p.Y == viewGrid.Y1)
                d |= Direction.North;

            if (p.Y == viewGrid.Y2)
                d |= Direction.South;

            return d;
        }
Пример #42
0
        void GenerateVertices(ref IntGrid3 viewGrid, Direction visibleChunkFaces,
                              VertexList <TerrainVertex> terrainVertexList,
                              VertexList <SceneryVertex> sceneryVertexList)
        {
            IntGrid3 chunkGrid = viewGrid.Intersect(new IntGrid3(this.ChunkOffset, Chunk.ChunkSize));

            // is the chunk inside frustum, but outside the viewgrid?
            if (chunkGrid.IsNull)
            {
                return;
            }

            if (m_scanned == false)
            {
                ScanForAllEmptyOrUndefined();
            }

            if (this.IsAllEmpty)
            {
                return;
            }

            if (this.IsAllUndefined)
            {
                CreateUndefinedChunk(ref viewGrid, ref chunkGrid, terrainVertexList, visibleChunkFaces);
                return;
            }

            if (m_voxelMap == null)
            {
                FillVoxelMap();
            }

            // Draw from up to down to avoid overdraw
            for (int z = chunkGrid.Z2; z >= chunkGrid.Z1; --z)
            {
                for (int y = chunkGrid.Y1; y <= chunkGrid.Y2; ++y)
                {
                    for (int x = chunkGrid.X1; x <= chunkGrid.X2; ++x)
                    {
                        var p = new IntVector3(x, y, z);

                        var td = m_map.GetTileData(p);

                        if (td.WaterLevel == 0)
                        {
                            if (td.IsEmpty)
                            {
                                continue;
                            }
                        }

                        var pos = p - this.ChunkOffset;

                        if (td.HasTree)
                        {
                            // Add tree as scenery vertex
                            HandleTree(sceneryVertexList, td, ref pos);
                            continue;
                        }

                        if (td.IsGreen)                         // XXX
                        {
                            continue;
                        }

                        var vox = m_voxelMap.Grid[pos.Z, pos.Y, pos.X];

                        HandleVoxel(p, ref vox, ref viewGrid, visibleChunkFaces, terrainVertexList);
                    }
                }
            }
        }
Пример #43
0
 public void SetContext(EnvironmentObject env, IntGrid3 area)
 {
     this.Environment = env;
     this.Area        = area;
 }
Пример #44
0
        void NotifyTileObjectChanges(IntGrid3 oldGrid, IntGrid3 newGrid)
        {
            if (this.Environment == null)
            {
                m_objects.Clear();
                return;
            }

            var rm = oldGrid.Range().Except(newGrid.Range())
                .SelectMany(p => this.Environment.GetContents(p));

            foreach (var ob in rm)
                m_objects.Remove(ob);

            var add = newGrid.Range().Except(oldGrid.Range())
                .SelectMany(p => this.Environment.GetContents(p));

            foreach (var ob in add)
                m_objects.Add(ob);
        }
Пример #45
0
        /// <summary>
        /// Find route from src to destination area
        /// </summary>
        public static AStarResult FindArea(IEnvironmentObject env, IntVector3 src, DirectionSet srcPositioning, IntGrid3 dstArea,
			int maxNodeCount = 200000, CancellationToken? cancellationToken = null)
        {
            var initLocs = env.GetPositioningLocations(src, srcPositioning);
            var target = new AStarAreaTarget(env, dstArea);
            return Find(initLocs, target, maxNodeCount, cancellationToken);
        }
Пример #46
0
        void ReadAndSetTileData(Stream stream, IntGrid3 bounds)
        {
            using (var reader = new BinaryReader(stream))
            {
                TileData td = new TileData();

                foreach (IntPoint3 p in bounds.Range())
                {
                    td.Raw = reader.ReadUInt64();

                    m_tileGrid.SetTileData(p, td);

                    if (MapTileTerrainChanged != null)
                        MapTileTerrainChanged(p);
                }
            }
        }
Пример #47
0
 public void Remove(IntGrid3 box)
 {
     m_boxs.Remove(box);
 }
Пример #48
0
        public void SetTileDataRange(ulong[] tileData, IntGrid3 bounds)
        {
            int i = 0;

            for (int z = bounds.Z; z < bounds.Z + bounds.Depth; ++z)
                for (int y = bounds.Y; y < bounds.Y + bounds.Rows; ++y)
                    for (int x = bounds.X; x < bounds.X + bounds.Columns; ++x)
                    {
                        ulong v = tileData[i++];
                        m_grid[z, y, x].Raw = v;
                    }
        }
Пример #49
0
 public MoveToAreaAssignment(IJobObserver parent, IEnvironmentObject environment, IntGrid3 destination, DirectionSet positioning)
     : base(parent, environment, positioning)
 {
     m_dest = destination;
 }
Пример #50
0
        public static void SendSetTerrains(SetTerrainDialog dialog, EnvironmentObject env, IntGrid3 cube)
        {
            var data = dialog.Data;

            var args = new Dictionary<string, object>()
            {
                { "envID", env.ObjectID },
                { "cube", cube },
                { "terrainID", data.TerrainID },
                { "terrainMaterialID", data.TerrainMaterialID },
                { "interiorID", data.InteriorID },
                { "interiorMaterialID", data.InteriorMaterialID },
                { "waterLevel", data.Water.HasValue ? (data.Water == true ? (byte?)TileData.MaxWaterLevel : (byte?)0) : null },
            };

            var script =
            @"env = world.GetObject(envID)
            for p in cube.Range():
            td = env.GetTileData(p)

            if terrainID != None:
            Dwarrowdelf.TileData.TerrainID.SetValue(td, terrainID)
            if terrainMaterialID != None:
            Dwarrowdelf.TileData.TerrainMaterialID.SetValue(td, terrainMaterialID)

            if interiorID != None:
            Dwarrowdelf.TileData.InteriorID.SetValue(td, interiorID)
            if interiorMaterialID != None:
            Dwarrowdelf.TileData.InteriorMaterialID.SetValue(td, interiorMaterialID)

            if waterLevel != None:
            Dwarrowdelf.TileData.WaterLevel.SetValue(td, waterLevel)

            env.SetTileData(p, td)

            env.ScanWaterTiles()
            ";
            var msg = new Dwarrowdelf.Messages.IPScriptMessage(script, args);

            GameData.Data.User.Send(msg);
        }
Пример #51
0
 static void SetArea(EnvironmentObject env, IntGrid3 area, TileData data)
 {
     foreach (var p in area.Range())
         env.SetTileData(p, data);
 }
Пример #52
0
        public void SetTerrains(IntGrid3 bounds, byte[] tileDataList, bool isCompressed)
        {
            this.Version += 1;

            m_tileGrid.Grow(bounds.Corner2);

            //Trace.TraceError("Recv {0}", bounds.Z);

            #if !parallel
            using (var memStream = new MemoryStream(tileDataList))
            {
                if (isCompressed == false)
                {
                    ReadAndSetTileData(memStream, bounds);
                }
                else
                {
                    using (var decompressStream = new DeflateStream(memStream, CompressionMode.Decompress))
                        ReadAndSetTileData(decompressStream, bounds);
                }
            }
            #else
            Task.Factory.StartNew(() =>
            {
                var dstStream = new MemoryStream();

                using (var memStream = new MemoryStream(tileDataList))
                using (var decompressStream = new DeflateStream(memStream, CompressionMode.Decompress))
                    decompressStream.CopyTo(dstStream);

                dstStream.Position = 0;
                return dstStream;
            }).ContinueWith(t =>
            {
                using (var stream = t.Result)
                    ReadAndSetTileData(stream, bounds);

                //Trace.TraceError("done {0}", bounds.Z);

            }, TaskScheduler.FromCurrentSynchronizationContext());

            #endif
        }
Пример #53
0
        public void SetTerrains(IntGrid3 bounds, ulong[] tileData)
        {
            this.Version += 1;

            m_tileGrid.Grow(bounds.Corner2);

            //Trace.TraceError("Recv {0}", bounds.Z);

            m_tileGrid.SetTileDataRange(tileData, bounds);

            if (this.MapTileTerrainChanged != null)
            {
                foreach (var p in bounds.Range())
                    MapTileTerrainChanged(p);
            }
        }
Пример #54
0
        void CreateUndefinedChunk(ref IntGrid3 viewGrid, ref IntGrid3 chunkGrid, VertexList<TerrainVertex> vertexList,
			Direction visibleChunkFaces)
        {
            // Faces that are visible due to viewgrid
            Direction sliceFaces = GetGridSliceDirections(ref chunkGrid, ref viewGrid) & visibleChunkFaces;

            // Only faces revealed by viewgrid are visible
            Direction visibleFaces = sliceFaces;

            if (visibleFaces == 0)
                return;

            int sides = (int)visibleFaces;

            FaceTexture tex = Chunk.UndefinedFaceTexture;

            const int occlusion = 0;
            var offset = chunkGrid.Corner1 - this.ChunkOffset;
            var size = new IntVector3(chunkGrid.Size.Width, chunkGrid.Size.Height, chunkGrid.Size.Depth);

            // All faces are revealed by viewgrid
            byte sliceHack = (byte)1;

            if (Chunk.UseBigUnknownChunk)
            {
                /* Note: Using chunk sized quads causes t-junction problems */

                for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1)
                {
                    if ((sides & 1) == 0)
                        continue;

                    var vertices = s_cubeFaceInfo[side].Vertices;

                    IntVector3 v0 = vertices[0] * size + offset;
                    IntVector3 v1 = vertices[1] * size + offset;
                    IntVector3 v2 = vertices[2] * size + offset;
                    IntVector3 v3 = vertices[3] * size + offset;

                    var vd = new TerrainVertex(v0, v1, v2, v3, occlusion, occlusion, occlusion, occlusion, tex, sliceHack);
                    vertexList.Add(vd);
                }
            }
            else
            {
                for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1)
                {
                    if ((sides & 1) == 0)
                        continue;

                    int d0 = side / 2;
                    int d1 = (d0 + 1) % 3;
                    int d2 = (d0 + 2) % 3;

                    bool posFace = (side & 1) == 1;

                    var vertices = s_cubeFaceInfo[side].Vertices;

                    IntVector3 v0 = vertices[0] + offset;
                    IntVector3 v1 = vertices[1] + offset;
                    IntVector3 v2 = vertices[2] + offset;
                    IntVector3 v3 = vertices[3] + offset;

                    var vec1 = new IntVector3();
                    vec1[d1] = 1;

                    var vec2 = new IntVector3();
                    vec2[d2] = 1;

                    for (int v = 0; v < size[d1]; ++v)
                        for (int u = 0; u < size[d2]; ++u)
                        {
                            var off = vec1 * v + vec2 * u;
                            if (posFace)
                                off[d0] = size[d0] - 1;

                            var vd = new TerrainVertex(v0 + off, v1 + off, v2 + off, v3 + off,
                                occlusion, occlusion, occlusion, occlusion, tex, sliceHack);
                            vertexList.Add(vd);
                        }
                }
            }
        }
Пример #55
0
        public static void SendSetTerrains(SetTerrainDialog dialog, EnvironmentObject env, IntGrid3 cube)
        {
            var data = dialog.Data;

            var args = new Dictionary <string, object>()
            {
                { "envID", env.ObjectID },
                { "cube", cube },
                { "tileID", data.TileID },
                { "materialID", data.MaterialID },
                { "waterLevel", data.Water.HasValue ? (data.Water == true ? (byte?)TileData.MaxWaterLevel : (byte?)0) : null },
            };

            var script =
                @"env = world.GetObject(envID)
for p in cube.Range():
	td = env.GetTileData(p)

	if tileID != None:
		Dwarrowdelf.TileData.ID.SetValue(td, tileID)
	if materialID != None:
		Dwarrowdelf.TileData.MaterialID.SetValue(td, materialID)

	if waterLevel != None:
		Dwarrowdelf.TileData.WaterLevel.SetValue(td, waterLevel)

	env.SetTileData(p, td)

env.ScanWaterTiles()
";
            var msg = new Dwarrowdelf.Messages.IPScriptMessage(script, args);

            GameData.Data.User.Send(msg);
        }
Пример #56
0
 public HaulToAreaAssignment(IJobObserver parent, IEnvironmentObject environment, IntGrid3 destination, DirectionSet positioning, IItemObject hauledItem)
     : base(parent, environment, positioning, hauledItem)
 {
     m_dest = destination;
 }
Пример #57
0
        public void GenerateVertices(ref IntGrid3 viewGrid, IntVector3 cameraChunkPos,
			VertexList<TerrainVertex> terrainVertexList, VertexList<SceneryVertex> sceneryVertexList)
        {
            terrainVertexList.Clear();
            sceneryVertexList.Clear();

            var diff = cameraChunkPos - this.ChunkPosition;

            Direction visibleChunkFaces = 0;
            if (diff.X >= 0)
                visibleChunkFaces |= Direction.PositiveX;
            if (diff.X <= 0)
                visibleChunkFaces |= Direction.NegativeX;
            if (diff.Y >= 0)
                visibleChunkFaces |= Direction.PositiveY;
            if (diff.Y <= 0)
                visibleChunkFaces |= Direction.NegativeY;
            if (diff.Z >= 0)
                visibleChunkFaces |= Direction.PositiveZ;
            if (diff.Z <= 0)
                visibleChunkFaces |= Direction.NegativeZ;

            GenerateVertices(ref viewGrid, visibleChunkFaces, terrainVertexList, sceneryVertexList);

            this.VertexCount = terrainVertexList.Count;
            this.SceneryVertexCount = sceneryVertexList.Count;
        }
Пример #58
0
        void CreateOreSphere(IntPoint3 center, int r, MaterialID oreMaterialID, double probIn, double probOut)
        {
            // adjust r, so that r == 1 gives sphere of one tile
            r -= 1;

            // XXX split the sphere into 8 parts, and mirror

            var bb = new IntGrid3(center.X - r, center.Y - r, center.Z - r, r * 2 + 1, r * 2 + 1, r * 2 + 1);

            var rs = MyMath.Square(r);

            foreach (var p in bb.Range())
            {
                var y = p.Y;
                var x = p.X;
                var z = p.Z;

                var v = MyMath.Square(x - center.X) + MyMath.Square(y - center.Y) + MyMath.Square(z - center.Z);

                if (rs >= v)
                {
                    var rr = Math.Sqrt(v);

                    double rel;

                    if (r == 0)
                        rel = 1;
                    else
                        rel = 1 - rr / r;

                    var prob = (probIn - probOut) * rel + probOut;

                    if (GetRandomDouble() <= prob)
                        CreateOre(p, oreMaterialID);
                }
            }
        }