mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- RemAIDeck update: next iteration (Last Rites, mostly for Reanimator).
This commit is contained in:
@@ -865,6 +865,36 @@ public class AiController {
|
|||||||
} else if ("VolrathsShapeshifter".equals(sa.getParam("AILogic"))) {
|
} else if ("VolrathsShapeshifter".equals(sa.getParam("AILogic"))) {
|
||||||
return SpecialCardAi.VolrathsShapeshifter.targetBestCreature(player, sa);
|
return SpecialCardAi.VolrathsShapeshifter.targetBestCreature(player, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("AnyNumber")) {
|
||||||
|
if ("DiscardUncastableAndExcess".equals(sa.getParam("AILogic"))) {
|
||||||
|
// Note that at this point, there is no guarantee that the AI will discard specific cards found here,
|
||||||
|
// but since the AI generally discards things it doesn't need / can't immediately use, it's a relatively
|
||||||
|
// safe assumption that the follow-up discard action will be in line with what is considered here.
|
||||||
|
CardCollection discards = new CardCollection();
|
||||||
|
final CardCollectionView inHand = player.getCardsIn(ZoneType.Hand);
|
||||||
|
final int numLandsOTB = CardLists.filter(player.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS).size();
|
||||||
|
int numOppInHand = 0;
|
||||||
|
for (Player p : player.getGame().getPlayers()) {
|
||||||
|
if (p.getCardsIn(ZoneType.Hand).size() > numOppInHand) {
|
||||||
|
numOppInHand = p.getCardsIn(ZoneType.Hand).size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Card c : inHand) {
|
||||||
|
if (c.hasSVar("DoNotDiscardIfAble") || c.hasSVar("IsReanimatorCard")) { continue; }
|
||||||
|
if (c.isCreature() && !ComputerUtilMana.hasEnoughManaSourcesToCast(c.getSpellPermanent(), player)) {
|
||||||
|
discards.add(c);
|
||||||
|
}
|
||||||
|
if ((c.isLand() && numLandsOTB >= 5) || (c.getFirstSpellAbility() != null && !ComputerUtilMana.hasEnoughManaSourcesToCast(c.getFirstSpellAbility(), player))) {
|
||||||
|
if (discards.size() + 1 <= numOppInHand) {
|
||||||
|
discards.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return discards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for good discards
|
// look for good discards
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package forge.ai.ability;
|
|||||||
import forge.ai.*;
|
import forge.ai.*;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollectionView;
|
||||||
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -98,7 +101,35 @@ public class DiscardAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement support for Discard AI for cards with AnyNumber set to true.
|
// TODO: Improve support for Discard AI for cards with AnyNumber set to true.
|
||||||
|
if (sa.hasParam("AnyNumber")) {
|
||||||
|
if ("DiscardUncastableAndExcess".equals(aiLogic)) {
|
||||||
|
final CardCollectionView inHand = ai.getCardsIn(ZoneType.Hand);
|
||||||
|
final int numLandsOTB = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS).size();
|
||||||
|
int numDiscard = 0;
|
||||||
|
int numOppInHand = 0;
|
||||||
|
for (Player p : ai.getGame().getPlayers()) {
|
||||||
|
if (p.getCardsIn(ZoneType.Hand).size() > numOppInHand) {
|
||||||
|
numOppInHand = p.getCardsIn(ZoneType.Hand).size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Card c : inHand) {
|
||||||
|
if (c.equals(sa.getHostCard())) { continue; }
|
||||||
|
if (c.hasSVar("DoNotDiscardIfAble") || c.hasSVar("IsReanimatorCard")) { continue; }
|
||||||
|
if (c.isCreature() && !ComputerUtilMana.hasEnoughManaSourcesToCast(c.getSpellPermanent(), ai)) {
|
||||||
|
numDiscard++;
|
||||||
|
}
|
||||||
|
if ((c.isLand() && numLandsOTB >= 5) || (c.getFirstSpellAbility() != null && !ComputerUtilMana.hasEnoughManaSourcesToCast(c.getFirstSpellAbility(), ai))) {
|
||||||
|
if (numDiscard + 1 <= numOppInHand) {
|
||||||
|
numDiscard++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (numDiscard == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Don't use draw abilities before main 2 if possible
|
// Don't use draw abilities before main 2 if possible
|
||||||
if (ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
if (ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Name:Last Rites
|
Name:Last Rites
|
||||||
ManaCost:2 B
|
ManaCost:2 B
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Discard | Cost$ 2 B | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBLastRitesDiscard | SpellDescription$ Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
|
A:SP$ Discard | Cost$ 2 B | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBLastRitesDiscard | AILogic$ DiscardUncastableAndExcess | SpellDescription$ Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
|
||||||
SVar:DBLastRitesDiscard:DB$ Discard | Mode$ RevealYouChoose | NumCards$ X | DiscardValid$ Card.nonLand | ValidTgts$ Opponent | References$ X
|
SVar:DBLastRitesDiscard:DB$ Discard | Mode$ RevealYouChoose | NumCards$ X | DiscardValid$ Card.nonLand | ValidTgts$ Opponent | References$ X
|
||||||
SVar:DBLastRitesCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBLastRitesCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:X:Remembered$Amount
|
SVar:X:Remembered$Amount
|
||||||
SVar:RemAIDeck:True
|
SVar:RemRandomDeck:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/last_rites.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/last_rites.jpg
|
||||||
Oracle:Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
|
Oracle:Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
|
||||||
|
|||||||
Reference in New Issue
Block a user