From c6e08a8872614836ea3c02f13693554663a9cd9d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 16 Aug 2015 13:02:02 +0200 Subject: [PATCH] * Fixed that effects created from attachments to the attached object by activated or triggered abilities did not exists independent from the attachment (fixes #1206). --- .../sets/bornofthegods/EverflameEidolon.java | 45 +++++++-- .../mage/sets/magic2012/Firebreathing.java | 16 +++- .../cards/continuous/BoostEnchantedTest.java | 92 +++++++++++++++++++ .../effects/ContinuousEffectImpl.java | 80 ++++++++-------- .../combat/CantBlockAttachedEffect.java | 19 +++- .../continuous/BoostEnchantedEffect.java | 65 ++++++++----- .../continuous/GainAbilityAttachedEffect.java | 65 +++++++------ 7 files changed, 275 insertions(+), 107 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/BoostEnchantedTest.java diff --git a/Mage.Sets/src/mage/sets/bornofthegods/EverflameEidolon.java b/Mage.Sets/src/mage/sets/bornofthegods/EverflameEidolon.java index 3239aff414..dc091c0b57 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/EverflameEidolon.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/EverflameEidolon.java @@ -29,19 +29,22 @@ package mage.sets.bornofthegods; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.SourceHasSubtypeCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.BestowAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; /** * @@ -60,12 +63,7 @@ public class EverflameEidolon extends CardImpl { // Bestow {2}{R} this.addAbility(new BestowAbility(this, "{2}{R}")); // {R}: Everflame Eidolon gets +1/+0 until end of turn. If it's an Aura, enchanted creature gets +1/+0 until end of turn instead. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( - new BoostEnchantedEffect(1, 0, Duration.EndOfTurn), - new BoostSourceEffect(1, 0, Duration.EndOfTurn), - new SourceHasSubtypeCondition("Aura"), - "{this} gets +1/+0 until end of turn. If it's an Aura, enchanted creature gets +1/+0 until end of turn instead"), - new ManaCostsImpl("{R}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new EverflameEidolonEffect(), new ManaCostsImpl("{R}"))); // Enchanted creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield))); } @@ -79,3 +77,34 @@ public class EverflameEidolon extends CardImpl { return new EverflameEidolon(this); } } + +class EverflameEidolonEffect extends OneShotEffect { + + public EverflameEidolonEffect() { + super(Outcome.BoostCreature); + this.staticText = "{this} gets +1/+0 until end of turn. If it's an Aura, enchanted creature gets +1/+0 until end of turn instead"; + } + + public EverflameEidolonEffect(final EverflameEidolonEffect effect) { + super(effect); + } + + @Override + public EverflameEidolonEffect copy() { + return new EverflameEidolonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourceObject != null) { + if (sourceObject.getSubtype().contains("Aura")) { + new BoostEnchantedEffect(1, 0, Duration.EndOfTurn).apply(game, source); + } else { + game.addEffect(new BoostSourceEffect(1, 0, Duration.EndOfTurn), source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/magic2012/Firebreathing.java b/Mage.Sets/src/mage/sets/magic2012/Firebreathing.java index 6cd0014823..e7d349cee9 100644 --- a/Mage.Sets/src/mage/sets/magic2012/Firebreathing.java +++ b/Mage.Sets/src/mage/sets/magic2012/Firebreathing.java @@ -25,12 +25,9 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2012; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ColoredManaCost; @@ -38,6 +35,12 @@ import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -47,20 +50,23 @@ import mage.target.common.TargetCreaturePermanent; */ public class Firebreathing extends CardImpl { - public Firebreathing (UUID ownerId) { + public Firebreathing(UUID ownerId) { super(ownerId, 132, "Firebreathing", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{R}"); this.expansionSetCode = "M12"; this.subtype.add("Aura"); + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + + // {R}: Enchanted creature gets +1/+0 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 0, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.R))); } - public Firebreathing (final Firebreathing card) { + public Firebreathing(final Firebreathing card) { super(card); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/BoostEnchantedTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/BoostEnchantedTest.java new file mode 100644 index 0000000000..f7db7fd18d --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/BoostEnchantedTest.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 org.mage.test.cards.continuous; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class BoostEnchantedTest extends CardTestPlayerBase { + + @Test + public void testFirebreathingNormal() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + // {R}: Enchanted creature gets +1/+0 until end of turn. + addCard(Zone.HAND, playerA, "Firebreathing"); // {R} Enchantment - Aura + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Firebreathing", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: Enchanted creature"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Firebreathing", 1); + assertPowerToughness(playerA, "Silvercoat Lion", 3, 2); + } + + /** + * On Ghitu Firebreathing (and probably other similar cards), when you + * activate the ability to give +1/0 to the enchanted creature and the + * return Ghitu Firebreathing to your hand, the +1/0 goes away on the + * creature. If you re-cast Ghitu Firebreathing onto the creature, the boost + * returns. + * + * Gatherer Rulings: 9/25/2006 If you return Ghitu Firebreathing to its + * owner's hand while the +1/+0 ability is on the stack, that ability will + * still give the creature that was last enchanted by Ghitu Firebreathing + * +1/+0. + * + */ + @Test + public void testFirebreathingReturnToHand() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + // {R}: Enchanted creature gets +1/+0 until end of turn. + addCard(Zone.HAND, playerA, "Firebreathing"); // {R} Enchantment - Aura + + addCard(Zone.BATTLEFIELD, playerB, "Island", 2); + addCard(Zone.HAND, playerB, "Boomerang"); // {U}{U} Instant + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Firebreathing", "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Boomerang", "Firebreathing"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: Enchanted creature", NO_TARGET, "Boomerang"); + + setStopAt(1, PhaseStep.END_COMBAT); + execute(); + + assertHandCount(playerA, "Firebreathing", 1); + assertGraveyardCount(playerB, "Boomerang", 1); + assertPowerToughness(playerA, "Silvercoat Lion", 3, 2); + } +} diff --git a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java index a360320332..e793058a81 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.effects; import java.util.ArrayList; @@ -69,7 +68,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu protected boolean affectedObjectsSet = false; protected List affectedObjectList = new ArrayList<>(); protected boolean temporary = false; - + // until your next turn protected int startingTurn; protected UUID startingControllerId; @@ -96,7 +95,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu this.used = effect.used; this.discarded = effect.discarded; this.affectedObjectsSet = effect.affectedObjectsSet; - this.affectedObjectList.addAll(effect.affectedObjectList); + this.affectedObjectList.addAll(effect.affectedObjectList); this.temporary = effect.temporary; this.startingTurn = effect.startingTurn; this.startingControllerId = effect.startingControllerId; @@ -148,8 +147,8 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu } /** - * Sets the discarded state of the effect. So it - * will be removed on next check. + * Sets the discarded state of the effect. So it will be removed on next + * check. */ @Override public void discard() { @@ -160,7 +159,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu public void init(Ability source, Game game) { targetPointer.init(game, source); //20100716 - 611.2c - if (AbilityType.ACTIVATED.equals(source.getAbilityType()) + if (AbilityType.ACTIVATED.equals(source.getAbilityType()) || AbilityType.SPELL.equals(source.getAbilityType()) || AbilityType.TRIGGERED.equals(source.getAbilityType())) { if (layer != null) { @@ -174,11 +173,10 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu case PTChangingEffects_7: this.affectedObjectsSet = true; } - } - else { - if (hasLayer(Layer.CopyEffects_1) || hasLayer(Layer.ControlChangingEffects_2) || hasLayer(Layer.TextChangingEffects_3) || - hasLayer(Layer.TypeChangingEffects_4) || hasLayer(Layer.ColorChangingEffects_5) || hasLayer(Layer.AbilityAddingRemovingEffects_6) || - hasLayer(Layer.PTChangingEffects_7)) { + } else { + if (hasLayer(Layer.CopyEffects_1) || hasLayer(Layer.ControlChangingEffects_2) || hasLayer(Layer.TextChangingEffects_3) + || hasLayer(Layer.TypeChangingEffects_4) || hasLayer(Layer.ColorChangingEffects_5) || hasLayer(Layer.AbilityAddingRemovingEffects_6) + || hasLayer(Layer.PTChangingEffects_7)) { this.affectedObjectsSet = true; } } @@ -226,7 +224,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu return true; } if (toughness instanceof DomainValue) { - return ((DomainValue)toughness).getAmount() < 0; + return ((DomainValue) toughness).getAmount() < 0; } return false; } @@ -237,8 +235,10 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu } /** - * Returns the status if the effect is temporary added to the ContinuousEffects - * @return + * Returns the status if the effect is temporary added to the + * ContinuousEffects + * + * @return */ @Override public boolean isTemporary() { diff --git a/Mage/src/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index d58293e927..b42d9e082b 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -27,12 +27,13 @@ */ package mage.abilities.effects.common.combat; -import mage.constants.AttachmentType; -import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; +import mage.constants.AttachmentType; +import mage.constants.Duration; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -62,8 +63,22 @@ public class CantBlockAttachedEffect extends RestrictionEffect { super(effect); } + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (affectedObjectsSet) { + Permanent equipment = game.getPermanent(source.getSourceId()); + if (equipment != null && equipment.getAttachedTo() != null) { + this.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game.getState().getZoneChangeCounter(equipment.getAttachedTo()))); + } + } + } + @Override public boolean applies(Permanent permanent, Ability source, Game game) { + if (affectedObjectsSet) { + return targetPointer.getFirst(game, source).equals(permanent.getId()); + } return permanent.getAttachments().contains(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java index f806ef6541..0f60a80c17 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,24 +20,24 @@ * 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.effects.common.continuous; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -79,15 +79,37 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { } @Override - public boolean apply(Game game, Ability source) { - Permanent enchantment = game.getPermanent(source.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo() != null) { - Permanent creature = game.getPermanent(enchantment.getAttachedTo()); - if (creature != null) { - creature.addPower(power.calculate(game, source, this)); - creature.addToughness(toughness.calculate(game, source, this)); + public void init(Ability source, Game game) { + super.init(source, game); + if (affectedObjectsSet) { + // Added boosts of activated or triggered abilities exist independent from the source they are created by + // so a continuous effect for the permanent itself with the attachment is created + Permanent equipment = game.getPermanent(source.getSourceId()); + if (equipment != null && equipment.getAttachedTo() != null) { + this.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game.getState().getZoneChangeCounter(equipment.getAttachedTo()))); } } + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = null; + if (affectedObjectsSet) { + permanent = game.getPermanent(targetPointer.getFirst(game, source)); + if (permanent == null) { + discard(); + return true; + } + } else { + Permanent equipment = game.getPermanent(source.getSourceId()); + if (equipment != null && equipment.getAttachedTo() != null) { + permanent = game.getPermanent(equipment.getAttachedTo()); + } + } + if (permanent != null) { + permanent.addPower(power.calculate(game, source, this)); + permanent.addToughness(toughness.calculate(game, source, this)); + } return true; } @@ -95,16 +117,15 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { StringBuilder sb = new StringBuilder(); sb.append("Enchanted creature gets "); String p = power.toString(); - if(!p.startsWith("-")) { + if (!p.startsWith("-")) { sb.append("+"); } sb.append(p).append("/"); String t = toughness.toString(); - if(!t.startsWith("-")){ - if(p.startsWith("-")) { + if (!t.startsWith("-")) { + if (p.startsWith("-")) { sb.append("-"); - } - else { + } else { sb.append("+"); } } diff --git a/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java index 3029a00fc1..9120ccb551 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java @@ -45,35 +45,36 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl { protected Ability ability; protected AttachmentType attachmentType; - protected boolean fixedTarget = false; + protected boolean independentEffect; + + public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType) { + this(ability, attachmentType, Duration.WhileOnBattlefield); + } + + public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType, Duration duration) { + this(ability, attachmentType, duration, null); + } public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType, Duration duration, String rule) { super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.ability = ability; this.attachmentType = attachmentType; - this.duration = duration; - if (duration == Duration.EndOfTurn) { - fixedTarget = true; + switch (duration) { + case WhileOnBattlefield: + case WhileInGraveyard: + case WhileOnStack: + independentEffect = false; + break; + default: + // such effects exist independent from the enchantment that created the effect + independentEffect = true; } - this.staticText = rule; - } - public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType, Duration duration) { - super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); - this.ability = ability; - this.attachmentType = attachmentType; - this.duration = duration; - if (duration == Duration.EndOfTurn) { - fixedTarget = true; + if (rule == null) { + setText(); + } else { + this.staticText = rule; } - setText(); - } - - public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType) { - super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); - this.ability = ability; - this.attachmentType = attachmentType; - setText(); } public GainAbilityAttachedEffect(final GainAbilityAttachedEffect effect) { @@ -81,7 +82,7 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl { this.ability = effect.ability.copy(); ability.newId(); // This is needed if the effect is copied e.g. by a clone so the ability can be added multiple times to permanents this.attachmentType = effect.attachmentType; - this.fixedTarget = effect.fixedTarget; + this.independentEffect = effect.independentEffect; } @Override @@ -92,27 +93,31 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl { @Override public void init(Ability source, Game game) { super.init(source, game); - if (fixedTarget) { + if (affectedObjectsSet) { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { - this.setTargetPointer(new FixedTarget(equipment.getAttachedTo())); + this.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game.getState().getZoneChangeCounter(equipment.getAttachedTo()))); } } } @Override public boolean apply(Game game, Ability source) { - Permanent creature = null; - if (fixedTarget) { - creature = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent permanent = null; + if (affectedObjectsSet) { + permanent = game.getPermanent(targetPointer.getFirst(game, source)); + if (permanent == null) { + discard(); + return true; + } } else { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { - creature = game.getPermanent(equipment.getAttachedTo()); + permanent = game.getPermanent(equipment.getAttachedTo()); } } - if (creature != null) { - creature.addAbility(ability, source.getSourceId(), game, false); + if (permanent != null) { + permanent.addAbility(ability, source.getSourceId(), game, false); } return true; }