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); }
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); } } } }