protected virtual void LockDoorway(Doorway doorway, Key key, KeyManager keyManager) { var placement = doorway.Tile.Placement; var prefabs = doorway.Tile.TileSet.LockPrefabs.Where(x => { return(DoorwaySocket.IsMatchingSocket(x.SocketGroup, doorway.SocketGroup)); }).Select(x => x.LockPrefabs).ToArray(); if (prefabs.Length == 0) { return; } var chosenEntry = prefabs[RandomStream.Next(0, prefabs.Length)].GetRandom(RandomStream, placement.IsOnMainPath, placement.NormalizedDepth, null, true); var prefab = chosenEntry.Value; GameObject doorObj = GameObject.Instantiate(prefab); doorObj.transform.parent = Root.transform; doorObj.transform.position = doorway.transform.position; doorObj.transform.rotation = doorway.transform.rotation; // Set this locked door as the current door prefab doorway.SetUsedPrefab(doorObj); doorway.ConnectedDoorway.SetUsedPrefab(doorObj); DungeonUtil.AddAndSetupDoorComponent(CurrentDungeon, doorObj, doorway); foreach (var keylock in doorObj.GetComponentsInChildren <Component>().OfType <IKeyLock>()) { keylock.OnKeyAssigned(key, keyManager); } }
public bool ChooseRandomDoorway(System.Random random, DoorwaySocketType?socketGroupFilter, Vector3?allowedDirection, out int doorwayIndex, out Doorway doorway) { doorwayIndex = -1; doorway = null; IEnumerable <Doorway> possibleDoorways = Doorways; if (socketGroupFilter.HasValue) { possibleDoorways = possibleDoorways.Where(x => { return(DoorwaySocket.IsMatchingSocket(x.SocketGroup, socketGroupFilter.Value)); }); } if (allowedDirection.HasValue) { possibleDoorways = possibleDoorways.Where(x => { return(x.transform.forward == allowedDirection); }); } if (possibleDoorways.Count() == 0) { return(false); } doorway = possibleDoorways.ElementAt(random.Next(0, possibleDoorways.Count())); doorwayIndex = Doorways.IndexOf(doorway); return(true); }
public DoorwayProxy(TileProxy tileProxy, int index, DoorwaySocket socket, Vector3 localPosition, Quaternion localRotation) { TileProxy = tileProxy; Index = index; Socket = socket; LocalPosition = localPosition; LocalRotation = localRotation; }
/// <summary> /// Checks if two doorway sockets can connect /// </summary> public static bool CanSocketsConnect(DoorwaySocket a, DoorwaySocket b) { if (CustomSocketConnectionDelegate != null) { return(CustomSocketConnectionDelegate(a, b)); } else { return(a == b); // By default, sockets can only connect if they match } }
protected virtual void ConnectOverlappingDoorways(float percentageChance) { if (percentageChance <= 0) { return; } List <Doorway> processedDoorways = new List <Doorway>(allDoorways.Count); const float epsilon = 0.00001f; foreach (var a in allDoorways) { foreach (var b in allDoorways) { if (a == b) { continue; } if (a.Tile == b.Tile) { continue; } if (processedDoorways.Contains(b)) { continue; } if (!DoorwaySocket.IsMatchingSocket(a.SocketGroup, b.SocketGroup)) { continue; } float distanceSqrd = (a.transform.position - b.transform.position).sqrMagnitude; if (distanceSqrd < epsilon) { if (RandomStream.NextDouble() < percentageChance) { currentDungeon.MakeConnection(a, b, RandomStream); } } } processedDoorways.Add(a); } }
private bool IsValidDoorwayPairing(Doorway a, Doorway b, Tile nextTile, ref float weight) { // Enforce matching socket group if (!DoorwaySocket.IsMatchingSocket(a.SocketGroup, b.SocketGroup)) { 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); }
private bool IsValidDoorwayPairing(Doorway a, Doorway b, ref float weight) { // Enforce matching socket group if (!DoorwaySocket.IsMatchingSocket(a.SocketGroup, b.SocketGroup)) { return(false); } // Enforce facing-direction Vector3?forcedDirection = null; // 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 (!AllowRotation) { 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); } } } }