private bool IsValidDoorwayPairing(Doorway a, Doorway b, Tile nextTile, ref float weight)
        {
            // Enforce matching socket group
            if (!DoorwaySocket.CanSocketsConnect(a.Socket, b.Socket))
            {
                return(false);
            }

            // Enforce facing-direction
            Vector3?forcedDirection = null;

            // If AllowRotation has been set to false, or if the tile to be placed disallows rotation, we must force a connection from the correct direction
            bool disallowRotation = (AllowRotation.HasValue && !AllowRotation.Value) || (nextTile != null && !nextTile.AllowRotation);

            // Always enforce facing direction for vertical doorways
            const float angleEpsilon = 1.0f;

            if (Vector3.Angle(a.transform.forward, UpVector) < angleEpsilon)
            {
                forcedDirection = -UpVector;
            }
            else if (Vector3.Angle(a.transform.forward, -UpVector) < angleEpsilon)
            {
                forcedDirection = UpVector;
            }
            else if (disallowRotation)
            {
                forcedDirection = -a.transform.forward;
            }

            if (forcedDirection.HasValue)
            {
                float       angleDiff    = Vector3.Angle(forcedDirection.Value, b.transform.forward);
                const float maxAngleDiff = 1.0f;

                if (angleDiff > maxAngleDiff)
                {
                    return(false);
                }
            }

            weight = CalculateDoorwayWeight(b);
            return(true);
        }
示例#2
0
        internal void ConnectOverlappingDoorways(float globalChance, DungeonFlow dungeonFlow, System.Random randomStream)
        {
            const float epsilon  = 0.00001f;
            var         doorways = AllTiles.SelectMany(t => t.UnusedDoorways);

            foreach (var a in doorways)
            {
                foreach (var b in doorways)
                {
                    // Don't try to connect doorways that are already connected to another
                    if (a.Used || b.Used)
                    {
                        continue;
                    }

                    // Don't try to connect doorways to themselves
                    if (a == b || a.TileProxy == b.TileProxy)
                    {
                        continue;
                    }

                    // These doors cannot be connected due to their sockets
                    if (!DoorwaySocket.CanSocketsConnect(a.Socket, b.Socket))
                    {
                        continue;
                    }

                    float distanceSqrd = (a.Position - b.Position).sqrMagnitude;

                    // The doorways are too far apart
                    if (distanceSqrd >= epsilon)
                    {
                        continue;
                    }

                    if (dungeonFlow.RestrictConnectionToSameSection)
                    {
                        bool tilesAreOnSameLineSegment = a.TileProxy.Placement.GraphLine == b.TileProxy.Placement.GraphLine;

                        // The tiles are not on a line segment
                        if (a.TileProxy.Placement.GraphLine == null)
                        {
                            tilesAreOnSameLineSegment = false;
                        }

                        if (!tilesAreOnSameLineSegment)
                        {
                            continue;
                        }
                    }

                    float chance = globalChance;

                    // Allow tiles to override the global connection chance
                    // If both tiles want to override the connection chance, use the lowest value
                    if (a.TileProxy.PrefabTile.OverrideConnectionChance && b.TileProxy.PrefabTile.OverrideConnectionChance)
                    {
                        chance = Mathf.Min(a.TileProxy.PrefabTile.ConnectionChance, b.TileProxy.PrefabTile.ConnectionChance);
                    }
                    else if (a.TileProxy.PrefabTile.OverrideConnectionChance)
                    {
                        chance = a.TileProxy.PrefabTile.ConnectionChance;
                    }
                    else if (b.TileProxy.PrefabTile.OverrideConnectionChance)
                    {
                        chance = b.TileProxy.PrefabTile.ConnectionChance;
                    }

                    // There is no chance to connect these doorways
                    if (chance <= 0f)
                    {
                        continue;
                    }

                    if (randomStream.NextDouble() < chance)
                    {
                        MakeConnection(a, b);
                    }
                }
            }
        }