From 8d683a7e5c5ca21a9aa5b62767ced34a3e4d0b18 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 30 Aug 2015 23:49:38 +0200 Subject: [PATCH] * Split cards - Fixed a bug when split cards get copied (e.g. by Isochron Scepter) refering still to the copied card. --- .../cards/abilities/keywords/InfectTest.java | 73 +++++++++++-------- Mage/src/mage/cards/CardImpl.java | 2 +- Mage/src/mage/cards/SplitCard.java | 26 +++++-- Mage/src/mage/cards/SplitCardHalf.java | 4 +- Mage/src/mage/cards/SplitCardHalfImpl.java | 9 ++- Mage/src/mage/cards/mock/MockSplitCard.java | 4 +- Mage/src/mage/game/Exile.java | 2 +- Mage/src/mage/game/GameImpl.java | 4 + 8 files changed, 80 insertions(+), 44 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java index 4b8729e65f..d1f5ab3848 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java @@ -37,21 +37,23 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - public class InfectTest extends CardTestPlayerBase { /** - - 702.89. Infect - 702.89a Infect is a static ability. - 702.89b Damage dealt to a player by a source with infect doesn’t cause that player to lose life. Rather, it causes the player to get that many poison counters. See rule 119.3. - 702.89c Damage dealt to a creature by a source with infect isn’t marked on that creature. Rather, it causes that many -1/-1 counters to be put on that creature. See rule 119.3. - 702.89d If a permanent leaves the battlefield before an effect causes it to deal damage, its last known information is used to determine whether it had infect. - 702.89e The infect rules function no matter what zone an object with infect deals damage from. - 702.89f Multiple instances of infect on the same object are redundant. - + * + * 702.89. Infect 702.89a Infect is a static ability. 702.89b Damage dealt + * to a player by a source with infect doesn’t cause that player to lose + * life. Rather, it causes the player to get that many poison counters. See + * rule 119.3. 702.89c Damage dealt to a creature by a source with infect + * isn’t marked on that creature. Rather, it causes that many -1/-1 counters + * to be put on that creature. See rule 119.3. 702.89d If a permanent leaves + * the battlefield before an effect causes it to deal damage, its last known + * information is used to determine whether it had infect. 702.89e The + * infect rules function no matter what zone an object with infect deals + * damage from. 702.89f Multiple instances of infect on the same object are + * redundant. + * */ - @Test public void testNormalUse() { addCard(Zone.BATTLEFIELD, playerB, "Tine Shrike"); // 2/1 Infect @@ -64,16 +66,15 @@ public class InfectTest extends CardTestPlayerBase { assertCounterCount(playerA, CounterType.POISON, 2); assertLife(playerA, 20); - assertLife(playerB, 20); - + assertLife(playerB, 20); + } - @Test public void testLoseInfectUse() { - // Creatures your opponents control lose infect. - addCard(Zone.BATTLEFIELD, playerA, "Melira, Sylvok Outcast"); - + // Creatures your opponents control lose infect. + addCard(Zone.BATTLEFIELD, playerA, "Melira, Sylvok Outcast"); + addCard(Zone.BATTLEFIELD, playerB, "Tine Shrike"); // 2/1 Infect attack(2, playerB, "Tine Shrike"); @@ -84,23 +85,29 @@ public class InfectTest extends CardTestPlayerBase { assertCounterCount(playerA, CounterType.POISON, 0); assertLife(playerA, 18); - assertLife(playerB, 20); - - } - + assertLife(playerB, 20); + + } + /** - * Inkmoth Nexus has no effect it he attacks becaus it has infect but there are no counters added + * Inkmoth Nexus has no effect it he attacks becaus it has infect but there + * are no counters added * http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/296553-melira-sylvok-outcast-vs-inkmoth-nexus */ @Test public void testInkmothNexusLoseInfect() { - // Creatures your opponents control lose infect. - addCard(Zone.BATTLEFIELD, playerA, "Melira, Sylvok Outcast"); - - addCard(Zone.BATTLEFIELD, playerB, "Plains", 1); - addCard(Zone.BATTLEFIELD, playerB, "Inkmoth Nexus"); + // Creatures your opponents control lose infect. + // Creatures you control can't have -1/-1 counters placed on them. + addCard(Zone.BATTLEFIELD, playerA, "Melira, Sylvok Outcast"); + // Put a -1/-1 counter on target creature. When that creature dies this turn, its controller gets a poison counter. + addCard(Zone.HAND, playerA, "Virulent Wound"); // Instant {B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - // {1}: Inkmoth Nexus becomes a 1/1 Blinkmoth artifact creature with flying and infect until end of turn. It's still a land. + addCard(Zone.BATTLEFIELD, playerB, "Plains", 1); + addCard(Zone.BATTLEFIELD, playerB, "Inkmoth Nexus"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Virulent Wound", "Melira, Sylvok Outcast"); + // {1}: Inkmoth Nexus becomes a 1/1 Blinkmoth artifact creature with flying and infect until end of turn. It's still a land. // (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.) activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}: {this} becomes"); attack(2, playerB, "Inkmoth Nexus"); @@ -108,13 +115,15 @@ public class InfectTest extends CardTestPlayerBase { setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); execute(); + assertGraveyardCount(playerA, "Virulent Wound", 1); + assertPowerToughness(playerA, "Melira, Sylvok Outcast", 2, 2); assertTapped("Plains", true); assertTapped("Inkmoth Nexus", true); assertCounterCount(playerA, CounterType.POISON, 0); assertLife(playerA, 20); - assertLife(playerB, 20); - - } - + assertLife(playerB, 20); + + } + } diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 56a2e90a13..54db7c4463 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -366,7 +366,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { break; case STACK: StackObject stackObject = game.getStack().getSpell(getId()); - if (stackObject == null && (this instanceof SplitCard)) { // handle if half od Split cast is on the stack + if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId()); if (stackObject == null) { stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId()); diff --git a/Mage/src/mage/cards/SplitCard.java b/Mage/src/mage/cards/SplitCard.java index 7aef9b2756..27b093adee 100644 --- a/Mage/src/mage/cards/SplitCard.java +++ b/Mage/src/mage/cards/SplitCard.java @@ -60,16 +60,32 @@ public abstract class SplitCard extends CardImpl { public SplitCard(SplitCard card) { super(card); - this.leftHalfCard = card.leftHalfCard.copy(); + this.leftHalfCard = card.getLeftHalfCard().copy(); + ((SplitCardHalf) leftHalfCard).setParentCard(this); this.rightHalfCard = card.rightHalfCard.copy(); + ((SplitCardHalf) rightHalfCard).setParentCard(this); } - public Card getLeftHalfCard() { - return leftHalfCard; + public SplitCardHalf getLeftHalfCard() { + return (SplitCardHalf) leftHalfCard; } - public Card getRightHalfCard() { - return rightHalfCard; + public SplitCardHalf getRightHalfCard() { + return (SplitCardHalf) rightHalfCard; + } + + @Override + public void assignNewId() { + super.assignNewId(); + leftHalfCard.assignNewId(); + rightHalfCard.assignNewId(); + } + + @Override + public void setCopy(boolean isCopy) { + super.setCopy(isCopy); + leftHalfCard.setCopy(isCopy); + rightHalfCard.setCopy(isCopy); } @Override diff --git a/Mage/src/mage/cards/SplitCardHalf.java b/Mage/src/mage/cards/SplitCardHalf.java index 52fa1086bb..f1ec397660 100644 --- a/Mage/src/mage/cards/SplitCardHalf.java +++ b/Mage/src/mage/cards/SplitCardHalf.java @@ -12,5 +12,7 @@ package mage.cards; public interface SplitCardHalf extends Card { @Override - Card copy(); + SplitCardHalf copy(); + + void setParentCard(SplitCard card); } diff --git a/Mage/src/mage/cards/SplitCardHalfImpl.java b/Mage/src/mage/cards/SplitCardHalfImpl.java index af6cc3f6ab..818d539c4a 100644 --- a/Mage/src/mage/cards/SplitCardHalfImpl.java +++ b/Mage/src/mage/cards/SplitCardHalfImpl.java @@ -62,7 +62,7 @@ public class SplitCardHalfImpl extends CardImpl implements SplitCardHalf { } @Override - public Card getMainCard() { + public SplitCard getMainCard() { return splitCardParent; } @@ -74,8 +74,13 @@ public class SplitCardHalfImpl extends CardImpl implements SplitCardHalf { } @Override - public SplitCardHalfImpl copy() { + public SplitCardHalf copy() { return new SplitCardHalfImpl(this); } + @Override + public void setParentCard(SplitCard card) { + this.splitCardParent = card; + } + } diff --git a/Mage/src/mage/cards/mock/MockSplitCard.java b/Mage/src/mage/cards/mock/MockSplitCard.java index fd9e8a0618..3eb271bdad 100644 --- a/Mage/src/mage/cards/mock/MockSplitCard.java +++ b/Mage/src/mage/cards/mock/MockSplitCard.java @@ -50,12 +50,12 @@ public class MockSplitCard extends SplitCard { } CardInfo leftHalf = CardRepository.instance.findCard(getLeftHalfName(card)); - if(leftHalf != null) { + if (leftHalf != null) { this.leftHalfCard = new MockCard(leftHalf); } CardInfo rightHalf = CardRepository.instance.findCard(getRightHalfName(card)); - if(rightHalf != null) { + if (rightHalf != null) { this.rightHalfCard = new MockCard(rightHalf); } } diff --git a/Mage/src/mage/game/Exile.java b/Mage/src/mage/game/Exile.java index 688a272758..42b513092f 100644 --- a/Mage/src/mage/game/Exile.java +++ b/Mage/src/mage/game/Exile.java @@ -100,7 +100,7 @@ public class Exile implements Serializable, Copyable { } public List getAllCards(Game game) { - List cards = new ArrayList(); + List cards = new ArrayList<>(); for (ExileZone exile : exileZones.values()) { cards.addAll(exile.getCards(game)); } diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index b8ad5577fe..dbaf208508 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -67,6 +67,7 @@ import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.cards.SplitCard; +import mage.cards.SplitCardHalf; import mage.cards.decks.Deck; import mage.choices.Choice; import mage.constants.CardType; @@ -1525,6 +1526,9 @@ public abstract class GameImpl implements Game, Serializable { Iterator copiedCards = this.getState().getCopiedCards().iterator(); while (copiedCards.hasNext()) { Card card = copiedCards.next(); + if (card instanceof SplitCardHalf) { + continue; // only the main card is moves, not the halves + } Zone zone = state.getZone(card.getId()); if (zone != Zone.BATTLEFIELD && zone != Zone.STACK) { switch (zone) {