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 _)); }
public CombinationAndRapidCombinationTest(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); var sheets = TableSheetsImporter.ImportSheets(); _tableSheets = new TableSheets(sheets); var gold = new GoldCurrencyState(new Currency("NCG", 2, minter: null)); var gameConfigState = new GameConfigState(sheets[nameof(GameConfigSheet)]); _agentAddress = new PrivateKey().ToAddress(); _avatarAddress = _agentAddress.Derive("avatar"); _slot0Address = _avatarAddress.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, 0 ) ); var slot0State = new CombinationSlotState( _slot0Address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); var agentState = new AgentState(_agentAddress); agentState.avatarAddresses[0] = _avatarAddress; var avatarState = new AvatarState( _avatarAddress, _agentAddress, 1, _tableSheets.GetAvatarSheets(), gameConfigState, default ) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction), }; _inventoryAddress = _avatarAddress.Derive(LegacyInventoryKey); _worldInformationAddress = _avatarAddress.Derive(LegacyWorldInformationKey); _questListAddress = _avatarAddress.Derive(LegacyQuestListKey); _initialState = new Tests.Action.State() .SetState(GoldCurrencyState.Address, gold.Serialize()) .SetState(gameConfigState.address, gameConfigState.Serialize()) .SetState(_agentAddress, agentState.Serialize()) .SetState(_avatarAddress, avatarState.SerializeV2()) .SetState(_inventoryAddress, avatarState.inventory.Serialize()) .SetState(_worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(_questListAddress, avatarState.questList.Serialize()) .SetState(_slot0Address, slot0State.Serialize()); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } }
public Sell3Test(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); _initialState = new State(); var sheets = TableSheetsImporter.ImportSheets(); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } _tableSheets = new TableSheets(sheets); _currency = new Currency("NCG", 2, minters: null); var goldCurrencyState = new GoldCurrencyState(_currency); var shopState = new ShopState(); _agentAddress = new PrivateKey().ToAddress(); var agentState = new AgentState(_agentAddress); _avatarAddress = new PrivateKey().ToAddress(); var rankingMapAddress = new PrivateKey().ToAddress(); _avatarState = new AvatarState( _avatarAddress, _agentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; agentState.avatarAddresses[0] = _avatarAddress; var equipment = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); _avatarState.inventory.AddItem(equipment); var consumable = ItemFactory.CreateItemUsable( _tableSheets.ConsumableItemSheet.First, Guid.NewGuid(), 0); _avatarState.inventory.AddItem(consumable); var costume = ItemFactory.CreateCostume( _tableSheets.CostumeItemSheet.First, Guid.NewGuid()); _avatarState.inventory.AddItem(costume); _initialState = _initialState .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize()) .SetState(Addresses.Shop, shopState.Serialize()) .SetState(_agentAddress, agentState.Serialize()) .SetState(_avatarAddress, _avatarState.Serialize()); }
public Buy3Test(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); _initialState = new State(); var sheets = TableSheetsImporter.ImportSheets(); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } _tableSheets = new TableSheets(sheets); var currency = new Currency("NCG", 2, minters: null); _goldCurrencyState = new GoldCurrencyState(currency); _sellerAgentAddress = new PrivateKey().ToAddress(); var sellerAgentState = new AgentState(_sellerAgentAddress); _sellerAvatarAddress = new PrivateKey().ToAddress(); var rankingMapAddress = new PrivateKey().ToAddress(); var sellerAvatarState = new AvatarState( _sellerAvatarAddress, _sellerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; sellerAgentState.avatarAddresses[0] = _sellerAvatarAddress; _buyerAgentAddress = new PrivateKey().ToAddress(); var buyerAgentState = new AgentState(_buyerAgentAddress); _buyerAvatarAddress = new PrivateKey().ToAddress(); _buyerAvatarState = new AvatarState( _buyerAvatarAddress, _buyerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; buyerAgentState.avatarAddresses[0] = _buyerAvatarAddress; var equipment = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); var consumable = ItemFactory.CreateItemUsable( _tableSheets.ConsumableItemSheet.First, Guid.NewGuid(), 0); var costume = ItemFactory.CreateCostume( _tableSheets.CostumeItemSheet.First, Guid.NewGuid()); var shopState = new ShopState(); shopState.Register(new ShopItem( _sellerAgentAddress, _sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0), equipment)); shopState.Register(new ShopItem( _sellerAgentAddress, _sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0), consumable)); shopState.Register(new ShopItem( _sellerAgentAddress, _sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0), costume)); _initialState = _initialState .SetState(GoldCurrencyState.Address, _goldCurrencyState.Serialize()) .SetState(Addresses.Shop, shopState.Serialize()) .SetState(_sellerAgentAddress, sellerAgentState.Serialize()) .SetState(_sellerAvatarAddress, sellerAvatarState.Serialize()) .SetState(_buyerAgentAddress, buyerAgentState.Serialize()) .SetState(_buyerAvatarAddress, _buyerAvatarState.Serialize()) .MintAsset(_buyerAgentAddress, shopState.Products .Select(pair => pair.Value.Price) .Aggregate((totalPrice, next) => totalPrice + next)); }
public Buy5Test(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); _initialState = new State(); var sheets = TableSheetsImporter.ImportSheets(); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } _tableSheets = new TableSheets(sheets); var currency = new Currency("NCG", 2, minters: null); _goldCurrencyState = new GoldCurrencyState(currency); _sellerAgentAddress = new PrivateKey().ToAddress(); var sellerAgentState = new AgentState(_sellerAgentAddress); _sellerAvatarAddress = new PrivateKey().ToAddress(); var rankingMapAddress = new PrivateKey().ToAddress(); var sellerAvatarState = new AvatarState( _sellerAvatarAddress, _sellerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; sellerAgentState.avatarAddresses[0] = _sellerAvatarAddress; _buyerAgentAddress = new PrivateKey().ToAddress(); var buyerAgentState = new AgentState(_buyerAgentAddress); _buyerAvatarAddress = new PrivateKey().ToAddress(); _buyerAvatarState = new AvatarState( _buyerAvatarAddress, _buyerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; buyerAgentState.avatarAddresses[0] = _buyerAvatarAddress; _productId = new Guid("6d460c1a-755d-48e4-ad67-65d5f519dbc8"); _initialState = _initialState .SetState(GoldCurrencyState.Address, _goldCurrencyState.Serialize()) .SetState(_sellerAgentAddress, sellerAgentState.Serialize()) .SetState(_sellerAvatarAddress, sellerAvatarState.Serialize()) .SetState(_buyerAgentAddress, buyerAgentState.Serialize()) .SetState(_buyerAvatarAddress, _buyerAvatarState.Serialize()) .SetState(Addresses.Shop, new ShopState().Serialize()) .MintAsset(_buyerAgentAddress, _goldCurrencyState.Currency * 100); }
private IAccountStateDelta SetAvatarStateAsV2To(IAccountStateDelta state, AvatarState avatarState) => state .SetState(_avatarAddress.Derive(LegacyInventoryKey), avatarState.inventory.Serialize()) .SetState(_avatarAddress.Derive(LegacyWorldInformationKey), avatarState.worldInformation.Serialize()) .SetState(_avatarAddress.Derive(LegacyQuestListKey), avatarState.questList.Serialize()) .SetState(_avatarAddress, avatarState.SerializeV2());
public void UnlockWorldByHackAndSlashAfterPatchTableWithAddRow( int avatarLevel, int worldIdToClear, int stageIdToClear, int worldIdToUnlock) { Assert.True(_tableSheets.CharacterLevelSheet.ContainsKey(avatarLevel)); Assert.True(_tableSheets.WorldSheet.ContainsKey(worldIdToClear)); Assert.True(_tableSheets.StageSheet.ContainsKey(stageIdToClear)); Assert.True(_tableSheets.WorldSheet.ContainsKey(worldIdToUnlock)); Assert.False(_tableSheets.WorldUnlockSheet.TryGetUnlockedInformation( worldIdToClear, stageIdToClear, out _)); var avatarState = _initialState.GetAvatarState(_avatarAddress); avatarState.level = avatarLevel; avatarState.worldInformation = new WorldInformation(0, _tableSheets.WorldSheet, stageIdToClear); Assert.True(avatarState.worldInformation.IsWorldUnlocked(worldIdToClear)); Assert.False(avatarState.worldInformation.IsWorldUnlocked(worldIdToUnlock)); var nextState = _initialState.SetState(_avatarAddress, avatarState.Serialize()); var hackAndSlash = new HackAndSlash3 { worldId = worldIdToClear, stageId = stageIdToClear, avatarAddress = _avatarAddress, costumes = new List <int>(), equipments = new List <Guid>(), foods = new List <Guid>(), WeeklyArenaAddress = _weeklyArenaState.address, RankingMapAddress = _rankingMapAddress, }; nextState = hackAndSlash.Execute(new ActionContext { PreviousStates = nextState, Signer = _agentAddress, Random = new TestRandom(), Rehearsal = false, }); Assert.True(hackAndSlash.Result.IsClear); avatarState = nextState.GetAvatarState(_avatarAddress); Assert.True(avatarState.worldInformation.IsStageCleared(stageIdToClear)); Assert.False(avatarState.worldInformation.IsWorldUnlocked(worldIdToUnlock)); var tableCsv = nextState.GetSheetCsv <WorldUnlockSheet>(); var worldUnlockSheet = nextState.GetSheet <WorldUnlockSheet>(); var newId = worldUnlockSheet.Last?.Id + 1 ?? 1; var newLine = $"{newId},{worldIdToClear},{stageIdToClear},{worldIdToUnlock}"; tableCsv = new StringBuilder(tableCsv).AppendLine(newLine).ToString(); var patchTableSheet = new PatchTableSheet { TableName = nameof(WorldUnlockSheet), TableCsv = tableCsv, }; nextState = patchTableSheet.Execute(new ActionContext { PreviousStates = nextState, Signer = AdminState.Address, Random = new TestRandom(), Rehearsal = false, }); var nextTableCsv = nextState.GetSheetCsv <WorldUnlockSheet>(); Assert.Equal(nextTableCsv, tableCsv); nextState = hackAndSlash.Execute(new ActionContext { PreviousStates = nextState, Signer = _agentAddress, Random = new TestRandom(), Rehearsal = false, }); Assert.True(hackAndSlash.Result.IsClear); avatarState = nextState.GetAvatarState(_avatarAddress); Assert.True(avatarState.worldInformation.IsWorldUnlocked(worldIdToUnlock)); }
public void Execute(params ShopItemData[] productDatas) { var buyerAvatarState = _initialState.GetAvatarState(_buyerAvatarAddress); var goldCurrency = _initialState.GetGoldCurrency(); var shopState = _initialState.GetShopState(); var buyCount = 0; var itemsToBuy = new List <BuyMultiple.PurchaseInfo>(); foreach (var product in productDatas) { var(sellerAvatarState, sellerAgentState) = CreateAvatarState(product.SellerAgentAddress, product.SellerAvatarAddress); INonFungibleItem nonFungibleItem; if (product.ItemType == ItemType.Equipment) { var itemUsable = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, product.ItemId, product.RequiredBlockIndex); nonFungibleItem = itemUsable; } else { var costume = ItemFactory.CreateCostume(_tableSheets.CostumeItemSheet.First, product.ItemId); costume.Update(product.RequiredBlockIndex); nonFungibleItem = costume; } // Case for backward compatibility of `Buy` if (product.ContainsInInventory) { sellerAvatarState.inventory.AddItem2((ItemBase)nonFungibleItem); } var shopItemId = Guid.NewGuid(); var shopItem = new ShopItem( sellerAgentState.address, sellerAvatarState.address, shopItemId, new FungibleAssetValue(_goldCurrencyState.Currency, product.Price, 0), product.RequiredBlockIndex, nonFungibleItem); shopState.Register(shopItem); if (product.Buy) { ++buyCount; var purchaseInfo = new BuyMultiple.PurchaseInfo( shopItem.ProductId, shopItem.SellerAgentAddress, shopItem.SellerAvatarAddress); itemsToBuy.Add(purchaseInfo); } } Assert.NotNull(shopState.Products); Assert.Equal(3, shopState.Products.Count); _initialState = _initialState .SetState(_buyerAvatarAddress, buyerAvatarState.Serialize()) .SetState(Addresses.Shop, shopState.Serialize()); var priceData = new PriceData(goldCurrency); foreach (var avatarState in _sellerAgentStateMap.Keys) { var agentState = _sellerAgentStateMap[avatarState]; priceData.TaxedPriceSum[agentState.address] = new FungibleAssetValue(goldCurrency, 0, 0); _initialState = _initialState .SetState(avatarState.address, avatarState.Serialize()); } IAccountStateDelta previousStates = _initialState; var buyerGold = previousStates.GetBalance(_buyerAgentAddress, goldCurrency); var priceSumData = productDatas .Where(i => i.Buy) .Aggregate(priceData, (priceSum, next) => { var price = new FungibleAssetValue(goldCurrency, next.Price, 0); var tax = price.DivRem(100, out _) * Buy.TaxRate; var taxedPrice = price - tax; priceData.TaxSum += tax; var prevSum = priceData.TaxedPriceSum[next.SellerAgentAddress]; priceData.TaxedPriceSum[next.SellerAgentAddress] = prevSum + taxedPrice; priceData.PriceSum += price; return(priceData); }); var buyMultipleAction = new BuyMultiple { buyerAvatarAddress = _buyerAvatarAddress, purchaseInfos = itemsToBuy, }; var nextState = buyMultipleAction.Execute(new ActionContext() { BlockIndex = 1, PreviousStates = previousStates, Random = new TestRandom(), Rehearsal = false, Signer = _buyerAgentAddress, }); var nextShopState = nextState.GetShopState(); Assert.Equal(productDatas.Length - buyCount, nextShopState.Products.Count); var nextBuyerAvatarState = nextState.GetAvatarState(_buyerAvatarAddress); foreach (var product in productDatas.Where(i => i.Buy)) { Assert.True( nextBuyerAvatarState.inventory.TryGetNonFungibleItem( product.ItemId, out INonFungibleItem outNonFungibleItem) ); Assert.Equal(product.RequiredBlockIndex, outNonFungibleItem.RequiredBlockIndex); } Assert.Equal(buyCount, nextBuyerAvatarState.mailBox.Count); goldCurrency = nextState.GetGoldCurrency(); var nextGoldCurrencyGold = nextState.GetBalance(Addresses.GoldCurrency, goldCurrency); Assert.Equal(priceSumData.TaxSum, nextGoldCurrencyGold); foreach (var product in productDatas) { var nextSellerGold = nextState.GetBalance(product.SellerAgentAddress, goldCurrency); Assert.Equal(priceSumData.TaxedPriceSum[product.SellerAgentAddress], nextSellerGold); } var nextBuyerGold = nextState.GetBalance(_buyerAgentAddress, goldCurrency); Assert.Equal(buyerGold - priceSumData.PriceSum, nextBuyerGold); previousStates = nextState; }
public void Execute() { var previousWeeklyState = _initialState.GetWeeklyArenaState(0); var previousAvatar1State = _initialState.GetAvatarState(_avatar1Address); previousAvatar1State.level = 10; var previousState = _initialState.SetState( _avatar1Address, previousAvatar1State.Serialize()); var itemIds = _tableSheets.WeeklyArenaRewardSheet.Values .Select(r => r.Reward.ItemId) .ToList(); Assert.All(itemIds, id => Assert.False(previousAvatar1State.inventory.HasItem(id))); var row = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.ATK); var costume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row.CostumeId], new ItemEnhancementTest.TestRandom()); costume.equipped = true; var avatarState = _initialState.GetAvatarState(_avatar1Address); avatarState.inventory.AddItem(costume); var row2 = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.DEF); var enemyCostume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row2.CostumeId], new ItemEnhancementTest.TestRandom()); enemyCostume.equipped = true; var enemyAvatarState = _initialState.GetAvatarState(_avatar2Address); enemyAvatarState.inventory.AddItem(enemyCostume); _initialState = _initialState .SetState(_avatar1Address, avatarState.Serialize()) .SetState(_avatar2Address, enemyAvatarState.Serialize()); var action = new RankingBattle2 { AvatarAddress = _avatar1Address, EnemyAddress = _avatar2Address, WeeklyArenaAddress = _weeklyArenaAddress, costumeIds = new List <int> { costume.Id }, equipmentIds = new List <Guid>(), consumableIds = new List <Guid>(), }; Assert.Null(action.Result); var nextState = action.Execute(new ActionContext() { PreviousStates = previousState, Signer = _agent1Address, Random = new ItemEnhancementTest.TestRandom(), Rehearsal = false, }); var nextAvatar1State = nextState.GetAvatarState(_avatar1Address); var nextWeeklyState = nextState.GetWeeklyArenaState(0); Assert.Contains(nextAvatar1State.inventory.Materials, i => itemIds.Contains(i.Id)); Assert.NotNull(action.Result); Assert.Contains(typeof(GetReward), action.Result.Select(e => e.GetType())); Assert.Equal(BattleLog.Result.Win, action.Result.result); Assert.True(nextWeeklyState[_avatar1Address].Score > previousWeeklyState[_avatar1Address].Score); }
public override IAccountStateDelta Execute(IActionContext context) { IAccountStateDelta states = context.PreviousStates; Address collectionAddress = MonsterCollectionState0.DeriveAddress(context.Signer, collectionRound); if (context.Rehearsal) { return(states .SetState(context.Signer, MarkChanged) .SetState(avatarAddress, MarkChanged) .SetState(collectionAddress, MarkChanged)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); if (!states.TryGetAgentAvatarStates(context.Signer, avatarAddress, out AgentState agentState, out AvatarState avatarState)) { throw new FailedLoadStateException($"Aborted as the avatar state of the signer failed to load."); } if (!states.TryGetState(collectionAddress, out Dictionary stateDict)) { throw new FailedLoadStateException($"Aborted as the monster collection state failed to load."); } MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(stateDict); if (monsterCollectionState.End) { throw new MonsterCollectionExpiredException($"{collectionAddress} has already expired on {monsterCollectionState.ExpiredBlockIndex}"); } if (!monsterCollectionState.CanReceive(context.BlockIndex)) { throw new RequiredBlockIndexException( $"{collectionAddress} is not available yet; it will be available after {Math.Max(monsterCollectionState.StartedBlockIndex, monsterCollectionState.ReceivedBlockIndex) + MonsterCollectionState0.RewardInterval}"); } long rewardLevel = monsterCollectionState.GetRewardLevel(context.BlockIndex); ItemSheet itemSheet = states.GetItemSheet(); for (int i = 0; i < rewardLevel; i++) { int level = i + 1; if (level <= monsterCollectionState.RewardLevel) { continue; } List <MonsterCollectionRewardSheet.RewardInfo> rewards = monsterCollectionState.RewardLevelMap[level]; Guid id = context.Random.GenerateRandomGuid(); MonsterCollectionResult result = new MonsterCollectionResult(id, avatarAddress, rewards); MonsterCollectionMail mail = new MonsterCollectionMail(result, context.BlockIndex, id, context.BlockIndex); avatarState.Update(mail); foreach (var rewardInfo in rewards) { var row = itemSheet[rewardInfo.ItemId]; var item = row is MaterialItemSheet.Row materialRow ? ItemFactory.CreateTradableMaterial(materialRow) : ItemFactory.CreateItem(row, context.Random); avatarState.inventory.AddItem2(item, rewardInfo.Quantity); } monsterCollectionState.UpdateRewardMap(level, result, context.BlockIndex); } // Return gold at the end of monster collect. if (rewardLevel == 4) { MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>(); Currency currency = states.GetGoldCurrency(); // Set default gold value. FungibleAssetValue gold = currency * 0; for (int i = 0; i < monsterCollectionState.Level; i++) { int level = i + 1; gold += currency * monsterCollectionSheet[level].RequiredGold; } agentState.IncreaseCollectionRound(); states = states.SetState(context.Signer, agentState.Serialize()); if (gold > currency * 0) { states = states.TransferAsset(collectionAddress, context.Signer, gold); } } return(states .SetState(avatarAddress, avatarState.Serialize()) .SetState(collectionAddress, monsterCollectionState.Serialize())); }
public Buy2Test(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); _initialState = new State(); var sheets = TableSheetsImporter.ImportSheets(); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } _tableSheets = new TableSheets(sheets); var currency = new Currency("NCG", 2, minters: null); _goldCurrencyState = new GoldCurrencyState(currency); _sellerAgentAddress = new PrivateKey().ToAddress(); var sellerAgentState = new AgentState(_sellerAgentAddress); _sellerAvatarAddress = new PrivateKey().ToAddress(); var rankingMapAddress = new PrivateKey().ToAddress(); var sellerAvatarState = new AvatarState( _sellerAvatarAddress, _sellerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; sellerAgentState.avatarAddresses[0] = _sellerAvatarAddress; _buyerAgentAddress = new PrivateKey().ToAddress(); var buyerAgentState = new AgentState(_buyerAgentAddress); _buyerAvatarAddress = new PrivateKey().ToAddress(); _buyerAvatarState = new AvatarState( _buyerAvatarAddress, _buyerAgentAddress, 0, _tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; buyerAgentState.avatarAddresses[0] = _buyerAvatarAddress; var equipment = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); var shopState = new ShopState(); shopState.Register(new ShopItem( _sellerAgentAddress, _sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0), equipment)); var result = new CombinationConsumable.ResultModel() { id = default,
private void Execute(bool backward, int recipeId, int?subRecipeId, int mintNCG) { var currency = new Currency("NCG", 2, minter: null); var row = _tableSheets.EquipmentItemRecipeSheet[recipeId]; var requiredStage = row.UnlockStage; var costActionPoint = row.RequiredActionPoint; var costNCG = row.RequiredGold * currency; var materialRow = _tableSheets.MaterialItemSheet[row.MaterialId]; var material = ItemFactory.CreateItem(materialRow, _random); var avatarState = _initialState.GetAvatarState(_avatarAddress); var previousActionPoint = avatarState.actionPoint; var previousResultEquipmentCount = avatarState.inventory.Equipments.Count(e => e.Id == row.ResultEquipmentId); var previousMailCount = avatarState.mailBox.Count; avatarState.worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, requiredStage); avatarState.inventory.AddItem(material, row.MaterialCount); if (subRecipeId.HasValue) { var subRow = _tableSheets.EquipmentItemSubRecipeSheetV2[subRecipeId.Value]; costActionPoint += subRow.RequiredActionPoint; costNCG += subRow.RequiredGold * currency; foreach (var materialInfo in subRow.Materials) { material = ItemFactory.CreateItem(_tableSheets.MaterialItemSheet[materialInfo.Id], _random); avatarState.inventory.AddItem(material, materialInfo.Count); } } IAccountStateDelta previousState; if (backward) { previousState = _initialState.SetState(_avatarAddress, avatarState.Serialize()); } else { previousState = _initialState .SetState(_avatarAddress.Derive(LegacyInventoryKey), avatarState.inventory.Serialize()) .SetState( _avatarAddress.Derive(LegacyWorldInformationKey), avatarState.worldInformation.Serialize()) .SetState(_avatarAddress.Derive(LegacyQuestListKey), avatarState.questList.Serialize()) .SetState(_avatarAddress, avatarState.SerializeV2()); } previousState = previousState.MintAsset(_agentAddress, mintNCG * currency); var goldCurrencyState = previousState.GetGoldCurrency(); var previousNCG = previousState.GetBalance(_agentAddress, goldCurrencyState); Assert.Equal(mintNCG * currency, previousNCG); var action = new CombinationEquipment8 { avatarAddress = _avatarAddress, slotIndex = 0, recipeId = recipeId, subRecipeId = subRecipeId, }; var nextState = action.Execute(new ActionContext { PreviousStates = previousState, Signer = _agentAddress, BlockIndex = 1, Random = _random, }); var slotState = nextState.GetCombinationSlotState(_avatarAddress, 0); Assert.NotNull(slotState.Result); Assert.NotNull(slotState.Result.itemUsable); if (subRecipeId.HasValue) { Assert.True(((Equipment)slotState.Result.itemUsable).optionCountFromCombination > 0); } else { Assert.Equal(0, ((Equipment)slotState.Result.itemUsable).optionCountFromCombination); } var nextAvatarState = nextState.GetAvatarStateV2(_avatarAddress); Assert.Equal(previousActionPoint - costActionPoint, nextAvatarState.actionPoint); Assert.Equal(previousMailCount + 1, nextAvatarState.mailBox.Count); Assert.IsType <CombinationMail>(nextAvatarState.mailBox.First()); Assert.Equal( previousResultEquipmentCount + 1, nextAvatarState.inventory.Equipments.Count(e => e.Id == row.ResultEquipmentId)); var agentGold = nextState.GetBalance(_agentAddress, goldCurrencyState); Assert.Equal(previousNCG - costNCG, agentGold); var blackSmithGold = nextState.GetBalance(Addresses.Blacksmith, goldCurrencyState); Assert.Equal(costNCG, blackSmithGold); }
public void SerializeWithDotnetAPI() { var sellerAvatarAddress = new PrivateKey().ToAddress(); var sellerAgentAddress = new PrivateKey().ToAddress(); CreateAvatarState(sellerAgentAddress, sellerAvatarAddress); IAccountStateDelta previousStates = _initialState; var shopState = previousStates.GetShopState(); var productId = Guid.NewGuid(); var equipment = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); shopState.Register(new ShopItem( sellerAgentAddress, sellerAvatarAddress, productId, new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0), 100, equipment)); shopState.Register(new ShopItem( sellerAgentAddress, sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0), 100, equipment)); var products = shopState.Products.Values .Select(p => new BuyMultiple.PurchaseInfo( p.ProductId, p.SellerAgentAddress, p.SellerAvatarAddress)) .ToList(); previousStates = previousStates .SetState(Addresses.Shop, shopState.Serialize()); var action = new BuyMultiple { buyerAvatarAddress = _buyerAvatarAddress, purchaseInfos = products, }; action.Execute(new ActionContext() { BlockIndex = 1, PreviousStates = previousStates, Random = new TestRandom(), Signer = _buyerAgentAddress, }); var formatter = new BinaryFormatter(); using var ms = new MemoryStream(); formatter.Serialize(ms, action); ms.Seek(0, SeekOrigin.Begin); var deserialized = (BuyMultiple)formatter.Deserialize(ms); Assert.Equal(action.PlainValue, deserialized.PlainValue); }
public void Execute(bool isNew, bool avatarBackward, bool enemyBackward) { var previousWeeklyState = _initialState.GetWeeklyArenaState(0); var previousAvatar1State = _initialState.GetAvatarState(_avatar1Address); previousAvatar1State.level = 10; var prevScore = previousWeeklyState[_avatar1Address].Score; if (isNew) { previousWeeklyState.Remove(_avatar1Address); } var previousState = _initialState.SetState( _avatar1Address, previousAvatar1State.Serialize()); var itemIds = _tableSheets.WeeklyArenaRewardSheet.Values .Select(r => r.Reward.ItemId) .ToList(); Assert.All(itemIds, id => Assert.False(previousAvatar1State.inventory.HasItem(id))); var row = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.ATK); var costume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row.CostumeId], new TestRandom()); costume.equipped = true; previousAvatar1State.inventory.AddItem(costume); var row2 = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.DEF); var enemyCostume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row2.CostumeId], new TestRandom()); enemyCostume.equipped = true; var enemyAvatarState = _initialState.GetAvatarState(_avatar2Address); enemyAvatarState.inventory.AddItem(enemyCostume); if (avatarBackward) { previousState = previousState.SetState(_avatar1Address, previousAvatar1State.Serialize()); } else { previousState = previousState .SetState(_avatar1Address.Derive(LegacyInventoryKey), previousAvatar1State.inventory.Serialize()) .SetState(_avatar1Address.Derive(LegacyWorldInformationKey), previousAvatar1State.worldInformation.Serialize()) .SetState(_avatar1Address.Derive(LegacyQuestListKey), previousAvatar1State.questList.Serialize()) .SetState(_avatar1Address, previousAvatar1State.SerializeV2()); } if (enemyBackward) { previousState = previousState.SetState(_avatar2Address, enemyAvatarState.Serialize()); } else { previousState = previousState .SetState(_avatar2Address.Derive(LegacyInventoryKey), enemyAvatarState.inventory.Serialize()) .SetState(_avatar2Address.Derive(LegacyWorldInformationKey), enemyAvatarState.worldInformation.Serialize()) .SetState(_avatar2Address.Derive(LegacyQuestListKey), enemyAvatarState.questList.Serialize()) .SetState(_avatar2Address, enemyAvatarState.SerializeV2()); } var action = new RankingBattle7 { avatarAddress = _avatar1Address, enemyAddress = _avatar2Address, weeklyArenaAddress = _weeklyArenaAddress, costumeIds = new List <Guid> { costume.ItemId }, equipmentIds = new List <Guid>(), consumableIds = new List <Guid>(), }; Assert.Null(action.Result); var nextState = action.Execute(new ActionContext() { PreviousStates = previousState, Signer = _agent1Address, Random = new TestRandom(), Rehearsal = false, }); var nextAvatar1State = nextState.GetAvatarStateV2(_avatar1Address); var nextWeeklyState = nextState.GetWeeklyArenaState(0); Assert.Contains(nextAvatar1State.inventory.Materials, i => itemIds.Contains(i.Id)); Assert.NotNull(action.Result); Assert.Contains(typeof(GetReward), action.Result.Select(e => e.GetType())); Assert.Equal(BattleLog.Result.Win, action.Result.result); Assert.True(nextWeeklyState[_avatar1Address].Score > prevScore); }
public override IAccountStateDelta Execute(IActionContext context) { IAccountStateDelta states = context.PreviousStates; if (context.Rehearsal) { return(states .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 0), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 1), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 2), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 3), MarkChanged) .SetState(context.Signer, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, context.Signer, MonsterCollectionState.DeriveAddress(context.Signer, 0)) .MarkBalanceChanged(GoldCurrencyMock, context.Signer, MonsterCollectionState.DeriveAddress(context.Signer, 1)) .MarkBalanceChanged(GoldCurrencyMock, context.Signer, MonsterCollectionState.DeriveAddress(context.Signer, 2)) .MarkBalanceChanged(GoldCurrencyMock, context.Signer, MonsterCollectionState.DeriveAddress(context.Signer, 3))); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>(); AgentState agentState = states.GetAgentState(context.Signer); if (agentState is null) { throw new FailedLoadStateException("Aborted as the agent state failed to load."); } if (level < 0 || level > 0 && !monsterCollectionSheet.TryGetValue(level, out MonsterCollectionSheet.Row _)) { throw new MonsterCollectionLevelException(); } Currency currency = states.GetGoldCurrency(); // Set default gold value. FungibleAssetValue requiredGold = currency * 0; FungibleAssetValue balance = states.GetBalance(context.Signer, currency); Address monsterCollectionAddress = MonsterCollectionState.DeriveAddress( context.Signer, agentState.MonsterCollectionRound ); if (states.TryGetState(monsterCollectionAddress, out Dictionary stateDict)) { var existingStates = new MonsterCollectionState(stateDict); int previousLevel = existingStates.Level; // Check collection level and required block index if (level < previousLevel && existingStates.IsLocked(context.BlockIndex)) { throw new RequiredBlockIndexException(); } if (level == previousLevel) { throw new MonsterCollectionLevelException(); } if (existingStates.CalculateStep(context.BlockIndex) > 0) { throw new MonsterCollectionExistingClaimableException(); } // Refund holding NCG to user FungibleAssetValue gold = states.GetBalance(monsterCollectionAddress, currency); states = states.TransferAsset(monsterCollectionAddress, context.Signer, gold); } if (level == 0) { return(states.SetState(monsterCollectionAddress, new Null())); } var monsterCollectionState = new MonsterCollectionState(monsterCollectionAddress, level, context.BlockIndex); for (int i = 0; i < level; i++) { requiredGold += currency * monsterCollectionSheet[i + 1].RequiredGold; } if (balance < requiredGold) { throw new InsufficientBalanceException(context.Signer, requiredGold, $"There is no sufficient balance for {context.Signer}: {balance} < {requiredGold}"); } states = states.TransferAsset(context.Signer, monsterCollectionAddress, requiredGold); states = states.SetState(monsterCollectionAddress, monsterCollectionState.Serialize()); return(states); }
public void Execute(int avatarLevel, int worldId, int stageId, bool contains) { Assert.True(_tableSheets.WorldSheet.TryGetValue(worldId, out var worldRow)); Assert.True(stageId >= worldRow.StageBegin); Assert.True(stageId <= worldRow.StageEnd); Assert.True(_tableSheets.StageSheet.TryGetValue(stageId, out _)); var previousAvatarState = _initialState.GetAvatarState(_avatarAddress); previousAvatarState.level = avatarLevel; previousAvatarState.worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, Math.Max(_tableSheets.StageSheet.First?.Id ?? 1, stageId - 1)); var costumeId = _tableSheets .CostumeItemSheet .Values .First(r => r.ItemSubType == ItemSubType.FullCostume) .Id; var costume = ItemFactory.CreateItem(_tableSheets.ItemSheet[costumeId], new TestRandom()); previousAvatarState.inventory.AddItem2(costume); var state = _initialState.SetState(_avatarAddress, previousAvatarState.Serialize()); var action = new HackAndSlash0() { costumes = new List <int> { costumeId }, equipments = new List <Guid>(), foods = new List <Guid>(), worldId = worldId, stageId = stageId, avatarAddress = _avatarAddress, WeeklyArenaAddress = _weeklyArenaState.address, RankingMapAddress = _rankingMapAddress, }; Assert.Null(action.Result); var nextState = action.Execute(new ActionContext() { PreviousStates = state, Signer = _agentAddress, Random = new TestRandom(), Rehearsal = false, }); var nextAvatarState = nextState.GetAvatarState(_avatarAddress); var newWeeklyState = nextState.GetWeeklyArenaState(0); Assert.NotNull(action.Result); Assert.NotEmpty(action.Result.OfType <GetReward>()); Assert.Equal(BattleLog.Result.Win, action.Result.result); Assert.Equal(contains, newWeeklyState.ContainsKey(_avatarAddress)); Assert.True(nextAvatarState.worldInformation.IsStageCleared(stageId)); var value = nextState.GetState(_rankingMapAddress); var rankingMapState = new RankingMapState((Dictionary)value); var info = rankingMapState.GetRankingInfos(null).First(); Assert.Equal(info.AgentAddress, _agentAddress); Assert.Equal(info.AvatarAddress, _avatarAddress); }
public void Execute(bool isNew, bool avatarBackward, bool enemyBackward) { var previousWeeklyState = _initialState.GetWeeklyArenaState(0); var previousAvatar1State = _initialState.GetAvatarState(_avatar1Address); previousAvatar1State.level = 10; var prevScore = previousWeeklyState[_avatar1Address].Score; if (isNew) { previousWeeklyState.Remove(_avatar1Address); } var previousState = _initialState.SetState( _avatar1Address, previousAvatar1State.Serialize()); var itemIds = _tableSheets.WeeklyArenaRewardSheet.Values .Select(r => r.Reward.ItemId) .ToList(); Assert.All(itemIds, id => Assert.False(previousAvatar1State.inventory.HasItem(id))); var row = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.ATK); var costume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row.CostumeId], new TestRandom()); costume.equipped = true; previousAvatar1State.inventory.AddItem(costume); var row2 = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.DEF); var enemyCostume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row2.CostumeId], new TestRandom()); enemyCostume.equipped = true; var enemyAvatarState = _initialState.GetAvatarState(_avatar2Address); enemyAvatarState.inventory.AddItem(enemyCostume); Address worldInformationAddress = _avatar1Address.Derive(LegacyWorldInformationKey); if (avatarBackward) { previousState = previousState.SetState(_avatar1Address, previousAvatar1State.Serialize()); } else { previousState = previousState .SetState( _avatar1Address.Derive(LegacyInventoryKey), previousAvatar1State.inventory.Serialize()) .SetState( worldInformationAddress, previousAvatar1State.worldInformation.Serialize()) .SetState( _avatar1Address.Derive(LegacyQuestListKey), previousAvatar1State.questList.Serialize()) .SetState(_avatar1Address, previousAvatar1State.SerializeV2()); } if (enemyBackward) { previousState = previousState.SetState(_avatar2Address, enemyAvatarState.Serialize()); } else { previousState = previousState .SetState( _avatar2Address.Derive(LegacyInventoryKey), enemyAvatarState.inventory.Serialize()) .SetState( _avatar2Address.Derive(LegacyWorldInformationKey), enemyAvatarState.worldInformation.Serialize()) .SetState( _avatar2Address.Derive(LegacyQuestListKey), enemyAvatarState.questList.Serialize()) .SetState(_avatar2Address, enemyAvatarState.SerializeV2()); } var action = new RankingBattle10 { avatarAddress = _avatar1Address, enemyAddress = _avatar2Address, weeklyArenaAddress = _weeklyArenaAddress, costumeIds = new List <Guid> { costume.ItemId }, equipmentIds = new List <Guid>(), }; var nextState = action.Execute(new ActionContext { PreviousStates = previousState, Signer = _agent1Address, Random = new TestRandom(), Rehearsal = false, }); var nextAvatar1State = nextState.GetAvatarStateV2(_avatar1Address); var nextWeeklyState = nextState.GetWeeklyArenaState(0); var nextArenaInfo = nextWeeklyState[_avatar1Address]; Assert.Contains(nextAvatar1State.inventory.Materials, i => itemIds.Contains(i.Id)); Assert.NotNull(action.ArenaInfo); Assert.NotNull(action.EnemyArenaInfo); Assert.True(nextArenaInfo.Score > prevScore); // Check simulation result equal. var player = new Player( previousAvatar1State, _tableSheets.CharacterSheet, _tableSheets.CharacterLevelSheet, _tableSheets.EquipmentItemSetEffectSheet); var simulator = new RankingSimulator( new TestRandom(), player, action.EnemyPlayerDigest, new List <Guid>(), _tableSheets.GetRankingSimulatorSheets(), RankingBattle10.StageId, action.ArenaInfo, action.EnemyArenaInfo, _tableSheets.CostumeStatSheet); simulator.Simulate(); Assert.Equal(nextArenaInfo.Score, simulator.Log.score); Assert.Equal(previousAvatar1State.SerializeV2(), nextAvatar1State.SerializeV2()); Assert.Equal(previousAvatar1State.worldInformation.Serialize(), nextAvatar1State.worldInformation.Serialize()); }