From 50bb73fa084bf0024e5c5400f499d20cc265ff0e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Feb 2013 01:13:15 +0100 Subject: [PATCH] Expanded handling of the ENTERS_THE_BATTLEFIELD event to fix issue #82. --- ...AllyEntersBattlefieldTriggeredAbility.java | 7 +- ...tureEntersBattlefieldTriggeredAbility.java | 10 +- ...tureEntersBattlefieldTriggeredAbility.java | 9 +- ...erCreatureYourControlTriggeredAbility.java | 11 +-- .../EntersBattlefieldAllTriggeredAbility.java | 72 ++++++++++++++- ...BattlefieldControlledTriggeredAbility.java | 92 +++++++++++++++++++ .../EntersBattlefieldTriggeredAbility.java | 21 ++++- .../abilities/common/LandfallAbility.java | 2 +- .../effects/AuraReplacementEffect.java | 2 +- .../common/ReturnToHandTargetEffect.java | 10 +- .../mage/abilities/keyword/EchoAbility.java | 5 +- .../mage/abilities/keyword/EvolveAbility.java | 5 +- Mage/src/mage/cards/CardImpl.java | 4 +- Mage/src/mage/game/GameImpl.java | 2 +- .../events/EntersTheBattlefieldEvent.java | 71 ++++++++++++++ Mage/src/mage/game/permanent/Permanent.java | 5 +- .../mage/game/permanent/PermanentImpl.java | 11 ++- Mage/src/mage/game/permanent/token/Token.java | 2 +- .../mage/watchers/common/LandfallWatcher.java | 6 +- .../mage/watchers/common/SoulbondWatcher.java | 75 ++++++++------- 20 files changed, 328 insertions(+), 94 deletions(-) create mode 100644 Mage/src/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java create mode 100644 Mage/src/mage/game/events/EntersTheBattlefieldEvent.java diff --git a/Mage/src/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java b/Mage/src/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java index 34186da8d58..08f444e57a2 100644 --- a/Mage/src/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java @@ -34,7 +34,6 @@ import mage.abilities.effects.Effect; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; /** @@ -53,12 +52,10 @@ public class AllyEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == EventType.ZONE_CHANGE) { + if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getToZone() == Zone.BATTLEFIELD - && permanent.getControllerId().equals(this.controllerId) + if (permanent.getControllerId().equals(this.controllerId) && (targetId.equals(this.getSourceId()) || (permanent.hasSubtype("Ally") && !targetId.equals(this.getSourceId())))) { return true; diff --git a/Mage/src/mage/abilities/common/AnotherCreatureEntersBattlefieldTriggeredAbility.java b/Mage/src/mage/abilities/common/AnotherCreatureEntersBattlefieldTriggeredAbility.java index f81333b1ce8..0b687558b0a 100644 --- a/Mage/src/mage/abilities/common/AnotherCreatureEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/AnotherCreatureEntersBattlefieldTriggeredAbility.java @@ -5,7 +5,7 @@ import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; public class AnotherCreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl { @@ -23,11 +23,9 @@ public class AnotherCreatureEntersBattlefieldTriggeredAbility extends TriggeredA @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getToZone() == Constants.Zone.BATTLEFIELD - && zEvent.getTarget().getCardType().contains(Constants.CardType.CREATURE) - && zEvent.getTargetId() != this.getSourceId()) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId() != this.getSourceId()) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent.getCardType().contains(Constants.CardType.CREATURE)) { return true; } } diff --git a/Mage/src/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java b/Mage/src/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java index 04b19729079..a98bb25f42d 100644 --- a/Mage/src/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java @@ -34,7 +34,6 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.TargetPlayer; @@ -77,7 +76,7 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI */ public CreatureEntersBattlefieldTriggeredAbility(Effect effect, boolean optional, boolean opponentController) { this(Zone.BATTLEFIELD, effect, optional, opponentController); - this.opponentController = opponentController; + } /** @@ -88,7 +87,6 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI */ public CreatureEntersBattlefieldTriggeredAbility(Zone zone, Effect effect, boolean optional, boolean opponentController) { this(zone, effect, null, optional, opponentController); - } /** @@ -115,10 +113,9 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == EventType.ZONE_CHANGE) { + if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD - && filter.match(permanent, sourceId, controllerId, game) + if (filter.match(permanent, sourceId, controllerId, game) && (permanent.getControllerId().equals(this.controllerId) ^ opponentController)) { if (!this.getTargets().isEmpty()) { Target target = this.getTargets().get(0); diff --git a/Mage/src/mage/abilities/common/EntersAnotherCreatureYourControlTriggeredAbility.java b/Mage/src/mage/abilities/common/EntersAnotherCreatureYourControlTriggeredAbility.java index f2b5b568554..b8aa022f516 100644 --- a/Mage/src/mage/abilities/common/EntersAnotherCreatureYourControlTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/EntersAnotherCreatureYourControlTriggeredAbility.java @@ -56,13 +56,10 @@ public class EntersAnotherCreatureYourControlTriggeredAbility extends ZoneChange @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && !event.getTargetId().equals(this.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getToZone() == Constants.Zone.BATTLEFIELD) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getCardType().contains(Constants.CardType.CREATURE) && permanent.getControllerId().equals(this.getControllerId())) { - return true; - } + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && !event.getTargetId().equals(this.getSourceId())) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.getCardType().contains(Constants.CardType.CREATURE) && permanent.getControllerId().equals(this.getControllerId())) { + return true; } } return false; diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldAllTriggeredAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldAllTriggeredAbility.java index 47cc091ec69..4a8bc917de2 100644 --- a/Mage/src/mage/abilities/common/EntersBattlefieldAllTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/EntersBattlefieldAllTriggeredAbility.java @@ -28,27 +28,93 @@ package mage.abilities.common; +import java.util.UUID; import mage.Constants.Zone; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; /** * * @author LevelX2 */ -public class EntersBattlefieldAllTriggeredAbility extends ZoneChangeAllTriggeredAbility { +public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { + + protected FilterPermanent filter; + protected String rule; + protected boolean controlled; + + /** + * zone = BATTLEFIELD + * optional = false + * + * @param effect + * @param filter + */ + public EntersBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter) { + this(Zone.BATTLEFIELD, effect, filter, false); + } + + public EntersBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter, String rule) { + this(Zone.BATTLEFIELD, effect, filter, false, rule); + } public EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) { - super(zone, Zone.BATTLEFIELD, effect, filter, "Whenever " + filter.getMessage() + " enters the battlefield, ", optional); + this(zone, effect, filter, optional, null); + this.filter = filter; + } + + public EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, String rule) { + this(zone, effect, filter, optional, rule, false); + } + + public EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, String rule, boolean controlled) { + super(Zone.BATTLEFIELD, effect, optional); + this.filter = filter; + this.rule = rule; + this.controlled = controlled; } public EntersBattlefieldAllTriggeredAbility(EntersBattlefieldAllTriggeredAbility ability) { super(ability); + this.filter = ability.filter; + this.rule = ability.rule; + this.controlled = ability.controlled; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { + UUID targetId = event.getTargetId(); + Permanent permanent = game.getPermanent(targetId); + if (filter.match(permanent, getSourceId(), getControllerId(), game)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + if (rule != null && !rule.isEmpty()) { + return rule; + } + StringBuilder sb = new StringBuilder("Whenever ").append(filter.getMessage()); + sb.append(" enters the battlefield"); + if (controlled) { + sb.append("under your control,"); + } else { + sb.append(","); + } + sb.append(super.getRule()); + return sb.toString(); } @Override public EntersBattlefieldAllTriggeredAbility copy() { return new EntersBattlefieldAllTriggeredAbility(this); } - } diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java new file mode 100644 index 00000000000..1c83b0bab73 --- /dev/null +++ b/Mage/src/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java @@ -0,0 +1,92 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.abilities.common; + +import java.util.UUID; +import mage.Constants.Zone; +import mage.abilities.effects.Effect; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class EntersBattlefieldControlledTriggeredAbility extends EntersBattlefieldAllTriggeredAbility { + + /** + * zone = BATTLEFIELD + * optional = false + * rule = null + * + * @param effect + * @param filter + */ + public EntersBattlefieldControlledTriggeredAbility(Effect effect, FilterPermanent filter) { + this(Zone.BATTLEFIELD, effect, filter, false); + } + + public EntersBattlefieldControlledTriggeredAbility(Effect effect, FilterPermanent filter, String rule) { + this(Zone.BATTLEFIELD, effect, filter, false, rule); + } + + public EntersBattlefieldControlledTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) { + this(zone, effect, filter, optional, null); + this.filter = filter; + } + + public EntersBattlefieldControlledTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, String rule) { + super(zone, effect, filter, optional, rule, true); + } + + public EntersBattlefieldControlledTriggeredAbility(EntersBattlefieldControlledTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { + UUID targetId = event.getTargetId(); + Permanent permanent = game.getPermanent(targetId); + if (filter.match(permanent, getSourceId(), getControllerId(), game)) { + return true; + } + } + return false; + } + + + + @Override + public EntersBattlefieldControlledTriggeredAbility copy() { + return new EntersBattlefieldControlledTriggeredAbility(this); + } +} diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldTriggeredAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldTriggeredAbility.java index 4074f05e975..ee1a7568ace 100644 --- a/Mage/src/mage/abilities/common/EntersBattlefieldTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/EntersBattlefieldTriggeredAbility.java @@ -29,30 +29,45 @@ package mage.abilities.common; import mage.Constants.Zone; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.game.Game; +import mage.game.events.GameEvent; /** * * @author BetaSteward_at_googlemail.com */ -public class EntersBattlefieldTriggeredAbility extends ZoneChangeTriggeredAbility { +public class EntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl { public EntersBattlefieldTriggeredAbility(Effect effect) { this(effect, false); } public EntersBattlefieldTriggeredAbility(Effect effect, boolean optional) { - super(Zone.BATTLEFIELD, effect, "When {this} enters the battlefield, ", optional); + super(Zone.BATTLEFIELD, effect, optional); } public EntersBattlefieldTriggeredAbility(EntersBattlefieldTriggeredAbility ability) { super(ability); } + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD + && event.getTargetId().equals(getSourceId())) { + return true; + } + return false; + } + + @Override + public String getRule() { + return "When {this} enters the battlefield, " + super.getRule(); + } @Override public EntersBattlefieldTriggeredAbility copy() { return new EntersBattlefieldTriggeredAbility(this); } - } diff --git a/Mage/src/mage/abilities/common/LandfallAbility.java b/Mage/src/mage/abilities/common/LandfallAbility.java index f7907a78fe1..8dce91584f7 100644 --- a/Mage/src/mage/abilities/common/LandfallAbility.java +++ b/Mage/src/mage/abilities/common/LandfallAbility.java @@ -58,7 +58,7 @@ public class LandfallAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.BATTLEFIELD) { + if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) { return true; diff --git a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java index 8853345d7d6..f4613b5904f 100644 --- a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java +++ b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java @@ -119,7 +119,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; - if(zEvent.getToZone() != null && zEvent.getToZone() == Constants.Zone.BATTLEFIELD && - zEvent.getFromZone() == null && this.echoPaid) { + if(zEvent.getFromZone() == null && this.echoPaid) { this.echoPaid = false; } } diff --git a/Mage/src/mage/abilities/keyword/EvolveAbility.java b/Mage/src/mage/abilities/keyword/EvolveAbility.java index 22e8edc2e85..8c77bc390fe 100644 --- a/Mage/src/mage/abilities/keyword/EvolveAbility.java +++ b/Mage/src/mage/abilities/keyword/EvolveAbility.java @@ -69,10 +69,9 @@ public class EvolveAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { Permanent triggeringCreature = game.getPermanent(event.getTargetId()); - if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD - && triggeringCreature != null + if (triggeringCreature != null && triggeringCreature.getCardType().contains(CardType.CREATURE) && triggeringCreature.getControllerId().equals(this.controllerId)) { Permanent sourceCreature = game.getPermanent(sourceId); diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 4ea0a8ef489..a5ddc42d34a 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -318,7 +318,7 @@ public abstract class CardImpl> extends MageObjectImpl game.addPermanent(permanent); game.setZone(objectId, Zone.BATTLEFIELD); game.applyEffects(); - permanent.entersBattlefield(sourceId, game); + permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); game.applyEffects(); if (flag) { permanent.setTapped(true); @@ -444,7 +444,7 @@ public abstract class CardImpl> extends MageObjectImpl game.addPermanent(permanent); game.setZone(objectId, Zone.BATTLEFIELD); //game.applyEffects(); // magenoxx: this causes bugs - permanent.entersBattlefield(sourceId, game); + permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); game.applyEffects(); game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD)); return true; diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 71db2e2fef4..d57968d52fc 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1614,7 +1614,7 @@ public abstract class GameImpl> implements Game, Serializa card.setOwnerId(ownerId); PermanentCard permanent = new PermanentCard(card.getCard(), ownerId); getBattlefield().addPermanent(permanent); - permanent.entersBattlefield(permanent.getId(), this); + permanent.entersBattlefield(permanent.getId(), this, Zone.OUTSIDE, false); ((PermanentImpl)permanent).removeSummoningSickness(); if (card.isTapped()) { permanent.setTapped(true); diff --git a/Mage/src/mage/game/events/EntersTheBattlefieldEvent.java b/Mage/src/mage/game/events/EntersTheBattlefieldEvent.java new file mode 100644 index 00000000000..0321e70e95e --- /dev/null +++ b/Mage/src/mage/game/events/EntersTheBattlefieldEvent.java @@ -0,0 +1,71 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.game.events; + +import java.util.ArrayList; +import java.util.UUID; +import mage.Constants.Zone; +import mage.game.permanent.Permanent; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class EntersTheBattlefieldEvent extends GameEvent { + + private Zone fromZone; + private Permanent target; + + public EntersTheBattlefieldEvent(Permanent target, UUID sourceId, UUID playerId, Zone fromZone) { + super(EventType.ENTERS_THE_BATTLEFIELD, target.getId(), sourceId, playerId); + this.fromZone = fromZone; + this.target = target; + } + + public EntersTheBattlefieldEvent(Permanent target, UUID sourceId, UUID playerId, Zone fromZone, ArrayList appliedEffects) { + super(EventType.ENTERS_THE_BATTLEFIELD, target.getId(), sourceId, playerId); + this.fromZone = fromZone; + if (appliedEffects != null) { + this.appliedEffects = appliedEffects; + } + } + + public Zone getFromZone() { + return fromZone; + } + + public Permanent getTarget() { + return target; + } + + public void setTarget(Permanent target) { + this.target = target; + } + +} diff --git a/Mage/src/mage/game/permanent/Permanent.java b/Mage/src/mage/game/permanent/Permanent.java index e45350ffa69..4bb0081ee9d 100644 --- a/Mage/src/mage/game/permanent/Permanent.java +++ b/Mage/src/mage/game/permanent/Permanent.java @@ -32,13 +32,12 @@ import java.util.ArrayList; import mage.MageObject; import mage.abilities.Ability; import mage.cards.Card; -import mage.counters.Counter; -import mage.counters.Counters; import mage.game.Controllable; import mage.game.Game; import java.util.List; import java.util.UUID; +import mage.Constants.Zone; public interface Permanent extends Card, Controllable { @@ -107,7 +106,7 @@ public interface Permanent extends Card, Controllable { boolean destroy(UUID sourceId, Game game, boolean noRegen); boolean sacrifice(UUID sourceId, Game game); boolean regenerate(UUID sourceId, Game game); - void entersBattlefield(UUID sourceId, Game game); + void entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent); String getValue(); @Deprecated diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 0e3d2f4dfbb..537cc5c8d80 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -61,6 +61,7 @@ import mage.game.events.DamageCreatureEvent; import mage.game.events.DamagePlaneswalkerEvent; import mage.game.events.DamagedCreatureEvent; import mage.game.events.DamagedPlaneswalkerEvent; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.players.Player; @@ -733,10 +734,16 @@ public abstract class PermanentImpl> extends CardImpl markedDamage.add(counter); } + @Override - public void entersBattlefield(UUID sourceId, Game game) { + public void entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent) { controlledFromStartOfControllerTurn = false; - game.replaceEvent(GameEvent.getEvent(EventType.ENTERS_THE_BATTLEFIELD, objectId, sourceId, controllerId)); + EntersTheBattlefieldEvent event = new EntersTheBattlefieldEvent(this, sourceId, getControllerId(), fromZone); + if (!game.replaceEvent(event)) { + if (fireEvent) { + game.fireEvent(event); + } + } } @Override diff --git a/Mage/src/mage/game/permanent/token/Token.java b/Mage/src/mage/game/permanent/token/Token.java index b05f14499c3..0ce877e256e 100644 --- a/Mage/src/mage/game/permanent/token/Token.java +++ b/Mage/src/mage/game/permanent/token/Token.java @@ -117,7 +117,7 @@ public class Token extends MageObjectImpl { game.getState().addCard(permanent); game.addPermanent(permanent); this.lastAddedTokenId = permanent.getId(); - permanent.entersBattlefield(sourceId, game); + permanent.entersBattlefield(sourceId, game, Zone.OUTSIDE, true); game.applyEffects(); game.fireEvent(new ZoneChangeEvent(permanent, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD)); } diff --git a/Mage/src/mage/watchers/common/LandfallWatcher.java b/Mage/src/mage/watchers/common/LandfallWatcher.java index ed9e0a979f0..291ce3254ee 100644 --- a/Mage/src/mage/watchers/common/LandfallWatcher.java +++ b/Mage/src/mage/watchers/common/LandfallWatcher.java @@ -3,7 +3,6 @@ package mage.watchers.common; import mage.Constants; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.watchers.WatcherImpl; @@ -28,9 +27,10 @@ public class LandfallWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (condition == true) //no need to check - condition has already occured + if (condition == true) { //no need to check - condition has already occured return; - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Constants.Zone.BATTLEFIELD) { + } + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.getCardType().contains(Constants.CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) { condition = true; diff --git a/Mage/src/mage/watchers/common/SoulbondWatcher.java b/Mage/src/mage/watchers/common/SoulbondWatcher.java index 209ca79c8e9..cc495b13e32 100644 --- a/Mage/src/mage/watchers/common/SoulbondWatcher.java +++ b/Mage/src/mage/watchers/common/SoulbondWatcher.java @@ -69,51 +69,48 @@ public class SoulbondWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getToZone() == Constants.Zone.BATTLEFIELD) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getCardType().contains(Constants.CardType.CREATURE)) { - if (permanent.getAbilities().contains(SoulbondAbility.getInstance())) { - Player controller = game.getPlayer(permanent.getControllerId()); - if (controller != null) { - Cards cards = new CardsImpl(Constants.Zone.PICK); - cards.add(permanent); - controller.lookAtCards("Soulbond", cards, game); - if (controller.chooseUse(Constants.Outcome.Benefit, "Use Soulbond?", game)) { - TargetControlledPermanent target = new TargetControlledPermanent(filter); - target.setNotTarget(true); - if (target.canChoose(permanent.getId(), controller.getId(), game)) { - if (controller.choose(Constants.Outcome.Benefit, target, permanent.getId(), game)) { - Permanent chosen = game.getPermanent(target.getFirstTarget()); - if (chosen != null) { - chosen.setPairedCard(permanent.getId()); - permanent.setPairedCard(chosen.getId()); - } + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.getCardType().contains(Constants.CardType.CREATURE)) { + if (permanent.getAbilities().contains(SoulbondAbility.getInstance())) { + Player controller = game.getPlayer(permanent.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(Constants.Zone.PICK); + cards.add(permanent); + controller.lookAtCards("Soulbond", cards, game); + if (controller.chooseUse(Constants.Outcome.Benefit, "Use Soulbond?", game)) { + TargetControlledPermanent target = new TargetControlledPermanent(filter); + target.setNotTarget(true); + if (target.canChoose(permanent.getId(), controller.getId(), game)) { + if (controller.choose(Constants.Outcome.Benefit, target, permanent.getId(), game)) { + Permanent chosen = game.getPermanent(target.getFirstTarget()); + if (chosen != null) { + chosen.setPairedCard(permanent.getId()); + permanent.setPairedCard(chosen.getId()); } } } } } + } - // if still unpaired - if (permanent.getPairedCard() == null) { - // try to find creature with Soulbond and unpaired - Player controller = null; - for (Permanent chosen : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), permanent.getId(), game)) { - if (!chosen.getId().equals(permanent.getId()) && chosen.getAbilities().contains(SoulbondAbility.getInstance()) && chosen.getPairedCard() == null) { - if (controller == null) { - controller = game.getPlayer(permanent.getControllerId()); - } - if (controller != null) { - Cards cards = new CardsImpl(Constants.Zone.PICK); - cards.add(chosen); - controller.lookAtCards("Soulbond", cards, game); - if (controller.chooseUse(Constants.Outcome.Benefit, "Use Soulbond for recent " + permanent.getName() + "?", game)) { - chosen.setPairedCard(permanent.getId()); - permanent.setPairedCard(chosen.getId()); - break; - } + // if still unpaired + if (permanent.getPairedCard() == null) { + // try to find creature with Soulbond and unpaired + Player controller = null; + for (Permanent chosen : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), permanent.getId(), game)) { + if (!chosen.getId().equals(permanent.getId()) && chosen.getAbilities().contains(SoulbondAbility.getInstance()) && chosen.getPairedCard() == null) { + if (controller == null) { + controller = game.getPlayer(permanent.getControllerId()); + } + if (controller != null) { + Cards cards = new CardsImpl(Constants.Zone.PICK); + cards.add(chosen); + controller.lookAtCards("Soulbond", cards, game); + if (controller.chooseUse(Constants.Outcome.Benefit, "Use Soulbond for recent " + permanent.getName() + "?", game)) { + chosen.setPairedCard(permanent.getId()); + permanent.setPairedCard(chosen.getId()); + break; } } }