mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
* Meld Keyword - Fixed that the melt status was not correctly handled related to rollbacks or AI game simulation (fixes #6723).
This commit is contained in:
parent
ecc05f9535
commit
ba31b956dc
5 changed files with 60 additions and 21 deletions
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -158,12 +157,10 @@ public class MeldTest extends CardTestPlayerBase {
|
|||
|
||||
// {T}: Add {C}.
|
||||
// {R},{T}: Target creature gains haste until end of turn.
|
||||
// {3}{R}{R},{T}: If you both own and control Hanweir Battlements and a creature named Hanweir Garrison, exile them, then meld them into Hanweir, the Writhing Township.
|
||||
// {3}{R}{R},{T}: If you both own and control Hanweir Battlements and a creature named Hanweir Garrison, exile them,
|
||||
// then meld them into Hanweir, the Writhing Township.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hanweir Battlements"); // Land
|
||||
|
||||
// Brisela, Voice of Nightmares 9/10
|
||||
// Flying, First strike, Vigilance, Lifelink
|
||||
// Your opponents can't cast spells with converted mana cost 3 or less.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
|
||||
// Return target creature to its owner's hand.
|
||||
addCard(Zone.HAND, playerB, "Unsummon", 1); // Instant {U}
|
||||
|
@ -180,4 +177,40 @@ public class MeldTest extends CardTestPlayerBase {
|
|||
assertHandCount(playerA, "Hanweir Garrison", 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmeldAfterRollback() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
|
||||
// Whenever Hanweir Garrison attacks, put two 1/1 red Human creature tokens onto the battlefield tapped and attacking.
|
||||
// <i>(Melds with Hanweir Battlements.)</i>
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hanweir Garrison"); // Creature 2/3 {2}{R}
|
||||
|
||||
// {T}: Add {C}.
|
||||
// {R},{T}: Target creature gains haste until end of turn.
|
||||
// {3}{R}{R},{T}: If you both own and control Hanweir Battlements and a creature named Hanweir Garrison, exile them,
|
||||
// then meld them into Hanweir, the Writhing Township.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Hanweir Battlements"); // Land
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
|
||||
// Return target creature to its owner's hand.
|
||||
addCard(Zone.HAND, playerB, "Unsummon", 1); // Instant {U}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}{R}{R}");
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Unsummon", "Hanweir, the Writhing Township");
|
||||
|
||||
rollbackTurns(2, PhaseStep.BEGIN_COMBAT, playerB, 0);
|
||||
rollbackAfterActionsStart();
|
||||
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Unsummon", "Hanweir, the Writhing Township");
|
||||
rollbackAfterActionsEnd();
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Unsummon", 1);
|
||||
|
||||
assertHandCount(playerA, "Hanweir Battlements", 1);
|
||||
assertHandCount(playerA, "Hanweir Garrison", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -80,7 +79,7 @@ public class MeldEffect extends OneShotEffect {
|
|||
meldCard.setOwnerId(controller.getId());
|
||||
meldCard.setTopHalfCard(meldWithCard, game);
|
||||
meldCard.setBottomHalfCard(sourceCard, game);
|
||||
meldCard.setMelded(true);
|
||||
meldCard.setMelded(true, game);
|
||||
game.addMeldCard(meldCard.getId(), meldCard);
|
||||
game.getState().addCard(meldCard);
|
||||
meldCard.setZone(Zone.EXILED, game);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mage.cards;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
|
@ -8,9 +10,6 @@ import mage.game.Game;
|
|||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author emerald000
|
||||
*/
|
||||
|
@ -20,7 +19,6 @@ public abstract class MeldCard extends CardImpl {
|
|||
protected Card bottomHalfCard;
|
||||
protected int topLastZoneChangeCounter;
|
||||
protected int bottomLastZoneChangeCounter;
|
||||
protected boolean isMelded;
|
||||
protected Cards halves;
|
||||
|
||||
public MeldCard(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, String costs) {
|
||||
|
@ -35,15 +33,14 @@ public abstract class MeldCard extends CardImpl {
|
|||
this.topLastZoneChangeCounter = card.topLastZoneChangeCounter;
|
||||
this.bottomLastZoneChangeCounter = card.bottomLastZoneChangeCounter;
|
||||
this.halves = new CardsImpl(card.halves);
|
||||
this.isMelded = card.isMelded;
|
||||
}
|
||||
|
||||
public void setMelded(boolean isMelded) {
|
||||
this.isMelded = isMelded;
|
||||
public void setMelded(boolean isMelded, Game game) {
|
||||
game.getState().getCardState(getId()).setMelded(isMelded);
|
||||
}
|
||||
|
||||
public boolean isMelded() {
|
||||
return isMelded;
|
||||
public boolean isMelded(Game game) {
|
||||
return game.getState().getCardState(getId()).isMelded();
|
||||
}
|
||||
|
||||
public Card getTopHalfCard() {
|
||||
|
@ -107,7 +104,7 @@ public abstract class MeldCard extends CardImpl {
|
|||
|
||||
@Override
|
||||
public boolean addCounters(Counter counter, Ability source, Game game, List<UUID> appliedEffects) {
|
||||
if (this.isMelded()) {
|
||||
if (this.isMelded(game)) {
|
||||
return super.addCounters(counter, source, game, appliedEffects);
|
||||
} else {
|
||||
// can this really happen?
|
||||
|
@ -163,7 +160,7 @@ public abstract class MeldCard extends CardImpl {
|
|||
if (isCopy()) {
|
||||
return super.removeFromZone(game, fromZone, sourceId);
|
||||
}
|
||||
if (isMelded() && fromZone == Zone.BATTLEFIELD) {
|
||||
if (isMelded(game) && fromZone == Zone.BATTLEFIELD) {
|
||||
Permanent permanent = game.getPermanent(objectId);
|
||||
return permanent != null && permanent.removeFromZone(game, fromZone, sourceId);
|
||||
}
|
||||
|
@ -182,7 +179,7 @@ public abstract class MeldCard extends CardImpl {
|
|||
|
||||
@Override
|
||||
public void updateZoneChangeCounter(Game game, ZoneChangeEvent event) {
|
||||
if (isCopy() || !isMelded()) {
|
||||
if (isCopy() || !isMelded(game)) {
|
||||
super.updateZoneChangeCounter(game, event);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ public class CardState implements Serializable {
|
|||
protected Counters counters;
|
||||
protected Abilities<Ability> abilities;
|
||||
protected boolean lostAllAbilities;
|
||||
protected boolean melded;
|
||||
|
||||
private static final Map<String, String> emptyInfo = new HashMap<>();
|
||||
private static final Abilities<Ability> emptyAbilities = new AbilitiesImpl<>();
|
||||
|
@ -41,6 +42,7 @@ public class CardState implements Serializable {
|
|||
}
|
||||
}
|
||||
this.lostAllAbilities = state.lostAllAbilities;
|
||||
this.melded = state.melded;
|
||||
}
|
||||
|
||||
public CardState copy() {
|
||||
|
@ -117,4 +119,12 @@ public class CardState implements Serializable {
|
|||
this.lostAllAbilities = lostAllAbilities;
|
||||
}
|
||||
|
||||
public boolean isMelded() {
|
||||
return melded;
|
||||
}
|
||||
|
||||
public void setMelded(boolean melded) {
|
||||
this.melded = melded;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public final class ZonesHandler {
|
|||
ZoneChangeInfo info = itr.next();
|
||||
MeldCard card = game.getMeldCard(info.event.getTargetId());
|
||||
// Copies should be handled as normal cards.
|
||||
if (card != null && !card.isMelded() && !card.isCopy()) {
|
||||
if (card != null && !card.isMelded(game) && !card.isCopy()) {
|
||||
ZoneChangeInfo.Unmelded unmelded = new ZoneChangeInfo.Unmelded(info, game);
|
||||
if (unmelded.subInfo.isEmpty()) {
|
||||
itr.remove();
|
||||
|
@ -175,7 +175,7 @@ public final class ZonesHandler {
|
|||
game.setZone(event.getTargetId(), event.getToZone());
|
||||
if (targetCard instanceof MeldCard && cards != null) {
|
||||
if (event.getToZone() != Zone.BATTLEFIELD) {
|
||||
((MeldCard) targetCard).setMelded(false);
|
||||
((MeldCard) targetCard).setMelded(false, game);
|
||||
}
|
||||
for (Card card : cards.getCards(game)) {
|
||||
game.setZone(card.getId(), event.getToZone());
|
||||
|
|
Loading…
Reference in a new issue