int GetEquippedIndex(ItemRecord record)
        {
            if (characterRecord == null || record.RecordType != RecordTypes.Item || record.Parent == null)
                return -1;

            // Try to match item RecordID with equipped item IDs
            // Item RecordID must be shifted right 8 bits
            uint[] equippedItems = characterRecord.ParsedData.equippedItems;
            for (int i = 0; i < equippedItems.Length; i++)
            {
                if (equippedItems[i] == (record.RecordRoot.RecordID >> 8))
                    return i;
            }

            return -1;
        }
Ejemplo n.º 2
0
        // Reads all records in SaveTree
        // Reader must be positioned at start of first RecordElement
        void ReadRecords(BinaryReader reader)
        {
            RecordDictionary.Clear();
            RootRecord = new SaveTreeBaseRecord();
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                // Read record length and skip empty records as they have no data
                int length = reader.ReadInt32();
                if (length <= 0)
                {
                    continue;
                }

                // Handle potential stream overflow (e.g. corrupt save, something went wrong)
                if (reader.BaseStream.Position + length >= reader.BaseStream.Length)
                {
                    break;
                }

                // Peek record type from RecordRoot so we can instantiate record class based on type
                RecordTypes type = PeekRecordType(reader);

                // Add record based on type
                SaveTreeBaseRecord record;
                switch (type)
                {
                case RecordTypes.Item:
                    record = new ItemRecord(reader, length);
                    break;

                case RecordTypes.Character:
                    record = new CharacterRecord(reader, length);
                    break;

                case RecordTypes.Spell:
                    record = new SpellRecord(reader, length);
                    break;

                case RecordTypes.GuildMembership:
                case RecordTypes.OldGuild:
                    record = new GuildMembershipRecord(reader, length);
                    break;

                case RecordTypes.DiseaseOrPoison:
                    record = new DiseaseOrPoisonRecord(reader, length);
                    break;

                case RecordTypes.TrappedSoul:
                    record = new TrappedSoulRecord(reader, length);
                    break;

                case RecordTypes.Container:
                    record = new ContainerRecord(reader, length);
                    break;

                //case RecordTypes.Door:
                //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                //    continue;
                //case RecordTypes.DungeonData:
                //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                //    continue;
                default:
                    record = new SaveTreeBaseRecord(reader, length);
                    break;
                }
                AddRecord(record);
            }

            LinkChildren();
        }
        /// <summary>
        /// Create from native save ItemRecord data.
        /// </summary>
        void FromItemRecord(ItemRecord itemRecord)
        {
            // Get template data
            ItemGroups group = (ItemGroups)itemRecord.ParsedData.category1;
            int index = itemRecord.ParsedData.category2;
            ItemTemplate itemTemplate = DaggerfallUnity.Instance.ItemHelper.GetItemTemplate(group, index);

            // Get player image
            int playerBitfield = (int)itemRecord.ParsedData.image1;
            int playerArchive = playerBitfield >> 7;
            int playerRecord = (playerBitfield & 0x7f);

            // Get world image
            int worldBitfield = (int)itemRecord.ParsedData.image2;
            int worldArchive = worldBitfield >> 7;
            int worldRecord = (worldBitfield & 0x7f);

            // Assign new data
            shortName = itemRecord.ParsedData.name;
            itemGroup = group;
            groupIndex = index;
            playerTextureArchive = playerArchive;
            playerTextureRecord = playerRecord;
            worldTextureArchive = worldArchive;
            worldTextureRecord = worldRecord;
            nativeMaterialValue = itemRecord.ParsedData.material;
            dyeColor = (DyeColors)itemRecord.ParsedData.color;
            weightInKg = (float)itemRecord.ParsedData.weight * 0.25f;
            drawOrder = itemTemplate.drawOrderOrEffect;
            value1 = (int)itemRecord.ParsedData.value1;
            value2 = (int)itemRecord.ParsedData.value2;
            hits1 = itemRecord.ParsedData.hits1;
            hits2 = itemRecord.ParsedData.hits2;
            hits3 = itemRecord.ParsedData.hits3;
            currentVariant = 0;
            enchantmentPoints = itemRecord.ParsedData.enchantmentPoints;
            message = (int)itemRecord.ParsedData.message;
            stackCount = 1;

            // Assign current variant
            if (itemTemplate.variants > 0)
            {
                if (IsCloak())
                    currentVariant = playerRecord - (itemTemplate.playerTextureRecord + 1);
                else
                    currentVariant = playerRecord - itemTemplate.playerTextureRecord;
            }

            // Assign legacy magic effects array
            bool foundEnchantment = false;
            if (itemRecord.ParsedData.magic != null)
            {
                legacyMagic = new int[itemRecord.ParsedData.magic.Length];
                for (int i = 0; i < itemRecord.ParsedData.magic.Length; i++)
                {
                    legacyMagic[i] = itemRecord.ParsedData.magic[i];
                    if (legacyMagic[i] != 0xffff)
                        foundEnchantment = true;
                }
            }

            // Discard list if no enchantment found
            if (!foundEnchantment)
                legacyMagic = null;

            // Fix leather helms
            ItemBuilder.FixLeatherHelm(this);

            // TEST: Force dye color to match material of imported weapons & armor
            // This is to fix cases where dye colour may be set incorrectly on imported item
            dyeColor = DaggerfallUnity.Instance.ItemHelper.GetDyeColor(this);
        }
Ejemplo n.º 4
0
        // Reads all records in SaveTree
        // Reader must be positioned at start of first RecordElement
        void ReadRecords(BinaryReader reader)
        {
            RecordDictionary.Clear();
            RootRecord = new SaveTreeBaseRecord();
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                // Read record length and skip empty records as they have no data
                int length = reader.ReadInt32();
                if (length <= 0)
                    continue;

                // Handle potential stream overflow (e.g. corrupt save, something went wrong)
                if (reader.BaseStream.Position + length >= reader.BaseStream.Length)
                    break;

                // Peek record type from RecordRoot so we can instantiate record class based on type
                RecordTypes type = PeekRecordType(reader);

                // Add record based on type
                SaveTreeBaseRecord record;
                switch (type)
                {
                    case RecordTypes.Item:
                        record = new ItemRecord(reader, length);
                        break;
                    case RecordTypes.Spell:
                        record = new SpellRecord(reader, length);
                        break;
                    case RecordTypes.Character:
                        record = new CharacterRecord(reader, length);
                        break;
                    //case RecordTypes.UnknownTownLink:
                    //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                    //    continue;
                    //case RecordTypes.DungeonData:
                    //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                    //    continue;
                    default:
                        record = new SaveTreeBaseRecord(reader, length);
                        break;
                }
                AddRecord(record);
            }

            LinkChildren();
        }
 /// <summary>
 /// Construct from legacy ItemRecord data.
 /// Generates new UID.
 /// </summary>
 public DaggerfallUnityItem(ItemRecord record)
 {
     uid = DaggerfallUnity.NextUID;
     FromItemRecord(record);
 }