Example #1
0
 /// <summary>
 /// Attempts to locate link target in given Link Cache.
 /// </summary>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>TryGet object with located record if successful</returns>
 public TMajorGetter?TryResolve(ILinkCache cache)
 {
     if (this.TryResolve(cache, out var rec))
     {
         return(rec);
     }
     return(default);
Example #2
0
 public Program(ILoadOrder <IModListing <ISkyrimModGetter> > loadOrder, ILinkCache <ISkyrimMod, ISkyrimModGetter> linkCache, ISkyrimMod patchMod, Lazy <Settings> settings)
 {
     LoadOrder     = loadOrder;
     LinkCache     = linkCache;
     PatchMod      = patchMod;
     this.settings = settings;
 }
        /// <summary>
        /// Will find and return the most overridden version of each record in the list of mods of the given type. <br/>
        /// <br />
        /// Additionally, it will come wrapped in a context object that has knowledge of where each record came from. <br/>
        /// This context helps when trying to override deep records such as Cells/PlacedObjects/etc, as the context is able to navigate
        /// and insert the record into the proper location for you. <br />
        /// <br />
        /// This system is overkill for simpler top-level records.
        /// </summary>
        /// <typeparam name="TMod">Setter Mod type to target</typeparam>
        /// <typeparam name="TModGetter">Getter Mod type to target</typeparam>
        /// <param name="mods">Mods to source from, in priority order</param>
        /// <param name="linkCache">LinkCache to use when creating parent objects</param>
        /// <param name="type">
        /// Type of record to search for and iterate. <br/>
        /// USAGE NOTE: <br/>
        /// Typically you should only supply the Getter interfaces for the type. <br/>
        /// A setter interface being given can result in no records being found, as most LoadOrders are readonly.
        /// </param>
        /// <param name="includeDeletedRecords">Whether to include deleted records in the output</param>
        /// <returns>Enumerable of the most overridden version of each record of the given type, optionally including deleted ones</returns>
        public static IEnumerable <IModContext <TMod, TModGetter, IMajorRecord, IMajorRecordGetter> > WinningOverrideContexts <TMod, TModGetter>(
            this IEnumerable <TModGetter> mods,
            ILinkCache linkCache,
            Type type,
            bool includeDeletedRecords = false)
            where TMod : class, IMod, TModGetter
            where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod, TModGetter>
        {
            var passedRecords = new HashSet <FormKey>();

            foreach (var mod in mods)
            {
                foreach (var record in mod.EnumerateMajorRecordContexts(linkCache, type))
                {
                    if (!passedRecords.Add(record.Record.FormKey))
                    {
                        continue;
                    }
                    if (!includeDeletedRecords && record.Record.IsDeleted)
                    {
                        continue;
                    }
                    yield return(record);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Checks if a Keyworded record contains a specific Keyword, by EditorID.
        /// Also looks up that keyword in the given cache.
        /// <br />
        /// Aspects: IKeywordedGetter&lt;IKeywordCommonGetter&gt;
        /// </summary>
        /// <param name="keyworded">Keyworded record to check</param>
        /// <param name="editorID">EditorID of the Keyword to look for</param>
        /// <param name="cache">LinkCache to resolve against</param>
        /// <param name="keyword">Keyword record retrieved, if keyworded record does contain</param>
        /// <param name="stringComparison">
        /// What string comparison type to use.<br />
        /// By default EditorIDs are case insensitive.
        /// </param>
        /// <returns>True if the Keyworded record contains a Keyword link that points to a winning Keyword record /w the given EditorID</returns>
        public static bool TryResolveKeyword <TKeyword>(
            this IKeywordedGetter <TKeyword> keyworded,
            string editorID,
            ILinkCache cache,
            [MaybeNullWhen(false)] out TKeyword keyword,
            StringComparison stringComparison = StringComparison.OrdinalIgnoreCase)
            where TKeyword : class, IKeywordCommonGetter
        {
            // ToDo
            // Consider EDID link cache systems if/when available
            if (keyworded.Keywords == null)
            {
                keyword = default;
                return(false);
            }
            foreach (var keywordForm in keyworded.Keywords.Select(link => link.FormKey))
            {
                if (cache.TryResolve <TKeyword>(keywordForm, out keyword) &&
                    (keyword.EditorID?.Equals(editorID, stringComparison) ?? false))
                {
                    return(true);
                }
            }

            keyword = default;
            return(false);
        }
Example #5
0
 public Link(ILookupTable lookupTable, ILinkCache linkCache, IRandomCharGenerator randomCharGenerator)
 {
     _lookupTable         = lookupTable;
     _linkCache           = linkCache;
     _randomCharGenerator = randomCharGenerator;
     random = new Random();
 }
Example #6
0
 public LogicCacheFacade(ILogicInstanceCache instanceCache, ILogicPageCache pageCache, ILogicTemplateCache templateCache, ILinkCache linkCache)
 {
     _linkCache    = linkCache;
     InstanceCache = instanceCache;
     PageCache     = pageCache;
     TemplateCache = templateCache;
 }
Example #7
0
 public SynthesisState(
     RunSynthesisMutagenPatcher runArguments,
     IReadOnlyList <IModListingGetter> rawLoadOrder,
     ILoadOrder <IModListing <TModGetter> > loadOrder,
     ILinkCache <TModSetter, TModGetter> linkCache,
     TModSetter patchMod,
     string extraDataPath,
     string?internalDataPath,
     string?defaultDataPath,
     CancellationToken cancellation,
     IFormKeyAllocator?formKeyAllocator)
 {
     LinkCache               = linkCache;
     RawLoadOrder            = rawLoadOrder;
     LoadOrder               = loadOrder;
     PatchMod                = patchMod;
     ExtraSettingsDataPath   = extraDataPath;
     InternalDataPath        = internalDataPath;
     DefaultSettingsDataPath = defaultDataPath;
     Cancel            = cancellation;
     LoadOrderFilePath = runArguments.LoadOrderFilePath;
     DataFolderPath    = runArguments.DataFolderPath;
     GameRelease       = runArguments.GameRelease;
     OutputPath        = runArguments.OutputPath;
     SourcePath        = runArguments.SourcePath;
     _formKeyAllocator = formKeyAllocator;
 }
 bool ILink.TryResolveCommon(ILinkCache cache, [MaybeNullWhen(false)] out IMajorRecordGetter formKey)
 {
     if (this.TryResolve(cache, out var rec))
     {
         formKey = rec;
         return(true);
     }
     formKey = default !;
Example #9
0
 /// <summary>
 /// Locates link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Located Major Record, or null if not located</returns>
 /// <typeparam name="TMajor">Major Record type of the FormLink</typeparam>
 public static TMajor?TryResolve <TMajor>(this IFormLinkGetter link, ILinkCache cache)
     where TMajor : class, IMajorRecordCommonGetter
 {
     if (link.TryResolve <TMajor>(cache, out var majorRecord))
     {
         return(majorRecord);
     }
     return(null);
 }
Example #10
0
 /// <summary>
 /// Checks if a Keyworded record contains a specific Keyword, by EditorID.
 /// <br />
 /// Aspects: IKeywordedGetter&lt;IKeywordCommonGetter&gt;
 /// </summary>
 /// <param name="keyworded">Keyworded record to check</param>
 /// <param name="editorID">EditorID of the Keyword to look for</param>
 /// <param name="cache">LinkCache to resolve against</param>
 /// <param name="stringComparison">
 /// What string comparison type to use.<br />
 /// By default EditorIDs are case insensitive.
 /// </param>
 /// <returns>True if the Keyworded record contains a Keyword link that points to a winning Keyword record /w the given EditorID</returns>
 public static bool HasKeyword <TKeyword>(
     this IKeywordedGetter <TKeyword> keyworded,
     string editorID,
     ILinkCache cache,
     StringComparison stringComparison = StringComparison.OrdinalIgnoreCase)
     where TKeyword : class, IKeywordCommonGetter
 {
     return(TryResolveKeyword(keyworded, editorID, cache, out _, stringComparison));
 }
Example #11
0
 public RecipeProcessor(HashSet <IFormLinkGetter <IItemGetter> > specificSet, HashSet <IFormLinkGetter <IItemGetter> > allSet, HashSet <IFormLinkGetter <IItemGetter> > ingredientSet,
                        ILinkCache <ISkyrimMod, ISkyrimModGetter> linkCache,
                        HashSet <IFormLinkGetter <IItemGetter> > doNotUnburdenFormKeys)
 {
     SpecificSet           = specificSet;
     AllSet                = allSet;
     IngredientSet         = ingredientSet;
     LinkCache             = linkCache;
     DoNotUnburdenFormKeys = doNotUnburdenFormKeys;
 }
Example #12
0
 /// <summary>
 /// Attempts to locate link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">FormLink to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <param name="majorRecord">Located record if successful</param>
 /// <returns>True if link was resolved and a record was retrieved</returns>
 /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
 public static bool TryResolve <TMajor>(this IFormLinkGetter link, ILinkCache cache, [MaybeNullWhen(false)] out TMajor majorRecord)
     where TMajor : class, IMajorRecordCommonGetter
 {
     if (!link.FormKeyNullable.TryGet(out var formKey))
     {
         majorRecord = default;
         return(false);
     }
     return(cache.TryResolve(formKey, out majorRecord));
 }
Example #13
0
 /// <summary>
 /// Will find and return the most overridden version of each record in the list of mods of the given type. <br/>
 /// <br />
 /// Additionally, it will come wrapped in a context object that has knowledge of where each record came from. <br/>
 /// This context helps when trying to override deep records such as Cells/PlacedObjects/etc, as the context is able to navigate
 /// and insert the record into the proper location for you. <br />
 /// <br />
 /// This system is overkill for simpler top-level records.
 /// </summary>
 /// <typeparam name="TMod">Setter Mod type to target</typeparam>
 /// <typeparam name="TModGetter">Getter Mod type to target</typeparam>
 /// <param name="loadOrder">LoadOrder to iterate over</param>
 /// <param name="linkCache">LinkCache to use when creating parent objects</param>
 /// <param name="type">
 /// Type of record to search for and iterate. <br/>
 /// USAGE NOTE: <br/>
 /// Typically you should only supply the Getter interfaces for the type. <br/>
 /// A setter interface being given can result in no records being found, as most LoadOrders are readonly.
 /// </param>
 /// <param name="includeDeletedRecords">Whether to include deleted records in the output</param>
 /// <returns>Enumerable of the most overridden version of each record of the given type, optionally including deleted ones</returns>
 public static IEnumerable <IModContext <TMod, TModGetter, IMajorRecord, IMajorRecordGetter> > WinningOverrideContexts <TMod, TModGetter>(
     this ILoadOrderGetter <TModGetter> loadOrder,
     ILinkCache linkCache,
     Type type,
     bool includeDeletedRecords = false)
     where TMod : class, IMod, TModGetter
     where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod, TModGetter>
 {
     return(loadOrder.PriorityOrder.WinningOverrideContexts <TMod, TModGetter>(linkCache, type, includeDeletedRecords: includeDeletedRecords));
 }
Example #14
0
 /// <summary>
 /// Will find and return the most overridden version of each record in the list of mods of the given type. <br/>
 /// <br />
 /// Additionally, it will come wrapped in a context object that has knowledge of where each record came from. <br/>
 /// This context helps when trying to override deep records such as Cells/PlacedObjects/etc, as the context is able to navigate
 /// and insert the record into the proper location for you. <br />
 /// <br />
 /// This system is overkill for simpler top-level records.
 /// </summary>
 /// <typeparam name="TMod">Setter Mod type to target</typeparam>
 /// <typeparam name="TModGetter">Getter Mod type to target</typeparam>
 /// <typeparam name="TSetter">
 /// Setter interface type of record to search for and iterate.
 /// </typeparam>
 /// <typeparam name="TGetter">
 /// Getter interface type of record to search for and iterate.
 /// </typeparam>
 /// <param name="loadOrder">LoadOrder to iterate over</param>
 /// <param name="linkCache">LinkCache to use when creating parent objects</param>
 /// <param name="includeDeletedRecords">Whether to include deleted records in the output</param>
 /// <returns>Enumerable of the most overridden version of each record of the given type, optionally including deleted ones</returns>
 public static IEnumerable <IModContext <TMod, TSetter, TGetter> > WinningOverrideContexts <TMod, TModGetter, TSetter, TGetter>(
     this LoadOrder <TModGetter> loadOrder,
     ILinkCache linkCache,
     bool includeDeletedRecords = true)
     where TMod : class, IMod, TModGetter
     where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod>
     where TSetter : class, IMajorRecordCommon, TGetter
     where TGetter : class, IMajorRecordCommonGetter
 {
     return(loadOrder.PriorityOrder.WinningOverrideContexts <TMod, TModGetter, TSetter, TGetter>(linkCache, includeDeletedRecords: includeDeletedRecords));
 }
Example #15
0
 /// <summary>
 /// Attempts to locate link's winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <param name="majorRecord">Major Record if located</param>
 /// <returns>True if successful in linking to record</returns>
 /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
 public static bool TryResolve <TMajor>(this IFormLinkGetter <TMajor> link, ILinkCache cache, [MaybeNullWhen(false)] out TMajor majorRecord)
     where TMajor : class, IMajorRecordGetter
 {
     if (link.FormKeyNullable is not {
     } formKey)
     {
         majorRecord = default;
         return(false);
     }
     return(cache.TryResolve <TMajor>(formKey, out majorRecord));
 }
Example #16
0
 public GameEnvironmentState(
     string gameFolderPath,
     LoadOrder <IModListing <TModGetter> > loadOrder,
     ILinkCache <TModSetter, TModGetter> linkCache,
     bool dispose = true)
 {
     GameFolderPath = gameFolderPath;
     LoadOrder      = loadOrder;
     LinkCache      = linkCache;
     _dispose       = dispose;
 }
Example #17
0
        /*private static void PatchSpells()
         * {
         *  static bool Predicate(IEffectGetter x)
         *  {
         *      if (x.Data == null) return false;
         *      var effect = x.BaseEffect.Resolve(_linkCache);
         *      return effect.Archetype.ActorValue == ActorValue.MagickaRate;
         *  }
         *
         *  List<ISpellGetter> spellsToPatch = _loadOrder.PriorityOrder.Spell().WinningOverrides()
         *      .AsParallel()
         *      .Where(spell => spell.Effects.Any(Predicate))
         *      .ToList();
         *  foreach (var spellCopy in spellsToPatch.Select(spell => _patchMod.Spells.GetOrAddAsOverride(spell)))
         *  {
         *      spellCopy.Effects.Where(Predicate).ForEach(x =>
         *      {
         *          x.Data!.Magnitude *= _settings.Value.MagickaRegen.Scale;
         *      });
         *  }
         * }*/

        public static void RunPatch(IPatcherState <ISkyrimMod, ISkyrimModGetter> state)
        {
            _linkCache = state.LinkCache;
            _loadOrder = state.LoadOrder;
            _patchMod  = state.PatchMod;
            CreateAbility();
            PatchClasses();
            PatchNPCs();
            PatchGameSettings();
            PatchRaces();
        }
Example #18
0
 /// <summary>
 /// Locates link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Located Major Record</returns>
 /// <exception cref="NullReferenceException">If link was not successful</exception>
 /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
 public static IModContext <TMajor>?ResolveSimpleContext <TMajor>(
     this IFormLinkGetter <TMajor> link,
     ILinkCache cache)
     where TMajor : class, IMajorRecordGetter
 {
     if (link.TryResolveSimpleContext <TMajor>(cache, out var majorRecord))
     {
         return(majorRecord);
     }
     return(null);
 }
Example #19
0
 /// <summary>
 /// Locate all of a link's target record contexts in given Link Cache.<br />
 /// The winning override will be returned first, and finished by the original defining definition.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Enumerable of the linked records</returns>
 /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
 public static IEnumerable <IModContext <TMajor> > ResolveAllSimpleContexts <TMajor>(
     this IFormLinkGetter <TMajor> link,
     ILinkCache cache)
     where TMajor : class, IMajorRecordGetter
 {
     if (link.FormKeyNullable is not {
     } formKey)
     {
         return(Enumerable.Empty <IModContext <TMajor> >());
     }
     return(cache.ResolveAllSimpleContexts <TMajor>(formKey));
 }
        public static void ClassifyAThing()
        {
            var theItemFormLink = Skyrim.Ingestible.Ale;

            SkyrimMod masterMod = new(theItemFormLink.FormKey.ModKey, SkyrimRelease.SkyrimSE);

            var theItem = new Ingestible(theItemFormLink.FormKey, masterMod.SkyrimRelease);

            masterMod.Ingestibles.Add(theItem);

            ModKey modKey = ModKey.FromNameAndExtension("Patch.esp");

            ISkyrimMod patchMod = new SkyrimMod(modKey, SkyrimRelease.SkyrimSE);

            var formListLink = GeneralStores.FormList.xGSxAlchCookFLST;
            var flst         = new FormList(formListLink.FormKey, patchMod.SkyrimRelease)
            {
                EditorID = nameof(GeneralStores.FormList.xGSxAlchCookFLST)
            };

            patchMod.FormLists.Add(flst);

            var newRecipe = patchMod.ConstructibleObjects.AddNew("newRecipe");

            (newRecipe.Items ??= new()).Add(new()
            {
                Item = new()
                {
                    Item = theItemFormLink
                }
            });
            newRecipe.WorkbenchKeyword.SetTo(Skyrim.Keyword.CraftingCookpot);

            LoadOrder <IModListing <ISkyrimModGetter> > loadOrder = new()
            {
                new ModListing <ISkyrimMod>(masterMod, true),
                new ModListing <ISkyrimMod>(patchMod, true)
            };

            ILinkCache <ISkyrimMod, ISkyrimModGetter> linkCache = loadOrder.ToImmutableLinkCache();

            var program = new Program(loadOrder, linkCache, patchMod, GameRelease.SkyrimSE, new());


            program.RunPatch();


            var itemLink = patchMod.FormLists.Single().Items.Single();

            Assert.Equal(theItemFormLink, itemLink.Cast <IIngestibleGetter>());
        }
    }
Example #21
0
 /// <summary>
 /// Locates link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Located Major Record</returns>
 /// <exception cref="RecordException">If link was not succesful</exception>
 /// <typeparam name="TMajor">Major Record type of the FormLink</typeparam>
 public static TMajor Resolve <TMajor>(this IFormLinkGetter link, ILinkCache cache)
     where TMajor : class, IMajorRecordCommonGetter
 {
     if (link.TryResolve <TMajor>(cache, out var majorRecord))
     {
         return(majorRecord);
     }
     throw RecordException.Create <TMajor>(
               message: "Could not resolve record",
               formKey: link.FormKeyNullable,
               modKey: link.FormKeyNullable?.ModKey,
               edid: null);
 }
Example #22
0
        /// <summary>
        /// Attempts to locate link target in given Link Cache.
        /// </summary>
        /// <param name="link">Link to resolve</param>
        /// <param name="package">Link Cache to resolve against</param>
        /// <param name="majorRecord">Major Record if located</param>
        /// <returns>True if successful in linking to record</returns>
        /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
        public static bool TryResolve <TMajor>(this ILink <TMajor> link, ILinkCache package, [MaybeNullWhen(false)] out TMajor majorRecord)
            where TMajor : IMajorRecordCommonGetter
        {
            var ret = link.TryResolve(package);

            if (ret.Succeeded)
            {
                majorRecord = ret.Value;
                return(true);
            }
            majorRecord = default;
            return(false);
        }
Example #23
0
 /// <summary>
 /// Locates link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Located Major Record</returns>
 /// <exception cref="NullReferenceException">If link was not succesful</exception>
 /// <typeparam name="TMod">Mod setter type that can be overridden into</typeparam>
 /// <typeparam name="TMajorSetter">Major Record setter type to resolve to</typeparam>
 /// <typeparam name="TMajorGetter">Major Record getter type to resolve to</typeparam>
 public static IModContext <TMod, TMajorSetter, TMajorGetter>?ResolveContext <TMod, TMajorSetter, TMajorGetter>(
     this IFormLink <TMajorGetter> link,
     ILinkCache <TMod> cache)
     where TMod : class, IContextMod <TMod>
     where TMajorSetter : class, IMajorRecordCommon, TMajorGetter
     where TMajorGetter : class, IMajorRecordCommonGetter
 {
     if (link.TryResolveContext <TMod, TMajorSetter, TMajorGetter>(cache, out var majorRecord))
     {
         return(majorRecord);
     }
     return(null);
 }
Example #24
0
 /// <summary>
 /// Locates link winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Located Major Record</returns>
 /// <exception cref="NullReferenceException">If link was not succesful</exception>
 /// <typeparam name="TMajor">Major Record type to resolve to</typeparam>
 public static TMajor?TryResolve <TMajor>(this IFormLinkGetter <TMajor> link, ILinkCache cache)
     where TMajor : class, IMajorRecordGetter
 {
     if (link.FormKeyNullable == null)
     {
         return(null);
     }
     if (link.TryResolve <TMajor>(cache, out var majorRecord))
     {
         return(majorRecord);
     }
     return(null);
 }
Example #25
0
 /// <summary>
 /// Will find and return the most overridden version of each record in the list of mods of the given type. <br/>
 /// <br />
 /// Additionally, it will come wrapped in a context object that has knowledge of where each record came from. <br/>
 /// This context helps when trying to override deep records such as Cells/PlacedObjects/etc, as the context is able to navigate
 /// and insert the record into the proper location for you. <br />
 /// <br />
 /// This system is overkill for simpler top-level records.
 /// </summary>
 /// <typeparam name="TMod">Setter Mod type to target</typeparam>
 /// <typeparam name="TModGetter">Getter Mod type to target</typeparam>
 /// <param name="modListings">Mod listings to source from, in priority order</param>
 /// <param name="linkCache">LinkCache to use when creating parent objects</param>
 /// <param name="type">
 /// Type of record to search for and iterate. <br/>
 /// USAGE NOTE: <br/>
 /// Typically you should only supply the Getter interfaces for the type. <br/>
 /// A setter interface being given can result in no records being found, as most LoadOrders are readonly.
 /// </param>
 /// <param name="includeDeletedRecords">Whether to include deleted records in the output</param>
 /// <returns>Enumerable of the most overridden version of each record of the given type, optionally including deleted ones</returns>
 public static IEnumerable <IModContext <TMod, TModGetter, IMajorRecord, IMajorRecordGetter> > WinningOverrideContexts <TMod, TModGetter>(
     this IEnumerable <IModListingGetter <TModGetter> > modListings,
     ILinkCache linkCache,
     Type type,
     bool includeDeletedRecords = false)
     where TMod : class, IMod, TModGetter
     where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod, TModGetter>
 {
     return(modListings
            .Select(l => l.Mod)
            .NotNull()
            .WinningOverrideContexts <TMod, TModGetter>(linkCache, type, includeDeletedRecords: includeDeletedRecords));
 }
Example #26
0
 internal static IEnumerable <IModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts(
     this IListGroupGetter <ICellBlockGetter> cellBlocks,
     ILinkCache linkCache,
     ModKey modKey,
     IModContext?parent)
 {
     return(EnumerateMajorRecordContexts(
                cellBlocks,
                linkCache,
                type: typeof(IMajorRecordCommonGetter),
                modKey: modKey,
                parent: parent,
                throwIfUnknown: true));
 }
Example #27
0
 /// <summary>
 /// Checks if a Keyworded record contains a specific Keyword, by FormKey.
 /// Also looks up that keyword in the given cache. <br />
 /// <br />
 /// Note that this function only succeeds if the record contains the keyword,
 /// and the cache found it as well. <br />
 /// <br />
 /// It is possible that the record contains the keyword, but it could not be found
 /// by the cache.
 /// <br />
 /// Aspects: IKeywordedGetter&lt;IKeywordCommonGetter&gt;
 /// </summary>
 /// <param name="keyworded">Keyworded record to check</param>
 /// <param name="keywordKey">FormKey of the Keyword record to look for</param>
 /// <param name="cache">LinkCache to resolve against</param>
 /// <param name="keyword">Keyword record retrieved, if keyworded record does contain</param>
 /// <returns>True if the Keyworded record contains a Keyword link /w the given FormKey</returns>
 public static bool TryResolveKeyword <TKeyword>(
     this IKeywordedGetter <TKeyword> keyworded,
     FormKey keywordKey,
     ILinkCache cache,
     [MaybeNullWhen(false)] out TKeyword keyword)
     where TKeyword : class, IKeywordCommonGetter
 {
     if (!keyworded.Keywords?.Any(x => x.FormKey == keywordKey) ?? true)
     {
         keyword = default;
         return(false);
     }
     return(cache.TryResolve(keywordKey, out keyword));
 }
Example #28
0
 /// <summary>
 /// Will find and return the most overridden version of each record in the list of mods of the given type. <br/>
 /// <br />
 /// Additionally, it will come wrapped in a context object that has knowledge of where each record came from. <br/>
 /// This context helps when trying to override deep records such as Cells/PlacedObjects/etc, as the context is able to navigate
 /// and insert the record into the proper location for you. <br />
 /// <br />
 /// This system is overkill for simpler top-level records.
 /// </summary>
 /// <typeparam name="TMod">Setter Mod type to target</typeparam>
 /// <typeparam name="TModGetter">Getter Mod type to target</typeparam>
 /// <typeparam name="TSetter">
 /// Setter interface type of record to search for and iterate.
 /// </typeparam>
 /// <typeparam name="TGetter">
 /// Getter interface type of record to search for and iterate.
 /// </typeparam>
 /// <param name="modListings">Mod listings to source from, in priority order</param>
 /// <param name="linkCache">LinkCache to use when creating parent objects</param>
 /// <param name="includeDeletedRecords">Whether to include deleted records in the output</param>
 /// <returns>Enumerable of the most overridden version of each record of the given type, optionally including deleted ones</returns>
 public static IEnumerable <IModContext <TMod, TSetter, TGetter> > WinningOverrideContexts <TMod, TModGetter, TSetter, TGetter>(
     this IEnumerable <IModListing <TModGetter> > modListings,
     ILinkCache linkCache,
     bool includeDeletedRecords = true)
     where TMod : class, IMod, TModGetter
     where TModGetter : class, IModGetter, IMajorRecordContextEnumerable <TMod>
     where TSetter : class, IMajorRecordCommon, TGetter
     where TGetter : class, IMajorRecordCommonGetter
 {
     return(modListings
            .Select(l => l.Mod)
            .NotNull()
            .WinningOverrideContexts <TMod, TModGetter, TSetter, TGetter>(linkCache, includeDeletedRecords: includeDeletedRecords));
 }
Example #29
0
 /// <summary>
 /// Locate all of a link's target record contexts in given Link Cache.<br />
 /// The winning override will be returned first, and finished by the original defining definition.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <returns>Enumerable of the linked records</returns>
 /// <typeparam name="TMod">Mod setter type that can be overridden into</typeparam>
 /// <typeparam name="TModGetter">Mod getter type that can be overridden into</typeparam>
 /// <typeparam name="TMajor">Major Record setter type to resolve to</typeparam>
 /// <typeparam name="TMajorGetter">Major Record getter type to resolve to</typeparam>
 public static IEnumerable <IModContext <TMod, TModGetter, TMajor, TMajorGetter> > ResolveAllContexts <TMod, TModGetter, TMajor, TMajorGetter>(
     this IFormLinkGetter <TMajorGetter> link,
     ILinkCache <TMod, TModGetter> cache)
     where TModGetter : class, IModGetter
     where TMod : class, TModGetter, IContextMod <TMod, TModGetter>
     where TMajor : class, IMajorRecordCommon, TMajorGetter
     where TMajorGetter : class, IMajorRecordCommonGetter
 {
     if (!link.FormKeyNullable.TryGet(out var formKey))
     {
         return(Enumerable.Empty <IModContext <TMod, TModGetter, TMajor, TMajorGetter> >());
     }
     return(cache.ResolveAllContexts <TMajor, TMajorGetter>(formKey));
 }
Example #30
0
 /// <summary>
 /// Attempts to locate link's winning target record in given Link Cache.
 /// </summary>
 /// <param name="link">Link to resolve</param>
 /// <param name="cache">Link Cache to resolve against</param>
 /// <param name="majorRecord">Major Record if located</param>
 /// <returns>True if successful in linking to record</returns>
 /// <typeparam name="TMod">Mod setter type that can be overridden into</typeparam>
 /// <typeparam name="TMajorSetter">Major Record setter type to resolve to</typeparam>
 /// <typeparam name="TMajorGetter">Major Record getter type to resolve to</typeparam>
 public static bool TryResolveContext <TMod, TMajorSetter, TMajorGetter>(
     this IFormLink <TMajorGetter> link,
     ILinkCache <TMod> cache,
     [MaybeNullWhen(false)] out IModContext <TMod, TMajorSetter, TMajorGetter> majorRecord)
     where TMod : class, IContextMod <TMod>
     where TMajorSetter : class, IMajorRecordCommon, TMajorGetter
     where TMajorGetter : class, IMajorRecordCommonGetter
 {
     if (!link.FormKeyNullable.TryGet(out var formKey))
     {
         majorRecord = default;
         return(false);
     }
     return(cache.TryResolveContext <TMajorSetter, TMajorGetter>(formKey, out majorRecord));
 }