diff --git a/EpinelPS/Data/GameData.cs b/EpinelPS/Data/GameData.cs index d70016c..7bfd82b 100644 --- a/EpinelPS/Data/GameData.cs +++ b/EpinelPS/Data/GameData.cs @@ -44,7 +44,7 @@ namespace EpinelPS.Data public readonly Dictionary StageDataRecords = []; [LoadRecord("RewardTable.json", "id")] - public readonly Dictionary RewardDataRecords = []; + public readonly Dictionary RewardDataRecords = []; [LoadRecord("UserExpTable.json", "level")] public readonly Dictionary UserExpDataRecords = []; @@ -518,7 +518,7 @@ namespace EpinelPS.Data { return StageDataRecords[stage]; } - public RewardTableRecord? GetRewardTableEntry(int rewardId) + public RewardRecord? GetRewardTableEntry(int rewardId) { return RewardDataRecords[rewardId]; } diff --git a/EpinelPS/Data/JsonStaticData.cs b/EpinelPS/Data/JsonStaticData.cs index 988f0cf..fc75679 100644 --- a/EpinelPS/Data/JsonStaticData.cs +++ b/EpinelPS/Data/JsonStaticData.cs @@ -134,14 +134,56 @@ namespace EpinelPS.Data public int characterLevel; } [MemoryPackable] - public partial class RewardTableRecord + public partial class RewardRecord { public int id; public int user_exp; public int character_exp; - public RewardEntry[]? rewards; + public List rewards = []; } + public enum PercentDisplayType + { + None, + Percent, + Random + } + public enum RewardType + { + None = 0, + User_exp = 1, + Char_exp = 2, + Currency = 3, + Character = 4, + Item = 5, + Frame = 6, + AttractivePoint = 7, + Bgm = 8, + Point = 9, + LiveWallpaper = 10, + Memorial = 11, + CharacterCostume = 12, + ItemRandom = 13, + InfraCoreExp = 14, + ItemRandomBox = 15, + Equipment_None = 16, + Equipment_MISSILIS = 17, + Equipment_ELYSION = 18, + Equipment_TETRA = 19, + Equipment_PILGRIM = 20, + Equipment_Random_01 = 21, + Equipment_Random_02 = 22, + Equipment_Random_03 = 23, + PassPoint = 41, + Equipment_ABNORMAL = 42, + FavoriteItem = 43, + ProfileCardObject = 44, + ProfileRandomBox = 45, + UserTitle = 46, + LobbyDecoBackground = 47 + } + + [MemoryPackable] public partial class RewardEntry { @@ -149,8 +191,8 @@ namespace EpinelPS.Data /// example: 1000000 /// public int reward_percent; - public string percent_display_type = ""; - public string reward_type = ""; + public PercentDisplayType percent_display_type; + public RewardType reward_type; public int reward_id; public int reward_value; } @@ -202,12 +244,33 @@ namespace EpinelPS.Data public string lesson_type = ""; public TacticAcademyLessonReward[]? lesson_reward; } + public enum OpenType + { + Open, + NonUpdate + } + + public enum ChapterGuideType + { + None, + Tutorial, + Common + } + [MemoryPackable] public partial class CampaignChapterRecord { public int id; + public string name_localized = ""; + public string description_localized = ""; + public int world; public int chapter; + public OpenType openType; + public DateTime openTime; + public ChapterGuideType chapter_guide; + public string chapter_image = ""; + public string hard_chapter_image = ""; public string field_id = ""; public string hard_field_id = ""; } @@ -878,7 +941,7 @@ namespace EpinelPS.Data { public int id; public int group_id; - public string reward_type = ""; + public RewardType reward_type; public int reward_id; public int reward_value_min; public int reward_value_max; diff --git a/EpinelPS/LobbyServer/Campaign/ObtainItem.cs b/EpinelPS/LobbyServer/Campaign/ObtainItem.cs index afa77e6..f944dfe 100644 --- a/EpinelPS/LobbyServer/Campaign/ObtainItem.cs +++ b/EpinelPS/LobbyServer/Campaign/ObtainItem.cs @@ -38,7 +38,7 @@ namespace EpinelPS.LobbyServer.Campaign ItemSpawner position = map.ItemSpawner.Where(x => x.positionId == req.FieldObject.PositionId).FirstOrDefault() ?? throw new Exception("bad position id"); FieldItemRecord positionReward = GameData.Instance.FieldItems[position.itemId]; - RewardTableRecord reward = GameData.Instance.GetRewardTableEntry(positionReward.type_value) ?? throw new Exception("failed to get reward"); + RewardRecord reward = GameData.Instance.GetRewardTableEntry(positionReward.type_value) ?? throw new Exception("failed to get reward"); response.Reward = RewardUtils.RegisterRewardsForUser(user, reward); // Hide it from the field diff --git a/EpinelPS/LobbyServer/Character/ObtainEpReward.cs b/EpinelPS/LobbyServer/Character/ObtainEpReward.cs index 7d0c8fa..daba0bb 100644 --- a/EpinelPS/LobbyServer/Character/ObtainEpReward.cs +++ b/EpinelPS/LobbyServer/Character/ObtainEpReward.cs @@ -24,7 +24,7 @@ namespace EpinelPS.LobbyServer.Character { item.ObtainedRewardLevels.Add(levelUpRecord.Value.id); - RewardTableRecord reward = GameData.Instance.GetRewardTableEntry(levelUpRecord.Value.reward_id) ?? throw new Exception("failed to get reward"); + RewardRecord reward = GameData.Instance.GetRewardTableEntry(levelUpRecord.Value.reward_id) ?? throw new Exception("failed to get reward"); response.Reward = RewardUtils.RegisterRewardsForUser(user, reward); JsonDb.Save(); diff --git a/EpinelPS/LobbyServer/FavoriteItem/ObtainFavoriteItemQuestReward.cs b/EpinelPS/LobbyServer/FavoriteItem/ObtainFavoriteItemQuestReward.cs index 5945457..e378e66 100644 --- a/EpinelPS/LobbyServer/FavoriteItem/ObtainFavoriteItemQuestReward.cs +++ b/EpinelPS/LobbyServer/FavoriteItem/ObtainFavoriteItemQuestReward.cs @@ -39,8 +39,8 @@ namespace EpinelPS.LobbyServer.FavoriteItem characterCsn = character.Csn; } - RewardTableRecord ? reward = GameData.Instance.GetRewardTableEntry(questData.reward_id); - if (reward?.rewards == null || reward.rewards.Length == 0 || reward.rewards[0].reward_type != "FavoriteItem") + RewardRecord ? reward = GameData.Instance.GetRewardTableEntry(questData.reward_id); + if (reward?.rewards == null || reward.rewards.Count == 0 || reward.rewards[0].reward_type != RewardType.FavoriteItem) { if (questData.reward_id > 0 && reward != null) { diff --git a/EpinelPS/LobbyServer/Messenger/FinishSubquest.cs b/EpinelPS/LobbyServer/Messenger/FinishSubquest.cs index e3ff1d5..a521098 100644 --- a/EpinelPS/LobbyServer/Messenger/FinishSubquest.cs +++ b/EpinelPS/LobbyServer/Messenger/FinishSubquest.cs @@ -17,7 +17,7 @@ namespace EpinelPS.LobbyServer.Messenger KeyValuePair opener = GameData.Instance.Subquests.Where(x => x.Key == req.SubQuestId).First(); KeyValuePair conversation = GameData.Instance.Messages.Where(x => x.Value.id == req.MessageId).First(); - RewardTableRecord rewardRecord = GameData.Instance.GetRewardTableEntry(conversation.Value.reward_id) ?? throw new Exception("unable to lookup reward"); + RewardRecord rewardRecord = GameData.Instance.GetRewardTableEntry(conversation.Value.reward_id) ?? throw new Exception("unable to lookup reward"); user.SetSubQuest(req.SubQuestId, true); diff --git a/EpinelPS/LobbyServer/Minigame/InTheMirror/GetStartMvgNewGamePlus.cs b/EpinelPS/LobbyServer/Minigame/InTheMirror/GetStartMvgNewGamePlus.cs index aa8c388..5895824 100644 --- a/EpinelPS/LobbyServer/Minigame/InTheMirror/GetStartMvgNewGamePlus.cs +++ b/EpinelPS/LobbyServer/Minigame/InTheMirror/GetStartMvgNewGamePlus.cs @@ -20,7 +20,7 @@ namespace EpinelPS.LobbyServer.Minigame.InTheMirror { foreach (var rewardEntry in GameData.Instance.RewardDataRecords[quest.reward_id].rewards ??= []) { - if (!string.IsNullOrEmpty(rewardEntry.reward_type)) + if (rewardEntry.reward_type != RewardType.None) { switch (rewardEntry.reward_id) { diff --git a/EpinelPS/LobbyServer/Mission/ObtainAchievement.cs b/EpinelPS/LobbyServer/Mission/ObtainAchievement.cs index 5a08e31..0b0c538 100644 --- a/EpinelPS/LobbyServer/Mission/ObtainAchievement.cs +++ b/EpinelPS/LobbyServer/Mission/ObtainAchievement.cs @@ -24,7 +24,7 @@ namespace EpinelPS.LobbyServer.Mission if (!GameData.Instance.TriggerTable.TryGetValue(item, out TriggerRecord? key)) throw new Exception("unknown TID"); - RewardTableRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); + RewardRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); NetRewardData reward = RewardUtils.RegisterRewardsForUser(user, rewardRecord); rewards.Add(reward); diff --git a/EpinelPS/LobbyServer/Mission/ObtainDaily.cs b/EpinelPS/LobbyServer/Mission/ObtainDaily.cs index de6c74e..45dd758 100644 --- a/EpinelPS/LobbyServer/Mission/ObtainDaily.cs +++ b/EpinelPS/LobbyServer/Mission/ObtainDaily.cs @@ -33,7 +33,7 @@ namespace EpinelPS.LobbyServer.Mission if (key.reward_id != 0) { // Actual reward - RewardTableRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); + RewardRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); rewards.Add(RewardUtils.RegisterRewardsForUser(user, rewardRecord)); } else diff --git a/EpinelPS/LobbyServer/Mission/ObtainWeekly.cs b/EpinelPS/LobbyServer/Mission/ObtainWeekly.cs index 5012d37..89bb4a7 100644 --- a/EpinelPS/LobbyServer/Mission/ObtainWeekly.cs +++ b/EpinelPS/LobbyServer/Mission/ObtainWeekly.cs @@ -29,7 +29,7 @@ namespace EpinelPS.LobbyServer.Mission if (key.reward_id != 0) { // Actual reward - RewardTableRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); + RewardRecord rewardRecord = GameData.Instance.GetRewardTableEntry(key.reward_id) ?? throw new Exception("unable to lookup reward"); rewards.Add(RewardUtils.RegisterRewardsForUser(user, rewardRecord)); } else diff --git a/EpinelPS/LobbyServer/Sidestory/ClearSideStoryStage.cs b/EpinelPS/LobbyServer/Sidestory/ClearSideStoryStage.cs index eb7e390..edfcdd6 100644 --- a/EpinelPS/LobbyServer/Sidestory/ClearSideStoryStage.cs +++ b/EpinelPS/LobbyServer/Sidestory/ClearSideStoryStage.cs @@ -21,7 +21,7 @@ namespace EpinelPS.LobbyServer.Sidestory if (GameData.Instance.SidestoryRewardTable.TryGetValue(req.SideStoryStageId, out SideStoryStageRecord? value)) { - RewardTableRecord? rewardData = GameData.Instance.GetRewardTableEntry(value.first_clear_reward); + RewardRecord? rewardData = GameData.Instance.GetRewardTableEntry(value.first_clear_reward); if (rewardData != null) response.Reward = RewardUtils.RegisterRewardsForUser(user, rewardData); diff --git a/EpinelPS/LobbyServer/Stage/ClearStage.cs b/EpinelPS/LobbyServer/Stage/ClearStage.cs index 0283446..7193f23 100644 --- a/EpinelPS/LobbyServer/Stage/ClearStage.cs +++ b/EpinelPS/LobbyServer/Stage/ClearStage.cs @@ -42,7 +42,7 @@ namespace EpinelPS.LobbyServer.Stage } DoQuestSpecificUserOperations(user, StageId); - RewardTableRecord? rewardData = GameData.Instance.GetRewardTableEntry(clearedStage.reward_id); + RewardRecord? rewardData = GameData.Instance.GetRewardTableEntry(clearedStage.reward_id); if (forceCompleteScenarios) { diff --git a/EpinelPS/LobbyServer/Tower/ClearTower.cs b/EpinelPS/LobbyServer/Tower/ClearTower.cs index 1fb99a6..bfd49da 100644 --- a/EpinelPS/LobbyServer/Tower/ClearTower.cs +++ b/EpinelPS/LobbyServer/Tower/ClearTower.cs @@ -63,7 +63,7 @@ namespace EpinelPS.LobbyServer.Tower user.AddTrigger(TriggerType.TowerBasicClear, TowerId); } - RewardTableRecord reward = GameData.Instance.GetRewardTableEntry(record.reward_id) ?? throw new Exception("failed to get reward"); + RewardRecord reward = GameData.Instance.GetRewardTableEntry(record.reward_id) ?? throw new Exception("failed to get reward"); response.Reward = RewardUtils.RegisterRewardsForUser(user, reward); diff --git a/EpinelPS/LobbyServer/Trigger/ObtainMainQuestReward.cs b/EpinelPS/LobbyServer/Trigger/ObtainMainQuestReward.cs index 56242c6..f68ebc0 100644 --- a/EpinelPS/LobbyServer/Trigger/ObtainMainQuestReward.cs +++ b/EpinelPS/LobbyServer/Trigger/ObtainMainQuestReward.cs @@ -29,7 +29,7 @@ namespace EpinelPS.LobbyServer.Trigger user.MainQuestData[item.Key] = true; MainQuestCompletionRecord? questInfo = GameData.Instance.GetMainQuestByTableId(item.Key) ?? throw new Exception("failed to lookup quest id " + item.Key); - RewardTableRecord? reward = GameData.Instance.GetRewardTableEntry(questInfo.reward_id) ?? throw new Exception("failed to lookup reward id " + questInfo.reward_id); + RewardRecord? reward = GameData.Instance.GetRewardTableEntry(questInfo.reward_id) ?? throw new Exception("failed to lookup reward id " + questInfo.reward_id); rewards.Add(RewardUtils.RegisterRewardsForUser(user, reward)); } } diff --git a/EpinelPS/Utils/NetUtils.cs b/EpinelPS/Utils/NetUtils.cs index 81fa16b..11f3a63 100644 --- a/EpinelPS/Utils/NetUtils.cs +++ b/EpinelPS/Utils/NetUtils.cs @@ -1,427 +1,427 @@ -using System.Collections; -using System.Collections.Generic; -using EpinelPS.Data; -using EpinelPS.Database; -using Google.Protobuf.WellKnownTypes; -using static Google.Rpc.Context.AttributeContext.Types; - -namespace EpinelPS.Utils -{ - public class NetUtils - { - public static (User?, AccessToken?) GetUser(string tokToCheck) - { - if (string.IsNullOrEmpty(tokToCheck)) - throw new Exception("missing auth token"); - - - foreach (AccessToken tok in JsonDb.Instance.LauncherAccessTokens) - { - if (tok.Token == tokToCheck) - { - User? user = JsonDb.Instance.Users.Find(x => x.ID == tok.UserID); - if (user != null) - { - return (user, tok); - } - } - } - - return (null, null); - } - public static NetUserItemData ToNet(ItemData item) - { - return new() - { - Corporation = item.Corp, - Count = item.Count, - Csn = item.Csn, - Exp = item.Exp, - Isn = item.Isn, - Lv = item.Level, - Position = item.Position, - Tid = item.ItemType - }; - } - - internal static NetUserItemData UserItemDataToNet(ItemData item) - { - return new NetUserItemData() - { - Count = item.Count, - Tid = item.ItemType, - Csn = item.Csn, - Lv = item.Level, - Exp = item.Exp, - Corporation = item.Corp, - Isn = item.Isn, - Position = item.Position - }; - } - - - public static List GetUserItems(User user) - { - List ret = []; - Dictionary itemDictionary = []; - - foreach (ItemData? item in user.Items.ToList()) - { - if (item.Csn == 0) - { - if (itemDictionary.TryGetValue(item.ItemType, out NetUserItemData? value)) - { - value.Count++; - } - else - { - itemDictionary[item.ItemType] = UserItemDataToNet(item); - } - } - else - { - itemDictionary[item.ItemType] = UserItemDataToNet(item); - } - } - - return ret; - } - - public static int GetItemPos(User user, long isn) - { - foreach (ItemData item in user.Items) - { - if (item.Isn == isn) - { - string? subType = GameData.Instance.GetItemSubType(item.ItemType); - switch (subType) - { - case "Module_A": - return 0; - case "Module_B": - return 1; - case "Module_C": - return 2; - case "Module_D": - return 3; - case "HarmonyCube": - return GetHarmonyCubePosition(item.ItemType); - default: - Console.WriteLine("Unknown item subtype: " + subType); - break; - } - break; - } - } - - return 0; - } - - public static int GetHarmonyCubePosition(int itemType) - { - if (GameData.Instance.ItemHarmonyCubeTable.TryGetValue(itemType, out ItemHarmonyCubeRecord? harmonyCube)) - { - return harmonyCube.location_id; - } - return 1; - } - /// - /// Takes multiple NetRewardData objects and merges it into one. Note that this function expects that rewards are already applied to user object. - /// - /// list of rewards - /// user to pull old currency count from - /// - public static NetRewardData MergeRewards(List rewards, User user) - { - NetRewardData result = new(); - - Dictionary currencyDict = []; - List items = []; - - foreach (NetRewardData reward in rewards) - { - foreach (NetCurrencyData? c in reward.Currency) - { - if (currencyDict.ContainsKey(c.Type)) - currencyDict[c.Type] += c.Value; - else - currencyDict.Add(c.Type, c.Value); - } - - foreach (NetItemData? item in reward.Item) - { - items.Add(item); - } - - foreach (NetUserItemData? item in reward.UserItems) - { - // TODO: do these need to be combined? - result.UserItems.Add(item); - } - - foreach (NetPointData? item in reward.Point) - { - result.Point.Add(item); +using System.Collections; +using System.Collections.Generic; +using EpinelPS.Data; +using EpinelPS.Database; +using Google.Protobuf.WellKnownTypes; +using static Google.Rpc.Context.AttributeContext.Types; + +namespace EpinelPS.Utils +{ + public class NetUtils + { + public static (User?, AccessToken?) GetUser(string tokToCheck) + { + if (string.IsNullOrEmpty(tokToCheck)) + throw new Exception("missing auth token"); + + + foreach (AccessToken tok in JsonDb.Instance.LauncherAccessTokens) + { + if (tok.Token == tokToCheck) + { + User? user = JsonDb.Instance.Users.Find(x => x.ID == tok.UserID); + if (user != null) + { + return (user, tok); + } + } + } + + return (null, null); + } + public static NetUserItemData ToNet(ItemData item) + { + return new() + { + Corporation = item.Corp, + Count = item.Count, + Csn = item.Csn, + Exp = item.Exp, + Isn = item.Isn, + Lv = item.Level, + Position = item.Position, + Tid = item.ItemType + }; + } + + internal static NetUserItemData UserItemDataToNet(ItemData item) + { + return new NetUserItemData() + { + Count = item.Count, + Tid = item.ItemType, + Csn = item.Csn, + Lv = item.Level, + Exp = item.Exp, + Corporation = item.Corp, + Isn = item.Isn, + Position = item.Position + }; + } + + + public static List GetUserItems(User user) + { + List ret = []; + Dictionary itemDictionary = []; + + foreach (ItemData? item in user.Items.ToList()) + { + if (item.Csn == 0) + { + if (itemDictionary.TryGetValue(item.ItemType, out NetUserItemData? value)) + { + value.Count++; + } + else + { + itemDictionary[item.ItemType] = UserItemDataToNet(item); + } + } + else + { + itemDictionary[item.ItemType] = UserItemDataToNet(item); + } + } + + return ret; + } + + public static int GetItemPos(User user, long isn) + { + foreach (ItemData item in user.Items) + { + if (item.Isn == isn) + { + string? subType = GameData.Instance.GetItemSubType(item.ItemType); + switch (subType) + { + case "Module_A": + return 0; + case "Module_B": + return 1; + case "Module_C": + return 2; + case "Module_D": + return 3; + case "HarmonyCube": + return GetHarmonyCubePosition(item.ItemType); + default: + Console.WriteLine("Unknown item subtype: " + subType); + break; + } + break; + } + } + + return 0; + } + + public static int GetHarmonyCubePosition(int itemType) + { + if (GameData.Instance.ItemHarmonyCubeTable.TryGetValue(itemType, out ItemHarmonyCubeRecord? harmonyCube)) + { + return harmonyCube.location_id; + } + return 1; + } + /// + /// Takes multiple NetRewardData objects and merges it into one. Note that this function expects that rewards are already applied to user object. + /// + /// list of rewards + /// user to pull old currency count from + /// + public static NetRewardData MergeRewards(List rewards, User user) + { + NetRewardData result = new(); + + Dictionary currencyDict = []; + List items = []; + + foreach (NetRewardData reward in rewards) + { + foreach (NetCurrencyData? c in reward.Currency) + { + if (currencyDict.ContainsKey(c.Type)) + currencyDict[c.Type] += c.Value; + else + currencyDict.Add(c.Type, c.Value); } - foreach (int item in reward.JukeboxBgm) - { - result.JukeboxBgm.Add(item); - } - - foreach (NetCharacterData? c in reward.Character) - { - Logging.WriteLine("MergeRewards - TODO Character", LogType.Error); - } - - if (reward.InfraCoreExp != null) - result.InfraCoreExp = reward.InfraCoreExp; - } - - foreach (KeyValuePair c in currencyDict) - { - result.Currency.Add(new NetCurrencyData() { Value = c.Value, Type = c.Key, FinalValue = user.Currency[(CurrencyType)c.Key] }); - } - - // TODO is this right? - foreach (NetItemData c in items) - { - result.Item.Add(c); - } - return result; - } - - private static long CalcOutpostRewardAmount(int value, double ratio, double boost, double elapsedMinutes) - { - double baseValue = value * ratio / 10000.0; - double minuteValue = baseValue + baseValue * boost / 100.0; - - - return (long)Math.Floor(minuteValue * elapsedMinutes); - } - - public static double CalculateBoostValueForOutpost(User user, CurrencyType type) - { - return user.OutpostBuffs.GetTotalPercentages(type) / 100.0; - } - - public static long GetOutpostRewardAmount(User user, CurrencyType type, double mins, bool includeBoost) - { - OutpostBattleTableRecord battleData = GameData.Instance.OutpostBattle[user.OutpostBattleLevel.Level]; - - int value = 0; - double ratio = 0; - double boost = 1.0; - if (includeBoost) - boost += CalculateBoostValueForOutpost(user, type); - - switch (type) - { - case CurrencyType.CharacterExp2: - value = battleData.character_exp2; - ratio = 1; - break; - case CurrencyType.CharacterExp: - value = battleData.character_exp1; - ratio = 3; - break; - case CurrencyType.Gold: - value = battleData.credit; - ratio = 3; - break; - case CurrencyType.UserExp: - value = battleData.user_exp; - ratio = 1; - break; - } - return CalcOutpostRewardAmount(value, ratio, boost, mins); - } - - public static NetRewardData GetOutpostReward(User user, TimeSpan duration) - { - //duration = TimeSpan.FromHours(1); - NetRewardData result = new(); - - OutpostBattleTableRecord battleData = GameData.Instance.OutpostBattle[user.OutpostBattleLevel.Level]; - - result.Currency.Add(new NetCurrencyData() - { - Type = (int)CurrencyType.CharacterExp2, - FinalValue = 0, - Value = CalcOutpostRewardAmount(battleData.character_exp2, 1, 1, duration.TotalMinutes) - }); - - result.Currency.Add(new NetCurrencyData() - { - Type = (int)CurrencyType.CharacterExp, - FinalValue = 0, - Value = CalcOutpostRewardAmount(battleData.character_exp1, 3, 1, duration.TotalMinutes) - }); - - result.Currency.Add(new NetCurrencyData() - { - Type = (int)CurrencyType.Gold, - FinalValue = 0, - Value = CalcOutpostRewardAmount(battleData.credit, 3, 1, duration.TotalMinutes) - }); - - result.Currency.Add(new NetCurrencyData() - { - Type = (int)CurrencyType.UserExp, - FinalValue = 0, - Value = CalcOutpostRewardAmount(battleData.user_exp, 3, 1, duration.TotalMinutes) - }); - - return result; - } - - public static void RegisterRewardsForUser(User user, NetRewardData rewardData) - { - foreach (NetCurrencyData? item in rewardData.Currency) - { - user.AddCurrency((CurrencyType)item.Type, item.Value); - } - - // TODO: other things that are used by the function above - } - - internal static List GetOutpostTimeReward(User user) - { - List res = []; - - // NetTimeRewardBuff - // FunctionType: 1: value increase, 2: percentage increase - // Tid: Outpost building ID - - NetTimeReward goldBuff = new() - { - UseId = 1, - ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.Gold, 1, true) * 10000, - ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.Gold, 1, false) * 10000 - }; - foreach (int item in user.OutpostBuffs.CreditPercentages) - { - goldBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); - } - - - NetTimeReward battleDataBuff = new() - { - UseId = 2, - ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp, 1, true) * 10000, - ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp, 1, false) * 10000 - }; - foreach (int item in user.OutpostBuffs.BattleDataPercentages) - { - battleDataBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); - } - - NetTimeReward xpBuff = new() - { - UseId = 3, - ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.UserExp, 1, true) * 10000, - ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.UserExp, 1, false) * 10000 - }; - foreach (int item in user.OutpostBuffs.UserExpPercentages) - { - xpBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); - } - - NetTimeReward coredustBuff = new() - { - UseId = 4, - ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp2, 60, true) * 100, - ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp2, 60, false) * 100 - }; - foreach (int item in user.OutpostBuffs.CoreDustPercentages) - { - coredustBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); - } - - res.Add(battleDataBuff); - res.Add(goldBuff); - res.Add(xpBuff); - res.Add(coredustBuff); - - return res; - } - - private static NetWholeTeamSlot? LookupCharacter(User user, long csn, int slot) - { - if (csn == 0) return new() { Slot = slot }; - - NetWholeTeamSlot result = new(); - - CharacterModel? c = user.GetCharacterBySerialNumber(csn); - if (c == null) return new() { Slot = slot }; - - return new NetWholeTeamSlot() - { - CostumeId = c.CostumeId, - Csn = csn, - Lv = c.Level, - Slot = slot, - Tid = c.Tid, - //UserFavoriteItem: TODO - }; - } - - internal static NetWholeUserTeamData GetDisplayedTeam(User user) - { - NetWholeUserTeamData result = new() { TeamNumber = 1, Type = 2 }; - - if (user.RepresentationTeamDataNew.Length == 5) - { - result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[0], 1)); - result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[1], 2)); - result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[2], 3)); - result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[3], 4)); - result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[4], 5)); - } - - int totalCP = 0; - - foreach (long item in user.RepresentationTeamDataNew) - { - totalCP += FormulaUtils.CalculateCP(user, item); - } - - result.TeamCombat = totalCP; - - return result; - } - - public static NetRewardData UseLootBox(User user, int boxId, int count) - { - ItemConsumeRecord? cItem = GameData.Instance.ConsumableItems.Where(x => x.Value.id == boxId).FirstOrDefault().Value ?? throw new Exception("cannot find box id " + boxId); - - if (cItem.use_type != "ItemRandomBox") throw new Exception("expected random box"); - - // find matching probability entries - RandomItemRecord[] probabilityEntries = [.. GameData.Instance.RandomItem.Values.Where(x => x.group_id == cItem.use_id)]; - if (probabilityEntries.Length == 0) throw new Exception($"cannot find any probability entries with ID {cItem.use_id}, box ID: {cItem.id}"); - - // run probability as many times as needed - NetRewardData ret = new() { PassPoint = new() }; - for (int i = 0; i < count; i++) - { - RandomItemRecord winningRecord = Rng.PickWeightedItem(probabilityEntries); - - Logging.WriteLine($"LootBox {boxId}: Won item - Type: {winningRecord.reward_type}, ID: {winningRecord.reward_id}, Value: {winningRecord.reward_value_min}", LogType.Info); - - if (winningRecord.reward_value_min != winningRecord.reward_value_max) - { - 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); - } - JsonDb.Save(); - - return ret; - } - } + foreach (NetItemData? item in reward.Item) + { + items.Add(item); + } + + foreach (NetUserItemData? item in reward.UserItems) + { + // TODO: do these need to be combined? + result.UserItems.Add(item); + } + + foreach (NetPointData? item in reward.Point) + { + result.Point.Add(item); + } + + foreach (int item in reward.JukeboxBgm) + { + result.JukeboxBgm.Add(item); + } + + foreach (NetCharacterData? c in reward.Character) + { + Logging.WriteLine("MergeRewards - TODO Character", LogType.Error); + } + + if (reward.InfraCoreExp != null) + result.InfraCoreExp = reward.InfraCoreExp; + } + + foreach (KeyValuePair c in currencyDict) + { + result.Currency.Add(new NetCurrencyData() { Value = c.Value, Type = c.Key, FinalValue = user.Currency[(CurrencyType)c.Key] }); + } + + // TODO is this right? + foreach (NetItemData c in items) + { + result.Item.Add(c); + } + return result; + } + + private static long CalcOutpostRewardAmount(int value, double ratio, double boost, double elapsedMinutes) + { + double baseValue = value * ratio / 10000.0; + double minuteValue = baseValue + baseValue * boost / 100.0; + + + return (long)Math.Floor(minuteValue * elapsedMinutes); + } + + public static double CalculateBoostValueForOutpost(User user, CurrencyType type) + { + return user.OutpostBuffs.GetTotalPercentages(type) / 100.0; + } + + public static long GetOutpostRewardAmount(User user, CurrencyType type, double mins, bool includeBoost) + { + OutpostBattleTableRecord battleData = GameData.Instance.OutpostBattle[user.OutpostBattleLevel.Level]; + + int value = 0; + double ratio = 0; + double boost = 1.0; + if (includeBoost) + boost += CalculateBoostValueForOutpost(user, type); + + switch (type) + { + case CurrencyType.CharacterExp2: + value = battleData.character_exp2; + ratio = 1; + break; + case CurrencyType.CharacterExp: + value = battleData.character_exp1; + ratio = 3; + break; + case CurrencyType.Gold: + value = battleData.credit; + ratio = 3; + break; + case CurrencyType.UserExp: + value = battleData.user_exp; + ratio = 1; + break; + } + return CalcOutpostRewardAmount(value, ratio, boost, mins); + } + + public static NetRewardData GetOutpostReward(User user, TimeSpan duration) + { + //duration = TimeSpan.FromHours(1); + NetRewardData result = new(); + + OutpostBattleTableRecord battleData = GameData.Instance.OutpostBattle[user.OutpostBattleLevel.Level]; + + result.Currency.Add(new NetCurrencyData() + { + Type = (int)CurrencyType.CharacterExp2, + FinalValue = 0, + Value = CalcOutpostRewardAmount(battleData.character_exp2, 1, 1, duration.TotalMinutes) + }); + + result.Currency.Add(new NetCurrencyData() + { + Type = (int)CurrencyType.CharacterExp, + FinalValue = 0, + Value = CalcOutpostRewardAmount(battleData.character_exp1, 3, 1, duration.TotalMinutes) + }); + + result.Currency.Add(new NetCurrencyData() + { + Type = (int)CurrencyType.Gold, + FinalValue = 0, + Value = CalcOutpostRewardAmount(battleData.credit, 3, 1, duration.TotalMinutes) + }); + + result.Currency.Add(new NetCurrencyData() + { + Type = (int)CurrencyType.UserExp, + FinalValue = 0, + Value = CalcOutpostRewardAmount(battleData.user_exp, 3, 1, duration.TotalMinutes) + }); + + return result; + } + + public static void RegisterRewardsForUser(User user, NetRewardData rewardData) + { + foreach (NetCurrencyData? item in rewardData.Currency) + { + user.AddCurrency((CurrencyType)item.Type, item.Value); + } + + // TODO: other things that are used by the function above + } + + internal static List GetOutpostTimeReward(User user) + { + List res = []; + + // NetTimeRewardBuff + // FunctionType: 1: value increase, 2: percentage increase + // Tid: Outpost building ID + + NetTimeReward goldBuff = new() + { + UseId = 1, + ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.Gold, 1, true) * 10000, + ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.Gold, 1, false) * 10000 + }; + foreach (int item in user.OutpostBuffs.CreditPercentages) + { + goldBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); + } + + + NetTimeReward battleDataBuff = new() + { + UseId = 2, + ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp, 1, true) * 10000, + ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp, 1, false) * 10000 + }; + foreach (int item in user.OutpostBuffs.BattleDataPercentages) + { + battleDataBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); + } + + NetTimeReward xpBuff = new() + { + UseId = 3, + ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.UserExp, 1, true) * 10000, + ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.UserExp, 1, false) * 10000 + }; + foreach (int item in user.OutpostBuffs.UserExpPercentages) + { + xpBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); + } + + NetTimeReward coredustBuff = new() + { + UseId = 4, + ValuePerMinAfterBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp2, 60, true) * 100, + ValuePerMinBeforeBuff = GetOutpostRewardAmount(user, CurrencyType.CharacterExp2, 60, false) * 100 + }; + foreach (int item in user.OutpostBuffs.CoreDustPercentages) + { + coredustBuff.Buffs.Add(new NetTimeRewardBuff() { Tid = 22401, FunctionType = 2, SourceType = OutpostBuffSourceType.TacticAcademy, Value = item }); + } + + res.Add(battleDataBuff); + res.Add(goldBuff); + res.Add(xpBuff); + res.Add(coredustBuff); + + return res; + } + + private static NetWholeTeamSlot? LookupCharacter(User user, long csn, int slot) + { + if (csn == 0) return new() { Slot = slot }; + + NetWholeTeamSlot result = new(); + + CharacterModel? c = user.GetCharacterBySerialNumber(csn); + if (c == null) return new() { Slot = slot }; + + return new NetWholeTeamSlot() + { + CostumeId = c.CostumeId, + Csn = csn, + Lv = c.Level, + Slot = slot, + Tid = c.Tid, + //UserFavoriteItem: TODO + }; + } + + internal static NetWholeUserTeamData GetDisplayedTeam(User user) + { + NetWholeUserTeamData result = new() { TeamNumber = 1, Type = 2 }; + + if (user.RepresentationTeamDataNew.Length == 5) + { + result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[0], 1)); + result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[1], 2)); + result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[2], 3)); + result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[3], 4)); + result.Slots.Add(LookupCharacter(user, user.RepresentationTeamDataNew[4], 5)); + } + + int totalCP = 0; + + foreach (long item in user.RepresentationTeamDataNew) + { + totalCP += FormulaUtils.CalculateCP(user, item); + } + + result.TeamCombat = totalCP; + + return result; + } + + public static NetRewardData UseLootBox(User user, int boxId, int count) + { + ItemConsumeRecord? cItem = GameData.Instance.ConsumableItems.Where(x => x.Value.id == boxId).FirstOrDefault().Value ?? throw new Exception("cannot find box id " + boxId); + + if (cItem.use_type != "ItemRandomBox") throw new Exception("expected random box"); + + // find matching probability entries + RandomItemRecord[] probabilityEntries = [.. GameData.Instance.RandomItem.Values.Where(x => x.group_id == cItem.use_id)]; + if (probabilityEntries.Length == 0) throw new Exception($"cannot find any probability entries with ID {cItem.use_id}, box ID: {cItem.id}"); + + // run probability as many times as needed + NetRewardData ret = new() { PassPoint = new() }; + for (int i = 0; i < count; i++) + { + RandomItemRecord winningRecord = Rng.PickWeightedItem(probabilityEntries); + + Logging.WriteLine($"LootBox {boxId}: Won item - Type: {winningRecord.reward_type}, ID: {winningRecord.reward_id}, Value: {winningRecord.reward_value_min}", LogType.Info); + + if (winningRecord.reward_value_min != winningRecord.reward_value_max) + { + Logging.WriteLine("TODO: reward_value_max", LogType.Warning); + } + + if (winningRecord.reward_type == RewardType.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); + } + JsonDb.Save(); + + return ret; + } + } } \ No newline at end of file diff --git a/EpinelPS/Utils/RewardUtils.cs b/EpinelPS/Utils/RewardUtils.cs index b7e681c..867935c 100644 --- a/EpinelPS/Utils/RewardUtils.cs +++ b/EpinelPS/Utils/RewardUtils.cs @@ -9,10 +9,10 @@ namespace EpinelPS.Utils { public static NetRewardData RegisterRewardsForUser(User user, int rewardId) { - RewardTableRecord rewardData = GameData.Instance.GetRewardTableEntry(rewardId) ?? throw new Exception($"unknown reward id {rewardId}"); + RewardRecord rewardData = GameData.Instance.GetRewardTableEntry(rewardId) ?? throw new Exception($"unknown reward id {rewardId}"); return RegisterRewardsForUser(user, rewardData); } - public static NetRewardData RegisterRewardsForUser(User user, RewardTableRecord rewardData) + public static NetRewardData RegisterRewardsForUser(User user, RewardRecord rewardData) { NetRewardData ret = new() { @@ -70,7 +70,7 @@ namespace EpinelPS.Utils foreach (RewardEntry item in rewardData.rewards) { - if (!string.IsNullOrEmpty(item.reward_type)) + if (item.reward_type != RewardType.None) { if (item.reward_percent != 1000000) { @@ -111,175 +111,174 @@ namespace EpinelPS.Utils /// /// /// - public static void AddSingleObject(User user, ref NetRewardData ret, int rewardId, string rewardType, int rewardCount) + public static void AddSingleObject(User user, ref NetRewardData ret, int rewardId, RewardType rewardType, int rewardCount) { - if (rewardId != 0 || !string.IsNullOrEmpty(rewardType)) + if (rewardId == 0 || rewardType == RewardType.None) return; + + if (rewardType == RewardType.Currency) { - if (string.IsNullOrEmpty(rewardType) || string.IsNullOrWhiteSpace(rewardType)) { } - else if (rewardType == "Currency") + AddSingleCurrencyObject(user, ref ret, (CurrencyType)rewardId, rewardCount); + } + else if (rewardType == RewardType.Item || + rewardType.ToString().StartsWith("Equipment_")) + { + // Check if user already has said item. If it is level 1, increase item count. + // If user does not have item, generate a new item ID + if (user.Items.Where(x => x.ItemType == rewardId && x.Level == 1).Any()) { - AddSingleCurrencyObject(user, ref ret, (CurrencyType)rewardId, rewardCount); - } - else if (rewardType == "Item" || rewardType.StartsWith("Equipment_")) - { - // Check if user already has said item. If it is level 1, increase item count. - // If user does not have item, generate a new item ID - if (user.Items.Where(x => x.ItemType == rewardId && x.Level == 1).Any()) + ItemData? newItem = user.Items.Where(x => x.ItemType == rewardId && x.Level == 1).FirstOrDefault(); + if (newItem != null) { - ItemData? newItem = user.Items.Where(x => x.ItemType == rewardId && x.Level == 1).FirstOrDefault(); - if (newItem != null) - { - newItem.Count += rewardCount; + newItem.Count += rewardCount; - // Tell the client the reward and its amount - ret.Item.Add(new NetItemData() - { - Count = rewardCount, - Tid = rewardId, - //Isn = newItem.Isn - }); - - // Tell the client the new amount of this item - ret.UserItems.Add(new NetUserItemData() - { - Isn = newItem.Isn, - Tid = newItem.ItemType, - Count = newItem.Count - }); - } - else - { - throw new Exception("should not occur"); - } - } - else - { - - int id = user.GenerateUniqueItemId(); - user.Items.Add(new ItemData() { ItemType = rewardId, Isn = id, Level = 1, Exp = 0, Count = rewardCount }); + // Tell the client the reward and its amount ret.Item.Add(new NetItemData() { Count = rewardCount, Tid = rewardId, - //Isn = id + //Isn = newItem.Isn }); - // Tell the client the new amount of this item (which is the same as user did not have item previously) + // Tell the client the new amount of this item ret.UserItems.Add(new NetUserItemData() { - Isn = id, - Tid = rewardId, - Count = rewardCount + Isn = newItem.Isn, + Tid = newItem.ItemType, + Count = newItem.Count }); } - } - else if (rewardType == "Memorial") - { - if (!user.Memorial.Contains(rewardId)) - { - ret.Memorial.Add(rewardId); - user.Memorial.Add(rewardId); - } - } - else if (rewardType == "Bgm") - { - if (!user.JukeboxBgm.Contains(rewardId)) - { - ret.JukeboxBgm.Add(rewardId); - user.JukeboxBgm.Add(rewardId); - } - } - else if (rewardType == "InfraCoreExp") - { - int beforeLv = user.InfraCoreLvl; - int beforeExp = user.InfraCoreExp; - - user.InfraCoreExp += rewardCount; - - // Check for level ups - Dictionary gradeTable = GameData.Instance.InfracoreTable; - int newLevel = user.InfraCoreLvl; - - foreach (InfracoreRecord grade in gradeTable.Values.OrderBy(g => g.grade)) - { - if (user.InfraCoreExp >= grade.infra_core_exp) - { - newLevel = grade.grade + 1; - } - else - { - break; - } - } - - if (newLevel > user.InfraCoreLvl) - { - user.InfraCoreLvl = newLevel; - } - - ret.InfraCoreExp = new NetIncreaseExpData() - { - BeforeLv = beforeLv, - BeforeExp = beforeExp, - CurrentLv = user.InfraCoreLvl, - CurrentExp = user.InfraCoreExp, - GainExp = rewardCount - }; - } - else if (rewardType == "ItemRandomBox") - { - ItemConsumeRecord? cItem = GameData.Instance.ConsumableItems.Where(x => x.Value.id == rewardId).FirstOrDefault().Value; - - if (cItem.item_sub_type == ItemSubType.ItemRandomBoxList) - { - NetRewardData reward = NetUtils.UseLootBox(user, rewardId, rewardCount); - - ret = NetUtils.MergeRewards([ret, reward], user); - } else { - NetItemData itm = new() - { - Count = rewardCount, - Tid = cItem.id, - Isn = user.GenerateUniqueItemId() - }; - ret.Item.Add(itm); - - user.Items.Add(new ItemData() { Count = rewardCount, Isn = itm.Isn, ItemType = itm.Tid }); + throw new Exception("should not occur"); } } - else if (rewardType == "FavoriteItem") - { - - NetUserFavoriteItemData newFavoriteItem = new NetUserFavoriteItemData - { - FavoriteItemId = user.GenerateUniqueItemId(), - Tid = rewardId, - Csn = 0, - Lv = 0, - Exp = 0 - }; - user.FavoriteItems.Add(newFavoriteItem); - - ret.UserFavoriteItems.Add(newFavoriteItem); - - NetFavoriteItemData favoriteItemData = new NetFavoriteItemData - { - FavoriteItemId = newFavoriteItem.FavoriteItemId, - Tid = newFavoriteItem.Tid, - Csn = newFavoriteItem.Csn, - Lv = newFavoriteItem.Lv, - Exp = newFavoriteItem.Exp - }; - ret.FavoriteItems.Add(favoriteItemData); - - } else { - Logging.WriteLine("TODO: Reward type " + rewardType, LogType.Warning); + + int id = user.GenerateUniqueItemId(); + user.Items.Add(new ItemData() { ItemType = rewardId, Isn = id, Level = 1, Exp = 0, Count = rewardCount }); + ret.Item.Add(new NetItemData() + { + Count = rewardCount, + Tid = rewardId, + //Isn = id + }); + + // Tell the client the new amount of this item (which is the same as user did not have item previously) + ret.UserItems.Add(new NetUserItemData() + { + Isn = id, + Tid = rewardId, + Count = rewardCount + }); } } + else if (rewardType == RewardType.Memorial) + { + if (!user.Memorial.Contains(rewardId)) + { + ret.Memorial.Add(rewardId); + user.Memorial.Add(rewardId); + } + } + else if (rewardType == RewardType.Bgm) + { + if (!user.JukeboxBgm.Contains(rewardId)) + { + ret.JukeboxBgm.Add(rewardId); + user.JukeboxBgm.Add(rewardId); + } + } + else if (rewardType == RewardType.InfraCoreExp) + { + int beforeLv = user.InfraCoreLvl; + int beforeExp = user.InfraCoreExp; + + user.InfraCoreExp += rewardCount; + + // Check for level ups + Dictionary gradeTable = GameData.Instance.InfracoreTable; + int newLevel = user.InfraCoreLvl; + + foreach (InfracoreRecord grade in gradeTable.Values.OrderBy(g => g.grade)) + { + if (user.InfraCoreExp >= grade.infra_core_exp) + { + newLevel = grade.grade + 1; + } + else + { + break; + } + } + + if (newLevel > user.InfraCoreLvl) + { + user.InfraCoreLvl = newLevel; + } + + ret.InfraCoreExp = new NetIncreaseExpData() + { + BeforeLv = beforeLv, + BeforeExp = beforeExp, + CurrentLv = user.InfraCoreLvl, + CurrentExp = user.InfraCoreExp, + GainExp = rewardCount + }; + } + else if (rewardType == RewardType.ItemRandomBox) + { + ItemConsumeRecord? cItem = GameData.Instance.ConsumableItems.Where(x => x.Value.id == rewardId).FirstOrDefault().Value; + + if (cItem.item_sub_type == ItemSubType.ItemRandomBoxList) + { + NetRewardData reward = NetUtils.UseLootBox(user, rewardId, rewardCount); + + ret = NetUtils.MergeRewards([ret, reward], user); + } + else + { + NetItemData itm = new() + { + Count = rewardCount, + Tid = cItem.id, + Isn = user.GenerateUniqueItemId() + }; + ret.Item.Add(itm); + + user.Items.Add(new ItemData() { Count = rewardCount, Isn = itm.Isn, ItemType = itm.Tid }); + } + } + else if (rewardType == RewardType.FavoriteItem) + { + + NetUserFavoriteItemData newFavoriteItem = new NetUserFavoriteItemData + { + FavoriteItemId = user.GenerateUniqueItemId(), + Tid = rewardId, + Csn = 0, + Lv = 0, + Exp = 0 + }; + user.FavoriteItems.Add(newFavoriteItem); + + ret.UserFavoriteItems.Add(newFavoriteItem); + + NetFavoriteItemData favoriteItemData = new NetFavoriteItemData + { + FavoriteItemId = newFavoriteItem.FavoriteItemId, + Tid = newFavoriteItem.Tid, + Csn = newFavoriteItem.Csn, + Lv = newFavoriteItem.Lv, + Exp = newFavoriteItem.Exp + }; + ret.FavoriteItems.Add(favoriteItemData); + + } + else + { + Logging.WriteLine("TODO: Reward type " + rewardType, LogType.Warning); + } } } }