private void BuildInventory(IList <string> data, InventoryConfig config, IDictionary <string, Item> items, IList <string> weaponRanks, IList <WeaponRankBonus> weaponRankBonuses) { this.Inventory = new List <UnitInventoryItem>(); foreach (int index in config.Slots) { string name = ParseHelper.SafeStringParse(data, index, "Item Name", false); if (string.IsNullOrEmpty(name)) { this.Inventory.Add(null); continue; } UnitInventoryItem item = new UnitInventoryItem(name, items); //Check if the item can be equipped string unitRank; if (this.WeaponRanks.TryGetValue(item.Item.Category, out unitRank)) { if (string.IsNullOrEmpty(unitRank) || string.IsNullOrEmpty(item.Item.WeaponRank) || weaponRanks.IndexOf(unitRank) >= weaponRanks.IndexOf(item.Item.WeaponRank)) { item.CanEquip = true; } } else if (string.IsNullOrEmpty(item.Item.WeaponRank) && !item.Item.UtilizedStats.Any()) { item.CanEquip = true; } this.Inventory.Add(item); } //Find the equipped item and flag it string equippedItemName = ParseHelper.SafeStringParse(data, config.EquippedItem, "Equipped Item", false); if (!string.IsNullOrEmpty(equippedItemName)) { UnitInventoryItem equipped = this.Inventory.FirstOrDefault(i => i != null && i.FullName == equippedItemName); if (equipped == null) { throw new UnmatchedEquippedItemException(equippedItemName); } equipped.IsEquipped = true; //Apply equipped stat modifiers foreach (string stat in equipped.Item.EquippedStatModifiers.Keys) { ModifiedStatValue mods; if (!this.Stats.General.TryGetValue(stat, out mods)) { throw new UnmatchedStatException(stat); } mods.Modifiers.Add($"{equipped.Item.Name} (Eqp)", equipped.Item.EquippedStatModifiers[stat]); } //Check if we need to apply weapon rank bonuses for the equipped item if (this.WeaponRanks.ContainsKey(equipped.Item.Category)) { string unitRank; this.WeaponRanks.TryGetValue(equipped.Item.Category, out unitRank); WeaponRankBonus bonus = weaponRankBonuses.FirstOrDefault(b => b.Category == equipped.Item.Category && b.Rank == unitRank); if (bonus != null) { foreach (string stat in bonus.CombatStatModifiers.Keys) { ModifiedStatValue mods; if (!this.Stats.Combat.TryGetValue(stat, out mods)) { throw new UnmatchedStatException(stat); } mods.Modifiers.Add($"{equipped.Item.Category} {unitRank} Rank Bonus", bonus.CombatStatModifiers[stat]); } foreach (string stat in bonus.StatModifiers.Keys) { ModifiedStatValue mods; if (!this.Stats.General.TryGetValue(stat, out mods)) { throw new UnmatchedStatException(stat); } mods.Modifiers.Add($"{equipped.Item.Category} {unitRank} Rank Bonus", bonus.StatModifiers[stat]); } } } } //Apply inventory stat modifiers for all nonequipped items foreach (UnitInventoryItem inv in this.Inventory.Where(i => i != null && !i.IsEquipped)) { foreach (string stat in inv.Item.InventoryStatModifiers.Keys) { ModifiedStatValue mods; if (!this.Stats.General.TryGetValue(stat, out mods)) { throw new UnmatchedStatException(stat); } mods.Modifiers.Add($"{inv.Item.Name} (Inv)", inv.Item.InventoryStatModifiers[stat]); } } }
/// <summary> /// Assembles and executes the equations in <paramref name="stats"/>. /// </summary> public void CalculateCombatStats(IList <CalculatedStatConfig> stats, IList <UnitInventoryItem> unitInventory) { foreach (CalculatedStatConfig stat in stats) { string equation = stat.Equation; UnitInventoryItem equipped = unitInventory.SingleOrDefault(i => i != null && i.IsEquipped); //{UnitStat[...]} //Replaced by values from the Basic stat list MatchCollection unitStatMatches = unitStatRegex.Matches(equation); if (unitStatMatches.Count > 0) { foreach (Match match in unitStatMatches) { ModifiedStatValue unitStat; if (!this.General.TryGetValue(match.Groups[1].Value, out unitStat)) { throw new UnmatchedStatException(match.Groups[1].Value); } equation = equation.Replace(match.Groups[0].Value, unitStat.FinalValue.ToString()); } } //{WeaponUtilStat} if (equation.Contains("{WeaponUtilStat}")) { int weaponUtilStatValue = 0; if (equipped != null) { foreach (string utilStatName in equipped.Item.UtilizedStats) { ModifiedStatValue weaponUtilStat; if (!this.General.TryGetValue(utilStatName, out weaponUtilStat)) { throw new UnmatchedStatException(utilStatName); } //Take the greatest stat value of all the utilized stats if (weaponUtilStat.FinalValue > weaponUtilStatValue) { weaponUtilStatValue = weaponUtilStat.FinalValue; } } } equation = equation.Replace("{WeaponUtilStat}", weaponUtilStatValue.ToString()); } //{WeaponStat[...]} MatchCollection weaponStatMatches = weaponStatRegex.Matches(equation); if (weaponStatMatches.Count > 0) { foreach (Match match in weaponStatMatches) { int weaponStatValue = 0; if (equipped != null && !equipped.Item.Stats.TryGetValue(match.Groups[1].Value, out weaponStatValue)) { throw new UnmatchedStatException(match.Groups[1].Value); } equation = equation.Replace(match.Groups[0].Value, weaponStatValue.ToString()); } } //Throw an error if anything remains unparsed if (equation.Contains("{") || equation.Contains("}")) { throw new UnrecognizedEquationVariableException(stat.Equation); } Expression expression = new Expression(equation); this.Combat[stat.SourceName].BaseValue = Math.Max(0, Convert.ToInt32(expression.Evaluate())); } }