Implement usetimereward, usepiece (#39)

* implement timereward

* implement usepiece

* will not grouping selectedCharacters

* remove unused field

* i forgot remove debug code

* maybe recycleroom worked

* fix Tid has 0 value

* add class research and corporation research

* delete unnecessary using

* rename args and local var

* fix receiving currency reward

* remove line from AddSingleCurrencyObject
This commit is contained in:
Ign1s_Reiga
2025-07-01 23:46:49 +09:00
committed by GitHub
parent 027f76d745
commit 6bf008146f
10 changed files with 511 additions and 50 deletions

View File

@@ -185,6 +185,17 @@ namespace EpinelPS.Data
public readonly Dictionary<int, LostSectorRecord> LostSector = []; public readonly Dictionary<int, LostSectorRecord> LostSector = [];
[LoadRecord("LostSectorStageTable.json", "id", typeof(LostSectorStageTable))] [LoadRecord("LostSectorStageTable.json", "id", typeof(LostSectorStageTable))]
public readonly Dictionary<int, LostSectorStageRecord> LostSectorStages = []; public readonly Dictionary<int, LostSectorStageRecord> LostSectorStages = [];
[LoadRecord("ItemPieceTable.json", "id", typeof(ItemPieceTable))]
public readonly Dictionary<int, ItemPieceRecord> PieceItems = [];
[LoadRecord("GachaGradeProbTable.json", "id", typeof(GachaGradeProbTable))]
public readonly Dictionary<int, GachaGradeProbRecord> GachaGradeProb = [];
[LoadRecord("GachaListProbTable.json", "id", typeof(GachaListProbTable))]
public readonly Dictionary<int, GachaListProbRecord> GachaListProb = [];
[LoadRecord("RecycleResearchStatTable.json", "id", typeof(RecycleResearchStatTable))]
public readonly Dictionary<int, RecycleResearchStatRecord> RecycleResearchStats = [];
[LoadRecord("RecycleResearchLevelTable.json", "id", typeof(RecycleResearchLevelTable))]
public readonly Dictionary<int, RecycleResearchLevelRecord> RecycleResearchLevels = [];
static async Task<GameData> BuildAsync() static async Task<GameData> BuildAsync()
{ {
await Load(); await Load();

View File

@@ -303,6 +303,30 @@
public List<GachaType> records = []; public List<GachaType> records = [];
} }
public class GachaGradeProbRecord
{
public int id;
public int group_id;
public string rare = "";
public int prob;
public int gacha_list_id;
}
public class GachaGradeProbTable
{
public List<GachaGradeProbRecord> records = [];
}
public class GachaListProbRecord
{
public int id;
public int group_id;
public int gacha_id;
}
public class GachaListProbTable
{
public List<GachaListProbRecord> records = [];
}
public class EventManager public class EventManager
{ {
public int id; public int id;
@@ -812,11 +836,23 @@
public string item_type = ""; public string item_type = "";
public ItemSubType item_sub_type; public ItemSubType item_sub_type;
public int use_id; public int use_id;
public int use_value;
} }
public class ItemConsumeTable public class ItemConsumeTable
{ {
public List<ItemConsumeRecord> records = []; public List<ItemConsumeRecord> records = [];
} }
public class ItemPieceRecord
{
public int id;
public string use_type = "";
public int use_id;
public int use_value;
}
public class ItemPieceTable
{
public List<ItemPieceRecord> records = [];
}
public class RandomItemRecord public class RandomItemRecord
{ {
public int id; public int id;
@@ -831,6 +867,33 @@
{ {
public List<RandomItemRecord> records = []; public List<RandomItemRecord> records = [];
} }
public class RecycleResearchStatRecord
{
public int id;
public string recycle_type = "";
public int unlock_condition_id;
public int unlock_level;
public int attack;
public int defense;
public int hp;
}
public class RecycleResearchStatTable
{
public List<RecycleResearchStatRecord> records = [];
}
public class RecycleResearchLevelRecord
{
public int id;
public string recycle_type = "";
public int recycle_level;
public int exp;
public int item_id;
public int item_value;
}
public class RecycleResearchLevelTable
{
public List<RecycleResearchLevelRecord> records = [];
}
public enum ContentOpenType public enum ContentOpenType
{ {
Stage, Stage,

View File

@@ -83,6 +83,14 @@ namespace EpinelPS.Database
/// </summary> /// </summary>
public long AvailableAt; public long AvailableAt;
} }
public class RecycleRoomResearchProgress
{
public int Level = 1;
public int Exp;
public int Attack;
public int Defense;
public int Hp;
}
public class SimroomData public class SimroomData
{ {
public int CurrentDifficulty; public int CurrentDifficulty;
@@ -266,6 +274,7 @@ namespace EpinelPS.Database
public List<SynchroSlot> SynchroSlots = new List<SynchroSlot>(); public List<SynchroSlot> SynchroSlots = new List<SynchroSlot>();
public bool SynchroDeviceUpgraded = false; public bool SynchroDeviceUpgraded = false;
public int SynchroDeviceLevel = 200; public int SynchroDeviceLevel = 200;
public Dictionary<int, RecycleRoomResearchProgress> ResearchProgress = [];
public ResetableData ResetableData = new(); public ResetableData ResetableData = new();
public WeeklyResetableData WeeklyResetableData = new(); public WeeklyResetableData WeeklyResetableData = new();
@@ -482,7 +491,7 @@ namespace EpinelPS.Database
var matchingCharacterIds = GameData.Instance.CharacterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet(); var matchingCharacterIds = GameData.Instance.CharacterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet();
// Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs // Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs
return Characters.Where(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)).First(); return Characters.Where(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)).FirstOrDefault();
} }
else else

View File

@@ -1,3 +1,5 @@
using EpinelPS.Data;
using EpinelPS.Database;
using EpinelPS.Utils; using EpinelPS.Utils;
namespace EpinelPS.LobbyServer.Inventory namespace EpinelPS.LobbyServer.Inventory
@@ -5,16 +7,204 @@ namespace EpinelPS.LobbyServer.Inventory
[PacketPath("/inventory/usepiece")] [PacketPath("/inventory/usepiece")]
public class UsePiece : LobbyMsgHandler public class UsePiece : LobbyMsgHandler
{ {
private static readonly Random random = new Random();
protected override async Task HandleAsync() protected override async Task HandleAsync()
{ {
// TODO: If this process takes too long, consider to avoid using function chain.
/*
* Req Contains:
* Isn: long value, the item serial number of the piece
* Count: int value, how many time
*/
var req = await ReadData<ReqUsePiece>(); var req = await ReadData<ReqUsePiece>();
var user = GetUser(); var user = GetUser();
var response = new ResUsePiece(); var response = new ResUsePiece();
// TODO var piece = user.Items.FirstOrDefault(x => x.Isn == req.Isn) ?? throw new InvalidDataException("cannot find piece with isn " + req.Isn);
if (req.Count * 50 > piece.Count) throw new Exception("count mismatch");
piece.Count -= req.Count * 50;
if (piece.Count == 0) user.Items.Remove(piece);
ItemPieceRecord? pItem = GameData.Instance.PieceItems
.FirstOrDefault(x => x.Value.id == piece.ItemType).Value
?? throw new Exception("cannot find piece id " + piece.ItemType);
var probList = GameData.Instance.GachaGradeProb
.Where(x => x.Key == pItem.use_id)
.SelectMany(grade => GameData.Instance.GachaListProb.Where(list => list.Value.group_id == grade.Value.gacha_list_id))
.Select(i => i.Value);
var allCharacters = probList.SelectMany(e => GameData.Instance.CharacterTable.Values.Where(c => c.id == e.gacha_id));
NetRewardData reward = new();
var selectedCharacters = Enumerable.Range(1, req.Count)
.Select(_ => SelectRandomCharacter(allCharacters, pItem.id));
int totalBodyLabels = 0;
foreach (var character in selectedCharacters)
{
ItemData? spareItem = user.Items.FirstOrDefault(i => i.ItemType == character.piece_id);
if (user.GetCharacter(character.id) is Database.Character ownedCharacter)
{
// If the character already exists, we can increase its piece count
int maxLimitBroken = GetValueByRarity(character.original_rare, 0, 2, 11);
bool canIncreaseItem = character.original_rare != "R" && ownedCharacter.Grade + (spareItem?.Count ?? 0) < maxLimitBroken;
(int newSpareItemCount, int dissoluteCharacterCount) = canIncreaseItem ? (1, 0) : (0, 1);
if (canIncreaseItem)
{
if (spareItem != null)
{
spareItem.Count = newSpareItemCount;
}
else
{
spareItem = new()
{
ItemType = character.piece_id,
Csn = 0,
Count = newSpareItemCount,
Level = 0,
Exp = 0,
Position = 0,
Corp = 0,
Isn = user.GenerateUniqueItemId()
};
user.Items.Add(spareItem);
}
reward.UserItems.Add(NetUtils.UserItemDataToNet(spareItem));
reward.Character.Add(GetNetCharacterData(ownedCharacter));
}
else
{
// If we cannot increase the item, we give body label instead
int bodyLabel = GetValueByRarity(character.original_rare, 150, 200, 6000);
totalBodyLabels += bodyLabel * dissoluteCharacterCount;
reward.Character.Add(GetNetCharacterData(ownedCharacter, bodyLabel));
}
}
else
{
var csn = user.GenerateUniqueCharacterId();
reward.UserCharacters.Add(new NetUserCharacterDefaultData
{
CostumeId = 0,
Csn = csn,
Grade = 0,
Lv = 1,
Skill1Lv = 1,
Skill2Lv = 1,
Tid = character.id,
UltiSkillLv = 1
});
reward.Character.Add(new NetCharacterData
{
Csn = user.GenerateUniqueCharacterId(),
Tid = character.id,
});
user.Characters.Add(new Database.Character
{
CostumeId = 0,
Csn = csn,
Grade = 0,
Level = 1,
Skill1Lvl = 1,
Skill2Lvl = 1,
Tid = character.id,
UltimateLevel = 1
});
// Add "New Character" Badge
user.AddBadge(BadgeContents.NikkeNew, character.name_code.ToString());
user.AddTrigger(TriggerType.ObtainCharacter, 1, character.name_code);
if (character.original_rare == "SSR")
{
user.AddTrigger(TriggerType.ObtainCharacterSSR, 1);
}
else
{
user.AddTrigger(TriggerType.ObtainCharacterNew, 1);
}
if (character.original_rare == "SSR" || character.original_rare == "SR")
{
user.BondInfo.Add(new() { NameCode = character.name_code, Lv = 1 });
}
}
user.AddTrigger(TriggerType.GachaCharacter, 0, 0);
}
reward.Currency.Add(new NetCurrencyData() { Type = (int)CurrencyType.DissolutionPoint, Value = totalBodyLabels });
user.AddCurrency(CurrencyType.DissolutionPoint, totalBodyLabels);
reward.UserItems.Add(NetUtils.UserItemDataToNet(piece));
response.Reward = reward;
JsonDb.Save();
await WriteDataAsync(response); await WriteDataAsync(response);
} }
private CharacterRecord SelectRandomCharacter(IEnumerable<CharacterRecord> characters, int pieceId)
{
var gradeProb = GetPieceGradeProb(pieceId);
var rCharacters = characters.Where(c => c.original_rare == "R");
var srCharacters = characters.Where(c => c.original_rare == "SR");
var ssrCharacters = characters.Where(c => c.original_rare == "SSR");
double roll = random.NextDouble() * 100;
if (0.0 < gradeProb.RProb && roll < gradeProb.RProb && rCharacters.Any())
{
return rCharacters.ElementAt(random.Next(rCharacters.Count()));
}
else if (0.0 < gradeProb.SRProb && roll < gradeProb.RProb + gradeProb.SRProb && srCharacters.Any())
{
return srCharacters.ElementAt(random.Next(srCharacters.Count()));
}
else if (0.0 < gradeProb.SSRProb && roll < gradeProb.RProb + gradeProb.SRProb + gradeProb.SSRProb && ssrCharacters.Any())
{
return ssrCharacters.ElementAt(random.Next(ssrCharacters.Count()));
}
else
{
throw new Exception("No characters available for the given value.");
} }
} }
// TODO: find the file where the grade probability is stored.
// TODO: Add Helm Mold and Laplace Mold
private PieceGradeProb GetPieceGradeProb(int pieceId) => pieceId switch
{
5310301 => new PieceGradeProb(0.0, 38.9997, 61.0003), // High quality Mold
5310302 or 5310303 or 5310304 or 5310305 => new PieceGradeProb(19.9998, 29.9997, 50.0005), // Manufacturer Mold
5310306 or 5310307 or 5310308 or 5310309 => new PieceGradeProb(0.0, 0.0, 100.0), // New Commander Mold or Perfect Mold
5330201 or 5359001 => new PieceGradeProb(0.0, 78.9993, 21.0007), // Mid quality Mold
_ => throw new Exception("unknown piece id")
};
private int GetValueByRarity(string rarity, int rValue, int srValue, int ssrValue) => rarity switch
{
"R" => rValue,
"SR" => srValue,
"SSR" => ssrValue,
_ => throw new Exception($"Unknown character rarity: {rarity}")
};
private NetCharacterData GetNetCharacterData(Database.Character character, int bodyLabel = 0)
{
return new NetCharacterData
{
Csn = character.Csn,
Tid = character.Tid,
PieceCount = bodyLabel == 0 ? 1 : 0,
CurrencyValue = bodyLabel
};
}
}
internal record PieceGradeProb(double RProb, double SRProb, double SSRProb);
}

View File

@@ -0,0 +1,52 @@
using EpinelPS.Data;
using EpinelPS.Database;
using EpinelPS.Utils;
namespace EpinelPS.LobbyServer.Inventory
{
[PacketPath("/inventory/usetimereward")]
public class UseTimeReward : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
/*
* Req Contains:
* Isn: long value
* Count: int value, how many items to use
*/
var req = await ReadData<ReqUseTimeReward>();
var user = GetUser();
var response = new ResUseTimeReward();
var timeReward = user.Items.Where(x => x.Isn == req.Isn).FirstOrDefault() ?? throw new InvalidDataException("cannot find time reward with isn " + req.Isn);
if (req.Count > timeReward.Count) throw new Exception("count mismatch");
timeReward.Count -= req.Count;
if (timeReward.Count == 0) user.Items.Remove(timeReward);
ItemConsumeRecord? cItem = GameData.Instance.ConsumableItems
.FirstOrDefault(x => x.Value.id == timeReward.ItemType).Value
?? throw new Exception("cannot find box id " + timeReward.ItemType);
// TODO: find out where these numbers come from
(CurrencyType itemType, long amount) = cItem.use_id switch
{
1 => (CurrencyType.Gold, NetUtils.GetOutpostRewardAmount(user, CurrencyType.Gold, TimeSpan.FromSeconds(cItem.use_value).TotalMinutes, false)),
2 => (CurrencyType.CharacterExp, NetUtils.GetOutpostRewardAmount(user, CurrencyType.CharacterExp, TimeSpan.FromSeconds(cItem.use_value).TotalMinutes, false)),
4 => (CurrencyType.CharacterExp2, NetUtils.GetOutpostRewardAmount(user, CurrencyType.CharacterExp2, TimeSpan.FromSeconds(cItem.use_value).TotalMinutes, false)),
_ => throw new Exception("unknown use_id " + cItem.use_id)
};
NetRewardData reward = new();
RewardUtils.AddSingleCurrencyObject(user, ref reward, itemType, amount);
response.Reward = reward;
// update client side item count
response.Reward.UserItems.Add(NetUtils.UserItemDataToNet(timeReward));
JsonDb.Save();
await WriteDataAsync(response);
}
}
}

View File

@@ -1,4 +1,5 @@
using EpinelPS.Utils; using EpinelPS.Database;
using EpinelPS.Utils;
namespace EpinelPS.LobbyServer.Outpost namespace EpinelPS.LobbyServer.Outpost
{ {
@@ -8,10 +9,19 @@ namespace EpinelPS.LobbyServer.Outpost
protected override async Task HandleAsync() protected override async Task HandleAsync()
{ {
var req = await ReadData<ReqGetRecycleRoomData>(); var req = await ReadData<ReqGetRecycleRoomData>();
var user = GetUser();
// TODO: save these things
var response = new ResGetRecycleRoomData(); var response = new ResGetRecycleRoomData();
response.Recycle.AddRange(user.ResearchProgress.Select(progress =>
{
return new NetUserRecycleRoomData()
{
Tid = progress.Key,
Lv = progress.Value.Level,
Exp = progress.Value.Exp
};
}));
await WriteDataAsync(response); await WriteDataAsync(response);
} }
} }

View File

@@ -0,0 +1,108 @@
using EpinelPS.Data;
using EpinelPS.Database;
using EpinelPS.Utils;
namespace EpinelPS.LobbyServer.Outpost.Recycle
{
[PacketPath("/outpost/RecycleRoom/LevelUpResearch")]
public class LevelUpResearch : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
/*
* Req Contains:
* Tid: int value, research tid
* Items: int value, used items.
*/
var req = await ReadData<ReqRecycleLevelUpResearch>();
var user = GetUser();
var response = new ResRecycleLevelUpResearch();
user.ResearchProgress.TryGetValue(req.Tid, out var progress);
// Check progress is null, null means research is not unlocked.
if (progress != null)
{
AddProgressToResearch(response, user, progress, req);
}
JsonDb.Save();
await WriteDataAsync(response);
}
private void AddProgressToResearch(ResRecycleLevelUpResearch response, User user, RecycleRoomResearchProgress progress, ReqRecycleLevelUpResearch req)
{
GameData.Instance.RecycleResearchStats.TryGetValue(req.Tid, out var statRecord);
if (statRecord is null)
return;
var levelRecord = GameData.Instance.RecycleResearchLevels.Values.Where(e => e.recycle_type == statRecord.recycle_type)
.FirstOrDefault(e => e.recycle_level == progress.Level);
if (levelRecord is null)
return;
if (statRecord.recycle_type == "Personal") // main research
{
var usedItem = user.Items.FirstOrDefault(e => e.ItemType == levelRecord.item_id); // item_id equals level-up item's tid.
if (usedItem is null || usedItem.Count < levelRecord.item_value)
return;
usedItem.Count -= levelRecord.item_value;
response.Items.Add(NetUtils.UserItemDataToNet(usedItem));
progress.Level += 1;
progress.Hp = statRecord.hp * progress.Level;
response.Recycle = new()
{
Tid = req.Tid,
Lv = progress.Level,
};
}
else if (statRecord.recycle_type == "Class" || statRecord.recycle_type == "Corporation") // class research or corporation research
{
var netItem = req.Items.Single();
var usedItem = user.Items.FirstOrDefault(e => e.ItemType == netItem.Tid);
if (usedItem is null)
return;
usedItem.Count -= netItem.Count;
response.Items.Add(NetUtils.UserItemDataToNet(usedItem));
(int newLevel, int newExp) = CalcCorpAndClassLevelUp(statRecord.recycle_type, netItem.Count, progress.Level, progress.Exp);
progress.Level = newLevel;
progress.Exp = newExp;
response.Recycle = new()
{
Tid = req.Tid,
Lv = newLevel,
Exp = newExp,
};
}
else
{
throw new Exception($"unknown recycle type {statRecord.recycle_type}");
}
}
// First: level, Second: exp
private (int, int) CalcCorpAndClassLevelUp(string researchType, int itemCount, int startLevel = 1, int startExp = 0)
{
// levelRecord.exp is required exp to level up.
var levelRecords = GameData.Instance.RecycleResearchLevels.Values.Where(e => e.recycle_type == researchType && e.recycle_level > startLevel);
foreach (var record in levelRecords)
{
if (itemCount < record.exp)
{
startExp += itemCount;
break;
}
itemCount -= record.exp - startExp;
startLevel += 1;
startExp = 0;
}
return (startLevel, startExp);
}
}
}

View File

@@ -1,9 +1,6 @@
using EpinelPS.Data;
using EpinelPS.Database;
using EpinelPS.Utils; using EpinelPS.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EpinelPS.LobbyServer.Outpost.Recycle namespace EpinelPS.LobbyServer.Outpost.Recycle
{ {
@@ -13,9 +10,32 @@ namespace EpinelPS.LobbyServer.Outpost.Recycle
protected override async Task HandleAsync() protected override async Task HandleAsync()
{ {
var req = await ReadData<ReqRecycleRunResearch>(); var req = await ReadData<ReqRecycleRunResearch>();
var user = GetUser();
var response = new ResRecycleRunResearch(); var response = new ResRecycleRunResearch();
// TODO
user.ResearchProgress.TryGetValue(req.Tid, out var progress);
// Check progress is null, non-null means research is already unlocked.
if (progress is null)
{
var researchRecord = GameData.Instance.RecycleResearchStats.Values.FirstOrDefault(e => e.id == req.Tid)
?? throw new Exception("not found research record with tid " + req.Tid);
progress = new()
{
Attack = researchRecord.attack,
Defense = researchRecord.defense,
Hp = researchRecord.hp,
};
user.ResearchProgress.Add(req.Tid, progress);
}
response.Recycle = new()
{
Tid = req.Tid,
Lv = progress.Level,
Exp = progress.Exp,
};
JsonDb.Save();
await WriteDataAsync(response); await WriteDataAsync(response);
} }

View File

@@ -393,6 +393,9 @@ namespace EpinelPS.Utils
Logging.WriteLine("TODO: reward_value_max", LogType.Warning); Logging.WriteLine("TODO: reward_value_max", LogType.Warning);
} }
if (winningRecord.reward_type == "Currency")
RewardUtils.AddSingleCurrencyObject(user, ref ret, (CurrencyType)winningRecord.reward_id, winningRecord.reward_value_min);
else
RewardUtils.AddSingleObject(user, ref ret, winningRecord.reward_id, winningRecord.reward_type, winningRecord.reward_value_min); RewardUtils.AddSingleObject(user, ref ret, winningRecord.reward_id, winningRecord.reward_type, winningRecord.reward_value_min);
} }
JsonDb.Save(); JsonDb.Save();

View File

@@ -72,6 +72,12 @@ namespace EpinelPS.Utils
foreach (var item in rewardData.rewards) foreach (var item in rewardData.rewards)
{ {
if (!string.IsNullOrEmpty(item.reward_type)) if (!string.IsNullOrEmpty(item.reward_type))
{
if (item.reward_type == "Currency")
{
AddSingleCurrencyObject(user, ref ret, (CurrencyType)item.reward_id, item.reward_value);
}
else
{ {
if (item.reward_percent != 1000000) if (item.reward_percent != 1000000)
{ {
@@ -81,9 +87,29 @@ namespace EpinelPS.Utils
AddSingleObject(user, ref ret, item.reward_id, item.reward_type, item.reward_value); AddSingleObject(user, ref ret, item.reward_id, item.reward_type, item.reward_value);
} }
} }
}
return ret; return ret;
} }
public static void AddSingleCurrencyObject(User user, ref NetRewardData ret, CurrencyType currencyType, long rewardCount)
{
bool found = user.Currency.Any(pair => pair.Key == currencyType);
if (found)
{
user.Currency[currencyType] += rewardCount;
}
else
{
user.Currency.Add(currencyType, rewardCount);
}
ret.Currency.Add(new NetCurrencyData()
{
FinalValue = found ? user.GetCurrencyVal(currencyType) : rewardCount,
Value = rewardCount,
Type = (int)currencyType
});
}
/// <summary> /// <summary>
/// Adds a single item to users inventory, and also adds it to ret parameter. /// Adds a single item to users inventory, and also adds it to ret parameter.
/// </summary> /// </summary>
@@ -98,37 +124,6 @@ namespace EpinelPS.Utils
if (rewardId != 0 || !string.IsNullOrEmpty(rewardType)) if (rewardId != 0 || !string.IsNullOrEmpty(rewardType))
{ {
if (string.IsNullOrEmpty(rewardType) || string.IsNullOrWhiteSpace(rewardType)) { } if (string.IsNullOrEmpty(rewardType) || string.IsNullOrWhiteSpace(rewardType)) { }
else if (rewardType == "Currency")
{
bool found = false;
foreach (var currentReward in user.Currency)
{
if (currentReward.Key == (CurrencyType)rewardId)
{
user.Currency[currentReward.Key] += rewardCount;
ret.Currency.Add(new NetCurrencyData()
{
FinalValue = user.Currency[currentReward.Key],
Value = rewardCount,
Type = rewardId
});
found = true;
break;
}
}
if (!found)
{
user.Currency.Add((CurrencyType)rewardId, rewardCount);
ret.Currency.Add(new NetCurrencyData()
{
FinalValue = rewardCount,
Value = rewardCount,
Type = rewardId
});
}
}
else if (rewardType == "Item" || rewardType.StartsWith("Equipment_")) else if (rewardType == "Item" || rewardType.StartsWith("Equipment_"))
{ {
// Check if user already has said item. If it is level 1, increase item count. // Check if user already has said item. If it is level 1, increase item count.