Ejemplo n.º 1
0
        /// <summary>
        /// Assigns character items from classic save tree.
        /// </summary>
        public void AssignItems(SaveTree saveTree)
        {
            // Find character record, should always be a singleton
            CharacterRecord characterRecord = (CharacterRecord)saveTree.FindRecord(RecordTypes.Character);

            if (characterRecord == null)
            {
                return;
            }

            // Find all character-owned items
            List <SaveTreeBaseRecord> itemRecords = saveTree.FindRecords(RecordTypes.Item, characterRecord);

            // Filter for container-based inventory items
            List <SaveTreeBaseRecord> filteredRecords = saveTree.FilterRecordsByParentType(itemRecords, RecordTypes.Container);

            // Add interim Daggerfall Unity items
            foreach (var record in filteredRecords)
            {
                // Get container parent
                ContainerRecord containerRecord = (ContainerRecord)record.Parent;

                // Create item, grabbing trapped soul if needed
                DaggerfallUnityItem newItem = new DaggerfallUnityItem((ItemRecord)record);
                if (newItem.ItemGroup == ItemGroups.MiscItems && newItem.GroupIndex == 1)
                {
                    if (record.Children.Count > 0)
                    {
                        TrappedSoulRecord soulRecord = (TrappedSoulRecord)record.Children[0];
                        newItem.TrappedSoulType = (MobileTypes)soulRecord.RecordRoot.SpriteIndex;
                    }
                    else
                    {
                        newItem.TrappedSoulType = MobileTypes.None;
                    }
                }
                // Add to local inventory or wagon
                if (containerRecord.IsWagon)
                {
                    wagonItems.AddItem(newItem);
                }
                else
                {
                    items.AddItem(newItem);
                }

                // Equip to player if equipped in save
                for (int i = 0; i < characterRecord.ParsedData.equippedItems.Length; i++)
                {
                    if (characterRecord.ParsedData.equippedItems[i] == record.RecordRoot.RecordID)
                    {
                        equipTable.EquipItem(newItem, true, false);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Assigns character items from classic save tree.
        /// </summary>
        public void AssignItems(SaveTree saveTree)
        {
            // Find character record, should always be a singleton
            CharacterRecord characterRecord = (CharacterRecord)saveTree.FindRecord(RecordTypes.Character);

            if (characterRecord == null)
            {
                return;
            }

            // Find all character-owned items
            List <SaveTreeBaseRecord> itemRecords = saveTree.FindRecords(RecordTypes.Item, characterRecord);

            // Filter for container-based inventory items
            List <SaveTreeBaseRecord> filteredRecords = saveTree.FilterRecordsByParentType(itemRecords, RecordTypes.Container);

            // Add interim Daggerfall Unity items
            foreach (var record in filteredRecords)
            {
                // Get container parent
                ContainerRecord containerRecord = (ContainerRecord)record.Parent;

                // Add to local inventory or wagon
                DaggerfallUnityItem newItem = new DaggerfallUnityItem((ItemRecord)record);
                if (containerRecord.IsWagon)
                {
                    wagonItems.AddItem(newItem);
                }
                else
                {
                    items.AddItem(newItem);
                }

                // Equip to player if equipped in save
                for (int i = 0; i < characterRecord.ParsedData.equippedItems.Length; i++)
                {
                    if (characterRecord.ParsedData.equippedItems[i] == (record.RecordRoot.RecordID >> 8))
                    {
                        equipTable.EquipItem(newItem);
                    }
                }
            }
        }
        void RestoreOldClassSpecials(SaveTree saveTree, Races classicTransformedRace)
        {
            try
            {
                // Get old class record
                SaveTreeBaseRecord oldClassRecord = saveTree.FindRecord(RecordTypes.OldClass);
                if (oldClassRecord == null)
                {
                    return;
                }

                // Read old class data
                System.IO.MemoryStream stream = new System.IO.MemoryStream(oldClassRecord.RecordData);
                System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);
                ClassFile classFile           = new ClassFile();
                classFile.Load(reader);
                reader.Close();

                // Restore any specials set by transformed race
                if (classicTransformedRace == Races.Vampire)
                {
                    // Restore pre-vampire specials
                    characterDocument.career.DamageFromSunlight   = classFile.Career.DamageFromSunlight;
                    characterDocument.career.DamageFromHolyPlaces = classFile.Career.DamageFromHolyPlaces;
                    characterDocument.career.Paralysis            = classFile.Career.Paralysis;
                    characterDocument.career.Disease = classFile.Career.Disease;
                }
                else if (classicTransformedRace == Races.Werewolf)
                {
                    // TODO: Restore pre-werewolf specials
                }
                else if (classicTransformedRace == Races.Wereboar)
                {
                    // TODO: Restore pre-wereboar specials
                }
            }
            catch (Exception ex)
            {
                Debug.LogErrorFormat("Could not restore old class specials for vamp/were import. Error: '{0}'", ex.Message);
            }
        }
        void StartFromClassicSave()
        {
            DaggerfallUnity.ResetUID();
            QuestMachine.Instance.ClearState();
            RaiseOnNewGameEvent();
            ResetWeaponManager();

            // Save index must be in range
            if (classicSaveIndex < 0 || classicSaveIndex >= 6)
            {
                throw new IndexOutOfRangeException("classicSaveIndex out of range.");
            }

            // Open saves in parent path of Arena2 folder
            string    path      = SaveLoadManager.Instance.DaggerfallSavePath;
            SaveGames saveGames = new SaveGames(path);

            if (!saveGames.IsPathOpen)
            {
                throw new Exception(string.Format("Could not open Daggerfall saves path {0}", path));
            }

            // Open save index
            if (!saveGames.TryOpenSave(classicSaveIndex))
            {
                string error = string.Format("Could not open classic save index {0}.", classicSaveIndex);
                DaggerfallUI.MessageBox(error);
                DaggerfallUnity.LogMessage(string.Format(error), true);
                return;
            }

            // Get required save data
            SaveTree saveTree = saveGames.SaveTree;
            SaveVars saveVars = saveGames.SaveVars;

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

            if (NoWorld)
            {
                playerEnterExit.DisableAllParents();
            }
            else
            {
                // Set player to world position
                playerEnterExit.EnableExteriorParent();
                StreamingWorld streamingWorld = FindStreamingWorld();
                int            worldX         = positionRecord.RecordRoot.Position.WorldX;
                int            worldZ         = positionRecord.RecordRoot.Position.WorldZ;
                streamingWorld.TeleportToWorldCoordinates(worldX, worldZ);
                streamingWorld.suppressWorld = false;
            }

            GameObject      cameraObject = GameObject.FindGameObjectWithTag("MainCamera");
            PlayerMouseLook mouseLook    = cameraObject.GetComponent <PlayerMouseLook>();

            if (mouseLook)
            {
                // Classic save value ranges from -256 (looking up) to 256 (looking down).
                // The maximum up and down range of view in classic is similar to 45 degrees up and down in DF Unity.
                float pitch = positionRecord.RecordRoot.Pitch;
                if (pitch != 0)
                {
                    pitch = (pitch * 45 / 256);
                }
                mouseLook.Pitch = pitch;

                float yaw = positionRecord.RecordRoot.Yaw;
                // In classic saves 2048 units of yaw is 360 degrees.
                if (yaw != 0)
                {
                    yaw = (yaw * 360 / 2048);
                }
                mouseLook.Yaw = yaw;
            }

            // Set whether the player's weapon is drawn
            WeaponManager weaponManager = GameManager.Instance.WeaponManager;

            weaponManager.Sheathed = (!saveVars.WeaponDrawn);

            // Set game time
            DaggerfallUnity.Instance.WorldTime.Now.FromClassicDaggerfallTime(saveVars.GameTime);

            // Get character record
            List <SaveTreeBaseRecord> records = saveTree.FindRecords(RecordTypes.Character);

            if (records.Count != 1)
            {
                throw new Exception("SaveTree CharacterRecord not found.");
            }

            // Get prototypical character document data
            CharacterRecord characterRecord = (CharacterRecord)records[0];

            characterDocument = characterRecord.ToCharacterDocument();

            // Assign data to player entity
            PlayerEntity playerEntity = FindPlayerEntity();

            playerEntity.AssignCharacter(characterDocument, characterRecord.ParsedData.level, characterRecord.ParsedData.maxHealth, false);

            // Assign biography modifiers
            playerEntity.BiographyResistDiseaseMod = saveVars.BiographyResistDiseaseMod;
            playerEntity.BiographyResistMagicMod   = saveVars.BiographyResistMagicMod;
            playerEntity.BiographyAvoidHitMod      = saveVars.BiographyAvoidHitMod;
            playerEntity.BiographyResistPoisonMod  = saveVars.BiographyResistPoisonMod;
            playerEntity.BiographyFatigueMod       = saveVars.BiographyFatigueMod;

            // Assign faction data
            playerEntity.FactionData.ImportClassicReputation(saveVars);

            // Assign global variables
            playerEntity.GlobalVars.ImportClassicGlobalVars(saveVars);

            // Set time of last check for raising skills
            playerEntity.TimeOfLastSkillIncreaseCheck = saveVars.LastSkillCheckTime;

            // Assign items to player entity
            playerEntity.AssignItems(saveTree);

            // Assign guild memberships
            playerEntity.AssignGuildMemberships(saveTree);

            // Assign diseases and poisons to player entity
            playerEntity.AssignDiseasesAndPoisons(saveTree);

            // Assign gold pieces
            playerEntity.GoldPieces = (int)characterRecord.ParsedData.physicalGold;

            // Assign weapon hand being used
            weaponManager.UsingRightHand = !saveVars.UsingLeftHandWeapon;

            // GodMode setting
            playerEntity.GodMode = saveVars.GodMode;

            // Setup bank accounts
            var bankRecords = saveTree.FindRecord(RecordTypes.BankAccount);

            Banking.DaggerfallBankManager.ReadNativeBankData(bankRecords);

            // Get regional data.
            playerEntity.RegionData = saveVars.RegionData;

            // Set time tracked by playerEntity for game minute-based updates
            playerEntity.LastGameMinutes = saveVars.GameTime;

            // Get breath remaining if player was submerged (0 if they were not in the water)
            playerEntity.CurrentBreath = saveVars.BreathRemaining;

            // TODO: Import classic spellbook
            playerEntity.DeserializeSpellbook(null);

            // Get last type of crime committed
            playerEntity.CrimeCommitted = (PlayerEntity.Crimes)saveVars.CrimeCommitted;

            // Get weather
            byte[] climateWeathers = saveVars.ClimateWeathers;

            // Enums for thunder and snow are reversed in classic and Unity, so they are converted here.
            for (int i = 0; i < climateWeathers.Length; i++)
            {
                // TODO: 0x80 flag can be set for snow or rain, to add fog to these weathers. This isn't in DF Unity yet, so
                // temporarily removing the flag.
                climateWeathers[i] &= 0x7f;
                if (climateWeathers[i] == 5)
                {
                    climateWeathers[i] = 6;
                }
                else if (climateWeathers[i] == 6)
                {
                    climateWeathers[i] = 5;
                }
            }
            GameManager.Instance.WeatherManager.PlayerWeather.ClimateWeathers = climateWeathers;

            // Load character biography text
            playerEntity.BackStory = saveGames.BioFile.Lines;

            // Validate spellbook item
            DaggerfallUnity.Instance.ItemHelper.ValidateSpellbookItem(playerEntity);

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

            lastStartMethod = StartMethods.LoadClassicSave;
            SaveIndex       = -1;

            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));
            //});
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Assigns character items from classic save tree.
        /// </summary>
        public void AssignItems(SaveTree saveTree)
        {
            // Find character record, should always be a singleton
            CharacterRecord characterRecord = (CharacterRecord)saveTree.FindRecord(RecordTypes.Character);

            if (characterRecord == null)
            {
                return;
            }

            // Find all character-owned items
            List <SaveTreeBaseRecord> itemRecords = saveTree.FindRecords(RecordTypes.Item, characterRecord);

            // Filter for container-based inventory items
            List <SaveTreeBaseRecord> filteredRecords = saveTree.FilterRecordsByParentType(itemRecords, RecordTypes.Container);

            // Add interim Daggerfall Unity items
            foreach (var record in filteredRecords)
            {
                // Get container parent
                ContainerRecord containerRecord = (ContainerRecord)record.Parent;

                // Some (most likely hacked) classic items have 0 or 65535 in image data bitfield
                // Discard these items as they will likely have other bad attributes such as an impossible weight
                // The goal here is just to prevent game from crashing due to bad item data
                if ((record as ItemRecord).ParsedData.image1 == 0 || (record as ItemRecord).ParsedData.image1 == 0xffff)
                {
                    continue;
                }

                // Create item, grabbing trapped soul if needed
                DaggerfallUnityItem newItem = new DaggerfallUnityItem((ItemRecord)record);
                if (newItem.ItemGroup == ItemGroups.MiscItems && newItem.GroupIndex == 1)
                {
                    if (record.Children.Count > 0)
                    {
                        TrappedSoulRecord soulRecord = (TrappedSoulRecord)record.Children[0];
                        newItem.TrappedSoulType = (MobileTypes)soulRecord.RecordRoot.SpriteIndex;
                    }
                    else
                    {
                        newItem.TrappedSoulType = MobileTypes.None;
                    }
                }
                // Add to local inventory or wagon
                if (containerRecord.IsWagon)
                {
                    wagonItems.AddItem(newItem);
                }
                else
                {
                    items.AddItem(newItem);
                }

                // Equip to player if equipped in save
                for (int i = 0; i < characterRecord.ParsedData.equippedItems.Length; i++)
                {
                    if (characterRecord.ParsedData.equippedItems[i] == record.RecordRoot.RecordID)
                    {
                        equipTable.EquipItem(newItem, true, false);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        void StartFromClassicSave()
        {
            DaggerfallUnity.ResetUID();
            QuestMachine.Instance.ClearState();
            RaiseOnNewGameEvent();
            ResetWeaponManager();

            // Save index must be in range
            if (classicSaveIndex < 0 || classicSaveIndex >= 6)
            {
                throw new IndexOutOfRangeException("classicSaveIndex out of range.");
            }

            // Open saves in parent path of Arena2 folder
            string    path      = SaveLoadManager.Instance.DaggerfallSavePath;
            SaveGames saveGames = new SaveGames(path);

            if (!saveGames.IsPathOpen)
            {
                throw new Exception(string.Format("Could not open Daggerfall saves path {0}", path));
            }

            // Open save index
            if (!saveGames.TryOpenSave(classicSaveIndex))
            {
                string error = string.Format("Could not open classic save index {0}.", classicSaveIndex);
                DaggerfallUI.MessageBox(error);
                DaggerfallUnity.LogMessage(string.Format(error), true);
                return;
            }

            // Get required save data
            SaveTree saveTree = saveGames.SaveTree;
            SaveVars saveVars = saveGames.SaveVars;

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

            if (NoWorld)
            {
                playerEnterExit.DisableAllParents();
            }
            else
            {
                // Set player to world position
                playerEnterExit.EnableExteriorParent();
                StreamingWorld streamingWorld = FindStreamingWorld();
                int            worldX         = positionRecord.RecordRoot.Position.WorldX;
                int            worldZ         = positionRecord.RecordRoot.Position.WorldZ;
                streamingWorld.TeleportToWorldCoordinates(worldX, worldZ);
                streamingWorld.suppressWorld = false;
            }

            GameObject      cameraObject = GameObject.FindGameObjectWithTag("MainCamera");
            PlayerMouseLook mouseLook    = cameraObject.GetComponent <PlayerMouseLook>();

            if (mouseLook)
            {
                // Classic save value ranges from -256 (looking up) to 256 (looking down).
                // The maximum up and down range of view in classic is similar to 45 degrees up and down in DF Unity.
                float pitch = positionRecord.RecordRoot.Pitch;
                if (pitch != 0)
                {
                    pitch = (pitch * 45 / 256);
                }
                mouseLook.Pitch = pitch;

                float yaw = positionRecord.RecordRoot.Yaw;
                // In classic saves 2048 units of yaw is 360 degrees.
                if (yaw != 0)
                {
                    yaw = (yaw * 360 / 2048);
                }
                mouseLook.Yaw = yaw;
            }

            // Set whether the player's weapon is drawn
            GameManager.Instance.WeaponManager.Sheathed = (!saveVars.WeaponDrawn);

            // Set game time
            DaggerfallUnity.Instance.WorldTime.Now.FromClassicDaggerfallTime(saveVars.GameTime);

            // Get character record
            List <SaveTreeBaseRecord> records = saveTree.FindRecords(RecordTypes.Character);

            if (records.Count != 1)
            {
                throw new Exception("SaveTree CharacterRecord not found.");
            }

            // Get prototypical character document data
            CharacterRecord characterRecord = (CharacterRecord)records[0];

            characterDocument = characterRecord.ToCharacterDocument();

            // Assign data to player entity
            PlayerEntity playerEntity = FindPlayerEntity();

            playerEntity.AssignCharacter(characterDocument, characterRecord.ParsedData.level, characterRecord.ParsedData.maxHealth, false);

            // Assign biography modifiers
            playerEntity.BiographyResistDiseaseMod = saveVars.BiographyResistDiseaseMod;
            playerEntity.BiographyResistMagicMod   = saveVars.BiographyResistMagicMod;
            playerEntity.BiographyAvoidHitMod      = saveVars.BiographyAvoidHitMod;
            playerEntity.BiographyResistPoisonMod  = saveVars.BiographyResistPoisonMod;
            playerEntity.BiographyFatigueMod       = saveVars.BiographyFatigueMod;

            // Assign faction data
            playerEntity.FactionData.ImportClassicReputation(saveVars);

            // Assign global variables
            playerEntity.GlobalVars.ImportClassicGlobalVars(saveVars);

            // Set time of last check for raising skills
            playerEntity.TimeOfLastSkillIncreaseCheck = saveVars.LastSkillCheckTime;

            // Assign items to player entity
            playerEntity.AssignItems(saveTree);

            // Assign gold pieces
            playerEntity.GoldPieces = (int)characterRecord.ParsedData.physicalGold;

            // GodMode setting
            playerEntity.GodMode = saveVars.GodMode;

            // Setup bank accounts
            var bankRecords = saveTree.FindRecord(RecordTypes.BankAccount);

            Banking.DaggerfallBankManager.ReadNativeBankData(bankRecords);

            // Get regional data.
            playerEntity.RegionData = saveVars.RegionData;

            // Set time tracked by playerEntity for game minute-based updates
            playerEntity.LastGameMinutes = saveVars.GameTime;

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

            lastStartMethod = StartMethods.LoadClassicSave;
            SaveIndex       = -1;

            if (OnStartGame != null)
            {
                OnStartGame(this, null);
            }
        }