/// <summary> /// Add a servant from the player's Chaldea to the battle party and equip the specified CE (if available) /// </summary> /// <param name="party"></param> /// <param name="chaldeaServant"></param> /// <param name="chaldeaCraftEssence"></param> /// <param name="additionalDamageBonus"></param> /// <returns></returns> public async Task <PartyMember> AddPartyMember(List <PartyMember> party, ChaldeaServant chaldeaServant, CraftEssence chaldeaCraftEssence, float additionalDamageBonus = 0.0f) { ServantNiceJson servantNiceJson = await _aaClient.GetServantInfo(chaldeaServant.ServantBasicInfo.Id.ToString()); int servantTotalAtk = servantNiceJson.AtkGrowth[chaldeaServant.ServantLevel - 1] + chaldeaServant.FouAttack; int servantTotalHp = servantNiceJson.HpGrowth[chaldeaServant.ServantLevel - 1] + chaldeaServant.FouHealth; PartyMember partyMember = new PartyMember { Id = party.Count, Servant = chaldeaServant, ServantNiceInfo = servantNiceJson, TotalAttack = servantTotalAtk, TotalHealth = servantTotalHp, NoblePhantasm = servantNiceJson // Set NP for party member at start of fight .NoblePhantasms // (assume highest upgraded NP by priority) .Aggregate((agg, next) => next.Priority >= agg.Priority ? next : agg), AdditionalDamageBonus = additionalDamageBonus }; if (chaldeaCraftEssence != null) { partyMember.EquippedCraftEssence = chaldeaCraftEssence; partyMember.EquipNiceInfo = await _aaClient.GetCraftEssenceInfo(chaldeaCraftEssence.CraftEssenceInfo.Id.ToString()); partyMember.TotalAttack += partyMember.EquipNiceInfo.AtkGrowth[chaldeaCraftEssence.CraftEssenceLevel - 1]; partyMember.TotalHealth += partyMember.EquipNiceInfo.HpGrowth[chaldeaCraftEssence.CraftEssenceLevel - 1]; ApplyCraftEssenceEffects(partyMember); } return(partyMember); }
public static void Update(this List <ChaldeaServant> chaldeaServants, ChaldeaServant chaldeaServant) { int index = chaldeaServants.FindIndex(c => c.ServantBasicInfo.Id == chaldeaServant.ServantBasicInfo.Id); if (index == -1) { chaldeaServants.Add(chaldeaServant); } else { chaldeaServants.RemoveAt(index); chaldeaServants.Insert(index, chaldeaServant); } }
private void CalculateEmbersNeeded(ChaldeaServant currentServant, ChaldeaServant goalServant, List <int> expGrowth) { // Reference: https://gamepress.gg/grandorder/exp-calculator // Reference: https://fategrandorder.fandom.com/wiki/Leveling const float FOUR_STAR_EMBER = 27000.0f; const float FOUR_STAR_EMBER_CLASS_BONUS = 32400.0f; const float FIVE_STAR_EMBER = 81000.0f; const float FIVE_STAR_EMBER_CLASS_BONUS = 97200.0f; int expNeeded = expGrowth[goalServant.ServantLevel - 1] - expGrowth[currentServant.ServantLevel - 1]; _requiredItemMaterials.FourStarEmber += (int)Math.Ceiling(expNeeded / FOUR_STAR_EMBER); _requiredItemMaterials.FourStarEmberClassBonus += (int)Math.Ceiling(expNeeded / FOUR_STAR_EMBER_CLASS_BONUS); _requiredItemMaterials.FiveStarEmber += (int)Math.Ceiling(expNeeded / FIVE_STAR_EMBER); _requiredItemMaterials.FiveStarEmberClassBonus += (int)Math.Ceiling(expNeeded / FIVE_STAR_EMBER_CLASS_BONUS); }
/// <summary> /// Set up party member based on pre-defined servant and craft essence info /// </summary> /// <param name="basicJson">Basic information for a servant</param> /// <param name="party">List of party members</param> /// <param name="resolvedClasses">Dependently injected classes that are resolved using Autofac</param> /// <param name="npLevel">The Noble Phantasm level of a servant</param> /// <param name="isSupport">Declare if this is a support (friend) servant</param> /// <param name="craftEssence">The craft being used with the servant</param> /// <param name="additionalDamageBonus">Damage bonus added manually for a party member. Example would be servant damage bonus for a specific event</param> /// <returns></returns> public static async Task <PartyMember> PartyMemberAsync(ServantBasicJson basicJson, List <PartyMember> party, ScopedClasses resolvedClasses, int npLevel = 1, bool isSupport = false, CraftEssence craftEssence = null, float additionalDamageBonus = 0.0f) { ServantNiceJson json = await resolvedClasses.AtlasAcademyClient.GetServantInfo(basicJson.Id.ToString()); ChaldeaServant chaldeaServant = new ChaldeaServant { ServantLevel = json.LvMax, NpLevel = npLevel, FouHealth = 1000, FouAttack = 1000, SkillLevels = new int[] { 10, 10, 10 }, IsSupportServant = isSupport, ServantBasicInfo = basicJson }; return(await resolvedClasses.CombatFormula.AddPartyMember(party, chaldeaServant, craftEssence, additionalDamageBonus)); }
public async Task WaverLored100() { _wireMockFixture.CheckIfMockServerInUse(); _wireMockUtility.AddStubs(_wireMockFixture); using (var scope = _container.BeginLifetimeScope()) { ScopedClasses resolvedClasses = AutofacUtility.ResolveScope(scope); ConstantExportJson constantExportJson = await FrequentlyUsed.GetConstantExportJsonAsync(resolvedClasses.AtlasAcademyClient); int servantId = 501900; ServantBasicJson servantBasicJson = constantExportJson.ListServantBasicJson.Find(s => s.Id == servantId); /* Load servants as if they're already in a save file */ ChaldeaServant currentServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 1, SkillLevels = new int[] { 1, 1, 1 } }; ChaldeaServant goalServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 100, SkillLevels = new int[] { 10, 10, 10 } }; RequiredItemMaterials req = resolvedClasses.MaterialCalculation.HowMuchIsNeeded( currentServant, goalServant, constantExportJson.GrailCostNiceJson, await resolvedClasses.AtlasAcademyClient.GetServantInfo(servantId.ToString())); Dictionary <string, int> materials = resolvedClasses.MaterialCalculation.GroupItemParents(req.Items); MaterialOutput(req, materials); using (new AssertionScope()) { RequiredItemsShouldBe(req, 222600000, 5, 753, 627, 251, 209); materials.Should().Contain("Caster Monument", 17); materials.Should().Contain("Caster Piece", 17); materials.Should().Contain("Crystallized Lore", 3); materials.Should().Contain("Eternal Gear", 15); materials.Should().Contain("Forbidden Page", 55); materials.Should().Contain("Gem of Caster", 51); materials.Should().Contain("Heart of the Foreign God", 33); materials.Should().Contain("Magic Gem of Caster", 51); materials.Should().Contain("Phoenix Feather", 70); materials.Should().Contain("Secret Gem of Caster", 51); materials.Should().Contain("Void's Dust", 105); } } }
public async Task ArashOneLore100() { _wireMockFixture.CheckIfMockServerInUse(); _wireMockUtility.AddStubs(_wireMockFixture); using (var scope = _container.BeginLifetimeScope()) { ScopedClasses resolvedClasses = AutofacUtility.ResolveScope(scope); ConstantExportJson constantExportJson = await FrequentlyUsed.GetConstantExportJsonAsync(resolvedClasses.AtlasAcademyClient); int servantId = 201300; ServantBasicJson servantBasicJson = constantExportJson.ListServantBasicJson.Find(s => s.Id == servantId); /* Load servants as if they're already in a save file */ ChaldeaServant currentServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 1, SkillLevels = new int[] { 1, 1, 1 } }; ChaldeaServant goalServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 100, SkillLevels = new int[] { 1, 1, 10 } }; RequiredItemMaterials req = resolvedClasses.MaterialCalculation.HowMuchIsNeeded( currentServant, goalServant, constantExportJson.GrailCostNiceJson, await resolvedClasses.AtlasAcademyClient.GetServantInfo(servantId.ToString())); Dictionary <string, int> materials = resolvedClasses.MaterialCalculation.GroupItemParents(req.Items); MaterialOutput(req, materials); using (new AssertionScope()) { RequiredItemsShouldBe(req, 32950000, 10, 753, 627, 251, 209); materials.Should().Contain("Archer Monument", 6); materials.Should().Contain("Archer Piece", 6); materials.Should().Contain("Crystallized Lore", 1); materials.Should().Contain("Gem of Archer", 6); materials.Should().Contain("Homunculus Baby", 8); materials.Should().Contain("Magic Gem of Archer", 6); materials.Should().Contain("Octuplet Crystals", 6); materials.Should().Contain("Proof of Hero", 25); materials.Should().Contain("Secret Gem of Archer", 6); materials.Should().Contain("Seed of Yggdrasil", 9); materials.Should().Contain("Void's Dust", 24); } } }
public async Task UshiwakamaruRiderSkilled100() { _wireMockFixture.CheckIfMockServerInUse(); _wireMockUtility.AddStubs(_wireMockFixture); using (var scope = _container.BeginLifetimeScope()) { ScopedClasses resolvedClasses = AutofacUtility.ResolveScope(scope); ConstantExportJson constantExportJson = await FrequentlyUsed.GetConstantExportJsonAsync(resolvedClasses.AtlasAcademyClient); int servantId = 401400; ServantBasicJson servantBasicJson = constantExportJson.ListServantBasicJson.Find(s => s.Id == servantId); /* Load servants as if they're already in a save file */ ChaldeaServant currentServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 1, SkillLevels = new int[] { 1, 1, 1 } }; ChaldeaServant goalServant = new ChaldeaServant { ServantBasicInfo = servantBasicJson, FouAttack = 1000, FouHealth = 1000, IsSupportServant = false, NpLevel = 1, ServantLevel = 100, SkillLevels = new int[] { 9, 9, 9 } }; RequiredItemMaterials req = resolvedClasses.MaterialCalculation.HowMuchIsNeeded( currentServant, goalServant, constantExportJson.GrailCostNiceJson, await resolvedClasses.AtlasAcademyClient.GetServantInfo(servantId.ToString())); Dictionary <string, int> materials = resolvedClasses.MaterialCalculation.GroupItemParents(req.Items); MaterialOutput(req, materials); using (new AssertionScope()) { RequiredItemsShouldBe(req, 72130000, 9, 753, 627, 251, 209); materials.Should().Contain("Eternal Gear", 48); materials.Should().Contain("Gem of Rider", 36); materials.Should().Contain("Ghost Lantern", 11); materials.Should().Contain("Magic Gem of Rider", 36); materials.Should().Contain("Meteor Horseshoe", 40); materials.Should().Contain("Octuplet Crystals", 56); materials.Should().Contain("Proof of Hero", 105); materials.Should().Contain("Rider Monument", 12); materials.Should().Contain("Rider Piece", 12); materials.Should().Contain("Secret Gem of Rider", 36); } } }
public RequiredItemMaterials HowMuchIsNeeded(ChaldeaServant currentServant, ChaldeaServant goalServant, GrailCostNiceJson grailCostNiceJson, ServantNiceJson currentServantNiceJson) { // Validate the two servant objects are the same servant if (currentServant.ServantBasicInfo != goalServant.ServantBasicInfo) { return(null); } // Set up _requiredItemMaterials = new RequiredItemMaterials(); // Allows nice JSON info to be saved prior, if provided if (currentServantNiceJson != null && currentServantNiceJson.Id == currentServant.ServantBasicInfo.Id) { _currentServantNiceJson = currentServantNiceJson; } else { return(_requiredItemMaterials); } /* Calculate ascension materials, QP, and/or grails */ if (currentServant.ServantLevel < goalServant.ServantLevel) { AscensionLevel[] allAscensionLevels = AscensionLevels(currentServant.ServantBasicInfo.Rarity); // Find the required ascension levels with removing ascensions above the goal List <AscensionLevel> requiredAscensionLevels = allAscensionLevels .Where(i => currentServant.ServantLevel < i.LevelCap) .ToList(); requiredAscensionLevels.RemoveAll(c => goalServant.ServantLevel < c.LevelCap); // Ascension materials if (requiredAscensionLevels.Count > 0) { foreach (AscensionLevel ascensionLevel in requiredAscensionLevels) { ItemMaterials ascensionItemMaterials = AscensionItemMaterials(ascensionLevel); if (ascensionItemMaterials == null) { continue; } _requiredItemMaterials.Qp += ascensionItemMaterials.Qp; AddItemMaterials(ascensionItemMaterials.Items); } } // Grails if (goalServant.ServantLevel > allAscensionLevels[^ 1].LevelCap) { IEnumerable <GrailInfo> grailInfoList = GetGrailRarityInfo(goalServant.ServantBasicInfo.Rarity, grailCostNiceJson) .Where(g => g.AddLevelMax + currentServant.ServantLevel <= goalServant.ServantLevel); foreach (GrailInfo grailInfo in grailInfoList) { _requiredItemMaterials.Qp += grailInfo.Qp; _requiredItemMaterials.GrailCount++; } } // Overall ember count CalculateEmbersNeeded(currentServant, goalServant, _currentServantNiceJson.ExpGrowth); } /* Calculate skill materials and QP */ for (int i = 0; i < 3; i++) { int currentSkillLevel = currentServant.SkillLevels[i]; int goalSkillLevel = goalServant.SkillLevels[i]; if (currentSkillLevel < goalSkillLevel) { for (int j = currentSkillLevel; j < goalSkillLevel; j++) { switch (j) { case 1: AddItemMaterials(_currentServantNiceJson.SkillMaterials.FirstSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.FirstSkill.Qp; break; case 2: AddItemMaterials(_currentServantNiceJson.SkillMaterials.SecondSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.SecondSkill.Qp; break; case 3: AddItemMaterials(_currentServantNiceJson.SkillMaterials.ThirdSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.ThirdSkill.Qp; break; case 4: AddItemMaterials(_currentServantNiceJson.SkillMaterials.FourthSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.FourthSkill.Qp; break; case 5: AddItemMaterials(_currentServantNiceJson.SkillMaterials.FifthSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.FifthSkill.Qp; break; case 6: AddItemMaterials(_currentServantNiceJson.SkillMaterials.SixthSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.SixthSkill.Qp; break; case 7: AddItemMaterials(_currentServantNiceJson.SkillMaterials.SeventhSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.SeventhSkill.Qp; break; case 8: AddItemMaterials(_currentServantNiceJson.SkillMaterials.EighthSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.EighthSkill.Qp; break; case 9: AddItemMaterials(_currentServantNiceJson.SkillMaterials.NinthSkill.Items); _requiredItemMaterials.Qp += _currentServantNiceJson.SkillMaterials.NinthSkill.Qp; break; } } } } return(_requiredItemMaterials); }