Example #1
0
    // Call this at the end of enemy's turn/start of player's turn so that we can see their intents in advance!
    // Enemy AI uses weights to determine cards to play. Higher weights are always prioritized; cards in the same weight are then randomly selected.
    // Once a card is selected, choose a target. If an attack was selected, check to see if any enemy arguments have the MUST_TARGET flag to select that as the target, else choose randomly
    public void CalculateIntents()
    {
        intents.Clear();                                                           // clear old intents
        List <AbstractCard> currentHand = new List <AbstractCard>(this.GetHand()); // new keyword allows for "deep copy" since AbstractCard appears to be a primitive type... somehow

        int actionBudget = this.curAP;
        int iterations   = 0;

        while (actionBudget > 0 && currentHand.Count > 0 && iterations < 20)
        {
            iterations++;                                  // prevent infinite loop
            int rand = Random.Range(0, currentHand.Count); // For now, just choose random cards

            AbstractCard selectedCard = currentHand[rand];
            if (selectedCard.COST > actionBudget)       // if it costs more than we can afford, don't use this card
            {
                continue;
            }

            if (selectedCard.IsAttack())
            {
                CalculateAttackIntentTarget(selectedCard);
            }
            else if (selectedCard.IsSkill())
            {
                CalculateSkillIntentTarget(selectedCard);
            }
            else if (selectedCard.IsTrait())
            {
                intents.Add(new EnemyIntent(selectedCard, this.GetCoreArgument()));    // Traits don't need to worry about targeting, really - just use core argument as target
            }
            else
            {
                intents.Add(new EnemyIntent(selectedCard, this.GetCoreArgument()));    // This is stuff like Status cards that don't affect arguments themselves so no target is really necessary, but I don't want weird stuff happening, soo... just target core
            }
            actionBudget -= selectedCard.COST;
            currentHand.RemoveAt(rand);
        }
        // Debug.Log("Intents generated; generated " + intents.Count + " intents");
    }
    // Handle post-card playing effects (move card to discard pile, spend AP costs, etc.)
    public override void NotifyOfEvent(AbstractEvent eventData)
    {
        if (eventData.type == EventType.CARD_PLAYED)
        {
            EventCardPlayed data       = (EventCardPlayed)eventData;
            AbstractCard    cardPlayed = data.cardPlayed;
            cardsPlayedThisTurn.Add(data.cardPlayed);
            numCardsPlayedThisTurn += 1;

            if (cardPlayed.COSTS_ALL_AP)
            {
                cardPlayed.OWNER.curAP -= cardPlayed.OWNER.curAP;   // Handle X-cost cards
            }
            else
            {
                cardPlayed.OWNER.curAP -= cardPlayed.COST;
            }
            if (cardPlayed.HasTag(CardTags.DESTROY))          // Destroy card
            {
                cardPlayed.OWNER.Destroy(cardPlayed);
            }
            else if (cardPlayed.IsTrait() || cardPlayed.HasTag(CardTags.SCOUR))                  // Scour stuff
            {
                cardPlayed.OWNER.Scour(cardPlayed);
            }
            else
            {
                if (cardPlayed.OWNER.GetHand().Contains(cardPlayed))            // This check is to prevent adding cards from "choice" mechanics from being added to the discard (see: Deckard's Instincts card)
                {
                    cardPlayed.OWNER.GetHand().Remove(cardPlayed);
                    cardPlayed.OWNER.GetDiscardPile().AddCard(cardPlayed);
                }
            }
        }
        else if (eventData.type == EventType.ARGUMENT_DESTROYED)
        {
            EventArgDestroyed data = (EventArgDestroyed)eventData;
            enemy.RecalculateIntents(data.argumentDestroyed);
        }
    }