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.Factory(ex, item.FormKey, item.EditorID); } } }
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 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 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 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); } } }
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 void RunPatch(IPatcherState <ISkyrimMod, ISkyrimModGetter> state) { // Loop over all NPCs in the load order foreach (var npc in state.LoadOrder.PriorityOrder.Npc().WinningOverrides()) { try { // Skip NPC if it inherits spells from its template if (npc.Configuration.TemplateFlags.HasFlag(NpcConfiguration.TemplateFlag.SpellList)) { continue; } // Find if the NPC has PerkSkill or AlchemySkill perks var hasPerkSkillBoosts = false; var hasAlchemySkillBoosts = false; foreach (var perk in npc.Perks.EmptyIfNull()) { if (perk.Perk.Equals(Skyrim.Perk.AlchemySkillBoosts)) { hasAlchemySkillBoosts = true; } if (perk.Perk.Equals(Skyrim.Perk.PerkSkillBoosts)) { hasPerkSkillBoosts = true; } if (hasAlchemySkillBoosts && hasPerkSkillBoosts) { break; } } // If NPC has both, it is safe if (hasAlchemySkillBoosts && hasPerkSkillBoosts) { continue; } // Otherwise, add the NPC to the patch var modifiedNpc = state.PatchMod.Npcs.GetOrAddAsOverride(npc); // Ensure perk list exists modifiedNpc.Perks ??= new ExtendedList <PerkPlacement>(); // Add missing perks if (!hasAlchemySkillBoosts) { modifiedNpc.Perks.Add(new PerkPlacement() { Perk = Skyrim.Perk.AlchemySkillBoosts, Rank = 1 }); } if (!hasPerkSkillBoosts) { modifiedNpc.Perks.Add(new PerkPlacement() { Perk = Skyrim.Perk.PerkSkillBoosts, Rank = 1 }); } } catch (Exception ex) { throw RecordException.Factory(ex, npc); } } }