fix(bugs): some gacha and visual issues
This commit is contained in:
1 parent
116ea108f9
commit
138b5a9484
5 files changed
+57
-2
No files matched your search
@@ -175,6 +175,13 @@ public sealed class TutorialGuideGroupExcel
|
||||
public uint GroupID { get; set; }
|
||||
}
|
||||
|
||||
public sealed class GachaCeilingExcel
|
||||
{
|
||||
public string GachaType { get; set; } = string.Empty;
|
||||
|
||||
public List<uint> CeilingItemList { get; set; } = [];
|
||||
}
|
||||
|
||||
// maps an item id to its main/sub type. the client NPEs on an item it cannot type.
|
||||
public sealed class ItemConfigExcel
|
||||
{
|
||||
|
||||
@@ -114,4 +114,9 @@ public sealed partial class GameData
|
||||
row.TryGetPropertyValue(name, out var node) && node is not null && node.GetValueKind() is JsonValueKind.Number
|
||||
? node.GetValue<uint>()
|
||||
: null;
|
||||
|
||||
private static string? Str(JsonObject row, string name) =>
|
||||
row.TryGetPropertyValue(name, out var node) && node is not null && node.GetValueKind() is JsonValueKind.String
|
||||
? node.GetValue<string>()
|
||||
: null;
|
||||
}
|
||||
@@ -120,6 +120,9 @@ public sealed partial class GameData
|
||||
|
||||
public IReadOnlyList<uint> TutorialGuideIds { get; private set; } = [];
|
||||
|
||||
// the standard banner's guaranteed 5* pool
|
||||
public IReadOnlyList<uint> GachaCeilingAvatars { get; private set; } = [];
|
||||
|
||||
// every relic / lightcone id the client can resolve a type for
|
||||
public IReadOnlySet<uint> KnownRelicIds { get; private set; } = new HashSet<uint>();
|
||||
|
||||
@@ -207,6 +210,9 @@ public sealed partial class GameData
|
||||
data.MainMissions = data.Merge<MainMissionExcel>("MainMission.json", r => UInt(r, "MainMissionID"), required: false);
|
||||
data.TutorialIds = [.. data.Merge<TutorialExcel>("TutorialData.json", r => UInt(r, "TutorialID"), required: false).Keys];
|
||||
data.TutorialGuideIds = [.. data.Merge<TutorialGuideGroupExcel>("TutorialGuideGroup.json", r => UInt(r, "GroupID"), required: false).Keys];
|
||||
data.GachaCeilingAvatars = [.. data
|
||||
.Merge<GachaCeilingExcel>("GachaCeiling.json", r => Str(r, "GachaType") == "Normal" ? 0u : null, required: false)
|
||||
.Values.SelectMany(r => r.CeilingItemList)];
|
||||
data.KnownRelicIds = data.Merge<ItemConfigExcel>("ItemConfigRelic.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
||||
data.KnownLightconeIds = data.Merge<ItemConfigExcel>("ItemConfigEquipment.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace CapySR.GameServer.Handlers;
|
||||
[Handlers]
|
||||
public static class MiscHandlers
|
||||
{
|
||||
private const uint StandardBannerId = 1001;
|
||||
|
||||
// client settings the game stores server side (auto battle, speed, ...)
|
||||
public static Task OnGetAllServerPrefsData(PlayerSession session, GetAllServerPrefsDataCsReq request)
|
||||
{
|
||||
@@ -63,8 +65,29 @@ public static class MiscHandlers
|
||||
public static Task OnGetVideoVersionKey(PlayerSession session, GetVideoVersionKeyCsReq request) =>
|
||||
session.SendAsync(new GetVideoVersionKeyScRsp { Retcode = 0 });
|
||||
|
||||
public static Task OnGetGachaInfo(PlayerSession session, GetGachaInfoCsReq request) =>
|
||||
session.SendAsync(new GetGachaInfoScRsp { Retcode = 0 });
|
||||
// an empty list leaves the gacha red-dot filter indexing nil every UI tick, which throws
|
||||
// out of UIManager.Tick every frame. hand it the standard banner and nothing else.
|
||||
public static Task OnGetGachaInfo(PlayerSession session, GetGachaInfoCsReq request)
|
||||
{
|
||||
var ceiling = new GachaCeiling { CeilingNum = 300, IsClaimed = false };
|
||||
|
||||
foreach (var avatarId in session.World.Data.GachaCeilingAvatars)
|
||||
{
|
||||
ceiling.AvatarList.Add(new GachaCeilingAvatar { AvatarId = avatarId, RepeatedCnt = 300 });
|
||||
}
|
||||
|
||||
var response = new GetGachaInfoScRsp { Retcode = 0, GachaRandom = 0 };
|
||||
|
||||
response.GachaInfoList.Add(new GachaInfo
|
||||
{
|
||||
GachaId = StandardBannerId,
|
||||
GachaCeiling = ceiling,
|
||||
BeginTime = 0,
|
||||
EndTime = 2524608000,
|
||||
});
|
||||
|
||||
return session.SendAsync(response);
|
||||
}
|
||||
|
||||
public static Task OnGetDailyActiveInfo(PlayerSession session, GetDailyActiveInfoCsReq request) =>
|
||||
session.SendAsync(new GetDailyActiveInfoScRsp { Retcode = 0 });
|
||||
|
||||
@@ -36,6 +36,20 @@ public class GameDataTests(ITestOutputHelper output)
|
||||
Assert.NotEmpty(data.Equipment);
|
||||
}
|
||||
|
||||
// an empty banner leaves the client's gacha red dot throwing once a frame
|
||||
[Fact]
|
||||
public void ReadsStandardBannerCeiling()
|
||||
{
|
||||
var data = TryLoad(output);
|
||||
if (data is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotEmpty(data.GachaCeilingAvatars);
|
||||
Assert.Contains(1003u, data.GachaCeilingAvatars);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesMarch7th()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user