Пример #1
0
        private static void PlaceWagon(bool fromSave = false)
        {
            if (fromSave == false)
            {
                WagonMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
                if (!transportManager.HasHorse())
                {
                    SetWagonPositionAndRotation(true);
                    DaggerfallUI.MessageBox("You have no horse to pull your wagon.");
                    ItemCollection playerItems = GameManager.Instance.PlayerEntity.Items;
                    for (int i = 0; i < playerItems.Count; i++)
                    {
                        DaggerfallUnityItem item = playerItems.GetItem(i);
                        if (item != null && item.IsOfTemplate(ItemGroups.Transportation, (int)Transportation.Small_cart))
                        {
                            playerItems.RemoveItem(item);
                        }
                    }
                }
                else
                {
                    SetWagonPositionAndRotation();
                }
            }
            else
            {
                PlaceWagonOnGround();
            }
            Wagon = MeshReplacement.ImportCustomGameobject(wagonModelID, null, WagonMatrix);
            if (Wagon == null)
            {
                Wagon = GameObjectHelper.CreateDaggerfallMeshGameObject(wagonModelID, null);
            }

            Wagon.transform.SetPositionAndRotation(WagonPosition, WagonRotation);
            if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon)
            {
                Wagon.SetActive(false);
            }
            else
            {
                Wagon.SetActive(true);
            }
            WagonDeployed = true;
        }
Пример #2
0
 private static void PlayerGPS_OnMapPixelChanged(DFPosition mapPixel)
 {
     // Check if near Northrock Fort
     if (mapPixel.X >= 937 && mapPixel.X <= 939 && mapPixel.Y >= 50 && mapPixel.Y <= 52)
     {
         // In Fort MP 2 messages, in adjacent MP message with track direction
         if (mapPixel.X == 938 && mapPixel.Y == 51)
         {
             DaggerfallUI.AddHUDText(FORT_VERYNEAR1, 5);
             DaggerfallUI.AddHUDText(FORT_VERYNEAR2, 5);
         }
         else if (mapPixel.X == 938 && mapPixel.Y == 50)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "south"), 5);
         }
         else if (mapPixel.X == 939 && mapPixel.Y == 50)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "south west"), 5);
         }
         else if (mapPixel.X == 939 && mapPixel.Y == 51)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "west"), 5);
         }
         else if (mapPixel.X == 939 && mapPixel.Y == 52)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "north west"), 5);
         }
         else if (mapPixel.X == 938 && mapPixel.Y == 52)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "north"), 5);
         }
         else if (mapPixel.X == 937 && mapPixel.Y == 52)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "north east"), 5);
         }
         else if (mapPixel.X == 937 && mapPixel.Y == 51)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "east"), 5);
         }
         else if (mapPixel.X == 937 && mapPixel.Y == 50)
         {
             DaggerfallUI.AddHUDText(String.Format(FORT_NEAR, "south east"), 5);
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Gets travel time based on overworld map logic.
        /// </summary>
        /// <param name="place">Target place resource. If null will use first place defined in quest.</param>
        /// <param name="returnTrip">Use return trip multiplier.</param>
        /// <returns>Travel time in seconds.</returns>
        int GetTravelTimeInSeconds(Place place, bool returnTrip = true)
        {
            if (place == null)
            {
                // Get first place resource from quest
                QuestResource[] placeResources = ParentQuest.GetAllResources(typeof(Place));
                if (placeResources == null || placeResources.Length == 0)
                {
                    Debug.LogError("Clock wants a travel time but quest has no Place resources.");
                    return(0);
                }
                place = (Place)placeResources[0];
            }

            // Get target location from place resource
            DFLocation location;

            if (!DaggerfallUnity.Instance.ContentReader.GetLocation(place.SiteDetails.regionName, place.SiteDetails.locationName, out location))
            {
                Debug.LogErrorFormat("Could not find Quest Place {0}/{1}", place.SiteDetails.regionName, place.SiteDetails.locationName);
                return(0);
            }

            // Get end position in map pixel coordinates
            DFPosition endPos = MapsFile.WorldCoordToMapPixel(location.Exterior.RecordElement.Header.X, location.Exterior.RecordElement.Header.Y);

            // Create a path to location
            // Use the most cautious time possible allowing for player to camp out or stop at inns along the way
            TravelTimeCalculator travelTimeCalculator = new TravelTimeCalculator();
            int travelTimeMinutes = travelTimeCalculator.CalculateTravelTime(endPos, true, false, false, false, true);

            // Apply return trip multiplier
            if (returnTrip)
            {
                travelTimeMinutes = (int)(travelTimeMinutes * returnTripMultiplier);
            }

            // Always allow at least 1 day for travel time
            if (travelTimeMinutes < 1440)
            {
                travelTimeMinutes = 1440;
            }

            return(GetTimeInSeconds(0, 0, travelTimeMinutes));
        }
Пример #4
0
        void MovingForward()
        {
            // Push mobile towards target position
            Vector3 direction = Vector3.Normalize(targetScenePosition - transform.position);

            transform.position += (direction * movementSpeed) * Time.deltaTime;

            // Update distance to target
            distanceToTarget = Vector3.Distance(transform.position, targetScenePosition);

            // If distance below threshold start seeking a new tile
            if (distanceToTarget < 0.1f)
            {
                currentNavPosition = targetNavPosition;
                ChangeState(MobileStates.SeekingTile);
                moveCount++;
            }
        }
Пример #5
0
        int GetNextNavPositionWeight(MobileDirection direction)
        {
            // Must have a current position on navgrid
            if (!cityNavigation || currentNavPosition.X == -1 || currentNavPosition.Y == -1)
            {
                return(0);
            }

            // Get next nav position and regard occupied tiles as weight 0
            DFPosition nextPosition = GetNextNavPosition(direction);

            if (cityNavigation.HasFlags(nextPosition, CityNavigation.TileFlags.Occupied))
            {
                return(0);
            }

            return(cityNavigation.GetNavGridWeightLocal(nextPosition));
        }
Пример #6
0
 private static void DeployTent(bool fromSave = false)
 {
     if (fromSave == false)
     {
         TentMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
         SetTentPositionAndRotation();
     }
     //Attempt to load a model replacement
     Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix);
     if (Tent == null)
     {
         Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null);
     }
     //Set the model's position in the world
     Tent.transform.SetPositionAndRotation(TentPosition, TentRotation);
     Tent.SetActive(true);
     TentDeployed = true;
 }
Пример #7
0
        /// <summary>
        /// Convert local navgrid position into a world position.
        /// Precision loss expected converting between world and navgrid.
        /// </summary>
        /// <param name="localPosition">Local position inside navgrid.</param>
        /// <returns>World DFPosition.</returns>
        public DFPosition NavGridToWorldPosition(DFPosition localPosition)
        {
            // Validate DaggerfallLocation
            if (!dfLocation || dfLocation.Summary.MapID == 0)
            {
                throw new Exception(noLocationError);
            }

            // Get location rect in world space
            RectOffset rect = dfLocation.LocationRect;

            // Navgrid fits 1:1 inside location rect but navgrid origin is top-left and world origin is bottom-left
            DFPosition worldPosition = new DFPosition(
                rect.left + localPosition.X * DaggerfallUnitsPerTile,
                rect.bottom - localPosition.Y * DaggerfallUnitsPerTile);

            return(worldPosition);
        }
Пример #8
0
        public static void DeployTent(bool fromSave = false)
        {
            if (fromSave == false)
            {
                CampMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
                SetTentPositionAndRotation();
                DaggerfallUI.MessageBox("You set up camp");
            }
            else
            {
                PlaceTentOnGround();
            }
            //Attempt to load a model replacement
            Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix);
            Fire = GameObjectHelper.CreateDaggerfallBillboardGameObject(210, 1, null);
            if (Tent == null)
            {
                Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null);
            }
            //Set the model's position in the world

            Tent.transform.SetPositionAndRotation(TentPosition, TentRotation);
            if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon)
            {
                FirePosition = Tent.transform.position + (Tent.transform.up * 0.8f);
                Tent.SetActive(false);
            }
            else
            {
                FirePosition = Tent.transform.position + (Tent.transform.forward * 3) + (Tent.transform.up * 0.8f);
                Tent.SetActive(true);
            }

            Fire.transform.SetPositionAndRotation(FirePosition, TentRotation);
            Fire.SetActive(true);
            AddTorchAudioSource(Fire);
            GameObject lightsNode = new GameObject("Lights");

            lightsNode.transform.parent = Fire.transform;
            AddLight(DaggerfallUnity.Instance, Fire, lightsNode.transform);
            CampDeployed = true;
            FireLit      = true;
        }
Пример #9
0
        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();
            }
        }
Пример #10
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);
        }
Пример #11
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(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;

            // Handle custom 1x1 location position
            if (location.HasCustomLocationPosition())
            {
                result.X = 72;
                result.Y = 55;
            }
            return(result);
        }
Пример #12
0
        void Update()
        {
            // Do nothing if not ready
            if (!ReadyCheck())
            {
                return;
            }

            // Update local world information whenever player map pixel changes
            DFPosition pos = CurrentMapPixel;

            if (pos.X != lastMapPixelX || pos.Y != lastMapPixelY)
            {
                RaiseOnMapPixelChangedEvent(pos);
                UpdateWorldInfo(pos.X, pos.Y);

                // Clear non-permanent scenes from cache, unless going to/from owned ship
                DFPosition shipCoords = DaggerfallBankManager.GetShipCoords();
                if (shipCoords == null || (!(pos.X == shipCoords.X && pos.Y == shipCoords.Y) && !(lastMapPixelX == shipCoords.X && lastMapPixelY == shipCoords.Y)))
                {
                    SaveLoadManager.ClearSceneCache(false);
                }

                lastMapPixelX = pos.X;
                lastMapPixelY = pos.Y;
            }

            // Raise other events
            RaiseEvents();

            // Check if player is inside actual location rect
            PlayerLocationRectCheck();

            // Update nearby objects
            nearbyObjectsUpdateTimer += Time.deltaTime;
            if (nearbyObjectsUpdateTimer > refreshNearbyObjectsInterval)
            {
                UpdateNearbyObjects();
                nearbyObjectsUpdateTimer = 0;
            }
        }
Пример #13
0
        void SetTargetPosition()
        {
            // Get target position on navgrid and in world
            targetNavPosition   = GetNextNavPosition(currentDirection);
            targetWorldPosition = cityNavigation.NavGridToWorldPosition(targetNavPosition);

            // Get the target position in scene
            targetScenePosition = cityNavigation.WorldToScenePosition(targetWorldPosition);
            distanceToTarget    = 0;

            // Target point will be at ground level (roughly waist-level for mobile), so adjust up by half mobile height
            targetScenePosition.y += halfMobileHeight;

            // Mobile now owns target tile and can release current tile
            cityNavigation.ClearFlags(currentNavPosition, CityNavigation.TileFlags.Occupied);
            cityNavigation.SetFlags(targetNavPosition, CityNavigation.TileFlags.Occupied);

            // Change state to moving forwards
            ChangeState(MobileStates.MovingForward);
            seekCount = 0;
        }
Пример #14
0
        void Update()
        {
            // Do nothing if not ready
            if (!ReadyCheck())
            {
                return;
            }

            // Update local world information whenever player map pixel changes
            DFPosition pos = CurrentMapPixel;

            if (pos.X != lastMapPixelX || pos.Y != lastMapPixelY)
            {
                UpdateWorldInfo(pos.X, pos.Y);
                lastMapPixelX = pos.X;
                lastMapPixelY = pos.Y;
            }

            // Check if player is inside actual location rect
            PlayerLocationRectCheck();
        }
Пример #15
0
        /// <summary>
        /// Spawn a new pool item within range of player.
        /// </summary>
        void SpawnAvailableMobile()
        {
            // Player must be in range of location
            if (!playerInLocationRange)
            {
                return;
            }

            // Get a free mobile from pool
            int item = GetNextFreePoolItem();

            if (item == -1)
            {
                return;
            }

            // Get closest point on navgrid to player position in world
            DFPosition playerWorldPos = new DFPosition(playerGPS.WorldX, playerGPS.WorldZ);
            DFPosition playerGridPos  = cityNavigation.WorldToNavGridPosition(playerWorldPos);

            // Spawn mobile at a random position and schedule to be live
            DFPosition spawnPosition;

            if (cityNavigation.GetRandomSpawnPosition(playerGridPos, out spawnPosition, navGridSpawnRadius))
            {
                PoolItem poolItem = populationPool[item];

                // Setup spawn position
                DFPosition worldPosition = cityNavigation.NavGridToWorldPosition(spawnPosition);
                Vector3    scenePosition = cityNavigation.WorldToScenePosition(worldPosition);
                poolItem.npc.Motor.transform.position = scenePosition;
                GameObjectHelper.AlignBillboardToGround(poolItem.npc.Motor.gameObject, new Vector2(0, 2f));

                // Schedule for enabling
                poolItem.active         = true;
                poolItem.scheduleEnable = true;

                populationPool[item] = poolItem;
            }
        }
Пример #16
0
        void Update()
        {
            if (worldTerrainGameObject != null)
            {
                // TODO: make sure this block is not executed when in floating origin mode (otherwise position update is done twice)
                // Handle moving to new map pixel or first-time init
                DFPosition curMapPixel = playerGPS.CurrentMapPixel;
                if (curMapPixel.X != MapPixelX ||
                    curMapPixel.Y != MapPixelY)
                {
                    UpdateWorldTerrain(curMapPixel);
                }

                Terrain terrain = worldTerrainGameObject.GetComponent <Terrain>();
                if (terrain)
                {
                    setMaterialFogParameters();

                    #if ENHANCED_SKY_CODE_AVAILABLE
                    if (isActiveEnhancedSkyMod)
                    {
                        if ((sampleFogColorFromSky == true) && (!skyMan.IsOvercast))
                        {
                            terrain.materialTemplate.SetFloat("_FogFromSkyTex", 1);
                        }
                        else
                        {
                            terrain.materialTemplate.SetFloat("_FogFromSkyTex", 0);
                        }
                    }
                    #endif

                    //terrain.materialTemplate.SetFloat("_BlendFactor", blendFactor);
                    terrain.materialTemplate.SetFloat("_BlendStart", blendStart);
                    terrain.materialTemplate.SetFloat("_BlendEnd", blendEnd);
                }

                updateSeasonalTextures(); // this is necessary since climate changes may occur after UpdateWorldTerrain() has been invoked, TODO: an event would be ideal to trigger updateSeasonalTextures() instead
            }
        }
Пример #17
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);
        }
Пример #18
0
        string GetPaperDollBackground(PlayerEntity entity)
        {
            // TODO: If player is were-creature and has transformed, use entity.RaceTemplate.TransformedPaperDollBackground regardless of geo backgrounds

            if (DaggerfallUnity.Settings.EnableGeographicBackgrounds)
            {
                PlayerGPS       playerGPS       = GameManager.Instance.PlayerGPS;
                PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit;
                DFPosition      position        = playerGPS.CurrentMapPixel;
                int             region          = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetPoliticIndex(position.X, position.Y) - 128;
                if (region < 0 || region >= DaggerfallUnity.Instance.ContentReader.MapFileReader.RegionCount || region >= regionBackgroundIdxChars.Length)
                {
                    return(entity.RaceTemplate.PaperDollBackground);
                }

                // Set background based on location.
                if (playerGPS.IsPlayerInTown(true))
                {
                    return("SCBG04I0.IMG");                                          // Town
                }
                else if (playerEnterExit.IsPlayerInsideDungeon)
                {
                    return("SCBG07I0.IMG");                                          // Dungeon
                }
                else if (playerGPS.CurrentLocation.MapTableData.LocationType == DFRegion.LocationTypes.Graveyard && playerGPS.IsPlayerInLocationRect)
                {
                    return("SCBG08I0.IMG");                                          // Graveyard
                }
                else
                {
                    return("SCBG0" + regionBackgroundIdxChars[region] + "I0.IMG");   // Region
                }
            }
            else
            {
                return(entity.RaceTemplate.PaperDollBackground);
            }
        }
Пример #19
0
        void SelectNextPath()
        {
            PlayerGPS playerGPS = GameManager.Instance.PlayerGPS;

            if (!playerGPS.HasCurrentLocation)
            {
                DFPosition currMapPixel = playerGPS.CurrentMapPixel;

                byte pathsDataPt     = GetPathsDataPoint(currMapPixel);
                byte playerDirection = GetDirection(GetNormalisedPlayerYaw());
                if (CountSetBits(pathsDataPt) == 2)
                {
                    playerDirection = (byte)(pathsDataPt & playerDirection);
                    if (playerDirection == 0)
                    {
                        byte fromDirection = GetDirection(GetNormalisedPlayerYaw(true));
                        playerDirection = (byte)(pathsDataPt ^ fromDirection);
                    }
#if UNITY_EDITOR
                    Debug.LogFormat("Heading {0}", GetDirectionStr(playerDirection));
#endif
                    byte roadDataPt = GetRoadsDataPoint(currMapPixel);
                    road = (roadDataPt & playerDirection) != 0;
                    BeginPathTravel(GetTargetPixel(playerDirection, currMapPixel), false);
                    return;
                }
                else
                {
                    DaggerfallUI.AddHUDText("You've arrived at a junction.");
                }
            }
            else
            {
                lastCrossed = GetDirection(GetNormalisedPlayerYaw(true));
            }
            // An intersection, location, or path end then end travel
            travelControlUI.CloseWindow();
        }
Пример #20
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);
        }
Пример #21
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);
        }
 //overloaded variant
 void InjectMaterialProperties(DFPosition worldPos)
 {
     InjectMaterialProperties(worldPos.X, worldPos.Y);
 }
Пример #23
0
        /// <summary>
        /// Gets Texture2D atlas from Daggerfall texture archive.
        /// Every record and frame in the archive will be added to atlas.
        /// An array of rects will be returned with sub-texture rect for each record index and frame.
        /// Currently supports one archive per atlas. Super-atlas packing (multiple archives) is in the works.
        /// </summary>
        /// <param name="settings">Get texture settings.</param>
        /// <param name="alphaTextureFormat">Alpha TextureFormat.</param>
        /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param>
        /// <returns>GetTextureResults.</returns>
        public GetTextureResults GetTexture2DAtlas(
            GetTextureSettings settings,
            SupportedAlphaTextureFormats alphaTextureFormat = SupportedAlphaTextureFormats.RGBA32,
            SupportedNonAlphaTextureFormats nonAlphaFormat  = SupportedNonAlphaTextureFormats.RGB24)
        {
            GetTextureResults results = new GetTextureResults();

            // Individual textures must remain readable to pack into atlas
            bool stayReadable = settings.stayReadable;

            settings.stayReadable = true;

            // Assign texture file
            TextureFile textureFile;

            if (settings.textureFile == null)
            {
                textureFile          = new TextureFile(Path.Combine(Arena2Path, TextureFile.IndexToFileName(settings.archive)), FileUsage.UseMemory, true);
                settings.textureFile = textureFile;
            }
            else
            {
                textureFile = settings.textureFile;
            }

            // Create lists
            results.atlasSizes       = new List <Vector2>(textureFile.RecordCount);
            results.atlasScales      = new List <Vector2>(textureFile.RecordCount);
            results.atlasOffsets     = new List <Vector2>(textureFile.RecordCount);
            results.atlasFrameCounts = new List <int>(textureFile.RecordCount);

            // Read every texture in archive
            bool               hasNormalMaps    = false;
            bool               hasEmissionMaps  = false;
            bool               hasAnimation     = false;
            bool               allowImport      = (settings.atlasMaxSize == 4096);
            List <Texture2D>   albedoTextures   = new List <Texture2D>();
            List <Texture2D>   normalTextures   = new List <Texture2D>();
            List <Texture2D>   emissionTextures = new List <Texture2D>();
            List <RecordIndex> indices          = new List <RecordIndex>();

            for (int record = 0; record < textureFile.RecordCount; record++)
            {
                // Get record index and frame count
                settings.record = record;
                int frames = textureFile.GetFrameCount(record);
                if (frames > 1)
                {
                    hasAnimation = true;
                }

                // Get record information
                DFSize      size   = textureFile.GetSize(record);
                DFSize      scale  = textureFile.GetScale(record);
                DFPosition  offset = textureFile.GetOffset(record);
                RecordIndex ri     = new RecordIndex()
                {
                    startIndex = albedoTextures.Count,
                    frameCount = frames,
                    width      = size.Width,
                    height     = size.Height,
                };
                indices.Add(ri);
                for (int frame = 0; frame < frames; frame++)
                {
                    settings.frame = frame;
                    GetTextureResults nextTextureResults = GetTexture2D(settings, alphaTextureFormat, nonAlphaFormat, allowImport);

                    albedoTextures.Add(nextTextureResults.albedoMap);
                    if (nextTextureResults.normalMap != null)
                    {
                        normalTextures.Add(nextTextureResults.normalMap);
                        hasNormalMaps = true;
                    }
                    if (nextTextureResults.emissionMap != null)
                    {
                        emissionTextures.Add(nextTextureResults.emissionMap);
                        hasEmissionMaps = true;
                    }
                }

                results.atlasSizes.Add(new Vector2(size.Width, size.Height));
                results.atlasScales.Add(new Vector2(scale.Width, scale.Height));
                results.atlasOffsets.Add(new Vector2(offset.X, offset.Y));
                results.atlasFrameCounts.Add(frames);
                results.textureFile = textureFile;
            }

            // Pack albedo textures into atlas and get our rects
            Texture2D atlasAlbedoMap = new Texture2D(settings.atlasMaxSize, settings.atlasMaxSize, ParseTextureFormat(alphaTextureFormat), MipMaps);

            Rect[] rects = atlasAlbedoMap.PackTextures(albedoTextures.ToArray(), settings.atlasPadding, settings.atlasMaxSize, !stayReadable);

            // Pack normal textures into atlas
            Texture2D atlasNormalMap = null;

            if (hasNormalMaps)
            {
                // Normals must be ARGB32
                atlasNormalMap = new Texture2D(settings.atlasMaxSize, settings.atlasMaxSize, TextureFormat.ARGB32, MipMaps);
                atlasNormalMap.PackTextures(normalTextures.ToArray(), settings.atlasPadding, settings.atlasMaxSize, !stayReadable);
            }

            // Pack emission textures into atlas
            // TODO: Change this as packing not consistent
            Texture2D atlasEmissionMap = null;

            if (hasEmissionMaps)
            {
                // Repacking to ensure correct mix of lit and unlit
                atlasEmissionMap = new Texture2D(settings.atlasMaxSize, settings.atlasMaxSize, ParseTextureFormat(alphaTextureFormat), MipMaps);
                atlasEmissionMap.PackTextures(emissionTextures.ToArray(), settings.atlasPadding, settings.atlasMaxSize, !stayReadable);
            }

            // Add to results
            if (results.atlasRects == null)
            {
                results.atlasRects = new List <Rect>(rects.Length);
            }
            if (results.atlasIndices == null)
            {
                results.atlasIndices = new List <RecordIndex>(indices.Count);
            }
            results.atlasRects.AddRange(rects);
            results.atlasIndices.AddRange(indices);

            // Shrink UV rect to compensate for internal border
            float ru          = 1f / atlasAlbedoMap.width;
            float rv          = 1f / atlasAlbedoMap.height;
            int   finalBorder = settings.borderSize + settings.atlasShrinkUVs;

            for (int i = 0; i < results.atlasRects.Count; i++)
            {
                Rect rct = results.atlasRects[i];
                rct.xMin += finalBorder * ru;
                rct.xMax -= finalBorder * ru;
                rct.yMin += finalBorder * rv;
                rct.yMax -= finalBorder * rv;
                results.atlasRects[i] = rct;
            }

            // Store results
            results.albedoMap       = atlasAlbedoMap;
            results.normalMap       = atlasNormalMap;
            results.emissionMap     = atlasEmissionMap;
            results.isAtlasAnimated = hasAnimation;
            results.isEmissive      = hasEmissionMaps;

            return(results);
        }
        // Start new character to location specified in INI
        void StartNewCharacter()
        {
            DaggerfallUnity.ResetUID();
            QuestMachine.Instance.ClearState();
            RaiseOnNewGameEvent();
            DaggerfallUI.Instance.PopToHUD();
            ResetWeaponManager();
            SaveLoadManager.ClearSceneCache(true);
            GameManager.Instance.GuildManager.ClearMembershipData();

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

            // Set time tracked in playerEntity
            playerEntity.LastGameMinutes = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime();

            // 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, characterDocument.classIndex, characterDocument.isCustom);

            // Assign starting spells to player entity
            SetStartingSpells(playerEntity);

            // Apply biography effects to player entity
            BiogFile.ApplyEffects(characterDocument.biographyEffects, playerEntity);

            // Setup bank accounts and houses
            Banking.DaggerfallBankManager.SetupAccounts();
            Banking.DaggerfallBankManager.SetupHouses();

            // Initialize region data
            playerEntity.InitializeRegionData();

            // Randomize weathers
            GameManager.Instance.WeatherManager.SetClimateWeathers();

            // Start game
            GameManager.Instance.PauseGame(false);
            DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack();
            DaggerfallUI.PostMessage(PostStartMessage);

            lastStartMethod = StartMethods.NewCharacter;

            // Offer main quest during pre-alpha
            QuestMachine.Instance.InstantiateQuest("__MQSTAGE00");

            // Launch startup optional quest
            if (!string.IsNullOrEmpty(LaunchQuest))
            {
                QuestMachine.Instance.InstantiateQuest(LaunchQuest);
                LaunchQuest = string.Empty;
            }
            // Launch any InitAtGameStart quests
            GameManager.Instance.QuestListsManager.InitAtGameStartQuests();

            if (OnStartGame != null)
            {
                OnStartGame(this, null);
            }
        }
        void DisplaySaveStatsGUI()
        {
            if (currentSaveTree == null)
            {
                return;
            }

            SaveTreeBaseRecord positionRecord = currentSaveTree.FindRecord(RecordTypes.CharacterPositionRecord);

            EditorGUILayout.Space();
            GUILayoutHelper.Horizontal(() =>
            {
                EditorGUILayout.LabelField(new GUIContent("Version"), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(currentSaveTree.Header.Version.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            GUILayoutHelper.Horizontal(() =>
            {
                string positionText = string.Format("X={0}, Y={1}, Z={2}",
                                                    positionRecord.RecordRoot.Position.WorldX,
                                                    positionRecord.RecordRoot.Position.WorldY,
                                                    positionRecord.RecordRoot.Position.WorldZ);

                EditorGUILayout.LabelField(new GUIContent("Player Position", "Position of player in the world."), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(positionText, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            GUILayoutHelper.Horizontal(() =>
            {
                DFPosition mapPixel = MapsFile.WorldCoordToMapPixel(positionRecord.RecordRoot.Position.WorldX, positionRecord.RecordRoot.Position.WorldZ);
                string mapPixelText = string.Format("X={0}, Y={1}", mapPixel.X, mapPixel.Y);

                EditorGUILayout.LabelField(new GUIContent("Player Map Pixel", "Position of player on small map."), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(mapPixelText, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            GUILayoutHelper.Horizontal(() =>
            {
                DaggerfallDateTime time = new DaggerfallDateTime();
                time.FromClassicDaggerfallTime(currentSaveVars.GameTime);

                EditorGUILayout.LabelField(new GUIContent("Player Time", "World time of this save."), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(time.LongDateTimeString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            GUILayoutHelper.Horizontal(() =>
            {
                EditorGUILayout.LabelField(new GUIContent("Player Environment"), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(((Environments)currentSaveTree.Header.Environment).ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            GUILayoutHelper.Horizontal(() =>
            {
                EditorGUILayout.LabelField(new GUIContent("RecordElement records"), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(currentSaveTree.RecordDictionary.Count.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            });
            //GUILayoutHelper.Horizontal(() =>
            //{
            //    EditorGUILayout.LabelField(new GUIContent("Header.Unknown"), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
            //    EditorGUILayout.SelectableLabel(currentSaveTree.Header.Unknown.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            //});
            //GUILayoutHelper.Horizontal(() =>
            //{
            //    EditorGUILayout.LabelField(new GUIContent("CharacterPosition.Unknown"), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
            //    EditorGUILayout.SelectableLabel(currentSaveTree.Header.CharacterPosition.Unknown.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            //});
        }
Пример #26
0
        /// <summary>
        /// Force update of world information (climate, politic, etc.) when Update() not running.
        /// </summary>
        public void UpdateWorldInfo()
        {
            DFPosition pos = CurrentMapPixel;

            UpdateWorldInfo(pos.X, pos.Y);
        }
Пример #27
0
        /// <summary>
        /// Creates a path from player's current location to destination and
        /// returns minutes taken to travel.
        /// </summary>
        /// <param name="endPos">Endpoint in map pixel coordinates.</param>
        public int CalculateTravelTime(DFPosition endPos,
                                       bool speedCautious = false,
                                       bool sleepModeInn  = false,
                                       bool travelShip    = false,
                                       bool hasHorse      = false,
                                       bool hasCart       = false)
        {
            int transportModifier = 0;

            if (hasHorse)
            {
                transportModifier = 128;
            }
            else if (hasCart)
            {
                transportModifier = 192;
            }
            else
            {
                transportModifier = 256;
            }

            int playerXMapPixel         = GameManager.Instance.PlayerGPS.CurrentMapPixel.X;
            int playerYMapPixel         = GameManager.Instance.PlayerGPS.CurrentMapPixel.Y;
            int distanceXMapPixels      = endPos.X - playerXMapPixel;
            int distanceYMapPixels      = endPos.Y - playerYMapPixel;
            int distanceXMapPixelsAbs   = Mathf.Abs(distanceXMapPixels);
            int distanceYMapPixelsAbs   = Mathf.Abs(distanceYMapPixels);
            int furthestOfXandYDistance = 0;

            if (distanceXMapPixelsAbs <= distanceYMapPixelsAbs)
            {
                furthestOfXandYDistance = distanceYMapPixelsAbs;
            }
            else
            {
                furthestOfXandYDistance = distanceXMapPixelsAbs;
            }

            int xPixelMovementDirection;
            int yPixelMovementDirection;

            if (distanceXMapPixels >= 0)
            {
                xPixelMovementDirection = 1;
            }
            else
            {
                xPixelMovementDirection = -1;
            }

            if (distanceYMapPixels >= 0)
            {
                yPixelMovementDirection = 1;
            }
            else
            {
                yPixelMovementDirection = -1;
            }

            int numberOfMovements = 0;
            int shorterOfXandYDistanceIncrementer = 0;

            int minutesTakenThisMove = 0;
            int minutesTakenTotal    = 0;

            DaggerfallConnect.Arena2.MapsFile mapsFile = DaggerfallUnity.Instance.ContentReader.MapFileReader;
            pixelsTraveledOnOcean = 0;

            while (numberOfMovements < furthestOfXandYDistance)
            {
                if (furthestOfXandYDistance == distanceXMapPixelsAbs)
                {
                    playerXMapPixel += xPixelMovementDirection;
                    shorterOfXandYDistanceIncrementer += distanceYMapPixelsAbs;

                    if (shorterOfXandYDistanceIncrementer > distanceXMapPixelsAbs)
                    {
                        shorterOfXandYDistanceIncrementer -= distanceXMapPixelsAbs;
                        playerYMapPixel += yPixelMovementDirection;
                    }
                }
                else
                {
                    playerYMapPixel += yPixelMovementDirection;
                    shorterOfXandYDistanceIncrementer += distanceXMapPixelsAbs;

                    if (shorterOfXandYDistanceIncrementer > distanceYMapPixelsAbs)
                    {
                        shorterOfXandYDistanceIncrementer -= distanceYMapPixelsAbs;
                        playerXMapPixel += xPixelMovementDirection;
                    }
                }

                int terrainMovementIndex = 0;
                int terrain = mapsFile.GetClimateIndex(playerXMapPixel, playerYMapPixel);
                if (terrain == (int)TerrainTypes.Ocean)
                {
                    ++pixelsTraveledOnOcean;
                    if (travelShip)
                    {
                        minutesTakenThisMove = 51;
                    }
                    else
                    {
                        minutesTakenThisMove = 255;
                    }
                }
                else
                {
                    terrainMovementIndex = terrainMovementModifierIndices[terrain - (int)TerrainTypes.Ocean];
                    minutesTakenThisMove = (((102 * transportModifier) >> 8)
                                            * (256 - terrainMovementModifiers[terrainMovementIndex] + 256)) >> 8;
                }

                if (!sleepModeInn)
                {
                    minutesTakenThisMove = (300 * minutesTakenThisMove) >> 8;
                }
                minutesTakenTotal += minutesTakenThisMove;
                ++numberOfMovements;
            }

            if (!speedCautious)
            {
                minutesTakenTotal = minutesTakenTotal >> 1;
            }

            return(minutesTakenTotal);
        }
Пример #28
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;
        }
Пример #29
0
        // Set location tilemap data
        public static void SetLocationTiles(ref MapPixelData mapPixel)
        {
            // Get location
            DaggerfallUnity dfUnity  = DaggerfallUnity.Instance;
            DFLocation      location = dfUnity.ContentReader.MapFileReader.GetLocation(mapPixel.mapRegionIndex, mapPixel.mapLocationIndex);

            // Position tiles inside terrain area
            DFPosition tilePos = TerrainHelper.GetLocationTerrainTileOrigin(location);

            // Full 8x8 locations have "terrain blend space" around walls to smooth down random terrain towards flat area.
            // This is indicated by texture index > 55 (ground texture range is 0-55), larger values indicate blend space.
            // We need to know rect of actual city area so we can use blend space outside walls.
            int xmin = int.MaxValue, ymin = int.MaxValue;
            int xmax = 0, ymax = 0;

            // Iterate blocks of this location
            for (int blockY = 0; blockY < location.Exterior.ExteriorData.Height; blockY++)
            {
                for (int blockX = 0; blockX < location.Exterior.ExteriorData.Width; blockX++)
                {
                    // Get block data
                    DFBlock block;
                    string  blockName = dfUnity.ContentReader.MapFileReader.GetRmbBlockName(ref location, blockX, blockY);
                    if (!dfUnity.ContentReader.GetBlock(blockName, out block))
                    {
                        continue;
                    }

                    // Copy ground tile info
                    for (int tileY = 0; tileY < RMBLayout.RMBTilesPerBlock; tileY++)
                    {
                        for (int tileX = 0; tileX < RMBLayout.RMBTilesPerBlock; tileX++)
                        {
                            DFBlock.RmbGroundTiles tile = block.RmbBlock.FldHeader.GroundData.GroundTiles[tileX, (RMBLayout.RMBTilesPerBlock - 1) - tileY];
                            int xpos = tilePos.X + blockX * RMBLayout.RMBTilesPerBlock + tileX;
                            int ypos = tilePos.Y + blockY * RMBLayout.RMBTilesPerBlock + tileY;

                            if (tile.TextureRecord < 56)
                            {
                                // Track interior bounds of location tiled area
                                if (xpos < xmin)
                                {
                                    xmin = xpos;
                                }
                                if (xpos > xmax)
                                {
                                    xmax = xpos;
                                }
                                if (ypos < ymin)
                                {
                                    ymin = ypos;
                                }
                                if (ypos > ymax)
                                {
                                    ymax = ypos;
                                }

                                // Store texture data from block
                                mapPixel.tilemapData[JobA.Idx(xpos, ypos, MapsFile.WorldMapTileDim)] = tile.TileBitfield == 0 ? byte.MaxValue : tile.TileBitfield;
                            }
                        }
                    }
                }
            }

            // Update location rect with extra clearance
            int  extraClearance = location.MapTableData.LocationType == DFRegion.LocationTypes.TownCity ? 3 : 2;
            Rect locationRect   = new Rect();

            locationRect.xMin     = xmin - extraClearance;
            locationRect.xMax     = xmax + extraClearance;
            locationRect.yMin     = ymin - extraClearance;
            locationRect.yMax     = ymax + extraClearance;
            mapPixel.locationRect = locationRect;
        }
Пример #30
0
        // 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);
            }
        }