From 2a089a035bec6464f97a2b30c3cb6e256ac6e0bf Mon Sep 17 00:00:00 2001 From: SELEKCJONER Date: Mon, 18 Nov 2024 22:35:45 +0100 Subject: [PATCH] Add 1x free gacha Copies regular 1x behavior --- .../Msgs/Gacha/CheckGachaDailyEvent.cs | 8 +- .../Msgs/Gacha/ExecuteEventGacha.cs | 213 ++++++++++++++++++ 2 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 EpinelPS/LobbyServer/Msgs/Gacha/ExecuteEventGacha.cs diff --git a/EpinelPS/LobbyServer/Msgs/Gacha/CheckGachaDailyEvent.cs b/EpinelPS/LobbyServer/Msgs/Gacha/CheckGachaDailyEvent.cs index 83333db..f259add 100644 --- a/EpinelPS/LobbyServer/Msgs/Gacha/CheckGachaDailyEvent.cs +++ b/EpinelPS/LobbyServer/Msgs/Gacha/CheckGachaDailyEvent.cs @@ -14,14 +14,14 @@ namespace EpinelPS.LobbyServer.Msgs.Gacha response.FreeCount = 1; response.EventData = new NetEventData() { - Id = 70070, - EventSystemType = 6, + Id = 80004, + EventSystemType = 21, EventVisibleDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)).Ticks, EventStartDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)).Ticks, EventEndDate = DateTime.Now.AddDays(20).Ticks, - EventDisableDate = DateTime.Now.AddDays(20).Ticks, + EventDisableDate = DateTime.Now.AddDays(20).Ticks }; - // this is net event data i think it should be the same as in list events + // this is net event data i think it should be the same as in list events and get joined event only for free pull gacha event await WriteDataAsync(response); } diff --git a/EpinelPS/LobbyServer/Msgs/Gacha/ExecuteEventGacha.cs b/EpinelPS/LobbyServer/Msgs/Gacha/ExecuteEventGacha.cs new file mode 100644 index 0000000..6bf3875 --- /dev/null +++ b/EpinelPS/LobbyServer/Msgs/Gacha/ExecuteEventGacha.cs @@ -0,0 +1,213 @@ +//yes i am lazy and its preety much same as exec gacha +//but only does 1x pull +//its here only so there is no system error on 1x free gacha event +using EpinelPS.Database; +using EpinelPS.StaticInfo; +using EpinelPS.Utils; + +namespace EpinelPS.LobbyServer.Msgs.Gacha +{ + [PacketPath("/gacha/event/execute")] + public class ExecuteEventGacha : LobbyMsgHandler + { + private static readonly Random random = new Random(); + + // Exclusion lists for sick pulls mode and normal mode 2500601 is the broken R rarity dorothy + private static readonly List sickPullsExclusionList = new List { 2500601 }; // Add more IDs as needed + private static readonly List normalPullsExclusionList = new List { 2500601,422401,306201,399901,399902,399903,399904,201401,301501,112101,313201,319301,319401,320301,422601,426101,328301,328401,235101,235301,136101,339201,140001,140101,140201,580001,580101,580201,581001,581101,581201,582001,582101,582201,583001,583101,583201,583301,190101,290701 }; // Add more IDs as needed + + protected override async Task HandleAsync() + { + var req = await ReadData(); + + // Count determines whether we select 1 or 10 characters + int numberOfPulls = 1; + + var user = GetUser(); + var response = new ResExecuteDailyFreeGacha(); + + var entireallCharacterData = GameData.Instance.characterTable.Values.ToList(); + // Remove the .Values part since it's already a list. + // Group by name_code to treat same name_code as one character + // Always add characters with grade_core_id == 1 and 101 + var allCharacterData = entireallCharacterData.GroupBy(c => c.name_code).SelectMany(g => g.Where(c => c.grade_core_id == 1 || c.grade_core_id == 101 || c.grade_core_id == 201 || c.name_code == 3999)).ToList(); + + // Separate characters by rarity categories + var rCharacters = allCharacterData.Where(c => c.original_rare == "R" ).ToList(); + var srCharacters = allCharacterData.Where(c => c.original_rare == "SR").ToList(); + + // Separate Pilgrim SSRs and non-Pilgrim SSRs + var pilgrimCharacters = allCharacterData.Where(c => c.original_rare == "SSR" && c.corporation == "PILGRIM").ToList(); + var ssrCharacters = allCharacterData.Where(c => c.original_rare == "SSR" && c.corporation != "PILGRIM").ToList(); + + var selectedCharacters = new List(); + + // Check if user has 'sickpulls' set to true to use old method + if (user.sickpulls) + { + // Old selection method: Randomly select characters based on req.Count value, excluding characters in the sickPullsExclusionList + selectedCharacters = allCharacterData.Where(c => !sickPullsExclusionList.Contains(c.id)).OrderBy(x => random.Next()).Take(numberOfPulls).ToList(); // Exclude characters based on the exclusion list for sick pulls + } + else + { + // New method: Select characters based on req.Count value, with each character having its category determined independently, excluding characters in the normalPullsExclusionList + for (int i = 0; i < numberOfPulls; i++) + { + var character = SelectRandomCharacter(rCharacters, srCharacters, ssrCharacters, pilgrimCharacters, normalPullsExclusionList); + selectedCharacters.Add(character); + } + } + + var pieceIds = new List>(); // 2D array to store characterId and pieceId as Tuple + // Add each character's item to user.Items if the character exists in user.Characters + foreach (var characterData in selectedCharacters) + { + // Check if the item for this character already exists in user.Items based on ItemType + var existingItem = user.Items.FirstOrDefault(item => item.ItemType == characterData.piece_id); + + if (existingItem != null) + { + // If the item exists, increment the count + existingItem.Count += 1; + + // Send the updated item in the response + response.Items.Add(new NetUserItemData() + { + Tid = existingItem.ItemType, + Csn = existingItem.Csn, + Count = existingItem.Count, + Level = existingItem.Level, + Exp = existingItem.Exp, + Position = existingItem.Position, + Isn = existingItem.Isn + }); + } + else + { + // If the item does not exist, create a new item entry + var newItem = new ItemData() + { + ItemType = characterData.piece_id, + Csn = 0, + Count = 1, // or any relevant count + Level = 0, + Exp = 0, + Position = 0, + Corp = 0, + Isn = user.GenerateUniqueItemId() + }; + user.Items.Add(newItem); + + // Add the new item to response + response.Items.Add(new NetUserItemData() + { + Tid = newItem.ItemType, + Csn = newItem.Csn, + Count = newItem.Count, + Level = newItem.Level, + Exp = newItem.Exp, + Position = newItem.Position, + Isn = newItem.Isn + }); + } + } + + // Populate the 2D array with characterId and pieceId for each selected character + foreach (var characterData in selectedCharacters) + { + var characterId = characterData.id; + var pieceId = characterData.piece_id; + + // Store characterId and pieceId in the array + pieceIds.Add(Tuple.Create(characterId, pieceId)); + var id = user.GenerateUniqueCharacterId(); + response.Gacha.Add(new NetGachaEntityData() + { + Corporation = 1, + PieceCount = 1, + CurrencyValue = 5, + Sn = id, + Tid = characterId, + Type = 1 + }); + + // Check if the user already has the character, if not add it + if (!user.HasCharacter(characterId)) + { + response.Characters.Add(new NetUserCharacterDefaultData() + { + CostumeId = 0, + Csn = id, + Grade = 0, + Level = 1, + Skill1Lv = 1, + Skill2Lv = 1, + Tid = characterId, + UltiSkillLv = 1 + }); + + user.Characters.Add(new Database.Character() + { + CostumeId = 0, + Csn = id, + Grade = 0, + Level = 1, + Skill1Lvl = 1, + Skill2Lvl = 1, + Tid = characterId, + UltimateLevel = 1 + }); + } + } + + + + user.GachaTutorialPlayCount++; + JsonDb.Save(); + + await WriteDataAsync(response); + } + + private CharacterRecord SelectRandomCharacter(List rCharacters, List srCharacters, List ssrCharacters, List pilgrimCharacters, List exclusionList) + { + // Remove excluded characters from each category + var availableRCharacters = rCharacters.Where(c => !exclusionList.Contains(c.id)).ToList(); + var availableSRCharacters = srCharacters.Where(c => !exclusionList.Contains(c.id)).ToList(); + var availableSSRCharacters = ssrCharacters.Where(c => !exclusionList.Contains(c.id)).ToList(); + var availablePilgrimCharacters = pilgrimCharacters.Where(c => !exclusionList.Contains(c.id)).ToList(); + + // Each time we call this method, a new category will be selected for a single character + double roll = random.NextDouble() * 100; // Roll from 0 to 100 + + if (roll < 53 && availableRCharacters.Any()) + { + // R category + return availableRCharacters[random.Next(availableRCharacters.Count)]; + } + else if (roll < 53 + 43 && availableSRCharacters.Any()) + { + // SR category + return availableSRCharacters[random.Next(availableSRCharacters.Count)]; + } + else + { + // SSR category + double ssrRoll = random.NextDouble() * 100; + + if (ssrRoll < 4.55 && availablePilgrimCharacters.Any()) + { + // PILGRIM SSR + return availablePilgrimCharacters[random.Next(availablePilgrimCharacters.Count)]; + } + else if (availableSSRCharacters.Any()) + { + // Non-PILGRIM SSR + return availableSSRCharacters[random.Next(availableSSRCharacters.Count)]; + } + } + + // Fallback to a random R character if somehow no SSR characters are left after exclusion + return availableRCharacters.Any() ? availableRCharacters[random.Next(availableRCharacters.Count)] : null; + } + } +} \ No newline at end of file