diff --git a/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoon.java b/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoon.java index 4d1d52f33e..131e99c240 100644 --- a/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoon.java +++ b/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoon.java @@ -34,6 +34,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.mana.RedManaAbility; import mage.cards.CardImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.DependencyType; import mage.constants.Duration; @@ -108,14 +109,16 @@ public class MagusOfTheMoon extends CardImpl { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { for (Permanent land : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { switch (layer) { - case AbilityAddingRemovingEffects_6: - land.removeAllAbilities(source.getSourceId(), game); - land.addAbility(new RedManaAbility(), source.getSourceId(), game); - break; case TypeChangingEffects_4: - land.getSubtype().clear(); + // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects + // So the ability removing has to be done before Layer 6 + land.removeAllAbilities(source.getSourceId(), game); + land.getSubtype().removeAll(CardRepository.instance.getLandTypes()); land.getSubtype().add("Mountain"); break; + case AbilityAddingRemovingEffects_6: + land.addAbility(new RedManaAbility(), source.getSourceId(), game); + break; } } return true; diff --git a/Mage.Sets/src/mage/sets/ninthedition/BloodMoon.java b/Mage.Sets/src/mage/sets/ninthedition/BloodMoon.java index c374adde74..ac21d7d985 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/BloodMoon.java +++ b/Mage.Sets/src/mage/sets/ninthedition/BloodMoon.java @@ -28,6 +28,12 @@ package mage.sets.ninthedition; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -35,11 +41,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.mana.RedManaAbility; -import mage.cards.CardImpl; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SupertypePredicate; @@ -56,7 +57,6 @@ public class BloodMoon extends CardImpl { super(ownerId, 176, "Blood Moon", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); this.expansionSetCode = "9ED"; - // Nonbasic lands are Mountains. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodMoonEffect())); } @@ -74,6 +74,7 @@ public class BloodMoon extends CardImpl { class BloodMoonEffect extends ContinuousEffectImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); + static { filter.add(Predicates.not(new SupertypePredicate("Basic"))); } @@ -99,16 +100,18 @@ class BloodMoonEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent land: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent land : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { switch (layer) { - case AbilityAddingRemovingEffects_6: - land.removeAllAbilities(source.getSourceId(), game); - land.addAbility(new RedManaAbility(), source.getSourceId(), game); - break; case TypeChangingEffects_4: - land.getSubtype().clear(); + // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects + // So the ability removing has to be done before Layer 6 + land.removeAllAbilities(source.getSourceId(), game); + land.getSubtype().removeAll(CardRepository.instance.getLandTypes()); land.getSubtype().add("Mountain"); break; + case AbilityAddingRemovingEffects_6: + land.addAbility(new RedManaAbility(), source.getSourceId(), game); + break; } } return true; diff --git a/Mage.Sets/src/mage/sets/returntoravnica/ChromaticLantern.java b/Mage.Sets/src/mage/sets/returntoravnica/ChromaticLantern.java index f17b07b117..7f40206182 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/ChromaticLantern.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/ChromaticLantern.java @@ -28,14 +28,13 @@ package mage.sets.returntoravnica; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterLandPermanent; @@ -51,7 +50,6 @@ public class ChromaticLantern extends CardImpl { // Lands you control have "{T}: Add one mana of any color to your mana pool." this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new AnyColorManaAbility(), Duration.WhileOnBattlefield, new FilterLandPermanent("Lands"), false))); - // {T}: Add one mana of any color to your mana pool. this.addAbility(new AnyColorManaAbility()); @@ -66,4 +64,3 @@ public class ChromaticLantern extends CardImpl { return new ChromaticLantern(this); } } - diff --git a/Mage.Sets/src/mage/sets/torment/ChainerDementiaMaster.java b/Mage.Sets/src/mage/sets/torment/ChainerDementiaMaster.java index 88929b04b2..253f7ade51 100644 --- a/Mage.Sets/src/mage/sets/torment/ChainerDementiaMaster.java +++ b/Mage.Sets/src/mage/sets/torment/ChainerDementiaMaster.java @@ -43,7 +43,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileAllEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; -import mage.abilities.effects.common.continuous.BecomesSubtypeTargetEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureTypeTargetEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -133,7 +133,7 @@ class ChainerDementiaMasterEffect extends OneShotEffect { ContinuousEffectImpl effect = new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield); effect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(effect, source); - effect = new BecomesSubtypeTargetEffect(Duration.WhileOnBattlefield, new ArrayList<>(Arrays.asList("Nightmare")), false); + effect = new BecomesCreatureTypeTargetEffect(Duration.WhileOnBattlefield, new ArrayList<>(Arrays.asList("Nightmare")), false); effect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(effect, source); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/LandTypeChangingEffects.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/LandTypeChangingEffects.java new file mode 100644 index 0000000000..3805325ccb --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/LandTypeChangingEffects.java @@ -0,0 +1,100 @@ +/* + * 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.abilities.mana.AnyColorManaAbility; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class LandTypeChangingEffects extends CardTestPlayerBase { + + /** + * + * Playing a commander game. Opponent had a Magus of the Moon, and I later + * dropped a Chromatic Lantern. + * + * I was not allowed to use the Chromatic Lantern's ability. Since layers + * are tricky I asked on the Judge's chat to confirm and the user "luma" + * said it should work on this scenario. + * + */ + @Test + public void testMagusOfTheMoonAndChromaticLantern() { + // Nonbasic lands are Mountains. + addCard(Zone.BATTLEFIELD, playerA, "Magus of the Moon"); + + addCard(Zone.BATTLEFIELD, playerB, "Canopy Vista", 1); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + // Lands you control have "{T}: Add one mana of any color to your mana pool." + // {T}: Add one mana of any color to your mana pool. + addCard(Zone.HAND, playerB, "Chromatic Lantern"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Chromatic Lantern"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerB, "Chromatic Lantern", 1); + + assertType("Canopy Vista", CardType.LAND, "Mountain"); + assertAbility(playerB, "Canopy Vista", new AnyColorManaAbility(), true); + } + + @Test + public void testChromaticLanternBeforeMagusOfTheMoon() { + // Nonbasic lands are Mountains. + addCard(Zone.HAND, playerA, "Magus of the Moon");// {2}{R} + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + + addCard(Zone.BATTLEFIELD, playerB, "Canopy Vista", 1); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + // Lands you control have "{T}: Add one mana of any color to your mana pool." + // {T}: Add one mana of any color to your mana pool. + addCard(Zone.HAND, playerB, "Chromatic Lantern"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Chromatic Lantern"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Magus of the Moon"); + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerB, "Chromatic Lantern", 1); + assertPermanentCount(playerA, "Magus of the Moon", 1); + + assertType("Canopy Vista", CardType.LAND, "Mountain"); + assertAbility(playerB, "Canopy Vista", new AnyColorManaAbility(), true); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java index 5d73e8dd40..9aa16ac8c5 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java @@ -8,6 +8,7 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.choices.ChoiceBasicLandType; import mage.choices.ChoiceImpl; import mage.constants.Outcome; import mage.game.Game; @@ -45,14 +46,7 @@ public class ChooseBasicLandTypeEffect extends OneShotEffect { mageObject = game.getObject(source.getSourceId()); } if (controller != null && mageObject != null) { - ChoiceImpl choices = new ChoiceImpl(true); - choices.setMessage("Choose basic land type"); - choices.isRequired(); - choices.getChoices().add("Forest"); - choices.getChoices().add("Plains"); - choices.getChoices().add("Mountain"); - choices.getChoices().add("Island"); - choices.getChoices().add("Swamp"); + ChoiceImpl choices = new ChoiceBasicLandType(); if (controller.choose(Outcome.Neutral, choices, game)) { game.informPlayers(mageObject.getName() + ": Chosen basic land type is " + choices.getChoice()); game.getState().setValue(mageObject.getId().toString() + VALUE_KEY, choices.getChoice()); diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java index 43e1bf12aa..e29c167c5c 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java @@ -37,6 +37,7 @@ import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.WhiteManaAbility; +import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceBasicLandType; import mage.constants.CardType; @@ -147,8 +148,19 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl { Permanent land = game.getPermanent(targetPermanent); if (land != null) { switch (layer) { - case AbilityAddingRemovingEffects_6: + case TypeChangingEffects_4: + // Attention: Cards like Unstable Frontier that use this class do not give the "Basic" supertype to the target + if (!land.getCardType().contains(CardType.LAND)) { + land.getCardType().add(CardType.LAND); + } + // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects + // So the ability removing has to be done before Layer 6 land.removeAllAbilities(source.getSourceId(), game); + // 305.7 + land.getSubtype().removeAll(CardRepository.instance.getLandTypes()); + land.getSubtype().addAll(landTypes); + break; + case AbilityAddingRemovingEffects_6: for (String landType : landTypes) { switch (landType) { case "Swamp": @@ -169,14 +181,6 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl { } } break; - case TypeChangingEffects_4: - // Attention: Cards like Unstable Frontier that use this class do not give the "Basic" supertype to the target - if (!land.getCardType().contains(CardType.LAND)) { - land.getCardType().add(CardType.LAND); - } - land.getSubtype().clear(); - land.getSubtype().addAll(landTypes); - break; } } } diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index 67c07ee1c0..538a4841fb 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -67,7 +67,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { chosenType = typeChoice.getChoice(); if (chosenType != null && !chosenType.isEmpty()) { // ADD TYPE TO TARGET - ContinuousEffect effect = new BecomesSubtypeTargetEffect(Duration.EndOfTurn, chosenType); + ContinuousEffect effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, chosenType); effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); game.addEffect(effect, source); return true; diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java index f891657cff..b01e282fb3 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java @@ -27,14 +27,14 @@ */ package mage.abilities.effects.common.continuous; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.effects.ContinuousEffectImpl; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -42,13 +42,13 @@ import mage.game.permanent.token.Token; /** * @author LevelX2 - * + * */ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { protected Token token; protected String type; - private FilterPermanent filter; + private final FilterPermanent filter; public BecomesCreatureAllEffect(Token token, String type, FilterPermanent filter, Duration duration) { super(duration, Outcome.BecomeCreature); @@ -71,7 +71,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { if (permanent != null) { switch (layer) { case TypeChangingEffects_4: @@ -93,8 +93,9 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { break; case ColorChangingEffects_5: if (sublayer == SubLayer.NA) { - if (token.getColor(game).hasColor()) + if (token.getColor(game).hasColor()) { permanent.getColor(game).setColor(token.getColor(game)); + } } break; case AbilityAddingRemovingEffects_6: diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java index 1658b00fc8..5a0f47fce5 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java @@ -29,6 +29,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -110,7 +111,7 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl { switch (loseType) { case ALL: case ALL_BUT_COLOR: - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); break; } if (token.getSubtype().size() > 0) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java index 37d0e41ac4..6202880d9b 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java @@ -25,13 +25,13 @@ * 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.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -106,7 +106,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements } } if ("".equals(type) || type == null) { - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); } if (token.getSubtype().size() > 0) { permanent.getSubtype().addAll(token.getSubtype()); @@ -123,7 +123,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements case AbilityAddingRemovingEffects_6: if (sublayer == SubLayer.NA) { if (token.getAbilities().size() > 0) { - for (Ability ability: token.getAbilities()) { + for (Ability ability : token.getAbilities()) { permanent.addAbility(ability, game); } } @@ -156,8 +156,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements private void setText() { if (type != null && type.length() > 0) { staticText = duration.toString() + " {this} becomes a " + token.getDescription() + " that's still a " + this.type; - } - else { + } else { staticText = duration.toString() + " {this} becomes a " + token.getDescription(); } } diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java index 10c22909b9..87eb0e989e 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2011 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,7 +20,7 @@ * 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. @@ -28,14 +28,15 @@ package mage.abilities.effects.common.continuous; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.effects.ContinuousEffectImpl; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; @@ -87,11 +88,11 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { if (loseAllAbilities) { - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); permanent.getSubtype().addAll(token.getSubtype()); } else { if (token.getSubtype().size() > 0) { - for (String subtype :token.getSubtype()) { + for (String subtype : token.getSubtype()) { if (!permanent.getSubtype().contains(subtype)) { permanent.getSubtype().add(subtype); } @@ -143,7 +144,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl { result = true; } } - if (!result && this.duration.equals(Duration.Custom) ) { + if (!result && this.duration.equals(Duration.Custom)) { this.discard(); } return result; @@ -166,7 +167,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl { } StringBuilder sb = new StringBuilder(); Target target = mode.getTargets().get(0); - if(target.getMaxNumberOfTargets() > 1){ + if (target.getMaxNumberOfTargets() > 1) { if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) { sb.append("up to "); } diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java similarity index 76% rename from Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeTargetEffect.java rename to Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java index f056b1ffee..b675cb4834 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.Duration; import mage.constants.Layer; import static mage.constants.Layer.TypeChangingEffects_4; @@ -21,20 +22,20 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ -public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl { +public class BecomesCreatureTypeTargetEffect extends ContinuousEffectImpl { protected ArrayList subtypes = new ArrayList(); - protected boolean loseOther; // loses other subtypes + protected boolean loseOther; // loses other creature types - public BecomesSubtypeTargetEffect(Duration duration, String subtype) { + public BecomesCreatureTypeTargetEffect(Duration duration, String subtype) { this(duration, createArrayList(subtype)); } - public BecomesSubtypeTargetEffect(Duration duration, ArrayList subtypes) { + public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList subtypes) { this(duration, subtypes, true); } - public BecomesSubtypeTargetEffect(Duration duration, ArrayList subtypes, boolean loseOther) { + public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList subtypes, boolean loseOther) { super(duration, Outcome.Detriment); this.subtypes = subtypes; this.staticText = setText(); @@ -47,7 +48,7 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl { return subtypes; } - public BecomesSubtypeTargetEffect(final BecomesSubtypeTargetEffect effect) { + public BecomesCreatureTypeTargetEffect(final BecomesCreatureTypeTargetEffect effect) { super(effect); this.subtypes.addAll(effect.subtypes); this.loseOther = effect.loseOther; @@ -60,8 +61,8 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl { } @Override - public BecomesSubtypeTargetEffect copy() { - return new BecomesSubtypeTargetEffect(this); + public BecomesCreatureTypeTargetEffect copy() { + return new BecomesCreatureTypeTargetEffect(this); } @Override @@ -72,7 +73,7 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (loseOther) { - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); permanent.getSubtype().addAll(subtypes); } else { for (String subtype : subtypes) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java index 80e7bcdb69..5b126ac4b5 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java @@ -6,12 +6,9 @@ package mage.abilities.effects.common.continuous; import java.util.ArrayList; -import java.util.Iterator; - -import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; @@ -26,90 +23,90 @@ import mage.game.permanent.Permanent; */ public class BecomesSubtypeAllEffect extends ContinuousEffectImpl { - protected ArrayList subtypes = new ArrayList(); - protected boolean loseOther; // loses other subtypes + protected ArrayList subtypes = new ArrayList(); + protected boolean loseOther; // loses other subtypes protected FilterCreaturePermanent filter; public BecomesSubtypeAllEffect(Duration duration, String subtype) { - this(duration, createArrayList(subtype)); - } + this(duration, createArrayList(subtype)); + } - public BecomesSubtypeAllEffect(Duration duration, ArrayList subtypes) { - this(duration, subtypes, new FilterCreaturePermanent("All creatures"), true); - } + public BecomesSubtypeAllEffect(Duration duration, ArrayList subtypes) { + this(duration, subtypes, new FilterCreaturePermanent("All creatures"), true); + } - public BecomesSubtypeAllEffect(Duration duration, - ArrayList subtypes, FilterCreaturePermanent filter, boolean loseOther) { - super(duration, Outcome.Detriment); - this.subtypes = subtypes; - this.staticText = setText(); - this.loseOther = loseOther; + public BecomesSubtypeAllEffect(Duration duration, + ArrayList subtypes, FilterCreaturePermanent filter, boolean loseOther) { + super(duration, Outcome.Detriment); + this.subtypes = subtypes; + this.staticText = setText(); + this.loseOther = loseOther; this.filter = filter; - } + } - private static ArrayList createArrayList(String subtype) { - ArrayList subtypes = new ArrayList<>(); - subtypes.add(subtype); - return subtypes; - } + private static ArrayList createArrayList(String subtype) { + ArrayList subtypes = new ArrayList<>(); + subtypes.add(subtype); + return subtypes; + } - public BecomesSubtypeAllEffect(final BecomesSubtypeAllEffect effect) { - super(effect); - this.subtypes.addAll(effect.subtypes); - this.loseOther = effect.loseOther; - this.filter = effect.filter; - } + public BecomesSubtypeAllEffect(final BecomesSubtypeAllEffect effect) { + super(effect); + this.subtypes.addAll(effect.subtypes); + this.loseOther = effect.loseOther; + this.filter = effect.filter; + } - @Override - public boolean apply(Game game, Ability source) { - return false; - } + @Override + public boolean apply(Game game, Ability source) { + return false; + } - @Override - public BecomesSubtypeAllEffect copy() { - return new BecomesSubtypeAllEffect(this); - } + @Override + public BecomesSubtypeAllEffect copy() { + return new BecomesSubtypeAllEffect(this); + } - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, - Game game) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { - if (permanent != null) { - switch (layer) { - case TypeChangingEffects_4: - if (loseOther) { - permanent.getSubtype().clear(); - permanent.getSubtype().addAll(subtypes); - } else { - for (String subtype : subtypes) { - if (!permanent.getSubtype().contains(subtype)) { - permanent.getSubtype().add(subtype); - } - } - } - break; - } - } else { - if (duration.equals(Duration.Custom)) { - discard(); - } - } - } - return true; - } + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, + Game game) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { + if (permanent != null) { + switch (layer) { + case TypeChangingEffects_4: + if (loseOther) { + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype().addAll(subtypes); + } else { + for (String subtype : subtypes) { + if (!permanent.getSubtype().contains(subtype)) { + permanent.getSubtype().add(subtype); + } + } + } + break; + } + } else { + if (duration.equals(Duration.Custom)) { + discard(); + } + } + } + return true; + } - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.TypeChangingEffects_4; - } + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.TypeChangingEffects_4; + } - private String setText() { - StringBuilder sb = new StringBuilder(); - sb.append("Target creature becomes that type"); - if (!duration.toString().isEmpty() - && !duration.equals(Duration.EndOfGame)) { - sb.append(" ").append(duration.toString()); - } - return sb.toString(); - } + private String setText() { + StringBuilder sb = new StringBuilder(); + sb.append("Target creature becomes that type"); + if (!duration.toString().isEmpty() + && !duration.equals(Duration.EndOfGame)) { + sb.append(" ").append(duration.toString()); + } + return sb.toString(); + } } diff --git a/Mage/src/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java index fdb1d714b8..de41de7c2b 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java @@ -30,6 +30,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; @@ -42,30 +43,29 @@ import mage.game.permanent.Permanent; * @author emerald000 */ public class LoseAllCreatureTypesTargetEffect extends ContinuousEffectImpl { - + public LoseAllCreatureTypesTargetEffect(Duration duration) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral); } - + public LoseAllCreatureTypesTargetEffect(final LoseAllCreatureTypesTargetEffect effect) { super(effect); } - + @Override public LoseAllCreatureTypesTargetEffect copy() { return new LoseAllCreatureTypesTargetEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { - permanent.getSubtype().clear(); - return true; + return permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); } return false; } - + @Override public String getText(Mode mode) { if (staticText != null && !staticText.isEmpty()) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java index 4f64c3fb86..660b98fc33 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java @@ -30,6 +30,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -50,10 +51,11 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement private final int lessThan; /** - * Permanent loses the creature type as long as the dynamic value is less than the value of lessThan. - * + * Permanent loses the creature type as long as the dynamic value is less + * than the value of lessThan. + * * @param dynamicValue - * @param lessThan + * @param lessThan */ public LoseCreatureTypeSourceEffect(DynamicValue dynamicValue, int lessThan) { super(Duration.WhileOnBattlefield, Outcome.Detriment); @@ -84,7 +86,7 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { permanent.getCardType().remove(CardType.CREATURE); - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); if (permanent.isAttacking() || permanent.getBlocking() > 0) { permanent.removeFromCombat(game); } diff --git a/Mage/src/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index 8dc84e142b..6c00848529 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -29,10 +29,14 @@ package mage.abilities.effects.common.continuous; import java.util.ArrayList; import java.util.List; - import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.*; +import mage.cards.repository.CardRepository; +import mage.constants.AttachmentType; +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; @@ -48,14 +52,14 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; - setText(); + setText(); } public SetCardSubtypeAttachedEffect(List setSubtypes, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.addAll(setSubtypes); this.attachmentType = attachmentType; - setText(); + setText(); } public SetCardSubtypeAttachedEffect(final SetCardSubtypeAttachedEffect effect) { @@ -70,8 +74,8 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { if (equipment != null && equipment.getAttachedTo() != null) { Permanent target = game.getPermanent(equipment.getAttachedTo()); if (target != null) { - target.getSubtype().clear(); - target.getSubtype().addAll(setSubtypes); + target.getSubtype().retainAll(CardRepository.instance.getLandTypes()); + target.getSubtype().addAll(setSubtypes); } } return true; @@ -91,7 +95,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { } sb.append(" creature is a"); - for (String subtype: this.setSubtypes) { + for (String subtype : this.setSubtypes) { sb.append(" ").append(subtype); } staticText = sb.toString(); diff --git a/Mage/src/mage/abilities/keyword/BestowAbility.java b/Mage/src/mage/abilities/keyword/BestowAbility.java index 3f721f8700..93307330d3 100644 --- a/Mage/src/mage/abilities/keyword/BestowAbility.java +++ b/Mage/src/mage/abilities/keyword/BestowAbility.java @@ -35,6 +35,7 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.SourceEffect; import mage.cards.Card; +import mage.cards.repository.CardRepository; import mage.constants.CardType; import mage.constants.DependencyType; import mage.constants.Duration; @@ -181,7 +182,7 @@ public class BestowAbility extends SpellAbility { } } else { permanent.getCardType().remove(CardType.CREATURE); - permanent.getSubtype().clear(); + permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes()); if (!permanent.getSubtype().contains("Aura")) { permanent.getSubtype().add("Aura"); } diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index 6e96be70a8..126a6903d9 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -69,6 +69,8 @@ public enum CardRepository { private Dao cardDao; private Set classNames; + private final TreeSet landTypes = new TreeSet(); + private CardRepository() { File file = new File("db"); if (!file.exists()) { @@ -85,7 +87,7 @@ public enum CardRepository { TableUtils.createTableIfNotExists(connectionSource, CardInfo.class); cardDao = DaoManager.createDao(connectionSource, CardInfo.class); } catch (SQLException ex) { - ex.printStackTrace(); + Logger.getLogger(CardRepository.class).error("Error creating card repository - ", ex); } } @@ -102,7 +104,7 @@ public enum CardRepository { } } } catch (SQLException ex) { - Logger.getLogger(CardRepository.class).error("Error adding cards to DB: " + ex.getCause()); + Logger.getLogger(CardRepository.class).error("Error adding cards to DB - ", ex); } return null; } @@ -252,21 +254,22 @@ public enum CardRepository { } public Set getLandTypes() { - TreeSet subtypes = new TreeSet<>(); - try { - QueryBuilder qb = cardDao.queryBuilder(); - qb.distinct().selectColumns("subtypes"); - qb.where().like("types", new SelectArg('%' + CardType.LAND.name() + '%')); - List results = cardDao.query(qb.prepare()); - for (CardInfo card : results) { - subtypes.addAll(card.getSubTypes()); - } - // Removing Dryad because of Dryad Arbor - subtypes.remove("Dryad"); + if (landTypes.isEmpty()) { + try { + QueryBuilder qb = cardDao.queryBuilder(); + qb.distinct().selectColumns("subtypes"); + qb.where().like("types", new SelectArg('%' + CardType.LAND.name() + '%')); + List results = cardDao.query(qb.prepare()); + for (CardInfo card : results) { + landTypes.addAll(card.getSubTypes()); + } + // Removing Dryad because of Dryad Arbor + landTypes.remove("Dryad"); - } catch (SQLException ex) { + } catch (SQLException ex) { + } } - return subtypes; + return landTypes; } public CardInfo findCard(String setCode, int cardNumber) { @@ -391,7 +394,7 @@ public enum CardRepository { ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL); return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME + "Content"); } catch (SQLException ex) { - ex.printStackTrace(); + Logger.getLogger(CardRepository.class).error("Error getting content version from DB - ", ex); } return 0; } @@ -401,7 +404,7 @@ public enum CardRepository { ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL); RepositoryUtil.updateVersion(connectionSource, VERSION_ENTITY_NAME + "Content", version); } catch (SQLException ex) { - ex.printStackTrace(); + Logger.getLogger(CardRepository.class).error("Error getting content version - ", ex); } }