* Double faces and adventure cards: improved support with some "exile and cast" effects like Hostage Taker (#7446);

This commit is contained in:
Oleg Agafonov 2021-01-27 10:13:10 +04:00
parent 43014f7f5e
commit e3db50f111
12 changed files with 201 additions and 190 deletions

View file

@ -188,11 +188,7 @@ class GontiLordOfLuxurySpendAnyManaEffect extends AsThoughEffectImpl implements
if (theCard == null) {
return false;
}
Card mainCard = theCard.getMainCard();
if (mainCard == null) {
return false;
}
objectId = mainCard.getId(); // for split cards
objectId = theCard.getMainCard().getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
// if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
@ -237,11 +233,7 @@ class GontiLordOfLuxuryLookEffect extends AsThoughEffectImpl {
if (theCard == null) {
return false;
}
Card mainCard = theCard.getMainCard();
if (mainCard == null) {
return false;
}
objectId = mainCard.getId(); // for split cards
objectId = theCard.getMainCard().getId(); // for split cards
if (affectedControllerId.equals(source.getControllerId())
&& game.getState().getZone(objectId) == Zone.EXILED) {
Player controller = game.getPlayer(source.getControllerId());

View file

@ -113,7 +113,7 @@ class IdentityThiefEffect extends OneShotEffect {
if (controller != null
&& targetPermanent != null
&& sourcePermanent != null) {
ContinuousEffect copyEffect = new CopyEffect(Duration.EndOfTurn, targetPermanent.getMainCard(), source.getSourceId());
ContinuousEffect copyEffect = new CopyEffect(Duration.EndOfTurn, targetPermanent, source.getSourceId());
copyEffect.setTargetPointer(new FixedTarget(sourcePermanent.getId()));
game.addEffect(copyEffect, source);
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());

View file

@ -8,8 +8,8 @@ import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.ReachAbility;
import mage.cards.Card;
@ -25,6 +25,7 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import mage.watchers.common.AttackedThisTurnWatcher;
import java.util.HashSet;
import java.util.Objects;
@ -52,14 +53,17 @@ public final class RobberOfTheRich extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Whenever Robber of the Rich attacks, if defending player has more cards in hand than you, exile the top card of their library. During any turn you attacked with a Rogue, you may cast that card and you may spend mana as though it were mana of any color to cast that spell.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
Ability ability = new ConditionalInterveningIfTriggeredAbility(
new AttacksTriggeredAbility(
new RobberOfTheRichEffect(), false, "", SetTargetPointer.PLAYER
), RobberOfTheRichCondition.instance, "Whenever {this} attacks, " +
), RobberOfTheRichAttacksCondition.instance, "Whenever {this} attacks, " +
"if defending player has more cards in hand than you, exile the top card of their library. " +
"During any turn you attacked with a Rogue, you may cast that card and " +
"you may spend mana as though it were mana of any color to cast that spell."
), new RobberOfTheRichWatcher());
"you may spend mana as though it were mana of any color to cast that spell.");
ability.addWatcher(new AttackedThisTurnWatcher());
ability.addHint(new ConditionHint(RobberOfTheRichAnyTurnAttackedCondition.instance));
this.addAbility(ability);
}
private RobberOfTheRich(final RobberOfTheRich card) {
@ -72,7 +76,7 @@ public final class RobberOfTheRich extends CardImpl {
}
}
enum RobberOfTheRichCondition implements Condition {
enum RobberOfTheRichAttacksCondition implements Condition {
instance;
@Override
@ -83,6 +87,30 @@ enum RobberOfTheRichCondition implements Condition {
}
}
enum RobberOfTheRichAnyTurnAttackedCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
// your turn
if (!source.isControlledBy(game.getActivePlayerId())) {
return false;
}
// attacked with Rogue
AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
return watcher != null && watcher.getAttackedThisTurnCreatures()
.stream()
.map(mor -> mor.getPermanentOrLKIBattlefield(game))
.filter(Objects::nonNull)
.anyMatch(permanent -> permanent.hasSubtype(SubType.ROGUE, game));
}
@Override
public String toString() {
return "During that turn you attacked with a Rogue";
}
}
class RobberOfTheRichEffect extends OneShotEffect {
RobberOfTheRichEffect() {
@ -114,129 +142,12 @@ class RobberOfTheRichEffect extends OneShotEffect {
// move card to exile
controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source, game, Zone.LIBRARY, true);
// Add effects only if the card has a spellAbility (e.g. not for lands).
if (card.getSpellAbility() == null) {
return true;
if (card.getSpellAbility() != null) {
// allow to cast the card
// and you may spend mana as though it were mana of any color to cast it
CardUtil.makeCardPlayableAndSpendManaAsAnyColor(game, source, card, Duration.Custom, RobberOfTheRichAnyTurnAttackedCondition.instance);
}
// allow to cast the card
game.addEffect(new RobberOfTheRichCastFromExileEffect(card.getId(), exileId), source);
// and you may spend mana as though it were mana of any color to cast it
ContinuousEffect effect = new RobberOfTheRichSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
return true;
}
}
class RobberOfTheRichCastFromExileEffect extends AsThoughEffectImpl {
private UUID cardId;
private UUID exileId;
RobberOfTheRichCastFromExileEffect(UUID cardId, UUID exileId) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
this.cardId = cardId;
this.exileId = exileId;
}
private RobberOfTheRichCastFromExileEffect(final RobberOfTheRichCastFromExileEffect effect) {
super(effect);
this.cardId = effect.cardId;
this.exileId = effect.exileId;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public RobberOfTheRichCastFromExileEffect copy() {
return new RobberOfTheRichCastFromExileEffect(this);
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
RobberOfTheRichWatcher watcher = game.getState().getWatcher(RobberOfTheRichWatcher.class);
if (watcher == null || !watcher.getAttackedWithRogue(source.getControllerId())) {
return false;
}
if (!sourceId.equals(cardId) || !source.isControlledBy(affectedControllerId)) {
return false;
}
ExileZone exileZone = game.getState().getExile().getExileZone(exileId);
if (exileZone != null && exileZone.contains(cardId)) {
return true;
}
discard();
return false;
}
}
class RobberOfTheRichSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
RobberOfTheRichSpendAnyManaEffect() {
super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit);
}
private RobberOfTheRichSpendAnyManaEffect(final RobberOfTheRichSpendAnyManaEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public RobberOfTheRichSpendAnyManaEffect copy() {
return new RobberOfTheRichSpendAnyManaEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
objectId = CardUtil.getMainCardId(game, objectId); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, fixedTarget.getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
return mana.getFirstAvailable();
}
}
class RobberOfTheRichWatcher extends Watcher {
private Set<UUID> rogueAttackers = new HashSet();
RobberOfTheRichWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.ATTACKER_DECLARED) {
return;
}
Permanent permanent = game.getPermanent(event.getSourceId());
if (permanent == null || !permanent.hasSubtype(SubType.ROGUE, game)) {
return;
}
rogueAttackers.add(event.getPlayerId());
}
@Override
public void reset() {
super.reset();
rogueAttackers.clear();
}
boolean getAttackedWithRogue(UUID playerId) {
return rogueAttackers.contains(playerId);
}
}

View file

@ -87,41 +87,3 @@ class StolenStrategyEffect extends OneShotEffect {
return true;
}
}
class StolenStrategyCastFromExileEffect extends AsThoughEffectImpl {
private final UUID cardId;
private final UUID exileId;
public StolenStrategyCastFromExileEffect(UUID cardId, UUID exileId) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it";
this.cardId = cardId;
this.exileId = exileId;
}
public StolenStrategyCastFromExileEffect(final StolenStrategyCastFromExileEffect effect) {
super(effect);
this.cardId = effect.cardId;
this.exileId = effect.exileId;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public StolenStrategyCastFromExileEffect copy() {
return new StolenStrategyCastFromExileEffect(this);
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(cardId) && source.isControlledBy(affectedControllerId)) {
ExileZone exileZone = game.getState().getExile().getExileZone(exileId);
return exileZone != null && exileZone.contains(cardId);
}
return false;
}
}

View file

@ -242,9 +242,9 @@ class ValkiGodOfLiesCopyExiledEffect extends OneShotEffect {
Cards cards = game.getExile().getExileZone(exileId);
if (!cards.isEmpty()
&& controller.choose(Outcome.Benefit, cards, target, game)) {
Card chosenExiledCreature = game.getCard(target.getFirstTarget());
if (chosenExiledCreature != null) {
ContinuousEffect copyEffect = new CopyEffect(Duration.WhileOnBattlefield, chosenExiledCreature.getMainCard(), source.getSourceId());
Card chosenExiledCard = game.getCard(target.getFirstTarget());
if (chosenExiledCard != null) {
ContinuousEffect copyEffect = new CopyEffect(Duration.WhileOnBattlefield, chosenExiledCard.getMainCard(), source.getSourceId());
copyEffect.setTargetPointer(new FixedTarget(Valki.getId()));
game.addEffect(copyEffect, source);
return true;

View file

@ -689,4 +689,58 @@ public class AdventureCardsTest extends CardTestPlayerBase {
execute();
assertAllCommandsUsed();
}
@Test
public void test_HostageTaker_CastFromExileAllParts() {
// bug: mdf must be playable as both sides
// https://github.com/magefree/mage/pull/7446
// Curious Pair {1}{G}, creature
// Treats to Share {G}, sorcery
// Create a Food token.
addCard(Zone.HAND, playerA, "Curious Pair");
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); // for prepare
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); // cast from hostage taker for any color
//
// When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker
// leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana
// as though it were mana of any type to cast that spell.
addCard(Zone.HAND, playerA, "Hostage Taker", 2); // {2}{U}{B}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
// prepare adventure card on battlefield
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
// turn 1 - exile by hostage
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
addTarget(playerA, "Curious Pair");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkExileCount("after exile 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
// play as creature for any color
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("after play 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair", 1);
// eat green mana (test what hostage's any color effect work)
activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 2);
// turn 3 - exile by hostage
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Hostage Taker");
addTarget(playerA, "Curious Pair");
waitStackResolved(3, PhaseStep.POSTCOMBAT_MAIN);
checkExileCount("after exile 3", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Curious Pair", 1);
// play as adventure spell
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Treats to Share");
waitStackResolved(3, PhaseStep.POSTCOMBAT_MAIN);
checkPermanentCount("after play 3", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Food", 1);
setStrictChooseMode(true);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
}

View file

@ -696,6 +696,46 @@ public class ModalDoubleFacesCardsTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Balduvian Bears", 2);
}
@Test
public void test_Single_HostageTaker_CastFromExile() {
// bug: mdf must be playable as both sides
// https://github.com/magefree/mage/pull/7446
// Akoum Warrior {5}{R} - creature
// Akoum Teeth - land
addCard(Zone.HAND, playerA, "Akoum Warrior");
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6); // cast from hostage taker for any color
//
// When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker
// leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana
// as though it were mana of any type to cast that spell.
addCard(Zone.HAND, playerA, "Hostage Taker", 1); // {2}{U}{B}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
// prepare mdf on battlefield
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", 6);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
// exile by hostage
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
addTarget(playerA, "Akoum Warrior");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkExileCount("after exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
// play as creature for any color
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Akoum Warrior", 1);
}
@Test
public void test_ETB_OnlySideCardsCanAddAbilitiesToGame() {
// possible bug: double triggers (loadCard adds abilities from main + side cards instead side card only)

View file

@ -2,11 +2,13 @@ package mage.abilities.effects.common.asthought;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.util.CardUtil;
import java.util.UUID;
@ -14,22 +16,31 @@ import java.util.UUID;
* Play card from current zone. Will be discarded on any card movements or blinks.
* <p>
* Recommends to use combo effects from CardUtil.makeCardPlayableAndSpendManaAsAnyColor instead signle effect
* <p>
* Affected to all card's parts
*
* @author JayDi85
*/
public class CanPlayCardControllerEffect extends AsThoughEffectImpl {
protected final MageObjectReference mor;
private final MageObjectReference mor;
private final Condition condition;
public CanPlayCardControllerEffect(Game game, UUID cardId, int cardZCC, Duration duration) {
this(game, cardId, cardZCC, duration, null);
}
public CanPlayCardControllerEffect(Game game, UUID cardId, int cardZCC, Duration duration, Condition condition) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, duration, Outcome.Benefit);
this.staticText = "You may play those card";
this.mor = new MageObjectReference(cardId, cardZCC, game);
this.condition = condition;
}
public CanPlayCardControllerEffect(final CanPlayCardControllerEffect effect) {
super(effect);
this.mor = effect.mor;
this.condition = effect.condition;
}
@Override
@ -48,6 +59,12 @@ public class CanPlayCardControllerEffect extends AsThoughEffectImpl {
discard();
return false;
}
return mor.refersTo(sourceId, game) && source.isControlledBy(affectedControllerId);
if (condition != null && !condition.apply(game, source)) {
return false;
}
UUID objectIdToCast = CardUtil.getMainCardId(game, sourceId); // affected to all card's parts
return mor.refersTo(objectIdToCast, game) && source.isControlledBy(affectedControllerId);
}
}

View file

@ -1,6 +1,7 @@
package mage.abilities.effects.common.asthought;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect;
import mage.constants.*;
@ -15,17 +16,27 @@ import java.util.UUID;
/**
* Spend mana as any color to cast targeted card. Will not affected after any card movements or blinks.
*
* Affects to all card's parts
*
* @author JayDi85
*/
public class YouMaySpendManaAsAnyColorToCastTargetEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
private final Condition condition;
public YouMaySpendManaAsAnyColorToCastTargetEffect(Duration duration) {
this(duration, null);
}
public YouMaySpendManaAsAnyColorToCastTargetEffect(Duration duration, Condition condition) {
super(AsThoughEffectType.SPEND_OTHER_MANA, duration, Outcome.Benefit);
this.staticText = "You may spend mana as though it were mana of any color to cast it";
this.condition = condition;
}
public YouMaySpendManaAsAnyColorToCastTargetEffect(final YouMaySpendManaAsAnyColorToCastTargetEffect effect) {
super(effect);
this.condition = effect.condition;
}
@Override
@ -40,10 +51,15 @@ public class YouMaySpendManaAsAnyColorToCastTargetEffect extends AsThoughEffectI
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (condition != null && !condition.apply(game, source)) {
return false;
}
objectId = CardUtil.getMainCardId(game, objectId); // for split cards
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
UUID targetId = CardUtil.getMainCardId(game, fixedTarget.getTarget()); // Affects to all card's parts (example: Hostage Taker exile mdf card)
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, fixedTarget.getTarget())
&& Objects.equals(objectId, targetId)
&& game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}

View file

@ -10,6 +10,7 @@ import mage.cards.Card;
import mage.cards.LevelerCard;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.util.CardUtil;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
@ -22,10 +23,8 @@ import java.util.UUID;
public class PermanentCard extends PermanentImpl {
protected int maxLevelCounters;
// A copy of the origin card that was cast (this is not the original card, so it's possible to chnage some attribute to this blueprint to change attributes to the permanent if it enters the battlefield with e.g. a subtype)
// A copy of the origin card that was cast (this is not the original card, so it's possible to change some attribute to this blueprint to change attributes to the permanent if it enters the battlefield with e.g. a subtype)
protected Card card;
// A copy of original card that was used for copy and create current permanent (used in copy effects and special commands like adjustTargets)
protected Card copiedFromCard;
// the number this permanent instance had
protected int zoneChangeCounter;
@ -220,4 +219,8 @@ public class PermanentCard extends PermanentImpl {
card.setZoneChangeCounter(value, game);
}
@Override
public Card getMainCard() {
return card.getMainCard();
}
}

View file

@ -3,6 +3,7 @@ package mage.game.permanent;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCost;
import mage.cards.Card;
import mage.constants.EmptyNames;
import mage.game.Game;
import mage.game.permanent.token.Token;
@ -118,4 +119,9 @@ public class PermanentToken extends PermanentImpl {
}
}
@Override
public Card getMainCard() {
// token don't have game card, so return itself
return this;
}
}

View file

@ -13,6 +13,7 @@ import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.*;
import mage.abilities.effects.ContinuousEffect;
@ -1024,21 +1025,30 @@ public final class CardUtil {
}
}
public static void makeCardPlayableAndSpendManaAsAnyColor(Game game, Ability source, Card card, Duration duration) {
makeCardPlayableAndSpendManaAsAnyColor(game, source, card, duration, null);
}
/**
* Add effects to game that allows to play/cast card from current zone and spend mana as any type for it.
* Effects will be discarded/ignored on any card movements or blinks (after ZCC change)
*
* Affected to all card's parts
*
* @param game
* @param card
* @param duration
* @param condition can be null
*/
public static void makeCardPlayableAndSpendManaAsAnyColor(Game game, Ability source, Card card, Duration duration) {
public static void makeCardPlayableAndSpendManaAsAnyColor(Game game, Ability source, Card card, Duration duration, Condition condition) {
// Effect can be used for cards in zones and permanents on battlefield
// So there is a workaround to get real ZCC (PermanentCard's ZCC is static, but it must be from Card's ZCC)
// PermanentCard's ZCC is static, but we need updated ZCC from the card (after moved to another zone)
// So there is a workaround to get actual card's ZCC
// Example: Hostage Taker
int zcc = game.getState().getZoneChangeCounter(card.getId());
game.addEffect(new CanPlayCardControllerEffect(game, card.getId(), zcc, duration), source);
game.addEffect(new YouMaySpendManaAsAnyColorToCastTargetEffect(duration).setTargetPointer(new FixedTarget(card.getId(), zcc)), source);
UUID objectId = card.getMainCard().getId();
int zcc = game.getState().getZoneChangeCounter(objectId);
game.addEffect(new CanPlayCardControllerEffect(game, objectId, zcc, duration, condition), source);
game.addEffect(new YouMaySpendManaAsAnyColorToCastTargetEffect(duration, condition).setTargetPointer(new FixedTarget(objectId, zcc)), source);
}
/**