use of mage.cards.AdventureCard in project mage by magefree.
the class JourneyToTheOracleEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Card card = controller.getLibrary().getFromTop(game);
if (card == null) {
return false;
}
controller.revealCards(source, new CardsImpl(card), game);
if (card.isLand(game)) {
// note that MDFC land cards are handled differently: they can't be moved
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
// query player
if (!controller.chooseUse(outcome, "Cast " + card.getName() + " by paying {1}?", source, game)) {
return false;
}
// handle split-cards
if (card instanceof SplitCard) {
SplitCardHalf leftHalfCard = ((SplitCard) card).getLeftHalfCard();
SplitCardHalf rightHalfCard = ((SplitCard) card).getRightHalfCard();
// get additional cost if any
Costs additionalCostsLeft = leftHalfCard.getSpellAbility().getCosts();
Costs additionalCostsRight = rightHalfCard.getSpellAbility().getCosts();
// set alternative cost and any additional cost
controller.setCastSourceIdWithAlternateMana(leftHalfCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsLeft);
controller.setCastSourceIdWithAlternateMana(rightHalfCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsRight);
// allow the card to be cast
game.getState().setValue("PlayFromNotOwnHandZone" + leftHalfCard.getId(), Boolean.TRUE);
game.getState().setValue("PlayFromNotOwnHandZone" + rightHalfCard.getId(), Boolean.TRUE);
}
// handle MDFC
if (card instanceof ModalDoubleFacesCard) {
ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
ModalDoubleFacesCardHalf rightHalfCard = ((ModalDoubleFacesCard) card).getRightHalfCard();
// some MDFC cards are lands. IE: sea gate restoration
if (!leftHalfCard.isLand(game)) {
// get additional cost if any
Costs additionalCostsMDFCLeft = leftHalfCard.getSpellAbility().getCosts();
// set alternative cost and any additional cost
controller.setCastSourceIdWithAlternateMana(leftHalfCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsMDFCLeft);
}
if (!rightHalfCard.isLand(game)) {
// get additional cost if any
Costs additionalCostsMDFCRight = rightHalfCard.getSpellAbility().getCosts();
// set alternative cost and any additional cost
controller.setCastSourceIdWithAlternateMana(rightHalfCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsMDFCRight);
}
// allow the card to be cast
game.getState().setValue("PlayFromNotOwnHandZone" + leftHalfCard.getId(), Boolean.TRUE);
game.getState().setValue("PlayFromNotOwnHandZone" + rightHalfCard.getId(), Boolean.TRUE);
}
// handle adventure cards
if (card instanceof AdventureCard) {
Card creatureCard = card.getMainCard();
Card spellCard = ((AdventureCard) card).getSpellCard();
// get additional cost if any
Costs additionalCostsCreature = creatureCard.getSpellAbility().getCosts();
Costs additionalCostsSpellCard = spellCard.getSpellAbility().getCosts();
// set alternative cost and any additional cost
controller.setCastSourceIdWithAlternateMana(creatureCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsCreature);
controller.setCastSourceIdWithAlternateMana(spellCard.getId(), new ManaCostsImpl<>("{1}"), additionalCostsSpellCard);
// allow the card to be cast
game.getState().setValue("PlayFromNotOwnHandZone" + creatureCard.getId(), Boolean.TRUE);
game.getState().setValue("PlayFromNotOwnHandZone" + spellCard.getId(), Boolean.TRUE);
}
// normal card
if (!(card instanceof SplitCard) || !(card instanceof ModalDoubleFacesCard) || !(card instanceof AdventureCard)) {
// get additional cost if any
Costs additionalCostsNormalCard = card.getSpellAbility().getCosts();
controller.setCastSourceIdWithAlternateMana(card.getMainCard().getId(), new ManaCostsImpl<>("{1}"), additionalCostsNormalCard);
}
// cast it
controller.cast(controller.chooseAbilityForCast(card.getMainCard(), game, false), game, false, new ApprovingObject(source, game));
// turn off effect after cast on every possible card-face
if (card instanceof SplitCard) {
SplitCardHalf leftHalfCard = ((SplitCard) card).getLeftHalfCard();
SplitCardHalf rightHalfCard = ((SplitCard) card).getRightHalfCard();
game.getState().setValue("PlayFromNotOwnHandZone" + leftHalfCard.getId(), null);
game.getState().setValue("PlayFromNotOwnHandZone" + rightHalfCard.getId(), null);
}
if (card instanceof ModalDoubleFacesCard) {
ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
ModalDoubleFacesCardHalf rightHalfCard = ((ModalDoubleFacesCard) card).getRightHalfCard();
game.getState().setValue("PlayFromNotOwnHandZone" + leftHalfCard.getId(), null);
game.getState().setValue("PlayFromNotOwnHandZone" + rightHalfCard.getId(), null);
}
if (card instanceof AdventureCard) {
Card creatureCard = card.getMainCard();
Card spellCard = ((AdventureCard) card).getSpellCard();
game.getState().setValue("PlayFromNotOwnHandZone" + creatureCard.getId(), null);
game.getState().setValue("PlayFromNotOwnHandZone" + spellCard.getId(), null);
}
// turn off effect on a normal card
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return true;
}
use of mage.cards.AdventureCard in project mage by magefree.
the class AsThoughEffectImpl method allowCardToPlayWithoutMana.
/**
* Internal method to do the necessary to allow the card from objectId to be
* cast or played (if it's a land) without paying any mana. Additional costs
* (like sacrificing or discarding) have still to be payed. Checks if the
* card is of the correct type or in the correct zone have to be done
* before.
*
* @param objectId sourceId of the card to play
* @param source source ability that allows this effect
* @param affectedControllerId player allowed to play the card
* @param game
* @return
*/
protected boolean allowCardToPlayWithoutMana(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Player player = game.getPlayer(affectedControllerId);
Card card = game.getCard(objectId);
if (card == null || player == null) {
return false;
}
if (!card.isLand(game)) {
if (card instanceof SplitCard) {
Card leftCard = ((SplitCard) card).getLeftHalfCard();
player.setCastSourceIdWithAlternateMana(leftCard.getId(), null, leftCard.getSpellAbility().getCosts());
Card rightCard = ((SplitCard) card).getRightHalfCard();
player.setCastSourceIdWithAlternateMana(rightCard.getId(), null, rightCard.getSpellAbility().getCosts());
} else if (card instanceof ModalDoubleFacesCard) {
Card leftCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
Card rightCard = ((ModalDoubleFacesCard) card).getRightHalfCard();
// some MDFC's are land. IE: sea gate restoration
if (!leftCard.isLand(game)) {
player.setCastSourceIdWithAlternateMana(leftCard.getId(), null, leftCard.getSpellAbility().getCosts());
}
if (!rightCard.isLand(game)) {
player.setCastSourceIdWithAlternateMana(rightCard.getId(), null, rightCard.getSpellAbility().getCosts());
}
} else if (card instanceof AdventureCard) {
Card creatureCard = card.getMainCard();
Card spellCard = ((AdventureCard) card).getSpellCard();
player.setCastSourceIdWithAlternateMana(creatureCard.getId(), null, creatureCard.getSpellAbility().getCosts());
player.setCastSourceIdWithAlternateMana(spellCard.getId(), null, spellCard.getSpellAbility().getCosts());
}
player.setCastSourceIdWithAlternateMana(objectId, null, card.getSpellAbility().getCosts());
}
return true;
}
use of mage.cards.AdventureCard in project mage by magefree.
the class CardTextPredicate method apply.
@Override
public boolean apply(Card input, Game game) {
if (text.isEmpty() && !isUnique) {
return true;
}
if (text.isEmpty() && isUnique) {
boolean found = !seenCards.containsKey(input.getName());
seenCards.put(input.getName(), true);
return found;
}
// first check in card name
if (inNames) {
String fullName = input.getName();
if (input instanceof MockCard) {
fullName = ((MockCard) input).getFullName(true);
} else if (input instanceof ModalDoubleFacesCard) {
fullName = input.getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + ((ModalDoubleFacesCard) input).getRightHalfCard().getName();
} else if (input instanceof AdventureCard) {
fullName = input.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + ((AdventureCard) input).getSpellCard().getName();
}
if (fullName.toLowerCase(Locale.ENGLISH).contains(text.toLowerCase(Locale.ENGLISH))) {
if (isUnique && seenCards.containsKey(input.getName())) {
return false;
}
if (isUnique) {
seenCards.put(input.getName(), true);
}
return true;
}
}
// separate by spaces
String[] tokens = text.toLowerCase(Locale.ENGLISH).split(" ");
for (String token : tokens) {
boolean found = false;
if (!token.isEmpty()) {
// then try to find in rules
if (inRules) {
if (input instanceof SplitCard) {
for (String rule : ((SplitCard) input).getLeftHalfCard().getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
for (String rule : ((SplitCard) input).getRightHalfCard().getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
}
if (input instanceof ModalDoubleFacesCard) {
for (String rule : ((ModalDoubleFacesCard) input).getLeftHalfCard().getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
for (String rule : ((ModalDoubleFacesCard) input).getRightHalfCard().getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
}
if (input instanceof AdventureCard) {
for (String rule : ((AdventureCard) input).getSpellCard().getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
}
for (String rule : input.getRules(game)) {
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
found = true;
break;
}
}
}
if (inTypes) {
for (SubType subType : input.getSubtype(game)) {
if (subType.toString().equalsIgnoreCase(token)) {
found = true;
break;
}
}
for (SuperType superType : input.getSuperType()) {
if (superType.toString().equalsIgnoreCase(token)) {
found = true;
break;
}
}
}
}
if (found && isUnique && seenCards.containsKey(input.getName())) {
found = false;
}
if (!found) {
return false;
}
}
if (isUnique) {
seenCards.put(input.getName(), true);
}
return true;
}
use of mage.cards.AdventureCard in project mage by magefree.
the class CommandersCastTest method test_AdventureCard.
@Test
public void test_AdventureCard() {
// Player order: A -> D -> C -> B
// kill creature
addCustomEffect_TargetDamage(playerA, 10);
// use case:
// cast adventure spell from command zone (inc command tax to 1x)
// return to command zone
// cast adventure spell from command zone (inc command tax to 2x)
// return to command zone
// cast as creature (with 2x command tax)
// Curious Pair, creature, {1}{G}, 1/3
// Treats to Share, sorcery, {G}
// Create a Food token.
addCard(Zone.COMMAND, playerA, "Curious Pair", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
// for commander cost test
addCard(Zone.HAND, playerA, "Forest", 3);
// commander tax: 0
// both sides are playable
checkCommandCardCount("before cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
checkPlayableAbility("before cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", true);
checkPlayableAbility("before cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
// cast adventure spell
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
// return commander
setChoice(playerA, true);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkCommandCardCount("after first cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
checkPermanentCount("after first cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Food", 1);
// commander tax: 1x
// can't cast due commander cost added (we stil have 2x mana)
checkPlayableAbility("after first cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("after first cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
// commander tax: 1x
// play land number 1 and give extra {G}, so total 3x
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
checkPlayableAbility("after mana add", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("after mana add", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
// play adventure spell, but keep it
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
// do not return commander
setChoice(playerA, false);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("after second cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Food", 2);
checkPlayableAbility("after second cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("after second cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
// wait next turn
// commander tax: 2x BUT it doesn't apply to exile zone (e.g. must use 2x mana instead 6x)
// it doesn't add commander tax too
castSpell(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
waitStackResolved(5, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("after exile cast", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
checkPermanentTapped("after exile cast", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest", true, 4 - 2);
// return commander to command zone
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "target damage 10", "Curious Pair");
// return to command zone
setChoice(playerA, true);
// can't cast - only {2} mana, but need {G} + {2} + {2}
checkPlayableAbility("after return 2", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("after return 2", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
// turn 9
// commander tax: 2x
// mana: {G}{G}{G}{G}
// can't cast adventure spell for {G} + {2} + {2}
// can't cast creature spell for {G}{G} + {2} + {2}
runCode("check commander tax 2x", 9, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
AdventureCard card = (AdventureCard) game.getCommanderCardsFromCommandZone(player, CommanderCardType.ANY).stream().findFirst().get();
Assert.assertEquals(2, CommanderCastCountValue.instance.calculate(game, card.getSpellAbility(), null));
Assert.assertEquals(2, CommanderCastCountValue.instance.calculate(game, card.getSpellCard().getSpellAbility(), null));
});
checkPlayableAbility("before last cast 1", 9, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("before last cast 1", 9, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
// play land number 2 - can play adventure spell
playLand(9, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
// commander tax: 2x
// mana: {G}{G}{G}{G}{G}
checkPlayableAbility("before last cast 2", 9, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
checkPlayableAbility("before last cast 2", 9, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
// turn 13
// play land number 3 - can play all parts
playLand(13, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
// commander tax: 2x
// mana: {G}{G}{G}{G}{G}{G}
checkPlayableAbility("before last cast 3", 13, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", true);
checkPlayableAbility("before last cast 3", 13, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
// cast creature
castSpell(13, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
waitStackResolved(13, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("after last cast", 13, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
checkPermanentTapped("after last cast", 13, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest", true, 2 + 2 + 2);
runCode("check commander tax 3x", 13, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
AdventureCard card = (AdventureCard) game.getCard(game.getCommandersIds(player, CommanderCardType.ANY, false).stream().findFirst().get());
Assert.assertEquals(3, CommanderCastCountValue.instance.calculate(game, card.getSpellAbility(), null));
Assert.assertEquals(3, CommanderCastCountValue.instance.calculate(game, card.getSpellCard().getSpellAbility(), null));
});
setStrictChooseMode(true);
setStopAt(13, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
use of mage.cards.AdventureCard in project mage by magefree.
the class EtherealValkyrieEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.drawCards(1, source, game);
TargetCardInHand targetCard = new TargetCardInHand(new FilterCard("card to exile face down. It becomes foretold."));
if (controller.chooseTarget(Outcome.Benefit, targetCard, source, game)) {
Card exileCard = game.getCard(targetCard.getFirstTarget());
if (exileCard == null) {
return false;
}
// process Split, MDFC, and Adventure cards first
// note that 'Foretell Cost' refers to the main card (left) and 'Foretell Split Cost' refers to the (right) card if it exists
ForetellAbility foretellAbility = null;
if (exileCard instanceof SplitCard) {
String leftHalfCost = CardUtil.reduceCost(((SplitCard) exileCard).getLeftHalfCard().getManaCost(), 2).getText();
String rightHalfCost = CardUtil.reduceCost(((SplitCard) exileCard).getRightHalfCard().getManaCost(), 2).getText();
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Cost", leftHalfCost);
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Split Cost", rightHalfCost);
foretellAbility = new ForetellAbility(exileCard, leftHalfCost, rightHalfCost);
} else if (exileCard instanceof ModalDoubleFacesCard) {
ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) exileCard).getLeftHalfCard();
if (!leftHalfCard.isLand(game)) {
String leftHalfCost = CardUtil.reduceCost(leftHalfCard.getManaCost(), 2).getText();
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Cost", leftHalfCost);
ModalDoubleFacesCardHalf rightHalfCard = ((ModalDoubleFacesCard) exileCard).getRightHalfCard();
if (rightHalfCard.isLand(game)) {
foretellAbility = new ForetellAbility(exileCard, leftHalfCost);
} else {
String rightHalfCost = CardUtil.reduceCost(rightHalfCard.getManaCost(), 2).getText();
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Split Cost", rightHalfCost);
foretellAbility = new ForetellAbility(exileCard, leftHalfCost, rightHalfCost);
}
}
} else if (exileCard instanceof AdventureCard) {
String creatureCost = CardUtil.reduceCost(exileCard.getMainCard().getManaCost(), 2).getText();
String spellCost = CardUtil.reduceCost(((AdventureCard) exileCard).getSpellCard().getManaCost(), 2).getText();
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Cost", creatureCost);
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Split Cost", spellCost);
foretellAbility = new ForetellAbility(exileCard, creatureCost, spellCost);
} else {
// normal card
String costText = CardUtil.reduceCost(exileCard.getManaCost(), 2).getText();
game.getState().setValue(exileCard.getId().toString() + "Foretell Cost", costText);
foretellAbility = new ForetellAbility(exileCard, costText);
}
// note that the card is not foretell'd into exile, it is put into exile and made foretold
if (foretellAbility != null) {
// copy source and use it for the foretold effect on the exiled card
// bug #8673
Ability copiedSource = source.copy();
copiedSource.newId();
copiedSource.setSourceId(exileCard.getId());
game.getState().setValue(exileCard.getMainCard().getId().toString() + "Foretell Turn Number", game.getTurnNum());
UUID exileId = CardUtil.getExileZoneId(exileCard.getMainCard().getId().toString() + "foretellAbility", game);
controller.moveCardsToExile(exileCard, source, game, true, exileId, " Foretell Turn Number: " + game.getTurnNum());
exileCard.setFaceDown(true, game);
foretellAbility.setSourceId(exileCard.getId());
foretellAbility.setControllerId(exileCard.getOwnerId());
game.getState().addOtherAbility(exileCard, foretellAbility);
foretellAbility.activate(game, true);
ContinuousEffect effect = foretellAbility.new ForetellAddCostEffect(new MageObjectReference(exileCard, game));
game.addEffect(effect, copiedSource);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.FORETOLD, exileCard.getId(), null, null));
return true;
}
}
}
return false;
}
Aggregations