コード例 #1
0
    public void RemoveFromWorld()
    {
        _placedInWorld = false;
        int colWidth  = mWidth * 2;
        int colLength = mLength * 2;

        for (int iX = 0; iX < colWidth; ++iX)
        {
            for (int iY = 0; iY < colLength; ++iY)
            {
                IntVec2        worldTile = GetWorldCollisionTile(iX, iY, mPosition, mItemRot);
                CCollisionTile tile      = mWorld.mMap.mGlobalCollisionTiles[worldTile.X, worldTile.Y];

                tile.mOccupied = 0;
                tile.mSolid    = false;
            }
        }

        for (int iX = 0; iX < mWidth; ++iX)
        {
            for (int iY = 0; iY < mLength; ++iY)
            {
                Vector2 worldPoint = RotationAxisTable[mItemRot].Transform(new Vector2(iX, iY));
                int     worldX     = (int)worldPoint.x + mX;
                int     worldY     = (int)worldPoint.y + mY;
                CTile   worldTile  = mWorld.mMap.mTiles[worldX, worldY];

                worldTile.mItem = -1;
            }
        }

        mWorld.RebuildInfluenceMap();
    }
コード例 #2
0
    public virtual void PlaceInWorld()
    {
        mBluerprint    = false;
        _placedInWorld = true;
        mBounds        = CalculateBounds(mPosition, mItemRot, mWidth, mLength);
        int colWidth  = mWidth * 2;
        int colLength = mLength * 2;

        for (int iX = 0; iX < colWidth; ++iX)
        {
            for (int iY = 0; iY < colLength; ++iY)
            {
                IntVec2        worldTile = GetWorldCollisionTile(iX, iY, mPosition, mItemRot);
                CCollisionTile tile      = mWorld.mMap.mGlobalCollisionTiles[worldTile.X, worldTile.Y];

                tile.mOccupied = -1;
                tile.mSolid    = mAsset.mTiles[iX, iY].mSolid;
            }
        }

        for (int iX = 0; iX < mWidth; ++iX)
        {
            for (int iY = 0; iY < mLength; ++iY)
            {
                Vector2 worldPoint = RotationAxisTable[mItemRot].Transform(new Vector2(iX, iY));
                int     worldX     = (int)worldPoint.x + mX;
                int     worldY     = (int)worldPoint.y + mY;
                CTile   worldTile  = mWorld.mMap.mTiles[worldX, worldY];

                worldTile.mItem = mID;
            }
        }

        mWorld.RebuildInfluenceMap();
    }
コード例 #3
0
    public void ModifyLocalCollisionMap(bool Active)
    {
        for (int iX = 0; iX < mAsset.mWidth * 2; ++iX)
        {
            for (int iY = 0; iY < mAsset.mLength * 2; ++iY)
            {
                IntVec2        worldTile = CItem.GetWorldCollisionTile(iX, iY, mPosition, mRotation);
                CCollisionTile tile      = mWorld.mMap.mLocalCollisionTiles[mPlayerID][worldTile.X, worldTile.Y];

                if (Active)
                {
                    tile.mOccupied = mID;
                    tile.mSolid    = mAsset.mTiles[iX, iY].mSolid;
                }
                else
                {
                    tile.mOccupied = 0;
                    tile.mSolid    = false;
                }
            }
        }

        Rect mr = new Rect(mBounds.min.x * 2.0f, mBounds.min.z * 2.0f, mBounds.size.x * 2.0f, mBounds.size.z * 2.0f);

        mWorld.mMap.CollisionModified(mPlayerID, mr);
    }
コード例 #4
0
    public void Generate(CMap Map, int PlayerId)
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        mRects.Clear();
        mEdges.Clear();
        mPortals.Clear();

        Array.Clear(mRectLookup, 0, mRectLookup.Length);

        for (int i = 0; i < Map.mWidth * 2 + 1; ++i)
        {
            mXAxisEdges[i].Clear();
            mYAxisEdges[i].Clear();
        }

        for (int iX = 0; iX < 7; ++iX)
        {
            for (int iY = 0; iY < 7; ++iY)
            {
                mBuckets[iX, iY].Clear();
            }
        }

        CCollisionTile[,] tileMap = Map.mLocalCollisionTiles[PlayerId];

        double setupTime = sw.Elapsed.TotalMilliseconds;

        // Touch all cells and expand rects
        for (int iY = 0; iY < Map.mWidth * 2; ++iY)
        {
            for (int iX = 0; iX < Map.mWidth * 2; ++iX)
            {
                CCollisionTile tile = tileMap[iX, iY];

                if (mRectLookup[iX, iY] == null && tile.mOccupied >= 0)
                {
                    bool expandX = true;
                    bool expandY = true;
                    int  sizeX   = 1;
                    int  sizeY   = 1;
                    //int type = tile.mOccupied + 10000 * (tile.mSolid ? 1 : 0);
                    int type = (tile.mOccupied + 10000) * (tile.mSolid ? 1 : 0);

                    while (expandX || expandY)
                    {
                        // Check expansion in X
                        if (expandX)
                        {
                            expandX = _CanExpandX(mRectLookup, tileMap, iX + sizeX - 1, iY, sizeY, type);
                        }

                        // Check expansion in Y
                        if (expandY)
                        {
                            expandY = _CanExpandY(mRectLookup, tileMap, iX, iY + sizeY - 1, sizeX, type);
                        }

                        // Check corner expansion if we do both
                        if (expandX && expandY)
                        {
                            // If we fail here, then prefer expand X.
                            if (mRectLookup[iX + sizeX, iY + sizeY] != null ||
                                //tileMap[iX + sizeX, iY + sizeY].mOccupied + 10000 * (tileMap[iX + sizeX, iY + sizeY].mSolid ? 1 : 0) != type ||
                                (tileMap[iX + sizeX, iY + sizeY].mOccupied + 10000) * (tileMap[iX + sizeX, iY + sizeY].mSolid ? 1 : 0) != type ||
                                tileMap[iX + sizeX, iY + sizeY].mWallXSolid ||
                                tileMap[iX + sizeX, iY + sizeY].mWallZSolid)
                            {
                                expandY = false;
                            }
                        }

                        if ((iX + sizeX) % 32 == 0)
                        {
                            expandX = false;
                        }
                        if ((iY + sizeY) % 32 == 0)
                        {
                            expandY = false;
                        }

                        if (expandX)
                        {
                            ++sizeX;
                        }
                        if (expandY)
                        {
                            ++sizeY;
                        }
                    }

                    // Add nav rect.
                    CNavRect r = new CNavRect();
                    r.mIndex  = mRects.Count;
                    r.mRect   = new Rect(iX, iY, sizeX, sizeY);
                    r.mFlags  = type;
                    r.mRoomId = -1;
                    mRects.Add(r);
                    mBuckets[iX / 32, iY / 32].Add(r);

                    // Clear expanded area
                    for (int jX = iX; jX < iX + sizeX; ++jX)
                    {
                        for (int jY = iY; jY < iY + sizeY; ++jY)
                        {
                            mRectLookup[jX, jY] = r;
                        }
                    }
                }
            }
        }

        double expansionTime = sw.Elapsed.TotalMilliseconds;

        // Go through each rect and determine accesible edges.
        for (int i = 0; i < mRects.Count; ++i)
        {
            Rect r = mRects[i].mRect;

            //-----------------------------------------------------------------------------
            // Bottom X
            //-----------------------------------------------------------------------------
            int start = (int)r.xMin;
            int run   = 0;
            int y     = (int)r.y;
            int x     = (int)r.x;

            for (int j = start; j < (int)r.xMax; ++j)
            {
                if (tileMap[j, y].mWallXSolid)
                {
                    if (run != 0)
                    {
                        // Add run to this point
                        CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                        mEdges.Add(e);
                        mXAxisEdges[y].Add(e);
                        run = 0;
                    }

                    start = j + 1;
                }
                else
                {
                    if (run != 0 && tileMap[j, y - 1].mWallZSolid)
                    {
                        // Add run to this point and start with 1 already in run
                        CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                        mEdges.Add(e);
                        mXAxisEdges[y].Add(e);

                        start = j;
                        run   = 0;
                    }

                    ++run;
                }
            }

            // Add final non-blocked edge.
            if (run != 0)
            {
                CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                mEdges.Add(e);
                mXAxisEdges[y].Add(e);
            }

            //-----------------------------------------------------------------------------
            // Top X
            //-----------------------------------------------------------------------------
            start = (int)r.xMin;
            run   = 0;
            y     = (int)r.yMax;
            x     = (int)r.x;

            for (int j = start; j < (int)r.xMax; ++j)
            {
                if (tileMap[j, y].mWallXSolid)
                {
                    if (run != 0)
                    {
                        // Add run to this point
                        CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                        mEdges.Add(e);
                        mXAxisEdges[y].Add(e);

                        run = 0;
                    }

                    start = j + 1;
                }
                else
                {
                    if (run != 0 && tileMap[j, y].mWallZSolid)
                    {
                        // Add run to this point and start with 1 already in run
                        CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                        mEdges.Add(e);
                        mXAxisEdges[y].Add(e);

                        start = j;
                        run   = 0;
                    }

                    ++run;
                }
            }

            // Add final non-blocked edge.
            if (run != 0)
            {
                CNavRectEdge e = new CNavRectEdge(new Vector2(start, y), new Vector2(start + run, y), mRects[i]);
                mEdges.Add(e);
                mXAxisEdges[y].Add(e);
            }

            //-----------------------------------------------------------------------------
            // Left Y
            //-----------------------------------------------------------------------------
            start = (int)r.yMin;
            run   = 0;
            y     = (int)r.y;
            x     = (int)r.x;

            for (int j = start; j < (int)r.yMax; ++j)
            {
                if (tileMap[x, j].mWallZSolid)
                {
                    if (run != 0)
                    {
                        // Add run to this point
                        CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                        mEdges.Add(e);
                        mYAxisEdges[x].Add(e);

                        run = 0;
                    }

                    start = j + 1;
                }
                else
                {
                    if (run != 0 && tileMap[x - 1, j].mWallXSolid)
                    {
                        // Add run to this point and start with 1 already in run
                        CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                        mEdges.Add(e);
                        mYAxisEdges[x].Add(e);

                        start = j;
                        run   = 0;
                    }

                    ++run;
                }
            }

            // Add final non-blocked edge.
            if (run != 0)
            {
                CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                mEdges.Add(e);
                mYAxisEdges[x].Add(e);
            }

            //-----------------------------------------------------------------------------
            // Right Y
            //-----------------------------------------------------------------------------
            start = (int)r.yMin;
            run   = 0;
            y     = (int)r.y;
            x     = (int)r.xMax;

            for (int j = start; j < (int)r.yMax; ++j)
            {
                if (tileMap[x, j].mWallZSolid)
                {
                    if (run != 0)
                    {
                        // Add run to this point
                        CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                        mEdges.Add(e);
                        mYAxisEdges[x].Add(e);

                        run = 0;
                    }

                    start = j + 1;
                }
                else
                {
                    if (run != 0 && tileMap[x, j].mWallXSolid)
                    {
                        // Add run to this point and start with 1 already in run
                        CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                        mEdges.Add(e);
                        mYAxisEdges[x].Add(e);

                        start = j;
                        run   = 0;
                    }

                    ++run;
                }
            }

            // Add final non-blocked edge.
            if (run != 0)
            {
                CNavRectEdge e = new CNavRectEdge(new Vector2(x, start), new Vector2(x, start + run), mRects[i]);
                mEdges.Add(e);
                mYAxisEdges[x].Add(e);
            }
        }

        double edgesTime = sw.Elapsed.TotalMilliseconds;

        // Generate portals.
        for (int k = 0; k < Map.mWidth * 2 + 1; ++k)
        {
            List <CNavRectEdge> edges = mXAxisEdges[k];

            for (int i = 0; i < edges.Count; ++i)
            {
                for (int j = i + 1; j < edges.Count; ++j)
                {
                    float min = Mathf.Max(edges[i].mA.x, edges[j].mA.x);
                    float max = Mathf.Min(edges[i].mB.x, edges[j].mB.x);

                    if (min < max)
                    {
                        CNavRectPortal p = new CNavRectPortal(new Vector2(min, edges[i].mA.y), new Vector2(max, edges[i].mA.y), edges[i].mRect, edges[j].mRect);
                        mPortals.Add(p);
                        edges[i].mRect.mPortals.Add(p);
                        edges[j].mRect.mPortals.Add(p);
                    }
                }
            }

            edges = mYAxisEdges[k];

            for (int i = 0; i < edges.Count; ++i)
            {
                for (int j = i + 1; j < edges.Count; ++j)
                {
                    float min = Mathf.Max(edges[i].mA.y, edges[j].mA.y);
                    float max = Mathf.Min(edges[i].mB.y, edges[j].mB.y);

                    if (min < max)
                    {
                        CNavRectPortal p = new CNavRectPortal(new Vector2(edges[i].mA.x, min), new Vector2(edges[i].mA.x, max), edges[i].mRect, edges[j].mRect);
                        mPortals.Add(p);
                        edges[i].mRect.mPortals.Add(p);
                        edges[j].mRect.mPortals.Add(p);
                    }
                }
            }
        }

        double portalsTime = sw.Elapsed.TotalMilliseconds;

        // Generate room IDs.
        int             roomCounter = 1;
        List <CNavRect> rectStack   = new List <CNavRect>();
        int             rectScan    = 0;

        while (rectScan < mRects.Count)
        {
            if (mRects[rectScan].mRoomId == -1)
            {
                if (mRects[rectScan].mFlags >= 10000)
                {
                    mRects[rectScan].mRoomId = 0;
                }
                else
                {
                    rectStack.Add(mRects[rectScan]);
                    mRects[rectScan].mRoomId = roomCounter;

                    while (rectStack.Count > 0)
                    {
                        CNavRect rect = rectStack[0];
                        rectStack.RemoveAt(0);

                        for (int i = 0; i < rect.mPortals.Count; ++i)
                        {
                            CNavRectPortal p = rect.mPortals[i];

                            if (p.mRectA.mFlags < 10000 && p.mRectA.mRoomId == -1)
                            {
                                rectStack.Add(p.mRectA);
                                p.mRectA.mRoomId = roomCounter;
                            }

                            if (p.mRectB.mFlags < 10000 && p.mRectB.mRoomId == -1)
                            {
                                rectStack.Add(p.mRectB);
                                p.mRectB.mRoomId = roomCounter;
                            }
                        }
                    }
                }

                ++roomCounter;
            }

            ++rectScan;
        }

        double roomTime = sw.Elapsed.TotalMilliseconds;

        sw.Stop();
        Debug.Log("NavRect: " + sw.Elapsed.TotalMilliseconds.ToString("0.000") +
                  "ms Setup: " + setupTime.ToString("0.000") +
                  "ms Rects(" + mRects.Count + "): " + (expansionTime - setupTime).ToString("0.000") +
                  "ms Edges(" + mEdges.Count + "): " + (edgesTime - expansionTime).ToString("0.000") +
                  "ms Portals(" + mPortals.Count + "): " + (portalsTime - edgesTime).ToString("0.000") +
                  "ms Rooms: " + (roomTime - portalsTime).ToString("0.000") + "ms");
    }