mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
refactor: improved Manifest effects to use shared code, added docs, todos and tests for all simple usages (part of #11873)
This commit is contained in:
parent
5c07b2e422
commit
00c3efedcf
6 changed files with 208 additions and 146 deletions
|
|
@ -1,28 +1,20 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.abilities.effects.keyword.ManifestEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
|
|
@ -66,42 +58,15 @@ class ScrollOfFateEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null
|
||||
|| controller.getHand().isEmpty()) {
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TargetCardInHand targetCard = new TargetCardInHand();
|
||||
if (!controller.chooseTarget(Outcome.PutCardInPlay, controller.getHand(),
|
||||
targetCard, source, game)) {
|
||||
if (!controller.chooseTarget(Outcome.PutCardInPlay, controller.getHand(), targetCard, source, game)) {
|
||||
return false;
|
||||
}
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
Set<Card> cards = targetCard
|
||||
.getTargets()
|
||||
.stream()
|
||||
.map(game::getCard)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
cards.stream().forEach(card -> {
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.isCreature(game)) {
|
||||
manaCosts = card.getSpellAbility() != null ? card.getSpellAbility().getManaCosts() : null;
|
||||
if (manaCosts == null) {
|
||||
manaCosts = new ManaCostsImpl<>("{0}");
|
||||
}
|
||||
}
|
||||
MageObjectReference objectReference = new MageObjectReference(card.getId(),
|
||||
card.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference,
|
||||
Duration.Custom, BecomesFaceDownCreatureEffect.FaceDownType.MANIFESTED), newSource);
|
||||
});
|
||||
controller.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
cards.stream()
|
||||
.map(Card::getId)
|
||||
.map(game::getPermanent)
|
||||
.filter(permanent -> permanent != null)
|
||||
.forEach(permanent -> permanent.setManifested(true));
|
||||
return true;
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, controller, new CardsImpl(targetCard.getTargets()).getCards(game));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,24 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.abilities.effects.keyword.ManifestEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -83,31 +81,12 @@ class ThievingAmalgamManifestEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player active = game.getPlayer(game.getActivePlayerId());
|
||||
if (controller == null || active == null) {
|
||||
Player targetPlayer = game.getPlayer(game.getActivePlayerId());
|
||||
if (controller == null || targetPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
Set<Card> cards = active.getLibrary().getTopCards(game, 1);
|
||||
cards.stream().forEach(card -> {
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.isCreature(game)) {
|
||||
manaCosts = card.getSpellAbility() != null ? card.getSpellAbility().getManaCosts() : null;
|
||||
if (manaCosts == null) {
|
||||
manaCosts = new ManaCostsImpl<>("{0}");
|
||||
}
|
||||
}
|
||||
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, BecomesFaceDownCreatureEffect.FaceDownType.MANIFESTED), newSource);
|
||||
});
|
||||
controller.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
cards.stream()
|
||||
.map(Card::getId)
|
||||
.map(game::getPermanent)
|
||||
.filter(permanent -> permanent != null)
|
||||
.forEach(permanent -> permanent.setManifested(true));
|
||||
return true;
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, controller, targetPlayer.getLibrary().getTopCards(game, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,101 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*/
|
||||
public class ManifestTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_Simple_ManifestFromOwnLibrary() {
|
||||
// Manifest the top card of your library.
|
||||
addCard(Zone.HAND, playerA, "Soul Summons", 1); // {1}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
|
||||
// manifest
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Simple_ManifestFromHand() {
|
||||
// {T}: Manifest a card from your hand.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Scroll of Fate", 1);
|
||||
addCard(Zone.HAND, playerA, "Basking Rootwalla", 1); // 1/1
|
||||
|
||||
// manifest
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Manifest");
|
||||
addTarget(playerA, "Basking Rootwalla");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Simple_ManifestTargetPlayer() {
|
||||
// Exile target creature. Its controller manifests the top card of their library.
|
||||
addCard(Zone.HAND, playerA, "Reality Shift", 1); // {1}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears", 1);
|
||||
|
||||
// manifest
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reality Shift");
|
||||
addTarget(playerA, "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Simple_ManifestFromOpponentLibrary() {
|
||||
// At the beginning of each opponent's upkeep, you manifest the top card of that player's library.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Thieving Amalgam", 1);
|
||||
|
||||
// no drew on first turn, so use 5 turns to check same libs size at the end
|
||||
runCode("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
Assert.assertEquals("libraries must be same on start", playerA.getLibrary().size(), playerB.getLibrary().size());
|
||||
});
|
||||
|
||||
// turn 1
|
||||
checkPermanentCount("turn 1.A - no face down", 1, PhaseStep.PRECOMBAT_MAIN, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
checkPermanentCount("turn 1.B - no face down", 1, PhaseStep.PRECOMBAT_MAIN, playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
|
||||
// turn 2
|
||||
checkPermanentCount("turn 2.A - +1 face down", 2, PhaseStep.PRECOMBAT_MAIN, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
checkPermanentCount("turn 2.B - no face down", 2, PhaseStep.PRECOMBAT_MAIN, playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
|
||||
// turn 3
|
||||
checkPermanentCount("turn 3.A - +1 face down", 3, PhaseStep.PRECOMBAT_MAIN, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
checkPermanentCount("turn 3.B - no face down", 3, PhaseStep.PRECOMBAT_MAIN, playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
|
||||
// turn 4
|
||||
checkPermanentCount("turn 4.A - +2 face down", 4, PhaseStep.PRECOMBAT_MAIN, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2);
|
||||
checkPermanentCount("turn 4.B - no face down", 4, PhaseStep.PRECOMBAT_MAIN, playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
|
||||
// turn 5
|
||||
checkPermanentCount("turn 5.A - +2 face down", 5, PhaseStep.PRECOMBAT_MAIN, playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2);
|
||||
checkPermanentCount("turn 5.B - no face down", 5, PhaseStep.PRECOMBAT_MAIN, playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2);
|
||||
assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
|
||||
Assert.assertEquals("manifested cards must be taken from opponent's library", 2, playerA.getLibrary().size() - playerB.getLibrary().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that ETB triggered abilities did not trigger for manifested cards
|
||||
*/
|
||||
|
|
@ -540,6 +635,8 @@ public class ManifestTest extends CardTestPlayerBase {
|
|||
.filter(permanent -> permanent.isFaceDown(game))
|
||||
.filter(permanent -> {
|
||||
Assert.assertEquals("face down permanent must have not name", "", permanent.getName());
|
||||
// TODO: buggy, manifested card must have some rules
|
||||
//Assert.assertTrue("face down permanent must have abilities", permanent.getAbilities().size() > 0);
|
||||
return true;
|
||||
})
|
||||
.findFirst()
|
||||
|
|
@ -559,6 +656,8 @@ public class ManifestTest extends CardTestPlayerBase {
|
|||
.filter(p -> {
|
||||
CardView debugView = new CardView((PermanentCard) currentGame.getPermanent(p.getId()), currentGame, false, false);
|
||||
Assert.assertNotEquals("face down view must have name", "", p.getName());
|
||||
// TODO: buggy, manifested card must have some rules
|
||||
//Assert.assertTrue("face down view must have abilities", p.getRules().size() > 0);
|
||||
return true;
|
||||
})
|
||||
.findFirst()
|
||||
|
|
@ -567,9 +666,9 @@ public class ManifestTest extends CardTestPlayerBase {
|
|||
return permanentView;
|
||||
}
|
||||
|
||||
private void assertFaceDown(String checkInfo, PermanentView faceDownPermanentView, String needRealName, String needFaceDownStatus, boolean needShowRealInfo) {
|
||||
private void assertFaceDownManifest(String checkInfo, PermanentView faceDownPermanentView, String needRealName, boolean needShowRealInfo) {
|
||||
String info = checkInfo + " - " + faceDownPermanentView;
|
||||
String needName = CardUtil.getCardNameForGUI(needShowRealInfo ? needRealName : "", needFaceDownStatus);
|
||||
String needName = CardUtil.getCardNameForGUI(needShowRealInfo ? needRealName : "", TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST);
|
||||
|
||||
// check view
|
||||
Assert.assertTrue(info + " - wrong face down status", faceDownPermanentView.isFaceDown());
|
||||
|
|
@ -600,11 +699,11 @@ public class ManifestTest extends CardTestPlayerBase {
|
|||
runCode("on active game", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
// hide from opponent
|
||||
PermanentView permanent = findFaceDownPermanent(game, playerA, playerB);
|
||||
assertFaceDown("in game: must hide from opponent", permanent, "Mountain", TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, false);
|
||||
assertFaceDownManifest("in game: must hide from opponent", permanent, "Mountain", false);
|
||||
|
||||
// show for yourself
|
||||
permanent = findFaceDownPermanent(game, playerB, playerB);
|
||||
assertFaceDown("in game: must show for yourself", permanent, "Mountain", TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, true);
|
||||
assertFaceDownManifest("in game: must show for yourself", permanent, "Mountain", true);
|
||||
});
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
|
@ -617,9 +716,9 @@ public class ManifestTest extends CardTestPlayerBase {
|
|||
|
||||
// show all after game end
|
||||
PermanentView permanent = findFaceDownPermanent(currentGame, playerA, playerB);
|
||||
assertFaceDown("end game: must show for opponent", permanent, "Mountain", TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, true);
|
||||
assertFaceDownManifest("end game: must show for opponent", permanent, "Mountain", true);
|
||||
//
|
||||
permanent = findFaceDownPermanent(currentGame, playerB, playerB);
|
||||
assertFaceDown("end game: must show for yourself", permanent, "Mountain", TokenRepository.XMAGE_IMAGE_NAME_FACE_DOWN_MANIFEST, true);
|
||||
assertFaceDownManifest("end game: must show for yourself", permanent, "Mountain", true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.keyword;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
|
|
@ -22,7 +21,36 @@ import mage.util.CardUtil;
|
|||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
* Manifest
|
||||
* <p>
|
||||
* 701.34a
|
||||
* To manifest a card, turn it face down. It becomes a 2/2 face-down creature card with no text, no name, no subtypes,
|
||||
* and no mana cost. Put that card onto the battlefield face down. That permanent is a manifested permanent for as
|
||||
* long as it remains face down. The effect defining its characteristics works while the card is face down and ends
|
||||
* when it’s turned face up.
|
||||
* <p>
|
||||
* 701.34b
|
||||
* Any time you have priority, you may turn a manifested permanent you control face up. This is a special action
|
||||
* that doesn’t use the stack (see rule 116.2b). To do this, show all players that the card representing that
|
||||
* permanent is a creature card and what that card’s mana cost is, pay that cost, then turn the permanent face up.
|
||||
* The effect defining its characteristics while it was face down ends, and it regains its normal characteristics.
|
||||
* (If the card representing that permanent isn’t a creature card or it doesn’t have a mana cost, it can’t be turned
|
||||
* face up this way.)
|
||||
* <p>
|
||||
* 701.34c TODO: need support it
|
||||
* If a card with morph is manifested, its controller may turn that card face up using either the procedure
|
||||
* described in rule 702.37e to turn a face-down permanent with morph face up or the procedure described above
|
||||
* to turn a manifested permanent face up.
|
||||
* <p>
|
||||
* 701.34d TODO: need support it
|
||||
* If a card with disguise is manifested, its controller may turn that card face up using either the procedure
|
||||
* described in rule 702.168d to turn a face-down permanent with disguise face up or the procedure described
|
||||
* above to turn a manifested permanent face up.
|
||||
* <p>
|
||||
* 701.34e TODO: need support it
|
||||
* If an effect instructs a player to manifest multiple cards from their library, those cards are manifested one at a time.
|
||||
*
|
||||
* @author LevelX2, JayDi85
|
||||
*/
|
||||
public class ManifestEffect extends OneShotEffect {
|
||||
|
||||
|
|
@ -58,33 +86,58 @@ public class ManifestEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
int value = amount.calculate(game, source, this);
|
||||
Set<Card> cards = controller.getLibrary().getTopCards(game, value);
|
||||
for (Card card : cards) {
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.isCreature(game)) {
|
||||
manaCosts = card.getSpellAbility() != null ? card.getSpellAbility().getManaCosts() : null;
|
||||
if (manaCosts == null) {
|
||||
manaCosts = new ManaCostsImpl<>("{0}");
|
||||
}
|
||||
}
|
||||
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
|
||||
}
|
||||
controller.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
for (Card card : cards) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
int manifestAmount = amount.calculate(game, source, this);
|
||||
return doManifestCards(game, source, controller, controller.getLibrary().getTopCards(game, manifestAmount));
|
||||
}
|
||||
|
||||
public static boolean doManifestCards(Game game, Ability source, Player manifestPlayer, Set<Card> cardsToManifest) {
|
||||
if (cardsToManifest.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare source ability
|
||||
// TODO: looks buggy, must not change source ability!
|
||||
// TODO: looks buggy, if target player manifested then source's controllerId will be wrong (not who manifested)
|
||||
// so BecomesFaceDownCreatureEffect will see wrong source.controllerId
|
||||
// (possible bugs: keep manifested after player leave/lose?)
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
|
||||
// prepare face down effect for battlefield permanents
|
||||
// TODO: need research - why it add effect before move?!
|
||||
for (Card card : cardsToManifest) {
|
||||
// search mana cost for a face up ability (look at face side of the double side card)
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.isCreature(game)) {
|
||||
manaCosts = card.getSpellAbility() != null ? card.getSpellAbility().getManaCosts() : null;
|
||||
if (manaCosts == null) {
|
||||
manaCosts = new ManaCostsImpl<>("{0}");
|
||||
}
|
||||
}
|
||||
// zcc + 1 for use case with Rally the Ancestors (see related test)
|
||||
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
}
|
||||
|
||||
// move cards to battlefield as face down
|
||||
// TODO: possible buggy for multiple cards, see rule 701.34e - it require manifest one by one (card to check: Omarthis, Ghostfire Initiate)
|
||||
manifestPlayer.moveCards(cardsToManifest, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
for (Card card : cardsToManifest) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
// TODO: why it set manifested here (face down effect doesn't work?!)
|
||||
// TODO: add test with battlefield trigger/watcher (must not see normal card, must not see face down status without manifest)
|
||||
permanent.setManifested(true);
|
||||
} else {
|
||||
// TODO: looks buggy, card can't be moved to battlefield, but face down effect already active
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
|
|
|
|||
|
|
@ -1,24 +1,12 @@
|
|||
|
||||
package mage.abilities.effects.keyword;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect.FaceDownType;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
|
@ -48,31 +36,11 @@ public class ManifestTargetPlayerEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (targetPlayer != null) {
|
||||
Ability newSource = source.copy();
|
||||
newSource.setWorksFaceDown(true);
|
||||
Set<Card> cards = targetPlayer.getLibrary().getTopCards(game, amount);
|
||||
for (Card card : cards) {
|
||||
ManaCosts manaCosts = null;
|
||||
if (card.isCreature(game)) {
|
||||
manaCosts = card.getSpellAbility() != null ? card.getSpellAbility().getManaCosts() : null;
|
||||
if (manaCosts == null) {
|
||||
manaCosts = new ManaCostsImpl<>("{0}");
|
||||
}
|
||||
}
|
||||
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
|
||||
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
|
||||
}
|
||||
targetPlayer.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null);
|
||||
for (Card card : cards) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
permanent.setManifested(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (targetPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
return ManifestEffect.doManifestCards(game, source, targetPlayer, targetPlayer.getLibrary().getTopCards(game, amount));
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
|
|
|
|||
|
|
@ -791,14 +791,12 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
|
||||
@Override
|
||||
public boolean turnFaceUp(Ability source, Game game, UUID playerId) {
|
||||
setFaceDown(false, game);
|
||||
return true;
|
||||
throw new IllegalStateException("Spells un-support turn face up commands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turnFaceDown(Ability source, Game game, UUID playerId) {
|
||||
setFaceDown(true, game);
|
||||
return true;
|
||||
throw new IllegalStateException("Spells un-support turn face up commands");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue