mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
* Commander: fixed duplicated triggers after play (example: Esika, God of the Tree, see #7501, #7503, #7505);
This commit is contained in:
parent
aa13b06af9
commit
ac98a3a31a
6 changed files with 108 additions and 19 deletions
|
@ -57,9 +57,7 @@ public final class EsikaGodOfTheTree extends ModalDoubleFacesCard {
|
|||
// Legendary Enchantment
|
||||
this.getRightHalfCard().addSuperType(SuperType.LEGENDARY);
|
||||
|
||||
// At the beginning of your upkeep, reveal cards from the top of your library until you reveal
|
||||
// a creature or planeswalker card. Put that card onto the battlefield and the rest
|
||||
// on the bottom of your library in a random order.
|
||||
// At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature or planeswalker card. Put that card onto the battlefield and the rest on the bottom of your library in a random order.
|
||||
this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new PrismaticBridgeEffect(), TargetController.YOU, false, false
|
||||
));
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package org.mage.test.cards.cost.modaldoublefaces;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ModalDoubleFacesCardsInCommanderTest extends CardTestCommanderDuelBase {
|
||||
|
||||
@Test
|
||||
public void test_Triggers_MustAddTriggersOneTimeOnly() {
|
||||
// possible bug: duplicated triggers from same card
|
||||
// https://github.com/magefree/mage/issues/7501
|
||||
|
||||
removeAllCardsFromHand(playerA);
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
skipInitShuffling();
|
||||
|
||||
// Esika, God of the Tree
|
||||
// creature, 1/4
|
||||
// Landfall — Whenever a land enters the battlefield under your control, Kazandu Mammoth gets +2/+2 until end of turn.
|
||||
//
|
||||
// The Prismatic Bridge
|
||||
// Enchantment
|
||||
// At the beginning of your upkeep, reveal cards from the top of your library until you reveal a creature or
|
||||
// planeswalker card. Put that card onto the battlefield and the rest on the bottom of your library in a random order.
|
||||
addCard(Zone.COMMAND, playerA, "Esika, God of the Tree"); // {W}{U}{B}{R}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
//
|
||||
// last goes to top library
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears");
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears");
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears");
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears");
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears");
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
//
|
||||
// Exile target artifact or enchantment.
|
||||
addCard(Zone.HAND, playerB, "Ironwright's Cleansing"); // {2}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||
|
||||
// prepare mdf
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "The Prismatic Bridge");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "The Prismatic Bridge", 1);
|
||||
checkLibraryCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 5);
|
||||
|
||||
// possible bug: you can catch choose dialog for duplicated upkeep triggers
|
||||
|
||||
// turn 3, first upkeep and bear move
|
||||
checkLibraryCount("after upkeep 1", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 5 - 1);
|
||||
checkPermanentCount("after upkeep 1", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 1);
|
||||
|
||||
// turn 5, second upkeep and bear move
|
||||
checkLibraryCount("after upkeep 2", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 5 - 2);
|
||||
checkPermanentCount("after upkeep 2", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
}
|
|
@ -925,7 +925,7 @@ public class TestPlayer implements Player {
|
|||
// show library
|
||||
if (params[0].equals(SHOW_COMMAND_LIBRARY) && params.length == 1) {
|
||||
printStart(action.getActionName());
|
||||
printCards(computerPlayer.getLibrary().getCards(game));
|
||||
printCards(computerPlayer.getLibrary().getCards(game), false); // do not sort
|
||||
printEnd();
|
||||
actions.remove(action);
|
||||
wasProccessed = true;
|
||||
|
@ -973,7 +973,7 @@ public class TestPlayer implements Player {
|
|||
printStart(action.getActionName());
|
||||
printCards(game.getExile().getAllCards(game).stream()
|
||||
.filter(card -> card.isOwnedBy(computerPlayer.getId()))
|
||||
.collect(Collectors.toList()));
|
||||
.collect(Collectors.toList()), true);
|
||||
printEnd();
|
||||
actions.remove(action);
|
||||
wasProccessed = true;
|
||||
|
@ -1108,16 +1108,23 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
private void printCards(Set<Card> cards) {
|
||||
printCards(new ArrayList<>(cards));
|
||||
printCards(new ArrayList<>(cards), true);
|
||||
}
|
||||
|
||||
private void printCards(List<Card> cards) {
|
||||
private void printCards(List<Card> cards, boolean sorted) {
|
||||
System.out.println("Total cards: " + cards.size());
|
||||
|
||||
List<String> data = cards.stream()
|
||||
.map(Card::getIdName)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
List<String> data;
|
||||
if (sorted) {
|
||||
data = cards.stream()
|
||||
.map(Card::getIdName)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
data = cards.stream()
|
||||
.map(Card::getIdName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
for (String s : data) {
|
||||
System.out.println(s);
|
||||
|
@ -1365,7 +1372,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
if (foundCount != count) {
|
||||
printStart("Exile cards");
|
||||
printCards(game.getExile().getAllCards(game));
|
||||
printCards(game.getExile().getAllCards(game), true);
|
||||
printEnd();
|
||||
Assert.fail(action.getActionName() + " - exile zone must have " + count + " cards with name " + permanentName + ", but found " + foundCount);
|
||||
}
|
||||
|
|
|
@ -598,6 +598,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
|
||||
/**
|
||||
* Add a card to specified zone of specified player.
|
||||
* <p>
|
||||
* Zone.LIBRARY - adding by put on top (e.g. last added card goes to top of the library)
|
||||
*
|
||||
* @param gameZone {@link mage.constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or
|
||||
|
|
|
@ -630,10 +630,6 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
}
|
||||
|
||||
private void addTrigger(TriggeredAbility ability, MageObject attachedTo) {
|
||||
addTrigger(ability, null, attachedTo);
|
||||
}
|
||||
|
||||
private void addTrigger(TriggeredAbility ability, UUID sourceId, MageObject attachedTo) {
|
||||
if (sourceId == null) {
|
||||
triggers.add(ability, attachedTo);
|
||||
|
|
|
@ -73,10 +73,21 @@ public class Commander implements CommandObject {
|
|||
|
||||
// other abilities
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (!(ability instanceof SpellAbility) && !(ability instanceof PlayLandAbility)) {
|
||||
Ability newAbility = ability.copy();
|
||||
abilities.add(newAbility);
|
||||
// skip already added above
|
||||
if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip triggers
|
||||
// workaround to fix double triggers for commanders on battlefield (example: Esika, God of the Tree)
|
||||
// TODO: is commanders on command zone can have triggers (is there a card with triggered ability in all zones)?
|
||||
if (ability instanceof TriggeredAbility) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// OK, can add it (example: activated, static, alternative cost, etc)
|
||||
Ability newAbility = ability.copy();
|
||||
abilities.add(newAbility);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue