diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java index ab8753847ef..737173b4ba5 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java @@ -53,9 +53,17 @@ public class UndyingTest extends CardTestPlayerBase { */ @Test public void testUndyingEvil() { + // Elite Vanguard + // Creature — Human Soldier 2/1 addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + // Last Gasp + // Instant, 1B + // Target creature gets -3/-3 until end of turn. addCard(Zone.HAND, playerA, "Last Gasp"); + // Undying Evil + // Target creature gains undying until end of turn. + // When it dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.) addCard(Zone.HAND, playerA, "Undying Evil"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Last Gasp", "Elite Vanguard"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/SorinLordOfInnistradTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/SorinLordOfInnistradTest.java index 902dd6fb882..0a8917b227f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/SorinLordOfInnistradTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/SorinLordOfInnistradTest.java @@ -50,8 +50,19 @@ public class SorinLordOfInnistradTest extends CardTestPlayerBase { @Test public void testCard3() { + // Sorin, Lord of Innistrad English + // Planeswalker — Sorin (Loyalty: 3), 2WB + // +1: Put a 1/1 black Vampire creature token with lifelink onto the battlefield. + // -2: You get an emblem with "Creatures you control get +1/+0." + // -6: Destroy up to three target creatures and/or other planeswalkers. Return each card put into a graveyard this way to the battlefield under your control. addCard(Zone.BATTLEFIELD, playerA, "Sorin, Lord of Innistrad"); + // Craw Wurm + // Creature — Wurm 6/4, 4GG addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm"); + // Angel of Mercy English + // Creature — Angel 3/3, 4W (5) + // Flying + // When Angel of Mercy enters the battlefield, you gain 3 life. addCard(Zone.BATTLEFIELD, playerB, "Angel of Mercy"); addCounters(1, PhaseStep.UPKEEP, playerA, "Sorin, Lord of Innistrad", CounterType.LOYALTY, 3); @@ -62,8 +73,9 @@ public class SorinLordOfInnistradTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Craw Wurm", 1); assertPermanentCount(playerA, "Angel of Mercy", 1); - assertLife(playerA, 23); + assertLife(playerB, 20); + assertLife(playerA, 23); assertPermanentCount(playerA, "Sorin, Lord of Innistrad", 0); assertPermanentCount(playerB, "Craw Wurm", 0); assertPermanentCount(playerB, "Angel of Mercy", 0); diff --git a/Mage/src/mage/abilities/TriggeredAbilities.java b/Mage/src/mage/abilities/TriggeredAbilities.java index 594f4ff91be..4e4467b053a 100644 --- a/Mage/src/mage/abilities/TriggeredAbilities.java +++ b/Mage/src/mage/abilities/TriggeredAbilities.java @@ -36,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; import mage.MageObject; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -64,7 +65,13 @@ public class TriggeredAbilities extends HashMap { public void checkTriggers(GameEvent event, Game game) { for (TriggeredAbility ability: this.values()) { if (ability.isInUseableZone(game, null, true)) { - MageObject object = getMageObject(event, game, ability); + MageObject object = null; + if (!ability.getZone().equals(Zone.COMMAND) && !game.getState().getZone(ability.getSourceId()).equals(ability.getZone())) { + object = game.getShortLivingLKI(ability.getSourceId(), ability.getZone()); + } + if (object == null) { + object = getMageObject(event, game, ability); + } if (object != null) { if (checkAbilityStillExists(ability, event, object)) { if (object instanceof Permanent) { diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 1dc4de69a15..cecf2ea7894 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -127,9 +127,9 @@ public abstract class GameImpl> implements Game, Serializa protected transient TableEventSource tableEventSource = new TableEventSource(); protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource(); - protected Map gameCards = new HashMap(); - protected Map lki = new HashMap(); - protected Map shortLivingLKI = new HashMap(); + protected Map gameCards = new HashMap(); + protected Map> lki = new EnumMap>(Zone.class); + protected Map> shortLivingLKI = new EnumMap>(Zone.class); protected GameState state; protected Date startTime; @@ -1763,18 +1763,24 @@ public abstract class GameImpl> implements Game, Serializa /*if (!lki.containsKey(objectId)) { return getCard(objectId); }*/ - MageObject object = lki.get(objectId); - if (object != null) { - return object.copy(); + Map lkiMap = lki.get(zone); + if (lkiMap != null) { + MageObject object = lkiMap.get(objectId); + if (object != null) { + return object.copy(); + } } return null; } @Override public MageObject getShortLivingLKI(UUID objectId, Zone zone) { - MageObject object = shortLivingLKI.get(objectId); - if (object != null) { - return object.copy(); + Map shortLivingLkiMap = shortLivingLKI.get(zone); + if (shortLivingLkiMap != null) { + MageObject object = shortLivingLkiMap.get(objectId); + if (object != null) { + return object.copy(); + } } return null; } @@ -1790,8 +1796,24 @@ public abstract class GameImpl> implements Game, Serializa public void rememberLKI(UUID objectId, Zone zone, MageObject object) { if (object instanceof Permanent || object instanceof StackObject) { MageObject copy = object.copy(); - lki.put(objectId, copy); - shortLivingLKI.put(objectId, copy); + + Map lkiMap = lki.get(zone); + if (lkiMap != null) { + lkiMap.put(objectId, copy); + } else { + HashMap newMap = new HashMap(); + newMap.put(objectId, copy); + lki.put(zone, newMap); + } + + Map shortLivingLkiMap = shortLivingLKI.get(zone); + if (shortLivingLkiMap != null) { + shortLivingLkiMap.put(objectId, copy); + } else { + HashMap newMap = new HashMap(); + newMap.put(objectId, copy); + shortLivingLKI.put(zone, newMap); + } } } diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index 4e28671e04a..31588bea904 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -185,6 +185,7 @@ public class PermanentCard extends PermanentImpl { Player owner = game.getPlayer(ownerId); game.rememberLKI(objectId, Zone.BATTLEFIELD, this); if (owner != null) { + this.setControllerId(ownerId); // neccessary for e.g. abilities in graveyard or hand to not have a controller != owner switch (event.getToZone()) { case GRAVEYARD: owner.putInGraveyard(card, game, !flag); @@ -199,10 +200,11 @@ public class PermanentCard extends PermanentImpl { game.addCommander(new Commander(card)); break; case LIBRARY: - if (flag) + if (flag) { owner.getLibrary().putOnTop(card, game); - else + } else { owner.getLibrary().putOnBottom(card, game); + } break; case BATTLEFIELD: //should never happen