Consider C# events.
This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments)
the event in your game loop, all those previously subscribed event handlers will get called.
I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState
. This GameStateManager
would expose a bunch of events like this:
public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;
and so on.
The GameStateManager
would then invoke those events at appropriate times.
public void SwitchTurn(Player newPlayer) {
currentPlayer = newPlayer;
// all the other stuff which needs to happen on turn changes
OnBeginTurn?.Invoke(currentPlayer);
}
A card could then subscribe to an event like this:
public void EnterGame() {
gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
gameStateManager.OnCardPlayed -= OnCardPlayed
}
private void OnCardPlayed(Card playedCard) {
// Deal 3 damage to every unit in the game when another player plays a resource card
if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
foreach(var otherCard in gameStateManager.allCardsInPlay) {
if(otherCard.type == Card.Type.UNIT) {
otherCard.Damage(3);
}
}
}
}
More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.
Yes, this will require that you have a hardcoded OnCardPlayed
method for every card which you need to program (although similar cards might share the same method).
I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.