feat(pack): gacha-point accrual with per-child override
This commit is contained in:
@@ -123,7 +123,31 @@ public sealed class GachaPointService : IGachaPointService
|
||||
private static bool IsLeaderCard(CardCosmeticReward? skin) => skin is not null;
|
||||
|
||||
public void Accrue(Viewer viewer, PackConfigEntry pack, PackChildGachaEntry child, int packNumber)
|
||||
=> throw new NotImplementedException();
|
||||
{
|
||||
if (pack.GachaPointConfig is null) return;
|
||||
if (packNumber <= 0) return;
|
||||
|
||||
// Per-child override wins when set (>0); fall back to the pack's default.
|
||||
int perPack = child.OverrideIncreaseGachaPoint > 0
|
||||
? child.OverrideIncreaseGachaPoint
|
||||
: pack.GachaPointConfig.IncreaseGachaPoint;
|
||||
if (perPack <= 0) return;
|
||||
|
||||
int delta = perPack * packNumber;
|
||||
|
||||
var existing = viewer.GachaPointBalances.FirstOrDefault(b => b.PackId == pack.Id);
|
||||
if (existing is null)
|
||||
{
|
||||
viewer.GachaPointBalances.Add(new ViewerGachaPointBalance
|
||||
{
|
||||
PackId = pack.Id, Points = delta,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.Points += delta;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<ExchangeOutcome> TryExchangeAsync(Viewer viewer, int packId, long cardId)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
@@ -183,4 +183,104 @@ public class GachaPointServiceTests
|
||||
Assert.That(result, Has.Count.EqualTo(1));
|
||||
Assert.That(result[0].IsReceived, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Accrue_uses_pack_increase_when_child_override_is_zero()
|
||||
{
|
||||
using var factory = new SVSimTestFactory();
|
||||
long viewerId = await factory.SeedViewerAsync();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
|
||||
|
||||
db.Packs.Add(new PackConfigEntry
|
||||
{
|
||||
Id = 10008, BasePackId = 10008, PackCategory = PackCategory.LegendCardPack,
|
||||
CommenceDate = DateTime.UtcNow.AddDays(-1), CompleteDate = DateTime.UtcNow.AddDays(30),
|
||||
GachaPointConfig = new PackGachaPointConfig { ExchangeablePoint = 400, IncreaseGachaPoint = 1 },
|
||||
ChildGachas =
|
||||
{
|
||||
new PackChildGachaEntry
|
||||
{
|
||||
GachaId = 100081, TypeDetail = 2, Cost = 100, CardCount = 8,
|
||||
OverrideIncreaseGachaPoint = 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var viewer = await db.Viewers
|
||||
.Include(v => v.GachaPointBalances)
|
||||
.FirstAsync(v => v.Id == viewerId);
|
||||
var pack = await db.Packs.Include(p => p.ChildGachas).FirstAsync(p => p.Id == 10008);
|
||||
var child = pack.ChildGachas[0];
|
||||
|
||||
var svc = scope.ServiceProvider.GetRequiredService<IGachaPointService>();
|
||||
svc.Accrue(viewer, pack, child, packNumber: 10);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var balance = viewer.GachaPointBalances.Single(b => b.PackId == 10008);
|
||||
Assert.That(balance.Points, Is.EqualTo(10));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Accrue_child_override_takes_precedence_over_pack_increase()
|
||||
{
|
||||
using var factory = new SVSimTestFactory();
|
||||
long viewerId = await factory.SeedViewerAsync();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
|
||||
|
||||
db.Packs.Add(new PackConfigEntry
|
||||
{
|
||||
Id = 10008, BasePackId = 10008, PackCategory = PackCategory.LegendCardPack,
|
||||
CommenceDate = DateTime.UtcNow.AddDays(-1), CompleteDate = DateTime.UtcNow.AddDays(30),
|
||||
GachaPointConfig = new PackGachaPointConfig { ExchangeablePoint = 400, IncreaseGachaPoint = 1 },
|
||||
ChildGachas =
|
||||
{
|
||||
new PackChildGachaEntry
|
||||
{
|
||||
GachaId = 100085, TypeDetail = 5, Cost = 0, CardCount = 8,
|
||||
OverrideIncreaseGachaPoint = 3,
|
||||
},
|
||||
},
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var viewer = await db.Viewers.Include(v => v.GachaPointBalances).FirstAsync(v => v.Id == viewerId);
|
||||
var pack = await db.Packs.Include(p => p.ChildGachas).FirstAsync(p => p.Id == 10008);
|
||||
var child = pack.ChildGachas[0];
|
||||
|
||||
var svc = scope.ServiceProvider.GetRequiredService<IGachaPointService>();
|
||||
svc.Accrue(viewer, pack, child, packNumber: 2);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
Assert.That(viewer.GachaPointBalances.Single().Points, Is.EqualTo(6));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Accrue_is_noop_when_pack_has_no_gacha_point_config()
|
||||
{
|
||||
using var factory = new SVSimTestFactory();
|
||||
long viewerId = await factory.SeedViewerAsync();
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
|
||||
|
||||
db.Packs.Add(new PackConfigEntry
|
||||
{
|
||||
Id = 99047, BasePackId = 99047, PackCategory = PackCategory.LegendCardPack,
|
||||
CommenceDate = DateTime.UtcNow.AddDays(-1), CompleteDate = DateTime.UtcNow.AddDays(30),
|
||||
GachaPointConfig = null,
|
||||
ChildGachas = { new PackChildGachaEntry { GachaId = 990475, TypeDetail = 5, Cost = 0, CardCount = 8 } },
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var viewer = await db.Viewers.Include(v => v.GachaPointBalances).FirstAsync(v => v.Id == viewerId);
|
||||
var pack = await db.Packs.Include(p => p.ChildGachas).FirstAsync(p => p.Id == 99047);
|
||||
|
||||
var svc = scope.ServiceProvider.GetRequiredService<IGachaPointService>();
|
||||
svc.Accrue(viewer, pack, pack.ChildGachas[0], packNumber: 5);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
Assert.That(viewer.GachaPointBalances, Is.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user