//##Lypyl
 /// <summary>
 /// Get distance between 2 world points represented by DFPosition objects
 /// Returns -1 on error
 /// </summary>
 public double Distance(DFPosition pos)
 {
     double dist = -1;
     try
     {
         dist = Math.Sqrt(Math.Pow(Math.Abs(X - pos.X), 2) + Math.Pow(Math.Abs(Y - pos.Y), 2));
     }
     catch (Exception ex)
     {
         DaggerfallWorkshop.DaggerfallUnity.LogMessage(ex.Message, true);
     }
     return dist;
 }
 void CreateCrossHair(DFPosition pos, int regionIndex = -1)
 {
     if (regionIndex == -1)
         regionIndex = GetPlayerRegion();
     CreateCrossHair(pos.X, pos.Y, regionIndex);
 }
Exemplo n.º 3
0
        // Teleports player to a random location in a random region
        IEnumerator TeleportRandomLocation()
        {
            if (!CanTeleport())
                yield break;

            // Find a random location
            UnityEngine.Random.seed = UnityEngine.Time.renderedFrameCount;
            DFPosition mapPos = new DFPosition();
            bool found = false;
            while (!found)
            {
                // Get random region
                int regionIndex = UnityEngine.Random.Range(0, dfUnity.ContentReader.MapFileReader.RegionCount);
                DFRegion region = dfUnity.ContentReader.MapFileReader.GetRegion(regionIndex);
                if (region.LocationCount == 0)
                    continue;

                // Get random location
                int locationIndex = UnityEngine.Random.Range(0, region.MapTable.Length);
                DFLocation location = dfUnity.ContentReader.MapFileReader.GetLocation(regionIndex, locationIndex);
                if (!location.Loaded)
                    continue;

                // Check inside range
                mapPos = MapsFile.LongitudeLatitudeToMapPixel((int)location.MapTableData.Longitude, (int)location.MapTableData.Latitude);
                if ((mapPos.X >= TerrainHelper.minMapPixelX + 2 && mapPos.X < TerrainHelper.maxMapPixelX - 2) &&
                    (mapPos.Y >= TerrainHelper.minMapPixelY + 2 && mapPos.Y < TerrainHelper.maxMapPixelY - 2))
                {
                    found = true;
                }
            }

            // Teleport
            if (titleScreen)
                titleScreen.ShowTitle = true;
            yield return new WaitForEndOfFrame();
            streamingWorld.TeleportToCoordinates(mapPos.X, mapPos.Y);
        }
 //overloaded variant
 void InjectMaterialProperties(DFPosition worldPos)
 {
     InjectMaterialProperties(worldPos.X, worldPos.Y);
 }
Exemplo n.º 5
0
 protected virtual void RaiseOnMapPixelChangedEvent(DFPosition mapPixel)
 {
     if (OnMapPixelChanged != null)
         OnMapPixelChanged(mapPixel);
 }
Exemplo n.º 6
0
        bool CheckPosition()
        {
            DFPosition mapPixel = StreamingWorld.LocalPlayerGPS.CurrentMapPixel;
            if (mapPixel.X != currentMapPixel.X ||
                mapPixel.Y != currentMapPixel.Y)
            {
                lastMapPixel = currentMapPixel;
                currentMapPixel = mapPixel;
                return true;
            }

            return false;
        }
Exemplo n.º 7
0
        // 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>
        /// Converts world coord back to longitude and latitude.
        /// </summary>
        /// <param name="worldX">World X position in native Daggerfall units.</param>
        /// <param name="worldZ">World Z position in native Daggerfall units.</param>
        /// <returns>Longitude and latitude.</returns>
        public static DFPosition WorldCoordToLongitudeLatitude(int worldX, int worldZ)
        {
            DFPosition mapPixel = WorldCoordToMapPixel(worldX, worldZ);
            DFPosition pos = new DFPosition();
            pos.X = mapPixel.X * 128;
            pos.Y = (499 - mapPixel.Y) * 128;

            return pos;
        }
Exemplo n.º 9
0
        // 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(int width, int height)
        {
            DFPosition result = new DFPosition();
            result.X = (RMBLayout.RMBTilesPerTerrain - width * RMBLayout.RMBTilesPerBlock) / 2;
            result.Y = (RMBLayout.RMBTilesPerTerrain - height * RMBLayout.RMBTilesPerBlock) / 2;

            // 1x1 locations seem to always use 72, 55 as origin rather than 56, 56 as expected
            if (width == 1 && height == 1)
            {
                result.X = 72;
                result.Y = 55;
            }

            return result;
        }
        // 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;
        }
        void UpdateWorldTerrain(DFPosition worldPos)
        {         
            if (worldTerrainGameObject != null) // sometimes it can happen that this point is reached before worldTerrainGameObject was created, in such case we just skip
            {
                // do not forget to update shader parameters (needed for correct fragment discarding for terrain tiles of map pixels inside TerrainDistance-1 area (the detailed terrain))
                Terrain terrain = worldTerrainGameObject.GetComponent<Terrain>();
                terrain.materialTemplate.SetInt("_PlayerPosX", this.playerGPS.CurrentMapPixel.X);
                terrain.materialTemplate.SetInt("_PlayerPosY", this.playerGPS.CurrentMapPixel.Y);

                Vector3 offset = new Vector3(0.0f, 0.0f, 0.0f);
                updatePositionWorldTerrain(ref worldTerrainGameObject, offset);

                bool doSeasonalTexturesUpdate = shouldUpdateSeasonalTextures();

                if (doSeasonalTexturesUpdate)
                {
                    Material mat = terrain.materialTemplate;
                    updateMaterialSeasonalTextures(ref mat, currentSeason); // this is necessary since climate changes may occur after UpdateWorldTerrain() has been invoked, TODO: an event would be ideal to trigger updateSeasonalTextures() instead
                    terrain.materialTemplate = mat;
                }              

                // make terrain transition ring update on next iteration in Update() as soon as no terrain transition ring update is still in progress
                updateTerrainTransitionRing = true;

                if (doSeasonalTexturesUpdate)
                {
                    //updateSeasonalTexturesTerrainTransitionRing();
                    terrainTransitionRingUpdateSeasonalTextures = true;
                }

                Resources.UnloadUnusedAssets();

                //System.GC.Collect();
            }
        }
 //player teleporting
 /// <summary>
 /// Updates enhanced sky objects
 /// </summary>
 /// <param name="worldPos"></param>
 public void EnhancedSkyUpdate(DFPosition worldPos)
 {
     //Debug.Log("EnhancedSkyUpdate");
     if (updateSkyEvent != null && SkyManager.instance.EnhancedSkyCurrentToggle)   //only trigger if eSky on
     {
         //Debug.Log("triggering fastTravelEvent");
         updateSkyEvent(IsOvercast);
     }
 }
 //// Find location by name
 //bool FindLocation(string name, out DFRegion.RegionMapTable locationInfo)
 //{
 //    locationInfo = new DFRegion.RegionMapTable();
 //    if (string.IsNullOrEmpty(name))
 //    {
 //        return false;
 //    }
 //    string[] locations = regionRecord.Region.MapNames.OrderBy(p => p).ToArray();
 //    name = name.ToLower();
 //    for (int i = 0; i < locations.Count(); i++)
 //    {
 //        if (locations[i].ToLower().StartsWith(name))                        // Valid location found,
 //        {
 //            if (!regionRecord.Region.MapNameLookup.ContainsKey(locations[i]))
 //            {
 //                DaggerfallUnity.LogMessage("Error: location name key not found in Region MapNameLookup dictionary");
 //                return false;
 //            }
 //            int index = regionRecord.Region.MapNameLookup[locations[i]];
 //            locationInfo = regionRecord.Region.MapTable[index];
 //            return true;
 //        }
 //        else if (locations[i][0] > name[0])
 //        {
 //            return false;
 //        }
 //    }
 //    return false;
 //}
 // Teleports player to position
 void TravelToLocation(DFPosition pos)
 {
     TravelToLocation(pos.X, pos.Y);
 }
        // Gets current player position in map pixels
        DFPosition GetPlayerMapPosition()
        {
            DFPosition position = new DFPosition();
            PlayerGPS playerGPS = GameManager.Instance.PlayerGPS;
            if (playerGPS)
                position = playerGPS.CurrentMapPixel;

            return position;
        }
Exemplo n.º 15
0
        // Init world at startup or when player teleports
        private void InitWorld(bool repositionPlayer = false)
        {
            // Cannot init world without a player, as world positions around player
            if (LocalPlayerGPS == null)
                return;

            // Player must be at origin on init for proper world sync
            // Starting position will be assigned when terrain ready
            LocalPlayerGPS.transform.position = Vector3.zero;

            // Init streaming world
            ClearStreamingWorld();
            worldCompensation = Vector3.zero;
            mapOrigin = LocalPlayerGPS.CurrentMapPixel;
            MapPixelX = mapOrigin.X;
            MapPixelY = mapOrigin.Y;
            playerStartPos = new Vector3(LocalPlayerGPS.transform.position.x, 0, LocalPlayerGPS.transform.position.z);
            lastPlayerPos = playerStartPos;

            // This value is the amount of scene player movement equivalent to 1 native world map unit
            sceneMapRatio = 1f / MeshReader.GlobalScale;

            // Set player world position to match PlayerGPS
            // StreamingWorld will then sync player to world
            worldX = LocalPlayerGPS.WorldX;
            worldZ = LocalPlayerGPS.WorldZ;

            init = true;
            this.repositionPlayer = repositionPlayer;
            RaiseOnInitWorldEvent();
        }
        /// <summary>
        /// Converts map pixel coord to longitude and latitude.
        /// </summary>
        /// <param name="mapPixelX">Map pixel X.</param>
        /// <param name="mapPixelY">Map pixel Y.</param>
        /// <returns></returns>
        public static DFPosition MapPixelToLongitudeLatitude(int mapPixelX, int mapPixelY)
        {
            DFPosition pos = new DFPosition();
            pos.X = mapPixelX * 128;
            pos.Y = (499 - mapPixelY) * 128;

            return pos;
        }
        /// <summary>
        /// Converts map pixel to world coord.
        /// </summary>
        /// <param name="worldX">Map pixel X.</param>
        /// <param name="worldZ">Map pixel Y.</param>
        /// <returns>World position.</returns>
        public static DFPosition MapPixelToWorldCoord(int mapPixelX, int mapPixelY)
        {
            DFPosition pos = new DFPosition();
            pos.X = mapPixelX * 32768;
            pos.Y = (499 - mapPixelY) * 32768;

            return pos;
        }
Exemplo n.º 18
0
 /// <summary>
 /// Returns terrain GameObject from mapPixel, or null if
 /// no terrain objects are mapped to that pixel
 /// </summary>
 public GameObject GetTerrainFromPixel(DFPosition mapPixel)
 {
     return GetTerrainFromPixel(mapPixel.X, mapPixel.Y);
 }
        /// <summary>
        /// Converts world coord to nearest map pixel.
        /// </summary>
        /// <param name="worldX">World X position in native Daggerfall units.</param>
        /// <param name="worldZ">World Z position in native Daggerfall units.</param>
        /// <returns>Map pixel position.</returns>
        public static DFPosition WorldCoordToMapPixel(int worldX, int worldZ)
        {
            DFPosition pos = new DFPosition();
            pos.X = worldX / 32768;
            pos.Y = 499 - (worldZ / 32768);

            return pos;
        }
Exemplo n.º 20
0
 protected virtual void RaiseOnTeleportToCoordinatesEvent(DFPosition worldPos)
 {
     if (OnTeleportToCoordinates != null)
         OnTeleportToCoordinates(worldPos);
 }
Exemplo n.º 21
0
 // Copies a subset of Color32 array into XY position of another Color32 array
 public static void CopyColors(ref Color32[] src, ref Color32[] dst, DFSize srcSize, DFSize dstSize, DFPosition srcPos, DFPosition dstPos, DFSize copySize)
 {
     for (int y = 0; y < copySize.Height; y++)
     {
         for (int x = 0; x < copySize.Width; x++)
         {
             Color32 col = src[(srcPos.Y + y) * srcSize.Width + (srcPos.X + x)];
             dst[(dstPos.Y + y) * dstSize.Width + (dstPos.X + x)] = col;
         }
     }
 }
Exemplo n.º 22
0
        // Init world at startup or when player teleports
        private void InitWorld()
        {
            // Cannot init world without a player, as world positions around player
            // Also do nothing if world is on hold at start
            if (LocalPlayerGPS == null || suppressWorld)
                return;

            // Player must be at origin on init for proper world sync
            // Starting position will be assigned when terrain ready based on respositionMethod
            LocalPlayerGPS.transform.position = Vector3.zero;

            // Raise OnPreInitWorld event
            RaiseOnPreInitWorldEvent();

            // Init streaming world
            ClearStreamingWorld();
            worldCompensation = Vector3.zero;
            mapOrigin = LocalPlayerGPS.CurrentMapPixel;
            MapPixelX = mapOrigin.X;
            MapPixelY = mapOrigin.Y;
            playerStartPos = new Vector3(LocalPlayerGPS.transform.position.x, 0, LocalPlayerGPS.transform.position.z);
            lastPlayerPos = playerStartPos;

            // Set player world position to match PlayerGPS
            // StreamingWorld will then sync player to world
            worldX = LocalPlayerGPS.WorldX;
            worldZ = LocalPlayerGPS.WorldZ;

            init = true;
            RaiseOnInitWorldEvent();
        }
Exemplo n.º 23
0
 void Initialize()
 {
     playerMotor.ClearActivePlatform();
     DFPosition mapPixel = StreamingWorld.LocalPlayerGPS.CurrentMapPixel;
     currentMapPixel = mapPixel;
     lastMapPixel = mapPixel;
 }
        //Gets path from player location to destination
        void GetPath(DFPosition endPos)
        {
            Vector2[] directions = new Vector2[] { new Vector2(0, 1), new Vector2(1, 0), new Vector2(0, -1), new Vector2(-1, 0), new Vector2(1, 1), new Vector2(-1, 1), new Vector2(1, -1), new Vector2(-1, -1) };
            //Vector2[] directions = new Vector2[] { new Vector2(0, 1), new Vector2(1, 0), new Vector2(0, -1), new Vector2(-1, 0)}; //4 direction movement
            Vector2 current = new Vector2(GameManager.Instance.PlayerGPS.CurrentMapPixel.X, GameManager.Instance.PlayerGPS.CurrentMapPixel.Y);
            Vector2 end = new Vector2(endPos.X, endPos.Y);
            terrains.Clear();
            while(current != end)
            {
                float distance = Vector2.Distance(current,end);
                int selection = 0;

                for (int i = 0; i < directions.Length; i++)
                {
                    Vector2 next = current + directions[i];
                    if (current.x < 0 || current.y < 0 || current.x >= DaggerfallConnect.Arena2.MapsFile.MaxMapPixelX || current.y >= DaggerfallConnect.Arena2.MapsFile.MaxMapPixelY)
                        continue;

                    float check = Vector2.Distance(next, end);
                    if(check < distance)
                    {
                        distance = check;
                        selection = i;
                    }

                }

                current += directions[selection];
                terrains.Add((TerrainTypes)DaggerfallUnity.Instance.ContentReader.MapFileReader.GetClimateIndex((int)current.x, (int)current.y));
            }
        }
Exemplo n.º 25
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 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;
        }
Exemplo n.º 26
0
        public static Texture2D GetTextureFromCifRci(string name, int record, out DFPosition offset, int frame = 0, TextureFormat format = TextureFormat.ARGB32)
        {
            offset = new DFPosition();
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return null;

            CifRciFile cifRciFile = new CifRciFile(Path.Combine(dfUnity.Arena2Path, name), FileUsage.UseMemory, true);
            cifRciFile.LoadPalette(Path.Combine(dfUnity.Arena2Path, cifRciFile.PaletteName));
            DFBitmap bitmap = cifRciFile.GetDFBitmap(record, frame);
            Texture2D texture = new Texture2D(bitmap.Width, bitmap.Height, format, false);
            texture.SetPixels32(cifRciFile.GetColor32(bitmap, 0));
            texture.Apply(false, true);
            texture.filterMode = DaggerfallUI.Instance.GlobalFilterMode;

            offset = cifRciFile.GetOffset(record);

            return texture;
        }
        // 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);
        }
Exemplo n.º 28
0
        public static Texture2D GetTextureFromImg(string name, out DFPosition offset, TextureFormat format = TextureFormat.ARGB32)
        {
            offset = new DFPosition();

            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return null;

            ImgFile imgFile = new ImgFile(Path.Combine(dfUnity.Arena2Path, name), FileUsage.UseMemory, true);
            imgFile.LoadPalette(Path.Combine(dfUnity.Arena2Path, imgFile.PaletteName));
            Texture2D texture = GetTextureFromImg(imgFile, format);
            texture.filterMode = DaggerfallUI.Instance.GlobalFilterMode;

            offset = imgFile.ImageOffset;

            return texture;
        }
        /// <summary>
        /// Converts longitude and latitude to map pixel coordinates.
        /// The world is 1000x500 map pixels.
        /// </summary>
        /// <param name="longitude">Longitude position.</param>
        /// <param name="latitude">Latitude position.</param>
        /// <returns>Map pixel position.</returns>
        public static DFPosition LongitudeLatitudeToMapPixel(int longitude, int latitude)
        {
            DFPosition pos = new DFPosition();
            pos.X = longitude / 128;
            pos.Y = 499 - (latitude / 128);

            return pos;
        }
        void UpdateWorldTerrain(DFPosition worldPos)
        {         
            if (worldTerrainGameObject != null) // sometimes it can happen that this point is reached before worldTerrainGameObject was created, in such case we just skip
            {
                // do not forget to update shader parameters (needed for correct fragment discarding for terrain tiles of map pixels inside TerrainDistance-1 area (the detailed terrain))
                Terrain terrain = worldTerrainGameObject.GetComponent<Terrain>();
                terrain.materialTemplate.SetInt("_PlayerPosX", this.playerGPS.CurrentMapPixel.X);
                terrain.materialTemplate.SetInt("_PlayerPosY", this.playerGPS.CurrentMapPixel.Y);

                Vector3 offset = new Vector3(0.0f, 0.0f, 0.0f);
                updatePositionWorldTerrain(ref worldTerrainGameObject, offset);

                updateSeasonalTextures();

                Resources.UnloadUnusedAssets();

                //System.GC.Collect();
            }
        }