diff --git a/.Lib9c.Tests/Action/SynthesizeTest.cs b/.Lib9c.Tests/Action/SynthesizeTest.cs
index 20f8872269..cda7f63720 100644
--- a/.Lib9c.Tests/Action/SynthesizeTest.cs
+++ b/.Lib9c.Tests/Action/SynthesizeTest.cs
@@ -103,11 +103,13 @@ public void ExecuteSingle(Grade grade, ItemSubType itemSubType)
(state, var items) = UpdateItemsFromSubType(grade, itemSubTypes, state, avatarAddress);
state = state.SetActionPoint(avatarAddress, 120);
- var previousAvatarState = state.GetAvatarState(avatarAddress);
var action = new Synthesize()
{
AvatarAddress = avatarAddress,
MaterialIds = SynthesizeSimulator.GetItemGuids(items),
+ ChargeAp = false,
+ MaterialGradeId = (int)grade,
+ MaterialItemSubTypeId = (int)itemSubType,
};
var ctx = new ActionContext
@@ -153,17 +155,11 @@ public void ExecuteSingle(Grade grade, ItemSubType itemSubType)
break;
}
- var gradeDict = SynthesizeSimulator.GetGradeDict(
- action.MaterialIds,
- previousAvatarState,
- blockIndex,
- avatarAddress.ToHex(),
- out _,
- out _
- );
-
var inputData = new SynthesizeSimulator.InputData()
{
+ Grade = grade,
+ ItemSubType = itemSubType,
+ MaterialCount = itemSubTypes.Length,
SynthesizeSheet = TableSheets.SynthesizeSheet,
SynthesizeWeightSheet = TableSheets.SynthesizeWeightSheet,
CostumeItemSheet = TableSheets.CostumeItemSheet,
@@ -173,7 +169,6 @@ out _
EquipmentItemOptionSheet = TableSheets.EquipmentItemOptionSheet,
SkillSheet = TableSheets.SkillSheet,
RandomObject = new TestRandom(),
- GradeDict = gradeDict,
};
var result = SynthesizeSimulator.Simulate(inputData)[0];
@@ -220,11 +215,13 @@ public void ExecuteMultiple(Grade grade, ItemSubType itemSubType)
(state, var items) = UpdateItemsFromSubType(grade, itemSubTypes, state, avatarAddress);
state = state.SetActionPoint(avatarAddress, 120);
- var previousAvatarState = state.GetAvatarState(avatarAddress);
var action = new Synthesize()
{
AvatarAddress = avatarAddress,
MaterialIds = SynthesizeSimulator.GetItemGuids(items),
+ ChargeAp = false,
+ MaterialGradeId = (int)grade,
+ MaterialItemSubTypeId = (int)itemSubType,
};
var ctx = new ActionContext
@@ -235,19 +232,12 @@ public void ExecuteMultiple(Grade grade, ItemSubType itemSubType)
Signer = agentAddress,
};
- state = action.Execute(ctx);
-
- var gradeDict = SynthesizeSimulator.GetGradeDict(
- action.MaterialIds,
- previousAvatarState,
- blockIndex,
- avatarAddress.ToHex(),
- out _,
- out _
- );
-
+ action.Execute(ctx);
var inputData = new SynthesizeSimulator.InputData()
{
+ Grade = grade,
+ ItemSubType = itemSubType,
+ MaterialCount = itemSubTypes.Length,
SynthesizeSheet = TableSheets.SynthesizeSheet,
SynthesizeWeightSheet = TableSheets.SynthesizeWeightSheet,
CostumeItemSheet = TableSheets.CostumeItemSheet,
@@ -257,7 +247,6 @@ out _
EquipmentItemOptionSheet = TableSheets.EquipmentItemOptionSheet,
SkillSheet = TableSheets.SkillSheet,
RandomObject = new TestRandom(),
- GradeDict = gradeDict,
};
var resultList = SynthesizeSimulator.Simulate(inputData);
@@ -299,6 +288,9 @@ public void ExecuteNotEnoughActionPoint()
{
AvatarAddress = avatarAddress,
MaterialIds = SynthesizeSimulator.GetItemGuids(items),
+ ChargeAp = false,
+ MaterialGradeId = (int)grade,
+ MaterialItemSubTypeId = (int)itemSubType,
};
var ctx = new ActionContext
@@ -336,6 +328,9 @@ public void ExecuteMultipleSameType(int testCount)
{
AvatarAddress = avatarAddress,
MaterialIds = SynthesizeSimulator.GetItemGuids(items),
+ ChargeAp = false,
+ MaterialGradeId = (int)grade,
+ MaterialItemSubTypeId = (int)itemSubType,
};
var ctx = new ActionContext
@@ -380,6 +375,9 @@ public void ExecuteInvalidMaterial(Grade grade, ItemSubType[] itemSubTypes)
{
AvatarAddress = avatarAddress,
MaterialIds = SynthesizeSimulator.GetItemGuids(items),
+ ChargeAp = false,
+ MaterialGradeId = (int)grade,
+ MaterialItemSubTypeId = (int)itemSubTypes[0],
};
var ctx = new ActionContext
diff --git a/Lib9c/Action/Synthesize.cs b/Lib9c/Action/Synthesize.cs
index d0035cf080..1f5438af8e 100644
--- a/Lib9c/Action/Synthesize.cs
+++ b/Lib9c/Action/Synthesize.cs
@@ -11,6 +11,7 @@
using Nekoyume.Model.Item;
using Nekoyume.Model.State;
using Nekoyume.Helper;
+using Nekoyume.Model.EnumType;
using Nekoyume.Module;
using Nekoyume.TableData;
@@ -34,11 +35,30 @@ public class Synthesize : GameAction
private const string MaterialsKey = "m";
private const string ChargeApKey = "c";
private const string AvatarAddressKey = "a";
+ private const string GradeKey = "g";
+ private const string ItemSubTypeKey = "i";
#region Fields
+ ///
+ /// Id list of items as material.
+ ///
public List MaterialIds = new();
+ ///
+ /// Whether to charge action points with action execution.
+ ///
public bool ChargeAp;
+ ///
+ /// AvatarAddress of the signer.
+ ///
public Address AvatarAddress;
+ ///
+ /// MaterialGrade of the material item.
+ ///
+ public int MaterialGradeId;
+ ///
+ /// ItemSubType of the material item.
+ ///
+ public int MaterialItemSubTypeId;
#endregion Fields
///
@@ -50,6 +70,8 @@ public override IWorld Execute(IActionContext context)
{
GasTracer.UseGas(1);
var states = context.PreviousState;
+ var materialGrade = (Grade)MaterialGradeId;
+ var materialItemSubType = (ItemSubType)MaterialItemSubTypeId;
// Collect addresses
var addressesHex = GetSignerAndOtherAddressesHex(context, AvatarAddress);
@@ -85,19 +107,34 @@ public override IWorld Execute(IActionContext context)
// Calculate action point
var actionPoint = CalculateActionPoint(states, avatarState, sheets, context);
-
- // Initialize variables
- var gradeDict = SynthesizeSimulator.GetGradeDict(MaterialIds, avatarState, context.BlockIndex,
- addressesHex, out var materialEquipments, out var materialCostumes);
+ var materialItems = SynthesizeSimulator.GetMaterialList(
+ MaterialIds,
+ avatarState,
+ context.BlockIndex,
+ materialGrade,
+ materialItemSubType,
+ addressesHex
+ );
// Unequip items (if necessary)
- foreach (var materialEquipment in materialEquipments)
+ foreach (var materialItem in materialItems)
{
- materialEquipment.Unequip();
+ switch (materialItem)
+ {
+ case Equipment equipment:
+ equipment.Unequip();
+ break;
+ case Costume costume:
+ costume.Unequip();
+ break;
+ }
}
- foreach (var materialCostume in materialCostumes)
+
+ if (materialItems.Count == 0 || materialItems.Count != MaterialIds.Count)
{
- materialCostume.Unequip();
+ throw new InvalidMaterialException(
+ $"{addressesHex} Aborted as the material item is not valid."
+ );
}
// Remove materials from inventory
@@ -113,6 +150,9 @@ public override IWorld Execute(IActionContext context)
var synthesizedItems = SynthesizeSimulator.Simulate(new SynthesizeSimulator.InputData()
{
+ Grade = materialGrade,
+ ItemSubType = materialItemSubType,
+ MaterialCount = materialItems.Count,
SynthesizeSheet = sheets.GetSheet(),
SynthesizeWeightSheet = sheets.GetSheet(),
CostumeItemSheet = sheets.GetSheet(),
@@ -123,7 +163,6 @@ public override IWorld Execute(IActionContext context)
SkillSheet = sheets.GetSheet(),
BlockIndex = context.BlockIndex,
RandomObject = context.GetRandom(),
- GradeDict = gradeDict,
});
// Add synthesized items to inventory
@@ -184,6 +223,8 @@ private long CalculateActionPoint(IWorld states, AvatarState avatarState, Sheets
[MaterialsKey] = new List(MaterialIds.OrderBy(i => i).Select(i => i.Serialize())),
[ChargeApKey] = ChargeAp.Serialize(),
[AvatarAddressKey] = AvatarAddress.Serialize(),
+ [GradeKey] = (Integer)MaterialGradeId,
+ [ItemSubTypeKey] = (Integer)MaterialItemSubTypeId,
}
.ToImmutableDictionary();
@@ -192,6 +233,8 @@ protected override void LoadPlainValueInternal(IImmutableDictionary>;
-
///
/// Represents the result of the synthesis.
///
@@ -33,25 +31,23 @@ public struct SynthesizeResult
///
public static class SynthesizeSimulator
{
- private static readonly ItemType[] ValidItemType =
- {
- ItemType.Costume,
- ItemType.Equipment,
- };
-
- private static readonly ItemSubType[] ValidItemSubType =
- {
- ItemSubType.FullCostume,
- ItemSubType.Title,
- ItemSubType.Grimoire,
- ItemSubType.Aura,
- };
-
///
/// Simulate the synthesis of items.
///
public struct InputData
{
+ ///
+ /// The grade of the material item.
+ ///
+ public Grade Grade;
+ ///
+ /// The subtype of the material item.
+ ///
+ public ItemSubType ItemSubType;
+ ///
+ /// The number of materials.
+ ///
+ public int MaterialCount;
///
/// The sheet that contains the synthesis information.
///
@@ -101,10 +97,6 @@ public struct InputData
/// Caution: Must have the same seed as when the action is executed
///
public IRandom RandomObject;
- ///
- /// The grade dictionary of the material items.
- ///
- public GradeDict GradeDict;
}
private struct EquipmentData
@@ -132,159 +124,131 @@ public static List Simulate(InputData inputData)
var synthesizeSheet = inputData.SynthesizeSheet;
var random = inputData.RandomObject;
- var gradeDict = inputData.GradeDict;
// Calculate the number of items to be synthesized based on materials
- foreach (var gradeItem in gradeDict)
+ var gradeId = (int)inputData.Grade;
+
+ if (!synthesizeSheet.TryGetValue(gradeId, out var synthesizeRow))
{
- var gradeId = gradeItem.Key;
- var subTypeDict = gradeItem.Value;
+ throw new SheetRowNotFoundException(
+ $"Aborted as the synthesize row for grade ({gradeId}) was failed to load in {nameof(SynthesizeSheet)}", gradeId
+ );
+ }
- if (!synthesizeSheet.TryGetValue(gradeId, out var synthesizeRow))
+ var itemSubType = inputData.ItemSubType;
+ var materialCount = inputData.MaterialCount;
+
+ var requiredCount = synthesizeRow.RequiredCountDict[itemSubType].RequiredCount;
+ var succeedRate = synthesizeRow.RequiredCountDict[itemSubType].SucceedRate;
+ var synthesizeCount = materialCount / requiredCount;
+ var remainder = materialCount % requiredCount;
+
+ if (synthesizeCount <= 0 || remainder != 0)
+ {
+ throw new NotEnoughMaterialException(
+ $"Aborted as the number of materials for grade {gradeId} and subtype {itemSubType} is not enough."
+ );
+ }
+
+ // Calculate success for each synthesis
+ for (var i = 0; i < synthesizeCount; i++)
+ {
+ // random value range is 0 ~ 9999
+ // If the SucceedRate of the table is 0, use '<' for always to fail.
+ // and SucceedRate of the table is 10000, always success(because left value range is 0~9999)
+ var isSuccess = random.Next(SynthesizeSheet.SucceedRateMax) < succeedRate;
+
+ var grade = (Grade)gradeId;
+ // Decide the item to add to inventory based on SynthesizeWeightSheet
+ var synthesizedItem = GetSynthesizedItem(
+ grade,
+ isSuccess,
+ inputData.SynthesizeWeightSheet,
+ inputData.CostumeItemSheet,
+ inputData.EquipmentItemSheet,
+ inputData.EquipmentItemRecipeSheet,
+ inputData.EquipmentItemSubRecipeSheetV2,
+ inputData.EquipmentItemOptionSheet,
+ inputData.SkillSheet,
+ inputData.BlockIndex,
+ random,
+ itemSubType,
+ out var equipmentData);
+
+ if (isSuccess && grade == (Grade)synthesizedItem.Grade)
{
- throw new SheetRowNotFoundException(
- $"Aborted as the synthesize row for grade ({gradeId}) was failed to load in {nameof(SynthesizeSheet)}", gradeId
- );
+ // If there are no items in the data that are one above the current grade, they cannot succeed.
+ isSuccess = false;
}
- foreach (var subTypeItem in subTypeDict)
+ synthesizeResults.Add(new SynthesizeResult
{
- var itemSubType = subTypeItem.Key;
- var materialCount = subTypeItem.Value;
-
- // TODO: subType별로 필요한 아이템 개수가 다를 수 있음
- var requiredCount = synthesizeRow.RequiredCountDict[itemSubType].RequiredCount;
- var succeedRate = synthesizeRow.RequiredCountDict[itemSubType].SucceedRate;
- var synthesizeCount = materialCount / requiredCount;
- var remainder = materialCount % requiredCount;
-
- if (synthesizeCount <= 0 || remainder != 0)
- {
- throw new NotEnoughMaterialException(
- $"Aborted as the number of materials for grade {gradeId} and subtype {itemSubType} is not enough."
- );
- }
-
- // Calculate success for each synthesis
- for (var i = 0; i < synthesizeCount; i++)
- {
- // random value range is 0 ~ 9999
- // If the SucceedRate of the table is 0, use '<' for always to fail.
- // and SucceedRate of the table is 10000, always success(because left value range is 0~9999)
- var isSuccess = random.Next(SynthesizeSheet.SucceedRateMax) < succeedRate;
-
- var grade = (Grade)gradeId;
- // Decide the item to add to inventory based on SynthesizeWeightSheet
- var synthesizedItem = GetSynthesizedItem(
- grade,
- isSuccess,
- inputData.SynthesizeWeightSheet,
- inputData.CostumeItemSheet,
- inputData.EquipmentItemSheet,
- inputData.EquipmentItemRecipeSheet,
- inputData.EquipmentItemSubRecipeSheetV2,
- inputData.EquipmentItemOptionSheet,
- inputData.SkillSheet,
- inputData.BlockIndex,
- random,
- itemSubType,
- out var equipmentData);
-
- if (isSuccess && grade == (Grade)synthesizedItem.Grade)
- {
- // If there are no items in the data that are one above the current grade, they cannot succeed.
- isSuccess = false;
- }
-
- synthesizeResults.Add(new SynthesizeResult
- {
- ItemBase = synthesizedItem,
- IsSuccess = isSuccess,
- RecipeId = equipmentData.RecipeId,
- SubRecipeId = equipmentData.SubRecipeId,
- });
- }
- }
+ ItemBase = synthesizedItem,
+ IsSuccess = isSuccess,
+ RecipeId = equipmentData.RecipeId,
+ SubRecipeId = equipmentData.SubRecipeId,
+ });
}
return synthesizeResults;
}
- ///
- /// Get the grade of the material items and return the dictionary of the grade and the number of items.
- ///
- /// material item ids
- /// target avatar state
- /// current block index
- /// addresses in hex
- /// material equipment list
- /// material costume list
- ///
- ///
- ///
- public static GradeDict GetGradeDict(List materialIds, AvatarState avatarState, long blockIndex,
- string addressesHex, out List materialEquipments, out List materialCostumes)
+ public static List GetMaterialList(
+ List materialIds, AvatarState avatarState, long blockIndex,
+ Grade grade, ItemSubType itemSubType,
+ string addressesHex)
{
- ItemSubType? cachedItemSubType = null;
- var gradeDict = new GradeDict();
- materialEquipments = new List();
- materialCostumes = new List();
+ return itemSubType switch
+ {
+ ItemSubType.FullCostume or ItemSubType.Title => GetCostumeMaterialList(materialIds, avatarState, grade, itemSubType, addressesHex),
+ ItemSubType.Aura or ItemSubType.Grimoire => GetEquipmentMaterialList(materialIds, avatarState, blockIndex, grade, itemSubType, addressesHex),
+ _ => throw new ArgumentException($"Invalid item sub type: {itemSubType}", nameof(itemSubType)),
+ };
+ }
+ public static List GetEquipmentMaterialList(
+ List materialIds, AvatarState avatarState, long blockIndex,
+ Grade grade, ItemSubType itemSubType,
+ string addressesHex)
+ {
+ var materialEquipments = new List();
foreach (var materialId in materialIds)
{
- var materialEquipment = GetEquipmentFromId(materialId, avatarState, blockIndex, addressesHex, ref cachedItemSubType);
- var materialCostume = GetCostumeFromId(materialId, avatarState, addressesHex, ref cachedItemSubType);
- if (materialEquipment == null && materialCostume == null)
+ var materialEquipment = GetEquipmentFromId(materialId, avatarState, grade, itemSubType, blockIndex, addressesHex);
+ if (materialEquipment == null)
{
throw new InvalidMaterialException(
- $"{addressesHex} Aborted as the material item is not a valid item type."
+ $"{addressesHex} Aborted as the material item is not a equipment item type."
);
}
- if (materialEquipment != null)
- {
- materialEquipments.Add(materialEquipment);
- SetGradeDict(ref gradeDict, materialEquipment.Grade, materialEquipment.ItemSubType);
- }
-
- if (materialCostume != null)
- {
- materialCostumes.Add(materialCostume);
- SetGradeDict(ref gradeDict, materialCostume.Grade, materialCostume.ItemSubType);
- }
- }
-
- if (cachedItemSubType == null)
- {
- throw new InvalidOperationException("ItemSubType is not set.");
+ materialEquipments.Add(materialEquipment);
}
- return gradeDict;
+ return materialEquipments;
}
- private static void SetGradeDict(ref GradeDict gradeDict, int grade, ItemSubType itemSubType)
+ public static List GetCostumeMaterialList(
+ List materialIds, AvatarState avatarState, Grade grade, ItemSubType itemSubType, string addressesHex)
{
- if (gradeDict.ContainsKey(grade))
+ var materialCostumes = new List();
+ foreach (var materialId in materialIds)
{
- if (gradeDict[grade].ContainsKey(itemSubType))
+ var materialEquipment = GetCostumeFromId(materialId, avatarState, grade, itemSubType, addressesHex);
+ if (materialEquipment == null)
{
- gradeDict[grade][itemSubType]++;
- }
- else
- {
- gradeDict[grade][itemSubType] = 1;
+ throw new InvalidMaterialException(
+ $"{addressesHex} Aborted as the material item is not a equipment item type."
+ );
}
+
+ materialCostumes.Add(materialEquipment);
}
- else
- {
- gradeDict[grade] = new Dictionary
- {
- { itemSubType, 1 },
- };
- }
+
+ return materialCostumes;
}
- private static Equipment? GetEquipmentFromId(Guid materialId, AvatarState avatarState, long blockIndex, string addressesHex, ref ItemSubType? cachedItemSubType)
+ private static Equipment? GetEquipmentFromId(Guid materialId, AvatarState avatarState, Grade grade, ItemSubType itemSubType, long blockIndex, string addressesHex)
{
if (!avatarState.inventory.TryGetNonFungibleItem(materialId, out Equipment materialEquipment))
{
@@ -300,32 +264,31 @@ private static void SetGradeDict(ref GradeDict gradeDict, int grade, ItemSubType
}
// Validate item type
- if (!ValidItemType.Contains(materialEquipment.ItemType))
+ if (materialEquipment.ItemType != ItemType.Equipment)
{
throw new InvalidMaterialException(
$"{addressesHex} Aborted as the material item is not a valid item type: {materialEquipment.ItemType}."
);
}
- if (!ValidItemSubType.Contains(materialEquipment.ItemSubType))
+ if (materialEquipment.Grade != (int)grade)
{
throw new InvalidMaterialException(
- $"{addressesHex} Aborted as the material item is not a valid item sub type: {materialEquipment.ItemSubType}."
+ $"{addressesHex} Aborted as the material item is not a valid grade: {materialEquipment.Grade}."
);
}
- cachedItemSubType ??= materialEquipment.ItemSubType;
- if (materialEquipment.ItemSubType != cachedItemSubType)
+ if (materialEquipment.ItemSubType != itemSubType)
{
throw new InvalidMaterialException(
- $"{addressesHex} Aborted as the material item is not a {cachedItemSubType}, but {materialEquipment.ItemSubType}."
- );
+ $"{addressesHex} Aborted as the material item is not a valid item sub type: {materialEquipment.ItemSubType}."
+ );
}
return materialEquipment;
}
- private static Costume? GetCostumeFromId(Guid materialId, AvatarState avatarState, string addressesHex, ref ItemSubType? cachedItemSubType)
+ private static Costume? GetCostumeFromId(Guid materialId, AvatarState avatarState, Grade grade, ItemSubType itemSubType, string addressesHex)
{
if (!avatarState.inventory.TryGetNonFungibleItem(materialId, out Costume costumeItem))
{
@@ -333,26 +296,25 @@ private static void SetGradeDict(ref GradeDict gradeDict, int grade, ItemSubType
}
// Validate item type
- if (!ValidItemType.Contains(costumeItem.ItemType))
+ if (costumeItem.ItemType != ItemType.Costume)
{
throw new InvalidMaterialException(
$"{addressesHex} Aborted as the material item is not a valid item type: {costumeItem.ItemType}."
);
}
- if (!ValidItemSubType.Contains(costumeItem.ItemSubType))
+ if (costumeItem.Grade != (int)grade)
{
throw new InvalidMaterialException(
- $"{addressesHex} Aborted as the material item is not a valid item sub type: {costumeItem.ItemSubType}."
+ $"{addressesHex} Aborted as the material item is not a valid grade: {costumeItem.Grade}."
);
}
- cachedItemSubType ??= costumeItem.ItemSubType;
- if (costumeItem.ItemSubType != cachedItemSubType)
+ if (costumeItem.ItemSubType != itemSubType)
{
throw new InvalidMaterialException(
- $"{addressesHex} Aborted as the material item is not a {cachedItemSubType}, but {costumeItem.ItemSubType}."
- );
+ $"{addressesHex} Aborted as the material item is not a valid item sub type: {costumeItem.ItemSubType}."
+ );
}
return costumeItem;
@@ -403,7 +365,7 @@ private static ItemBase GetSynthesizedItem(
private static ItemBase GetRandomCostume(Grade grade, bool isSuccess, ItemSubType itemSubType, SynthesizeWeightSheet weightSheet, CostumeItemSheet costumeItemSheet, IRandom random)
{
- HashSet? synthesizeResultPool = null;
+ HashSet? synthesizeResultPool;
if (isSuccess)
{
synthesizeResultPool = GetSynthesizeResultPool(GetTargetGrade(grade), itemSubType, costumeItemSheet);
@@ -459,7 +421,7 @@ private static ItemBase GetRandomEquipment(
IRandom random,
ref EquipmentData equipmentData)
{
- HashSet? synthesizeResultPool = null;
+ HashSet? synthesizeResultPool;
if (isSuccess)
{
synthesizeResultPool = GetSynthesizeResultPool(GetTargetGrade(grade), itemSubType, equipmentItemSheet);
@@ -602,15 +564,15 @@ public static HashSet GetSynthesizeResultPool(Grade sourceGrade, ItemSubTyp
/// grades of material items
/// excepted FullCostume,Title
/// CostumeItemSheet to use
- /// list of items key(int)
- public static List GetSynthesizeResultPool(List sourceGrades, ItemSubType subType, CostumeItemSheet sheet)
+ /// list of items key(int), grade(Grade) tuple
+ public static HashSet<(int, Grade)> GetSynthesizeResultPool(HashSet sourceGrades, ItemSubType subType, CostumeItemSheet sheet)
{
return sheet
.Values
.Where(r => r.ItemSubType == subType)
- .Where(r => sourceGrades.Any(grade => (Grade)r.Grade == GetUpgradeGrade(grade, subType, sheet)))
- .Select(r => r.Id)
- .ToList();
+ .Where(r => sourceGrades.Any(grade => (Grade)r.Grade == grade))
+ .Select(r => (r.Id, (Grade)r.Grade))
+ .ToHashSet();
}
///
@@ -619,15 +581,15 @@ public static List GetSynthesizeResultPool(List sourceGrades, ItemSu
/// grades of material items
/// excepted Grimoire,Aura
/// EquipmentItemSheet to use
- /// list of items key(int)
- public static List GetSynthesizeResultPool(List sourceGrades, ItemSubType subType, EquipmentItemSheet sheet)
+ /// list of items key(int), grade(Grade) tuple
+ public static HashSet<(int, Grade)> GetSynthesizeResultPool(HashSet sourceGrades, ItemSubType subType, EquipmentItemSheet sheet)
{
return sheet
.Values
.Where(r => r.ItemSubType == subType)
- .Where(r => sourceGrades.Any(grade => (Grade)r.Grade == GetUpgradeGrade(grade, subType, sheet)))
- .Select(r => r.Id)
- .ToList();
+ .Where(r => sourceGrades.Any(grade => (Grade)r.Grade == grade))
+ .Select(r => (r.Id, (Grade)r.Grade))
+ .ToHashSet();
}
///
@@ -707,7 +669,14 @@ public static List GetItemGuids(IEnumerable itemBases) => itemBa
};
}).ToList();
- private static Grade GetTargetGrade(Grade grade) => grade switch
+ ///
+ /// Get the target grade of the item.
+ /// max grade is Divinity
+ ///
+ /// grade of the item
+ /// target grade
+ ///
+ public static Grade GetTargetGrade(Grade grade) => grade switch
{
Grade.Normal => Grade.Rare,
Grade.Rare => Grade.Epic,