Beispiel #1
0
        private static bool FinishItemSkillXp(ref object?item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, List <string> knownFieldList, List <string> usedFieldList, string parsedFile, string parsedKey)
        {
            PgQuestRewardSkillXp NewItem = new PgQuestRewardSkillXp();

            bool Result = true;

            if (contentTable.Count < 3)
            {
                Result = Program.ReportFailure(parsedFile, parsedKey, "Missing fields in Skill Xp reward");
            }

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                if (!knownFieldList.Contains(Key))
                {
                    Result = Program.ReportFailure($"Unknown field {Key}");
                }
                else
                {
                    usedFieldList.Add(Key);

                    switch (Key)
                    {
                    case "T":
                        break;

                    case "Skill":
                        Result = Inserter <PgSkill> .SetItemByKey((PgSkill valueSkill) => NewItem.Skill_Key = valueSkill.Key, Value);

                        break;

                    case "Xp":
                        Result = SetIntProperty((int valueInt) => NewItem.RawXp = valueInt, Value);
                        break;

                    default:
                        Result = Program.ReportFailure("Unexpected failure");
                        break;
                    }
                }

                if (!Result)
                {
                    break;
                }
            }

            if (Result)
            {
                item = NewItem;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
        public static bool SetNpcNoZone(Action <PgNpcLocation> setter, MapAreaName areaName, string npcId, string parsedFile, string parsedKey, ErrorControl errorControl)
        {
            PgNpc      ParsedNpc = null !;
            SpecialNpc NpcEnum   = SpecialNpc.Internal_None;
            string     NpcName   = string.Empty;

            PgNpcLocation NpcLocation = new PgNpcLocation();

            NpcLocation.NpcId = npcId;

            if (Inserter <PgNpc> .SetItemByKey((PgNpc valueNpc) => ParsedNpc = valueNpc, npcId, ErrorControl.IgnoreIfNotFound))
            {
                NpcLocation.Npc_Key = ParsedNpc.Key;
            }
            else if (StringToEnumConversion <SpecialNpc> .TryParse(npcId, out NpcEnum, ErrorControl.IgnoreIfNotFound))
            {
                NpcLocation.NpcEnum = NpcEnum;
            }
            else if (npcId.ToUpper().StartsWith("NPC_"))
            {
                NpcLocation.NpcName = npcId.Substring(4);
            }
            else
            {
                return(Program.ReportFailure(parsedFile, parsedKey, $"'{npcId}' unknown NPC name", errorControl));
            }

            ParsingContext.AddSuplementaryObject(NpcLocation);

            Debug.Assert(!string.IsNullOrEmpty(NpcLocation.NpcId));
            Debug.Assert(NpcLocation.Npc_Key != null || NpcLocation.NpcEnum != SpecialNpc.Internal_None || NpcLocation.NpcName.Length > 0);

            setter(NpcLocation);
            return(true);
        }
        private bool ParseRecipesThatUseItem(PgItemUse item, object value, string parsedFile, string parsedKey)
        {
            if (!(value is List <object> ObjectList))
            {
                return(Program.ReportFailure(parsedFile, parsedKey, $"Value '{value}' was expected to be a list"));
            }

            foreach (object Item in ObjectList)
            {
                if (!(Item is int ObjectId))
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, $"Value '{Item}' was expected to be an int"));
                }

                string   Key          = $"recipe_{ObjectId}";
                PgRecipe ParsedRecipe = null !;
                if (!Inserter <PgRecipe> .SetItemByKey((PgRecipe valueRecipe) => ParsedRecipe = valueRecipe, Key))
                {
                    return(false);
                }

                if (item.RecipeList.Contains(ParsedRecipe.Key))
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, $"Recipe '{Key}' already listed"));
                }

                item.RecipeList.Add(ParsedRecipe.Key);
            }

            return(true);
        }
Beispiel #4
0
        public static bool Parse(Action <PgSkill> setter, object value, string parsedFile, string parsedKey, ErrorControl errorControl = ErrorControl.Normal)
        {
            if (!(value is string ValueKey))
            {
                return(Program.ReportFailure(parsedFile, parsedKey, $"Value '{value}' was expected to be a string"));
            }

            if (ValueKey == "ArmorSmithing")
            {
                ValueKey = "Armorsmithing";
            }

            if (ValueKey == "Unknown")
            {
                setter(PgSkill.Unknown);
                return(true);
            }
            else if (ValueKey == "AnySkill")
            {
                setter(PgSkill.AnySkill);
                return(true);
            }
            else
            {
                return(Inserter <PgSkill> .SetItemByKey(setter, ValueKey, errorControl));
            }
        }
Beispiel #5
0
        private bool FinishItem(PgQuestRewardCollection item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string SkillKey = Entry.Key;
                object Value    = Entry.Value;

                PgSkill ParsedSkill = null !;
                if (!Inserter <PgSkill> .SetItemByKey((PgSkill valueSkill) => ParsedSkill = valueSkill, SkillKey))
                {
                    return(false);
                }

                if (!(Value is int XpValue))
                {
                    return(Program.ReportFailure($"Value '{Value}' was expected to be an int"));
                }

                PgQuestRewardSkillXp NewReward = new PgQuestRewardSkillXp()
                {
                    Skill_Key = ParsedSkill.Key, RawXp = XpValue
                };
                item.Add(NewReward);
            }

            return(true);
        }
Beispiel #6
0
        private static bool ParseItemEffectAttribute(string effectString, string parsedFile, string parsedKey, out PgItemEffect itemEffect)
        {
            itemEffect = null !;

            string[] Split = effectString.Split('{');
            if (Split.Length != 2)
            {
                return(false);
            }

            string AttributeName   = Split[0];
            string AttributeEffect = Split[1];

            if (!AttributeName.EndsWith("}"))
            {
                return(false);
            }

            AttributeName = AttributeName.Substring(0, AttributeName.Length - 1);
            if (AttributeName.Contains("{") || AttributeName.Contains("}"))
            {
                return(false);
            }

            if (AttributeName.Length == 0 || AttributeEffect.Length == 0)
            {
                return(false);
            }

            PgAttribute ParsedAttribute = null !;

            if (!Inserter <PgAttribute> .SetItemByKey((PgAttribute valueAttribute) => ParsedAttribute = valueAttribute, AttributeName))
            {
                return(false);
            }

            if (!Tools.TryParseFloat(AttributeEffect, out float ParsedEffect, out FloatFormat ParsedEffectFormat))
            {
                return(false);
            }

            if (ParsedEffectFormat != FloatFormat.Standard)
            {
                return(false);
            }

            itemEffect = new PgItemEffectAttribute()
            {
                Attribute_Key = ParsedAttribute.Key, AttributeEffect = ParsedEffect, AttributeEffectFormat = ParsedEffectFormat
            };
            return(true);
        }
        private bool FinishItem(PgAdvancement item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            bool Result = true;

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                PgAttribute ParsedAttribute = null !;
                float       ParsedValue     = 0;

                if (Key == "MENTAL_DEFENSE_RATING")
                {
                    continue;
                }

                Result = Inserter <PgAttribute> .SetItemByKey((PgAttribute valueAttribute) => ParsedAttribute = valueAttribute, Key);

                if (Result)
                {
                    if (Value is float FloatValue)
                    {
                        ParsedValue = FloatValue;
                    }
                    else if (Value is int IntValue)
                    {
                        ParsedValue = IntValue;
                    }
                    else
                    {
                        Result = Program.ReportFailure(parsedFile, parsedKey, $"Unknown attribute value '{Value}'");
                    }
                }

                if (Result)
                {
                    PgAdvancementEffectAttribute NewAdvancementEffectAttribute = new PgAdvancementEffectAttribute()
                    {
                        Attribute_Key = ParsedAttribute.Key, RawValue = ParsedValue
                    };

                    ParsingContext.AddSuplementaryObject(NewAdvancementEffectAttribute);
                    item.EffectAttributeList.Add(NewAdvancementEffectAttribute);
                }
            }

            return(Result);
        }
Beispiel #8
0
        private bool ParseTargetTypeTagReq(PgAbility item, object value, string parsedFile, string parsedKey)
        {
            if (value is not string AsString || !AsString.StartsWith("AnatomyType_"))
            {
                return(false);
            }

            string AnatomySkillName = AsString.Substring(12);

            AnatomySkillName = $"Anatomy_{AnatomySkillName}";

            if (!Inserter <PgSkill> .SetItemByKey((PgSkill valueSkill) => item.TargetTypeTagReq_Key = valueSkill.Key, AnatomySkillName))
            {
                return(false);
            }

            return(true);
        }
        private static bool IsBuggedDescription(string description, List <int> iconIdList, string startPattern, string endPattern, string attributeKey, out PgPowerEffect fixedEffect)
        {
            int         StartIndex      = description.IndexOf(startPattern);
            int         EndIndex        = description.LastIndexOf(endPattern);
            PgAttribute ParsedAttribute = null !;

            if (StartIndex == 0 &&
                EndIndex > startPattern.Length &&
                Tools.TryParseFloat(description.Substring(startPattern.Length, EndIndex - startPattern.Length), out float ParsedEffect, out FloatFormat ParsedEffectFormat) &&
                Inserter <PgAttribute> .SetItemByKey((PgAttribute valueAttribute) => ParsedAttribute = valueAttribute, attributeKey))
            {
                PgPowerEffectAttribute NewPowerEffectAttribute = new PgPowerEffectAttribute()
                {
                    Description = description, IconIdList = iconIdList, AttributeEffect = ParsedEffect, AttributeEffectFormat = ParsedEffectFormat
                };
                NewPowerEffectAttribute.SetAttribute(ParsedAttribute);
                fixedEffect = NewPowerEffectAttribute;
                return(true);
            }
Beispiel #10
0
        private bool ParseSourceQuest(ref object?item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            bool          Result    = true;
            PgSourceQuest NewSource = new PgSourceQuest();

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                switch (Key)
                {
                case "Type":
                    break;

                case "QuestId":
                    Result = Inserter <PgQuest> .SetItemByKey((PgQuest valueQuest) => NewSource.Quest_Key = valueQuest.Key, $"quest_{Value}");

                    break;

                default:
                    Result = Program.ReportFailure(parsedFile, parsedKey, $"Key '{Key}' not handled");
                    break;
                }

                if (!Result)
                {
                    break;
                }
            }

            if (Result)
            {
                item = NewSource;
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private bool FinishItem(PgStorageVault item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            bool Result = true;

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                switch (Key)
                {
                case "ID":
                    Result = SetIntProperty((int valueInt) => item.RawId = valueInt, Value);
                    break;

                case "NpcFriendlyName":
                    Result = SetStringProperty((string valueString) => item.NpcFriendlyName = valueString, Value);
                    break;

                case "Area":
                    Result = ParseArea((MapAreaName valueEnum) => item.Area = valueEnum, Value, parsedFile, parsedKey);
                    break;

                case "NumSlots":
                    Result = SetIntProperty((int valueInt) => item.RawNumSlots = valueInt, Value);
                    break;

                case "HasAssociatedNpc":
                    Result = SetBoolProperty((bool valueBool) => item.RawHasAssociatedNpc = valueBool, Value);
                    break;

                case "Levels":
                    Result = Inserter <PgStorageFavorLevel> .SetItemProperty((PgStorageFavorLevel valueStorageFavorLevel) => item.Levels = valueStorageFavorLevel, Value);

                    break;

                case "Requirements":
                    Result = Inserter <PgStorageRequirement> .SetItemProperty((PgStorageRequirement valueStorageRequirement) => item.Requirement = valueStorageRequirement, Value);

                    break;

                case "RequirementDescription":
                    Result = SetStringProperty((string valueString) => item.RequirementDescription = valueString, Value);
                    break;

                case "Grouping":
                    Result = ParseArea((MapAreaName valueEnum) => item.Grouping = valueEnum, Value, parsedFile, parsedKey);
                    break;

                case "RequiredItemKeywords":
                    Result = StringToEnumConversion <ItemKeyword> .TryParseList(Value, item.RequiredItemKeywordList);

                    break;

                case "SlotAttribute":
                    Result = Inserter <PgAttribute> .SetItemByKey((PgAttribute valueAttribute) => item.SlotAttribute_Key = valueAttribute.Key, Value);

                    break;

                case "EventLevels":
                    Result = Inserter <PgStorageEventList> .SetItemProperty((PgStorageEventList valueStorageEventLevel) => item.EventLevels = valueStorageEventLevel, Value);

                    break;

                default:
                    Result = Program.ReportFailure(parsedFile, parsedKey, $"Key '{Key}' not handled");
                    break;
                }

                if (!Result)
                {
                    break;
                }
            }

            if (Result)
            {
                if (!item.RawHasAssociatedNpc.HasValue || item.HasAssociatedNpc)
                {
                    Inserter <PgQuest> .SetNpc((PgNpcLocation npcLocation) => item.AssociatedNpc = npcLocation, item.Key, parsedFile, parsedKey, ErrorControl.IgnoreIfNotFound);
                }
            }

            return(Result);
        }
Beispiel #12
0
        private bool ParseSourceEffect(ref object?item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            if (!contentTable.ContainsKey("EffectName"))
            {
                return(Program.ReportFailure(parsedFile, parsedKey, "Source has no effect name"));
            }

            if (!(contentTable["EffectName"] is string EffectNameString))
            {
                return(Program.ReportFailure("Source effect name was expected to be a string"));
            }

            if (EffectNameString == "Learn Ability")
            {
                item = new PgSourceLearnAbility();
                return(true);
            }

            PgRecipe ParsedRecipe = null !;

            if (Inserter <PgRecipe> .SetItemByInternalName((PgRecipe valueRecipe) => ParsedRecipe = valueRecipe, EffectNameString, ErrorControl.IgnoreIfNotFound))
            {
                item = new PgSourceRecipe()
                {
                    Recipe_Key = ParsedRecipe.Key
                };
                return(true);
            }

            if (Inserter <PgRecipe> .SetItemByName((PgRecipe valueRecipe) => ParsedRecipe = valueRecipe, EffectNameString, ErrorControl.IgnoreIfNotFound))
            {
                item = new PgSourceRecipe()
                {
                    Recipe_Key = ParsedRecipe.Key
                };
                return(true);
            }

            PgEffect ParsedEffect = null !;

            if (Inserter <PgEffect> .SetItemByName((PgEffect valueEffect) => ParsedEffect = valueEffect, EffectNameString, ErrorControl.IgnoreIfNotFound))
            {
                item = new PgSourceEffect()
                {
                    Effect_Key = ParsedEffect.Key
                };
                return(true);
            }

            if (!contentTable.ContainsKey("EffectTypeId"))
            {
                return(Program.ReportFailure($"Unknown effect name {EffectNameString}"));
            }

            if (!(contentTable["EffectTypeId"] is string ValueString))
            {
                return(Program.ReportFailure($"Effect type id was expected to be a string"));
            }

            string EffectKey = $"effect_{ValueString}";

            if (Inserter <PgEffect> .SetItemByKey((PgEffect valueEffect) => ParsedEffect = valueEffect, EffectKey, ErrorControl.IgnoreIfNotFound))
            {
                item = new PgSourceEffect()
                {
                    Effect_Key = ParsedEffect.Key
                };
                return(true);
            }

            return(Program.ReportFailure($"Unknown effect name {EffectNameString}"));
        }
Beispiel #13
0
        private bool FinishItem(PgItem item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            bool Result = true;
            Dictionary <ItemKeyword, List <float> > KeywordTable = new Dictionary <ItemKeyword, List <float> >();
            List <string>            KeywordValueList            = new List <string>();
            Dictionary <string, int> SkillRequirementTable       = new Dictionary <string, int>();

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                switch (Key)
                {
                case "BestowRecipes":
                    Result = ParseBestowRecipeList(item, Value, parsedFile, parsedKey);
                    break;

                case "BestowAbility":
                    Result = Inserter <PgAbility> .SetItemByInternalName((PgAbility valueAbility) => item.BestowAbility_Key = valueAbility.Key, Value);

                    break;

                case "BestowQuest":
                    Result = Inserter <PgQuest> .SetItemByInternalName((PgQuest valueQuest) => item.BestowQuest_Key = valueQuest.Key, Value);

                    break;

                case "AllowPrefix":
                    Result = SetBoolProperty((bool valueBool) => item.SetAllowPrefix(valueBool), Value);
                    break;

                case "AllowSuffix":
                    Result = SetBoolProperty((bool valueBool) => item.SetAllowSuffix(valueBool), Value);
                    break;

                case "CraftPoints":
                    Result = SetIntProperty((int valueInt) => item.RawCraftPoints = valueInt, Value);
                    break;

                case "CraftingTargetLevel":
                    Result = SetIntProperty((int valueInt) => item.RawCraftingTargetLevel = valueInt, Value);
                    break;

                case "Description":
                    Result = SetStringProperty((string valueString) => item.Description = valueString, Value);
                    break;

                case "DroppedAppearance":
                    Result = ParseDroppedAppearance(item, Value, parsedFile, parsedKey);
                    break;

                case "EffectDescs":
                    Result = ParseEffectDescriptionList(item.EffectDescriptionList, Value, parsedFile, parsedKey);
                    break;

                case "DyeColor":
                    Result = ParseDyeColor(item, Value, parsedFile, parsedKey);
                    break;

                case "EquipAppearance":
                    Result = SetStringProperty((string valueString) => item.EquipAppearance = valueString, Value);     // TODO: parse
                    break;

                case "EquipSlot":
                    Result = StringToEnumConversion <ItemSlot> .SetEnum((ItemSlot valueEnum) => item.EquipSlot = valueEnum, Value);

                    break;

                case "FoodDesc":
                    Result = SetStringProperty((string valueString) => item.FoodDesc = valueString, Value);     // TODO: parse
                    break;

                case "IconId":
                    Result = SetIconIdProperty((int valueInt) => item.RawIconId = valueInt, Value);
                    break;

                case "InternalName":
                    Result = SetStringProperty((string valueString) => item.InternalName = valueString, Value);
                    break;

                case "IsTemporary":
                    Result = SetBoolProperty((bool valueBool) => item.SetIsTemporary(valueBool), Value);
                    break;

                case "IsCrafted":
                    Result = SetBoolProperty((bool valueBool) => item.SetIsCrafted(valueBool), Value);
                    break;

                case "Keywords":
                    Result = ParseKeywordList(item, Value, KeywordTable, KeywordValueList, parsedFile, parsedKey);
                    break;

                case "MacGuffinQuestName":
                    Result = Inserter <PgQuest> .SetItemByInternalName((PgQuest valueQuest) => item.MacGuffinQuest_Key = valueQuest.Key, Value);

                    break;

                case "MaxCarryable":
                    Result = SetIntProperty((int valueInt) => item.RawMaxCarryable = valueInt, Value);
                    break;

                case "MaxOnVendor":
                    Result = SetIntProperty((int valueInt) => item.RawMaxOnVendor = valueInt, Value);
                    break;

                case "MaxStackSize":
                    Result = SetIntProperty((int valueInt) => item.RawMaxStackSize = valueInt, Value);
                    break;

                case "Name":
                    Result = SetStringProperty((string valueString) => item.Name = valueString, Value);
                    break;

                case "RequiredAppearance":
                    Result = StringToEnumConversion <Appearance> .SetEnum((Appearance valueEnum) => item.RequiredAppearance = valueEnum, Value);

                    break;

                case "SkillReqs":
                    Result = ParseSkillRequirements(item, Value, SkillRequirementTable, parsedFile, parsedKey);
                    break;

                case "StockDye":
                    Result = ParseStockDye(item, Value, parsedFile, parsedKey);
                    break;

                case "TSysProfile":
                    Result = StringToEnumConversion <Profile> .SetEnum((Profile valueEnum) => item.TSysProfile = valueEnum, Value);

                    break;

                case "Value":
                    Result = SetFloatProperty((float valueFloat) => item.RawValue = valueFloat, Value);
                    break;

                case "NumUses":
                    Result = SetIntProperty((int valueInt) => item.RawNumUses = valueInt, Value);
                    break;

                case "DestroyWhenUsedUp":
                    Result = SetBoolProperty((bool valueBool) => item.SetDestroyWhenUsedUp(valueBool), Value);
                    break;

                case "Behaviors":
                    Result = Inserter <PgItemBehavior> .AddKeylessArray(item.BehaviorList, Value);

                    break;

                case "DynamicCraftingSummary":
                    Result = SetStringProperty((string valueString) => item.DynamicCraftingSummary = valueString, Value);
                    break;

                case "IsSkillReqsDefaults":
                    Result = SetBoolProperty((bool valueBool) => item.SetIsSkillReqsDefaults(valueBool), Value);
                    break;

                case "BestowTitle":
                    Result = Inserter <PgPlayerTitle> .SetItemByKey((PgPlayerTitle valuePlayerTitle) => item.BestowTitle_Key = valuePlayerTitle.Key, $"Title_{Value}");

                    break;

                case "BestowLoreBook":
                    Result = Inserter <PgLoreBook> .SetItemByKey((PgLoreBook valueLoreBook) => item.BestowLoreBook_Key = valueLoreBook.Key, $"Book_{Value}");

                    break;

                case "Lint_VendorNpc":
                    Result = StringToEnumConversion <WorkOrderSign> .SetEnum((WorkOrderSign valueEnum) => item.LintVendorNpc = valueEnum, Value);

                    break;

                case "MountedAppearance":
                    Result = SetStringProperty((string valueString) => item.MountedAppearance = valueString, Value);
                    break;

                case "AttuneOnPickup":
                    Result = SetBoolProperty((bool valueBool) => item.SetAttuneOnPickup(valueBool), Value);
                    break;

                default:
                    Result = Program.ReportFailure(parsedFile, parsedKey, $"Key '{Key}' not handled");
                    break;
                }

                if (!Result)
                {
                    break;
                }
            }

            if (Result)
            {
                item.KeywordTable          = KeywordTable;
                item.SkillRequirementTable = SkillRequirementTable;
            }

            return(Result);
        }
 private bool ParseKeywordAsSkillRequirement(PgNpcPreference item, string value, string parsedFile, string parsedKey)
 {
     return(Inserter <PgSkill> .SetItemByKey((PgSkill valueSkill) => item.SetSkillRequirement(valueSkill), value));
 }
        private bool FinishItem(PgRecipeItem item, Dictionary <string, object> contentTable, Dictionary <string, Json.Token> contentTypeTable, List <object> itemCollection, Json.Token lastItemType, string parsedFile, string parsedKey)
        {
            bool Result = true;

            foreach (KeyValuePair <string, object> Entry in contentTable)
            {
                string Key   = Entry.Key;
                object Value = Entry.Value;

                switch (Key)
                {
                case "ItemCode":
                    Result = Inserter <PgItem> .SetItemByKey((PgItem valueItem) => item.Item_Key = valueItem.Key, $"item_{Value}");

                    break;

                case "StackSize":
                    Result = SetIntProperty((int valueInt) => item.RawStackSize = valueInt, Value);
                    break;

                case "PercentChance":
                    Result = SetFloatProperty((float valueFloat) => item.RawPercentChance = valueFloat, Value);
                    break;

                case "ItemKeys":
                    Result = StringToEnumConversion <RecipeItemKey> .TryParseList(Value, item.ItemKeyList);

                    break;

                case "Desc":
                    Result = SetStringProperty((string valueString) => item.Description = valueString, Value);
                    break;

                case "ChanceToConsume":
                    Result = SetFloatProperty((float valueFloat) => item.RawChanceToConsume = valueFloat, Value);
                    break;

                case "DurabilityConsumed":
                    Result = SetFloatProperty((float valueFloat) => item.RawDurabilityConsumed = valueFloat, Value);
                    break;

                case "AttuneToCrafter":
                    Result = SetBoolProperty((bool valueBool) => item.RawAttuneToCrafter = valueBool, Value);
                    break;

                default:
                    Result = Program.ReportFailure(parsedFile, parsedKey, $"Key '{Key}' not handled");
                    break;
                }

                if (!Result)
                {
                    break;
                }
            }

            if (Result)
            {
                if (item.Item_Key == null && item.ItemKeyList.Count == 0)
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, "Missing item or item keys"));
                }

                if (item.Item_Key != null && item.ItemKeyList.Count > 0)
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, "Inconsistent item or item keys"));
                }

                if (item.ItemKeyList.Count > 0 && item.Description.Length == 0)
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, "Empty Description"));
                }

                if (item.ItemKeyList.Count == 0 && item.Description.Length > 0)
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, "Unexpected Description"));
                }

                if ((item.RawPercentChance.HasValue && item.RawChanceToConsume.HasValue) || (item.RawPercentChance.HasValue && item.RawDurabilityConsumed.HasValue) || (item.RawChanceToConsume.HasValue && item.RawDurabilityConsumed.HasValue))
                {
                    return(Program.ReportFailure(parsedFile, parsedKey, "Inconsistent percentage"));
                }

                if (item.RawPercentChance.HasValue)
                {
                    item.RawPercentChance = item.RawPercentChance.Value * 100;
                }

                if (item.RawChanceToConsume.HasValue)
                {
                    item.RawChanceToConsume = item.RawChanceToConsume.Value * 100;
                }

                if (item.RawDurabilityConsumed.HasValue)
                {
                    item.RawDurabilityConsumed = item.RawDurabilityConsumed.Value * 100;
                }
            }

            return(Result);
        }
        private static bool ParseItemEffectAttribute(string effectString, string parsedFile, string parsedKey, out PgPowerEffect powerEffect)
        {
            powerEffect = null !;

            string[] Split = effectString.Split('{');
            if (Split.Length != 2 && Split.Length != 3)
            {
                return(false);
            }

            string AttributeName   = Split[0];
            string AttributeEffect = Split[1];

            if (!AttributeName.EndsWith("}"))
            {
                return(false);
            }

            AttributeName = AttributeName.Substring(0, AttributeName.Length - 1);
            if (AttributeName.Contains("{") || AttributeName.Contains("}"))
            {
                return(false);
            }

            if (AttributeName.Length == 0 || AttributeEffect.Length == 0)
            {
                return(false);
            }

            PgAttribute ParsedAttribute = null !;

            if (!Inserter <PgAttribute> .SetItemByKey((PgAttribute valueAttribute) => ParsedAttribute = valueAttribute, AttributeName))
            {
                return(false);
            }

            if (Split.Length == 3)
            {
                if (!AttributeEffect.EndsWith("}"))
                {
                    return(false);
                }

                AttributeEffect = AttributeEffect.Substring(0, AttributeEffect.Length - 1);
            }

            if (!Tools.TryParseFloat(AttributeEffect, out float ParsedEffect, out FloatFormat ParsedEffectFormat))
            {
                return(false);
            }

            if (ParsedEffectFormat != FloatFormat.Standard)
            {
                return(false);
            }

            PgPowerEffectAttribute NewPowerEffectAttribute;

            if (Split.Length == 3)
            {
                string AttributeSkill = Split[2];

                PgSkill ParsedSkill = null !;

                if (AttributeSkill == "AnySkill")
                {
                    ParsedSkill = PgSkill.AnySkill;
                }
                else if (!Inserter <PgSkill> .SetItemByKey((PgSkill valueSkill) => ParsedSkill = valueSkill, AttributeSkill))
                {
                    return(false);
                }

                NewPowerEffectAttribute = new PgPowerEffectAttribute()
                {
                    AttributeEffect = ParsedEffect, AttributeEffectFormat = ParsedEffectFormat, Skill_Key = ParsedSkill.Key
                };
            }
            else
            {
                NewPowerEffectAttribute = new PgPowerEffectAttribute()
                {
                    AttributeEffect = ParsedEffect, AttributeEffectFormat = ParsedEffectFormat
                }
            };

            NewPowerEffectAttribute.SetAttribute(ParsedAttribute);
            powerEffect = NewPowerEffectAttribute;
            return(true);
        }