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; }
private void LayoutDungeon(ref DFLocation location) { #if SHOW_LAYOUT_TIMES // Start timing System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); long startTime = stopwatch.ElapsedMilliseconds; #endif // Create dungeon layout foreach (var block in location.Dungeon.Blocks) { GameObject go = GameObjectHelper.CreateRDBBlockGameObject( block.BlockName, DungeonTextureTable, block.IsStartingBlock, Summary.DungeonType, RandomMonsterPower, RandomMonsterVariance, (int)DateTime.Now.Ticks/*Summary.ID*/, // TODO: Add more options for seed dfUnity.Option_DungeonBlockPrefab); 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); } #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 void SetDungeon(DFLocation location) { if (!ReadyCheck()) return; // Validate if (this.isSet) throw new Exception("This location has already been set."); if (!location.Loaded) throw new Exception("DFLocation not loaded."); if (!location.HasDungeon) throw new Exception("DFLocation does not contain a dungeon."); // Set summary summary = new DungeonSummary(); summary.ID = location.MapTableData.MapId; summary.RegionName = location.RegionName; summary.LocationName = location.Name; summary.LocationData = location; summary.LocationType = location.MapTableData.LocationType; summary.DungeonType = location.MapTableData.DungeonType; // Set texture table from location if (DungeonTextureUse == DaggerfallWorkshop.DungeonTextureUse.UseLocation_PartiallyImplemented) UseLocationDungeonTextureTable(); // Perform layout startMarker = null; if (location.Name == "Orsinium") LayoutOrsinium(ref location); else LayoutDungeon(ref location); // Seal location isSet = true; }
/// <summary> /// Attempts to get a Daggerfall location from MAPS.BSA. /// </summary> /// <param name="regionName">Name of region.</param> /// <param name="locationName">Name of location.</param> /// <param name="locationOut">DFLocation data out.</param> /// <returns>True if successful.</returns> public bool GetLocation(string regionName, string locationName, out DFLocation locationOut) { locationOut = new DFLocation(); if (!isReady) return false; // Get location data locationOut = mapFileReader.GetLocation(regionName, locationName); if (!locationOut.Loaded) { DaggerfallUnity.LogMessage(string.Format("Unknown location RegionName='{0}', LocationName='{1}'.", regionName, locationName), true); return false; } return true; }
public static int GetNatureArchive(DFLocation.ClimateTextureSet climateTextureSet, DaggerfallDateTime.Seasons worldSeason) { ClimateNatureSets natureSet = FromAPITextureSet(climateTextureSet); ClimateSeason climateSeason = ClimateSeason.Summer; if (worldSeason == DaggerfallDateTime.Seasons.Winter) climateSeason = ClimateSeason.Winter; return GetNatureArchive(natureSet, climateSeason); }
public static bool FindMultiNameLocation(string multiName, out DFLocation locationOut) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; locationOut = new DFLocation(); if (string.IsNullOrEmpty(multiName)) return false; // Split combined name string[] parts = multiName.Split('/'); if (parts.Length != 2) { DaggerfallUnity.LogMessage(string.Format("Multi name '{0}' does not follow the structure RegionName/LocationName.", multiName), true); return false; } // Get location if (!dfUnity.ContentReader.GetLocation(parts[0], parts[1], out locationOut)) return false; return true; }
/// <summary> /// Convert API climate base over to DaggerfallUnity equivalent. /// </summary> /// <param name="climate">DFLocation.ClimateBaseType.</param> /// <returns>ClimateBases.</returns> public static ClimateBases FromAPIClimateBase(DFLocation.ClimateBaseType climate) { switch (climate) { case DFLocation.ClimateBaseType.Desert: return ClimateBases.Desert; case DFLocation.ClimateBaseType.Mountain: return ClimateBases.Mountain; case DFLocation.ClimateBaseType.Temperate: return ClimateBases.Temperate; case DFLocation.ClimateBaseType.Swamp: return ClimateBases.Swamp; default: return ClimateBases.Temperate; } }
/// <summary> /// Starts player inside dungeon with no exterior world. /// </summary> public void StartDungeonInterior(DFLocation location, bool preferEnterMarker = true) { // Ensure we have component references if (!ReferenceComponents()) return; // Layout dungeon GameObject newDungeon = GameObjectHelper.CreateDaggerfallDungeonGameObject(location, DungeonParent.transform); newDungeon.hideFlags = defaultHideFlags; dungeon = newDungeon.GetComponent<DaggerfallDungeon>(); GameObject marker = null; if (preferEnterMarker && dungeon.EnterMarker != null) marker = dungeon.EnterMarker; else marker = dungeon.StartMarker; // Find start marker to position player if (!marker) { // Could not find marker DaggerfallUnity.LogMessage("No start or enter marker found for this dungeon. Aborting load."); Destroy(newDungeon); return; } EnableDungeonParent(); // Set to start position MovePlayerToMarker(marker); // Set player facing north PlayerMouseLook playerMouseLook = GameManager.Instance.PlayerMouseLook; if (playerMouseLook) playerMouseLook.SetFacing(Vector3.forward); }
/// <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; // 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(); }
// Start new character to location specified in INI void StartNewCharacter() { DaggerfallUI.Instance.PopToHUD(); // Assign character sheet PlayerEntity playerEntity = FindPlayerEntity(); playerEntity.AssignCharacter(characterSheet); // Set game time DaggerfallUnity.Instance.WorldTime.Now.SetClassicGameStartTime(); // Get start parameters DFPosition mapPixel = new DFPosition(DaggerfallUnity.Settings.StartCellX, DaggerfallUnity.Settings.StartCellY); bool startInDungeon = DaggerfallUnity.Settings.StartInDungeon; // Read location if any DFLocation location = new DFLocation(); ContentReader.MapSummary mapSummary; bool hasLocation = DaggerfallUnity.Instance.ContentReader.HasLocation(mapPixel.X, mapPixel.Y, out mapSummary); if (hasLocation) { if (!DaggerfallUnity.Instance.ContentReader.GetLocation(mapSummary.RegionIndex, mapSummary.MapIndex, out location)) hasLocation = false; } // Start at specified location StreamingWorld streamingWorld = FindStreamingWorld(); if (hasLocation && startInDungeon && location.HasDungeon) { if (streamingWorld) { streamingWorld.TeleportToCoordinates(mapPixel.X, mapPixel.Y); streamingWorld.suppressWorld = true; } playerEnterExit.EnableDungeonParent(); playerEnterExit.StartDungeonInterior(location); } else { playerEnterExit.EnableExteriorParent(); if (streamingWorld) { streamingWorld.SetAutoReposition(StreamingWorld.RepositionMethods.Origin, Vector3.zero); streamingWorld.suppressWorld = false; } } // Start game GameManager.Instance.PauseGame(false); DaggerfallUI.Instance.FadeHUDFromBlack(); }
/// <summary> /// Starts player inside building with no exterior world. /// </summary> public void StartBuildingInterior(DFLocation location, StaticDoor exteriorDoor) { // Ensure we have component references if (!ReferenceComponents()) return; TransitionInterior(null, exteriorDoor); }
/// <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) { // Ensure we have component references if (!ReferenceComponents()) return; // 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 = HideFlags.HideAndDontSave; dungeon = newDungeon.GetComponent<DaggerfallDungeon>(); // Find start marker to position player if (!dungeon.StartMarker) { // Could not find a start marker Destroy(newDungeon); return; } // Cache player starting position and facing to use on exit dungeonEntrancePosition = transform.position; dungeonEntranceForward = transform.forward; // Disable exterior parent if (ExteriorParent != null) ExteriorParent.SetActive(false); // Enable dungeon parent if (DungeonParent != null) DungeonParent.SetActive(true); // Player is now inside dungeon isPlayerInside = true; isPlayerInsideDungeon = true; // Set to start position MovePlayerToDungeonStart(); // Raise event RaiseOnTransitionDungeonInteriorEvent(door, dungeon); }
// Create new location game object private GameObject CreateLocationGameObject(int terrain, out DFLocation locationOut) { locationOut = new DFLocation(); // Terrain must have a location DaggerfallTerrain dfTerrain = terrainArray[terrain].terrainObject.GetComponent<DaggerfallTerrain>(); if (!dfTerrain.MapData.hasLocation) return null; // Get location data locationOut = dfUnity.ContentReader.MapFileReader.GetLocation(dfTerrain.MapData.mapRegionIndex, dfTerrain.MapData.mapLocationIndex); if (!locationOut.Loaded) return null; // Sample height of terrain at origin tile position, this is more accurate than scaled average - thanks Nystul! // TODO: Daggerfall does not always position locations at exact centre as assumed. // Working around this for now and will update this code later Terrain terrainInstance = dfTerrain.gameObject.GetComponent<Terrain>(); float scale = terrainInstance.terrainData.heightmapScale.x; float xSamplePos = dfUnity.TerrainSampler.HeightmapDimension * 0.55f; float ySamplePos = dfUnity.TerrainSampler.HeightmapDimension * 0.55f; Vector3 pos = new Vector3(xSamplePos * scale, 0, ySamplePos * scale); float height = terrainInstance.SampleHeight(pos + terrainArray[terrain].terrainObject.transform.position); // Spawn parent game object for new location //float height = dfTerrain.MapData.averageHeight * TerrainScale; GameObject locationObject = new GameObject(string.Format("DaggerfallLocation [Region={0}, Name={1}]", locationOut.RegionName, locationOut.Name)); locationObject.transform.parent = StreamingTarget; locationObject.hideFlags = defaultHideFlags; locationObject.transform.position = terrainArray[terrain].terrainObject.transform.position + new Vector3(0, height, 0); DaggerfallLocation dfLocation = locationObject.AddComponent<DaggerfallLocation>() as DaggerfallLocation; dfLocation.SetLocation(locationOut, false); // Raise event RaiseOnCreateLocationGameObjectEvent(dfLocation); return locationObject; }
// Determines tile origin of location inside terrain area. // This is not always centred precisely but rather seems to follow some other // logic/formula for locations of certain RMB dimensions (e.g. 1x1). // Unknown if there are more exceptions or if a specific formula is needed. // This method will be used in the interim pending further research. public static DFPosition GetLocationTerrainTileOrigin(DFLocation location) { // Get map width and height int width = location.Exterior.ExteriorData.Width; int height = location.Exterior.ExteriorData.Height; // Centring works nearly all the time DFPosition result = new DFPosition(); result.X = (RMBLayout.RMBTilesPerTerrain - width * RMBLayout.RMBTilesPerBlock) / 2; result.Y = (RMBLayout.RMBTilesPerTerrain - height * RMBLayout.RMBTilesPerBlock) / 2; // But some 1x1 locations (e.g. Privateer's Hold exterior) are positioned differently // Seems to be 1x1 blocks using CUST prefix, but possibly more research needed const int custPrefixIndex = 40; if (width == 1 && height == 1) { if (location.Exterior.ExteriorData.BlockIndex[0] == custPrefixIndex) { result.X = 72; result.Y = 55; } } return result; }
// Orsinium defines two blocks at [-1,-1] private void LayoutOrsinium(ref DFLocation location) { // Create dungeon layout and handle misplaced block foreach (var block in location.Dungeon.Blocks) { if (block.X == -1 && block.Z == -1 && block.BlockName == "N0000065.RDB") continue; GameObject go = GameObjectHelper.CreateRDBBlockGameObject( block.BlockName, DungeonTextureTable, block.IsStartingBlock, Summary.DungeonType, RandomMonsterPower, RandomMonsterVariance, (int)DateTime.Now.Ticks/*Summary.ID*/, // TODO: Add more options for seed dfUnity.Option_DungeonBlockPrefab); 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); } }
public void SetLocation(DFLocation location, bool performLayout = true) { if (!ReadyCheck()) return; // Validate if (this.isSet) throw new Exception("This location has already been set."); if (!location.Loaded) throw new Exception("DFLocation not loaded."); // Set summary summary = new LocationSummary(); summary.ID = location.MapTableData.MapId; summary.Longitude = (int)location.MapTableData.Longitude; summary.Latitude = (int)location.MapTableData.Latitude; DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(summary.Longitude, summary.Latitude); DFPosition worldCoord = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); summary.MapPixelX = mapPixel.X; summary.MapPixelY = mapPixel.Y; summary.WorldCoordX = worldCoord.X; summary.WorldCoordZ = worldCoord.Y; summary.RegionName = location.RegionName; summary.LocationName = location.Name; summary.WorldClimate = location.Climate.WorldClimate; summary.LocationType = location.MapTableData.LocationType; summary.DungeonType = location.MapTableData.DungeonType; summary.HasDungeon = location.HasDungeon; summary.Climate = ClimateSwaps.FromAPIClimateBase(location.Climate.ClimateType); summary.Nature = ClimateSwaps.FromAPITextureSet(location.Climate.NatureSet); summary.SkyBase = location.Climate.SkyBase; summary.BlockWidth = location.Exterior.ExteriorData.Width; summary.BlockHeight = location.Exterior.ExteriorData.Height; // Assign starting climate CurrentSeason = ClimateSeason.Summer; CurrentClimate = summary.Climate; CurrentNatureSet = summary.Nature; // Perform layout if (performLayout) { LayoutLocation(ref location); ApplyClimateSettings(); } // Seal location isSet = true; }
private void PlayerGPS_OnEnterLocationRect(DaggerfallConnect.DFLocation location) { // Refresh when entering a location rect RefreshSiteTargets(); }
/// <summary> /// Performs a fully standalone in-place location layout. /// This method is used only by editor layouts, not by streaming world. /// </summary> private void LayoutLocation(ref DFLocation location) { #if SHOW_LAYOUT_TIMES // Start timing System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); long startTime = stopwatch.ElapsedMilliseconds; #endif // Get city dimensions int width = location.Exterior.ExteriorData.Width; int height = location.Exterior.ExteriorData.Height; // Create billboard batch game objects for this location TextureAtlasBuilder miscBillboardAtlas = null; summary.NatureBillboardBatch = null; DaggerfallBillboardBatch lightsBillboardBatch = null; DaggerfallBillboardBatch animalsBillboardBatch = null; DaggerfallBillboardBatch miscBillboardBatch = null; if (dfUnity.Option_BatchBillboards) { miscBillboardAtlas = dfUnity.MaterialReader.MiscBillboardAtlas; int natureArchive = ClimateSwaps.GetNatureArchive(CurrentNatureSet, CurrentSeason); summary.NatureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, transform); lightsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, transform); animalsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, transform); miscBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(miscBillboardAtlas.AtlasMaterial, transform); } // Import blocks for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (dfUnity.Option_BatchBillboards) { // Set block origin for billboard batches // This causes next additions to be offset by this position Vector3 blockOrigin = new Vector3((x * RMBLayout.RMBSide), 0, (y * RMBLayout.RMBSide)); summary.NatureBillboardBatch.BlockOrigin = blockOrigin; lightsBillboardBatch.BlockOrigin = blockOrigin; animalsBillboardBatch.BlockOrigin = blockOrigin; miscBillboardBatch.BlockOrigin = blockOrigin; } string blockName = dfUnity.ContentReader.BlockFileReader.CheckName(dfUnity.ContentReader.MapFileReader.GetRmbBlockName(ref location, x, y)); GameObject go = GameObjectHelper.CreateRMBBlockGameObject( blockName, dfUnity.Option_RMBGroundPlane, dfUnity.Option_CityBlockPrefab, summary.NatureBillboardBatch, lightsBillboardBatch, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch, CurrentNatureSet, CurrentSeason); go.transform.parent = this.transform; go.transform.position = new Vector3((x * RMBLayout.RMBSide), 0, (y * RMBLayout.RMBSide)); } } // Apply batches if (summary.NatureBillboardBatch) summary.NatureBillboardBatch.Apply(); if (lightsBillboardBatch) lightsBillboardBatch.Apply(); if (animalsBillboardBatch) animalsBillboardBatch.Apply(); if (miscBillboardBatch) miscBillboardBatch.Apply(); // Enumerate start marker game objects EnumerateStartMarkers(); #if SHOW_LAYOUT_TIMES // Show timer long totalTime = stopwatch.ElapsedMilliseconds - startTime; DaggerfallUnity.LogMessage(string.Format("Time to layout location: {0}ms", totalTime), true); #endif }
public static GameObject CreateDaggerfallDungeonGameObject(DFLocation location, Transform parent) { if (!location.HasDungeon) { string multiName = string.Format("{0}/{1}", location.RegionName, location.Name); DaggerfallUnity.LogMessage(string.Format("Location '{0}' does not contain a dungeon map", multiName), true); return null; } GameObject go = new GameObject(string.Format("DaggerfallDungeon [Region={0}, Name={1}]", location.RegionName, location.Name)); if (parent) go.transform.parent = parent; DaggerfallDungeon c = go.AddComponent<DaggerfallDungeon>(); c.SetDungeon(location); return go; }
protected virtual void RaiseOnEnterLocationRectEvent(DFLocation location) { if (OnEnterLocationRect != null) OnEnterLocationRect(location); }
/// <summary> /// Convert API nature set to DaggerfallUnity equivalent. /// </summary> /// <param name="set"></param> /// <returns>ClimateNatureSets.</returns> public static ClimateNatureSets FromAPITextureSet(DFLocation.ClimateTextureSet set) { switch (set) { case DFLocation.ClimateTextureSet.Nature_RainForest: return ClimateNatureSets.RainForest; case DFLocation.ClimateTextureSet.Nature_SubTropical: return ClimateNatureSets.SubTropical; case DFLocation.ClimateTextureSet.Nature_Swamp: return ClimateNatureSets.Swamp; case DFLocation.ClimateTextureSet.Nature_Desert: return ClimateNatureSets.Desert; case DFLocation.ClimateTextureSet.Nature_TemperateWoodland: return ClimateNatureSets.TemperateWoodland; case DFLocation.ClimateTextureSet.Nature_WoodlandHills: return ClimateNatureSets.WoodlandHills; case DFLocation.ClimateTextureSet.Nature_HauntedWoodlands: return ClimateNatureSets.HauntedWoodlands; case DFLocation.ClimateTextureSet.Nature_Mountains: return ClimateNatureSets.Mountains; default: return ClimateNatureSets.TemperateWoodland; } }
private void UpdateWorldInfo(int x, int y) { // Requires MAPS.BSA connection if (dfUnity.ContentReader.MapFileReader == null) return; // Get climate and politic data currentClimateIndex = dfUnity.ContentReader.MapFileReader.GetClimateIndex(x, y); currentPoliticIndex = dfUnity.ContentReader.MapFileReader.GetPoliticIndex(x, y); climateSettings = MapsFile.GetWorldClimateSettings(currentClimateIndex); if (currentPoliticIndex > 128) regionName = dfUnity.ContentReader.MapFileReader.GetRegionName(currentPoliticIndex - 128); else if (currentPoliticIndex == 64) regionName = "Ocean"; else regionName = "Unknown"; // Get region data currentRegion = dfUnity.ContentReader.MapFileReader.GetRegion(CurrentRegionIndex); // Get location data ContentReader.MapSummary mapSummary; if (dfUnity.ContentReader.HasLocation(x, y, out mapSummary)) { currentLocation = dfUnity.ContentReader.MapFileReader.GetLocation(mapSummary.RegionIndex, mapSummary.MapIndex); hasCurrentLocation = true; CalculateWorldLocationRect(); } else { currentLocation = new DFLocation(); hasCurrentLocation = false; ClearWorldLocationRect(); } // Get location type if (hasCurrentLocation) { if (currentRegion.MapTable == null) { DaggerfallUnity.LogMessage(string.Format("PlayerGPS: Location {0} in region{1} has a null MapTable.", currentLocation.Name, currentLocation.RegionName)); } else { currentLocationType = currentRegion.MapTable[mapSummary.MapIndex].LocationType; } } }
// Start new character to location specified in INI void StartNewCharacter() { DaggerfallUnity.ResetUID(); RaiseOnNewGameEvent(); DaggerfallUI.Instance.PopToHUD(); ResetWeaponManager(); // Must have a character document if (characterDocument == null) characterDocument = new CharacterDocument(); // Assign character sheet PlayerEntity playerEntity = FindPlayerEntity(); playerEntity.AssignCharacter(characterDocument); // Set game time DaggerfallUnity.Instance.WorldTime.Now.SetClassicGameStartTime(); // Get start parameters DFPosition mapPixel = new DFPosition(DaggerfallUnity.Settings.StartCellX, DaggerfallUnity.Settings.StartCellY); bool startInDungeon = DaggerfallUnity.Settings.StartInDungeon; // Read location if any DFLocation location = new DFLocation(); ContentReader.MapSummary mapSummary; bool hasLocation = DaggerfallUnity.Instance.ContentReader.HasLocation(mapPixel.X, mapPixel.Y, out mapSummary); if (hasLocation) { if (!DaggerfallUnity.Instance.ContentReader.GetLocation(mapSummary.RegionIndex, mapSummary.MapIndex, out location)) hasLocation = false; } if (NoWorld) { playerEnterExit.DisableAllParents(); } else { // Start at specified location StreamingWorld streamingWorld = FindStreamingWorld(); if (hasLocation && startInDungeon && location.HasDungeon) { if (streamingWorld) { streamingWorld.TeleportToCoordinates(mapPixel.X, mapPixel.Y); streamingWorld.suppressWorld = true; } playerEnterExit.EnableDungeonParent(); playerEnterExit.StartDungeonInterior(location); } else { playerEnterExit.EnableExteriorParent(); if (streamingWorld) { streamingWorld.SetAutoReposition(StreamingWorld.RepositionMethods.Origin, Vector3.zero); streamingWorld.suppressWorld = false; } } } // Assign starting gear to player entity DaggerfallUnity.Instance.ItemHelper.AssignStartingGear(playerEntity); // Start game GameManager.Instance.PauseGame(false); DaggerfallUI.Instance.FadeHUDFromBlack(); DaggerfallUI.PostMessage(PostStartMessage); if (OnStartGame != null) OnStartGame(this, null); }
// Create new location game object private GameObject CreateLocationGameObject(int terrain, out DFLocation locationOut) { locationOut = new DFLocation(); // Terrain must have a location DaggerfallTerrain dfTerrain = terrainArray[terrain].terrainObject.GetComponent<DaggerfallTerrain>(); if (!dfTerrain.MapData.hasLocation) return null; // Get location data locationOut = dfUnity.ContentReader.MapFileReader.GetLocation(dfTerrain.MapData.mapRegionIndex, dfTerrain.MapData.mapLocationIndex); if (!locationOut.Loaded) return null; // Get sampled position of height as more accurate than scaled average - thanks Nystul! Terrain terrainInstance = dfTerrain.gameObject.GetComponent<Terrain>(); float scale = terrainInstance.terrainData.heightmapScale.x; float xSamplePos = (TerrainHelper.terrainTileDim - 1) / 2.0f; // get center terrain tile of block float ySamplePos = (TerrainHelper.terrainTileDim - 1) / 2.0f; // get center terrain tile of block Vector3 pos = new Vector3(xSamplePos * scale, 0, ySamplePos * scale); float height = terrainInstance.SampleHeight(pos + terrainArray[terrain].terrainObject.transform.position); // Spawn parent game object for new location //float height = dfTerrain.MapData.averageHeight * TerrainScale; GameObject locationObject = new GameObject(string.Format("DaggerfallLocation [Region={0}, Name={1}]", locationOut.RegionName, locationOut.Name)); locationObject.transform.parent = this.transform; //locationObject.hideFlags = HideFlags.HideAndDontSave; locationObject.transform.position = terrainArray[terrain].terrainObject.transform.position + new Vector3(0, height, 0); DaggerfallLocation dfLocation = locationObject.AddComponent<DaggerfallLocation>() as DaggerfallLocation; dfLocation.SetLocation(locationOut, false); // Raise event RaiseOnCreateLocationGameObjectEvent(dfLocation); return locationObject; }