/// <summary>
        /// Player is leaving dungeon, transition them back outside.
        /// </summary>
        public void TransitionDungeonExterior()
        {
            if (!ReferenceComponents() || !dungeon || !isPlayerInsideDungeon)
            {
                return;
            }

            // Enable exterior parent
            if (ExteriorParent != null)
            {
                ExteriorParent.SetActive(true);
            }

            // Disable dungeon parent
            if (DungeonParent != null)
            {
                DungeonParent.SetActive(false);
            }

            // Destroy dungeon game object
            Destroy(dungeon.gameObject);
            dungeon = null;

            // Set player outside exterior door position and set facing
            transform.position = dungeonEntrancePosition;
            SetFacing(-dungeonEntranceForward);
            SetStanding();

            // Player is now outside dungeon
            isPlayerInside              = false;
            isPlayerInsideDungeon       = false;
            isPlayerInsideDungeonPalace = false;
            lastPlayerDungeonBlockIndex = -1;
            playerDungeonBlockData      = new DFLocation.DungeonBlock();
        }
Пример #2
0
        /// <summary>
        /// Player is leaving dungeon, transition them back outside.
        /// </summary>
        public void TransitionDungeonExterior(bool doFade = false)
        {
            if (!ReferenceComponents() || !dungeon || !isPlayerInsideDungeon)
            {
                return;
            }

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToDungeonExterior);

            EnableExteriorParent();

            // Player is now outside dungeon
            isPlayerInside              = false;
            isPlayerInsideDungeon       = false;
            isPlayerInsideDungeonPalace = false;
            lastPlayerDungeonBlockIndex = -1;
            playerDungeonBlockData      = new DFLocation.DungeonBlock();

            // Position player to door
            world.SetAutoReposition(StreamingWorld.RepositionMethods.DungeonEntrance, Vector3.zero);

            // Raise event
            RaiseOnTransitionDungeonExteriorEvent();

            // Fade in from black
            if (doFade)
            {
                DaggerfallUI.Instance.FadeHUDFromBlack();
            }
        }
        private void LayoutDungeon(ref DFLocation location, bool importEnemies = true)
        {
#if SHOW_LAYOUT_TIMES
            // Start timing
            System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
            long startTime = stopwatch.ElapsedMilliseconds;
#endif

            // Get player level - use level 1 if game not running (e.g. importing in editor mode)
            float playerLevel = 1;
            if (Application.isPlaying)
            {
                playerLevel = GameManager.Instance.PlayerEntity.Level;
            }

            // Calculate monster power - this is a clamped 0-1 value based on player's level from 1-20
            float monsterPower = Mathf.Clamp01(playerLevel / 20f);

            // Create dungeon layout
            for (int i = 0; i < summary.LocationData.Dungeon.Blocks.Length; i++)
            {
                DFLocation.DungeonBlock block = summary.LocationData.Dungeon.Blocks[i];
                GameObject go = GameObjectHelper.CreateRDBBlockGameObject(
                    block.BlockName,
                    DungeonTextureTable,
                    block.IsStartingBlock,
                    Summary.DungeonType,
                    monsterPower,
                    RandomMonsterVariance,
                    (int)DateTime.Now.Ticks /*Summary.ID*/,      // TODO: Add more options for seed
                    dfUnity.Option_DungeonBlockPrefab,
                    importEnemies);
                go.transform.parent   = this.transform;
                go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide);

                DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>();
                if (block.IsStartingBlock)
                {
                    FindMarkers(daggerfallBlock, ref block, true); // Assign start marker and enter marker
                }
                else
                {
                    FindMarkers(daggerfallBlock, ref block, false); // Only find water level and palaceblock info from start marker
                }
                summary.LocationData.Dungeon.Blocks[i].WaterLevel  = block.WaterLevel;
                summary.LocationData.Dungeon.Blocks[i].CastleBlock = block.CastleBlock;

                // Add water blocks
                RDBLayout.AddWater(go, go.transform.position, block.WaterLevel);
            }

            RemoveOverlappingDoors();

#if SHOW_LAYOUT_TIMES
            // Show timer
            long totalTime = stopwatch.ElapsedMilliseconds - startTime;
            DaggerfallUnity.LogMessage(string.Format("Time to layout dungeon: {0}ms", totalTime), true);
#endif
        }
        public bool GetBlockData(int index, out DFLocation.DungeonBlock blockDataOut)
        {
            if (!summary.LocationData.Loaded)
            {
                blockDataOut = new DFLocation.DungeonBlock();
                return(false);
            }

            blockDataOut = summary.LocationData.Dungeon.Blocks[index];

            return(true);
        }
        // Finds start and enter markers, should be called with true for starting block, otherwise false to just get water level and castle block data
        private void FindMarkers(DaggerfallRDBBlock dfBlock, ref DFLocation.DungeonBlock block, bool assign)
        {
            if (!dfBlock)
            {
                throw new Exception("DaggerfallDungeon: dfBlock cannot be null.");
            }

            if (dfBlock.StartMarkers != null && dfBlock.StartMarkers.Length > 0)
            {
                // There should only be one start marker per start block
                // This message will let us know if more than one is found
                if (dfBlock.StartMarkers.Length > 1)
                {
                    DaggerfallUnity.LogMessage("DaggerfallDungeon: Multiple 'Start' markers found. Using first marker.", true);
                }

                if (assign)
                {
                    startMarker = dfBlock.StartMarkers[0];
                }

                DaggerfallBillboard dfBillboard = dfBlock.StartMarkers[0].GetComponent <DaggerfallBillboard>();
                block.WaterLevel  = dfBillboard.Summary.WaterLevel;
                block.CastleBlock = dfBillboard.Summary.CastleBlock;
            }
            else // No water
            {
                block.WaterLevel = 10000;
            }

            if (dfBlock.EnterMarkers != null && dfBlock.EnterMarkers.Length > 0)
            {
                // There should only be one enter marker per start block
                // This message will let us know if more than one is found
                if (dfBlock.EnterMarkers.Length > 1)
                {
                    DaggerfallUnity.LogMessage("DaggerfallDungeon: Multiple 'Enter' markers found. Using first marker.", true);
                }

                if (assign)
                {
                    enterMarker = dfBlock.EnterMarkers[0];
                }
            }
        }
        // Orsinium defines two blocks at [-1,-1]
        private void LayoutOrsinium(ref DFLocation location, bool importEnemies = true)
        {
            // Calculate monster power - this is a clamped 0-1 value based on player's level from 1-20
            float monsterPower = Mathf.Clamp01(GameManager.Instance.PlayerEntity.Level / 20f);

            // Create dungeon layout and handle misplaced block
            for (int i = 0; i < summary.LocationData.Dungeon.Blocks.Length; i++)
            {
                DFLocation.DungeonBlock block = summary.LocationData.Dungeon.Blocks[i];
                if (block.X == -1 && block.Z == -1 && block.BlockName == "N0000065.RDB")
                {
                    continue;
                }

                GameObject go = GameObjectHelper.CreateRDBBlockGameObject(
                    block.BlockName,
                    DungeonTextureTable,
                    block.IsStartingBlock,
                    Summary.DungeonType,
                    monsterPower,
                    RandomMonsterVariance,
                    (int)DateTime.Now.Ticks /*Summary.ID*/,      // TODO: Add more options for seed
                    dfUnity.Option_DungeonBlockPrefab,
                    importEnemies);
                go.transform.parent   = this.transform;
                go.transform.position = new Vector3(block.X * RDBLayout.RDBSide, 0, block.Z * RDBLayout.RDBSide);

                DaggerfallRDBBlock daggerfallBlock = go.GetComponent <DaggerfallRDBBlock>();
                if (block.IsStartingBlock)
                {
                    FindMarkers(daggerfallBlock, ref block, true); // Assign start marker and enter marker
                }
                else
                {
                    FindMarkers(daggerfallBlock, ref block, false); // Only find water level and castle block info from start marker
                }
                summary.LocationData.Dungeon.Blocks[i].WaterLevel  = block.WaterLevel;
                summary.LocationData.Dungeon.Blocks[i].CastleBlock = block.CastleBlock;

                // Add water blocks
                RDBLayout.AddWater(go, go.transform.position, block.WaterLevel);
            }

            RemoveOverlappingDoors();
        }
Пример #7
0
        /// <summary>
        /// Transition player through a dungeon entrance door into dungeon interior.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array.</param>
        /// <param name="door">Exterior door player clicked on.</param>
        public void TransitionDungeonInterior(Transform doorOwner, StaticDoor door, DFLocation location, bool doFade = false)
        {
            // Ensure we have component references
            if (!ReferenceComponents())
            {
                return;
            }

            // Reset dungeon block on entering dungeon
            lastPlayerDungeonBlockIndex = -1;
            playerDungeonBlockData      = new DFLocation.DungeonBlock();

            // Override location if specified
            if (OverrideLocation != null)
            {
                DFLocation overrideLocation = dfUnity.ContentReader.MapFileReader.GetLocation(OverrideLocation.Summary.RegionName, OverrideLocation.Summary.LocationName);
                if (overrideLocation.Loaded)
                {
                    location = overrideLocation;
                }
            }

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToDungeonInterior, door);

            // Layout dungeon
            GameObject newDungeon = GameObjectHelper.CreateDaggerfallDungeonGameObject(location, DungeonParent.transform);

            newDungeon.hideFlags = defaultHideFlags;
            dungeon = newDungeon.GetComponent <DaggerfallDungeon>();

            // Find start marker to position player
            if (!dungeon.StartMarker)
            {
                // Could not find a start marker
                Destroy(newDungeon);
                return;
            }

            EnableDungeonParent();

            // Set to start position
            MovePlayerToMarker(dungeon.StartMarker);

            // Find closest dungeon exit door to orient player
            StaticDoor[] doors = DaggerfallStaticDoors.FindDoorsInCollections(dungeon.StaticDoorCollections, DoorTypes.DungeonExit);
            if (doors != null && doors.Length > 0)
            {
                Vector3 doorPos;
                int     doorIndex;
                if (DaggerfallStaticDoors.FindClosestDoorToPlayer(transform.position, doors, out doorPos, out doorIndex))
                {
                    // Set player facing away from door
                    PlayerMouseLook playerMouseLook = GameManager.Instance.PlayerMouseLook;
                    if (playerMouseLook)
                    {
                        Vector3 normal = DaggerfallStaticDoors.GetDoorNormal(doors[doorIndex]);
                        playerMouseLook.SetFacing(normal);
                    }
                }
            }

            // Raise event
            RaiseOnTransitionDungeonInteriorEvent(door, dungeon);

            // Fade in from black
            if (doFade)
            {
                DaggerfallUI.Instance.FadeHUDFromBlack();
            }
        }
Пример #8
0
        IEnumerator Respawner(int worldX, int worldZ, bool insideDungeon, bool insideBuilding, bool forceReposition)
        {
            // Wait for end of frame so existing world data can be removed
            yield return(new WaitForEndOfFrame());

            // Reset dungeon block on new spawn
            lastPlayerDungeonBlockIndex = -1;
            playerDungeonBlockData      = new DFLocation.DungeonBlock();

            // Reset inside state
            isPlayerInside              = false;
            isPlayerInsideDungeon       = false;
            isPlayerInsideDungeonPalace = false;

            // Set player GPS coordinates
            playerGPS.WorldX = worldX;
            playerGPS.WorldZ = worldZ;

            // Set streaming world coordinates
            DFPosition pos = MapsFile.WorldCoordToMapPixel(worldX, worldZ);

            world.MapPixelX = pos.X;
            world.MapPixelY = pos.Y;

            // Get location at this position
            ContentReader.MapSummary summary;
            bool hasLocation = dfUnity.ContentReader.HasLocation(pos.X, pos.Y, out summary);

            if (!insideDungeon && !insideBuilding)
            {
                // Start outside
                EnableExteriorParent();
                if (!forceReposition)
                {
                    // Teleport to explicit world coordinates
                    world.TeleportToWorldCoordinates(worldX, worldZ);
                }
                else
                {
                    // Force reposition to closest start marker if available
                    world.TeleportToCoordinates(pos.X, pos.Y, StreamingWorld.RepositionMethods.RandomStartMarker);
                }

                // Wait until world is ready
                while (world.IsInit)
                {
                    yield return(new WaitForEndOfFrame());
                }
            }
            else if (hasLocation && insideDungeon)
            {
                // Start in dungeon
                DFLocation location;
                world.TeleportToCoordinates(pos.X, pos.Y, StreamingWorld.RepositionMethods.None);
                dfUnity.ContentReader.GetLocation(summary.RegionIndex, summary.MapIndex, out location);
                StartDungeonInterior(location, true);
                world.suppressWorld = true;
            }
            else if (hasLocation && insideBuilding && exteriorDoors != null)
            {
                // Start in building
                DFLocation location;
                world.TeleportToCoordinates(pos.X, pos.Y, StreamingWorld.RepositionMethods.None);
                dfUnity.ContentReader.GetLocation(summary.RegionIndex, summary.MapIndex, out location);
                StartBuildingInterior(location, exteriorDoors[0]);
                world.suppressWorld = true;
            }
            else
            {
                // All else fails teleport to map pixel
                DaggerfallUnity.LogMessage("Something went wrong! Teleporting to origin of nearest map pixel.");
                EnableExteriorParent();
                world.TeleportToCoordinates(pos.X, pos.Y);
            }

            // Lower respawn flag
            isRespawning = false;
        }