oecs-sharp/Game.CardWars/Systems/GameSetupSystem.cs

104 lines
3.8 KiB
C#

using OECS;
namespace Game.CardWars;
/// <summary>
/// One-time setup: creates players, leaders, banners, decks, castles, and deals starting hands.
/// </summary>
public class GameSetupSystem : ISystem
{
private readonly int _playerCount;
private readonly string _cardDataCsv;
private bool _hasRun;
public GameSetupSystem(int playerCount, string cardDataCsv)
{
_playerCount = playerCount;
_cardDataCsv = cardDataCsv;
}
public void Run(World world)
{
if (_hasRun) return;
_hasRun = true;
var state = world.ReadSingleton<GameState>();
ref var mutable = ref world.GetSingleton<GameState>();
mutable.PlayerCount = _playerCount;
mutable.Phase = GamePhase.PlayPhase;
mutable.CurrentPlayerIndex = 0;
mutable.StartingPlayerIndex = 0;
mutable.RoundNumber = 1;
world.MarkModified<GameState>(World.SingletonEntity);
// Register card effects.
CardEffectRegistry.Add<WarriorEffect>();
CardEffectRegistry.Add<ArcherEffect>();
CardEffectRegistry.Add<MercenaryEffect>();
CardEffectRegistry.Add<MerchantEffect>();
CardEffectRegistry.Add<DancerEffect>();
CardEffectRegistry.Add<PaladinEffect>();
CardEffectRegistry.Add<PrincessEffect>();
CardEffectRegistry.Add<DuelistEffect>();
CardEffectRegistry.Add<NunEffect>();
CardEffectRegistry.Add<ScoutEffect>();
CardEffectRegistry.Add<WitchEffect>();
CardEffectRegistry.Add<ThiefEffect>();
CardEffectRegistry.Add<PegasusEffect>();
CardEffectRegistry.Add<CurseMasterEffect>();
CardEffectRegistry.Add<MageEffect>();
CardEffectRegistry.Freeze();
// Create public deck.
var publicDeck = world.CreateEntity();
world.AddComponent(publicDeck, new PublicDeck());
// Load card definitions and create card instances for the public deck.
var defs = CardDataLoader.LoadDefinitions(world, _cardDataCsv);
foreach (var (defEntity, _) in defs)
{
world.AddComponent(defEntity, new InDeck { Source = defEntity, Target = publicDeck });
}
// Shuffle public deck.
var seed = state.Seed;
GameUtil.ShuffleDeck(world, publicDeck, ref seed);
// Create the first castle.
var castle = world.CreateEntity();
world.AddComponent(castle, new Castle { Color = CastleColor.Black });
// Create players.
for (int i = 0; i < _playerCount; i++)
{
var player = world.CreateEntity();
world.AddComponent(player, new Player { Index = i });
// Create leader card (always on field, rank 0 placeholder).
var leader = world.CreateEntity();
world.AddComponent(leader, new Leader());
world.AddComponent(leader, new CardDef { Name = $"领袖{i}", Ranks = new[] { 0 }, Effect = CardEffect.None, Kind = CardKind.Faction });
world.AddComponent(leader, new Card { Rank = 0, FaceDown = false });
world.AddComponent(leader, new OnField { Source = leader, Target = player });
// Create banner.
var banner = world.CreateEntity();
world.AddComponent(banner, new Banner());
world.AddComponent(banner, new OnField { Source = banner, Target = player });
// Create faction deck.
var factionDeck = world.CreateEntity();
world.AddComponent(factionDeck, new FactionDeck());
}
// Deal starting hands: 3 public cards per player.
foreach (var player in GameUtil.FindAllEntities<Player>(world))
{
for (int i = 0; i < 3; i++)
GameUtil.DrawCard(world, publicDeck, player);
}
mutable.Seed = seed;
world.MarkModified<GameState>(World.SingletonEntity);
}
}