public void CalculateHourglassCost([Values(1, 2, 3)] int diff) { var state = new GameConfigState(); var row = new GameConfigSheet.Row(); row.Set(new List <string> { "hourglass_per_block", "3" }); state.Update(row); Assert.AreEqual(1, RapidCombination.CalculateHourglassCount(state, diff)); }
private void UpdateHasNotification(long blockIndex) { if (_data is null || _data.Result is null) { HasNotification.Value = false; return; } switch (_data.Result) { case CombinationConsumable.ResultModel ccResult: if (ccResult.id == default) { HasNotification.Value = false; return; } break; case ItemEnhancement.ResultModel _: default: HasNotification.Value = false; return; } var diff = _data.Result.itemUsable.RequiredBlockIndex - blockIndex; if (diff <= 0) { HasNotification.Value = false; return; } var gameConfigState = Game.Game.instance.States.GameConfigState; var cost = RapidCombination.CalculateHourglassCount(gameConfigState, diff); var row = Game.Game.instance.TableSheets.MaterialItemSheet.Values .First(r => r.ItemSubType == ItemSubType.Hourglass); var isEnough = States.Instance.CurrentAvatarState.inventory.HasItem(row.ItemId, cost); HasNotification.Value = isEnough; }
public void Case(int randomSeed, int[] optionNumbers) { var gameConfigState = _initialState.GetGameConfigState(); Assert.NotNull(gameConfigState); var recipeRow = _tableSheets.EquipmentItemRecipeSheet.OrderedList.First(e => e.SubRecipeIds.Any()); var subRecipeRow = _tableSheets.EquipmentItemSubRecipeSheetV2[recipeRow.SubRecipeIds.First()]; var combinationEquipmentAction = new CombinationEquipment { avatarAddress = _avatarAddress, slotIndex = 0, recipeId = recipeRow.Id, subRecipeId = subRecipeRow.Id, }; var inventoryValue = _initialState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); var inventoryState = new Inventory((List)inventoryValue); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, recipeRow.MaterialId), recipeRow.MaterialCount); foreach (var materialInfo in subRecipeRow.Materials) { inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, materialInfo.Id), materialInfo.Count); } var worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, recipeRow.UnlockStage); var nextState = _initialState .SetState(_inventoryAddress, inventoryState.Serialize()) .SetState(_worldInformationAddress, worldInformation.Serialize()); var random = new TestRandom(randomSeed); nextState = combinationEquipmentAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 0, Random = random, Signer = _agentAddress, }); var slot0Value = nextState.GetState(_slot0Address); Assert.NotNull(slot0Value); var slot0State = new CombinationSlotState((Dictionary)slot0Value); Assert.NotNull(slot0State.Result.itemUsable); var equipment = (Equipment)slot0State.Result.itemUsable; var additionalStats = equipment.StatsMap .GetAdditionalStats(true) .ToArray(); var skills = equipment.Skills; Assert.Equal(optionNumbers.Length, equipment.optionCountFromCombination); var optionSheet = _tableSheets.EquipmentItemOptionSheet; var mainAdditionalStatMin = 0; var mainAdditionalStatMax = 0; var requiredBlockIndex = 0; foreach (var optionNumber in optionNumbers) { var optionInfo = subRecipeRow.Options[optionNumber - 1]; requiredBlockIndex += optionInfo.RequiredBlockIndex; var optionRow = optionSheet[optionInfo.Id]; if (optionRow.StatMin > 0 || optionRow.StatMax > 0) { if (optionRow.StatType == equipment.UniqueStatType) { mainAdditionalStatMin += optionRow.StatMin; mainAdditionalStatMax += optionRow.StatMax; continue; } var additionalStatValue = additionalStats .First(e => e.statType == optionRow.StatType) .additionalValue; Assert.True(additionalStatValue >= optionRow.StatMin); Assert.True(additionalStatValue <= optionRow.StatMax + 1); } else if (optionRow.SkillId != default) { var skill = skills.First(e => e.SkillRow.Id == optionRow.SkillId); Assert.True(skill.Chance >= optionRow.SkillChanceMin); Assert.True(skill.Chance <= optionRow.SkillChanceMax + 1); Assert.True(skill.Power >= optionRow.SkillDamageMin); Assert.True(skill.Power <= optionRow.SkillDamageMax + 1); } } var mainAdditionalStatValue = additionalStats .First(e => e.statType == equipment.UniqueStatType) .additionalValue; Assert.True(mainAdditionalStatValue >= mainAdditionalStatMin); Assert.True(mainAdditionalStatValue <= mainAdditionalStatMax + 1); Assert.Equal(requiredBlockIndex + 1, slot0State.RequiredBlockIndex); // FIXME // https://github.com/planetarium/lib9c/pull/517#discussion_r679218764 // The tests after this line should be finished. However, since then the logic is being developed by // different developers in different branches. I wrote a test beforehand, but it's failing. // I plan to move to another branch after this PR is merged and finish writing the tests. return; if (requiredBlockIndex == 0) { return; } var hourglassRow = _tableSheets.MaterialItemSheet .First(pair => pair.Value.ItemSubType == ItemSubType.Hourglass) .Value; inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); var hourglassCount = requiredBlockIndex * gameConfigState.HourglassPerBlock; inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, hourglassRow.Id), hourglassCount); Assert.True(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out var hourglasses)); Assert.Equal(hourglassCount, hourglasses.Sum(e => e.count)); nextState = nextState.SetState(_inventoryAddress, inventoryState.Serialize()); var rapidCombinationAction = new RapidCombination { avatarAddress = _avatarAddress, slotIndex = 0, }; nextState = rapidCombinationAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 1, Random = random, Signer = _agentAddress, }); inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); }
public void Case(int randomSeed, int[] optionNumbers) { var gameConfigState = _initialState.GetGameConfigState(); Assert.NotNull(gameConfigState); var subRecipeRow = _tableSheets.EquipmentItemSubRecipeSheetV2.OrderedList.First(e => e.Options.Count == 4 && e.RequiredBlockIndex > GameConfig.RequiredAppraiseBlock && e.RequiredGold == 0); var recipeRow = _tableSheets.EquipmentItemRecipeSheet.OrderedList.First(e => e.SubRecipeIds.Contains(subRecipeRow.Id)); var combinationEquipmentAction = new CombinationEquipment { avatarAddress = _avatarAddress, slotIndex = 0, recipeId = recipeRow.Id, subRecipeId = subRecipeRow.Id, }; var inventoryValue = _initialState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); var inventoryState = new Inventory((List)inventoryValue); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, recipeRow.MaterialId), recipeRow.MaterialCount); foreach (var materialInfo in subRecipeRow.Materials) { inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, materialInfo.Id), materialInfo.Count); } var worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, recipeRow.UnlockStage); var nextState = _initialState .SetState(_inventoryAddress, inventoryState.Serialize()) .SetState(_worldInformationAddress, worldInformation.Serialize()); var random = new TestRandom(randomSeed); nextState = combinationEquipmentAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 0, Random = random, Signer = _agentAddress, }); var slot0Value = nextState.GetState(_slot0Address); Assert.NotNull(slot0Value); var slot0State = new CombinationSlotState((Dictionary)slot0Value); Assert.NotNull(slot0State.Result.itemUsable); var equipment = (Equipment)slot0State.Result.itemUsable; var additionalStats = equipment.StatsMap .GetAdditionalStats(true) .ToArray(); var skills = equipment.Skills; Assert.Equal(optionNumbers.Length, equipment.optionCountFromCombination); var optionSheet = _tableSheets.EquipmentItemOptionSheet; var mainAdditionalStatMin = 0; var mainAdditionalStatMax = 0; var requiredBlockIndex = recipeRow.RequiredBlockIndex + subRecipeRow.RequiredBlockIndex; var orderedOptions = subRecipeRow.Options .OrderByDescending(e => e.Ratio) .ThenBy(e => e.RequiredBlockIndex) .ThenBy(e => e.Id) .ToArray(); foreach (var optionNumber in optionNumbers) { var optionInfo = orderedOptions[optionNumber - 1]; requiredBlockIndex += optionInfo.RequiredBlockIndex; var optionRow = optionSheet[optionInfo.Id]; if (optionRow.StatMin > 0 || optionRow.StatMax > 0) { if (optionRow.StatType == equipment.UniqueStatType) { mainAdditionalStatMin += optionRow.StatMin; mainAdditionalStatMax += optionRow.StatMax; continue; } var additionalStatValue = additionalStats .First(e => e.statType == optionRow.StatType) .additionalValue; Assert.True(additionalStatValue >= optionRow.StatMin); Assert.True(additionalStatValue <= optionRow.StatMax + 1); } else if (optionRow.SkillId != default) { var skill = skills.First(e => e.SkillRow.Id == optionRow.SkillId); Assert.True(skill.Chance >= optionRow.SkillChanceMin); Assert.True(skill.Chance <= optionRow.SkillChanceMax + 1); Assert.True(skill.Power >= optionRow.SkillDamageMin); Assert.True(skill.Power <= optionRow.SkillDamageMax + 1); } } var mainAdditionalStatValue = additionalStats .First(e => e.statType == equipment.UniqueStatType) .additionalValue; Assert.True(mainAdditionalStatValue >= mainAdditionalStatMin); Assert.True(mainAdditionalStatValue <= mainAdditionalStatMax + 1); Assert.Equal(requiredBlockIndex, slot0State.RequiredBlockIndex); if (requiredBlockIndex == 0) { return; } var hourglassRow = _tableSheets.MaterialItemSheet .First(pair => pair.Value.ItemSubType == ItemSubType.Hourglass) .Value; inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); var diff = slot0State.RequiredBlockIndex - GameConfig.RequiredAppraiseBlock; var hourglassCount = RapidCombination0.CalculateHourglassCount(gameConfigState, diff); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, hourglassRow.Id), hourglassCount); Assert.True(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out var hourglasses)); Assert.Equal(hourglassCount, hourglasses.Sum(e => e.count)); nextState = nextState.SetState(_inventoryAddress, inventoryState.Serialize()); var rapidCombinationAction = new RapidCombination { avatarAddress = _avatarAddress, slotIndex = 0, }; nextState = rapidCombinationAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = GameConfig.RequiredAppraiseBlock, Random = random, Signer = _agentAddress, }); inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); }