Test framework: added support to put mdf cards on battlefield by cheats or unit tests;

This commit is contained in:
Oleg Agafonov 2021-02-03 14:23:50 +04:00
parent be77ecea84
commit 4b9de96a6b
7 changed files with 111 additions and 49 deletions

View file

@ -15,10 +15,8 @@ import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.themes.ThemeType; import mage.client.themes.ThemeType;
import mage.client.util.ClientEventType; import mage.client.util.*;
import mage.client.util.Event; import mage.client.util.Event;
import mage.client.util.GUISizeHelper;
import mage.client.util.Listener;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.constants.Zone; import mage.constants.Zone;
@ -33,6 +31,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentCard;
import mage.players.Player; import mage.players.Player;
import mage.players.StubPlayer; import mage.players.StubPlayer;
import mage.util.CardUtil;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import mage.view.*; import mage.view.*;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -107,16 +106,19 @@ public class TestCardRenderDialog extends MageDialog {
ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code); ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code);
CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(), CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(),
new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt())); new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt()));
Card card = CardImpl.createCard(cardInfo.getClassName(), testSet); Card newCard = CardImpl.createCard(cardInfo.getClassName(), testSet);
if (extraAbilities != null) {
extraAbilities.forEach(ability -> card.addAbility(ability));
}
Set<Card> cardsList = new HashSet<>(); Set<Card> cardsList = new HashSet<>();
cardsList.add(card); cardsList.add(newCard);
game.loadCards(cardsList, controllerId); game.loadCards(cardsList, controllerId);
PermanentCard perm = new PermanentCard(card, controllerId, game); Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
if (extraAbilities != null) {
extraAbilities.forEach(ability -> permCard.addAbility(ability));
}
PermanentCard perm = new PermanentCard(permCard, controllerId, game);
if (damage > 0) perm.damage(damage, controllerId, null, game); if (damage > 0) perm.damage(damage, controllerId, null, game);
if (power > 0) perm.getPower().setValue(power); if (power > 0) perm.getPower().setValue(power);
if (toughness > 0) perm.getToughness().setValue(toughness); if (toughness > 0) perm.getToughness().setValue(toughness);
@ -125,8 +127,7 @@ public class TestCardRenderDialog extends MageDialog {
if (perm.isTransformable()) { if (perm.isTransformable()) {
perm.setTransformed(true); perm.setTransformed(true);
} }
PermanentView cardView = new PermanentView(perm, card, controllerId, game); PermanentView cardView = new PermanentView(perm, permCard, controllerId, game);
//cardView.setInViewerOnly(true);
return cardView; return cardView;
} }
@ -136,13 +137,15 @@ public class TestCardRenderDialog extends MageDialog {
ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code); ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code);
CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(), CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(),
new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt())); new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt()));
Card card = CardImpl.createCard(cardInfo.getClassName(), testSet); Card newCard = CardImpl.createCard(cardInfo.getClassName(), testSet);
Set<Card> cardsList = new HashSet<>(); Set<Card> cardsList = new HashSet<>();
cardsList.add(card); cardsList.add(newCard);
game.loadCards(cardsList, controllerId); game.loadCards(cardsList, controllerId);
PermanentCard perm = new PermanentCard(card, controllerId, game); Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentCard perm = new PermanentCard(permCard, controllerId, game);
perm.setFaceDown(true, game); perm.setFaceDown(true, game);
perm.setMorphed(isMorphed); perm.setMorphed(isMorphed);
perm.setManifested(isManifested); perm.setManifested(isManifested);
@ -151,7 +154,7 @@ public class TestCardRenderDialog extends MageDialog {
if (perm.isTransformable()) { if (perm.isTransformable()) {
perm.setTransformed(true); perm.setTransformed(true);
} }
PermanentView cardView = new PermanentView(perm, card, controllerId, game); PermanentView cardView = new PermanentView(perm, permCard, controllerId, game);
cardView.setInViewerOnly(false); // must false for face down cardView.setInViewerOnly(false); // must false for face down
return cardView; return cardView;
} }
@ -293,6 +296,8 @@ public class TestCardRenderDialog extends MageDialog {
cardViews.add(createHandCard(game, playerYou.getId(), "DKA", "140")); // Huntmaster of the Fells, transforms cardViews.add(createHandCard(game, playerYou.getId(), "DKA", "140")); // Huntmaster of the Fells, transforms
cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "401", 1, 1, 0, false, additionalIcons)); // Hinterland Drake cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "401", 1, 1, 0, false, additionalIcons)); // Hinterland Drake
cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "1441", 1, 1, 0, true, additionalIcons)); // Kathari Remnant cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "1441", 1, 1, 0, true, additionalIcons)); // Kathari Remnant
cardViews.add(createPermanentCard(game, playerYou.getId(), "KHM", "50", 1, 1, 0, true, additionalIcons)); // Cosima, God of the Voyage
//*/ //*/

View file

@ -21,6 +21,7 @@ import mage.server.util.ConfigWrapper;
import mage.server.util.PluginClassLoader; import mage.server.util.PluginClassLoader;
import mage.server.util.config.GamePlugin; import mage.server.util.config.GamePlugin;
import mage.server.util.config.Plugin; import mage.server.util.config.Plugin;
import mage.util.CardUtil;
import mage.util.Copier; import mage.util.Copier;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -247,14 +248,15 @@ public abstract class MageTestBase {
} else { } else {
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
CardInfo cardInfo = CardRepository.instance.findCard(cardName); CardInfo cardInfo = CardRepository.instance.findCard(cardName);
Card card = cardInfo != null ? cardInfo.getCard() : null; Card newCard = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) { if (newCard != null) {
if (gameZone == Zone.BATTLEFIELD) { if (gameZone == Zone.BATTLEFIELD) {
PermanentCard p = new PermanentCard(card, null, currentGame); Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentCard p = new PermanentCard(permCard, null, currentGame);
p.setTapped(tapped); p.setTapped(tapped);
perms.add(p); perms.add(p);
} else { } else {
cards.add(card); cards.add(newCard);
} }
} else { } else {
logger.fatal("Couldn't find a card: " + cardName); logger.fatal("Couldn't find a card: " + cardName);

View file

@ -33,6 +33,7 @@ import mage.server.util.PluginClassLoader;
import mage.server.util.config.GamePlugin; import mage.server.util.config.GamePlugin;
import mage.server.util.config.Plugin; import mage.server.util.config.Plugin;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import mage.util.CardUtil;
import mage.util.Copier; import mage.util.Copier;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -250,14 +251,15 @@ public abstract class MageTestPlayerBase {
} else { } else {
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
CardInfo cardInfo = CardRepository.instance.findCard(cardName); CardInfo cardInfo = CardRepository.instance.findCard(cardName);
Card card = cardInfo != null ? cardInfo.getCard() : null; Card newCard = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) { if (newCard != null) {
if (gameZone == Zone.BATTLEFIELD) { if (gameZone == Zone.BATTLEFIELD) {
PermanentCard p = new PermanentCard(card, null, currentGame); Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentCard p = new PermanentCard(permCard, null, currentGame);
p.setTapped(tapped); p.setTapped(tapped);
perms.add(p); perms.add(p);
} else { } else {
cards.add(card); cards.add(newCard);
} }
} else { } else {
logger.fatal("Couldn't find a card: " + cardName); logger.fatal("Couldn't find a card: " + cardName);
@ -404,23 +406,25 @@ public abstract class MageTestPlayerBase {
CustomTestCard.addAdditionalSubtypes(customName, additionalSubTypes); CustomTestCard.addAdditionalSubtypes(customName, additionalSubTypes);
CardSetInfo testSet = new CardSetInfo(customName, "custom", "123", Rarity.COMMON); CardSetInfo testSet = new CardSetInfo(customName, "custom", "123", Rarity.COMMON);
PermanentCard card = new PermanentCard(new CustomTestCard(controllerPlayer.getId(), testSet, cardType, spellCost), controllerPlayer.getId(), currentGame); Card newCard = new CustomTestCard(controllerPlayer.getId(), testSet, cardType, spellCost);
Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentCard permanent = new PermanentCard(permCard, controllerPlayer.getId(), currentGame);
switch (putAtZone) { switch (putAtZone) {
case BATTLEFIELD: case BATTLEFIELD:
getBattlefieldCards(controllerPlayer).add(card); getBattlefieldCards(controllerPlayer).add(permanent);
break; break;
case GRAVEYARD: case GRAVEYARD:
getGraveCards(controllerPlayer).add(card); getGraveCards(controllerPlayer).add(newCard);
break; break;
case HAND: case HAND:
getHandCards(controllerPlayer).add(card); getHandCards(controllerPlayer).add(newCard);
break; break;
case LIBRARY: case LIBRARY:
getLibraryCards(controllerPlayer).add(card); getLibraryCards(controllerPlayer).add(newCard);
break; break;
case COMMAND: case COMMAND:
getCommandCards(controllerPlayer).add(card); getCommandCards(controllerPlayer).add(newCard);
break; break;
default: default:
Assert.fail("Unsupported zone: " + putAtZone); Assert.fail("Unsupported zone: " + putAtZone);

View file

@ -655,11 +655,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
if (gameZone == Zone.BATTLEFIELD) { if (gameZone == Zone.BATTLEFIELD) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
CardInfo cardInfo = CardRepository.instance.findCard(cardName); CardInfo cardInfo = CardRepository.instance.findCard(cardName);
Card card = cardInfo != null ? cardInfo.getCard() : null; Card newCard = cardInfo != null ? cardInfo.getCard() : null;
if (card == null) { if (newCard == null) {
throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName); throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
} }
PermanentCard p = new PermanentCard(card.copy(), player.getId(), currentGame);
Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentCard p = new PermanentCard(permCard, player.getId(), currentGame);
p.setTapped(tapped); p.setTapped(tapped);
getBattlefieldCards(player).add(p); getBattlefieldCards(player).add(p);

View file

@ -1,6 +1,7 @@
package org.mage.test.serverside.performance; package org.mage.test.serverside.performance;
import mage.abilities.keyword.InfectAbility; import mage.abilities.keyword.InfectAbility;
import mage.cards.Card;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
@ -11,6 +12,7 @@ import mage.game.mulligan.LondonMulligan;
import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentImpl; import mage.game.permanent.PermanentImpl;
import mage.remote.traffic.ZippedObjectImpl; import mage.remote.traffic.ZippedObjectImpl;
import mage.util.CardUtil;
import mage.utils.CompressUtil; import mage.utils.CompressUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -24,7 +26,9 @@ public class SerializationTest extends CardTestPlayerBase {
@Test @Test
public void test_PermanentImpl_Simple() { public void test_PermanentImpl_Simple() {
CardInfo cardInfo = CardRepository.instance.findCard("Balduvian Bears"); CardInfo cardInfo = CardRepository.instance.findCard("Balduvian Bears");
PermanentImpl permanent = new PermanentCard(cardInfo.getCard(), playerA.getId(), currentGame); Card newCard = cardInfo.getCard();
Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentImpl permanent = new PermanentCard(permCard, playerA.getId(), currentGame);
currentGame.addPermanent(permanent, 0); currentGame.addPermanent(permanent, 0);
Object compressed = CompressUtil.compress(permanent); Object compressed = CompressUtil.compress(permanent);
@ -36,7 +40,9 @@ public class SerializationTest extends CardTestPlayerBase {
@Test @Test
public void test_PermanentImpl_MarkedDamageInfo() { public void test_PermanentImpl_MarkedDamageInfo() {
CardInfo cardInfo = CardRepository.instance.findCard("Balduvian Bears"); CardInfo cardInfo = CardRepository.instance.findCard("Balduvian Bears");
PermanentImpl permanent = new PermanentCard(cardInfo.getCard(), playerA.getId(), currentGame); Card newCard = cardInfo.getCard();
Card permCard = CardUtil.getDefaultCardSideForBattlefield(newCard);
PermanentImpl permanent = new PermanentCard(permCard, playerA.getId(), currentGame);
currentGame.addPermanent(permanent, 0); currentGame.addPermanent(permanent, 0);
// mark damage from infected ability // mark damage from infected ability

View file

@ -8,15 +8,20 @@ import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.TransformAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.LevelerCard; import mage.cards.LevelerCard;
import mage.cards.ModalDoubleFacesCard;
import mage.cards.SplitCard;
import mage.constants.SpellAbilityType;
import mage.game.Game; import mage.game.Game;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.util.CardUtil;
import javax.annotation.processing.SupportedSourceVersion; import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import java.util.UUID; import java.util.UUID;
/** /**
* Static permanent on the battlefield. There are possible multiple permanents per one card,
* so be carefull for targets (ids are different) and ZCC (zcc is static for permanent).
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedSourceVersion(SourceVersion.RELEASE_8)
@ -31,6 +36,22 @@ public class PermanentCard extends PermanentImpl {
public PermanentCard(Card card, UUID controllerId, Game game) { public PermanentCard(Card card, UUID controllerId, Game game) {
super(card.getId(), card.getOwnerId(), controllerId, card.getName()); super(card.getId(), card.getOwnerId(), controllerId, card.getName());
// usage check: you must put to play only real card's part
// if you use it in test code then call CardUtil.getDefaultCardSideForBattlefield for default side
// it's a basic check and still allows to create permanent from instant or sorcery
boolean goodForBattlefield = true;
if (card instanceof ModalDoubleFacesCard) {
goodForBattlefield = false;
} else if (card instanceof SplitCard) {
// fused spells allowed (it uses main card)
if (card.getSpellAbility() != null && !card.getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)) {
goodForBattlefield = false;
}
}
if (!goodForBattlefield) {
throw new IllegalArgumentException("ERROR, can't create permanent card from split or mdf: " + card.getName());
}
this.card = card; this.card = card;
this.zoneChangeCounter = card.getZoneChangeCounter(game); // local value already set to the raised number this.zoneChangeCounter = card.getZoneChangeCounter(game); // local value already set to the raised number
init(card, game); init(card, game);

View file

@ -15,10 +15,7 @@ import mage.abilities.effects.common.asthought.CanPlayCardControllerEffect;
import mage.abilities.effects.common.asthought.YouMaySpendManaAsAnyColorToCastTargetEffect; import mage.abilities.effects.common.asthought.YouMaySpendManaAsAnyColorToCastTargetEffect;
import mage.abilities.hint.Hint; import mage.abilities.hint.Hint;
import mage.abilities.hint.HintUtils; import mage.abilities.hint.HintUtils;
import mage.cards.Card; import mage.cards.*;
import mage.cards.MeldCard;
import mage.cards.ModalDoubleFacesCard;
import mage.cards.SplitCard;
import mage.constants.*; import mage.constants.*;
import mage.filter.Filter; import mage.filter.Filter;
import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.mageobject.NamePredicate;
@ -896,33 +893,36 @@ public final class CardUtil {
/** /**
* Put card to battlefield without resolve (for cheats and tests only) * Put card to battlefield without resolve (for cheats and tests only)
* *
* @param source must be non null (if you need it empty then use fakeSourceAbility) * @param source must be non null (if you need it empty then use fakeSourceAbility)
* @param game * @param game
* @param card * @param newCard
* @param player * @param player
*/ */
public static void putCardOntoBattlefieldWithEffects(Ability source, Game game, Card card, Player player) { public static void putCardOntoBattlefieldWithEffects(Ability source, Game game, Card newCard, Player player) {
// same logic as ZonesHandler->maybeRemoveFromSourceZone // same logic as ZonesHandler->maybeRemoveFromSourceZone
// workaround to put real permanent from one side (example: you call mdf card by cheats)
Card permCard = getDefaultCardSideForBattlefield(newCard);
// prepare card and permanent // prepare card and permanent
card.setZone(Zone.BATTLEFIELD, game); permCard.setZone(Zone.BATTLEFIELD, game);
card.setOwnerId(player.getId()); permCard.setOwnerId(player.getId());
PermanentCard permanent; PermanentCard permanent;
if (card instanceof MeldCard) { if (permCard instanceof MeldCard) {
permanent = new PermanentMeld(card, player.getId(), game); permanent = new PermanentMeld(permCard, player.getId(), game);
} else { } else {
permanent = new PermanentCard(card, player.getId(), game); permanent = new PermanentCard(permCard, player.getId(), game);
} }
// put onto battlefield with possible counters // put onto battlefield with possible counters
game.getPermanentsEntering().put(permanent.getId(), permanent); game.getPermanentsEntering().put(permanent.getId(), permanent);
card.checkForCountersToAdd(permanent, source, game); permCard.checkForCountersToAdd(permanent, source, game);
permanent.entersBattlefield(source, game, Zone.OUTSIDE, false); permanent.entersBattlefield(source, game, Zone.OUTSIDE, false);
game.addPermanent(permanent, game.getState().getNextPermanentOrderNumber()); game.addPermanent(permanent, game.getState().getNextPermanentOrderNumber());
game.getPermanentsEntering().remove(permanent.getId()); game.getPermanentsEntering().remove(permanent.getId());
// workaround for special tapped status from test framework's command (addCard) // workaround for special tapped status from test framework's command (addCard)
if (card instanceof PermanentCard && ((PermanentCard) card).isTapped()) { if (permCard instanceof PermanentCard && ((PermanentCard) permCard).isTapped()) {
permanent.setTapped(true); permanent.setTapped(true);
} }
@ -938,6 +938,27 @@ public final class CardUtil {
} }
} }
/**
* Choose default card's part to put on battlefield (for cheats and tests only)
*
* @param card
* @return
*/
public static Card getDefaultCardSideForBattlefield(Card card) {
// chose left side all time
Card permCard;
if (card instanceof SplitCard) {
permCard = card;
} else if (card instanceof AdventureCard) {
permCard = card;
} else if (card instanceof ModalDoubleFacesCard) {
permCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
} else {
permCard = card;
}
return permCard;
}
/** /**
* Return card name for same name searching * Return card name for same name searching
* *