示例#1
0
        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;
        }
示例#2
0
        // 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;
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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);
        }
示例#7
0
 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();
        }
示例#10
0
        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);
        }
示例#11
0
        /// <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);
        }
示例#12
0
        /// <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);
        }
示例#13
0
        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;
        }