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.MapID = 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 = (MapsFile.Climates)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; summary.LegacyLocation = location; // Assign starting climate CurrentSeason = ClimateSeason.Summer; CurrentClimate = summary.Climate; CurrentNatureSet = summary.Nature; // Perform layout if (performLayout) { LayoutLocation(ref location); ApplyClimateSettings(); } // Set location rect SetLocationRect(); // Seal location isSet = true; }
// Calculate location rect in world units private void CalculateWorldLocationRect() { if (!hasCurrentLocation) { return; } // Convert world coords to map pixel coords then back again // This finds the absolute SW origin of this map pixel in world coords DFPosition mapPixel = CurrentMapPixel; DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); // Find tile offset point using same logic as terrain helper DFPosition tileOrigin = TerrainHelper.GetLocationTerrainTileOrigin(CurrentLocation); // Adjust world origin by tileorigin*2 in world units worldOrigin.X += (tileOrigin.X * 2) * MapsFile.WorldMapTileDim; worldOrigin.Y += (tileOrigin.Y * 2) * MapsFile.WorldMapTileDim; // Get width and height of location in world units int width = currentLocation.Exterior.ExteriorData.Width * MapsFile.WorldMapRMBDim; int height = currentLocation.Exterior.ExteriorData.Height * MapsFile.WorldMapRMBDim; // Set location rect in world coordinates locationWorldRectMinX = worldOrigin.X; locationWorldRectMaxX = worldOrigin.X + width; locationWorldRectMinZ = worldOrigin.Y; locationWorldRectMaxZ = worldOrigin.Y + height; }
/// <summary> /// Helper to get location rect in world coordinates. /// </summary> /// <param name="location">Target location.</param> /// <returns>Location rect in world space. xMin,yMin is SW corner. xMax,yMax is NE corner.</returns> public static Rect GetLocationRect(DFLocation location) { // This finds the absolute SW origin of map pixel in world coords DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(location.MapTableData.Longitude, location.MapTableData.Latitude); DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); // Find tile offset point using same logic as terrain helper DFPosition tileOrigin = TerrainHelper.GetLocationTerrainTileOrigin(location); // Adjust world origin by tileorigin*2 in world units worldOrigin.X += (tileOrigin.X * 2) * MapsFile.WorldMapTileDim; worldOrigin.Y += (tileOrigin.Y * 2) * MapsFile.WorldMapTileDim; // Get width and height of location in world units int width = location.Exterior.ExteriorData.Width * MapsFile.WorldMapRMBDim; int height = location.Exterior.ExteriorData.Height * MapsFile.WorldMapRMBDim; // Create location rect in world coordinates Rect locationRect = new Rect() { xMin = worldOrigin.X, xMax = worldOrigin.X + width, yMin = worldOrigin.Y, yMax = worldOrigin.Y + height, }; return(locationRect); }
protected void BeginPathTravel(DFPosition targetPixel, bool starting = true) { if (targetPixel != null) { lastCrossed = 0; travelControlUI.SetDestination(road ? MsgFollowRoad : MsgFollowTrack); DFPosition targetMPworld = MapsFile.MapPixelToWorldCoord(targetPixel.X, targetPixel.Y); Rect targetRect = SetLocationRects(targetPixel, targetMPworld) ? locationBorderRect : new Rect(targetMPworld.X + MidLo, targetMPworld.Y + MidLo, PSize, PSize); DestinationCautious = true; if (starting && alwaysUseStartingAccel) { travelControlUI.TimeAcceleration = defaultStartingAccel; } travelControlUI.HalfLimit = true; if (playerAutopilot == null) { playerAutopilot = new PlayerAutoPilot(targetPixel, targetRect, road ? RecklessTravelMultiplier : CautiousTravelMultiplier); playerAutopilot.OnArrival += SelectNextPath; } else { playerAutopilot.InitTargetRect(targetPixel, targetRect, road ? RecklessTravelMultiplier : CautiousTravelMultiplier); } InitTravelUI(); } }
// Calculate location rect in world units private void CalculateWorldLocationRect() { if (!hasCurrentLocation) { return; } // Convert world coords to map pixel coords then back again // This finds the SW origin of this map pixel in world coords DFPosition mapPixel = CurrentMapPixel; DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); // Calculate centre point of this terrain area in world coords DFPosition centrePoint = new DFPosition( worldOrigin.X + (int)MapsFile.WorldMapTerrainDim / 2, worldOrigin.Y + (int)MapsFile.WorldMapTerrainDim / 2); // Get width and height of location in world units int width = currentLocation.Exterior.ExteriorData.Width * (int)MapsFile.WorldMapRMBDim; int height = currentLocation.Exterior.ExteriorData.Height * (int)MapsFile.WorldMapRMBDim; // Set true location rect in world coordinates locationWorldRectMinX = centrePoint.X - width / 2; locationWorldRectMaxX = centrePoint.X + width / 2; locationWorldRectMinZ = centrePoint.Y - height / 2; locationWorldRectMaxZ = centrePoint.Y + height / 2; }
// Teleport to new coordinates and re-init world public void TeleportToCoordinates(int mapPixelX, int mapPixelY) { DFPosition worldPos = MapsFile.MapPixelToWorldCoord(mapPixelX, mapPixelY); LocalPlayerGPS.WorldX = worldPos.X; LocalPlayerGPS.WorldZ = worldPos.Y; InitWorld(true); }
private void InitLocationRects(DFPosition mapPixel) { if (RoadsIntegration && (playerAutopilot == null || DestinationName != null)) { DFPosition worldOriginMP = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); SetLocationRects(mapPixel, worldOriginMP); } }
public void __EditorApplyToPlayerGPS() { if (LocalPlayerGPS) { DFPosition pos = MapsFile.MapPixelToWorldCoord(MapPixelX, MapPixelY); LocalPlayerGPS.WorldX = pos.X; LocalPlayerGPS.WorldZ = pos.Y; } }
private void DeployFullBlownVampirism() { const int deathIsNotEternalTextID = 401; // Cancel rest window if sleeping if (DaggerfallUI.Instance.UserInterfaceManager.TopWindow is DaggerfallRestWindow) { (DaggerfallUI.Instance.UserInterfaceManager.TopWindow as DaggerfallRestWindow).CloseWindow(); } // Halt random enemy spawns for next playerEntity update so player isn't bombarded by spawned enemies after transform time GameManager.Instance.PlayerEntity.PreventEnemySpawns = true; // Reset legal reputation for all regions and strip player of guild memberships ResetLegalRepAndGuildMembership(); // Raise game time to an evening two weeks later float raiseTime = (2 * DaggerfallDateTime.SecondsPerWeek) + (DaggerfallDateTime.DuskHour + 1 - DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.Hour) * 3600; DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.RaiseTime(raiseTime); // Transfer player to a random cemetery // Always using a small cemetery, nothing spoils that first vampire moment like being lost the guts of a massive dungeon // Intentionally not spawning enemies, for this time the PLAYER is the monster lurking inside the crypt DFLocation location = GetRandomCemetery(); DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(location.MapTableData.Longitude, location.MapTableData.Latitude); DFPosition worldPos = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); GameManager.Instance.PlayerEnterExit.RespawnPlayer( worldPos.X, worldPos.Y, true, false); // Assign vampire spells to spellbook GameManager.Instance.PlayerEntity.AssignPlayerVampireSpells(InfectionVampireClan); // Fade in from black DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack(1.0f); // Start permanent vampirism effect stage two EntityEffectBundle bundle = GameManager.Instance.PlayerEffectManager.CreateVampirismCurse(); GameManager.Instance.PlayerEffectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows); // Display popup DaggerfallMessageBox mb = DaggerfallUI.MessageBox(deathIsNotEternalTextID); mb.Show(); // Terminate custom disease lifecycle EndDisease(); }
byte IsPlayerOnPath(PlayerGPS playerGPS, byte pathsDataPt) { if (pathsDataPt == 0) { return(0); } byte onPath = 0; DFPosition worldOriginMP = MapsFile.MapPixelToWorldCoord(playerGPS.CurrentMapPixel.X, playerGPS.CurrentMapPixel.Y); DFPosition posInMp = new DFPosition(playerGPS.WorldX - worldOriginMP.X, playerGPS.WorldZ - worldOriginMP.Y); if ((pathsDataPt & N) != 0 && posInMp.X > MidLo && posInMp.X < MidHi && posInMp.Y > MidLo) { onPath = (byte)(onPath | N); } if ((pathsDataPt & E) != 0 && posInMp.Y > MidLo && posInMp.Y < MidHi && posInMp.X > MidLo) { onPath = (byte)(onPath | E); } if ((pathsDataPt & S) != 0 && posInMp.X > MidLo && posInMp.X < MidHi && posInMp.Y < MidHi) { onPath = (byte)(onPath | S); } if ((pathsDataPt & W) != 0 && posInMp.Y > MidLo && posInMp.Y < MidHi && posInMp.X < MidHi) { onPath = (byte)(onPath | W); } if ((pathsDataPt & NE) != 0 && (Mathf.Abs(posInMp.X - posInMp.Y) < PSize) && posInMp.X > MidLo) { onPath = (byte)(onPath | NE); } if ((pathsDataPt & SW) != 0 && (Mathf.Abs(posInMp.X - posInMp.Y) < PSize) && posInMp.X < MidHi) { onPath = (byte)(onPath | SW); } if ((pathsDataPt & NW) != 0 && (Mathf.Abs(posInMp.X - (MPworldUnits - posInMp.Y)) < PSize) && posInMp.X < MidHi) { onPath = (byte)(onPath | NW); } if ((pathsDataPt & SE) != 0 && (Mathf.Abs(posInMp.X - (MPworldUnits - posInMp.Y)) < PSize) && posInMp.X > MidLo) { onPath = (byte)(onPath | SE); } return(onPath); }
/// <summary> /// Convert a virtual world position back into scene space. /// This is specific to the peered location due to floating origin. /// Some precision loss is expected converting back to scene space. /// </summary> /// <param name="worldPosition">World location to convert to nearest point in scene space.</param> /// <param name="refineY">Attempt to refine Y position to actual terrain data.</param> /// <returns>Scene Vector3 position.</returns> public Vector3 WorldToScenePosition(DFPosition worldPosition, bool refineY = true) { // Validate DaggerfallLocation if (!dfLocation || dfLocation.Summary.MapID == 0) { throw new Exception(noLocationError); } // Get location origin in both scene and world // The SW origin of location in scene spaces aligns with SW terrain tile origin in world space Vector3 locationOrigin = dfLocation.transform.position; DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(dfLocation.Summary.MapPixelX, dfLocation.Summary.MapPixelY); // Get difference between origin and target position in scene space Vector3 offset = new Vector3( (worldPosition.X - worldOrigin.X) / StreamingWorld.SceneMapRatio, 0, (worldPosition.Y - worldOrigin.Y) / StreamingWorld.SceneMapRatio); // Calculate X-Z position and use Y from location origin // World > scene conversion results in mobile being aligned exactly on edge of tile in scene // Move the mobile transform a half-tile into centre so it appears to be properly aligned Vector3 result = locationOrigin + offset; result.x += HalfTile; result.z -= HalfTile; // Attempt to refine Y by sampling terrain at this map pixel position if (refineY) { GameObject terrainObject = GameManager.Instance.StreamingWorld.GetTerrainFromPixel(dfLocation.Summary.MapPixelX, dfLocation.Summary.MapPixelY); if (terrainObject) { // Sample actual terrain height at this scene position for Y and adjust for world compensation Terrain terrain = terrainObject.GetComponent <Terrain>(); float height = terrain.SampleHeight(result); result.y = height + GameManager.Instance.StreamingWorld.WorldCompensation.y; } } return(result); }
/// <summary> /// Convert a scene position back into virtual world space. /// This is specific to the peered location due to floating origin. /// </summary> /// <param name="scenePosition">Scene position to convert to nearest point in world space.</param> /// <returns>World DFPosition.</returns> public DFPosition SceneToWorldPosition(Vector3 scenePosition) { // Validate DaggerfallLocation if (!dfLocation || dfLocation.Summary.MapID == 0) { throw new Exception(noLocationError); } // Get location origin in both scene and world // The SW origin of location in scene spaces aligns with SW terrain tile origin in world space Vector3 locationOrigin = dfLocation.transform.position; DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(dfLocation.Summary.MapPixelX, dfLocation.Summary.MapPixelY); // Get difference between origin and target position in scene space Vector3 difference = scenePosition - locationOrigin; // Convert difference into Daggerfall units and apply to origin in world space DFPosition result = new DFPosition( (int)(difference.x * StreamingWorld.SceneMapRatio) + worldOrigin.X, (int)(difference.z * StreamingWorld.SceneMapRatio) + worldOrigin.Y); return(result); }
public override void Update(Task caller) { base.Update(caller); // Do nothing while player respawning if (GameManager.Instance.PlayerEnterExit.IsRespawning) { return; } // Handle resume on next tick of action after respawn process complete if (resumePending) { GameObject player = GameManager.Instance.PlayerObject; player.transform.position = resumePosition; resumePending = false; SetComplete(); return; } // Create SiteLink if not already present if (!QuestMachine.HasSiteLink(ParentQuest, targetPlace)) { QuestMachine.CreateSiteLink(ParentQuest, targetPlace); } // Attempt to get Place resource Place place = ParentQuest.GetPlace(targetPlace); if (place == null) { return; } // Get selected spawn QuestMarker for this Place bool usingMarker = false; QuestMarker marker = new QuestMarker(); if (targetMarker >= 0 && targetMarker < place.SiteDetails.questSpawnMarkers.Length) { marker = place.SiteDetails.questSpawnMarkers[targetMarker]; usingMarker = true; } // Attempt to get location data - using GetLocation(regionName, locationName) as it can support all locations DFLocation location; if (!DaggerfallUnity.Instance.ContentReader.GetLocation(place.SiteDetails.regionName, place.SiteDetails.locationName, out location)) { return; } // Spawn inside dungeon at this world position DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel((int)location.MapTableData.Longitude, location.MapTableData.Latitude); DFPosition worldPos = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y); GameManager.Instance.PlayerEnterExit.RespawnPlayer( worldPos.X, worldPos.Y, true, true); // Determine start position if (usingMarker) { // Use specified quest marker Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide); resumePosition = dungeonBlockPosition + marker.flatPosition; } else { // Use first quest marker marker = place.SiteDetails.questSpawnMarkers[0]; Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide); resumePosition = dungeonBlockPosition + marker.flatPosition; } resumePending = true; }