* Fixed some ability and subtype removing effects (fixes #1352).

This commit is contained in:
LevelX2 2015-11-07 12:29:31 +01:00
parent bb99148b78
commit b1c3d690f5
19 changed files with 300 additions and 189 deletions

View file

@ -34,6 +34,7 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.repository.CardRepository;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.DependencyType; import mage.constants.DependencyType;
import mage.constants.Duration; import mage.constants.Duration;
@ -108,14 +109,16 @@ public class MagusOfTheMoon extends CardImpl {
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { 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) { switch (layer) {
case AbilityAddingRemovingEffects_6:
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4: 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"); land.getSubtype().add("Mountain");
break; break;
case AbilityAddingRemovingEffects_6:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
} }
} }
return true; return true;

View file

@ -28,6 +28,12 @@
package mage.sets.ninthedition; package mage.sets.ninthedition;
import java.util.UUID; 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.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
@ -35,11 +41,6 @@ import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.constants.Zone; 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.common.FilterLandPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SupertypePredicate; 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}"); super(ownerId, 176, "Blood Moon", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
this.expansionSetCode = "9ED"; this.expansionSetCode = "9ED";
// Nonbasic lands are Mountains. // Nonbasic lands are Mountains.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodMoonEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodMoonEffect()));
} }
@ -74,6 +74,7 @@ public class BloodMoon extends CardImpl {
class BloodMoonEffect extends ContinuousEffectImpl { class BloodMoonEffect extends ContinuousEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent(); private static final FilterLandPermanent filter = new FilterLandPermanent();
static { static {
filter.add(Predicates.not(new SupertypePredicate("Basic"))); filter.add(Predicates.not(new SupertypePredicate("Basic")));
} }
@ -99,16 +100,18 @@ class BloodMoonEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { 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) { switch (layer) {
case AbilityAddingRemovingEffects_6:
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4: 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"); land.getSubtype().add("Mountain");
break; break;
case AbilityAddingRemovingEffects_6:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
} }
} }
return true; return true;

View file

@ -28,14 +28,13 @@
package mage.sets.returntoravnica; package mage.sets.returntoravnica;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.mana.AnyColorManaAbility; import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent; 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." // 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))); 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. // {T}: Add one mana of any color to your mana pool.
this.addAbility(new AnyColorManaAbility()); this.addAbility(new AnyColorManaAbility());
@ -66,4 +64,3 @@ public class ChromaticLantern extends CardImpl {
return new ChromaticLantern(this); return new ChromaticLantern(this);
} }
} }

View file

@ -43,7 +43,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileAllEffect; import mage.abilities.effects.common.ExileAllEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; 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.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
@ -133,7 +133,7 @@ class ChainerDementiaMasterEffect extends OneShotEffect {
ContinuousEffectImpl effect = new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield); ContinuousEffectImpl effect = new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield);
effect.setTargetPointer(new FixedTarget(permanent, game)); effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source); 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)); effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source); game.addEffect(effect, source);
} }

View file

@ -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);
}
}

View file

@ -8,6 +8,7 @@ package mage.abilities.effects.common;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.choices.ChoiceBasicLandType;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
@ -45,14 +46,7 @@ public class ChooseBasicLandTypeEffect extends OneShotEffect {
mageObject = game.getObject(source.getSourceId()); mageObject = game.getObject(source.getSourceId());
} }
if (controller != null && mageObject != null) { if (controller != null && mageObject != null) {
ChoiceImpl choices = new ChoiceImpl(true); ChoiceImpl choices = new ChoiceBasicLandType();
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");
if (controller.choose(Outcome.Neutral, choices, game)) { if (controller.choose(Outcome.Neutral, choices, game)) {
game.informPlayers(mageObject.getName() + ": Chosen basic land type is " + choices.getChoice()); game.informPlayers(mageObject.getName() + ": Chosen basic land type is " + choices.getChoice());
game.getState().setValue(mageObject.getId().toString() + VALUE_KEY, choices.getChoice()); game.getState().setValue(mageObject.getId().toString() + VALUE_KEY, choices.getChoice());

View file

@ -37,6 +37,7 @@ import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
import mage.cards.repository.CardRepository;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceBasicLandType; import mage.choices.ChoiceBasicLandType;
import mage.constants.CardType; import mage.constants.CardType;
@ -147,8 +148,19 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
Permanent land = game.getPermanent(targetPermanent); Permanent land = game.getPermanent(targetPermanent);
if (land != null) { if (land != null) {
switch (layer) { 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); 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) { for (String landType : landTypes) {
switch (landType) { switch (landType) {
case "Swamp": case "Swamp":
@ -169,14 +181,6 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
} }
} }
break; 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;
} }
} }
} }

View file

@ -67,7 +67,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect {
chosenType = typeChoice.getChoice(); chosenType = typeChoice.getChoice();
if (chosenType != null && !chosenType.isEmpty()) { if (chosenType != null && !chosenType.isEmpty()) {
// ADD TYPE TO TARGET // 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))); effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source)));
game.addEffect(effect, source); game.addEffect(effect, source);
return true; return true;

View file

@ -27,14 +27,14 @@
*/ */
package mage.abilities.effects.common.continuous; 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.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -48,7 +48,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
protected Token token; protected Token token;
protected String type; protected String type;
private FilterPermanent filter; private final FilterPermanent filter;
public BecomesCreatureAllEffect(Token token, String type, FilterPermanent filter, Duration duration) { public BecomesCreatureAllEffect(Token token, String type, FilterPermanent filter, Duration duration) {
super(duration, Outcome.BecomeCreature); super(duration, Outcome.BecomeCreature);
@ -71,7 +71,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { 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) { if (permanent != null) {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
@ -93,9 +93,10 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
if (token.getColor(game).hasColor()) if (token.getColor(game).hasColor()) {
permanent.getColor(game).setColor(token.getColor(game)); permanent.getColor(game).setColor(token.getColor(game));
} }
}
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {

View file

@ -29,6 +29,7 @@ package mage.abilities.effects.common.continuous;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
@ -110,7 +111,7 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
switch (loseType) { switch (loseType) {
case ALL: case ALL:
case ALL_BUT_COLOR: case ALL_BUT_COLOR:
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
break; break;
} }
if (token.getSubtype().size() > 0) { if (token.getSubtype().size() > 0) {

View file

@ -25,13 +25,13 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.effects.common.continuous; package mage.abilities.effects.common.continuous;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
@ -106,7 +106,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
} }
} }
if ("".equals(type) || type == null) { if ("".equals(type) || type == null) {
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
} }
if (token.getSubtype().size() > 0) { if (token.getSubtype().size() > 0) {
permanent.getSubtype().addAll(token.getSubtype()); permanent.getSubtype().addAll(token.getSubtype());
@ -123,7 +123,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
if (token.getAbilities().size() > 0) { if (token.getAbilities().size() > 0) {
for (Ability ability: token.getAbilities()) { for (Ability ability : token.getAbilities()) {
permanent.addAbility(ability, game); permanent.addAbility(ability, game);
} }
} }
@ -156,8 +156,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements
private void setText() { private void setText() {
if (type != null && type.length() > 0) { if (type != null && type.length() > 0) {
staticText = duration.toString() + " {this} becomes a " + token.getDescription() + " that's still a " + this.type; staticText = duration.toString() + " {this} becomes a " + token.getDescription() + " that's still a " + this.type;
} } else {
else {
staticText = duration.toString() + " {this} becomes a " + token.getDescription(); staticText = duration.toString() + " {this} becomes a " + token.getDescription();
} }
} }

View file

@ -28,14 +28,15 @@
package mage.abilities.effects.common.continuous; package mage.abilities.effects.common.continuous;
import java.util.UUID; 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.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
@ -87,11 +88,11 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
if (loseAllAbilities) { if (loseAllAbilities) {
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
permanent.getSubtype().addAll(token.getSubtype()); permanent.getSubtype().addAll(token.getSubtype());
} else { } else {
if (token.getSubtype().size() > 0) { if (token.getSubtype().size() > 0) {
for (String subtype :token.getSubtype()) { for (String subtype : token.getSubtype()) {
if (!permanent.getSubtype().contains(subtype)) { if (!permanent.getSubtype().contains(subtype)) {
permanent.getSubtype().add(subtype); permanent.getSubtype().add(subtype);
} }
@ -143,7 +144,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
result = true; result = true;
} }
} }
if (!result && this.duration.equals(Duration.Custom) ) { if (!result && this.duration.equals(Duration.Custom)) {
this.discard(); this.discard();
} }
return result; return result;
@ -166,7 +167,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Target target = mode.getTargets().get(0); Target target = mode.getTargets().get(0);
if(target.getMaxNumberOfTargets() > 1){ if (target.getMaxNumberOfTargets() > 1) {
if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) { if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) {
sb.append("up to "); sb.append("up to ");
} }

View file

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import static mage.constants.Layer.TypeChangingEffects_4; import static mage.constants.Layer.TypeChangingEffects_4;
@ -21,20 +22,20 @@ import mage.game.permanent.Permanent;
* *
* @author LevelX2 * @author LevelX2
*/ */
public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl { public class BecomesCreatureTypeTargetEffect extends ContinuousEffectImpl {
protected ArrayList<String> subtypes = new ArrayList(); protected ArrayList<String> 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)); this(duration, createArrayList(subtype));
} }
public BecomesSubtypeTargetEffect(Duration duration, ArrayList<String> subtypes) { public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList<String> subtypes) {
this(duration, subtypes, true); this(duration, subtypes, true);
} }
public BecomesSubtypeTargetEffect(Duration duration, ArrayList<String> subtypes, boolean loseOther) { public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList<String> subtypes, boolean loseOther) {
super(duration, Outcome.Detriment); super(duration, Outcome.Detriment);
this.subtypes = subtypes; this.subtypes = subtypes;
this.staticText = setText(); this.staticText = setText();
@ -47,7 +48,7 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl {
return subtypes; return subtypes;
} }
public BecomesSubtypeTargetEffect(final BecomesSubtypeTargetEffect effect) { public BecomesCreatureTypeTargetEffect(final BecomesCreatureTypeTargetEffect effect) {
super(effect); super(effect);
this.subtypes.addAll(effect.subtypes); this.subtypes.addAll(effect.subtypes);
this.loseOther = effect.loseOther; this.loseOther = effect.loseOther;
@ -60,8 +61,8 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl {
} }
@Override @Override
public BecomesSubtypeTargetEffect copy() { public BecomesCreatureTypeTargetEffect copy() {
return new BecomesSubtypeTargetEffect(this); return new BecomesCreatureTypeTargetEffect(this);
} }
@Override @Override
@ -72,7 +73,7 @@ public class BecomesSubtypeTargetEffect extends ContinuousEffectImpl {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (loseOther) { if (loseOther) {
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
permanent.getSubtype().addAll(subtypes); permanent.getSubtype().addAll(subtypes);
} else { } else {
for (String subtype : subtypes) { for (String subtype : subtypes) {

View file

@ -6,12 +6,9 @@
package mage.abilities.effects.common.continuous; package mage.abilities.effects.common.continuous;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -78,7 +75,7 @@ public class BecomesSubtypeAllEffect extends ContinuousEffectImpl {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (loseOther) { if (loseOther) {
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
permanent.getSubtype().addAll(subtypes); permanent.getSubtype().addAll(subtypes);
} else { } else {
for (String subtype : subtypes) { for (String subtype : subtypes) {

View file

@ -30,6 +30,7 @@ package mage.abilities.effects.common.continuous;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -60,8 +61,7 @@ public class LoseAllCreatureTypesTargetEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {
permanent.getSubtype().clear(); return permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
return true;
} }
return false; return false;
} }

View file

@ -30,6 +30,7 @@ package mage.abilities.effects.common.continuous;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.repository.CardRepository;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
@ -50,7 +51,8 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement
private final int lessThan; 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 dynamicValue
* @param lessThan * @param lessThan
@ -84,7 +86,7 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
permanent.getCardType().remove(CardType.CREATURE); permanent.getCardType().remove(CardType.CREATURE);
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
if (permanent.isAttacking() || permanent.getBlocking() > 0) { if (permanent.isAttacking() || permanent.getBlocking() > 0) {
permanent.removeFromCombat(game); permanent.removeFromCombat(game);
} }

View file

@ -29,10 +29,14 @@ package mage.abilities.effects.common.continuous;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl; 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.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -70,7 +74,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl {
if (equipment != null && equipment.getAttachedTo() != null) { if (equipment != null && equipment.getAttachedTo() != null) {
Permanent target = game.getPermanent(equipment.getAttachedTo()); Permanent target = game.getPermanent(equipment.getAttachedTo());
if (target != null) { if (target != null) {
target.getSubtype().clear(); target.getSubtype().retainAll(CardRepository.instance.getLandTypes());
target.getSubtype().addAll(setSubtypes); target.getSubtype().addAll(setSubtypes);
} }
} }
@ -91,7 +95,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl {
} }
sb.append(" creature is a"); sb.append(" creature is a");
for (String subtype: this.setSubtypes) { for (String subtype : this.setSubtypes) {
sb.append(" ").append(subtype); sb.append(" ").append(subtype);
} }
staticText = sb.toString(); staticText = sb.toString();

View file

@ -35,6 +35,7 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.SourceEffect; import mage.abilities.effects.common.continuous.SourceEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.repository.CardRepository;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.DependencyType; import mage.constants.DependencyType;
import mage.constants.Duration; import mage.constants.Duration;
@ -181,7 +182,7 @@ public class BestowAbility extends SpellAbility {
} }
} else { } else {
permanent.getCardType().remove(CardType.CREATURE); permanent.getCardType().remove(CardType.CREATURE);
permanent.getSubtype().clear(); permanent.getSubtype().retainAll(CardRepository.instance.getLandTypes());
if (!permanent.getSubtype().contains("Aura")) { if (!permanent.getSubtype().contains("Aura")) {
permanent.getSubtype().add("Aura"); permanent.getSubtype().add("Aura");
} }

View file

@ -69,6 +69,8 @@ public enum CardRepository {
private Dao<CardInfo, Object> cardDao; private Dao<CardInfo, Object> cardDao;
private Set<String> classNames; private Set<String> classNames;
private final TreeSet<String> landTypes = new TreeSet();
private CardRepository() { private CardRepository() {
File file = new File("db"); File file = new File("db");
if (!file.exists()) { if (!file.exists()) {
@ -85,7 +87,7 @@ public enum CardRepository {
TableUtils.createTableIfNotExists(connectionSource, CardInfo.class); TableUtils.createTableIfNotExists(connectionSource, CardInfo.class);
cardDao = DaoManager.createDao(connectionSource, CardInfo.class); cardDao = DaoManager.createDao(connectionSource, CardInfo.class);
} catch (SQLException ex) { } 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) { } 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; return null;
} }
@ -252,21 +254,22 @@ public enum CardRepository {
} }
public Set<String> getLandTypes() { public Set<String> getLandTypes() {
TreeSet<String> subtypes = new TreeSet<>(); if (landTypes.isEmpty()) {
try { try {
QueryBuilder<CardInfo, Object> qb = cardDao.queryBuilder(); QueryBuilder<CardInfo, Object> qb = cardDao.queryBuilder();
qb.distinct().selectColumns("subtypes"); qb.distinct().selectColumns("subtypes");
qb.where().like("types", new SelectArg('%' + CardType.LAND.name() + '%')); qb.where().like("types", new SelectArg('%' + CardType.LAND.name() + '%'));
List<CardInfo> results = cardDao.query(qb.prepare()); List<CardInfo> results = cardDao.query(qb.prepare());
for (CardInfo card : results) { for (CardInfo card : results) {
subtypes.addAll(card.getSubTypes()); landTypes.addAll(card.getSubTypes());
} }
// Removing Dryad because of Dryad Arbor // Removing Dryad because of Dryad Arbor
subtypes.remove("Dryad"); landTypes.remove("Dryad");
} catch (SQLException ex) { } catch (SQLException ex) {
} }
return subtypes; }
return landTypes;
} }
public CardInfo findCard(String setCode, int cardNumber) { public CardInfo findCard(String setCode, int cardNumber) {
@ -391,7 +394,7 @@ public enum CardRepository {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL); ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME + "Content"); return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME + "Content");
} catch (SQLException ex) { } catch (SQLException ex) {
ex.printStackTrace(); Logger.getLogger(CardRepository.class).error("Error getting content version from DB - ", ex);
} }
return 0; return 0;
} }
@ -401,7 +404,7 @@ public enum CardRepository {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL); ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
RepositoryUtil.updateVersion(connectionSource, VERSION_ENTITY_NAME + "Content", version); RepositoryUtil.updateVersion(connectionSource, VERSION_ENTITY_NAME + "Content", version);
} catch (SQLException ex) { } catch (SQLException ex) {
ex.printStackTrace(); Logger.getLogger(CardRepository.class).error("Error getting content version - ", ex);
} }
} }