public static int GetOrder <TMajor>(this TMajor record, SynthesisState <ISkyrimMod, ISkyrimModGetter> state) where TMajor : class, IMajorRecordCommonGetter
        {
            if (record == null || state == null)
            {
                return(-1);
            }

            return(state.LoadOrder.HasMod(record.FormKey.ModKey, true) ? state.LoadOrder.ListedOrder.Select(x => x.ModKey).ToList().IndexOf(record.FormKey.ModKey) : -1);
        }
Пример #2
0
        /// <summary>
        /// This is our actual function to do our patch
        /// </summary>
        /// <param name="state">An object containing all the parameters for our patch</param>
        public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            // Add 2 magicka offset to every NPC. Oooh boy
            foreach (var npc in state.LoadOrder.PriorityOrder.WinningOverrides <INpcGetter>())
            {
                var patchNpc = state.PatchMod.Npcs.GetOrAddAsOverride(npc);
                patchNpc.Configuration.MagickaOffset += 2;
            }

            // We will not go over the more advanced Mutagen usage here, as this area is focused on how
            // to take advantage of specific Synthesis features.  To get more examples of Mutagen usage,
            // that will still apply here, check out the Freeform project.
        }
Пример #3
0
        public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            if (!state.LoadOrder.ContainsKey(ultimateDodgeMod))
            {
                throw new Exception("ERROR: The Ultimate Dodge Mod hasn't been detected in your load order. You need to install TUDM prior to running this patcher!");
            }

            FormKey UDRollNakedLandingSetKey = ultimateDodgeMod.MakeFormKey(0x011591);
            FormKey UDRollLightLandingSetKey = ultimateDodgeMod.MakeFormKey(0x011590);
            FormKey UDRollHeavyLandingSetKey = ultimateDodgeMod.MakeFormKey(0x01158F);

            if (!state.LinkCache.TryResolve <IFootstepSetGetter>(UDRollNakedLandingSetKey, out var UDRollNakedLandingSet) || UDRollNakedLandingSet == null)
            {
                throw new Exception("ERROR: UDRollNakedLandingSet FormKey not found! Are you on the latest TUDM x64 version?");
            }
            if (!state.LinkCache.TryResolve <IFootstepSetGetter>(UDRollLightLandingSetKey, out var UDRollLightLandingSet) || UDRollLightLandingSet == null)
            {
                throw new Exception("ERROR: UDRollLightLandingSet FormKey not found! Are you on the latest TUDM x64 version?");
            }
            if (!state.LinkCache.TryResolve <IFootstepSetGetter>(UDRollHeavyLandingSetKey, out var UDRollHeavyLandingSet) || UDRollHeavyLandingSet == null)
            {
                throw new Exception("ERROR: UDRollHeavyLandingSet FormKey not found! Are you on the latest TUDM x64 version?");
            }

            foreach (var armor in state.LoadOrder.PriorityOrder.WinningOverrides <IArmorGetter>())
            {
                Console.WriteLine("CHECKING ARMOR " + armor.EditorID);
                if (armor.Keywords == null)
                {
                    continue;
                }
                if (armor.Keywords.Contains(Skyrim.Keyword.ArmorCuirass) || armor.Keywords.Contains(Skyrim.Keyword.ClothingBody))
                {
                    foreach (var armature in armor.Armature)
                    {
                        armature.TryResolve(state.LinkCache, out var armorAddonVar);
                        if (armorAddonVar == null)
                        {
                            continue;
                        }
                        else
                        {
                            ArmorAddon armorAddon = armorAddonVar.DeepCopy();
                            Console.WriteLine("CHECKING ARMATURE " + armorAddon.EditorID);
                            if (HasBodyFlag(armorAddon))
                            {
                                Console.WriteLine("ARMATURE HAS BODYFLAG");
                                switch (armor.DeepCopy().BodyTemplate !.ArmorType)
                                {
Пример #4
0
        private async Task PatchFunction(SynthesisState <IOblivionMod, IOblivionModGetter> state)
        {
            // Add a new NPC
            state.PatchMod.Npcs.AddNew();

            //Add a null item entry to all NPCs
            foreach (var npc in state.LoadOrder.PriorityOrder.WinningOverrides <INpcGetter>())
            {
                var patchNpc = state.PatchMod.Npcs.GetOrAddAsOverride(npc);
                patchNpc.Items.Add(
                    new ItemEntry()
                {
                    Count = 1,
                    Item  = FormKey.Null
                });
            }
        }
Пример #5
0
 public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
 {
     // Part 1 - Patch every placed light in worldspaces/cells
     foreach (var placedObjectGetter in state.LoadOrder.PriorityOrder.PlacedObject().WinningContextOverrides(state.LinkCache))
     {
         var placedObject = placedObjectGetter.Record;
         if (placedObject.EditorID != null)
         {
             if (placedObject.LightData == null)
             {
                 continue;
             }
         }
         state.LinkCache.TryLookup <ILightGetter>(placedObject.Base.FormKey ?? FormKey.Null, out var placedObjectBase);
         if (placedObjectBase == null || placedObjectBase.EditorID == null)
         {
             continue;
         }
         if (placedObjectBase.EditorID.ContainsInsensitive("Candle") || placedObjectBase.EditorID.ContainsInsensitive("Torch") || placedObjectBase.EditorID.ContainsInsensitive("Camp"))
         {
             if (placedObject != null && placedObject.LightData != null && placedObject.LightData.FadeOffset > 0)
             {
                 Console.WriteLine("Patching " + placedObject.EditorID + " " + placedObject.FormKey);
                 IPlacedObject modifiedObject = placedObjectGetter.GetOrAddAsOverride(state.PatchMod);
                 modifiedObject.LightData !.FadeOffset /= 2;
             }
         }
         else
         {
             continue;
         }
     }
     // Part 2 - Patch every LIGH record
     foreach (var light in state.LoadOrder.PriorityOrder.WinningOverrides <ILightGetter>())
     {
         if (light.EditorID == null)
         {
             continue;
         }
         if (light.EditorID.ContainsInsensitive("Torch") || light.EditorID.ContainsInsensitive("Camp") || light.EditorID.ContainsInsensitive("Candle"))
         {
             var modifiedLight = state.PatchMod.Lights.GetOrAddAsOverride(light);
             modifiedLight.FadeValue /= 2;
         }
     }
 }
Пример #6
0
        private static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            var armor  = new ArmorAnalyzer(state);
            var weapon = new WeaponAnalyzer(state);

            Console.WriteLine("Analyzing mod list");
            var th1 = new Thread(() => armor.Analyze());
            var th2 = new Thread(() => weapon.Analyze());

            th1.Start();
            th2.Start();
            th1.Join();
            th2.Join();

            Console.WriteLine("Generating armor enchantments");
            armor.Generate();

            Console.WriteLine("Generating weapon enchantments");
            weapon.Generate();
        }
Пример #7
0
        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);
                }
            }
        }
Пример #8
0
        private static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            Console.WriteLine($"Running Cell Editor ID Fixer ...");

            var counter = 0;

            foreach (var cellContext in state.LoadOrder.PriorityOrder.Cell().WinningContextOverrides(state.LinkCache))
            {
                var cell = cellContext.Record;
                if ((!(cell.EditorID?.Contains("_") ?? false)))
                {
                    continue;
                }
                Console.WriteLine($"Cell EDID {cell.EditorID} in {cell.FormKey.ModKey.FileName}");
                var overridenCell = cellContext.GetOrAddAsOverride(state.PatchMod);
                overridenCell.EditorID = overridenCell.EditorID?.Replace("_", "");
                counter++;
            }

            Console.WriteLine();
            Console.WriteLine($"Made overrides for {counter} CELL records.");
        }
Пример #9
0
        public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            foreach (var npc in state.LoadOrder.PriorityOrder.WinningOverrides <INpcGetter>())
            {
                // filter out NPCs that don't match the EditorIDs defined in NpcsToProtect, are already flagged as protected or flagged as essential
                if (!NpcMatchesListEditorID(npc))
                {
                    continue;
                }

                if (NpcIsEssential(npc))
                {
                    continue;
                }

                if (NpcIsProtected(npc))
                {
                    continue;
                }

                if (PatcherOutputLevel != OutputLevel.Disabled)
                {
                    Console.WriteLine("[INFO] [Processing] \"" + npc.EditorID + "\" will be flagged as Protected.");
                }

                // Patch NPCs
                var npcPatch = state.PatchMod.Npcs.GetOrAddAsOverride(npc);
                npcPatch.Configuration.Flags |= NpcConfiguration.Flag.Protected;

                // Handle error of NPC not being flagged as protected after it should have been
                if (!npcPatch.Configuration.Flags.HasFlag(NpcConfiguration.Flag.Protected))
                {
                    Console.WriteLine("[ERROR] \"" + npc.EditorID +
                                      "\" was not flagged as Protected for whatever reason.");
                }
            }
        }
Пример #10
0
        private static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            var database = JObject.Parse(File.ReadAllText(Path.Combine(state.ExtraSettingsDataPath, "database.json")))
                           .ToObject <Database>();
            Dictionary <string, FormKey>         formkeys        = new Dictionary <string, FormKey>();
            Dictionary <string, List <FormKey> > alternativekeys = new Dictionary <string, List <FormKey> >();

            foreach (var(key, value) in database.DB)
            {
                foreach (var src in database.sources)
                {
                    if (value.keyword == null)
                    {
                        continue;
                    }
                    var keyword = state.LoadOrder.PriorityOrder.Keyword()
                                  .WinningOverrides()
                                  .FirstOrDefault(kywd =>
                                                  ((kywd.FormKey.ModKey.Equals(src)) &&
                                                   ((kywd.EditorID?.ToString() ?? "") == value.keyword)));
                    if (keyword == null || formkeys.ContainsKey(key))
                    {
                        continue;
                    }
                    formkeys[key] = keyword.FormKey;
                    break;
                }
            }

            foreach (var weapon in state.LoadOrder.PriorityOrder.Weapon().WinningOverrides())
            {
                var edid             = weapon.EditorID;
                var nameToTest       = weapon.Name?.String?.ToLower();
                var matchingKeywords = database.DB.Where(kv =>
                                                         kv.Value.commonNames.Any(cn => nameToTest?.Contains(cn) ?? false))
                                       .Select(kd => kd.Key)
                                       .ToArray();
                var globalExcludes = database.excludes.phrases.Any(ph => nameToTest?.Contains(ph) ?? false) ||
                                     database.excludes.weapons.Contains(edid);

                if (database.includes.ContainsKey(edid ?? ""))
                {
                    if (formkeys.ContainsKey(database.includes[edid ?? ""]))
                    {
                        var nw = state.PatchMod.Weapons.GetOrAddAsOverride(weapon);
                        nw.Keywords?.Add(formkeys[database.includes[edid ?? ""]]);
                        Console.WriteLine(
                            $"{nameToTest} is {database.DB[database.includes[edid ?? ""]].outputDescription}, adding {database.includes[edid ?? ""]} from {formkeys[database.includes[edid ?? ""]].ModKey}");
                    }
                    else
                    {
                        Console.WriteLine(
                            $"{nameToTest} is {database.DB[database.includes[edid ?? ""]].outputDescription}, but not changing (missing esp?)");
                    }
                }

                if (matchingKeywords.Length <= 0 || globalExcludes)
                {
                    continue;
                }

                if (!matchingKeywords.All(weaponType =>
                                          weapon.Keywords?.Contains(formkeys.GetValueOrDefault(weaponType)) ?? false))
                {
                    var nw = state.PatchMod.Weapons.GetOrAddAsOverride(weapon);

                    foreach (var kyd in matchingKeywords)
                    {
                        if (formkeys.ContainsKey(kyd) && !(nw.Keywords?.Contains(formkeys[kyd]) ?? false) &&
                            !database.DB[kyd].exclude.Any(cn => nameToTest?.Contains(cn) ?? false))
                        {
                            nw.Keywords?.Add(formkeys[kyd]);
                            Console.WriteLine(
                                $"{nameToTest} is {database.DB[kyd].outputDescription}, adding {kyd} from {formkeys[kyd].ModKey}");
                        }
                    }
                }

                foreach (var kyd in matchingKeywords)
                {
                    if (!matchingKeywords.All(kyd => database.DB[kyd].akeywords?.Length > 0))
                    {
                        if (!alternativekeys.ContainsKey(kyd))
                        {
                            alternativekeys[kyd] = new List <FormKey>();
                            foreach (var keywd in database.DB[kyd].akeywords)
                            {
                                var test = state.LoadOrder.PriorityOrder.Keyword().WinningOverrides()
                                           .Where(kywd => ((kywd.EditorID ?? "") == keywd)).FirstOrDefault();
                                if (test != null)
                                {
                                    Console.WriteLine(
                                        $"Alternative Keyword found using {test.FormKey.ModKey} for {kyd}");
                                    alternativekeys[kyd].Add(test.FormKey);
                                }
                                else
                                {
                                    Console.WriteLine(
                                        $"Alternative Keyword not found generating {keywd} for {kyd}");
                                    alternativekeys[kyd].Add(state.PatchMod.Keywords.AddNew(keywd).FormKey);
                                }
                            }
                        }

                        if (alternativekeys[kyd].Count <= 0)
                        {
                            continue;
                        }
                        foreach (var alt in alternativekeys[kyd])
                        {
                            var nw = state.PatchMod.Weapons.GetOrAddAsOverride(weapon);
                            nw.Keywords?.Add(alt);
                            Console.WriteLine(
                                $"{nameToTest} is {database.DB[kyd].outputDescription}, adding extra keyword from {alt.ModKey}");
                        }
                    }
                }
            }
        }
Пример #11
0
 public SpeechPlayingForm(SynthesisState state)
 {
     InitializeComponent();
     state.Synthesizer.SpeakCompleted += SynthesizerOnSpeakCompleted;
 }
Пример #12
0
        private static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            string configFile = Path.Combine(state.ExtraSettingsDataPath, "config.json");

            if (!File.Exists(configFile))
            {
                Utils.LogThrow(new ArgumentException("Config file does not exist!"));
            }

            var config = Utils.FromJson <Config>(configFile);

            IEnumerable <IModListing <ISkyrimModGetter> >    loadOrder = state.LoadOrder.PriorityOrder;
            List <(IRaceGetter race, AttackData?attackData)> races     = loadOrder
                                                                         .WinningOverrides <IRaceGetter>()
                                                                         .Where(x => x.EditorID != null)
                                                                         .Select(race =>
            {
                try
                {
                    List <KeyValuePair <string, List <string> > > classifications = config.Classifications
                                                                                    .Where(x => x.Key.Equals(race.EditorID !, StringComparison.OrdinalIgnoreCase))
                                                                                    .ToList();

                    if (classifications.Count == 1)
                    {
                        return(race, edid: classifications.First().Key);
                    }

                    if (race.Name?.String == null)
                    {
                        return(race, edid: string.Empty);
                    }

                    classifications = config.Classifications.Where(x =>
                    {
                        var(_, value) = x;
                        return(value.Any(y => y.Equals(race.Name.String, StringComparison.OrdinalIgnoreCase)));
                    }).ToList();

                    return(race, edid: classifications.First().Key);
                }
                catch (InvalidOperationException)
                {
                    return(race, edid: string.Empty);
                }
            })
                                                                         .Where(x => !x.edid.Equals(string.Empty))
                                                                         .Select(x => config.AttackData.TryGetValue(x.edid, out var attackData) ? (x.race, attackData) : (x.race, null))
                                                                         .Where(x => x.attackData != null)
                                                                         .ToList();

            Utils.Log($"Found {races.Count} races to patch");
            foreach (var tuple in races)
            {
                var(race, attackData) = tuple;
                if (attackData == null)
                {
                    continue;
                }

                var patchedRace = state.PatchMod.Races.GetOrAddAsOverride(race);

                if (Math.Abs(attackData.AngleTolerance - float.MaxValue) > float.Epsilon)
                {
                    patchedRace.AimAngleTolerance = attackData.AngleTolerance;
                }
                if (Math.Abs(attackData.AngularAcceleration - float.MaxValue) > float.Epsilon)
                {
                    patchedRace.AngularAccelerationRate = attackData.AngularAcceleration;
                }
                if (Math.Abs(attackData.UnarmedReach - float.MaxValue) > float.Epsilon)
                {
                    patchedRace.UnarmedReach = attackData.UnarmedReach;
                }

                if (attackData.Attacks.Count == 0)
                {
                    continue;
                }
                IEnumerable <(Mutagen.Bethesda.Skyrim.Attack attackToPatch, Attack data)> attacksToPatch = patchedRace.Attacks
                                                                                                           .Where(x => x.AttackEvent != null)
                                                                                                           .Where(x => x.AttackData != null)
                                                                                                           .Where(x => attackData.Attacks.ContainsKey(x.AttackEvent !))
                                                                                                           .Select(x =>
                {
                    attackData.Attacks.TryGetValue(x.AttackEvent !, out var attack);
                    return(attackToPatch: x, data: attack !);
                });

                foreach (var valueTuple in attacksToPatch)
                {
                    var(attackToPatch, data) = valueTuple;

                    if (Math.Abs(data.StrikeAngle - float.MaxValue) > float.Epsilon)
                    {
                        attackToPatch.AttackData !.StrikeAngle = data.StrikeAngle;
                    }
                    if (Math.Abs(data.AttackAngle - float.MaxValue) > float.Epsilon)
                    {
                        attackToPatch.AttackData !.AttackAngle = data.AttackAngle;
                    }
                }
            }
        }
 public SpeechPlayingDialogBox(SynthesisState state)
     : this()
 {
     state.Synthesizer.SpeakCompleted += SynthesizerOnSpeakCompleted;
 }
Пример #14
0
        public static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            /*
             * TO DO:
             * check if exceeding 254 plugin load and warn
             * clean up, tighten up
             * custom binarywrite, to flag output as esl and stop the dummy Synthesis.esp being created
             */


            //create hash set to hold mods we want
            var modKeySet = new HashSet <ModKey>();


            //check if ActionSpeed.esp is in load order
            var mk = ModKey.FromNameAndExtension("ActionSpeed.esp");

            if (!state.LoadOrder.ContainsKey(mk))
            {
                //warning if not, stops patch
                System.Console.WriteLine($"Please add {mk} to your load order");
                return;
            }

            //adds ActionSpeed.esp to your loader as a master, as it is required by zEdit
            //patcher and this loader will not catch it otherwise. saves a manual click in zedit
            else
            {
                modKeySet.Add(mk);
            }


            // got it, carrying on
            System.Console.WriteLine($"{mk} found! Loading...");


            //detect npc records in mods, adds mods containing those records to set
            foreach (var npcGetter in state.LoadOrder.PriorityOrder.Npc().WinningOverrides())
            {
                var modKey     = npcGetter.FormKey.ModKey;
                var linkedKeys = npcGetter.LinkFormKeys.Select(l => l.ModKey);

                //add keys to our hashset
                modKeySet.Add(modKey);
                modKeySet.Add(linkedKeys);
            }

            //make sure we get mods that make overrides to npc records
            foreach (var npcGetter in state.LoadOrder.PriorityOrder.Npc().WinningContextOverrides(state.LinkCache))
            {
                //add keys to our hashset
                modKeySet.Add(npcGetter.ModKey);
            }

            //removes null mod names that may have been gathered
            modKeySet.Remove(ModKey.Null);

            //list collected masters
            foreach (ModKey key in modKeySet)
            {
                System.Console.WriteLine(key);
            }

            //shows total number of mods we're going to have as masters
            System.Console.WriteLine("\n" + "\n" + $"Adding {modKeySet.Count} masters to loader.");

            System.Console.WriteLine("Finished" + "\n");

            //getting the Skyrim data path to dump our created HeartSeekerLoader.esp, will be co-opted by mod organizer anyhow
            var dataPath = Path.Combine(GameRelease.SkyrimSE.ToWjGame().MetaData().GameLocation().ToString(), "Data");

            //gets modkey from the load order
            var myLoadOrder = state.LoadOrder.Select(loadKey => loadKey.Key);

            //takes the set of mods we've collected and adds them as masters to the esp
            state.PatchMod.ModHeader.MasterReferences.AddRange(
                modKeySet.Select(m => new MasterReference()
            {
                Master = m
            }));


            //special output of our esp to get around synthesis default, dummy synthesis esp still created
            state.PatchMod.WriteToBinary(
                Path.Combine(dataPath, "ActionSpeedLoader.esp"),
                new BinaryWriteParameters()
            {
                // Don't modify the content of the masters list with what records we have inside
                MastersListContent = BinaryWriteParameters.MastersListContentOption.NoCheck,

                // Order the masters to match load order
                //old load order getter config
                MastersListOrdering = new BinaryWriteParameters.MastersListOrderingByLoadOrder(myLoadOrder),
                //new mutagen 0.21.3, i've not got working yet
                //MastersListOrdering = new BinaryWriteParameters.MastersListOrderingByLoadOrder(state.LoadOrder),
                //Ignore default Synthesis.esp mod output name
                ModKey = BinaryWriteParameters.ModKeyOption.NoCheck,
            });
        }
Пример #15
0
        private static void RunPatch(SynthesisState <ISkyrimMod, ISkyrimModGetter> state)
        {
            string configFilePath = Path.Combine(state.ExtraSettingsDataPath, "config.json");
            string errorMessage;

            if (!File.Exists(configFilePath))
            {
                errorMessage = "Cannot find config.json for Custom Weights.";
                SynthesisLog(errorMessage);
                throw new FileNotFoundException(errorMessage, configFilePath);
            }

            try
            {
                Config = JsonConvert.DeserializeObject <Config>(File.ReadAllText(configFilePath));
            }
            catch (JsonSerializationException jsonException)
            {
                errorMessage = "Failed to Parse config.json, please review the format.";
                SynthesisLog(errorMessage);
                throw new JsonSerializationException(errorMessage, jsonException);
            }

            var weights          = Config.Weights;
            var bookWeight       = weights.Books;
            var ingredientWeight = weights.Ingredients;
            var scrollWeight     = weights.Scrolls;
            var soulGemWeight    = weights.Soulgems;
            var armorWeight      = weights.Armors;
            var weaponWeight     = weights.Weapons;
            var foodWeight       = weights.Foods;
            var potionWeight     = weights.Potions;
            var ingotWeight      = weights.Ingots;
            var gemWeight        = weights.Gems;
            var animalPartWeight = weights.AnimalParts;
            var animalHideWeight = weights.AnimalHides;
            var clutterWeight    = weights.Clutter;
            var miscWeight       = weights.MiscItems;

            // ***** PRINT CONFIG SETTINGS ***** //
            SynthesisLog("Item Weight Configuration:", true);
            if (bookWeight >= 0)
            {
                SynthesisLog($"BOOKS will have their weights set to {bookWeight}");
            }
            if (ingredientWeight >= 0)
            {
                SynthesisLog($"INGREDIENTS will have their weights set to {ingredientWeight}");
            }
            if (scrollWeight >= 0)
            {
                SynthesisLog($"SCROLLS will have their weights set to {scrollWeight}");
            }
            if (soulGemWeight >= 0)
            {
                SynthesisLog($"SOUL GEMS will have their weights set to {soulGemWeight}");
            }
            if (armorWeight >= 0)
            {
                SynthesisLog($"ARMOURS will have their weights set to {armorWeight}");
            }
            if (weaponWeight >= 0)
            {
                SynthesisLog($"WEAPONS will have their weights set to {weaponWeight}");
            }
            if (foodWeight >= 0)
            {
                SynthesisLog($"FOODS will have their weights set to {foodWeight}");
            }
            if (potionWeight >= 0)
            {
                SynthesisLog($"POTIONS will have their weights set to {potionWeight}");
            }
            if (ingotWeight >= 0)
            {
                SynthesisLog($"INGOTS will have their weights set to {ingotWeight}");
            }
            if (gemWeight >= 0)
            {
                SynthesisLog($"GEMS will have their weights set to {gemWeight}");
            }
            if (animalPartWeight >= 0)
            {
                SynthesisLog($"ANIMAL PARTS will have their weights set to {animalPartWeight}");
            }
            if (animalHideWeight >= 0)
            {
                SynthesisLog($"ANIMAL HIDES will have their weights set to {animalHideWeight}");
            }
            if (clutterWeight >= 0)
            {
                SynthesisLog($"CLUTTER will have their weights set to {clutterWeight}");
            }
            if (miscWeight >= 0)
            {
                SynthesisLog($"MISCELLANEOUS ITEMS will have their weights set to {miscWeight}");
            }

            Config.Categories.Where(c => c.Weight >= 0).ForEach(c =>
                                                                SynthesisLog($"\"{c.Name}\" category matches will have their weights set to {c.Weight}"));

            // START WORK ...
            SynthesisLog("Running Item Weight Customizer ...", true);

            // ***** BOOKS ***** //
            if (bookWeight >= 0 || ActionableCategoryExists("books"))
            {
                foreach (IBookGetter book in state.LoadOrder.PriorityOrder.WinningOverrides <IBookGetter>())
                {
                    var newWeight = FindWeightCategory("books", book.EditorID) ?? bookWeight;
                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(book.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedBook = book.DeepCopy();
                    modifiedBook.Weight = newWeight;
                    state.PatchMod.Books.Add(modifiedBook);
                }
            }

            // ***** INGREDIENTS ***** //
            if (ingredientWeight >= 0 || ActionableCategoryExists("ingredients"))
            {
                foreach (IIngredientGetter ingredient in state.LoadOrder.PriorityOrder
                         .WinningOverrides <IIngredientGetter>())
                {
                    var newWeight = FindWeightCategory("ingredients", ingredient.EditorID) ?? ingredientWeight;
                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(ingredient.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedIngredient = ingredient.DeepCopy();
                    modifiedIngredient.Weight = newWeight;
                    state.PatchMod.Ingredients.Add(modifiedIngredient);
                }
            }

            // ***** SCROLLS ***** //
            if (scrollWeight >= 0 || ActionableCategoryExists("scrolls"))
            {
                foreach (IScrollGetter scroll in state.LoadOrder.PriorityOrder.WinningOverrides <IScrollGetter>())
                {
                    var newWeight = FindWeightCategory("scrolls", scroll.EditorID) ?? scrollWeight;
                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(scroll.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedScroll = scroll.DeepCopy();
                    modifiedScroll.Weight = newWeight;
                    state.PatchMod.Scrolls.Add(modifiedScroll);
                }
            }

            // ***** SOUL GEMS ***** //
            if (soulGemWeight >= 0 || ActionableCategoryExists("soulgems"))
            {
                foreach (ISoulGemGetter soulGem in state.LoadOrder.PriorityOrder.WinningOverrides <ISoulGemGetter>())
                {
                    var newWeight = FindWeightCategory("soulgems", soulGem.EditorID) ?? soulGemWeight;
                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(soulGem.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedSoulGem = soulGem.DeepCopy();
                    modifiedSoulGem.Weight = newWeight;
                    state.PatchMod.SoulGems.Add(modifiedSoulGem);
                }
            }

            // ***** ARMOURS ***** //
            if (armorWeight >= 0 || ActionableCategoryExists("armors"))
            {
                foreach (IArmorGetter armor in state.LoadOrder.PriorityOrder.WinningOverrides <IArmorGetter>())
                {
                    var newWeight = FindWeightCategory("armors", armor.EditorID) ?? armorWeight;
                    if (Math.Abs(armor.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedArmor = armor.DeepCopy();
                    modifiedArmor.Weight = (float)Math.Round((armor.Weight * newWeight));
                    // modifiedArmor.Weight = newWeight;
                    state.PatchMod.Armors.GetOrAddAsOverride(modifiedArmor);
                }
            }

            // ***** WEAPONS ***** //
            if (weaponWeight >= 0 || ActionableCategoryExists("weapons"))
            {
                foreach (IWeaponGetter weapon in state.LoadOrder.PriorityOrder.WinningOverrides <IWeaponGetter>())
                {
                    var newWeight = FindWeightCategory("weapons", weapon.EditorID) ?? weaponWeight;
                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (weapon.BasicStats != null &&
                        Math.Abs(weapon.BasicStats.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }

                    var modifiedWeapon = state.PatchMod.Weapons.GetOrAddAsOverride(weapon);
                    //var modifiedWeapon = weapon.DeepCopy();
                    modifiedWeapon.BasicStats !.Weight = (float)Math.Round((weapon.BasicStats.Weight * newWeight));
                    // modifiedWeapon.BasicStats!.Weight = newWeight;
                    //state.PatchMod.Weapons.Add(modifiedWeapon);
                }
            }

            // ***** FOODS & POTIONS ***** //
            if (foodWeight >= 0 || potionWeight >= 0 || ActionableCategoryExists("foods") ||
                ActionableCategoryExists("potions"))
            {
                foreach (IIngestibleGetter ingestible in state.LoadOrder.PriorityOrder
                         .WinningOverrides <IIngestibleGetter>())
                {
                    float newWeight = -1;
                    if (ingestible.Keywords?.Any(link => link.FormKey == VendorItemFood) ?? false)
                    {
                        newWeight = FindWeightCategory("foods", ingestible.EditorID) ?? foodWeight;
                    }
                    else
                    {
                        newWeight = FindWeightCategory("potions", ingestible.EditorID) ?? potionWeight;
                    }

                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(ingestible.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedIngestible = ingestible.DeepCopy();
                    modifiedIngestible.Weight = newWeight;
                    state.PatchMod.Ingestibles.Add(modifiedIngestible);
                }
            }

            // ***** MISCELLANEOUS ITEMS ***** //
            if (ingotWeight >= 0 || ActionableCategoryExists("ingots") ||
                gemWeight >= 0 || ActionableCategoryExists("gems") ||
                animalPartWeight >= 0 || ActionableCategoryExists("animalParts") ||
                animalHideWeight >= 0 || ActionableCategoryExists("animalHides") ||
                clutterWeight >= 0 || ActionableCategoryExists("clutter") ||
                miscWeight >= 0 || ActionableCategoryExists("miscItems"))
            {
                foreach (IMiscItemGetter item in state.LoadOrder.PriorityOrder
                         .WinningOverrides <IMiscItemGetter>())
                {
                    float newWeight = -1;
                    if (item.Keywords?.Any(link => link.FormKey == VendorItemOreIngot) ?? false)
                    {
                        newWeight = FindWeightCategory("ingots", item.EditorID) ?? ingotWeight;
                    }
                    else if (item.Keywords?.Any(link => link.FormKey == VendorItemGem) ?? false)
                    {
                        newWeight = FindWeightCategory("gems", item.EditorID) ?? gemWeight;
                    }
                    else if (item.Keywords?.Any(link => link.FormKey == VendorItemAnimalPart) ?? false)
                    {
                        newWeight = FindWeightCategory("animalParts", item.EditorID) ?? animalPartWeight;
                    }
                    else if (item.Keywords?.Any(link => link.FormKey == VendorItemAnimalHide) ?? false)
                    {
                        newWeight = FindWeightCategory("animalHides", item.EditorID) ?? animalHideWeight;
                    }
                    else if (item.Keywords?.Any(link => link.FormKey == VendorItemClutter) ?? false)
                    {
                        newWeight = FindWeightCategory("clutter", item.EditorID) ?? clutterWeight;
                    }
                    else
                    {
                        newWeight = FindWeightCategory("miscItems", item.EditorID) ?? miscWeight;
                    }

                    if (newWeight < 0)
                    {
                        continue;
                    }
                    if (Math.Abs(item.Weight - newWeight) < float.Epsilon)
                    {
                        continue;
                    }
                    var modifiedItem = item.DeepCopy();
                    modifiedItem.Weight = (float)Math.Round((item.Weight * newWeight), 1);
                    // modifiedItem.Weight = newWeight;
                    state.PatchMod.MiscItems.Add(modifiedItem);
                }
            }

            SynthesisLog("Done patching weights!", true);
        }