// 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); } }