public override IValue Serialize() => #pragma warning disable LAA1002 new Dictionary(new Dictionary <IKey, IValue> { [(Text)"name"] = (Text)name, [(Text)"characterId"] = (Integer)characterId, [(Text)"level"] = (Integer)level, [(Text)"exp"] = (Integer)exp, [(Text)"inventory"] = inventory.Serialize(), [(Text)"worldInformation"] = worldInformation.Serialize(), [(Text)"updatedAt"] = updatedAt.Serialize(), [(Text)"agentAddress"] = agentAddress.Serialize(), [(Text)"questList"] = questList.Serialize(), [(Text)"mailBox"] = mailBox.Serialize(), [(Text)"blockIndex"] = (Integer)blockIndex, [(Text)"dailyRewardReceivedIndex"] = (Integer)dailyRewardReceivedIndex, [(Text)"actionPoint"] = (Integer)actionPoint, [(Text)"stageMap"] = stageMap.Serialize(), [(Text)"monsterMap"] = monsterMap.Serialize(), [(Text)"itemMap"] = itemMap.Serialize(), [(Text)"eventMap"] = eventMap.Serialize(), [(Text)"hair"] = (Integer)hair, [(Text)"lens"] = (Integer)lens, [(Text)"ear"] = (Integer)ear, [(Text)"tail"] = (Integer)tail, [(Text)"combinationSlotAddresses"] = combinationSlotAddresses .OrderBy(i => i) .Select(i => i.Serialize()) .Serialize(), [(Text)"nonce"] = Nonce.Serialize(), [(Text)"ranking_map_address"] = RankingMapAddress.Serialize(), }.Union((Dictionary)base.Serialize()));
public override IValue Serialize() => #pragma warning disable LAA1002 new Dictionary(new Dictionary <IKey, IValue> { [(Text)LegacyNameKey] = (Text)name, [(Text)LegacyCharacterIdKey] = (Integer)characterId, [(Text)LegacyLevelKey] = (Integer)level, [(Text)ExpKey] = (Integer)exp, [(Text)LegacyInventoryKey] = inventory.Serialize(), [(Text)LegacyWorldInformationKey] = worldInformation.Serialize(), [(Text)LegacyUpdatedAtKey] = updatedAt.Serialize(), [(Text)LegacyAgentAddressKey] = agentAddress.Serialize(), [(Text)LegacyQuestListKey] = questList.Serialize(), [(Text)LegacyMailBoxKey] = mailBox.Serialize(), [(Text)LegacyBlockIndexKey] = (Integer)blockIndex, [(Text)LegacyDailyRewardReceivedIndexKey] = (Integer)dailyRewardReceivedIndex, [(Text)LegacyActionPointKey] = (Integer)actionPoint, [(Text)LegacyStageMapKey] = stageMap.Serialize(), [(Text)LegacyMonsterMapKey] = monsterMap.Serialize(), [(Text)LegacyItemMapKey] = itemMap.Serialize(), [(Text)LegacyEventMapKey] = eventMap.Serialize(), [(Text)LegacyHairKey] = (Integer)hair, [(Text)LensKey] = (Integer)lens, [(Text)LegacyEarKey] = (Integer)ear, [(Text)LegacyTailKey] = (Integer)tail, [(Text)LegacyCombinationSlotAddressesKey] = combinationSlotAddresses .OrderBy(i => i) .Select(i => i.Serialize()) .Serialize(), [(Text)LegacyNonceKey] = Nonce.Serialize(), [(Text)LegacyRankingMapAddressKey] = RankingMapAddress.Serialize(), }.Union((Dictionary)base.Serialize()));
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 _)); }