mirror of
https://github.com/magefree/mage.git
synced 2026-01-09 12:22:10 -08:00
Modal double-faced cards - fixed game error on usage with some replacement effects (example: Diluvian Primordial, closes #12176) (#12184)
This commit is contained in:
parent
1ae48593a8
commit
36d6547bf8
10 changed files with 339 additions and 38 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
|
|
@ -115,8 +114,7 @@ public class MayCastTargetCardEffect extends OneShotEffect {
|
|||
|
||||
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
|
||||
boolean noMana = manaAdjustment == CastManaAdjustment.WITHOUT_PAYING_MANA_COST;
|
||||
controller.cast(controller.chooseAbilityForCast(card, game, noMana),
|
||||
game, noMana, new ApprovingObject(source, game));
|
||||
CardUtil.castSingle(controller, source, game, card, noMana, null);
|
||||
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
|
||||
} else {
|
||||
// TODO: support (and add tests!) for the non-NONE manaAdjustment
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package mage.abilities.effects.common.replacement;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -50,9 +51,21 @@ public class ThatSpellGraveyardExileReplacementEffect extends ReplacementEffectI
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
return zEvent.getToZone() == Zone.GRAVEYARD
|
||||
&& zEvent.getTargetId().equals(((FixedTarget) getTargetPointer()).getTarget())
|
||||
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1
|
||||
== game.getState().getZoneChangeCounter(zEvent.getTargetId());
|
||||
if (zEvent.getToZone() != Zone.GRAVEYARD) {
|
||||
return false;
|
||||
}
|
||||
Card cardMoving = game.getCard(zEvent.getTargetId());
|
||||
Card cardTarget = game.getCard(((FixedTarget) getTargetPointer()).getTarget());
|
||||
if (cardMoving == null || cardTarget == null) {
|
||||
return false;
|
||||
}
|
||||
// for MDFC.
|
||||
Card mainCardMoving = cardMoving.getMainCard();
|
||||
Card mainCardTarget = cardTarget.getMainCard();
|
||||
return mainCardMoving != null
|
||||
&& mainCardTarget != null
|
||||
&& mainCardMoving.getId().equals(mainCardTarget.getId())
|
||||
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1
|
||||
== game.getState().getZoneChangeCounter(mainCardMoving.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ public abstract class AdventureCard extends CardImpl {
|
|||
@Override
|
||||
public boolean moveToZone(Zone toZone, Ability source, Game game, boolean flag, List<UUID> appliedEffects) {
|
||||
if (super.moveToZone(toZone, source, game, flag, appliedEffects)) {
|
||||
game.getState().setZone(getSpellCard().getId(), toZone);
|
||||
Zone currentZone = game.getState().getZone(getId());
|
||||
game.getState().setZone(getSpellCard().getId(), currentZone);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ public abstract class ModalDoubleFacedCard extends CardImpl implements CardWithH
|
|||
@Override
|
||||
public boolean moveToZone(Zone toZone, Ability source, Game game, boolean flag, List<UUID> appliedEffects) {
|
||||
if (super.moveToZone(toZone, source, game, flag, appliedEffects)) {
|
||||
setSideZones(toZone, game);
|
||||
Zone currentZone = game.getState().getZone(getId());
|
||||
setSideZones(currentZone, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -131,7 +132,8 @@ public abstract class ModalDoubleFacedCard extends CardImpl implements CardWithH
|
|||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, Ability source, Game game, List<UUID> appliedEffects) {
|
||||
if (super.moveToExile(exileId, name, source, game, appliedEffects)) {
|
||||
setSideZones(Zone.EXILED, game);
|
||||
Zone currentZone = game.getState().getZone(getId());
|
||||
setSideZones(currentZone, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -233,10 +235,12 @@ public abstract class ModalDoubleFacedCard extends CardImpl implements CardWithH
|
|||
case MODAL_RIGHT:
|
||||
return this.rightHalfCard.cast(game, fromZone, ability, controllerId);
|
||||
default:
|
||||
if (this.leftHalfCard.getSpellAbility() != null)
|
||||
if (this.leftHalfCard.getSpellAbility() != null) {
|
||||
this.leftHalfCard.getSpellAbility().setControllerId(controllerId);
|
||||
if (this.rightHalfCard.getSpellAbility() != null)
|
||||
}
|
||||
if (this.rightHalfCard.getSpellAbility() != null) {
|
||||
this.rightHalfCard.getSpellAbility().setControllerId(controllerId);
|
||||
}
|
||||
return super.cast(game, fromZone, ability, controllerId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,8 +77,9 @@ public abstract class SplitCard extends CardImpl implements CardWithHalves {
|
|||
@Override
|
||||
public boolean moveToZone(Zone toZone, Ability source, Game game, boolean flag, List<UUID> appliedEffects) {
|
||||
if (super.moveToZone(toZone, source, game, flag, appliedEffects)) {
|
||||
game.getState().setZone(getLeftHalfCard().getId(), toZone);
|
||||
game.getState().setZone(getRightHalfCard().getId(), toZone);
|
||||
Zone currentZone = game.getState().getZone(getId());
|
||||
game.getState().setZone(getLeftHalfCard().getId(), currentZone);
|
||||
game.getState().setZone(getRightHalfCard().getId(), currentZone);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1494,6 +1494,10 @@ public final class CardUtil {
|
|||
}
|
||||
|
||||
public static void castSingle(Player player, Ability source, Game game, Card card, ManaCostsImpl<ManaCost> manaCost) {
|
||||
castSingle(player, source, game, card, false, manaCost);
|
||||
}
|
||||
|
||||
public static void castSingle(Player player, Ability source, Game game, Card card, boolean noMana, ManaCostsImpl<ManaCost> manaCost) {
|
||||
// handle split-cards
|
||||
if (card instanceof SplitCard) {
|
||||
SplitCardHalf leftHalfCard = ((SplitCard) card).getLeftHalfCard();
|
||||
|
|
@ -1560,8 +1564,8 @@ public final class CardUtil {
|
|||
}
|
||||
|
||||
// cast it
|
||||
player.cast(player.chooseAbilityForCast(card.getMainCard(), game, false),
|
||||
game, false, new ApprovingObject(source, game));
|
||||
player.cast(player.chooseAbilityForCast(card.getMainCard(), game, noMana),
|
||||
game, noMana, new ApprovingObject(source, game));
|
||||
|
||||
// turn off effect after cast on every possible card-face
|
||||
if (card instanceof SplitCard) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue