public static partial void CustomBinaryEndExport(MutagenWriter writer, IWorldspaceGetter obj) { try { var topCell = obj.TopCell; var subCells = obj.SubCells; if (subCells?.Count == 0 && topCell == null) { return; } using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.WorldChildren); writer.Write(obj.SubCellsTimestamp); writer.Write(obj.SubCellsUnknown); topCell?.WriteToBinary(writer); ListBinaryTranslation <IWorldspaceBlockGetter> .Instance.Write( writer : writer, items : subCells, transl : (MutagenWriter subWriter, IWorldspaceBlockGetter subItem) => { subItem.WriteToBinary(subWriter); }); } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public virtual void Write( MutagenWriter writer, IGlobalGetter item, TypedWriteParams?translationParams = null) { using (HeaderExport.Record( writer: writer, record: translationParams.ConvertToCustom(RecordTypes.GLOB))) { try { OblivionMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); writer.MetaData.FormVersion = item.FormVersion; WriteRecordTypes( item: item, writer: writer, translationParams: translationParams); writer.MetaData.FormVersion = null; } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void Write( MutagenWriter writer, ISpellLeveledGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.LVSP), type: ObjectType.Record)) { try { OblivionMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); SpellBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void Write( MutagenWriter writer, ILensFlareGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.LENS), type: Mutagen.Bethesda.Binary.ObjectType.Record)) { try { SkyrimMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void Write( MutagenWriter writer, IMaterialSwapGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.MSWP), type: ObjectType.Record)) { try { Fallout4MajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void Write( MutagenWriter writer, ISpellLeveledGetter item, TypedWriteParams?translationParams = null) { using (HeaderExport.Record( writer: writer, record: translationParams.ConvertToCustom(RecordTypes.LVSP))) { try { OblivionMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); SpellBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, translationParams: translationParams); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public virtual void Write( MutagenWriter writer, IGameSettingGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.GMST), type: ObjectType.Record)) { try { SkyrimMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public virtual void Write( MutagenWriter writer, IGlobalGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.GLOB), type: Mutagen.Bethesda.Binary.ObjectType.Record)) { try { OblivionMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); writer.MetaData.FormVersion = item.FormVersion; WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); writer.MetaData.FormVersion = null; } catch (Exception ex) { throw RecordException.Factory(ex, item.FormKey, item.EditorID); } } }
public void CreateWithUmbrellaInterface() { var ex = new Exception(); var rec = RecordException.Create <IItem>("Message", FormKey.Null, "SomeEdid"); rec.RecordType.Should().Be(typeof(IItem)); }
public void Write( MutagenWriter writer, IHairGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.HAIR), type: Mutagen.Bethesda.Binary.ObjectType.Record)) { try { Fallout4MajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Factory(ex, item.FormKey, item.EditorID); } } }
public void Write( MutagenWriter writer, IActorValueInformationGetter item, TypedWriteParams?translationParams = null) { using (HeaderExport.Record( writer: writer, record: translationParams.ConvertToCustom(RecordTypes.AVIF))) { try { Fallout4MajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, translationParams: translationParams); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void EnrichWithUmbrellaInterface() { var ex = new Exception(); var rec = RecordException.Enrich <IItem>(ex, FormKey.Null, "SomeEdid"); rec.RecordType.Should().Be(typeof(IItem)); }
public static partial void CustomBinaryEndExport(MutagenWriter writer, IDialogTopicGetter obj) { try { if (!obj.Items.TryGet(out var items) || items.Count == 0) { return; } using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.TopicChildren); writer.Write(obj.Timestamp); ListBinaryTranslation <IDialogItemGetter> .Instance.Write( writer : writer, items : items, transl : (MutagenWriter subWriter, IDialogItemGetter subItem) => { subItem.WriteToBinary(subWriter); }); } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public static Dictionary <CustomSet <ModKey>, RecordsClassifiedByMasters <TMod, TModGetter> > ClassifyRecordsByReferencedMasters <TMod, TModGetter>( TModGetter patchMod, CustomSetFactory <ModKey> setFactory, int maximumMastersPerMod = MAXIMUM_MASTERS_PER_MOD) where TMod : class, IMod, TModGetter where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod, TModGetter> { var recordSets = new Dictionary <CustomSet <ModKey>, RecordsClassifiedByMasters <TMod, TModGetter> >(); var masterSetBuilder = setFactory.NewSet(); var patchModKey = patchMod.ModKey; var linkCache = patchMod.ToUntypedImmutableLinkCache(); foreach (IModContext <TMod, TModGetter, IMajorRecordCommon, IMajorRecordCommonGetter>?context in patchMod.EnumerateMajorRecordContexts <IMajorRecordCommon, IMajorRecordCommonGetter>(linkCache, false)) { masterSetBuilder.Clear(); bool isNewRecord = false; IModContext?thisContext = context; while (thisContext is not null) { var record = context.Record; var modKey = record.FormKey.ModKey; masterSetBuilder.Add(modKey); if (modKey == patchModKey) { isNewRecord = true; } // TODO Does this include all child records? foreach (var link in record.ContainedFormLinks) { masterSetBuilder.Add(link.FormKey.ModKey); } thisContext = thisContext.Parent; int recordMasterCount = masterSetBuilder.Count; if (recordMasterCount > maximumMastersPerMod) { throw RecordException.Factory(new Exception($"Too many masters ({recordMasterCount}) referenced by one record"), record); } } CustomSet <ModKey> masterSet = masterSetBuilder.ToCustomSet(); var recordSet = recordSets.Autovivify(masterSet, () => new(masterSet)); recordSet.contextSet.Add(context); if (isNewRecord) { recordSet.hasNewRecords = true; } } return(recordSets); }
public void Write( MutagenWriter writer, ILensFlareGetter item, TypedWriteParams?translationParams = null) { using (HeaderExport.Record( writer: writer, record: translationParams.ConvertToCustom(RecordTypes.LENS))) { try { SkyrimMajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, translationParams: translationParams); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
public void Write( MutagenWriter writer, IActorValueInformationGetter item, RecordTypeConverter?recordTypeConverter = null) { using (HeaderExport.Header( writer: writer, record: recordTypeConverter.ConvertToCustom(RecordTypes.AVIF), type: Mutagen.Bethesda.Binary.ObjectType.Record)) { try { Fallout4MajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Enrich(ex, item); } } }
static partial void CustomBinaryEndImport(MutagenFrame frame, IWorldspaceInternal obj) { try { if (!frame.Reader.TryReadGroup(out var groupHeader)) { return; } if (groupHeader.GroupType == (int)GroupTypeEnum.WorldChildren) { obj.SubCellsTimestamp = BinaryPrimitives.ReadInt32LittleEndian(groupHeader.LastModifiedData); var formKey = FormKeyBinaryTranslation.Instance.Parse(groupHeader.ContainedRecordTypeData, frame.MetaData.MasterReferences !); if (formKey != obj.FormKey) { throw new ArgumentException("Cell children group did not match the FormID of the parent worldspace."); } } else { frame.Reader.Position -= groupHeader.HeaderLength; return; } var subFrame = MutagenFrame.ByLength(frame.Reader, groupHeader.ContentLength); for (int i = 0; i < 3; i++) { if (subFrame.Complete) { return; } var subType = HeaderTranslation.GetNextSubrecordType(frame.Reader, out var subLen); switch (subType.TypeInt) { case 0x44414F52: // "ROAD": obj.Road = Road.CreateFromBinary(subFrame); break; case 0x4C4C4543: // "CELL": obj.TopCell = Cell.CreateFromBinary(subFrame); break; case 0x50555247: // "GRUP": obj.SubCells.SetTo( Mutagen.Bethesda.Binary.ListBinaryTranslation <WorldspaceBlock> .Instance.Parse( frame: frame, triggeringRecord: RecordTypes.GRUP, transl: LoquiBinaryTranslation <WorldspaceBlock> .Instance.Parse)); break; default: return; } } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public static partial void CustomBinaryEndImport(MutagenFrame frame, ICellInternal obj) { try { CustomBinaryEnd(frame, obj); } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public T this[FormKey key] { get { try { return(ConstructWrapper(this._locs[key])); } catch (Exception ex) { throw RecordException.Factory(ex, key, edid: null); } } }
public IEnumerator <IKeyValue <T, FormKey> > GetEnumerator() { foreach (var kv in this._locs) { KeyValue <T, FormKey> item; try { item = new KeyValue <T, FormKey>(kv.Key, ConstructWrapper(kv.Value)); } catch (Exception ex) { throw RecordException.Factory(ex, kv.Key, edid: null); } yield return(item); } }
public virtual void Write( MutagenWriter writer, IAPlacedGetter item, RecordTypeConverter?recordTypeConverter = null) { try { Fallout4MajorRecordBinaryWriteTranslation.WriteEmbedded( item: item, writer: writer); MajorRecordBinaryWriteTranslation.WriteRecordTypes( item: item, writer: writer, recordTypeConverter: recordTypeConverter); } catch (Exception ex) { throw RecordException.Factory(ex, item.FormKey, item.EditorID); } }
public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state) { foreach (var armorAddon in state.LoadOrder.PriorityOrder.WinningOverrides <IArmorAddonGetter>()) { try { if (armorAddon.BodyTemplate == null || !(armorAddon.BodyTemplate.FirstPersonFlags.HasFlag(BipedObjectFlag.Body) && armorAddon.BodyTemplate.FirstPersonFlags.HasFlag(BipedObjectFlag.Amulet))) { continue; } // Ignore things that are probably skins like Miraak's hidden skin if (armorAddon.BodyTemplate.FirstPersonFlags.HasFlag(BipedObjectFlag.Head) && armorAddon.BodyTemplate.FirstPersonFlags.HasFlag(BipedObjectFlag.Hair) && armorAddon.BodyTemplate.FirstPersonFlags.HasFlag(BipedObjectFlag.Hands)) { continue; } // Ignore Naked Torso and Child Clothes if (armorAddon.EditorID == null || armorAddon.EditorID.Contains("Naked") || armorAddon.EditorID.Contains("Child")) { continue; } var modifiedArmorAddon = state.PatchMod.ArmorAddons.GetOrAddAsOverride(armorAddon); if (modifiedArmorAddon.BodyTemplate == null) { modifiedArmorAddon.BodyTemplate = new BodyTemplate(); } modifiedArmorAddon.BodyTemplate.FirstPersonFlags &= ~BipedObjectFlag.Amulet; } catch (Exception ex) { throw RecordException.Factory(ex, armorAddon); } } }
public static partial void CustomBinaryEndImport(MutagenFrame frame, IDialogTopicInternal obj) { try { if (frame.Reader.Complete) { return; } if (!frame.TryGetGroup(out var groupMeta)) { return; } if (groupMeta.GroupType == (int)GroupTypeEnum.TopicChildren) { obj.Timestamp = BinaryPrimitives.ReadInt32LittleEndian(groupMeta.LastModifiedData); obj.Unknown = frame.GetInt32(offset: 20); if (FormKey.Factory(frame.MetaData.MasterReferences !, BinaryPrimitives.ReadUInt32LittleEndian(groupMeta.ContainedRecordTypeData)) != obj.FormKey) { throw new ArgumentException("Dialog children group did not match the FormID of the parent."); } } else { return; } frame.Reader.Position += groupMeta.HeaderLength; obj.Responses.SetTo(ListBinaryTranslation <DialogResponses> .Instance.Parse( reader: frame.SpawnWithLength(groupMeta.ContentLength), transl: (MutagenFrame r, RecordType header, out DialogResponses listItem) => { return(LoquiBinaryTranslation <DialogResponses> .Instance.Parse( frame: r, item: out listItem)); })); } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
partial void CustomEnd(OverlayStream stream, int finalPos, int offset) { try { if (stream.Complete) { return; } var startPos = stream.Position; if (!stream.TryGetGroup(out var groupMeta)) { return; } if (groupMeta.GroupType != (int)GroupTypeEnum.TopicChildren) { return; } this._grupData = stream.ReadMemory(checked ((int)groupMeta.TotalLength)); var formKey = FormKey.Factory(_package.MetaData.MasterReferences !, BinaryPrimitives.ReadUInt32LittleEndian(groupMeta.ContainedRecordTypeData)); if (formKey != this.FormKey) { throw new ArgumentException("Dialog children group did not match the FormID of the parent."); } var contentSpan = this._grupData.Value.Slice(_package.MetaData.Constants.GroupConstants.HeaderLength); this.Items = BinaryOverlayList.FactoryByArray <IDialogItemGetter>( contentSpan, _package, getter: (s, p) => DialogItemBinaryOverlay.DialogItemFactory(new OverlayStream(s, p), p), locs: ParseRecordLocations( stream: new OverlayStream(contentSpan, _package), trigger: DialogItem_Registration.TriggeringRecordType, constants: GameConstants.Oblivion.MajorConstants, skipHeader: false)); } catch (Exception ex) { throw RecordException.Enrich(ex, this); } }
public void CreateFindResultTest() { var record1 = new Record("someRecordKey", "someBody"); var record2 = new Record("anotherRecordKey", "anotherBody"); var exception = new RecordException(); var findResult = new FindResult(new List <Record> { record1, record2 }, new List <RecordException> { exception }, 10, 1, 3, 2); Assert.AreEqual(2, findResult.Records.Count); Assert.AreEqual(1, findResult.Errors.Count); Assert.AreEqual(10, findResult.Limit); Assert.AreEqual(1, findResult.Offset); Assert.AreEqual(3, findResult.Total); Assert.AreEqual(2, findResult.Count); Assert.AreEqual(record1.RecordKey, findResult.Records[0].RecordKey); Assert.AreEqual(record1.RecordKey, findResult.Records[0].RecordKey); Assert.AreEqual(record2.RecordKey, findResult.Records[1].RecordKey); Assert.AreEqual(record2.RecordKey, findResult.Records[1].RecordKey); }
public void PatchNpcs() { /* * 1. Loop over all npcs. * 2. Verify it is not a ghost, an inherited template, and has a valid race * 3. Check if it has a match with a race in races.json * 4. Add perks based on settings.json * */ foreach (var npc in this.state.LoadOrder.PriorityOrder.WinningOverrides <INpcGetter>()) { try { if (npc.Configuration.TemplateFlags.HasFlag(NpcConfiguration.TemplateFlag.SpellList) || npc.EditorID == null) { continue; // Perks are inherited from a template } if (npc.Keywords != null && npc.Keywords.Contains(Skyrim.Keyword.ActorTypeGhost)) { continue; // Ghost shouldnt be affected by armor } if (!npc.Race.TryResolve(state.LinkCache, out var race) || race.EditorID == null || !this.racesToPatch.Contains(race.EditorID)) { continue; } var npcCopy = this.state.PatchMod.Npcs.GetOrAddAsOverride(npc); if (npcCopy.Perks == null) { npcCopy.Perks = new ExtendedList <PerkPlacement>(); } foreach (var perk in this.perksToAdd) { PerkPlacement p = new PerkPlacement { Rank = 1, Perk = perk.AsLink <IPerkGetter>() }; npcCopy.Perks.Add(p); } if (npc.EditorID == "Player" && this.settings.Racials) { // a quest runs after racemenu that will sift and apply the correct racial perk. This perk is removed after. PerkPlacement p = new PerkPlacement { Rank = 1, Perk = FormKeys.Perks.ASX_DummyPerk.AsLink <IPerkGetter>() }; npcCopy.Perks.Add(p); continue; } if (this.settings.Racials && ActionSpeedX.FormKeys.Perks.RacialPerks.ContainsKey(race.EditorID)) { PerkPlacement p = new PerkPlacement { Rank = 1, Perk = FormKeys.Perks.RacialPerks[race.EditorID].AsLink <IPerkGetter>() }; npcCopy.Perks.Add(p); } if (this.settings.Factions && npc.Factions != null) { foreach (var faction in npc.Factions) { if (faction.Faction.TryResolve(this.state.LinkCache, out var wtf) && wtf.EditorID != null && ActionSpeedX.FormKeys.Perks.FactionPerks.ContainsKey(wtf.EditorID)) { PerkPlacement p = new PerkPlacement { Rank = 1, Perk = FormKeys.Perks.FactionPerks[wtf.EditorID].AsLink <IPerkGetter>() }; npcCopy.Perks.Add(p); } } } } catch (Exception e) { throw RecordException.Factory("Error processing npc record", npc, e); } } }
public static partial void CustomBinaryEndExport(MutagenWriter writer, ICellGetter obj) { try { var navMeshes = obj.NavigationMeshes; var landscape = obj.Landscape; if ((obj.Persistent?.Count ?? 0) == 0 && (obj.Temporary?.Count ?? 0) == 0 && navMeshes.Count == 0 && landscape == null) { return; } using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellChildren); writer.Write(obj.Timestamp); writer.Write(obj.UnknownGroupData); if (obj.Persistent?.Count > 0) { using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellPersistentChildren); writer.Write(obj.PersistentTimestamp); writer.Write(obj.PersistentUnknownGroupData); ListBinaryTranslation <IPlacedGetter> .Instance.Write( writer : writer, items : obj.Persistent, transl : WritePlaced); } } if (obj.Temporary?.Count > 0 || navMeshes.Count > 0 || landscape != null) { using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellTemporaryChildren); writer.Write(obj.TemporaryTimestamp); writer.Write(obj.TemporaryUnknownGroupData); landscape?.WriteToBinary(writer); foreach (var navMesh in navMeshes) { navMesh.WriteToBinary(writer); } if (obj.Temporary != null) { ListBinaryTranslation <IPlacedGetter> .Instance.Write( writer : writer, items : obj.Temporary, transl : WritePlaced); } } } } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
private static void CustomBinaryEnd(MutagenFrame frame, ICellInternal obj) { try { if (frame.Reader.Complete) { return; } if (!frame.TryGetGroup(out var groupMeta)) { return; } var formKey = FormKey.Factory(frame.MetaData.MasterReferences !, BinaryPrimitives.ReadUInt32LittleEndian(groupMeta.ContainedRecordTypeData)); if (groupMeta.GroupType == (int)GroupTypeEnum.CellChildren) { obj.Timestamp = BinaryPrimitives.ReadInt32LittleEndian(groupMeta.LastModifiedData); obj.UnknownGroupData = BinaryPrimitives.ReadInt32LittleEndian(groupMeta.HeaderData.Slice(groupMeta.HeaderData.Length - 4)); frame.Position += groupMeta.HeaderLength; if (formKey != obj.FormKey) { throw new ArgumentException("Cell children group did not match the FormID of the parent cell."); } } else { return; } var subFrame = frame.SpawnWithLength(groupMeta.ContentLength); while (!subFrame.Complete) { var persistGroupMeta = frame.GetGroup(); if (!persistGroupMeta.IsGroup) { throw new ArgumentException(); } GroupTypeEnum type = (GroupTypeEnum)persistGroupMeta.GroupType; var itemFrame = frame.SpawnWithLength(persistGroupMeta.TotalLength); switch (type) { case GroupTypeEnum.CellTemporaryChildren: ParseTemporary( itemFrame, obj); break; case GroupTypeEnum.CellPersistentChildren: ParseTypical( itemFrame, obj); break; default: throw new NotImplementedException(); } } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public static partial void CustomBinaryEndExport(MutagenWriter writer, ICellGetter obj) { try { var pathGrid = obj.PathGrid; var landscape = obj.Landscape; if ((obj.Persistent?.Count ?? 0) == 0 && (obj.Temporary?.Count ?? 0) == 0 && (obj.VisibleWhenDistant?.Count ?? 0) == 0 && pathGrid == null && landscape == null) { return; } using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellChildren); writer.Write(obj.Timestamp); if (obj.Persistent?.Count > 0) { using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellPersistentChildren); writer.Write(obj.PersistentTimestamp); ListBinaryTranslation <IPlacedGetter> .Instance.Write( writer : writer, items : obj.Persistent, transl : (r, item) => { item.WriteToBinary(r); }); } } if (obj.Temporary?.Count > 0 || pathGrid != null || landscape != null) { using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellTemporaryChildren); writer.Write(obj.TemporaryTimestamp); landscape?.WriteToBinary(writer); pathGrid?.WriteToBinary(writer); if (obj.Temporary != null) { ListBinaryTranslation <IPlacedGetter> .Instance.Write( writer : writer, items : obj.Temporary, transl : (r, item) => { item.WriteToBinary(r); }); } } } if (obj.VisibleWhenDistant?.Count > 0) { using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group)) { FormKeyBinaryTranslation.Instance.Write( writer, obj.FormKey); writer.Write((int)GroupTypeEnum.CellVisibleDistantChildren); writer.Write(obj.VisibleWhenDistantTimestamp); ListBinaryTranslation <IPlacedGetter> .Instance.Write( writer : writer, items : obj.VisibleWhenDistant, transl : (r, item) => { item.WriteToBinary(r); }); } } } } catch (Exception ex) { throw RecordException.Enrich(ex, obj); } }
public void PatchArmors() { /** * 1. Loop over all armors. * 2. For each armor, iterate over its keywords and match it to the tier rank in armor_rankings.json. Grab the HIGHEST tier. * 3. Based on that tier + armor slot + armor type, assign it a keyword from the appropiate ASX_<armor> keyword from Light/HeavyArmorKeywordCollection * 4. If description setting is turned on, update the item description. */ foreach (var armor in this.state.LoadOrder.PriorityOrder.WinningOverrides <IArmorGetter>()) { try { if (armor.EditorID == null || armor.Keywords == null || armor.BodyTemplate == null || armor.BodyTemplate.ArmorType == ArmorType.Clothing) { continue; } string armorType; Dictionary <string, List <FormKey> > armorKeysMap; if (armor.BodyTemplate.ArmorType == ArmorType.LightArmor) { armorKeysMap = ActionSpeedX.FormKeys.Keywords.LightArmorKeywordCollection; armorType = LIGHT; } else { armorKeysMap = ActionSpeedX.FormKeys.Keywords.HeavyArmorKeywordCollection; armorType = HEAVY; } int tier = -1; /* We want to grab the highest material tier as some items can have multiple material keywrods * Loop over the armorRankings(see armor_materials.json) and check the current armors keywords for a match. * Item.key = int/str, item.val=List(armor material strings) */ foreach (var keyword in armor.Keywords) { if (keyword.TryResolve(state.LinkCache, out var kw)) { if (kw.EditorID != null && this.materialRanks.ContainsKey(kw.EditorID)) { int rank = this.materialRanks[kw.EditorID]; if (rank > tier) { tier = rank; } } } } if (tier < 0) { Console.WriteLine($"No recognized material type for {armor.EditorID}. Skipping. "); // tier = 1; continue; } else { tier--; //correct array access } string slot; if (armor.Keywords.Contains(Skyrim.Keyword.ArmorBoots)) { slot = BOOTS; } else if (armor.Keywords.Contains(Skyrim.Keyword.ArmorCuirass)) { slot = CUIRASS; } else if (armor.Keywords.Contains(Skyrim.Keyword.ArmorGauntlets)) { slot = GAUNTLETS; } else if (armor.Keywords.Contains(Skyrim.Keyword.ArmorHelmet)) { slot = HELMET; } else if (armor.Keywords.Contains(Skyrim.Keyword.ArmorShield)) { slot = SHIELD; } else { Console.WriteLine("No matching equip slot for " + armor.EditorID); continue; } var nw = state.PatchMod.Armors.GetOrAddAsOverride(armor); nw.Keywords?.Add(armorKeysMap[slot][tier]); if (this.settings.Descriptions) { PatchArmorDescription(nw, armorType, slot, tier); } } catch (Exception e) { throw RecordException.Factory("Error processing armor record", armor, e); } } }