示例#1
0
        /// <summary>
        /// Sets a given direction blocked. This means that it will no longer be allowed to connect on that direction.
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="value"></param>
        public void SetBlockedDirection(Direction dir, bool value)
        {
            byte result = AdjacencyBitmap.SetDirection(blockedConnections, dir, value);

            SyncBlockedConnections(blockedConnections, result);
            EditorblockedConnections = BlockedConnections;
            adjacents.UpdateDirection(dir, !value, true);
            UpdateMeshAndDirection();
        }
示例#2
0
        /**
         * Adjusts the connections value based on the given new tile.
         * Returns whether value changed.
         */
        private bool UpdateSingleConnection(Direction direction, TileDefinition tile)
        {
            bool isConnected = (tile.turf && (tile.turf.genericType == type || type == null));

            if (tile.fixtures != null)
            {
                isConnected = isConnected || (tile.fixtures.GetFixtureAtLayerIndex(LayerIndex) && (tile.fixtures.GetFixtureAtLayerIndex(LayerIndex).genericType == type || type == null));
            }

            isConnected &= (AdjacencyBitmap.Adjacent(TileState.blockedDirection, direction) == 0);

            return(adjacents.UpdateDirection(direction, isConnected, true));
        }
示例#3
0
        public MeshDirectionInfo GetMeshAndDirection(AdjacencyBitmap adjacents)
        {
            // Count number of connections along cardinal (which is all that we use atm)
            var cardinalInfo = adjacents.GetCardinalInfo();

            // Determine rotation and mesh specially for every single case.
            float rotation = 0.0f;
            Mesh  mesh;

            if (cardinalInfo.IsO())
            {
                mesh = o;
            }
            else if (cardinalInfo.IsU())
            {
                mesh     = u;
                rotation = TileHelper.AngleBetween(Direction.North, cardinalInfo.GetOnlyPositive());
            }
            else if (cardinalInfo.IsI())
            {
                mesh     = i;
                rotation = TileHelper.AngleBetween(Orientation.Vertical, cardinalInfo.GetFirstOrientation());
            }
            else if (cardinalInfo.IsL())
            {
                mesh     = l;
                rotation = TileHelper.AngleBetween(Direction.NorthEast, cardinalInfo.GetCornerDirection());
            }
            else if (cardinalInfo.IsT())
            {
                mesh     = t;
                rotation = TileHelper.AngleBetween(Direction.South, cardinalInfo.GetOnlyNegative());
            }
            else // Must be X
            {
                mesh = x;
            }

            return(new MeshDirectionInfo {
                mesh = mesh, rotation = rotation
            });
        }
示例#4
0
        /// <summary>
        /// Ensures that the object is properly initialized.
        /// </summary>
        private void EnsureInit()
        {
            if (!this)
            {
                return;
            }

            if (adjacents == null)
            {
                adjacents = new AdjacencyBitmap();
            }

            if (!filter)
            {
                filter = GetComponent <MeshFilter>();
            }

            genericType  = GetComponent <PlacedTileObject>()?.GetGenericType();
            specificType = GetComponent <PlacedTileObject>()?.GetSpecificType();
        }
示例#5
0
        /// <summary>
        /// Update a single direction.
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="placedObject"></param>
        /// <returns></returns>
        private bool UpdateSingleConnection(Direction dir, PlacedTileObject placedObject)
        {
            // For some reason called before OnAwake()
            EnsureInit();
            UpdateBlockedFromEditor();

            bool isConnected = false;

            if (placedObject)
            {
                isConnected = (placedObject && placedObject.HasAdjacencyConnector());

                // If cross connect is allowed, we only allow it to connect when the object type matches the connector type
                if (CrossConnectAllowed)
                {
                    isConnected &= (placedObject.GetGenericType() == genericType && genericType != "");
                }
                else
                {
                    isConnected &= (placedObject.GetGenericType() == genericType || genericType == null);
                }

                // Check for specific
                isConnected &= (placedObject.GetSpecificType() == specificType || specificType == "");

                isConnected &= (AdjacencyBitmap.Adjacent(blockedConnections, dir) == 0);
            }
            bool isUpdated = adjacents.UpdateDirection(dir, isConnected, true);

            SyncAdjacentConnections(adjacents.Connections, adjacents.Connections);

            // Cross connect will override adjacents for other layers, so return isConnected instead.
            if (CrossConnectAllowed)
            {
                return(isConnected);
            }
            else
            {
                return(isUpdated);
            }
        }
示例#6
0
        public MeshDirectionInfo GetMeshAndDirection(AdjacencyBitmap adjacents)
        {
            // Count number of connections along cardinal (which is all that we use atm)
            var cardinalInfo = adjacents.GetCardinalInfo();

            // Determine rotation and mesh specially for every single case.
            float rotation = 0.0f;
            Mesh  mesh;

            if (cardinalInfo.IsO())
            {
                mesh        = o;
                orientation = OffsetOrientation.o;
            }
            else if (cardinalInfo.IsU())
            {
                if (cardinalInfo.north > 0 || cardinalInfo.east > 0)
                {
                    mesh        = uNorth;
                    orientation = OffsetOrientation.uNorth;
                }
                else
                {
                    mesh        = uSouth;
                    orientation = OffsetOrientation.uSouth;
                }
                rotation = TileHelper.AngleBetween(Direction.North, cardinalInfo.GetOnlyPositive());
            }
            else if (cardinalInfo.IsI())
            {
                mesh        = i;
                orientation = OffsetOrientation.i;
                rotation    = TileHelper.AngleBetween(Orientation.Vertical, cardinalInfo.GetFirstOrientation());
            }
            else if (cardinalInfo.IsL())
            {
                Direction sides = cardinalInfo.GetCornerDirection();
                mesh = sides == Direction.NorthEast ? lNE
                    : sides == Direction.SouthEast ? lSE
                    : sides == Direction.SouthWest ? lSW
                    : lNW;

                orientation = sides == Direction.NorthEast ? OffsetOrientation.lNE
                    : sides == Direction.SouthEast ? OffsetOrientation.lSE
                    : sides == Direction.SouthWest ? OffsetOrientation.lSW
                    : OffsetOrientation.lNW;

                rotation = 90;
            }
            else if (cardinalInfo.IsT())
            {
                Direction notside = cardinalInfo.GetOnlyNegative();
                mesh = notside == Direction.North ? tSWE
                    : notside == Direction.East ? tNSW
                    : notside == Direction.South ? tNEW
                    : tNSE;

                orientation = notside == Direction.North ? OffsetOrientation.tSWE
                    : notside == Direction.East ? OffsetOrientation.tNSW
                    : notside == Direction.South ? OffsetOrientation.tNEW
                    : OffsetOrientation.tNSE;

                rotation = 90;
            }
            else // Must be X
            {
                mesh        = x;
                orientation = OffsetOrientation.x;

                rotation = 90;
            }

            return(new MeshDirectionInfo {
                mesh = mesh, rotation = rotation
            });
        }
示例#7
0
        public MeshDirectionInfo GetMeshAndDirection(AdjacencyBitmap adjacents)
        {
            var cardinalInfo = adjacents.GetCardinalInfo();

            float rotation = 0.0f;
            Mesh  mesh;

            if (cardinalInfo.IsO())
            {
                mesh = o;
            }
            else if (cardinalInfo.IsU())
            {
                mesh     = u;
                rotation = TileHelper.AngleBetween(Direction.North, cardinalInfo.GetOnlyPositive());

                if (opaque)
                {
                    viewObstacles[0].SetActive(false);
                    viewObstacles[1].SetActive(false);
                    viewObstacles[2].SetActive(true);
                    viewObstacles[3].SetActive(false);
                }
            }
            else if (cardinalInfo.IsI())
            {
                mesh     = i;
                rotation = TileHelper.AngleBetween(Orientation.Vertical, cardinalInfo.GetFirstOrientation());

                if (opaque)
                {
                    viewObstacles[0].SetActive(false);
                    viewObstacles[1].SetActive(false);
                    viewObstacles[2].SetActive(true);
                    viewObstacles[3].SetActive(true);
                }
            }
            else if (cardinalInfo.IsL())
            {
                // Determine lSolid or lCorner by finding whether the area between the two connections is filled
                // We check for if any of the following bitfields matches the connection bitfield
                // N+NE+E = 0/1/2, E+SE+S = 2/3/4, S+SW+W = 4/5/6, W+NW+N = 6/7/0
                bool isFilled = (adjacents.Connections & 0b00000111) == 0b00000111 || (adjacents.Connections & 0b00011100) == 0b00011100 || (adjacents.Connections & 0b01110000) == 0b01110000 || (adjacents.Connections & 0b11000001) == 0b11000001;
                mesh     = isFilled ? lSingle : lNone;
                rotation = TileHelper.AngleBetween(Direction.NorthEast, cardinalInfo.GetCornerDirection());

                if (opaque)
                {
                    viewObstacles[0].SetActive(false);
                    viewObstacles[1].SetActive(true);
                    viewObstacles[2].SetActive(true);
                    viewObstacles[3].SetActive(false);
                }
            }
            else if (cardinalInfo.IsT())
            {
                // We make another bitfield (noticing a pattern?). 0x0 means no fills, 0x1 means right corner filled, 0x2 means left corner filled,
                // therefore both corners filled = 0x3.
                int corners = ((1 - cardinalInfo.north) * 2 | (1 - cardinalInfo.east)) * adjacents.Adjacent(Direction.SouthWest)
                              + ((1 - cardinalInfo.east) * 2 | (1 - cardinalInfo.south)) * adjacents.Adjacent(Direction.NorthWest)
                              + ((1 - cardinalInfo.south) * 2 | (1 - cardinalInfo.west)) * adjacents.Adjacent(Direction.NorthEast)
                              + ((1 - cardinalInfo.west) * 2 | (1 - cardinalInfo.north)) * adjacents.Adjacent(Direction.SouthEast);
                mesh = corners == 0 ? tNone
                    : corners == 1 ? tSingleLeft
                    : corners == 2 ? tSingleRight
                    : tDouble;

                rotation = TileHelper.AngleBetween(Direction.South, cardinalInfo.GetOnlyNegative());

                if (opaque)
                {
                    viewObstacles[0].SetActive(true);
                    viewObstacles[1].SetActive(true);
                    viewObstacles[2].SetActive(true);
                    viewObstacles[3].SetActive(corners >= 3);
                }
            }
            else
            {
                // This sneaky piece of code uses the cardinal info to store diagonals by rotating everything -45 degrees
                // NE -> N, SW -> S, etc.
                var diagonals = new AdjacencyBitmap.CardinalInfo((byte)(adjacents.Connections >> 1));

                switch (diagonals.numConnections)
                {
                case 0:
                    mesh = xNone;
                    break;

                case 1:
                    mesh     = xSingle;
                    rotation = TileHelper.AngleBetween(Direction.South, diagonals.GetOnlyPositive());
                    break;

                case 2:
                    if (diagonals.north == diagonals.south)
                    {
                        mesh     = xOpposite;
                        rotation = TileHelper.AngleBetween(Orientation.Horizontal, diagonals.GetFirstOrientation());
                    }
                    else
                    {
                        mesh     = xSide;
                        rotation = TileHelper.AngleBetween(Direction.SouthEast, diagonals.GetCornerDirection());
                    }
                    break;

                case 3:
                    mesh     = xTriple;
                    rotation = TileHelper.AngleBetween(Direction.North, diagonals.GetOnlyNegative());
                    break;

                default:
                    mesh = xQuad;
                    break;
                }
                if (opaque)
                {
                    viewObstacles[0].SetActive(true);
                    viewObstacles[1].SetActive(true);
                    viewObstacles[2].SetActive(true);
                    viewObstacles[3].SetActive(true);
                }
            }

            return(new MeshDirectionInfo {
                mesh = mesh, rotation = rotation
            });
        }