Additional card content

This commit is contained in:
gamer147
2026-05-24 17:07:05 -04:00
parent 12fb2f4801
commit 34bcc579a5
18 changed files with 53025 additions and 16 deletions

View File

@@ -117,6 +117,18 @@ public class BaseDataSeeder : IDataSeeder
}
}
private class CardCosmeticRewardMap : ClassMap<CardCosmeticReward>
{
public CardCosmeticRewardMap()
{
Map(m => m.CardId).Name("card_id");
Map(m => m.Type).Name("type");
Map(m => m.CosmeticId).Name("cosmetic_id");
Map(m => m.Quantity).Name("quantity").Default(1);
Map(m => m.Card).Ignore();
}
}
public void Seed(ModelBuilder builder)
{
// Migrations bake the HasData rows into InsertData calls — once the migration is
@@ -146,6 +158,7 @@ public class BaseDataSeeder : IDataSeeder
List<MyPageBackgroundEntry> myPageBackgrounds = ReadCsv<MyPageBackgroundEntry, MyPageBackgroundEntryMap>("mypagebackgrounds.csv");
List<RankInfoEntry> rankinfos = ReadCsv<RankInfoEntry, RankInfoEntryMap>("ranks.csv");
List<ClassExpEntry> classexp = ReadCsv<ClassExpEntry, ClassExpEntryMap>("classexp.csv");
List<CardCosmeticReward> cardCosmeticRewards = ReadCsv<CardCosmeticReward, CardCosmeticRewardMap>("card_cosmetic_rewards.csv");
builder.Entity<ClassEntry>().HasData(classes);
builder.Entity<LeaderSkinEntry>().HasData(leaderSkins);
@@ -156,5 +169,6 @@ public class BaseDataSeeder : IDataSeeder
builder.Entity<MyPageBackgroundEntry>().HasData(myPageBackgrounds);
builder.Entity<RankInfoEntry>().HasData(rankinfos);
builder.Entity<ClassExpEntry>().HasData(classexp);
builder.Entity<CardCosmeticReward>().HasData(cardCosmeticRewards);
}
}

View File

@@ -0,0 +1,15 @@
namespace SVSim.Database.Enums;
/// <summary>
/// Subset of UserGoods.Type values that can be granted as a card-acquisition cosmetic.
/// Numeric values MUST match Wizard/UserGoods.cs:8-22 so wire serialization
/// (reward_type in /pack/open response) is direct passthrough.
/// </summary>
public enum CosmeticType
{
Sleeve = 6,
Emblem = 7,
Degree = 8,
Skin = 10,
MyPageBG = 15,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
using SVSim.Database.Enums;
namespace SVSim.Database.Models;
/// <summary>
/// Association: when a viewer acquires <see cref="CardId"/>, they should also receive
/// the cosmetic identified by (<see cref="Type"/>, <see cref="CosmeticId"/>) if they don't
/// already own it.
///
/// Always recorded on the NON-FOIL row of a card. Foil twins (card_id + 1) inherit at
/// lookup time — see CardAcquisitionService for the foil-resolution rule.
///
/// Composite PK on (CardId, Type, CosmeticId): naturally enforces "no duplicates" AND
/// satisfies EF's deterministic-PK requirement for HasData seeding.
/// </summary>
public class CardCosmeticReward
{
public long CardId { get; set; }
public CosmeticType Type { get; set; }
public long CosmeticId { get; set; }
public int Quantity { get; set; } = 1;
public ShadowverseCardEntry Card { get; set; } = null!;
}

View File

@@ -25,6 +25,7 @@ public class SVSimDbContext : DbContext
public DbSet<ShadowverseCardEntry> Cards => Set<ShadowverseCardEntry>();
public DbSet<ShadowverseCardSetEntry> CardSets => Set<ShadowverseCardSetEntry>();
public DbSet<ShadowverseDeckEntry> Decks => Set<ShadowverseDeckEntry>();
public DbSet<CardCosmeticReward> CardCosmeticRewards => Set<CardCosmeticReward>();
public DbSet<ClassEntry> Classes => Set<ClassEntry>();
public DbSet<ClassExpEntry> ClassExpCurve => Set<ClassExpEntry>();
@@ -115,6 +116,18 @@ public class SVSimDbContext : DbContext
modelBuilder.Entity<PackConfigEntry>().OwnsMany(p => p.Banners);
modelBuilder.Entity<Viewer>().OwnsMany(v => v.PackOpenCounts);
modelBuilder.Entity<CardCosmeticReward>(b =>
{
b.HasKey(r => new { r.CardId, r.Type, r.CosmeticId });
b.HasIndex(r => r.CardId);
// No inverse nav on the Card side — avoid forcing CosmeticRewards to load on every
// Card query. See project_ef_split_query memory for the cartesian-explode risk.
b.HasOne(r => r.Card)
.WithMany()
.HasForeignKey(r => r.CardId)
.OnDelete(DeleteBehavior.Cascade);
});
// GameConfiguration.Config: on Postgres use EF Core 8's OwnsOne+ToJson(jsonb column).
// On SQLite (tests) ToJson's WriteJson has a known NullReferenceException when owned
// collections are present — use a plain TEXT value converter instead so the same