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