Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions forge-ai/src/main/java/forge/ai/ComputerUtilCost.java
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,17 @@ public static int getMaxXValue(SpellAbility sa, Player ai, final boolean effect)

if (root.costHasManaX()) {
val = ComputerUtilMana.determineLeftoverMana(root, ai, effect);

if (sa.hasParam("AIMaxTgtCost")) {
String value = sa.getParam("AIMaxTgtCost");
String svar = source.getSVar(value);
if (svar.contains("LeftoverMana")) {
// limit the CMC to available mana
svar = svar.replace("LeftoverMana", ""+val);
}
int calculated = AbilityUtils.calculateAmount(source, svar, sa);
val = ObjectUtils.min(val, calculated);
}
}

if (sa.usesTargeting()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import forge.item.PaperCard;
import forge.model.FModel;
import org.testng.AssertJUnit;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import forge.game.Game;
Expand Down Expand Up @@ -897,4 +898,47 @@ public void testPithingNeedlePreventsAbilitiesFromBeingChosen() {
game.getAction().checkStateEffects(true);
AssertJUnit.assertNull(picker.chooseSpellAbilityToPlay(null));
}

@DataProvider(name = "testXIsTheLargestPayableCMCData")
public static Object[][] testXIsTheLargestPayableCMCData() {
return new Object[][] {
{"Green Sun's Zenith"},
//{"Finale of Devastation"}, //X is not limited to allow reach 10 and gain +X/+X
//{"Rocco, Cabaretti Caterer"}, //not working: it is creature with TrigChangeZone
{"Chord of Calling"},
{"Nature's Rhythm"}
};
}

@Test(dataProvider = "testXIsTheLargestPayableCMCData")
public void testXIsTheLargestPayableCMC(String cardName) {
Game game = initAndCreateGame();
Player ai = game.getPlayers().get(1);
ai.setTeam(0);

Player opponent = game.getPlayers().get(0);
opponent.setTeam(1);

// 9 mana available
addCards("Forest", 3, ai);
addCards("Mountain", 3, ai);
addCards("Plains", 3, ai);

// the most expensive payable creature is Endurance with CMC=3
addCardToZone(cardName, ai, ZoneType.Hand);
addCardToZone("Birds of Paradise", ai, ZoneType.Library); //CMC 1 - subpar
addCardToZone("Grizzly Bears", ai, ZoneType.Library); //CMC 2 - subpar
addCardToZone("Endurance", ai, ZoneType.Library); //CMC 3 - maximum
addCardToZone("Apex Devastator", ai, ZoneType.Library); //CMC 10 - to much
addCardToZone("Emrakul, the Aeons Torn", ai, ZoneType.Library); //CMC 15 - to much

game.getPhaseHandler().devModeSet(PhaseType.MAIN2, ai);
game.getAction().checkStateEffects(true);
SpellAbilityPicker picker = new SpellAbilityPicker(game, ai);
SpellAbility sa = picker.chooseSpellAbilityToPlay(null);

AssertJUnit.assertNotNull(sa);
AssertJUnit.assertEquals("Card '%s' was cast with X instead".formatted(cardName), 3, sa.getXManaCostPaid().intValue());
}

}
3 changes: 2 additions & 1 deletion forge-gui/res/cardsfolder/c/chord_of_calling.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Name:Chord of Calling
ManaCost:X G G G
Types:Instant
K:Convoke
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLEX | ChangeNum$ 1 | StackDescription$ SpellDescription | SpellDescription$ Search your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLEX | ChangeNum$ 1 | StackDescription$ SpellDescription | AIMaxTgtCost$ Y | SpellDescription$ Search your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.
SVar:X:Count$xPaid
SVar:Y:Count$ValidLibrary Creature.YouOwn+cmcLELeftoverMana$GreatestCardManaCost
Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.)\nSearch your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.
2 changes: 1 addition & 1 deletion forge-gui/res/cardsfolder/f/finale_of_devastation.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Name:Finale of Devastation
ManaCost:X G G
Types:Sorcery
A:SP$ ChangeZone | ChangeType$ Creature.YouCtrl+cmcLEX | Hidden$ True | Origin$ Library | OriginAlternative$ Graveyard | Destination$ Battlefield | ShuffleNonMandatory$ True | SubAbility$ DBPump | SpellDescription$ Search your library and/or graveyard for a creature card with mana value X or less and put it onto the battlefield. If you search your library this way, shuffle.
A:SP$ ChangeZone | ChangeType$ Creature.YouCtrl+cmcLEX | ChangeTypeDesc$ creature | Hidden$ True | Origin$ Library | OriginAlternative$ Graveyard | Destination$ Battlefield | ShuffleNonMandatory$ True | SubAbility$ DBPump | SpellDescription$ Search your library and/or graveyard for a creature card with mana value X or less and put it onto the battlefield. If you search your library this way, shuffle.
SVar:DBPump:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Haste | NumAtt$ +X | NumDef$ +X | ConditionCheckSVar$ X | ConditionSVarCompare$ GE10 | StackDescription$ SpellDescription | SpellDescription$ If X is 10 or more, creatures you control get +X/+X and gain haste until end of turn.
SVar:X:Count$xPaid
Oracle:Search your library and/or graveyard for a creature card with mana value X or less and put it onto the battlefield. If you search your library this way, shuffle. If X is 10 or more, creatures you control get +X/+X and gain haste until end of turn.
3 changes: 2 additions & 1 deletion forge-gui/res/cardsfolder/g/green_suns_zenith.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Name:Green Sun's Zenith
ManaCost:X G
Types:Sorcery
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.Green+cmcLEX | ChangeNum$ 1 | SubAbility$ DBShuffle | StackDescription$ Search your library for a green creature card with mana value X or less, put it onto the battlefield, then shuffle. | SpellDescription$ Search your library for a green creature card with mana value X or less, put it onto the battlefield, then shuffle. Shuffle CARDNAME into its owner's library.
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.Green+cmcLEX | ChangeNum$ 1 | SubAbility$ DBShuffle | AIMaxTgtCost$ Y | StackDescription$ Search your library for a green creature card with mana value X or less, put it onto the battlefield, then shuffle. | SpellDescription$ Search your library for a green creature card with mana value X or less, put it onto the battlefield, then shuffle. Shuffle CARDNAME into its owner's library.
SVar:X:Count$xPaid
SVar:Y:Count$ValidLibrary Creature.YouOwn+Green+cmcLELeftoverMana$GreatestCardManaCost
SVar:DBShuffle:DB$ ChangeZone | Origin$ Stack | Destination$ Library | Shuffle$ True | Defined$ Parent
Oracle:Search your library for a green creature card with mana value X or less, put it onto the battlefield, then shuffle. Shuffle Green Sun's Zenith into its owner's library.
3 changes: 2 additions & 1 deletion forge-gui/res/cardsfolder/n/natures_rhythm.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Name:Nature's Rhythm
ManaCost:X G G
Types:Sorcery
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLEX | ChangeNum$ 1 | StackDescription$ SpellDescription | SpellDescription$ Search your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLEX | ChangeNum$ 1 | AIMaxTgtCost$ Y | StackDescription$ SpellDescription | SpellDescription$ Search your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.
SVar:X:Count$xPaid
SVar:Y:Count$ValidLibrary Creature.YouOwn+Green+cmcLELeftoverMana$GreatestCardManaCost
K:Harmonize:X G G G G
Oracle:Search your library for a creature card with mana value X or less, put it onto the battlefield, then shuffle.\nHarmonize {X}{G}{G}{G}{G} (You may cast this card from your graveyard for its harmonize cost. You may tap a creature you control to reduce that cost by an amount of generic mana equal to its power. Then exile this spell.)