示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
 public DoorwayProxy(TileProxy tileProxy, int index, DoorwaySocket socket, Vector3 localPosition, Quaternion localRotation)
 {
     TileProxy     = tileProxy;
     Index         = index;
     Socket        = socket;
     LocalPosition = localPosition;
     LocalRotation = localRotation;
 }
示例#4
0
 /// <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
     }
 }
示例#5
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
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);
                    }
                }
            }
        }