From 31f6225bd4b1794c50062a1c9036c8f3aa07f57b Mon Sep 17 00:00:00 2001 From: Syu Date: Mon, 30 Oct 2023 15:53:24 +0900 Subject: [PATCH 1/2] Update 70.2~70.3 Date --- Lib9c/TableCSV/CreateAvatarFavSheet.csv | 3 +- Lib9c/TableCSV/CreateAvatarItemSheet.csv | 4 +- .../Item/EquipmentItemRecipeSheet.csv | 78 ------------------- .../Quest/CombinationEquipmentQuestSheet.csv | 78 ------------------- Lib9c/TableCSV/Quest/QuestRewardSheet.csv | 3 +- Lib9c/TableCSV/Quest/WorldQuestSheet.csv | 2 +- 6 files changed, 7 insertions(+), 161 deletions(-) diff --git a/Lib9c/TableCSV/CreateAvatarFavSheet.csv b/Lib9c/TableCSV/CreateAvatarFavSheet.csv index f47b22aafb..bb9bb482ae 100644 --- a/Lib9c/TableCSV/CreateAvatarFavSheet.csv +++ b/Lib9c/TableCSV/CreateAvatarFavSheet.csv @@ -1,2 +1,3 @@ currency,quantity,target -CRYSTAL,200000,Agent \ No newline at end of file +CRYSTAL,200000,Agent +RUNE_ADVENTURER,1,Avatar \ No newline at end of file diff --git a/Lib9c/TableCSV/CreateAvatarItemSheet.csv b/Lib9c/TableCSV/CreateAvatarItemSheet.csv index 2943c22af7..a37d1a7de7 100644 --- a/Lib9c/TableCSV/CreateAvatarItemSheet.csv +++ b/Lib9c/TableCSV/CreateAvatarItemSheet.csv @@ -1,3 +1,3 @@ ItemId,Count -10112000,1 -10212000,1 \ No newline at end of file +10110000,2 +10210000,1 \ No newline at end of file diff --git a/Lib9c/TableCSV/Item/EquipmentItemRecipeSheet.csv b/Lib9c/TableCSV/Item/EquipmentItemRecipeSheet.csv index 491fae394f..6b4f0831d0 100644 --- a/Lib9c/TableCSV/Item/EquipmentItemRecipeSheet.csv +++ b/Lib9c/TableCSV/Item/EquipmentItemRecipeSheet.csv @@ -1,21 +1,10 @@ id,result_equipment_id,material_id,material_count,required_action_point,required_gold,required_block_index,unlock_stage,sub_recipe_id,sub_recipe_id_2,sub_recipe_id_3,required_crystal,item_sub_type 1,10110000,303000,2,0,0,5,3,373,374,,0,Weapon -2,10111000,303000,2,0,0,5,11,1,2,,2,Weapon -3,10112000,303000,2,0,0,5,19,4,5,,2,Weapon -4,10113000,303000,8,0,0,155,51,7,8,,19,Weapon 5,10114000,303000,12,0,0,477,99,10,11,,64,Weapon 6,10120000,303001,4,0,0,37,27,376,377,,8,Weapon -7,10121000,303001,4,0,0,45,29,13,14,,11,Weapon -8,10122000,303001,6,0,0,89,39,16,17,,15,Weapon -9,10123000,303001,15,0,0,1167,114,19,20,,1056,Weapon 10,10124000,303001,24,0,0,7155,174,22,23,,22560,Weapon -11,10130000,303002,7,0,0,241,63,379,380,,234,Weapon -12,10131000,303002,8,0,0,257,66,25,26,,279,Weapon -13,10132000,303002,9,0,0,329,78,28,29,,317,Weapon 14,10133000,303002,27,0,0,9807,190,31,32,,41040,Weapon 15,10134000,303002,47,0,0,21585,204,34,35,,167040,Weapon -16,10130001,303002,17,0,0,1482,130,382,383,,8340,Weapon -17,10131001,303002,19,0,0,1643,138,37,38,,14520,Weapon 18,10132001,303002,21,0,0,5190,154,40,41,,32040,Weapon 19,10133001,303002,61,0,0,28050,220,43,44,,216180,Weapon 20,10134001,303002,73,0,0,34302,236,46,47,,495900,Weapon @@ -29,37 +18,16 @@ id,result_equipment_id,material_id,material_count,required_action_point,required 28,10152000,303004,360,0,0,3000,305,101520001,101520002,101520003,500000,Weapon 29,10153000,303004,360,0,0,3000,330,101530001,101530002,,500000,Weapon 30,10154000,303004,360,0,0,3000,330,101540001,101540002,101540003,500000,Weapon -31,10140001,303003,85,0,0,60375,999,388,389,,1533000,Weapon -32,10141001,303003,85,0,0,62115,999,61,62,,1648200,Weapon -33,10142001,303003,86,0,0,63915,999,64,65,,1664100,Weapon -34,10143001,303003,86,0,0,65775,999,67,68,,1664100,Weapon -35,10144001,303003,87,0,0,67695,999,70,71,,1686900,Weapon -36,10150001,303004,117,0,0,156975,999,394,395,,5619000,Weapon -37,10151001,303004,118,0,0,160815,999,85,86,,5823300,Weapon -38,10152001,303004,119,0,0,164715,999,88,89,,5876100,Weapon -39,10153001,303004,121,0,0,168675,999,91,92,,5974800,Weapon -40,10154001,303004,122,0,0,172695,999,94,95,,6020700,Weapon -41,10155000,303004,125,0,0,180915,999,397,398,,6003000,Weapon -42,10210000,303100,2,0,0,5,6,400,401,,1,Armor 43,10211000,303100,2,0,0,5,13,97,98,,2,Armor -44,10212000,303100,3,0,0,23,24,100,101,,3,Armor -45,10213000,303100,10,0,0,210,59,103,104,,23,Armor 46,10214000,303100,14,0,0,1076,108,106,107,,742,Armor -47,10220000,303101,5,0,0,70,35,403,404,,5,Armor -48,10221000,303101,5,0,0,79,37,109,110,,8,Armor 49,10222000,303101,7,0,0,120,45,112,113,,11,Armor -50,10223000,303101,16,0,0,1341,123,115,116,,928,Armor 51,10224000,303101,26,0,0,8361,182,118,119,,23920,Armor -52,10230000,303102,9,0,0,310,75,406,407,,300,Armor -53,10231000,303102,10,0,0,348,81,121,122,,348,Armor -54,10232000,303102,11,0,0,432,93,124,125,,387,Armor 55,10233000,303102,40,0,0,18426,201,127,128,,140400,Armor 56,10234000,303102,52,0,0,23991,208,130,131,,182520,Armor 57,10230001,303102,20,0,0,1824,146,409,410,,9600,Armor 58,10231001,303102,22,0,0,5463,158,133,134,,33000,Armor 59,10232001,303102,23,0,0,6189,166,136,137,,35040,Armor 60,10233001,303102,67,0,0,31056,228,139,140,,455400,Armor -61,10234001,303102,76,0,0,36195,246,142,143,,889200,Armor 62,10240000,303103,250,0,0,40000,294,102400001,102400002,,1166700,Armor 63,10241000,303103,120,0,0,20000,261,102410001,102410002,,1173660,Armor 64,10242000,303103,120,0,0,24000,270,102420001,102420002,,1188720,Armor @@ -70,80 +38,34 @@ id,result_equipment_id,material_id,material_count,required_action_point,required 69,10252001,303104,360,0,0,3000,315,102520011,102520012,102520013,1000000,Armor 70,10253001,303104,360,0,0,3000,335,102530011,102530012,,1000000,Armor 71,10254001,303104,360,0,0,3000,335,102540011,102540012,102540013,1000000,Armor -72,10240001,303103,82,0,0,52575,999,415,416,,1303800,Armor -73,10241001,303103,82,0,0,54015,999,157,158,,1414500,Armor -74,10242001,303103,83,0,0,55515,999,160,161,,1433100,Armor -75,10243001,303103,83,0,0,57075,999,163,164,,1433100,Armor -76,10244001,303103,84,0,0,58695,999,166,167,,1449000,Armor -77,10250000,303104,88,0,0,69675,999,418,419,,4039200,Armor -78,10251000,303104,88,0,0,71715,999,169,170,,4158000,Armor -79,10252000,303104,89,0,0,73815,999,172,173,,4206600,Armor -80,10253000,303104,90,0,0,75975,999,175,176,,4252500,Armor -81,10254000,303104,90,0,0,78195,999,178,179,,4441500,Armor -82,10255000,303104,123,0,0,176775,999,424,425,,5646600,Armor -83,10310000,303200,2,0,0,5,9,427,428,,1,Belt -84,10311000,303200,2,0,0,5,20,193,194,,2,Belt -85,10312000,303200,4,0,0,30,25,196,197,,5,Belt -86,10313000,303200,12,0,0,274,69,199,200,,26,Belt 87,10314000,303200,18,0,0,1560,134,202,203,,954,Belt -88,10320000,303201,6,0,0,99,41,430,431,,12,Belt -89,10321000,303201,6,0,0,109,43,205,206,,15,Belt -90,10322000,303201,9,0,0,181,55,208,209,,22,Belt 91,10323000,303201,22,0,0,5796,162,211,212,,2992,Belt 92,10324000,303201,45,0,0,20472,203,214,215,,122220,Belt -93,10330000,303202,10,0,0,389,87,433,434,,330,Belt 94,10331000,303202,11,0,0,410,90,217,218,,387,Belt -95,10332000,303202,14,0,0,1119,111,220,221,,4872,Belt -96,10333000,303202,58,0,0,26637,216,223,224,,203580,Belt 97,10334000,303202,150,0,0,30000,251,226,227,,737100,Belt -98,10340000,303203,26,0,0,9054,186,436,437,,49608,Belt -99,10341000,303203,28,0,0,10620,194,229,230,,57960,Belt -100,10342000,303203,76,0,0,36015,240,232,233,,1128600,Belt 101,10343000,303203,76,0,0,36015,240,235,236,,1128600,Belt -102,10344000,303203,76,0,0,36015,240,238,239,,1128600,Belt 103,10350000,303203,250,0,0,40000,296,103500001,103500002,,4177800,Belt 104,10351000,303203,120,0,0,20000,260,103510001,103510002,,4347000,Belt 105,10352000,303203,120,0,0,24000,269,103520001,103520002,,4395600,Belt 106,10353000,303203,180,0,0,28000,278,103530001,103530002,,4441500,Belt 107,10354000,303203,180,0,0,32000,287,103540001,103540002,,4638900,Belt -108,10410000,303300,2,0,0,5,15,442,443,,1,Necklace -109,10411000,303300,2,0,0,11,21,253,254,,2,Necklace -110,10412000,303300,4,0,0,53,31,256,257,,5,Necklace 111,10413000,303300,15,0,0,368,84,259,260,,32,Necklace -112,10414000,303300,20,0,0,4977,150,262,263,,1060,Necklace -113,10420000,303301,7,0,0,131,47,445,446,,14,Necklace -114,10421000,303301,8,0,0,143,49,265,266,,20,Necklace -115,10422000,303301,10,0,0,225,61,268,269,,25,Necklace 116,10423000,303301,25,0,0,7728,178,271,272,,3472,Necklace 117,10424000,303301,150,0,0,19419,202,274,275,,116880,Necklace -118,10430000,303302,13,0,0,1005,102,448,449,,4320,Necklace -119,10431000,303302,13,0,0,1038,105,277,278,,4560,Necklace -120,10432000,303302,17,0,0,1409,126,280,281,,5952,Necklace 121,10433000,303302,55,0,0,25284,212,283,284,,195120,Necklace 122,10434000,303302,70,0,0,32649,232,286,287,,472500,Necklace 123,10440000,303303,77,0,0,9093,249,451,452,,729000,Necklace -124,10441000,303303,77,0,0,36375,249,289,290,,1528200,Necklace -125,10442000,303303,77,0,0,36375,249,292,293,,1528200,Necklace -126,10443000,303303,77,0,0,36375,249,295,296,,1528200,Necklace -127,10444000,303303,77,0,0,36375,249,298,299,,1528200,Necklace 128,10450000,303303,250,0,0,40000,293,104500001,104500002,,4361400,Necklace 129,10451000,303303,120,0,0,20000,255,104510001,104510002,,4536000,Necklace 130,10452000,303303,120,0,0,24000,264,104520001,104520002,,4584600,Necklace 131,10453000,303303,180,0,0,28000,274,104530001,104530002,,4630500,Necklace 132,10454000,303303,180,0,0,32000,284,104540001,104540002,,4889100,Necklace 133,10510000,303400,2,0,0,5,17,457,458,,1,Ring -134,10511000,303400,2,0,0,17,22,313,314,,2,Ring -135,10512000,303400,5,0,0,61,33,316,317,,5,Ring -136,10513000,303400,17,0,0,454,96,319,320,,38,Ring 137,10514000,303400,24,0,0,6642,170,322,323,,2544,Ring -138,10520000,303401,8,0,0,168,53,460,461,,16,Ring 139,10521000,303401,9,0,0,195,57,325,326,,22,Ring -140,10522000,303401,12,0,0,292,72,328,329,,29,Ring 141,10523000,303401,28,0,0,17493,198,331,332,,3808,Ring 142,10524000,303401,49,0,0,22758,205,334,335,,132900,Ring -143,10530000,303402,15,0,0,1220,117,463,464,,4980,Ring 144,10531000,303402,16,0,0,1278,120,337,338,,5568,Ring -145,10532000,303402,19,0,0,1731,142,340,341,,6648,Ring 146,10533000,303402,64,0,0,29523,224,343,344,,748800,Ring 147,10534000,303402,76,0,0,36075,243,346,347,,889200,Ring 148,10540000,303403,250,0,0,40000,298,105400001,105400002,,1170000,Ring diff --git a/Lib9c/TableCSV/Quest/CombinationEquipmentQuestSheet.csv b/Lib9c/TableCSV/Quest/CombinationEquipmentQuestSheet.csv index aa61761708..77fd0b8418 100644 --- a/Lib9c/TableCSV/Quest/CombinationEquipmentQuestSheet.csv +++ b/Lib9c/TableCSV/Quest/CombinationEquipmentQuestSheet.csv @@ -1,21 +1,10 @@ id,goal,quest_reward_id,recipe_id 1100001,1,101,1 -1100002,1,101,2 -1100003,1,101,3 -1100004,1,101,4 1100005,1,101,5 1100006,1,102,6 -1100007,1,102,7 -1100008,1,102,8 -1100009,1,102,9 1100010,1,102,10 -1100011,1,103,11 -1100012,1,103,12 -1100013,1,103,13 1100014,1,103,14 1100015,1,103,15 -1100016,1,103,16 -1100017,1,103,17 1100018,1,103,18 1100019,1,103,19 1100020,1,103,20 @@ -29,37 +18,16 @@ id,goal,quest_reward_id,recipe_id 1100028,1,105,28 1100029,1,105,29 1100030,1,105,30 -1100031,1,105,31 -1100032,1,105,32 -1100033,1,105,33 -1100034,1,105,34 -1100035,1,105,35 -1100036,1,105,36 -1100037,1,105,37 -1100038,1,105,38 -1100039,1,105,39 -1100040,1,105,40 -1100041,1,105,41 -1100042,1,201,42 1100043,1,201,43 -1100044,1,201,44 -1100045,1,201,45 1100046,1,201,46 -1100047,1,202,47 -1100048,1,202,48 1100049,1,202,49 -1100050,1,202,50 1100051,1,202,51 -1100052,1,203,52 -1100053,1,203,53 -1100054,1,203,54 1100055,1,203,55 1100056,1,203,56 1100057,1,203,57 1100058,1,203,58 1100059,1,203,59 1100060,1,203,60 -1100061,1,203,61 1100062,1,204,62 1100063,1,204,63 1100064,1,204,64 @@ -70,80 +38,34 @@ id,goal,quest_reward_id,recipe_id 1100069,1,205,69 1100070,1,205,70 1100071,1,205,71 -1100072,1,205,72 -1100073,1,205,73 -1100074,1,205,74 -1100075,1,205,75 -1100076,1,205,76 -1100077,1,205,77 -1100078,1,205,78 -1100079,1,205,79 -1100080,1,205,80 -1100081,1,205,81 -1100082,1,205,82 -1100083,1,301,83 -1100084,1,301,84 -1100085,1,301,85 -1100086,1,301,86 1100087,1,301,87 -1100088,1,302,88 -1100089,1,302,89 -1100090,1,302,90 1100091,1,302,91 1100092,1,302,92 -1100093,1,303,93 1100094,1,303,94 -1100095,1,303,95 -1100096,1,303,96 1100097,1,303,97 -1100098,1,304,98 -1100099,1,304,99 -1100100,1,304,100 1100101,1,304,101 -1100102,1,304,102 1100103,1,305,103 1100104,1,305,104 1100105,1,305,105 1100106,1,305,106 1100107,1,305,107 -1100108,1,401,108 -1100109,1,401,109 -1100110,1,401,110 1100111,1,401,111 -1100112,1,401,112 -1100113,1,402,113 -1100114,1,402,114 -1100115,1,402,115 1100116,1,402,116 1100117,1,402,117 -1100118,1,403,118 -1100119,1,403,119 -1100120,1,403,120 1100121,1,403,121 1100122,1,403,122 1100123,1,404,123 -1100124,1,404,124 -1100125,1,404,125 -1100126,1,404,126 -1100127,1,404,127 1100128,1,405,128 1100129,1,405,129 1100130,1,405,130 1100131,1,405,131 1100132,1,405,132 1100133,1,501,133 -1100134,1,501,134 -1100135,1,501,135 -1100136,1,501,136 1100137,1,501,137 -1100138,1,502,138 1100139,1,502,139 -1100140,1,502,140 1100141,1,502,141 1100142,1,502,142 -1100143,1,503,143 1100144,1,503,144 -1100145,1,503,145 1100146,1,503,146 1100147,1,503,147 1100148,1,504,148 diff --git a/Lib9c/TableCSV/Quest/QuestRewardSheet.csv b/Lib9c/TableCSV/Quest/QuestRewardSheet.csv index 40d23f46c1..f17b8d0d0e 100644 --- a/Lib9c/TableCSV/Quest/QuestRewardSheet.csv +++ b/Lib9c/TableCSV/Quest/QuestRewardSheet.csv @@ -37,7 +37,6 @@ id,reward_id 28,22 29,23 29,24 -29,38 30,23 30,25 31,26 @@ -53,6 +52,8 @@ id,reward_id 38,36 39,37 39,21 +40,36 +40,38 101,101 102,102 103,103 diff --git a/Lib9c/TableCSV/Quest/WorldQuestSheet.csv b/Lib9c/TableCSV/Quest/WorldQuestSheet.csv index f141788596..ea4d511fcb 100644 --- a/Lib9c/TableCSV/Quest/WorldQuestSheet.csv +++ b/Lib9c/TableCSV/Quest/WorldQuestSheet.csv @@ -3,7 +3,7 @@ id,goal,quest_reward_id 100002,2,38 100003,3,38 100004,4,28 -100005,5,38 +100005,5,40 100006,6,201 100007,7,38 100008,8,39 From 06c062793d8d595d56b7ce21a17213e62183a7a5 Mon Sep 17 00:00:00 2001 From: Yang Chun Ung Date: Thu, 2 Nov 2023 13:40:09 +0900 Subject: [PATCH 2/2] Fix broken test from recipe deleted --- .../Action/CreateOrReplaceAvatarTest.cs | 43 ++- .../CreateOrReplaceAvatarFactoryTest.cs | 25 +- .../Action/CombinationEquipment0Test.cs | 29 +- .../Action/CombinationEquipmentTest.cs | 8 +- .../CombinationAndRapidCombinationTest.cs | 298 ------------------ .../Pet/IncreaseBlockPerHourglassTest.cs | 12 +- .../Action/UnlockEquipmentRecipe1Test.cs | 53 ++-- .../Action/UnlockEquipmentRecipeTest.cs | 53 ++-- .Lib9c.Tests/CrystalCalculatorTest.cs | 21 +- 9 files changed, 169 insertions(+), 373 deletions(-) delete mode 100644 .Lib9c.Tests/Action/Scenario/CombinationAndRapidCombinationTest.cs diff --git a/.Lib9c.DevExtensions.Tests/Action/CreateOrReplaceAvatarTest.cs b/.Lib9c.DevExtensions.Tests/Action/CreateOrReplaceAvatarTest.cs index 654f1b4c16..0ab36e8230 100644 --- a/.Lib9c.DevExtensions.Tests/Action/CreateOrReplaceAvatarTest.cs +++ b/.Lib9c.DevExtensions.Tests/Action/CreateOrReplaceAvatarTest.cs @@ -5,6 +5,7 @@ using System.Linq; using Bencodex.Types; using Lib9c.DevExtensions.Action; +using Lib9c.Tests; using Lib9c.Tests.Action; using Libplanet.Action.State; using Libplanet.Crypto; @@ -24,6 +25,7 @@ namespace Lib9c.DevExtensions.Tests.Action public class CreateOrReplaceAvatarTest { private readonly IAccount _initialStates; + private readonly TableSheets _tableSheets; public CreateOrReplaceAvatarTest() { @@ -36,6 +38,7 @@ public CreateOrReplaceAvatarTest() GoldCurrencyState.Address, new GoldCurrencyState(ncgCurrency).Serialize()); var sheets = TableSheetsImporter.ImportSheets(); + _tableSheets = new TableSheets(sheets); foreach (var (key, value) in sheets) { _initialStates = _initialStates.SetState( @@ -69,16 +72,8 @@ public CreateOrReplaceAvatarTest() int.MaxValue, new[] { - (10111000, 0), - (10111000, 21), // 21: See also EnhancementCostSheetV2.csv - (10211000, 0), - (10211000, 21), - (10311000, 0), - (10311000, 21), - (10411000, 0), - (10411000, 21), - (10511000, 0), - (10511000, 21), + (ItemSubType.Weapon, 0), + (ItemSubType.Weapon, 21), // 21: See also EnhancementCostSheetV2.csv }, new[] { @@ -291,12 +286,22 @@ public void Serialize( int ear, int tail, int level, - (int equipmentId, int level)[]? equipments, + (ItemSubType itemSubType, int level)[]? equipmentData, (int consumableId, int count)[]? foods, int[]? costumeIds, (int runeId, int level)[]? runes, (int stageId, int[] crystalRandomBuffIds)? crystalRandomBuff) { + var equipments = new List<(int, int)>(); + if (!(equipmentData is null)) + { + foreach (var data in equipmentData) + { + var row = _tableSheets.EquipmentItemRecipeSheet.Values.First(r => + r.ItemSubType == data.itemSubType); + equipments.Add((row.ResultEquipmentId, data.level)); + } + } var action = new CreateOrReplaceAvatar( avatarIndex, name, @@ -305,7 +310,7 @@ public void Serialize( ear, tail, level, - equipments, + equipments.ToArray(), foods, costumeIds, runes, @@ -348,12 +353,22 @@ public void Execute_Success( int ear, int tail, int level, - (int equipmentId, int level)[]? equipments, + (ItemSubType itemSubType, int level)[]? equipmentData, (int consumableId, int count)[]? foods, int[]? costumeIds, (int runeId, int level)[]? runes, (int stageId, int[] crystalRandomBuffIds)? crystalRandomBuff) { + var equipments = new List<(int, int)>(); + if (!(equipmentData is null)) + { + foreach (var data in equipmentData) + { + var row = _tableSheets.EquipmentItemRecipeSheet.Values.First(r => + r.ItemSubType == data.itemSubType); + equipments.Add((row.ResultEquipmentId, data.level)); + } + } var agentAddr = new PrivateKey().ToAddress(); Execute( _initialStates, @@ -366,7 +381,7 @@ public void Execute_Success( ear, tail, level, - equipments, + equipments.ToArray(), foods, costumeIds, runes, diff --git a/.Lib9c.DevExtensions.Tests/Action/Factory/CreateOrReplaceAvatarFactoryTest.cs b/.Lib9c.DevExtensions.Tests/Action/Factory/CreateOrReplaceAvatarFactoryTest.cs index 68b42140e7..2ff7e3035a 100644 --- a/.Lib9c.DevExtensions.Tests/Action/Factory/CreateOrReplaceAvatarFactoryTest.cs +++ b/.Lib9c.DevExtensions.Tests/Action/Factory/CreateOrReplaceAvatarFactoryTest.cs @@ -1,14 +1,24 @@ #nullable enable using System; +using System.Collections.Generic; using System.Linq; using Lib9c.DevExtensions.Action.Factory; +using Lib9c.Tests; +using Nekoyume.Model.Item; using Xunit; namespace Lib9c.DevExtensions.Tests.Action.Factory { public class CreateOrReplaceAvatarFactoryTest { + private readonly TableSheets _tableSheets; + + public CreateOrReplaceAvatarFactoryTest() + { + _tableSheets = new TableSheets(TableSheetsImporter.ImportSheets()); + } + [Theory] [MemberData( nameof(CreateOrReplaceAvatarTest.Get_Execute_Success_MemberData), @@ -22,12 +32,23 @@ public void TryGetByBlockIndex_Success( int ear, int tail, int level, - (int equipmentId, int level)[]? equipments, + (ItemSubType itemSubType, int level)[]? equipmentData, (int consumableId, int count)[]? foods, int[]? costumeIds, (int runeId, int level)[]? runes, (int stageId, int[] crystalRandomBuffIds)? crystalRandomBuff) { + var equipments = new List<(int, int)>(); + if (!(equipmentData is null)) + { + foreach (var data in equipmentData) + { + var row = _tableSheets.EquipmentItemRecipeSheet.Values.First(r => + r.ItemSubType == data.itemSubType); + equipments.Add((row.ResultEquipmentId, data.level)); + } + } + var (e, r) = CreateOrReplaceAvatarFactory .TryGetByBlockIndex( blockIndex, @@ -38,7 +59,7 @@ public void TryGetByBlockIndex_Success( ear, tail, level, - equipments, + equipments.ToArray(), foods, costumeIds, runes, diff --git a/.Lib9c.Tests/Action/CombinationEquipment0Test.cs b/.Lib9c.Tests/Action/CombinationEquipment0Test.cs index 5f837628ac..981663b9c8 100644 --- a/.Lib9c.Tests/Action/CombinationEquipment0Test.cs +++ b/.Lib9c.Tests/Action/CombinationEquipment0Test.cs @@ -137,15 +137,28 @@ public void ExecuteWithSubRecipe() _avatarState.inventory.AddItem2(material, count: materialInfo.Count); } - for (var i = 1; i < row.UnlockStage + 1; i++) + var worldSheet = _tableSheets.WorldSheet; + var worldId = 1; + foreach (var worldRow in worldSheet.OrderedList) { - _avatarState.worldInformation.ClearStage( - 1, - i, - 0, - _tableSheets.WorldSheet, - _tableSheets.WorldUnlockSheet - ); + if (worldRow.StageBegin <= row.UnlockStage && row.UnlockStage <= worldRow.StageEnd) + { + worldId = worldRow.Id; + } + } + + for (int j = 1; j < worldId + 1; j++) + { + for (var i = 1; i < row.UnlockStage + 1; i++) + { + _avatarState.worldInformation.ClearStage( + j, + i, + 0, + _tableSheets.WorldSheet, + _tableSheets.WorldUnlockSheet + ); + } } _initialState = _initialState.SetState(_avatarAddress, _avatarState.Serialize()); diff --git a/.Lib9c.Tests/Action/CombinationEquipmentTest.cs b/.Lib9c.Tests/Action/CombinationEquipmentTest.cs index 17db7d16ff..1139a9a86f 100644 --- a/.Lib9c.Tests/Action/CombinationEquipmentTest.cs +++ b/.Lib9c.Tests/Action/CombinationEquipmentTest.cs @@ -94,7 +94,7 @@ public CombinationEquipmentTest(ITestOutputHelper outputHelper) // Migration AvatarState. [InlineData(null, false, false, true, true, true, 3, 0, true, 1L, 1, null, true, false, false, false)] // SubRecipe - [InlineData(null, true, true, true, true, false, 11, 0, true, 1L, 2, 1, true, false, false, false)] + [InlineData(null, true, true, true, true, false, 27, 0, true, 1L, 6, 376, true, false, false, false)] // 3rd sub recipe, not Mimisbrunnr Equipment. [InlineData(null, true, true, true, true, false, 349, 0, true, 1L, 28, 101520003, true, false, false, false)] // Purchase CRYSTAL. @@ -104,9 +104,9 @@ public CombinationEquipmentTest(ITestOutputHelper outputHelper) // Arena round not found [InlineData(null, false, false, true, true, false, 3, 0, true, 0L, 1, null, true, false, false, false)] // UnlockEquipmentRecipe not executed. - [InlineData(typeof(FailedLoadStateException), false, true, true, true, false, 11, 0, true, 0L, 2, 1, true, false, false, false)] + [InlineData(typeof(FailedLoadStateException), false, true, true, true, false, 11, 0, true, 0L, 6, 1, true, false, false, false)] // CRYSTAL not paid. - [InlineData(typeof(InvalidRecipeIdException), true, false, true, true, false, 11, 0, true, 0L, 2, 1, true, false, false, false)] + [InlineData(typeof(InvalidRecipeIdException), true, false, true, true, false, 11, 0, true, 0L, 6, 1, true, false, false, false)] // AgentState not exist. [InlineData(typeof(FailedLoadStateException), true, true, false, true, false, 3, 0, true, 0L, 1, null, true, false, false, false)] // AvatarState not exist. @@ -119,7 +119,7 @@ public CombinationEquipmentTest(ITestOutputHelper outputHelper) // CombinationSlotState locked. [InlineData(typeof(CombinationSlotUnlockException), true, true, true, true, false, 3, 0, false, 0L, 1, null, true, false, false, false)] // Stage not cleared. - [InlineData(typeof(NotEnoughClearedStageLevelException), true, true, true, true, false, 3, 0, true, 0L, 2, null, true, false, false, false)] + [InlineData(typeof(NotEnoughClearedStageLevelException), true, true, true, true, false, 3, 0, true, 0L, 6, null, true, false, false, false)] // Not enough material. [InlineData(typeof(NotEnoughMaterialException), true, true, true, true, false, 3, 0, true, 0L, 1, null, false, false, false, false)] public void Execute( diff --git a/.Lib9c.Tests/Action/Scenario/CombinationAndRapidCombinationTest.cs b/.Lib9c.Tests/Action/Scenario/CombinationAndRapidCombinationTest.cs deleted file mode 100644 index b94a86e78a..0000000000 --- a/.Lib9c.Tests/Action/Scenario/CombinationAndRapidCombinationTest.cs +++ /dev/null @@ -1,298 +0,0 @@ -namespace Lib9c.Tests.Action.Scenario -{ - using System.Globalization; - using System.Linq; - using Bencodex.Types; - using Libplanet.Action.State; - using Libplanet.Crypto; - using Libplanet.Types.Assets; - using Nekoyume; - using Nekoyume.Action; - using Nekoyume.Model; - using Nekoyume.Model.Item; - using Nekoyume.Model.State; - using Nekoyume.TableData; - using Serilog; - using Xunit; - using Xunit.Abstractions; - using static Lib9c.SerializeKeys; - - public class CombinationAndRapidCombinationTest - { - private readonly IAccount _initialState; - private readonly TableSheets _tableSheets; - private Address _agentAddress; - private Address _avatarAddress; - private Address _inventoryAddress; - private Address _worldInformationAddress; - private Address _questListAddress; - private Address _slot0Address; - - public CombinationAndRapidCombinationTest(ITestOutputHelper outputHelper) - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.TestOutput(outputHelper) - .CreateLogger(); - - var sheets = TableSheetsImporter.ImportSheets(); - _tableSheets = new TableSheets(sheets); - -#pragma warning disable CS0618 - // Use of obsolete method Currency.Legacy(): https://github.com/planetarium/lib9c/discussions/1319 - var gold = new GoldCurrencyState(Currency.Legacy("NCG", 2, null)); -#pragma warning restore CS0618 - 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 Account(MockState.Empty) - .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()); - } - } - - // NOTE: Do not remove. - // [Theory] - // [InlineData(new[] { 1 })] - // [InlineData(new[] { 1, 2 })] - // [InlineData(new[] { 1, 3 })] - // [InlineData(new[] { 1, 4 })] - // [InlineData(new[] { 1, 2, 3 })] - // [InlineData(new[] { 1, 2, 4 })] - // [InlineData(new[] { 1, 3, 4 })] - // [InlineData(new[] { 1, 2, 3, 4 })] - // public void FindRandomSeedForCase(int[] optionNumbers) - // { - // var randomSeed = 0; - // while (randomSeed < 100000) - // { - // try - // { - // Case(randomSeed, optionNumbers); - // } - // catch - // { - // randomSeed++; - // continue; - // } - // - // Log.Debug(randomSeed.ToString()); - // break; - // } - // } - [Theory] - [InlineData(6, new[] { 1 })] - [InlineData(0, new[] { 1, 2 })] - [InlineData(7, new[] { 1, 3 })] - [InlineData(9, new[] { 1, 4 })] - [InlineData(2, new[] { 1, 2, 3 })] - [InlineData(1, new[] { 1, 2, 4 })] - [InlineData(5, new[] { 1, 3, 4 })] - [InlineData(18, new[] { 1, 2, 3, 4 })] - 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 unlockedRecipeIdsAddress = _avatarAddress.Derive("recipe_ids"); - var recipeIds = List.Empty; - for (int i = 1; i < recipeRow.UnlockStage + 1; i++) - { - recipeIds = recipeIds.Add(i.Serialize()); - } - - var nextState = _initialState - .SetState(unlockedRecipeIdsAddress, recipeIds) - .SetState(_inventoryAddress, inventoryState.Serialize()) - .SetState(_worldInformationAddress, worldInformation.Serialize()); - - var random = new TestRandom(randomSeed); - var ctx = new ActionContext - { - PreviousState = nextState, - BlockIndex = 0, - Signer = _agentAddress, - }; - ctx.SetRandom(random); - nextState = combinationEquipmentAction.Execute(ctx); - - 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 RapidCombination8 - { - avatarAddress = _avatarAddress, - slotIndex = 0, - }; - - nextState = rapidCombinationAction.Execute(new ActionContext - { - PreviousState = nextState, - BlockIndex = GameConfig.RequiredAppraiseBlock, - RandomSeed = random.Seed, - Signer = _agentAddress, - }); - inventoryValue = nextState.GetState(_inventoryAddress); - Assert.NotNull(inventoryValue); - inventoryState = new Inventory((List)inventoryValue); - Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); - } - } -} diff --git a/.Lib9c.Tests/Action/Scenario/Pet/IncreaseBlockPerHourglassTest.cs b/.Lib9c.Tests/Action/Scenario/Pet/IncreaseBlockPerHourglassTest.cs index a992234b8f..e5b95e3a38 100644 --- a/.Lib9c.Tests/Action/Scenario/Pet/IncreaseBlockPerHourglassTest.cs +++ b/.Lib9c.Tests/Action/Scenario/Pet/IncreaseBlockPerHourglassTest.cs @@ -52,13 +52,13 @@ public IncreaseBlockPerHourglassTest() } [Theory] - [InlineData(1, 10113000, null)] // No Pet - [InlineData(1, 10113000, 1)] // Lv.1 increases 1 block per HG: 3 -> 4 - [InlineData(1, 10113000, 30)] // Lv.30 increases 30 blocks per HG: 3 -> 33 - [InlineData(1, 10120000, 30)] // Test for min. Hourglass is 1 + [InlineData(1, 155, null)] // No Pet + [InlineData(1, 155, 1)] // Lv.1 increases 1 block per HG: 3 -> 4 + [InlineData(1, 155, 30)] // Lv.30 increases 30 blocks per HG: 3 -> 33 + [InlineData(1, 37, 30)] // Test for min. Hourglass is 1 public void RapidCombinationTest_Equipment( int randomSeed, - int targetItemId, + int requiredBlock, int? petLevel ) { @@ -74,7 +74,7 @@ public void RapidCombinationTest_Equipment( // Get recipe var recipe = _tableSheets.EquipmentItemRecipeSheet.Values.First( - recipe => recipe.ResultEquipmentId == targetItemId + recipe => recipe.RequiredBlockIndex >= requiredBlock ); Assert.NotNull(recipe); diff --git a/.Lib9c.Tests/Action/UnlockEquipmentRecipe1Test.cs b/.Lib9c.Tests/Action/UnlockEquipmentRecipe1Test.cs index 5fa19679ad..db324c7e8e 100644 --- a/.Lib9c.Tests/Action/UnlockEquipmentRecipe1Test.cs +++ b/.Lib9c.Tests/Action/UnlockEquipmentRecipe1Test.cs @@ -59,52 +59,67 @@ public UnlockEquipmentRecipe1Test() } [Theory] - [InlineData(new[] { 2, 3 }, true, false, false, true, 4, null)] - [InlineData(new[] { 2 }, true, false, false, true, 2, null)] + [InlineData(new[] { 6, 5 }, true, false, false, true, true, null)] + [InlineData(new[] { 6 }, true, false, false, true, true, null)] // Unlock Belt without Armor unlock. - [InlineData(new[] { 83 }, true, false, false, true, 1, null)] + [InlineData(new[] { 94 }, true, false, false, true, true, null)] // Unlock Weapon & Ring - [InlineData(new[] { 2, 133 }, true, false, false, true, 3, null)] + [InlineData(new[] { 6, 133 }, true, false, false, true, true, null)] // AvatarState migration. - [InlineData(new[] { 2 }, true, true, false, true, 2, null)] + [InlineData(new[] { 6 }, true, true, false, true, true, null)] // Invalid recipe id. - [InlineData(new[] { -1 }, true, false, false, false, 100, typeof(InvalidRecipeIdException))] - [InlineData(new[] { 1 }, true, false, false, true, 100, typeof(InvalidRecipeIdException))] - [InlineData(new int[] { }, true, false, false, false, 100, typeof(InvalidRecipeIdException))] + [InlineData(new[] { -1 }, true, false, false, false, false, typeof(InvalidRecipeIdException))] + [InlineData(new[] { 1 }, true, false, false, true, false, typeof(InvalidRecipeIdException))] + [InlineData(new int[] { }, true, false, false, false, false, typeof(InvalidRecipeIdException))] // AvatarState is null. - [InlineData(new[] { 2 }, false, true, false, true, 100, typeof(FailedLoadStateException))] - [InlineData(new[] { 2 }, false, false, false, true, 100, typeof(FailedLoadStateException))] + [InlineData(new[] { 6 }, false, true, false, true, true, typeof(FailedLoadStateException))] + [InlineData(new[] { 6 }, false, false, false, true, true, typeof(FailedLoadStateException))] // Already unlocked recipe. - [InlineData(new[] { 2 }, true, false, true, true, 100, typeof(AlreadyRecipeUnlockedException))] + [InlineData(new[] { 6 }, true, false, true, true, true, typeof(AlreadyRecipeUnlockedException))] // Skip prev recipe. - [InlineData(new[] { 3 }, true, false, false, true, 100, typeof(InvalidRecipeIdException))] + [InlineData(new[] { 5 }, true, false, false, true, false, typeof(InvalidRecipeIdException))] // Stage not cleared. - [InlineData(new[] { 2 }, true, false, false, false, 100, typeof(NotEnoughClearedStageLevelException))] + [InlineData(new[] { 6 }, true, false, false, false, true, typeof(NotEnoughClearedStageLevelException))] // Insufficient CRYSTAL. - [InlineData(new[] { 2 }, true, false, false, true, 1, typeof(NotEnoughFungibleAssetValueException))] + [InlineData(new[] { 6 }, true, false, false, true, false, typeof(NotEnoughFungibleAssetValueException))] public void Execute( IEnumerable ids, bool stateExist, bool migrationRequired, bool alreadyUnlocked, bool stageCleared, - int balance, + bool balanceEnough, Type exc ) { var context = new ActionContext(); - var state = _initialState.MintAsset(context, _agentAddress, balance * _currency); List recipeIds = ids.ToList(); + var rows = _tableSheets.EquipmentItemRecipeSheet.Values + .Where(r => recipeIds.Contains(r.Id)).ToList(); + var balance = balanceEnough ? rows.Sum(r => r.CRYSTAL) : 1; + var state = _initialState.MintAsset(context, _agentAddress, balance * _currency); Address unlockedRecipeIdsAddress = _avatarAddress.Derive("recipe_ids"); if (stateExist) { + var stage = rows.Any() ? rows.Max(r => r.UnlockStage) : 1; + var worldSheet = _tableSheets.WorldSheet; + var worldId = worldSheet.OrderedList + .Last(r => r.StageBegin <= stage && stage <= r.StageEnd).Id; var worldInformation = _avatarState.worldInformation; if (stageCleared) { - var stage = _tableSheets.EquipmentItemRecipeSheet[recipeIds.Max()].UnlockStage; - for (int i = 1; i < stage + 1; i++) + for (int j = 1; j < worldId + 1; j++) { - worldInformation.ClearStage(1, i, 0, _tableSheets.WorldSheet, _tableSheets.WorldUnlockSheet); + for (var i = 1; i < stage + 1; i++) + { + _avatarState.worldInformation.ClearStage( + j, + i, + 0, + _tableSheets.WorldSheet, + _tableSheets.WorldUnlockSheet + ); + } } } else diff --git a/.Lib9c.Tests/Action/UnlockEquipmentRecipeTest.cs b/.Lib9c.Tests/Action/UnlockEquipmentRecipeTest.cs index 0a51ab2a25..a7f8bf3888 100644 --- a/.Lib9c.Tests/Action/UnlockEquipmentRecipeTest.cs +++ b/.Lib9c.Tests/Action/UnlockEquipmentRecipeTest.cs @@ -59,52 +59,67 @@ public UnlockEquipmentRecipeTest() } [Theory] - [InlineData(new[] { 2, 3 }, true, false, false, true, 4, null)] - [InlineData(new[] { 2 }, true, false, false, true, 2, null)] + [InlineData(new[] { 6, 5 }, true, false, false, true, true, null)] + [InlineData(new[] { 6 }, true, false, false, true, true, null)] // Unlock Belt without Armor unlock. - [InlineData(new[] { 83 }, true, false, false, true, 1, null)] + [InlineData(new[] { 94 }, true, false, false, true, true, null)] // Unlock Weapon & Ring - [InlineData(new[] { 2, 133 }, true, false, false, true, 3, null)] + [InlineData(new[] { 6, 133 }, true, false, false, true, true, null)] // AvatarState migration. - [InlineData(new[] { 2 }, true, true, false, true, 2, null)] + [InlineData(new[] { 6 }, true, true, false, true, true, null)] // Invalid recipe id. - [InlineData(new[] { -1 }, true, false, false, false, 100, typeof(InvalidRecipeIdException))] - [InlineData(new[] { 1 }, true, false, false, true, 100, typeof(InvalidRecipeIdException))] - [InlineData(new int[] { }, true, false, false, false, 100, typeof(InvalidRecipeIdException))] + [InlineData(new[] { -1 }, true, false, false, false, false, typeof(InvalidRecipeIdException))] + [InlineData(new[] { 1 }, true, false, false, true, false, typeof(InvalidRecipeIdException))] + [InlineData(new int[] { }, true, false, false, false, false, typeof(InvalidRecipeIdException))] // AvatarState is null. - [InlineData(new[] { 2 }, false, true, false, true, 100, typeof(FailedLoadStateException))] - [InlineData(new[] { 2 }, false, false, false, true, 100, typeof(FailedLoadStateException))] + [InlineData(new[] { 6 }, false, true, false, true, true, typeof(FailedLoadStateException))] + [InlineData(new[] { 6 }, false, false, false, true, true, typeof(FailedLoadStateException))] // Already unlocked recipe. - [InlineData(new[] { 2 }, true, false, true, true, 100, typeof(AlreadyRecipeUnlockedException))] + [InlineData(new[] { 6 }, true, false, true, true, true, typeof(AlreadyRecipeUnlockedException))] // Skip prev recipe. - [InlineData(new[] { 3 }, true, false, false, true, 100, typeof(InvalidRecipeIdException))] + [InlineData(new[] { 5 }, true, false, false, true, true, typeof(InvalidRecipeIdException))] // Stage not cleared. - [InlineData(new[] { 2 }, true, false, false, false, 100, typeof(NotEnoughClearedStageLevelException))] + [InlineData(new[] { 6 }, true, false, false, false, true, typeof(NotEnoughClearedStageLevelException))] // Insufficient CRYSTAL. - [InlineData(new[] { 2 }, true, false, false, true, 1, typeof(NotEnoughFungibleAssetValueException))] + [InlineData(new[] { 6 }, true, false, false, true, false, typeof(NotEnoughFungibleAssetValueException))] public void Execute( IEnumerable ids, bool stateExist, bool migrationRequired, bool alreadyUnlocked, bool stageCleared, - int balance, + bool balanceEnough, Type exc ) { var context = new ActionContext(); - var state = _initialState.MintAsset(context, _agentAddress, balance * _currency); List recipeIds = ids.ToList(); + var rows = _tableSheets.EquipmentItemRecipeSheet.Values + .Where(r => recipeIds.Contains(r.Id)).ToList(); + var balance = balanceEnough ? rows.Sum(r => r.CRYSTAL) : 1; + var state = _initialState.MintAsset(context, _agentAddress, balance * _currency); Address unlockedRecipeIdsAddress = _avatarAddress.Derive("recipe_ids"); if (stateExist) { + var stage = rows.Any() ? rows.Max(r => r.UnlockStage) : 1; + var worldSheet = _tableSheets.WorldSheet; + var worldId = worldSheet.OrderedList + .Last(r => r.StageBegin <= stage && stage <= r.StageEnd).Id; var worldInformation = _avatarState.worldInformation; if (stageCleared) { - var stage = _tableSheets.EquipmentItemRecipeSheet[recipeIds.Max()].UnlockStage; - for (int i = 1; i < stage + 1; i++) + for (int j = 1; j < worldId + 1; j++) { - worldInformation.ClearStage(1, i, 0, _tableSheets.WorldSheet, _tableSheets.WorldUnlockSheet); + for (var i = 1; i < stage + 1; i++) + { + _avatarState.worldInformation.ClearStage( + j, + i, + 0, + _tableSheets.WorldSheet, + _tableSheets.WorldUnlockSheet + ); + } } } else diff --git a/.Lib9c.Tests/CrystalCalculatorTest.cs b/.Lib9c.Tests/CrystalCalculatorTest.cs index c3e8d989b2..bff47869bb 100644 --- a/.Lib9c.Tests/CrystalCalculatorTest.cs +++ b/.Lib9c.Tests/CrystalCalculatorTest.cs @@ -33,10 +33,25 @@ public CrystalCalculatorTest() } [Theory] - [InlineData(new[] { 2 }, 2)] - [InlineData(new[] { 2, 3 }, 4)] - public void CalculateRecipeUnlockCost(IEnumerable recipeIds, int expected) + [InlineData(1)] + [InlineData(2)] + public void CalculateRecipeUnlockCost(int recipeCount) { + var recipeIds = new List(); + var expected = 0; + foreach (var row in _equipmentItemRecipeSheet.OrderedList) + { + if (recipeIds.Count < recipeCount) + { + recipeIds.Add(row.Id); + expected += row.CRYSTAL; + } + else + { + break; + } + } + Assert.Equal(expected * CrystalCalculator.CRYSTAL, CrystalCalculator.CalculateRecipeUnlockCost(recipeIds, _equipmentItemRecipeSheet)); }