diff --git a/Mage.Sets/src/mage/sets/gatecrash/MurderInvestigation.java b/Mage.Sets/src/mage/sets/gatecrash/MurderInvestigation.java index 7234a561b5..a0b08e8061 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/MurderInvestigation.java +++ b/Mage.Sets/src/mage/sets/gatecrash/MurderInvestigation.java @@ -86,7 +86,7 @@ class AttachedPermanentPowerCount implements DynamicValue { public int calculate(Game game, Ability sourceAbility, Effect effect) { Permanent attachmentPermanent = game.getPermanent(sourceAbility.getSourceId()); if (attachmentPermanent == null) { - attachmentPermanent = (Permanent) game.getLastKnownInformation(sourceAbility.getSourceId(), Zone.BATTLEFIELD); + attachmentPermanent = (Permanent) game.getLastKnownInformation(sourceAbility.getSourceId(), Zone.BATTLEFIELD, sourceAbility.getSourceObjectZoneChangeCounter()); } if (attachmentPermanent != null && attachmentPermanent.getAttachedTo() != null) { if (effect.getValue("attachedTo") != null) { diff --git a/Mage.Tests/src/test/java/org/mage/test/lki/LastKnownInformationTest.java b/Mage.Tests/src/test/java/org/mage/test/lki/LastKnownInformationTest.java index 74a23b175b..7e97f411d0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/lki/LastKnownInformationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/lki/LastKnownInformationTest.java @@ -22,7 +22,7 @@ public class LastKnownInformationTest extends CardTestPlayerBase { * http://www.slightlymagic.net/forum/viewtopic.php?f=116&t=14516 * * Tests Safehold Elite with persist returns to battlefield with -1/-1 counter - * Murder Investigation puts 2 tokens onto battlefield because enchanted Safehold Elite + * Murder Investigation has to put 2 tokens onto battlefield because enchanted Safehold Elite * was 2/2 * * @author LevelX diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 16a8490c32..ccef814220 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -901,6 +901,10 @@ public abstract class AbilityImpl implements Ability { } } } + // check agains shortLKI for effects that move multiple object at the same time (e.g. destroy all) + if (game.getShortLivingLKI(getSourceId(), getZone())) { + return true; + } // check against current state Zone test = game.getState().getZone(parameterSourceId); return test != null && zone.match(test); diff --git a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java index 4378242e1d..c48b9d3363 100644 --- a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java @@ -26,7 +26,7 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl { } public DiesAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional, boolean diesRuleText) { - super(Zone.BATTLEFIELD, effect, optional); + super(Zone.ALL, effect, optional); // because the trigger only triggers if the object was attached, it doesn't matter where the Attachment was moved to (e.g. by replacement effect) after the trigger triggered, so Zone.all this.attachedDescription = attachedDescription; this.diesRuleText = diesRuleText; } @@ -51,10 +51,10 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (((ZoneChangeEvent)event).isDiesEvent()) { - Permanent p = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (p.getAttachments().contains(this.getSourceId())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getTarget().getAttachments().contains(this.getSourceId())) { for (Effect effect : getEffects()) { - effect.setValue("attachedTo", p); + effect.setValue("attachedTo", zEvent.getTarget()); } return true; } diff --git a/Mage/src/mage/abilities/common/DiesCreatureTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesCreatureTriggeredAbility.java index 675142f1e6..6b4202de14 100644 --- a/Mage/src/mage/abilities/common/DiesCreatureTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesCreatureTriggeredAbility.java @@ -8,7 +8,6 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** @@ -64,8 +63,7 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone().equals(Zone.BATTLEFIELD) && zEvent.getToZone().equals(Zone.GRAVEYARD)) { - Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && filter.match(permanent, sourceId, controllerId, game)) { + if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) { if (setTargetPointer) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java index 9a3cd60155..7583252a37 100644 --- a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java @@ -57,7 +57,7 @@ public class DiesTriggeredAbility extends ZoneChangeTriggeredAbility { @Override public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { // check it was previously on battlefield - Permanent before = (Permanent) game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD); + Permanent before = ((ZoneChangeEvent) event).getTarget(); // check now it is in graveyard Zone after = game.getState().getZone(sourceId); return before != null && after != null && Zone.GRAVEYARD.match(after); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 997c93f855..3e7d9a252f 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -684,8 +684,9 @@ public abstract class GameImpl implements Game, Serializable { if (extraPlayer != null && extraPlayer.isInGame()) { state.setExtraTurn(true); state.setTurnId(extraTurn.getId()); - if (!this.isSimulation()) + if (!this.isSimulation()) { informPlayers(extraPlayer.getName() + " takes an extra turn"); + } playTurn(extraPlayer); state.setTurnNum(state.getTurnNum() + 1); } @@ -1705,9 +1706,10 @@ public abstract class GameImpl implements Game, Serializable { private boolean movePermanentToGraveyardWithInfo(Permanent permanent) { boolean result = false; if (permanent.moveToZone(Zone.GRAVEYARD, null, this, false)) { - if (!this.isSimulation()) + if (!this.isSimulation()) { this.informPlayers(new StringBuilder(permanent.getLogName()) - .append(" is put into graveyard from battlefield").toString()); + .append(" is put into graveyard from battlefield").toString()); + } result = true; } return result; diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 075c5fbf95..95f63a57ff 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -262,6 +262,11 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { throw new UnsupportedOperationException("Unsupported operation: use addAbility(Ability ability, Game game) instead"); } + /** + * + * @param ability + * @param game + */ @Override public void addAbility(Ability ability, Game game) { if (!abilities.containsKey(ability.getId())) { diff --git a/Mage/src/mage/game/permanent/PermanentToken.java b/Mage/src/mage/game/permanent/PermanentToken.java index df60985559..75dcbb9e9b 100644 --- a/Mage/src/mage/game/permanent/PermanentToken.java +++ b/Mage/src/mage/game/permanent/PermanentToken.java @@ -95,8 +95,8 @@ public class PermanentToken extends PermanentImpl { game.rememberLKI(objectId, Zone.BATTLEFIELD, this); if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) { game.setZone(objectId, zone); // needed for triggered dies abilities - game.fireEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, zone)); - game.getState().removeTriggersOfSourceId(this.getId());// if token is gone endless triggered abilities have to be removed + game.addSimultaneousEvent(new ZoneChangeEvent(this, this.getControllerId(), Zone.BATTLEFIELD, zone)); // causes maybe a problem with Dies trigger of Tokens + // game.getState().removeTriggersOfSourceId(this.getId());// if token is gone endless triggered abilities have to be removed return true; } } diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 5a85393e51..8b0536318d 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -198,6 +198,7 @@ public class Spell implements StackObject, Card { result |= spellAbility.resolve(game); } } + game.getState().handleSimultaneousEvent(game); game.resetShortLivingLKI(); index++; }