public static OwnerTarget GetBinaryOwner(ReadOnlySpan <byte> span, RecordInfoCache cache, MasterReferenceReader masters) { FormID form = new FormID(BinaryPrimitives.ReadUInt32LittleEndian(span)); FormKey formKey = FormKey.Factory(masters, form.Raw); if (cache.IsOfRecordType <Npc>(formKey)) { return(new NpcOwner() { Npc = new FormLink <INpcGetter>(FormKeyBinaryTranslation.Instance.Parse(span, masters)), Global = new FormLink <IGlobalGetter>(FormKeyBinaryTranslation.Instance.Parse(span.Slice(4), masters)) }); } else if (cache.IsOfRecordType <Faction>(formKey)) { return(new FactionOwner() { Faction = new FormLink <IFactionGetter>(FormKeyBinaryTranslation.Instance.Parse(span, masters)), RequiredRank = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(4)) }); } else { return(new NoOwner() { RawOwnerData = BinaryPrimitives.ReadUInt32LittleEndian(span), RawVariableData = BinaryPrimitives.ReadUInt32LittleEndian(span.Slice(4)) }); } }
public void Write_MasterListSync_Throw() { using var tmp = GetFile(); var mod = new SkyrimMod(WriteKey, SkyrimRelease.SkyrimLE); mod.Weapons.RecordCache.Set( new Weapon(FormKey.Factory("012345:Skyrim.esm"), SkyrimRelease.SkyrimLE)); Assert.Throws <RecordException>( () => { try { mod.WriteToBinary( tmp.File.Path, new BinaryWriteParameters() { ModKey = BinaryWriteParameters.ModKeyOption.NoCheck, MastersListContent = BinaryWriteParameters.MastersListContentOption.NoCheck, }); } catch (RecordException ex) { Assert.IsType <ArgumentException>(ex.InnerException); throw; } }); }
private TextFileFormKeyAllocator(IMod mod, string filePath) { this.Mod = mod; using var streamReader = new StreamReader(filePath); var idLine = streamReader.ReadLine(); if (!uint.TryParse(idLine, out var nextID)) { throw new ArgumentException($"Unconvertable next ID line: {idLine}"); } this.Mod.NextObjectID = nextID; while (true) { var edidStr = streamReader.ReadLine(); var formKeyStr = streamReader.ReadLine(); if (edidStr == null) { break; } if (formKeyStr == null) { throw new ArgumentException("Unexpected odd number of lines."); } var formKey = FormKey.Factory(formKeyStr); _cache.Add(edidStr, formKey); } }
public override object?ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer) { var obj = reader.Value; if (obj == null) { if (objectType == typeof(FormKey)) { return(FormKey.Null); } if (objectType == typeof(FormKey?)) { return(null); } throw new NotImplementedException(); } else { if (objectType == typeof(FormKey) || objectType == typeof(FormKey?)) { return(FormKey.Factory(obj.ToString())); } if (!objectType.Name.Contains("FormLink")) { throw new ArgumentException(); } if (objectType.Name.AsSpan()[..^ 2].EndsWith("Nullable", StringComparison.Ordinal))
public FormKey Parse( ReadOnlySpan<byte> span, MasterReferenceReader masterReferences) { var id = BinaryPrimitives.ReadUInt32LittleEndian(span); return FormKey.Factory(masterReferences, id); }
public void Comparer_Alphabetical_Equal() { FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51A:Oblivion.esm"); var compare = FormKey.AlphabeticalComparer(); Assert.Equal(0, compare.Compare(k2, k1)); }
public void Comparer_Alphabetical_ByIDGreater() { FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51B:Oblivion.esm"); var compare = FormKey.AlphabeticalComparer(); Assert.True(compare.Compare(k2, k1) > 0); }
public void Comparer_Alphabetical_ByName() { FormKey k1 = FormKey.Factory("00C51A:Knights.esm"); FormKey k2 = FormKey.Factory("00C51A:Oblivion.esm"); var compare = FormKey.AlphabeticalComparer(); Assert.True(compare.Compare(k1, k2) < 0); }
public void IteratesContainedFormLinks() { var mod = new SkyrimMod(ModKey.FromNameAndExtension("Test.esp"), SkyrimRelease.SkyrimSE); var npc = mod.Npcs.AddNew(); var key = FormKey.Factory("123456:Skyrim.esm"); npc.Class.SetTo(key); mod.ContainedFormLinks.Select(x => x.FormKey).Should().Contain(key); }
public override object?ConvertFrom(ITypeDescriptorContext?context, CultureInfo?culture, object value) { switch (value) { case string str: return(FormKey.Factory(str)); default: throw new NotImplementedException(); } }
public void Comparer_LoadOrder_Unknown() { var loadOrder = new LoadOrder <OblivionMod>() { new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")), new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")), }; FormKey k1 = FormKey.Factory("00C51A:MyMod.esm"); FormKey k2 = FormKey.Factory("00C51B:Oblivion.esm"); var compare = FormKey.LoadOrderComparer(loadOrder); Assert.Throws <ArgumentOutOfRangeException>(() => compare.Compare(k1, k2)); }
public void Comparer_LoadOrder_Typical() { var loadOrder = new LoadOrder <OblivionMod>() { new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")), new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")), }; FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51A:Knights.esm"); var compare = FormKey.LoadOrderComparer(loadOrder); Assert.True(compare.Compare(k1, k2) < 0); }
public void Comparer_ModKeyList_Unknown() { List <ModKey> modKeys = new List <ModKey>() { ModKey.FromNameAndExtension("Oblivion.esm"), ModKey.FromNameAndExtension("Knights.esm"), }; FormKey k1 = FormKey.Factory("00C51A:MyMod.esm"); FormKey k2 = FormKey.Factory("00C51B:Oblivion.esm"); var compare = FormKey.LoadOrderComparer(modKeys); Assert.Throws <ArgumentOutOfRangeException>(() => compare.Compare(k1, k2)); }
public void Comparer_ModKeyList_FallbackGreater() { List <ModKey> modKeys = new List <ModKey>() { ModKey.FromNameAndExtension("Oblivion.esm"), ModKey.FromNameAndExtension("Knights.esm"), }; FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51B:Oblivion.esm"); var compare = FormKey.LoadOrderComparer(modKeys); Assert.True(compare.Compare(k2, k1) > 0); }
public void Comparer_ModKeyList_Typical() { List <ModKey> modKeys = new List <ModKey>() { ModKey.FromNameAndExtension("Oblivion.esm"), ModKey.FromNameAndExtension("Knights.esm"), }; FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51A:Knights.esm"); var compare = FormKey.LoadOrderComparer(modKeys); Assert.True(compare.Compare(k1, k2) < 0); }
public void Comparer_LoadOrder_FallbackGreater() { var loadOrder = new LoadOrder <OblivionMod>() { new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")), new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")), }; FormKey k1 = FormKey.Factory("00C51A:Oblivion.esm"); FormKey k2 = FormKey.Factory("00C51B:Oblivion.esm"); var compare = FormKey.LoadOrderComparer(loadOrder); Assert.True(compare.Compare(k2, k1) > 0); }
public static EnumerableFormKeySettingsVM Factory(FieldMeta fieldMeta, object?defaultVal) { var defaultKeys = new List <FormKey>(); if (defaultVal is IEnumerable e) { foreach (var item in e) { defaultKeys.Add(FormKey.Factory(item.ToString())); } } return(new EnumerableFormKeySettingsVM( fieldMeta, defaultVal as IEnumerable <FormKey> ?? Enumerable.Empty <FormKey>())); }
public void Write_MasterListSync() { using var tmp = GetFile(); var mod = new SkyrimMod(WriteKey, SkyrimRelease.SkyrimLE); mod.Weapons.RecordCache.Set( new Weapon(FormKey.Factory("012345:Skyrim.esm"), SkyrimRelease.SkyrimLE)); mod.WriteToBinary( tmp.File.Path, new BinaryWriteParameters() { ModKey = BinaryWriteParameters.ModKeyOption.NoCheck, MastersListContent = BinaryWriteParameters.MastersListContentOption.Iterate, }); }
public void ParallelWrite_MasterListSync_Throw() { using var tmp = GetFile(); var mod = new SkyrimMod(WriteKey, SkyrimRelease.SkyrimLE); mod.Weapons.RecordCache.Set( new Weapon(FormKey.Factory("012345:Skyrim.esm"), SkyrimRelease.SkyrimLE)); Assert.Throws <AggregateException>( () => mod.WriteToBinaryParallel( tmp.File.Path, new BinaryWriteParameters() { ModKey = BinaryWriteParameters.ModKeyOption.NoCheck, MastersListContent = BinaryWriteParameters.MastersListContentOption.NoCheck, })); }
public LateSetPickerVM(MainVM mainVM) { SetCommand = ReactiveCommand.CreateFromTask(async() => { LinkCache = null; ScopedTypes = null; FormKey = FormKey.Null; await Task.Delay(2000); FormKey = FormKey.Factory("0136D4:Skyrim.esm"); await Task.Delay(2000); LinkCache = mainVM.LinkCache; ScopedTypes = mainVM.ScopedTypes; }); }
public static void RunPatch(IPatcherState <ISkyrimMod, ISkyrimModGetter> state) { //Your code here! var keyword_IsAdultRace = FormKey.Factory("045AF7:ImCh.esm"); var keyword_IsChildRace = FormKey.Factory("005901:ImCh.esm"); foreach (var furnitureGetter in state.LoadOrder.PriorityOrder.Furniture().WinningOverrides()) { if (furnitureGetter.InteractionKeyword == Skyrim.Keyword.ActorTypeNPC && !furnitureGetter.MajorFlags.HasFlag(Furniture.MajorFlag.ChildCanUse)) { var furniture = state.PatchMod.Furniture.GetOrAddAsOverride(furnitureGetter); furniture.InteractionKeyword.SetTo(keyword_IsAdultRace); } } foreach (var raceGetter in state.LoadOrder.PriorityOrder.Race().WinningOverrides()) { if (raceGetter.Keywords != null && raceGetter.Keywords.Contains(Skyrim.Keyword.ActorTypeNPC)) { var race = state.PatchMod.Races.GetOrAddAsOverride(raceGetter); if (race.Flags.HasFlag(Race.Flag.Child)) { if (race.Keywords != null) { race.Flags -= Race.Flag.Child; race.Flags |= Race.Flag.AllowPickpocket; race.Keywords.Add(keyword_IsChildRace); } } else { if (race.Keywords != null) { race.Keywords.Add(keyword_IsAdultRace); } } } } }
public void Write_ModNotOnLoadOrder() { using var tmp = GetFile(); var mod = new SkyrimMod(WriteKey, SkyrimRelease.SkyrimLE); mod.Weapons.RecordCache.Set( new Weapon(FormKey.Factory("012345:Skyrim.esm"), SkyrimRelease.SkyrimLE)); mod.Weapons.RecordCache.Set( new Weapon(FormKey.Factory("012345:SomeOtherMod.esp"), SkyrimRelease.SkyrimLE)); Assert.Throws <MissingModException>(() => { mod.WriteToBinary( tmp.File, new BinaryWriteParameters() { ModKey = BinaryWriteParameters.ModKeyOption.NoCheck, MastersListContent = BinaryWriteParameters.MastersListContentOption.Iterate, MastersListOrdering = new BinaryWriteParameters.MastersListOrderingByLoadOrder( Skyrim.Constants.Skyrim.AsEnumerable()) }); }); }
/// <summary> /// Some record copying and new record construction. Writes to an esp /// </summary> public static void MakeAMod(string inputPath, string outputPath) { // Create a readonly mod object from the file path, using the overlay pattern using var inputMod = SkyrimMod.CreateFromBinaryOverlay(inputPath, SkyrimRelease.SkyrimSE); // Create our mod to eventually export var outputMod = new SkyrimMod(ModKey.FromNameAndExtension(Path.GetFileName(outputPath)), SkyrimRelease.SkyrimSE); // Copy over all existing weapons, while changing their damage foreach (var weap in inputMod.Weapons) { // Make a copy of the readonly record so we can modify it var copy = weap.DeepCopy(); if (copy.BasicStats == null) { // Skip any weapon that doesn't have the stats subrecord continue; } // Bump up the damage! copy.BasicStats.Damage += 100; // Add to our output mod // The record is implicitly an override, as its FormKey originates from Skyrim.esm, not our mod. outputMod.Weapons.RecordCache.Set(copy); System.Console.WriteLine($"Overriding {copy.EditorID}"); } // Add our own brand new weapon // This convenience function creates a new weapon already added to the mod, with a new FormID var overpoweredSword = outputMod.Weapons.AddNew(); overpoweredSword.EditorID = "MutagenBlade"; overpoweredSword.Name = "Mutagen Blade"; overpoweredSword.BasicStats = new WeaponBasicStats() { Damage = 9000, Weight = 1, Value = 9000, }; // Actually, scrap this. Too many things to add by hand. Let's try by using an existing record as a template // Let's base our weapon off Skyrim's DraugrSword if (inputMod.Weapons.RecordCache.TryGetValue(FormKey.Factory("02C66F:Skyrim.esm"), out var templateSword)) { // Now we can copy in the values we like from our template. Let's skip the items we already set earlier overpoweredSword.DeepCopyIn( templateSword, // We can optionally specify a mask that copies over everything but our earlier items new Weapon.TranslationMask(true) { Name = false, EditorID = false, BasicStats = false }); // Now we are good to go, as our weapon is already in our mod, and has the values we want } else { System.Console.WriteLine("Couldn't create our sword! The template could not be found."); // I guess let's remove it outputMod.Weapons.RecordCache.Remove(overpoweredSword); } // Write out our mod outputMod.WriteToBinaryParallel(outputPath); System.Console.WriteLine($"Wrote out mod to: {new FilePath(outputPath).Path}"); PrintSeparator(); }
public override object?ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer) { var obj = reader.Value; if (obj == null) { if (objectType == typeof(FormKey)) { return(FormKey.Null); } if (objectType == typeof(FormKey?)) { return(null); } if (!objectType.Name.Contains("FormLink")) { throw new ArgumentException(); } if (IsNullableLink(objectType)) { return(Activator.CreateInstance( typeof(FormLinkNullable <>).MakeGenericType(objectType.GenericTypeArguments[0]))); } else { return(Activator.CreateInstance( typeof(FormLink <>).MakeGenericType(objectType.GenericTypeArguments[0]), FormKey.Null)); } } else { var str = obj.ToString(); if (objectType == typeof(FormKey)) { if (str.IsNullOrWhitespace()) { return(FormKey.Null); } else { return(FormKey.Factory(str)); } } else if (objectType == typeof(FormKey?)) { if (str.IsNullOrWhitespace()) { return(default(FormKey?)); } else { return(FormKey.Factory(str)); } } if (!objectType.Name.Contains("FormLink")) { throw new ArgumentException(); } FormKey key; if (str.IsNullOrWhitespace()) { key = FormKey.Null; } else { key = FormKey.Factory(str); } if (IsNullableLink(objectType)) { return(Activator.CreateInstance( typeof(FormLinkNullable <>).MakeGenericType(objectType.GenericTypeArguments[0]), key)); } else { return(Activator.CreateInstance( typeof(FormLink <>).MakeGenericType(objectType.GenericTypeArguments[0]), key)); } } }