support for random quantity box prize

- add ItemService.GetItemQuantity
- add ItemService.CheckAndOpenBox and new form of ItemService.OpenBox
- add runes to DT rewards
This commit is contained in:
Robert Paciorek 2023-09-08 21:08:27 +00:00 committed by Spirtix
parent e57e5ad44b
commit c6ad11b5d7
4 changed files with 77 additions and 45 deletions

View File

@ -620,15 +620,15 @@ public class ContentController : Controller {
} }
--invItem.Quantity; --invItem.Quantity;
// get real item id (from box) and add it to inventory // get real item id (from box) add it to inventory
ItemData boxItem = itemService.GetItem(req.ItemID); itemService.OpenBox(req.ItemID, out int newItemId, out int quantity);
ItemData newItem = itemService.GetItem(itemService.OpenBox(boxItem).ItemId); ItemData newItem = itemService.GetItem(newItemId);
CommonInventoryResponseItem newInvItem = inventoryService.AddItemToInventoryAndGetResponse(viking, newItem.ItemID, 1); CommonInventoryResponseItem newInvItem = inventoryService.AddItemToInventoryAndGetResponse(viking, newItem.ItemID, quantity);
// prepare list of possible rewards for response // prepare list of possible rewards for response
List<ItemData> prizeItems = new List<ItemData>(); List<ItemData> prizeItems = new List<ItemData>();
prizeItems.Add(newItem); prizeItems.Add(newItem);
foreach (var reward in boxItem.Relationship.Where(e => e.Type == "Prize")) { foreach (var reward in itemService.GetItem(req.ItemID).Relationship.Where(e => e.Type == "Prize")) {
if (prizeItems.Count >= req.RedeemItemFetchCount) if (prizeItems.Count >= req.RedeemItemFetchCount)
break; break;
prizeItems.Add(itemService.GetItem(reward.ItemId)); prizeItems.Add(itemService.GetItem(reward.ItemId));
@ -654,17 +654,23 @@ public class ContentController : Controller {
List<CommonInventoryResponseItem> items = new List<CommonInventoryResponseItem>(); List<CommonInventoryResponseItem> items = new List<CommonInventoryResponseItem>();
for (int i = 0; i < request.Items.Length; i++) { for (int i = 0; i < request.Items.Length; i++) {
int itemId = request.Items[i]; int itemId = request.Items[i];
if (itemService.IsBundleItem(itemId) && !request.AddMysteryBoxToInventory) { if (request.AddMysteryBoxToInventory) {
// force add boxes as item (without "opening")
items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1));
} else if (itemService.IsBundleItem(itemId)) {
// open and add bundle
ItemData bundleItem = itemService.GetItem(itemId); ItemData bundleItem = itemService.GetItem(itemId);
foreach (var reward in bundleItem.Relationship.Where(e => e.Type == "Bundle")) { foreach (var reward in bundleItem.Relationship.Where(e => e.Type == "Bundle")) {
int quantity = reward.Quantity; int quantity = itemService.GetItemQuantity(reward);
if (quantity == 0)
quantity = 1;
for (int j=0; j<quantity; ++j) for (int j=0; j<quantity; ++j)
items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, reward.ItemId, 1)); items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, reward.ItemId, 1));
} }
} else { } else {
items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1)); // check for mystery box ... open if need
itemService.CheckAndOpenBox(itemId, out itemId, out int quantity);
for (int j=0; j<quantity; ++j) {
items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1));
}
} }
// NOTE: The quantity of purchased items is always 0 and the items are instead duplicated in both the request and the response. // NOTE: The quantity of purchased items is always 0 and the items are instead duplicated in both the request and the response.
// Call AddItemToInventoryAndGetResponse with Quantity == 1 we get response with quantity == 0. // Call AddItemToInventoryAndGetResponse with Quantity == 1 we get response with quantity == 0.
@ -684,20 +690,19 @@ public class ContentController : Controller {
[VikingSession] [VikingSession]
public IActionResult PurchaseItemsV1(Viking viking, [FromForm] string itemIDArrayXml) { public IActionResult PurchaseItemsV1(Viking viking, [FromForm] string itemIDArrayXml) {
int[] itemIdArr = XmlUtil.DeserializeXml<int[]>(itemIDArrayXml); int[] itemIdArr = XmlUtil.DeserializeXml<int[]>(itemIDArrayXml);
CommonInventoryResponseItem[] items = new CommonInventoryResponseItem[itemIdArr.Length]; List<CommonInventoryResponseItem> items = new List<CommonInventoryResponseItem>();
for (int i = 0; i < itemIdArr.Length; i++) { for (int i = 0; i < itemIdArr.Length; i++) {
int itemId = itemIdArr[i]; itemService.CheckAndOpenBox(itemIdArr[i], out int itemId, out int quantity);
if (itemService.IsBoxItem(itemId)) { for (int j=0; j<quantity; ++j) {
itemId = itemService.OpenBox(itemId).ItemId; items.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1));
// NOTE: The quantity of purchased items is always 0 and the items are instead duplicated in both the request and the response.
// Call AddItemToInventoryAndGetResponse with Quantity == 1 we get response with quantity == 0.
} }
items[i] = inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1);
// NOTE: The quantity of purchased items is always 0 and the items are instead duplicated in both the request and the response.
// Call AddItemToInventoryAndGetResponse with Quantity == 1 we get response with quantity == 0.
} }
CommonInventoryResponse response = new CommonInventoryResponse { CommonInventoryResponse response = new CommonInventoryResponse {
Success = true, Success = true,
CommonInventoryIDs = items, CommonInventoryIDs = items.ToArray(),
UserGameCurrency = achievementService.GetUserCurrency(viking) UserGameCurrency = achievementService.GetUserCurrency(viking)
}; };
return Ok(response); return Ok(response);
@ -979,19 +984,13 @@ public class ContentController : Controller {
foreach (BluePrintSpecification output in blueprintItem.BluePrint.Outputs) { foreach (BluePrintSpecification output in blueprintItem.BluePrint.Outputs) {
if (output.ItemID is null) if (output.ItemID is null)
continue; continue;
// get new item info itemService.CheckAndOpenBox((int)(output.ItemID), out int newItemId, out int quantity);
int newItemId = (int)(output.ItemID); for (int i=0; i<quantity; ++i) {
ItemData newItemData = itemService.GetItem(newItemId); resItemList.Add(
inventoryService.AddBattleItemToInventory(viking, newItemId, (int)output.Tier)
// check for "box tickets" );
if (itemService.ItemHasCategory(newItemData, 462)) {
newItemId = itemService.OpenBox(newItemData).ItemId;
} }
resItemList.Add(
inventoryService.AddBattleItemToInventory(viking, newItemId, (int)output.Tier)
);
} }
// NOTE: saved inside AddBattleItemToInventory // NOTE: saved inside AddBattleItemToInventory
@ -1139,8 +1138,8 @@ public class ContentController : Controller {
ApplyRewardsRequest req = XmlUtil.DeserializeXml<ApplyRewardsRequest>(request); ApplyRewardsRequest req = XmlUtil.DeserializeXml<ApplyRewardsRequest>(request);
List<AchievementReward> achievementRewards = new List<AchievementReward>(); List<AchievementReward> achievementRewards = new List<AchievementReward>();
UserItemStatsMap? rewardedItem = null; UserItemStatsMap? rewardedBattleItem = null;
CommonInventoryResponse? rewardedBlueprint = null; CommonInventoryResponse? rewardedStandardItem = null;
int rewardMultipler = 0; int rewardMultipler = 0;
if (req.LevelRewardType == LevelRewardType.LevelFailure) { if (req.LevelRewardType == LevelRewardType.LevelFailure) {
@ -1175,23 +1174,26 @@ public class ContentController : Controller {
); );
} }
// - battle backpack items and blueprints // - battle backpack items, blueprints and other items
if (req.LevelRewardType != LevelRewardType.LevelFailure) { if (req.LevelRewardType != LevelRewardType.LevelFailure) {
Gender gender = XmlUtil.DeserializeXml<AvatarData>(viking.AvatarSerialized).GenderType; Gender gender = XmlUtil.DeserializeXml<AvatarData>(viking.AvatarSerialized).GenderType;
ItemData rewardItem = itemService.GetDTReward(gender); ItemData rewardItem = itemService.GetDTReward(gender);
if (itemService.ItemHasCategory(rewardItem, 651)) { if (itemService.ItemHasCategory(rewardItem, 651) || rewardItem.PossibleStatsMap is null) {
// blueprint // blueprint or no battle item (including box)
CommonInventoryResponseItem blueprintItem = inventoryService.AddItemToInventoryAndGetResponse(viking, rewardItem.ItemID, 1); List<CommonInventoryResponseItem> standardItems = new List<CommonInventoryResponseItem>();
rewardedBlueprint = new CommonInventoryResponse { itemService.CheckAndOpenBox(rewardItem.ItemID, out int itemId, out int quantity);
for (int i=0; i<quantity; ++i) {
standardItems.Add(inventoryService.AddItemToInventoryAndGetResponse(viking, itemId, 1));
// NOTE: client require single quantity items
}
rewardedStandardItem = new CommonInventoryResponse {
Success = true, Success = true,
CommonInventoryIDs = new CommonInventoryResponseItem[] { CommonInventoryIDs = standardItems.ToArray()
blueprintItem
}
}; };
} else { } else {
// DT item // DT item
InventoryItemStatsMap item = inventoryService.AddBattleItemToInventory(viking, rewardItem.ItemID, random.Next(1, 4)); InventoryItemStatsMap item = inventoryService.AddBattleItemToInventory(viking, rewardItem.ItemID, random.Next(1, 4));
rewardedItem = new UserItemStatsMap { rewardedBattleItem = new UserItemStatsMap {
Item = item.Item, Item = item.Item,
ItemStats = item.ItemStatsMap.ItemStats, ItemStats = item.ItemStatsMap.ItemStats,
ItemTier = item.ItemStatsMap.ItemTier, ItemTier = item.ItemStatsMap.ItemTier,
@ -1207,8 +1209,8 @@ public class ContentController : Controller {
return Ok(new ApplyRewardsResponse { return Ok(new ApplyRewardsResponse {
Status = Status.Success, Status = Status.Success,
AchievementRewards = achievementRewards.ToArray(), AchievementRewards = achievementRewards.ToArray(),
RewardedItemStatsMap = rewardedItem, RewardedItemStatsMap = rewardedBattleItem,
CommonInventoryResponse = rewardedBlueprint, CommonInventoryResponse = rewardedStandardItem,
}); });
} }

View File

@ -422,4 +422,10 @@
<int>16160</int> <int>16160</int>
<int>16209</int> <int>16209</int>
<int>16162</int> <int>16162</int>
<!-- runes (~0.95% probability) -->
<int>18794</int>
<int>18794</int>
<int>18794</int>
<int>18794</int>
</ArrayOfInt> </ArrayOfInt>

View File

@ -17,4 +17,7 @@ public class ItemDataRelationship
[XmlElement(ElementName = "q")] [XmlElement(ElementName = "q")]
public int Quantity; public int Quantity;
[XmlElement(ElementName = "mxq")]
public int? MaxQuantity;
} }

View File

@ -35,6 +35,16 @@ namespace sodoff.Services {
return items[itemID]; return items[itemID];
} }
public int GetItemQuantity(ItemDataRelationship itemData) {
if (itemData.MaxQuantity is null || itemData.MaxQuantity < 2 || itemData.MaxQuantity == itemData.Quantity) {
if (itemData.Quantity == 0)
return 1;
else
return itemData.Quantity;
}
return random.Next(1, (int)itemData.MaxQuantity + 1);
}
public ItemDataRelationship OpenBox(ItemData boxItem) { public ItemDataRelationship OpenBox(ItemData boxItem) {
var boxRewards = boxItem.Relationship.Where(e => e.Type == "Prize").ToArray(); var boxRewards = boxItem.Relationship.Where(e => e.Type == "Prize").ToArray();
int totalWeight = boxRewards.Sum(e => e.Weight); int totalWeight = boxRewards.Sum(e => e.Weight);
@ -52,8 +62,19 @@ namespace sodoff.Services {
return null; return null;
} }
public ItemDataRelationship OpenBox(int boxItemId) { public void OpenBox(int boxItemId, out int itemId, out int quantity) {
return OpenBox(items[boxItemId]); var reward = OpenBox(items[boxItemId]);
itemId = reward.ItemId;
quantity = GetItemQuantity(reward);
}
public void CheckAndOpenBox(int boxItemId, out int itemId, out int quantity) {
if (IsBoxItem(boxItemId)) {
OpenBox(boxItemId, out itemId, out quantity);
} else {
itemId = boxItemId;
quantity = 1;
}
} }
public bool IsBoxItem(int itemId) { public bool IsBoxItem(int itemId) {