private void OptimizeCharacter(GameData.DataBuddyInformation character, string stat, bool ignoreRecordMateria, int numberOfEquipment) { DataPartyDetails party = FFRKProxy.Instance.GameState.PartyDetails; int index = -1; for (int i = 0; i < 5; i++) { if (characters[i] != null && characters[i].BuddyId == character.BuddyId) { index = i; break; } } if (index == -1) { return; } List<uint> equippedWeapons = new List<uint>(); List<uint> equippedArmor = new List<uint>(); List<uint> equippedAccessories = new List<uint>(); List<DataRecordMateriaInformation> equippedRecordMateria = new List<DataRecordMateriaInformation>(); for (int i = 0; i < 5; i++) { if (i == index) { continue; } if (weaponBoxes[i].SelectedItem != null) { equippedWeapons.Add(((DataEquipmentInformation)weaponBoxes[i].SelectedItem).InstanceId); } if (armorBoxes[i].SelectedItem != null) { equippedArmor.Add(((DataEquipmentInformation)armorBoxes[i].SelectedItem).InstanceId); } if (accessoryBoxes[i].SelectedItem != null) { equippedAccessories.Add(((DataEquipmentInformation)accessoryBoxes[i].SelectedItem).InstanceId); } if (recordMateriaBoxes[i].SelectedItem != null) { equippedRecordMateria.Add(((DataRecordMateriaInformation)recordMateriaBoxes[i].SelectedItem)); } } List<DataEquipmentInformation> atkWeapons = new List<DataEquipmentInformation>(); foreach (DataEquipmentInformation weapon in party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Weapon && !equippedWeapons.Contains(equip.InstanceId))) { if (characters[index].UsableEquipCategories.Contains(weapon.Category)) { atkWeapons.Add(weapon); } } List<DataEquipmentInformation> atkArmor = new List<DataEquipmentInformation>(); foreach (DataEquipmentInformation armor in party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Armor && !equippedArmor.Contains(equip.InstanceId))) { if (characters[index].UsableEquipCategories.Contains(armor.Category)) { atkArmor.Add(armor); } } atkWeapons = atkWeapons.OrderByDescending(weapon => weapon.StatWithSynergy(stat, weapon.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))).ToList(); List<DataEquipmentInformation> possibleWeapons = new List<DataEquipmentInformation>(); foreach (DataEquipmentInformation weapon in atkWeapons) { if (FFRKInspector.GameData.EquipmentElementalInformation.ElementalEquipment.ContainsKey(weapon.EquipmentId) || possibleWeapons.Count(item => item.Category == weapon.Category) < numberOfEquipment) { possibleWeapons.Add(weapon); } } atkArmor = atkArmor.OrderByDescending(armor => armor.StatWithSynergy(stat, armor.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))) .ThenByDescending(armor => armor.StatWithSynergy("Res", armor.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)) + armor.StatWithSynergy("Def", armor.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))) .ToList(); List<DataEquipmentInformation> possibleArmor = new List<DataEquipmentInformation>(); foreach (DataEquipmentInformation armor in atkArmor) { if (FFRKInspector.GameData.EquipmentElementalInformation.ElementalEquipment.ContainsKey(armor.EquipmentId) || possibleArmor.Count(item => item.Category == armor.Category) < numberOfEquipment) { possibleArmor.Add(armor); } } DataEquipmentInformation accessory = party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Accessory && !equippedAccessories.Contains(equip.InstanceId)) .OrderByDescending(acc => acc.StatWithSynergy(stat, acc.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))) .ThenByDescending(acc => acc.StatWithSynergy("Res", acc.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)) + acc.StatWithSynergy("Def", acc.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))) .First(); List<DataRecordMateriaInformation> possibleRecordMateria = new List<DataRecordMateriaInformation>(); if (!ignoreRecordMateria) { possibleRecordMateria = party.RecordMaterias.Where(rm => !equippedRecordMateria.Any(eRM => eRM.RecordMateriaId == rm.RecordMateriaId)).ToList(); if ((character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.DESHI && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.SentinelsGrimoire().SoulBreakId)) || (character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.YSHTOLA && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.StoneskinII().SoulBreakId)) || (character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.RAMZA && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.Shout().SoulBreakId)) ) { if (possibleRecordMateria.Any(rm => rm.RecordMateriaId == new GameData.RecordMaterias.MakoMight().RecordMateriaId || rm.RecordMateriaId == new GameData.RecordMaterias.DrMogsTeachings().RecordMateriaId)) { possibleRecordMateria.RemoveAll(rm => !(rm.RecordMateriaId == new GameData.RecordMaterias.MakoMight().RecordMateriaId || rm.RecordMateriaId == new GameData.RecordMaterias.DrMogsTeachings().RecordMateriaId)); } } } DataEquipmentInformation weaponToEquip = null; DataEquipmentInformation armorToEquip = null; DataRecordMateriaInformation recordMateriaToEquip = null; double maxDamage = 0; GameData.SchemaConstants.Formulas formulaToUse; switch (stat) { case "Mag": formulaToUse = GameData.SchemaConstants.Formulas.Magical; break; case "Mnd": formulaToUse = GameData.SchemaConstants.Formulas.Healing; break; default: formulaToUse = GameData.SchemaConstants.Formulas.Physical; break; } GameData.Ability ability = (GameData.Ability)abilityBoxes[index * 2].SelectedItem; if (ability == null || ability.Formula != formulaToUse || ability.Category == GameData.SchemaConstants.AbilityCategory.None) { switch (formulaToUse) { case GameData.SchemaConstants.Formulas.Magical: ability = new GameData.Abilities.Ruin(); break; case GameData.SchemaConstants.Formulas.Healing: ability = new GameData.Abilities.Cure(); break; default: ability = new GameData.Abilities.Attack(); break; } } bool characterHasNightmareShift = character.EligibleForNightmareShift(RealmSynergy.NightmareCategory); bool characterHasSynergy = character != null && (character.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift); bool accessoryHasSynergy = accessory != null && (accessory.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift); int recordMateriaCount = possibleRecordMateria.Count; Dictionary<GameData.SchemaConstants.EquipmentCategory, int> categoriesChecked = new Dictionary<GameData.SchemaConstants.EquipmentCategory, int>(); foreach (DataEquipmentInformation weapon in possibleWeapons) { bool weaponHasSynergy = weapon != null && (weapon.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift); foreach (DataEquipmentInformation armor in possibleArmor) { bool armorHasSynergy = armor != null && (armor.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift); if (recordMateriaCount > 0) { foreach (DataRecordMateriaInformation recordMateria in possibleRecordMateria) { double atk = CalculateStat("Atk", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double mag = CalculateStat("Mag", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double mnd = CalculateStat("Mnd", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double damage = damagePerHit(character, weapon, armor, accessory, recordMateria, atk, mag, mnd, ability); if (damage > maxDamage) { if (damage > 9999 && maxDamage >= 9999) { continue; } maxDamage = damage; weaponToEquip = weapon; armorToEquip = armor; recordMateriaToEquip = recordMateria; } else if (damage == maxDamage && weapon == weaponToEquip && armor != armorToEquip) { bool otherArmorSynergy = armorToEquip.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift; if ((armor.StatWithSynergy("Def", armorHasSynergy) + armor.StatWithSynergy("Res", armorHasSynergy)) > (armorToEquip.StatWithSynergy("Def", otherArmorSynergy) + armorToEquip.StatWithSynergy("Res", otherArmorSynergy))) { armorToEquip = armor; } } } } else { DataRecordMateriaInformation recordMateria = recordMaterias[index]; double atk = CalculateStat("Atk", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double mag = CalculateStat("Mag", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double mnd = CalculateStat("Mnd", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy); double damage = damagePerHit(character, weapon, armor, accessory, recordMateria, atk, mag, mnd, ability); if (damage > maxDamage) { if (damage > 9999 && maxDamage >= 9999) { continue; } maxDamage = damage; weaponToEquip = weapon; armorToEquip = armor; recordMateriaToEquip = recordMateria; } else if (damage == maxDamage && weapon == weaponToEquip && armor != armorToEquip) { bool otherArmorSynergy = armorToEquip.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift; if ((armor.StatWithSynergy("Def", armorHasSynergy) + armor.StatWithSynergy("Res", armorHasSynergy)) > (armorToEquip.StatWithSynergy("Def", otherArmorSynergy) + armorToEquip.StatWithSynergy("Res", otherArmorSynergy))) { armorToEquip = armor; } } } } } if (weaponToEquip != null) { for (int i = 0; i < weaponBoxes[index].Items.Count; i++) { if (((DataEquipmentInformation)weaponBoxes[index].Items[i]).InstanceId == weaponToEquip.InstanceId) { weaponBoxes[index].SelectedIndex = i; break; } } } if (armorToEquip != null) { for (int i = 0; i < armorBoxes[index].Items.Count; i++) { if (((DataEquipmentInformation)armorBoxes[index].Items[i]).InstanceId == armorToEquip.InstanceId) { armorBoxes[index].SelectedIndex = i; break; } } } if (accessory != null) { for (int i = 0; i < accessoryBoxes[index].Items.Count; i++) { if (((DataEquipmentInformation)accessoryBoxes[index].Items[i]).InstanceId == accessory.InstanceId) { accessoryBoxes[index].SelectedIndex = i; break; } } } if (recordMateriaToEquip != null) { for (int i = 0; i < recordMateriaBoxes[index].Items.Count; i++) { if (((DataRecordMateriaInformation)recordMateriaBoxes[index].Items[i]).RecordMateriaId == recordMateriaToEquip.RecordMateriaId) { recordMateriaBoxes[index].SelectedIndex = i; break; } } } }