diff --git a/Mage.Client/src/main/java/mage/client/cards/Card.java b/Mage.Client/src/main/java/mage/client/cards/Card.java index 09806d887ef..e984b305920 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Card.java +++ b/Mage.Client/src/main/java/mage/client/cards/Card.java @@ -46,6 +46,7 @@ import mage.client.util.ImageHelper; import mage.client.util.gui.ArrowBuilder; import mage.constants.CardType; import mage.constants.EnlargeMode; +import mage.constants.SubType; import mage.constants.SuperType; import mage.view.*; import org.apache.log4j.Logger; @@ -277,7 +278,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis if (!card.getSubTypes().isEmpty()) { sbType.append("- "); - for (String subType : card.getSubTypes()) { + for (SubType subType : card.getSubTypes()) { sbType.append(subType).append(' '); } } diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index 00c349a84b3..2e611c93cb1 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -1,15 +1,5 @@ package mage.client.cards; -import java.awt.*; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import javax.swing.*; import mage.cards.Card; import mage.cards.MageCard; import mage.cards.decks.DeckCardInfo; @@ -23,6 +13,7 @@ import mage.client.dialog.PreferencesDialog; import mage.client.plugins.impl.Plugins; import mage.client.util.*; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.util.RandomUtil; import mage.view.CardView; @@ -30,6 +21,17 @@ import mage.view.CardsView; import org.apache.log4j.Logger; import org.mage.card.arcane.CardRenderer; +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + /** * Created by StravantUser on 2016-09-20. */ @@ -1273,8 +1275,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg for (SuperType str : card.getSuperTypes()) { s |= str.toString().toLowerCase().contains(searchStr); } - for (String str : card.getSubTypes()) { - s |= str.toLowerCase().contains(searchStr); + for (SubType str : card.getSubTypes()) { + s |= str.toString().toLowerCase().contains(searchStr); } } // Rarity @@ -1349,8 +1351,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg for (SuperType type : card.getSuperTypes()) { t += ' ' + type.toString().toLowerCase(); } - for (String str : card.getSubTypes()) { - t += ' ' + str.toLowerCase(); + for (SubType str : card.getSubTypes()) { + t += " " + str.toString().toLowerCase(); } for (String qty : qtys.keySet()) { diff --git a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java index 310613284d8..d2deeea32db 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java @@ -357,8 +357,8 @@ public final class GuiDisplayUtil { if (!card.getSubTypes().isEmpty()) { types += "- "; } - for (String subType : card.getSubTypes()) { - types += subType + ' '; + for (SubType subType : card.getSubTypes()) { + types += subType + " "; } return types.trim(); } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index ac06a3c64f8..4bf8218156f 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -9,6 +9,7 @@ import mage.client.plugins.impl.Plugins; import mage.client.util.audio.AudioManager; import mage.constants.CardType; import mage.constants.EnlargeMode; +import mage.constants.SubType; import mage.constants.SuperType; import mage.view.AbilityView; import mage.view.CardView; @@ -681,7 +682,7 @@ public abstract class CardPanel extends MagePermanent implements MouseListener, if (!card.getSubTypes().isEmpty()) { sbType.append("- "); - for (String subType : card.getSubTypes()) { + for (SubType subType : card.getSubTypes()) { sbType.append(subType).append(' '); } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java index 11912aade90..b418cd22df5 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java @@ -3,6 +3,7 @@ package org.mage.card.arcane; import com.google.common.collect.MapMaker; import mage.cards.action.ActionCallback; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.view.CardView; import mage.view.CounterView; @@ -161,7 +162,7 @@ public class CardPanelRenderImpl extends CardPanel { for (SuperType s : this.view.getSuperTypes()) { sb.append(s); } - for (String s : this.view.getSubTypes()) { + for (SubType s : this.view.getSubTypes()) { sb.append(s); } for (String s : this.view.getManaCost()) { diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java index 1f175411889..f28cb134e4b 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java @@ -9,6 +9,7 @@ import mage.cards.ArtRect; import mage.client.dialog.PreferencesDialog; import mage.constants.AbilityType; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.view.CardView; import mage.view.CounterView; @@ -428,7 +429,7 @@ public abstract class CardRenderer { } if (!cardView.getSubTypes().isEmpty()) { sbType.append("- "); - for (String subType : cardView.getSubTypes()) { + for (SubType subType : cardView.getSubTypes()) { sbType.append(subType).append(' '); } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java index 740e4d73c28..2fd8363f41f 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java @@ -11,6 +11,8 @@ import mage.cards.FrameStyle; import mage.client.dialog.PreferencesDialog; import mage.constants.CardType; import mage.constants.MageObjectType; +import mage.constants.SubType; +import mage.util.SubTypeList; import mage.view.CardView; import mage.view.PermanentView; import org.apache.log4j.Logger; @@ -1024,8 +1026,8 @@ public class ModernCardRenderer extends CardRenderer { // Determine which background paint to use from a set of colors // and the current card. - protected static Paint getBackgroundPaint(ObjectColor colors, Collection types, Collection subTypes) { - if (subTypes.contains("Vehicle")) { + protected static Paint getBackgroundPaint(ObjectColor colors, Collection types, SubTypeList subTypes) { + if (subTypes.contains(SubType.VEHICLE)) { return BG_TEXTURE_VEHICLE; } else if (types.contains(CardType.LAND)) { return BG_TEXTURE_LAND; diff --git a/Mage.Common/src/main/java/mage/view/AbilityView.java b/Mage.Common/src/main/java/mage/view/AbilityView.java index c95d00de745..c3af08af6cd 100644 --- a/Mage.Common/src/main/java/mage/view/AbilityView.java +++ b/Mage.Common/src/main/java/mage/view/AbilityView.java @@ -32,6 +32,7 @@ import mage.ObjectColor; import mage.abilities.Ability; import mage.constants.CardType; import mage.constants.SuperType; +import mage.util.SubTypeList; import java.util.ArrayList; import java.util.EnumSet; @@ -57,7 +58,7 @@ public class AbilityView extends CardView { this.toughness = ""; this.loyalty = ""; this.cardTypes = EnumSet.noneOf(CardType.class); - this.subTypes = new ArrayList<>(); + this.subTypes = new SubTypeList(); this.superTypes =EnumSet.noneOf(SuperType.class); this.color = new ObjectColor(); this.manaCost = ability.getManaCosts().getSymbols(); diff --git a/Mage.Common/src/main/java/mage/view/CardView.java b/Mage.Common/src/main/java/mage/view/CardView.java index c938700d678..358a377a146 100644 --- a/Mage.Common/src/main/java/mage/view/CardView.java +++ b/Mage.Common/src/main/java/mage/view/CardView.java @@ -27,8 +27,6 @@ */ package mage.view; -import java.util.*; -import java.util.stream.Collectors; import mage.MageObject; import mage.ObjectColor; import mage.abilities.Abilities; @@ -51,6 +49,10 @@ import mage.game.stack.Spell; import mage.game.stack.StackAbility; import mage.target.Target; import mage.target.Targets; +import mage.util.SubTypeList; + +import java.util.*; +import java.util.stream.Collectors; /** * @author BetaSteward_at_googlemail.com @@ -68,7 +70,7 @@ public class CardView extends SimpleCardView { protected String loyalty = ""; protected String startingLoyalty; protected EnumSet cardTypes; - protected List subTypes; + protected SubTypeList subTypes; protected EnumSet superTypes; protected ObjectColor color; protected ObjectColor frameColor; @@ -238,7 +240,7 @@ public class CardView extends SimpleCardView { } if (!card.getSubtype(game).isEmpty()) { sbType.append("- "); - for (String subType : card.getSubtype(game)) { + for (SubType subType : card.getSubtype(game)) { sbType.append(subType).append(' '); } } @@ -573,7 +575,7 @@ public class CardView extends SimpleCardView { this.loyalty = ""; this.startingLoyalty = ""; this.cardTypes = EnumSet.noneOf(CardType.class); - this.subTypes = new ArrayList<>(); + this.subTypes = new SubTypeList(); this.superTypes = EnumSet.noneOf(SuperType.class); this.color = new ObjectColor(); this.frameColor = new ObjectColor(); @@ -697,7 +699,7 @@ public class CardView extends SimpleCardView { return cardTypes; } - public List getSubTypes() { + public SubTypeList getSubTypes() { return subTypes; } @@ -985,7 +987,7 @@ public class CardView extends SimpleCardView { } if (!getSubTypes().isEmpty()) { type.append(" - "); - type.append(String.join(" ", getSubTypes())); + type.append(String.join(" ", getSubTypes().stream().map(p->p.toString()).collect(Collectors.toSet()))); } return type.toString(); } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 0a17119b234..dc1baacac21 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -27,10 +27,6 @@ */ package mage.player.ai; -import java.io.IOException; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; import mage.MageObject; import mage.Mana; import mage.abilities.*; @@ -81,6 +77,11 @@ import mage.util.TournamentUtil; import mage.util.TreeNode; import org.apache.log4j.Logger; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; + /** * * suitable for two player games and some multiplayer games @@ -1340,8 +1341,8 @@ public class ComputerPlayer extends PlayerImpl implements Player { if (game.getOpponents(this.getId()).contains(permanent.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE) && !permanent.getSubtype(game).isEmpty()) { - if (choice.getChoices().contains(permanent.getSubtype(game).get(0))) { - choice.setChoice(permanent.getSubtype(game).get(0)); + if (choice.getChoices().contains(permanent.getSubtype(game).get(0).toString())) { + choice.setChoice(permanent.getSubtype(game).get(0).toString()); break; } } @@ -1352,8 +1353,8 @@ public class ComputerPlayer extends PlayerImpl implements Player { Player opponent = game.getPlayer(opponentId); for (Card card : opponent.getGraveyard().getCards(game)) { if (card != null && card.getCardType().contains(CardType.CREATURE) && !card.getSubtype(game).isEmpty()) { - if (choice.getChoices().contains(card.getSubtype(game).get(0))) { - choice.setChoice(card.getSubtype(game).get(0)); + if (choice.getChoices().contains(card.getSubtype(game).get(0).toString())) { + choice.setChoice(card.getSubtype(game).get(0).toString()); break; } } @@ -1368,8 +1369,8 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (UUID cardId : this.getHand()) { Card card = game.getCard(cardId); if (card != null && card.getCardType().contains(CardType.CREATURE) && !card.getSubtype(game).isEmpty()) { - if (choice.getChoices().contains(card.getSubtype(game).get(0))) { - choice.setChoice(card.getSubtype(game).get(0)); + if (choice.getChoices().contains(card.getSubtype(game).get(0).toString())) { + choice.setChoice(card.getSubtype(game).get(0).toString()); break; } } @@ -1378,8 +1379,8 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (UUID cardId : this.getLibrary().getCardList()) { Card card = game.getCard(cardId); if (card != null && card.getCardType().contains(CardType.CREATURE) && !card.getSubtype(game).isEmpty()) { - if (choice.getChoices().contains(card.getSubtype(game).get(0))) { - choice.setChoice(card.getSubtype(game).get(0)); + if (choice.getChoices().contains(card.getSubtype(game).get(0).toString())) { + choice.setChoice(card.getSubtype(game).get(0).toString()); break; } } diff --git a/Mage.Sets/src/mage/cards/a/AphettoDredging.java b/Mage.Sets/src/mage/cards/a/AphettoDredging.java index fa92e01c0f3..7caa69c441e 100644 --- a/Mage.Sets/src/mage/cards/a/AphettoDredging.java +++ b/Mage.Sets/src/mage/cards/a/AphettoDredging.java @@ -33,9 +33,8 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -67,9 +66,7 @@ public class AphettoDredging extends CardImpl { if (ability instanceof SpellAbility) { Player controller = game.getPlayer(ability.getControllerId()); if (controller != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) { if (!controller.canRespond()) { return; diff --git a/Mage.Sets/src/mage/cards/a/Aurification.java b/Mage.Sets/src/mage/cards/a/Aurification.java index 7d905002200..47c4a2ad41c 100644 --- a/Mage.Sets/src/mage/cards/a/Aurification.java +++ b/Mage.Sets/src/mage/cards/a/Aurification.java @@ -39,10 +39,7 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; @@ -50,8 +47,8 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import mage.util.SubTypeList; -import java.util.ArrayList; import java.util.UUID; /** @@ -76,8 +73,8 @@ public class Aurification extends CardImpl { this.addAbility(new AddGoldCountersAbility()); // Each creature with a gold counter on it is a Wall in addition to its other creature types and has defender. - ArrayList subtypes = new ArrayList<>(1); - subtypes.add("Wall"); + SubTypeList subtypes = new SubTypeList(); + subtypes.add(SubType.WALL); BecomesSubtypeAllEffect becomesSubtypeAllEffect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subtypes, filter, false); becomesSubtypeAllEffect.setText(""); diff --git a/Mage.Sets/src/mage/cards/b/BladeOfTheBloodchief.java b/Mage.Sets/src/mage/cards/b/BladeOfTheBloodchief.java index 2d7f0fd9110..b6a3d777f53 100644 --- a/Mage.Sets/src/mage/cards/b/BladeOfTheBloodchief.java +++ b/Mage.Sets/src/mage/cards/b/BladeOfTheBloodchief.java @@ -36,6 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -130,7 +131,7 @@ class BladeOfTheBloodchiefEffect extends OneShotEffect { if (enchantment != null && enchantment.getAttachedTo() != null) { Permanent creature = game.getPermanent(enchantment.getAttachedTo()); if (creature != null) { - if (creature.hasSubtype("Vampire", game)) { + if (creature.hasSubtype(SubType.VAMPIRE, game)) { creature.addCounters(CounterType.P1P1.createInstance(2), source, game); } else { creature.addCounters(CounterType.P1P1.createInstance(), source, game); diff --git a/Mage.Sets/src/mage/cards/b/BladedBracers.java b/Mage.Sets/src/mage/cards/b/BladedBracers.java index 71956a0f4eb..c83250805ec 100644 --- a/Mage.Sets/src/mage/cards/b/BladedBracers.java +++ b/Mage.Sets/src/mage/cards/b/BladedBracers.java @@ -37,10 +37,8 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; +import mage.util.SubTypeList; import java.util.UUID; @@ -57,12 +55,14 @@ public class BladedBracers extends CardImpl { // Equipped creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); - + SubTypeList subTypes = new SubTypeList(); + subTypes.add(SubType.HUMAN); + subTypes.add(SubType.ANGEL); // As long as equipped creature is a Human or an Angel, it has vigilance. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT), - new EquippedHasSubtypeCondition("Human", "Angel"), ruleText))); + new EquippedHasSubtypeCondition(subTypes), ruleText))); // Equip {2} this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); diff --git a/Mage.Sets/src/mage/cards/b/BloodMoon.java b/Mage.Sets/src/mage/cards/b/BloodMoon.java index 1893837119a..c064eadcc3f 100644 --- a/Mage.Sets/src/mage/cards/b/BloodMoon.java +++ b/Mage.Sets/src/mage/cards/b/BloodMoon.java @@ -33,7 +33,6 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.mana.RedManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; @@ -101,7 +100,7 @@ class BloodMoonEffect extends ContinuousEffectImpl { // 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(game).removeAll(CardRepository.instance.getLandTypes()); + land.getSubtype(game).removeAll(SubType.getLandTypes(false)); land.getSubtype(game).add("Mountain"); break; case AbilityAddingRemovingEffects_6: diff --git a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java index 7d7675a5497..318f6e9eefb 100644 --- a/Mage.Sets/src/mage/cards/b/BloodlineShaman.java +++ b/Mage.Sets/src/mage/cards/b/BloodlineShaman.java @@ -34,7 +34,6 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; import mage.cards.*; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -47,6 +46,7 @@ import mage.game.Game; import mage.players.Player; import java.util.UUID; +import java.util.stream.Collectors; /** * @@ -103,7 +103,7 @@ class BloodlineShamanEffect extends OneShotEffect { // Choose a creature type. Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!controller.choose(outcome, typeChoice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/b/BoldwyrIntimidator.java b/Mage.Sets/src/mage/cards/b/BoldwyrIntimidator.java index aa154e9ea4b..fc127c9b9c1 100644 --- a/Mage.Sets/src/mage/cards/b/BoldwyrIntimidator.java +++ b/Mage.Sets/src/mage/cards/b/BoldwyrIntimidator.java @@ -39,13 +39,12 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import java.util.ArrayList; -import java.util.Collections; import java.util.UUID; /** @@ -65,14 +64,14 @@ public class BoldwyrIntimidator extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoldwyrIntimidatorEffect())); // {R}: Target creature becomes a Coward until end of turn. - Effect effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, new ArrayList<>(Collections.singletonList("Coward")), true); + Effect effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, SubType.COWARD); effect.setText("Target creature becomes a Coward until end of turn"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{R}")); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); // {2}{R}: Target creature becomes a Warrior until end of turn. - effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, new ArrayList<>(Collections.singletonList("Warrior")), true); + effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, SubType.WARRIOR); effect.setText("Target creature becomes a Warrior until end of turn"); ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}{R}")); ability.addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/b/BondsOfFaith.java b/Mage.Sets/src/mage/cards/b/BondsOfFaith.java index 4d8cf936074..a24cdd1858d 100644 --- a/Mage.Sets/src/mage/cards/b/BondsOfFaith.java +++ b/Mage.Sets/src/mage/cards/b/BondsOfFaith.java @@ -40,10 +40,7 @@ import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -69,8 +66,8 @@ public class BondsOfFaith extends CardImpl { this.addAbility(ability); // Enchanted creature gets +2/+2 as long as it's a Human. Otherwise, it can't attack or block. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(2, 2), new EquippedHasSubtypeCondition("Human"), rule))); - Effect effect = new ConditionalRestrictionEffect(new CantAttackBlockAttachedEffect(AttachmentType.AURA), new InvertCondition(new EquippedHasSubtypeCondition("Human"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(2, 2), new EquippedHasSubtypeCondition(SubType.HUMAN), rule))); + Effect effect = new ConditionalRestrictionEffect(new CantAttackBlockAttachedEffect(AttachmentType.AURA), new InvertCondition(new EquippedHasSubtypeCondition(SubType.HUMAN))); effect.setText("Otherwise, it can't attack or block"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } diff --git a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java index 363ace046df..a030d4733bd 100644 --- a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java +++ b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java @@ -27,7 +27,6 @@ */ package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -36,10 +35,7 @@ import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; @@ -48,6 +44,8 @@ import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** * * @author emerald000 @@ -111,7 +109,7 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.isCreature() - && creature.hasSubtype("Warrior", game) + && creature.hasSubtype(SubType.WARRIOR, game) && !event.getTargetId().equals(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/b/ButchersCleaver.java b/Mage.Sets/src/mage/cards/b/ButchersCleaver.java index 6d374950a85..1ae0888fb37 100644 --- a/Mage.Sets/src/mage/cards/b/ButchersCleaver.java +++ b/Mage.Sets/src/mage/cards/b/ButchersCleaver.java @@ -37,10 +37,7 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import java.util.UUID; @@ -62,7 +59,7 @@ public class ButchersCleaver extends CardImpl { // As long as equipped creature is a Human, it has lifelink. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.EQUIPMENT), - new EquippedHasSubtypeCondition("Human"), staticText))); + new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); // Equip {3} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3))); diff --git a/Mage.Sets/src/mage/cards/c/CallToTheKindred.java b/Mage.Sets/src/mage/cards/c/CallToTheKindred.java index 3b1c1611c0c..a62f05882a1 100644 --- a/Mage.Sets/src/mage/cards/c/CallToTheKindred.java +++ b/Mage.Sets/src/mage/cards/c/CallToTheKindred.java @@ -124,8 +124,8 @@ class CallToTheKindredEffect extends OneShotEffect { if (!creature.getAbilities().contains(ChangelingAbility.getInstance())) { StringBuilder sb = new StringBuilder("creature card with at least one subtype from: "); ArrayList> subtypes = new ArrayList<>(); - for (String subtype : creature.getSubtype(game)) { - subtypes.add(new SubtypePredicate(SubType.byDescription(subtype))); + for (SubType subtype : creature.getSubtype(game)) { + subtypes.add(new SubtypePredicate(subtype)); sb.append(subtype).append(", "); } filter.add(Predicates.or(subtypes)); diff --git a/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java b/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java index 9a9cfb45b12..340081d3bc7 100644 --- a/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java +++ b/Mage.Sets/src/mage/cards/c/CaptivatingVampire.java @@ -119,7 +119,7 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { break; case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { - if (!permanent.hasSubtype("Vampire", game)) { + if (!permanent.hasSubtype(SubType.VAMPIRE, game)) { permanent.getSubtype(game).add("Vampire"); } } diff --git a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java index 8fcc5ae9d04..341102f14a5 100644 --- a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java +++ b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java @@ -87,13 +87,13 @@ public class CavernOfSouls extends CardImpl { class CavernOfSoulsManaBuilder extends ConditionalManaBuilder { - String creatureType; + SubType creatureType; @Override public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) { Object value = game.getState().getValue(source.getSourceId() + "_type"); if (value != null && value instanceof String) { - creatureType = (String) value; + creatureType = SubType.byDescription((String) value); } Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); @@ -117,7 +117,7 @@ class CavernOfSoulsManaBuilder extends ConditionalManaBuilder { class CavernOfSoulsConditionalMana extends ConditionalMana { - public CavernOfSoulsConditionalMana(Mana mana, String creatureType) { + public CavernOfSoulsConditionalMana(Mana mana, SubType creatureType) { super(mana); staticText = "Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered"; addCondition(new CavernOfSoulsManaCondition(creatureType)); @@ -126,9 +126,9 @@ class CavernOfSoulsConditionalMana extends ConditionalMana { class CavernOfSoulsManaCondition extends CreatureCastManaCondition { - String creatureType; + SubType creatureType; - CavernOfSoulsManaCondition(String creatureType) { + CavernOfSoulsManaCondition(SubType creatureType) { this.creatureType = creatureType; } diff --git a/Mage.Sets/src/mage/cards/c/ChainerDementiaMaster.java b/Mage.Sets/src/mage/cards/c/ChainerDementiaMaster.java index 17cc2ac5bc6..5c680f9a7fe 100644 --- a/Mage.Sets/src/mage/cards/c/ChainerDementiaMaster.java +++ b/Mage.Sets/src/mage/cards/c/ChainerDementiaMaster.java @@ -55,8 +55,6 @@ import mage.players.Player; import mage.target.common.TargetCardInGraveyard; import mage.target.targetpointer.FixedTarget; -import java.util.ArrayList; -import java.util.Collections; import java.util.UUID; /** @@ -130,7 +128,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 BecomesCreatureTypeTargetEffect(Duration.WhileOnBattlefield, new ArrayList<>(Collections.singletonList("Nightmare")), false); + effect = new BecomesCreatureTypeTargetEffect(Duration.WhileOnBattlefield, SubType.NIGHTMARE, false); effect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index a428eece458..ffe889978b7 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -61,7 +61,7 @@ public class CoalitionFlag extends CardImpl { this.addAbility(ability); // Enchanted creature is a Flagbearer. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect("Flagbearer", Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.FLAGBEARER, Duration.WhileOnBattlefield, AttachmentType.AURA))); // While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TargetsHaveToTargetPermanentIfAbleEffect(new FilterPermanent(SubType.FLAGBEARER, "one Flagbearer")))); diff --git a/Mage.Sets/src/mage/cards/c/CoatOfArms.java b/Mage.Sets/src/mage/cards/c/CoatOfArms.java index 57a7930a2ca..9d1834ac35d 100644 --- a/Mage.Sets/src/mage/cards/c/CoatOfArms.java +++ b/Mage.Sets/src/mage/cards/c/CoatOfArms.java @@ -37,7 +37,7 @@ import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.util.CardUtil; +import mage.util.SubTypeList; import java.util.List; import java.util.UUID; @@ -94,14 +94,14 @@ class CoatOfArmsEffect extends ContinuousEffectImpl { private int getAmount(List permanents, Permanent target, Game game) { int amount = 0; - List targetSubtype = target.getSubtype(game); - if (target.getAbilities().contains(ChangelingAbility.getInstance())) { + SubTypeList targetSubtype = target.getSubtype(game); + if (target.getAbilities().contains(ChangelingAbility.getInstance()) || target.isAllCreatureTypes()) { return permanents.size() - 1; } for (Permanent permanent : permanents) { if (!permanent.getId().equals(target.getId())) { - for (String subtype : targetSubtype) { - if (!CardUtil.isNonCreatureSubtype(subtype)) { + for (SubType subtype : targetSubtype) { + if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) { if (permanent.hasSubtype(subtype, game)) { amount++; break; diff --git a/Mage.Sets/src/mage/cards/c/Conspiracy.java b/Mage.Sets/src/mage/cards/c/Conspiracy.java index a0ae54169d7..ce960960c75 100644 --- a/Mage.Sets/src/mage/cards/c/Conspiracy.java +++ b/Mage.Sets/src/mage/cards/c/Conspiracy.java @@ -36,7 +36,6 @@ import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; @@ -44,6 +43,7 @@ import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.players.Player; +import mage.util.SubTypeList; import java.util.Iterator; import java.util.List; @@ -94,32 +94,33 @@ class ConspiracyEffect extends ContinuousEffectImpl { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); String choice = (String) game.getState().getValue(source.getSourceId().toString() + "_type"); + SubType chosenSubtype = SubType.byDescription(choice); if (controller != null && choice != null) { // Creature cards you own that aren't on the battlefield // in graveyard for (UUID cardId : controller.getGraveyard()) { Card card = game.getCard(cardId); if (card.isCreature()) { - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } // on Hand for (UUID cardId : controller.getHand()) { Card card = game.getCard(cardId); if (card.isCreature()) { - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } // in Exile for (Card card : game.getState().getExile().getAllCards(game)) { if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } // in Library (e.g. for Mystical Teachings) for (Card card : controller.getLibrary().getCards(game)) { if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } // commander in command zone @@ -127,7 +128,7 @@ class ConspiracyEffect extends ContinuousEffectImpl { if (game.getState().getZone(commanderId) == Zone.COMMAND) { Card card = game.getCard(commanderId); if (card.isCreature()) { - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } } @@ -138,21 +139,21 @@ class ConspiracyEffect extends ContinuousEffectImpl { stackObject.getControllerId().equals(source.getControllerId()) && stackObject.isCreature()) { Card card = ((Spell) stackObject).getCard(); - setCreatureSubtype(card, choice, game); + setCreatureSubtype(card, chosenSubtype, game); } } // creatures you control List creatures = game.getBattlefield().getAllActivePermanents( new FilterControlledCreaturePermanent(), source.getControllerId(), game); for (Permanent creature : creatures) { - setCreatureSubtype(creature, choice, game); + setCreatureSubtype(creature, chosenSubtype, game); } return true; } return false; } - private void setCreatureSubtype(MageObject object, String subtype, Game game) { + private void setCreatureSubtype(MageObject object, SubType subtype, Game game) { if (object != null) { if (object instanceof Card) { Card card = (Card) object; @@ -165,9 +166,9 @@ class ConspiracyEffect extends ContinuousEffectImpl { } } - private void setChosenSubtype(List subtype, String choice) { + private void setChosenSubtype(SubTypeList subtype, SubType choice) { if (subtype.size() != 1 || !subtype.contains(choice)) { - subtype.removeAll(CardRepository.instance.getCreatureTypes()); + subtype.removeAll(SubType.getCreatureTypes(false)); subtype.add(choice); } } diff --git a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java index e235f5a94bf..48dbe7b9732 100644 --- a/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java +++ b/Mage.Sets/src/mage/cards/c/CoordinatedBarrage.java @@ -31,7 +31,6 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -45,6 +44,7 @@ import mage.players.Player; import mage.target.common.TargetAttackingOrBlockingCreature; import java.util.UUID; +import java.util.stream.Collectors; /** * @@ -92,7 +92,7 @@ class CoordinatedBarrageEffect extends OneShotEffect { if (controller != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose a creature type"); - choice.setChoices(SubType.getCreatureTypes(false)); + choice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); if (controller.choose(Outcome.Damage, choice, game)) { String chosenType = choice.getChoice(); FilterControlledPermanent filter = new FilterControlledPermanent(); diff --git a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java index 82e816936ea..06fac86a6f7 100644 --- a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java +++ b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java @@ -44,6 +44,7 @@ import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -115,7 +116,7 @@ class CrucibleOfTheSpiritDragonManaCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = game.getObject(source.getSourceId()); - if (object != null && object.hasSubtype("Dragon", game)) { + if (object != null && object.hasSubtype(SubType.DRAGON, game)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CrypticGateway.java b/Mage.Sets/src/mage/cards/c/CrypticGateway.java index 7d54ab99399..49df03c3cc6 100644 --- a/Mage.Sets/src/mage/cards/c/CrypticGateway.java +++ b/Mage.Sets/src/mage/cards/c/CrypticGateway.java @@ -193,25 +193,25 @@ class CrypticGatewayEffect extends OneShotEffect { boolean commonSubType = false; boolean changeling = false; boolean changeling2 = false; - if (creature.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + if (creature.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature.isAllCreatureTypes()) { changeling = true; } - if (creature2.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature2.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + if (creature2.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature2.isAllCreatureTypes()) { changeling2 = true; } ArrayList subtypes = new ArrayList<>(); - for (String subtype : creature.getSubtype(game)) { + for (SubType subtype : creature.getSubtype(game)) { if (creature2.getSubtype(game).contains(subtype) || changeling2) { - subtypes.add(new SubtypePredicate(SubType.byDescription(subtype))); + subtypes.add(new SubtypePredicate(subtype)); commonSubType = true; } } - for (String subtype : creature2.getSubtype(game)) { + for (SubType subtype : creature2.getSubtype(game)) { if (creature.getSubtype(game).contains(subtype) || changeling) { - subtypes.add(new SubtypePredicate(SubType.byDescription(subtype))); + subtypes.add(new SubtypePredicate(subtype)); commonSubType = true; } } diff --git a/Mage.Sets/src/mage/cards/d/DeathcultRogue.java b/Mage.Sets/src/mage/cards/d/DeathcultRogue.java index 46f878ad635..1aba5ee1d0e 100644 --- a/Mage.Sets/src/mage/cards/d/DeathcultRogue.java +++ b/Mage.Sets/src/mage/cards/d/DeathcultRogue.java @@ -35,6 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -91,7 +92,7 @@ class DeathcultRogueRestrictionEffect extends RestrictionEffect { @Override public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { - if (blocker.hasSubtype("Rogue", game)) { + if (blocker.hasSubtype(SubType.ROGUE, game)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/d/DefyDeath.java b/Mage.Sets/src/mage/cards/d/DefyDeath.java index b565bbf18c0..34bef381e0b 100644 --- a/Mage.Sets/src/mage/cards/d/DefyDeath.java +++ b/Mage.Sets/src/mage/cards/d/DefyDeath.java @@ -34,6 +34,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.game.Game; @@ -87,7 +88,7 @@ class DefyDeathEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null && permanent.hasSubtype("Angel", game)) { + if (permanent != null && permanent.hasSubtype(SubType.ANGEL, game)) { permanent.addCounters(CounterType.P1P1.createInstance(2), source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/d/Deicide.java b/Mage.Sets/src/mage/cards/d/Deicide.java index 46c4c58eaee..bc56c3f2f56 100644 --- a/Mage.Sets/src/mage/cards/d/Deicide.java +++ b/Mage.Sets/src/mage/cards/d/Deicide.java @@ -34,6 +34,7 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -92,7 +93,7 @@ class DeicideExileEffect extends SearchTargetGraveyardHandLibraryForCardNameAndE // if it is a God. For each of the Gods in the Theros block, it won’t matter what your // devotion to its color(s) was. The card is a God card when not on the battlefield. Card cardInExile = game.getExile().getCard(targetEnchantment.getId(), game); - if (cardInExile != null && cardInExile.hasSubtype("God", game)) { + if (cardInExile != null && cardInExile.hasSubtype(SubType.GOD, game)) { Player enchantmentController = game.getPlayer(targetEnchantment.getControllerId()); return super.applySearchAndExile(game, source, cardInExile.getName(), enchantmentController.getId()); } diff --git a/Mage.Sets/src/mage/cards/d/DismissIntoDream.java b/Mage.Sets/src/mage/cards/d/DismissIntoDream.java index 132f5803356..5baf195d06d 100644 --- a/Mage.Sets/src/mage/cards/d/DismissIntoDream.java +++ b/Mage.Sets/src/mage/cards/d/DismissIntoDream.java @@ -101,8 +101,8 @@ class DismissIntoDreamEffect extends ContinuousEffectImpl { object.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), source.getSourceId(), game); break; case TypeChangingEffects_4: - if (!object.hasSubtype("Illusion", game)) { - object.getSubtype(game).add("Illusion"); + if (!object.hasSubtype(SubType.ILLUSION, game)) { + object.getSubtype(game).add(SubType.ILLUSION); } break; } diff --git a/Mage.Sets/src/mage/cards/d/DistantMelody.java b/Mage.Sets/src/mage/cards/d/DistantMelody.java index 4a3eab27577..a48c3f435b1 100644 --- a/Mage.Sets/src/mage/cards/d/DistantMelody.java +++ b/Mage.Sets/src/mage/cards/d/DistantMelody.java @@ -33,7 +33,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -45,6 +44,7 @@ import mage.game.Game; import mage.players.Player; import java.util.UUID; +import java.util.stream.Collectors; /** * @@ -92,7 +92,7 @@ class DistantMelodyEffect extends OneShotEffect { if (player != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/e/EatenBySpiders.java b/Mage.Sets/src/mage/cards/e/EatenBySpiders.java index 13a79c5bdf1..080c6c3d51f 100644 --- a/Mage.Sets/src/mage/cards/e/EatenBySpiders.java +++ b/Mage.Sets/src/mage/cards/e/EatenBySpiders.java @@ -34,6 +34,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.Game; @@ -99,7 +100,7 @@ class EatenBySpidersEffect extends OneShotEffect { for (UUID attachmentId : attachments) { Permanent attachment = game.getPermanent(attachmentId); - if (attachment.hasSubtype("Equipment", game)) { + if (attachment.hasSubtype(SubType.EQUIPMENT, game)) { attachment.destroy(source.getSourceId(), game, false); } } diff --git a/Mage.Sets/src/mage/cards/e/EbonPraetor.java b/Mage.Sets/src/mage/cards/e/EbonPraetor.java index ddf43a9bab0..1af96e74088 100644 --- a/Mage.Sets/src/mage/cards/e/EbonPraetor.java +++ b/Mage.Sets/src/mage/cards/e/EbonPraetor.java @@ -111,7 +111,7 @@ class EbonPraetorEffect extends OneShotEffect { if (cost instanceof SacrificeTargetCost) { Permanent sacrificedCreature = ((SacrificeTargetCost) cost).getPermanents().get(0); Permanent sourceCreature = game.getPermanent(source.getSourceId()); - if (sacrificedCreature.hasSubtype("Thrull", game) && sourceCreature != null) { + if (sacrificedCreature.hasSubtype(SubType.THRULL, game) && sourceCreature != null) { sourceCreature.addCounters(CounterType.P1P0.createInstance(), source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/e/EgoErasure.java b/Mage.Sets/src/mage/cards/e/EgoErasure.java index 65870c0fc12..6b9e2f13fe0 100644 --- a/Mage.Sets/src/mage/cards/e/EgoErasure.java +++ b/Mage.Sets/src/mage/cards/e/EgoErasure.java @@ -34,7 +34,6 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.ChangelingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -106,7 +105,7 @@ class EgoErasureLoseEffect extends ContinuousEffectImpl { for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { Permanent permanent = it.next().getPermanent(game); if (permanent != null) { - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); } else { it.remove(); } diff --git a/Mage.Sets/src/mage/cards/e/ElderCathar.java b/Mage.Sets/src/mage/cards/e/ElderCathar.java index 497a8165b70..95c21449918 100644 --- a/Mage.Sets/src/mage/cards/e/ElderCathar.java +++ b/Mage.Sets/src/mage/cards/e/ElderCathar.java @@ -35,6 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.Counter; import mage.counters.CounterType; import mage.game.Game; @@ -95,7 +96,7 @@ class ElderCatharAddCountersTargetEffect extends OneShotEffect { Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); if (permanent != null) { if (counter != null) { - if (permanent.hasSubtype("Human", game)) { + if (permanent.hasSubtype(SubType.HUMAN, game)) { permanent.addCounters(counter2.copy(), source, game); } else { permanent.addCounters(counter.copy(), source, game); diff --git a/Mage.Sets/src/mage/cards/e/EldraziTemple.java b/Mage.Sets/src/mage/cards/e/EldraziTemple.java index e004631e49e..b837220a2e4 100644 --- a/Mage.Sets/src/mage/cards/e/EldraziTemple.java +++ b/Mage.Sets/src/mage/cards/e/EldraziTemple.java @@ -39,6 +39,7 @@ import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.game.Game; import java.util.UUID; @@ -95,6 +96,6 @@ class EldraziTempleCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = game.getObject(source.getSourceId()); - return object != null && object.hasSubtype("Eldrazi", game) && object.getColor(game).isColorless(); + return object != null && object.hasSubtype(SubType.ELDRAZI, game) && object.getColor(game).isColorless(); } } diff --git a/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java b/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java index 0a15f7bf288..270051d63ce 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java +++ b/Mage.Sets/src/mage/cards/e/ElvishSoultiller.java @@ -36,9 +36,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -98,9 +97,7 @@ class ElvishSoultillerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject mageObject = game.getObject(source.getSourceId()); if (controller != null && mageObject != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + Choice typeChoice = new ChoiceCreatureType(); while (!controller.choose(outcome, typeChoice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/e/ErebossEmissary.java b/Mage.Sets/src/mage/cards/e/ErebossEmissary.java index 91627f5b1ff..cb47e1fd352 100644 --- a/Mage.Sets/src/mage/cards/e/ErebossEmissary.java +++ b/Mage.Sets/src/mage/cards/e/ErebossEmissary.java @@ -40,11 +40,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.target.common.TargetCardInHand; -import java.util.Collections; import java.util.UUID; /** @@ -66,7 +66,7 @@ public class ErebossEmissary extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( new BoostEnchantedEffect(2, 2, Duration.EndOfTurn), new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SourceHasSubtypeCondition(Collections.singletonList("Aura")), + new SourceHasSubtypeCondition(SubType.AURA), "{this} gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead"), new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard())))); diff --git a/Mage.Sets/src/mage/cards/e/EssenceFlux.java b/Mage.Sets/src/mage/cards/e/EssenceFlux.java index f3c0bef5bc1..a53f9403165 100644 --- a/Mage.Sets/src/mage/cards/e/EssenceFlux.java +++ b/Mage.Sets/src/mage/cards/e/EssenceFlux.java @@ -35,6 +35,7 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.ExileZone; @@ -124,7 +125,7 @@ class EssenceFluxEffect extends OneShotEffect { controller.moveCards(cardsToBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); for (UUID cardId : cardsToBattlefield) { Permanent permanent = game.getPermanent(cardId); - if (permanent != null && permanent.hasSubtype("Spirit", game)) { + if (permanent != null && permanent.hasSubtype(SubType.SPIRIT, game)) { Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setTargetPointer(new FixedTarget(permanent, game)); return effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/e/Excavator.java b/Mage.Sets/src/mage/cards/e/Excavator.java index 1ebe3370173..e0344e9171f 100644 --- a/Mage.Sets/src/mage/cards/e/Excavator.java +++ b/Mage.Sets/src/mage/cards/e/Excavator.java @@ -107,23 +107,23 @@ class ExcavatorEffect extends ContinuousEffectImpl implements SourceEffect { if(cost instanceof SacrificeTargetCost) { SacrificeTargetCost sacrificeCost = (SacrificeTargetCost) cost; for(Permanent permanent : sacrificeCost.getPermanents()) { - if(permanent.hasSubtype("Forest", game)) + if(permanent.hasSubtype(SubType.FOREST, game)) { abilities.add(new ForestwalkAbility()); } - if(permanent.hasSubtype("Plains", game)) + if(permanent.hasSubtype(SubType.PLAINS, game)) { abilities.add(new PlainswalkAbility()); } - if(permanent.hasSubtype("Island", game)) + if(permanent.hasSubtype(SubType.ISLAND, game)) { abilities.add(new IslandwalkAbility()); } - if(permanent.hasSubtype("Mountain", game)) + if(permanent.hasSubtype(SubType.MOUNTAIN, game)) { abilities.add(new MountainwalkAbility()); } - if(permanent.hasSubtype("Swamp", game)) + if(permanent.hasSubtype(SubType.SWAMP, game)) { abilities.add(new SwampwalkAbility()); } diff --git a/Mage.Sets/src/mage/cards/e/Extinction.java b/Mage.Sets/src/mage/cards/e/Extinction.java index 5de59569514..f052cc8ee5e 100644 --- a/Mage.Sets/src/mage/cards/e/Extinction.java +++ b/Mage.Sets/src/mage/cards/e/Extinction.java @@ -32,9 +32,8 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -85,9 +84,7 @@ class ExtinctionEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/e/EyeGouge.java b/Mage.Sets/src/mage/cards/e/EyeGouge.java index ed6746ec023..d041787a177 100644 --- a/Mage.Sets/src/mage/cards/e/EyeGouge.java +++ b/Mage.Sets/src/mage/cards/e/EyeGouge.java @@ -36,6 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -53,7 +54,7 @@ public class EyeGouge extends CardImpl { // Target creature gets -1/-1 until end of turn. If it's a Cyclops, destroy it. this.getSpellAbility().addEffect(new BoostTargetEffect(-1,-1, Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - Effect effect = new ConditionalOneShotEffect(new DestroyTargetEffect(), new TargetHasSubtypeCondition("Cyclops"), + Effect effect = new ConditionalOneShotEffect(new DestroyTargetEffect(), new TargetHasSubtypeCondition(SubType.CYCLOPS), "If it's a Cyclops, destroy it"); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java b/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java index 89cc8def475..8bb46a1d208 100644 --- a/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java +++ b/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java @@ -39,10 +39,7 @@ import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -106,7 +103,7 @@ class FalkenrathAristocratEffect extends OneShotEffect { if (cost instanceof SacrificeTargetCost) { Permanent sacrificedCreature = ((SacrificeTargetCost) cost).getPermanents().get(0); Permanent sourceCreature = game.getPermanent(source.getSourceId()); - if (sacrificedCreature.hasSubtype("Human", game) && sourceCreature != null) { + if (sacrificedCreature.hasSubtype(SubType.HUMAN, game) && sourceCreature != null) { sourceCreature.addCounters(CounterType.P1P1.createInstance(), source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/g/GideonsDefeat.java b/Mage.Sets/src/mage/cards/g/GideonsDefeat.java index 2c9cb0c89db..871e0418b37 100644 --- a/Mage.Sets/src/mage/cards/g/GideonsDefeat.java +++ b/Mage.Sets/src/mage/cards/g/GideonsDefeat.java @@ -27,7 +27,6 @@ */ package mage.cards.g; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -45,6 +44,8 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -98,7 +99,7 @@ class GideonsDefeatEffect extends OneShotEffect { if (controller != null && permanent != null) { controller.moveCards(permanent, Zone.EXILED, source, game); game.applyEffects(); - if (permanent.isPlaneswalker() && permanent.hasSubtype(SubType.GIDEON.getDescription(), game)) { + if (permanent.isPlaneswalker() && permanent.hasSubtype(SubType.GIDEON, game)) { controller.gainLife(5, game); } return true; diff --git a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java index 4f2f6335d99..53e099c7292 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java +++ b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java @@ -35,6 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -97,7 +98,7 @@ class GoblinAssassinTriggeredAbiliy extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - if ((targetId.equals(this.getSourceId())) || (permanent.hasSubtype("Goblin", game) && !targetId.equals(this.getSourceId()))) { + if ((targetId.equals(this.getSourceId())) || (permanent.hasSubtype(SubType.GOBLIN, game) && !targetId.equals(this.getSourceId()))) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GraveSifter.java b/Mage.Sets/src/mage/cards/g/GraveSifter.java index f6e17eba431..70a0880e2d1 100644 --- a/Mage.Sets/src/mage/cards/g/GraveSifter.java +++ b/Mage.Sets/src/mage/cards/g/GraveSifter.java @@ -34,9 +34,8 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -97,9 +96,8 @@ class GraveSifterEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Choice typeChoice = new ChoiceImpl(true); + Choice typeChoice = new ChoiceCreatureType(); typeChoice.setMessage("Choose creature type to return cards from your graveyard"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { diff --git a/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java b/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java index 54b7b2d09ce..5b0d8df1fe0 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java +++ b/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java @@ -38,10 +38,7 @@ import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -152,7 +149,7 @@ class GuardianOfTazeemEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent land = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Permanent targetCreature = game.getPermanent(source.getFirstTarget()); - if (land != null && targetCreature != null && land.hasSubtype("Island", game)) { + if (land != null && targetCreature != null && land.hasSubtype(SubType.ISLAND, game)) { ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("that creature"); effect.setTargetPointer(new FixedTarget(targetCreature, game)); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java b/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java index f371e06e766..d9a3b0b634b 100644 --- a/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java +++ b/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java @@ -182,7 +182,7 @@ class HaakonPlayKnightsFromGraveyardEffect extends AsThoughEffectImpl { if (affectedControllerId.equals(source.getControllerId())) { Card knightToCast = game.getCard(objectId); if (knightToCast != null - && knightToCast.hasSubtype("Knight", game) + && knightToCast.hasSubtype(SubType.KNIGHT, game) && knightToCast.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(objectId) == Zone.GRAVEYARD) { return true; diff --git a/Mage.Sets/src/mage/cards/h/HarshMercy.java b/Mage.Sets/src/mage/cards/h/HarshMercy.java index 0843bec0ff6..c12b3d76102 100644 --- a/Mage.Sets/src/mage/cards/h/HarshMercy.java +++ b/Mage.Sets/src/mage/cards/h/HarshMercy.java @@ -27,18 +27,14 @@ */ package mage.cards.h; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -49,6 +45,10 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author pcasaretto @@ -97,9 +97,7 @@ class HarshMercyEffect extends OneShotEffect { PlayerIteration: for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(Outcome.DestroyPermanent, typeChoice, game)) { if (!player.canRespond()) { continue PlayerIteration; diff --git a/Mage.Sets/src/mage/cards/h/HavenOfTheSpiritDragon.java b/Mage.Sets/src/mage/cards/h/HavenOfTheSpiritDragon.java index 6fe07964e2e..dccadc333ae 100644 --- a/Mage.Sets/src/mage/cards/h/HavenOfTheSpiritDragon.java +++ b/Mage.Sets/src/mage/cards/h/HavenOfTheSpiritDragon.java @@ -27,7 +27,6 @@ */ package mage.cards.h; -import java.util.UUID; import mage.ConditionalMana; import mage.MageObject; import mage.Mana; @@ -46,6 +45,7 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicate; @@ -53,6 +53,8 @@ import mage.filter.predicate.Predicates; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * * @author jeffwadsworth @@ -123,7 +125,7 @@ class HavenOfTheSpiritManaCondition extends CreatureCastManaCondition { public boolean apply(Game game, Ability source, UUID manaProducer, Cost costToPay) { if (super.apply(game, source)) { MageObject object = game.getObject(source.getSourceId()); - if (object.hasSubtype("Dragon", game) + if (object.hasSubtype(SubType.DRAGON, game) && object.isCreature()) { return true; } @@ -140,7 +142,7 @@ class DragonCreatureCardPredicate implements Predicate { @Override public boolean apply(Card input, Game game) { return input.isCreature() - && input.hasSubtype("Dragon", game); + && input.hasSubtype(SubType.DRAGON, game); } @Override diff --git a/Mage.Sets/src/mage/cards/h/HeavyMattock.java b/Mage.Sets/src/mage/cards/h/HeavyMattock.java index b716e9a4ceb..6ba2dd23536 100644 --- a/Mage.Sets/src/mage/cards/h/HeavyMattock.java +++ b/Mage.Sets/src/mage/cards/h/HeavyMattock.java @@ -39,6 +39,7 @@ import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -56,7 +57,7 @@ public class HeavyMattock extends CardImpl { // Equipped creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); // As long as equipped creature is a Human, it gets an additional +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 1), new EquippedHasSubtypeCondition("Human"), staticText))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 1), new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); // Equip {2} this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); } diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfWar.java b/Mage.Sets/src/mage/cards/h/HeraldOfWar.java index 7073febe9da..e293a8edc31 100644 --- a/Mage.Sets/src/mage/cards/h/HeraldOfWar.java +++ b/Mage.Sets/src/mage/cards/h/HeraldOfWar.java @@ -27,7 +27,6 @@ */ package mage.cards.h; -import mage.constants.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.SpellAbility; @@ -35,11 +34,11 @@ import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.FlashbackAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -107,7 +106,7 @@ class HeraldOfWarCostReductionEffect extends CostModificationEffectImpl { public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.hasSubtype("Angel", game) || sourceCard.hasSubtype("Human", game))) { + if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.hasSubtype(SubType.ANGEL, game) || sourceCard.hasSubtype(SubType.HUMAN, game))) { return true; } } diff --git a/Mage.Sets/src/mage/cards/h/Hivestone.java b/Mage.Sets/src/mage/cards/h/Hivestone.java index 6331f80a7c9..07db6fdd9fa 100644 --- a/Mage.Sets/src/mage/cards/h/Hivestone.java +++ b/Mage.Sets/src/mage/cards/h/Hivestone.java @@ -1,7 +1,5 @@ package mage.cards.h; -import java.util.ArrayList; -import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect; @@ -11,6 +9,9 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; +import mage.util.SubTypeList; + +import java.util.UUID; /** * Created by Alexsandr0x. @@ -27,8 +28,8 @@ public class Hivestone extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // Creatures you control are Slivers in addition to their other creature types. - ArrayList subTypes = new ArrayList<>(); - subTypes.add("Sliver"); + SubTypeList subTypes = new SubTypeList(); + subTypes.add(SubType.SLIVER); Effect effect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subTypes, filter, false); effect.setText("Creatures you control are Slivers in addition to their other creature types"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); diff --git a/Mage.Sets/src/mage/cards/h/HolyJusticiar.java b/Mage.Sets/src/mage/cards/h/HolyJusticiar.java index a30680a45d0..63149f936bb 100644 --- a/Mage.Sets/src/mage/cards/h/HolyJusticiar.java +++ b/Mage.Sets/src/mage/cards/h/HolyJusticiar.java @@ -27,21 +27,23 @@ */ package mage.cards.h; -import java.util.UUID; -import mage.constants.CardType; import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.Ability; -import mage.target.common.TargetCreaturePermanent; -import mage.abilities.common.SimpleActivatedAbility; -import mage.constants.Zone; -import mage.abilities.effects.OneShotEffect; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.game.permanent.Permanent; +import mage.constants.SubType; +import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; /** * @@ -90,7 +92,7 @@ class HolyJusticiarEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent creature = game.getPermanent(source.getFirstTarget()); if (creature != null) { - if (creature.hasSubtype("Zombie", game)) { + if (creature.hasSubtype(SubType.ZOMBIE, game)) { creature.tap(game); creature.moveToExile(source.getSourceId(), creature.getName(), source.getSourceId(), game); } else { diff --git a/Mage.Sets/src/mage/cards/j/JarKaiBattleStance.java b/Mage.Sets/src/mage/cards/j/JarKaiBattleStance.java index aa8327b3644..b5d33edfd6b 100644 --- a/Mage.Sets/src/mage/cards/j/JarKaiBattleStance.java +++ b/Mage.Sets/src/mage/cards/j/JarKaiBattleStance.java @@ -27,8 +27,6 @@ */ package mage.cards.j; -import java.util.Arrays; -import java.util.UUID; import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.SourceHasSubtypeCondition; import mage.abilities.decorator.ConditionalContinuousEffect; @@ -39,7 +37,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.target.common.TargetCreaturePermanent; +import mage.util.SubTypeList; + +import java.util.UUID; /** * @@ -53,11 +55,13 @@ public class JarKaiBattleStance extends CardImpl { // Target creature gains double strike until end of turn. this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - + SubTypeList s = new SubTypeList(); + s.add(SubType.JEDI); + s.add(SubType.SITH); // If that creature is a Jedi or Sith, it also gains trample until end of turn. this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), - new LockedInCondition(new SourceHasSubtypeCondition(Arrays.asList("Jedi", "Sith"))), + new LockedInCondition(new SourceHasSubtypeCondition(s)), "If that creature is a Jedi or Sith, it also gains trample until end of turn")); } diff --git a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java index 50239639deb..1b745d84819 100644 --- a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java +++ b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java @@ -27,7 +27,6 @@ */ package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.costs.mana.ManaCostsImpl; @@ -36,6 +35,7 @@ import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -44,6 +44,8 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.target.TargetPlayer; +import java.util.UUID; + /** * * @author maurer.it_at_gmail.com @@ -110,7 +112,7 @@ class KalastriaHighbornTriggeredAbility extends TriggeredAbilityImpl { zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getFromZone() == Zone.BATTLEFIELD && (permanent.getControllerId().equals(this.getControllerId()) && - permanent.hasSubtype("Vampire", game) || permanent.getId().equals(this.getSourceId())); + permanent.hasSubtype(SubType.VAMPIRE, game) || permanent.getId().equals(this.getSourceId())); } @Override diff --git a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java index 381cd1c82f8..60861faa60f 100644 --- a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java +++ b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java @@ -27,7 +27,6 @@ */ package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -40,9 +39,8 @@ import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -51,6 +49,8 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author emerald000 @@ -153,9 +153,7 @@ class KaronaFalseGodEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && controller != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + Choice typeChoice = new ChoiceCreatureType(); while (!controller.choose(Outcome.BoostCreature, typeChoice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/k/KinTreeInvocation.java b/Mage.Sets/src/mage/cards/k/KinTreeInvocation.java index d08c7894044..5241ac058d4 100644 --- a/Mage.Sets/src/mage/cards/k/KinTreeInvocation.java +++ b/Mage.Sets/src/mage/cards/k/KinTreeInvocation.java @@ -27,8 +27,6 @@ */ package mage.cards.k; -import java.util.ArrayList; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; @@ -41,6 +39,9 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; +import mage.util.SubTypeList; + +import java.util.UUID; /** * @@ -92,7 +93,7 @@ class KinTreeInvocationCreateTokenEffect extends OneShotEffect { } } - ArrayList list = new ArrayList<>(); + SubTypeList list = new SubTypeList(); list.add("Spirit"); list.add("Warrior"); ObjectColor objectColor = new ObjectColor(); diff --git a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java index b66fa3ae7d2..d818357555d 100644 --- a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java +++ b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java @@ -120,7 +120,7 @@ class LimDulTheNecromancerEffect extends OneShotEffect { if (controller.moveCards(card, Zone.BATTLEFIELD, source, game) && card.isCreature()) { Permanent creature = game.getPermanent(card.getId()); - ContinuousEffect effect = new AddCardSubTypeTargetEffect("Zombie", Duration.WhileOnBattlefield); + ContinuousEffect effect = new AddCardSubTypeTargetEffect(SubType.ZOMBIE, Duration.WhileOnBattlefield); effect.setTargetPointer(new FixedTarget(creature.getId())); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/l/LuminescentRain.java b/Mage.Sets/src/mage/cards/l/LuminescentRain.java index 0ce823909bf..c583ff79dd1 100644 --- a/Mage.Sets/src/mage/cards/l/LuminescentRain.java +++ b/Mage.Sets/src/mage/cards/l/LuminescentRain.java @@ -44,6 +44,7 @@ import mage.game.Game; import mage.players.Player; import java.util.UUID; +import java.util.stream.Collectors; /** * @@ -90,7 +91,7 @@ class LuminescentRainEffect extends OneShotEffect { if (player != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(p->p.toString()).collect(Collectors.toSet())); while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheMoon.java b/Mage.Sets/src/mage/cards/m/MagusOfTheMoon.java index 92460ddf872..871c17ff862 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheMoon.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheMoon.java @@ -34,7 +34,6 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.mana.RedManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; @@ -107,7 +106,7 @@ public class MagusOfTheMoon extends CardImpl { // 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(game).removeAll(CardRepository.instance.getLandTypes()); + land.getSubtype(game).removeAll(SubType.getLandTypes(false)); land.getSubtype(game).add("Mountain"); break; case AbilityAddingRemovingEffects_6: diff --git a/Mage.Sets/src/mage/cards/m/MarduWoeReaper.java b/Mage.Sets/src/mage/cards/m/MarduWoeReaper.java index f94ace5db51..676930894a3 100644 --- a/Mage.Sets/src/mage/cards/m/MarduWoeReaper.java +++ b/Mage.Sets/src/mage/cards/m/MarduWoeReaper.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -37,6 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; @@ -45,6 +45,8 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** * * @author emerald000 @@ -98,7 +100,7 @@ class MarduWoeReaperTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getPlayerId().equals(this.getControllerId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && (permanent.getId().equals(this.getSourceId()) || permanent.hasSubtype("Warrior", game))) { + if (permanent != null && (permanent.getId().equals(this.getSourceId()) || permanent.hasSubtype(SubType.WARRIOR, game))) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MasterBiomancer.java b/Mage.Sets/src/mage/cards/m/MasterBiomancer.java index 43cd8922e80..77867d8e463 100644 --- a/Mage.Sets/src/mage/cards/m/MasterBiomancer.java +++ b/Mage.Sets/src/mage/cards/m/MasterBiomancer.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -36,10 +35,7 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; @@ -48,6 +44,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author LevelX2 @@ -109,7 +107,7 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { if (power > 0) { creature.addCounters(CounterType.P1P1.createInstance(power), source, game); } - ContinuousEffect effect = new AddCardSubTypeTargetEffect("Mutant", Duration.Custom); + ContinuousEffect effect = new AddCardSubTypeTargetEffect(SubType.MUTANT, Duration.Custom); effect.setTargetPointer(new FixedTarget(creature.getId(), creature.getZoneChangeCounter(game) + 1)); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/m/MazesEnd.java b/Mage.Sets/src/mage/cards/m/MazesEnd.java index 1a50f39391e..10765e2087a 100644 --- a/Mage.Sets/src/mage/cards/m/MazesEnd.java +++ b/Mage.Sets/src/mage/cards/m/MazesEnd.java @@ -115,7 +115,7 @@ class MazesEndEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { List names = new ArrayList<>(); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { - if (permanent.hasSubtype("Gate", game)) { + if (permanent.hasSubtype(SubType.GATE, game)) { if (!names.contains(permanent.getName())) { names.add(permanent.getName()); } diff --git a/Mage.Sets/src/mage/cards/m/MistbindClique.java b/Mage.Sets/src/mage/cards/m/MistbindClique.java index 76f3901fb7d..cdbfec81a02 100644 --- a/Mage.Sets/src/mage/cards/m/MistbindClique.java +++ b/Mage.Sets/src/mage/cards/m/MistbindClique.java @@ -109,7 +109,7 @@ class MistbindCliqueAbility extends ZoneChangeTriggeredAbility { && event.getSourceId().equals(getSourceId()) && !event.getSourceId().equals(event.getTargetId())) { Permanent sacrificed = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (sacrificed != null && sacrificed.hasSubtype("Faerie", game)) { + if (sacrificed != null && sacrificed.hasSubtype(SubType.FAERIE, game)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MistformSliver.java b/Mage.Sets/src/mage/cards/m/MistformSliver.java index e94d22927a4..44d420067f4 100644 --- a/Mage.Sets/src/mage/cards/m/MistformSliver.java +++ b/Mage.Sets/src/mage/cards/m/MistformSliver.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -39,21 +38,18 @@ import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.choices.ChoiceCreatureType; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author cbt33, Plopman (Engineered Plague) */ public class MistformSliver extends CardImpl { @@ -97,16 +93,14 @@ class MistformSliverEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(Outcome.Detriment, typeChoice, game)) { if (!player.canRespond()) { return false; } } game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - ContinuousEffect effect = new AddCardSubTypeTargetEffect(typeChoice.getChoice(), Duration.EndOfTurn); + ContinuousEffect effect = new AddCardSubTypeTargetEffect(SubType.byDescription(typeChoice.getChoice()), Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/m/Mutavault.java b/Mage.Sets/src/mage/cards/m/Mutavault.java index 4b364e1057e..df6f6decb66 100644 --- a/Mage.Sets/src/mage/cards/m/Mutavault.java +++ b/Mage.Sets/src/mage/cards/m/Mutavault.java @@ -27,20 +27,20 @@ */ package mage.cards.m; -import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; -import mage.abilities.keyword.ChangelingAbility; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; import mage.game.permanent.token.Token; +import java.util.UUID; + /** * * @author jonubuu @@ -73,7 +73,7 @@ class MutavaultToken extends Token { public MutavaultToken() { super("", "2/2 creature with all creature types"); cardType.add(CardType.CREATURE); - subtype.add(ChangelingAbility.ALL_CREATURE_TYPE); + setIsAllCreatureTypes(true); power = new MageInt(2); toughness = new MageInt(2); } diff --git a/Mage.Sets/src/mage/cards/m/MyrReservoir.java b/Mage.Sets/src/mage/cards/m/MyrReservoir.java index 02cbfcec6dc..718eb2b7c41 100644 --- a/Mage.Sets/src/mage/cards/m/MyrReservoir.java +++ b/Mage.Sets/src/mage/cards/m/MyrReservoir.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.ConditionalMana; import mage.MageObject; import mage.Mana; @@ -49,6 +48,8 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * @author nantuko */ @@ -114,7 +115,7 @@ class MyrManaCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = game.getObject(source.getSourceId()); - if (object != null && object.hasSubtype("Myr", game)) { + if (object != null && object.hasSubtype(SubType.MYR, game)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/m/MyriadLandscape.java b/Mage.Sets/src/mage/cards/m/MyriadLandscape.java index e052bbc2ab1..b4a6662a5d1 100644 --- a/Mage.Sets/src/mage/cards/m/MyriadLandscape.java +++ b/Mage.Sets/src/mage/cards/m/MyriadLandscape.java @@ -27,9 +27,6 @@ */ package mage.cards.m; -import java.util.HashSet; -import java.util.Iterator; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -44,11 +41,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterBasicLandCard; import mage.game.Game; import mage.target.common.TargetCardInLibrary; +import mage.util.SubTypeList; + +import java.util.Iterator; +import java.util.UUID; /** * @@ -103,12 +105,11 @@ class TargetCardInLibrarySharingLandType extends TargetCardInLibrary { if (super.canTarget(id, cards, game)) { if (!getTargets().isEmpty()) { // check if new target shares a Land Type - HashSet landTypes = null; + SubTypeList landTypes = new SubTypeList(); for (UUID landId: getTargets()) { Card landCard = game.getCard(landId); if (landCard != null) { - if (landTypes == null) { - landTypes = new HashSet<>(); + if (landTypes.isEmpty()) { landTypes.addAll(landCard.getSubtype(game)); } else { landTypes.removeIf(next -> !landCard.getSubtype(game).contains(next)); @@ -116,9 +117,9 @@ class TargetCardInLibrarySharingLandType extends TargetCardInLibrary { } } Card card = game.getCard(id); - if (card != null && landTypes != null) { - for (Iterator iterator = landTypes.iterator(); iterator.hasNext();) { - String next = iterator.next(); + if (card != null && !landTypes.isEmpty()) { + for (Iterator iterator = landTypes.iterator(); iterator.hasNext();) { + SubType next = iterator.next(); if (card.getSubtype(game).contains(next)) { return true; } diff --git a/Mage.Sets/src/mage/cards/n/NakedSingularity.java b/Mage.Sets/src/mage/cards/n/NakedSingularity.java index b849fd3a96f..f8afd0701ee 100644 --- a/Mage.Sets/src/mage/cards/n/NakedSingularity.java +++ b/Mage.Sets/src/mage/cards/n/NakedSingularity.java @@ -38,10 +38,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.Choice; import mage.choices.ChoiceColor; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; @@ -103,19 +100,19 @@ class NakedSingularityEffect extends ReplacementEffectImpl { Choice choice = new ChoiceColor(true); choice.getChoices().clear(); choice.setMessage("Pick a color to produce"); - if (permanent.hasSubtype("Plains", game)) { + if (permanent.hasSubtype(SubType.PLAINS, game)) { choice.getChoices().add("Red"); } - if (permanent.hasSubtype("Island", game)) { + if (permanent.hasSubtype(SubType.ISLAND, game)) { choice.getChoices().add("Green"); } - if (permanent.hasSubtype("Swamp", game)) { + if (permanent.hasSubtype(SubType.SWAMP, game)) { choice.getChoices().add("White"); } - if (permanent.hasSubtype("Mountain", game)) { + if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { choice.getChoices().add("Blue"); } - if (permanent.hasSubtype("Forest", game)) { + if (permanent.hasSubtype(SubType.FOREST, game)) { choice.getChoices().add("Black"); } String chosenColor; diff --git a/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java b/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java index deeacfcf47f..bd910d5eddd 100644 --- a/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java +++ b/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; @@ -41,6 +40,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; @@ -48,6 +48,8 @@ import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.UUID; + /** * @author noxx */ @@ -97,7 +99,7 @@ class NecromancersStockpileDiscardTargetCost extends CostImpl { if (card == null) { return false; } - isZombieCard = card.hasSubtype("Zombie", game); + isZombieCard = card.hasSubtype(SubType.ZOMBIE, game); paid |= player.discard(card, null, game); } diff --git a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java index 02109ab7866..36e0c7eb5fd 100644 --- a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java +++ b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -44,11 +43,7 @@ import mage.abilities.keyword.IntimidateAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -58,6 +53,8 @@ import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author nantuko @@ -74,7 +71,7 @@ public class NimDeathmantle extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect("Zombie", Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.ZOMBIE, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); // Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it. this.addAbility(new NimDeathmantleTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/n/NuteGunray.java b/Mage.Sets/src/mage/cards/n/NuteGunray.java index fe8898854cf..b6324c203f0 100644 --- a/Mage.Sets/src/mage/cards/n/NuteGunray.java +++ b/Mage.Sets/src/mage/cards/n/NuteGunray.java @@ -66,7 +66,7 @@ public class NuteGunray extends CardImpl { public NuteGunray(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}"); addSuperType(SuperType.LEGENDARY); - this.subtype.add("Neimidian"); + this.subtype.add("Neimoidian"); this.subtype.add("Advisor"); this.power = new MageInt(2); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/o/OliviaMobilizedForWar.java b/Mage.Sets/src/mage/cards/o/OliviaMobilizedForWar.java index db3d667e093..55800cc2b5e 100644 --- a/Mage.Sets/src/mage/cards/o/OliviaMobilizedForWar.java +++ b/Mage.Sets/src/mage/cards/o/OliviaMobilizedForWar.java @@ -41,14 +41,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.counters.CounterType; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.UUID; import mage.filter.StaticFilters; +import java.util.UUID; + /** - * * @author fireshoes */ public class OliviaMobilizedForWar extends CardImpl { @@ -72,7 +69,7 @@ public class OliviaMobilizedForWar extends CardImpl { effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); effect.setText(", it gains haste until end of turn,"); doIfCostPaid.addEffect(effect); - effect = new BecomesCreatureTypeTargetEffect(Duration.WhileOnBattlefield, new ArrayList<>(Collections.singletonList("Vampire")), false); + effect = new BecomesCreatureTypeTargetEffect(Duration.WhileOnBattlefield, SubType.VAMPIRE, false); effect.setText("and it becomes a Vampire in addition to its other types"); doIfCostPaid.addEffect(effect); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, doIfCostPaid, diff --git a/Mage.Sets/src/mage/cards/o/OliviaVoldaren.java b/Mage.Sets/src/mage/cards/o/OliviaVoldaren.java index 3d5d2c4ee80..4b8160a4362 100644 --- a/Mage.Sets/src/mage/cards/o/OliviaVoldaren.java +++ b/Mage.Sets/src/mage/cards/o/OliviaVoldaren.java @@ -27,7 +27,6 @@ */ package mage.cards.o; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -52,6 +51,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author nantuko @@ -85,7 +86,7 @@ public class OliviaVoldaren extends CardImpl { // {1}{R}: Olivia Voldaren deals 1 damage to another target creature. That creature becomes a Vampire in addition to its other types. Put a +1/+1 counter on Olivia Voldaren. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}{R}")); ability.addTarget(new TargetCreaturePermanent(filter)); - Effect effect = new AddCardSubTypeTargetEffect("Vampire", Duration.WhileOnBattlefield); + Effect effect = new AddCardSubTypeTargetEffect(SubType.VAMPIRE, Duration.WhileOnBattlefield); effect.setText("That creature becomes a Vampire in addition to its other types"); ability.addEffect(effect); ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance())); diff --git a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java index 53db6dfd14c..915989e0c41 100644 --- a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java +++ b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java @@ -27,7 +27,6 @@ */ package mage.cards.o; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -38,10 +37,7 @@ import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; @@ -51,6 +47,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author fireshoes @@ -105,7 +103,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.isCreature() - && creature.hasSubtype("Rogue", game) + && creature.hasSubtype(SubType.ROGUE, game) && !event.getTargetId().equals(source.getSourceId())) { return true; } diff --git a/Mage.Sets/src/mage/cards/o/OozeGarden.java b/Mage.Sets/src/mage/cards/o/OozeGarden.java index a9c0d423485..5d13ee28f02 100644 --- a/Mage.Sets/src/mage/cards/o/OozeGarden.java +++ b/Mage.Sets/src/mage/cards/o/OozeGarden.java @@ -27,10 +27,6 @@ */ package mage.cards.o; -import java.util.ArrayList; -import java.util.UUID; - -import mage.constants.CardType; import mage.ObjectColor; import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; @@ -41,6 +37,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; @@ -50,6 +47,9 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.permanent.token.Token; import mage.target.common.TargetControlledCreaturePermanent; +import mage.util.SubTypeList; + +import java.util.UUID; /** * @@ -105,8 +105,8 @@ class OozeGardenCreateTokenEffect extends OneShotEffect { value = ((SacrificeTargetCost)cost).getPermanents().get(0).getPower().getValue(); } } - ArrayList list = new ArrayList<>(); - list.add("Ooze"); + SubTypeList list = new SubTypeList(); + list.add(SubType.OOZE); Token token = new Token("Ooze", "X/X green Ooze creature token, where X is the sacrificed creature's power", ObjectColor.GREEN, list, value, value, new AbilitiesImpl<>()) { diff --git a/Mage.Sets/src/mage/cards/o/OranRiefHydra.java b/Mage.Sets/src/mage/cards/o/OranRiefHydra.java index 05f874edcaf..8170a164d3d 100644 --- a/Mage.Sets/src/mage/cards/o/OranRiefHydra.java +++ b/Mage.Sets/src/mage/cards/o/OranRiefHydra.java @@ -27,7 +27,6 @@ */ package mage.cards.o; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -38,6 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -45,6 +45,8 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author fireshoes @@ -143,7 +145,7 @@ class OranRiefHydraEffect extends OneShotEffect { Permanent land = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (land != null && sourcePermanent != null) { - if (land.hasSubtype("Forest", game)) { + if (land.hasSubtype(SubType.FOREST, game)) { sourcePermanent.addCounters(CounterType.P1P1.createInstance(2), source, game); } else { sourcePermanent.addCounters(CounterType.P1P1.createInstance(), source, game); diff --git a/Mage.Sets/src/mage/cards/o/Outbreak.java b/Mage.Sets/src/mage/cards/o/Outbreak.java index 9dc75671b96..68dfd203da5 100644 --- a/Mage.Sets/src/mage/cards/o/Outbreak.java +++ b/Mage.Sets/src/mage/cards/o/Outbreak.java @@ -27,7 +27,6 @@ */ package mage.cards.o; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.DiscardTargetCost; @@ -36,7 +35,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -50,8 +48,10 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author fireshoes */ public class Outbreak extends CardImpl { @@ -63,7 +63,7 @@ public class Outbreak extends CardImpl { } public Outbreak(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); // You may discard a Swamp card rather than pay Outbreak's mana cost. this.addAbility(new AlternativeCostSourceAbility(new DiscardTargetCost(new TargetCardInHand(filterLand)))); @@ -99,7 +99,7 @@ class OutbreakEffect extends OneShotEffect { if (player != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(p -> p.toString()).collect(Collectors.toSet())); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/p/PacksDisdain.java b/Mage.Sets/src/mage/cards/p/PacksDisdain.java index e8cc2b1ded4..5ac5ed6e5a4 100644 --- a/Mage.Sets/src/mage/cards/p/PacksDisdain.java +++ b/Mage.Sets/src/mage/cards/p/PacksDisdain.java @@ -27,7 +27,6 @@ */ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; @@ -36,9 +35,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -50,6 +48,8 @@ import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author fenhl @@ -94,9 +94,7 @@ class PacksDisdainEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(Outcome.UnboostCreature, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java b/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java index 265ad05b7a1..9a56693e15e 100644 --- a/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java +++ b/Mage.Sets/src/mage/cards/p/PatriarchsBidding.java @@ -27,17 +27,11 @@ */ package mage.cards.p; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -51,6 +45,9 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; +import java.util.*; +import java.util.stream.Collectors; + /** * @author duncant */ @@ -99,7 +96,7 @@ class PatriarchsBiddingEffect extends OneShotEffect { Player player = game.getPlayer(playerId); Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!player.choose(Outcome.PutCreatureInPlay, typeChoice, game)) { if (!player.canRespond()) { break; diff --git a/Mage.Sets/src/mage/cards/p/PeerPressure.java b/Mage.Sets/src/mage/cards/p/PeerPressure.java index 1fb41bcef1d..d9574d1b49c 100644 --- a/Mage.Sets/src/mage/cards/p/PeerPressure.java +++ b/Mage.Sets/src/mage/cards/p/PeerPressure.java @@ -27,7 +27,6 @@ */ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.ContinuousEffect; @@ -35,7 +34,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -50,6 +48,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; +import java.util.stream.Collectors; + /** * * @author emerald000 @@ -95,7 +96,7 @@ class PeerPressureEffect extends OneShotEffect { if (controller != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose creature type"); - choice.setChoices(SubType.getCreatureTypes(false)); + choice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::getDescription).collect(Collectors.toSet())); while (!controller.choose(Outcome.GainControl, choice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/p/PrecursorGolem.java b/Mage.Sets/src/mage/cards/p/PrecursorGolem.java index d112bf59a91..a0b3a9f99ba 100644 --- a/Mage.Sets/src/mage/cards/p/PrecursorGolem.java +++ b/Mage.Sets/src/mage/cards/p/PrecursorGolem.java @@ -27,7 +27,6 @@ */ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -51,6 +50,8 @@ import mage.players.Player; import mage.target.Target; import mage.util.TargetAddress; +import java.util.UUID; + /** * @author duncant */ @@ -114,7 +115,7 @@ class PrecursorGolemCopyTriggeredAbility extends TriggeredAbilityImpl { Target targetInstance = addr.getTarget(spell); for (UUID target : targetInstance.getTargets()) { Permanent permanent = game.getPermanent(target); - if (permanent == null || !permanent.hasSubtype("Golem", game)) { + if (permanent == null || !permanent.hasSubtype(SubType.GOLEM, game)) { return false; } if (targetGolem == null) { diff --git a/Mage.Sets/src/mage/cards/p/PrimalBeyond.java b/Mage.Sets/src/mage/cards/p/PrimalBeyond.java index e4de9786556..e3f52bcc5f8 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalBeyond.java +++ b/Mage.Sets/src/mage/cards/p/PrimalBeyond.java @@ -27,7 +27,6 @@ */ package mage.cards.p; -import java.util.UUID; import mage.ConditionalMana; import mage.MageObject; import mage.Mana; @@ -49,6 +48,8 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.target.common.TargetCardInHand; +import java.util.UUID; + /** * * @author TGower @@ -110,6 +111,6 @@ class PrimalBeyondManaCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = game.getObject(source.getSourceId()); - return object != null && object.hasSubtype("Elemental", game); + return object != null && object.hasSubtype(SubType.ELEMENTAL, game); } } diff --git a/Mage.Sets/src/mage/cards/r/RaidersSpoils.java b/Mage.Sets/src/mage/cards/r/RaidersSpoils.java index 7f8c260f6e2..9e4f639c7ea 100644 --- a/Mage.Sets/src/mage/cards/r/RaidersSpoils.java +++ b/Mage.Sets/src/mage/cards/r/RaidersSpoils.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.PayLifeCost; @@ -38,12 +37,15 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** * * @author emerald000 @@ -95,7 +97,7 @@ class RaidersSpoilsTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent permanent = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && permanent != null && permanent.hasSubtype("Warrior", game) && permanent.getControllerId().equals(controllerId)) { + if (damageEvent.isCombatDamage() && permanent != null && permanent.hasSubtype(SubType.WARRIOR, game) && permanent.getControllerId().equals(controllerId)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java b/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java index d960230ab2d..e2d56fd638f 100644 --- a/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java +++ b/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java @@ -27,8 +27,6 @@ */ package mage.cards.r; -import java.util.ArrayList; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; @@ -51,6 +49,9 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.ArrayList; +import java.util.UUID; + /** * * @author jeffwadsworth @@ -111,8 +112,8 @@ class ReinsOfTheVinesteedEffect extends OneShotEffect { FilterCreaturePermanent FILTER = new FilterCreaturePermanent(); StringBuilder sb = new StringBuilder("creature that shares a creature type with the formerly attached creature: "); ArrayList> subtypes = new ArrayList<>(); - for (String subtype : lastStateCreature.getSubtype(game)) { - subtypes.add(new SubtypePredicate(SubType.byDescription(subtype))); + for (SubType subtype : lastStateCreature.getSubtype(game)) { + subtypes.add(new SubtypePredicate(subtype)); sb.append(subtype).append(", "); } FILTER.add(Predicates.or(subtypes)); diff --git a/Mage.Sets/src/mage/cards/r/RiptideChronologist.java b/Mage.Sets/src/mage/cards/r/RiptideChronologist.java index 7cdcfa71f04..6cb000f8594 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideChronologist.java +++ b/Mage.Sets/src/mage/cards/r/RiptideChronologist.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -37,7 +36,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -50,14 +48,16 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author fireshoes */ public class RiptideChronologist extends CardImpl { public RiptideChronologist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add("Human"); this.subtype.add("Wizard"); this.power = new MageInt(1); @@ -97,7 +97,7 @@ class RiptideChronologistEffect extends OneShotEffect { if (player != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java index fcc7ce9c71d..d96b823851a 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java +++ b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -35,20 +34,19 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.cards.repository.CardRepository; +import mage.cards.*; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; +import java.util.UUID; +import java.util.stream.Collectors; + /** * * @author emerald000 @@ -101,7 +99,7 @@ class RiptideShapeshifterEffect extends OneShotEffect { if (controller != null && sourceObject != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose a creature type:"); - choice.setChoices(CardRepository.instance.getCreatureTypes()); + choice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!controller.choose(Outcome.BoostCreature, choice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java b/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java index fe5e0855e26..e8e20ae965d 100644 --- a/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java +++ b/Mage.Sets/src/mage/cards/r/RoarOfTheCrowd.java @@ -27,16 +27,14 @@ */ package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -46,14 +44,15 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreatureOrPlayer; +import java.util.UUID; + /** - * * @author michael.napoleon@gmail.com */ public class RoarOfTheCrowd extends CardImpl { public RoarOfTheCrowd(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Choose a creature type. Roar of the Crowd deals damage to target creature or player equal to the number of permanents you control of the chosen type. TargetCreatureOrPlayer target = new TargetCreatureOrPlayer(); @@ -72,27 +71,26 @@ public class RoarOfTheCrowd extends CardImpl { } class RoarOfTheCrowdEffect extends OneShotEffect { - - RoarOfTheCrowdEffect() { - super(Outcome.LoseLife); - this.staticText = "Choose a creature type. {this} deals damage to target creature or player equal to the number of permanents you control of the chosen type."; - } - RoarOfTheCrowdEffect(final RoarOfTheCrowdEffect effect) { - super(effect); - } - - @Override - public RoarOfTheCrowdEffect copy() { - return new RoarOfTheCrowdEffect(this); - } - - @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + RoarOfTheCrowdEffect() { + super(Outcome.LoseLife); + this.staticText = "Choose a creature type. {this} deals damage to target creature or player equal to the number of permanents you control of the chosen type."; + } + + RoarOfTheCrowdEffect(final RoarOfTheCrowdEffect effect) { + super(effect); + } + + @Override + public RoarOfTheCrowdEffect copy() { + return new RoarOfTheCrowdEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); if (player != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(Outcome.LoseLife, typeChoice, game)) { if (!player.canRespond()) { return false; @@ -103,5 +101,5 @@ class RoarOfTheCrowdEffect extends OneShotEffect { return new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter)).apply(game, source); } return false; - } + } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SageOfFables.java b/Mage.Sets/src/mage/cards/s/SageOfFables.java index c01ac0f01ca..813ea8bece5 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfFables.java +++ b/Mage.Sets/src/mage/cards/s/SageOfFables.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -38,10 +37,7 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; @@ -49,6 +45,8 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * * @author fireshoes @@ -102,7 +100,7 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.isCreature() - && creature.hasSubtype("Wizard", game) + && creature.hasSubtype(SubType.WIZARD, game) && !event.getTargetId().equals(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/s/ScroungedScythe.java b/Mage.Sets/src/mage/cards/s/ScroungedScythe.java index 2cd192fde50..342045e0a1e 100644 --- a/Mage.Sets/src/mage/cards/s/ScroungedScythe.java +++ b/Mage.Sets/src/mage/cards/s/ScroungedScythe.java @@ -28,7 +28,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.EquippedHasSubtypeCondition; import mage.abilities.costs.mana.GenericManaCost; @@ -39,10 +38,9 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.MenaceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; + +import java.util.UUID; /** * @@ -64,7 +62,7 @@ public class ScroungedScythe extends CardImpl { // As long as equipped creature is a Human, it has menace. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.EQUIPMENT), - new EquippedHasSubtypeCondition("Human"), staticText))); + new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); // Equip {2} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); diff --git a/Mage.Sets/src/mage/cards/s/SenseiGoldenTail.java b/Mage.Sets/src/mage/cards/s/SenseiGoldenTail.java index 10e6cdeee09..aaf4ebcd07a 100644 --- a/Mage.Sets/src/mage/cards/s/SenseiGoldenTail.java +++ b/Mage.Sets/src/mage/cards/s/SenseiGoldenTail.java @@ -39,10 +39,7 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.BushidoAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SuperType; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.Counter; import mage.target.common.TargetCreaturePermanent; @@ -71,7 +68,7 @@ public class SenseiGoldenTail extends CardImpl { ability.addTarget(new TargetCreaturePermanent()); // That creature gains bushido 1 and becomes a Samurai in addition to its other creature types. Activate this ability only any time you could cast a sorcery. ability.addEffect(new GainAbilityTargetEffect(new BushidoAbility(1),Duration.Custom)); - ability.addEffect(new AddCardSubTypeTargetEffect("Samurai",Duration.Custom)); + ability.addEffect(new AddCardSubTypeTargetEffect(SubType.SAMURAI,Duration.Custom)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SharedAnimosity.java b/Mage.Sets/src/mage/cards/s/SharedAnimosity.java index 4dbe52428c7..cd1793af06a 100644 --- a/Mage.Sets/src/mage/cards/s/SharedAnimosity.java +++ b/Mage.Sets/src/mage/cards/s/SharedAnimosity.java @@ -27,10 +27,6 @@ */ package mage.cards.s; -import java.util.ArrayList; -import java.util.UUID; - -import mage.constants.*; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; @@ -39,6 +35,7 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.ChangelingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; @@ -48,6 +45,9 @@ import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.ArrayList; +import java.util.UUID; + /** * * @author Plopman @@ -100,7 +100,7 @@ class SharedAnimosityEffect extends ContinuousEffectImpl { filter.add(Predicates.not(new PermanentIdPredicate(this.targetPointer.getFirst(game, source)))); filter.add(new AttackingPredicate()); boolean allCreatureTypes = false; - if (permanent.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + if (permanent.isAllCreatureTypes()) { allCreatureTypes = true; } else { for(Ability ability : permanent.getAbilities()){ @@ -111,8 +111,8 @@ class SharedAnimosityEffect extends ContinuousEffectImpl { } if(!allCreatureTypes){ ArrayList> predicateList = new ArrayList<>(); - for(String subtype : permanent.getSubtype(game)){ - predicateList.add(new SubtypePredicate(SubType.byDescription(subtype))); + for(SubType subtype : permanent.getSubtype(game)){ + predicateList.add(new SubtypePredicate(subtype)); } filter.add(Predicates.or(predicateList)); } diff --git a/Mage.Sets/src/mage/cards/s/SharpenedPitchfork.java b/Mage.Sets/src/mage/cards/s/SharpenedPitchfork.java index 9d13737ec07..697d88c15d1 100644 --- a/Mage.Sets/src/mage/cards/s/SharpenedPitchfork.java +++ b/Mage.Sets/src/mage/cards/s/SharpenedPitchfork.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.EquippedHasSubtypeCondition; import mage.abilities.costs.mana.GenericManaCost; @@ -38,10 +37,9 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; + +import java.util.UUID; /** * @@ -62,7 +60,7 @@ public class SharpenedPitchfork extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT))); // As long as equipped creature is a Human, it gets +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 1), new EquippedHasSubtypeCondition("Human"), staticText))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 1), new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); } public SharpenedPitchfork(final SharpenedPitchfork card) { diff --git a/Mage.Sets/src/mage/cards/s/Shuriken.java b/Mage.Sets/src/mage/cards/s/Shuriken.java index 2bcba0633c0..df2fa0209bf 100644 --- a/Mage.Sets/src/mage/cards/s/Shuriken.java +++ b/Mage.Sets/src/mage/cards/s/Shuriken.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; @@ -43,18 +42,14 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author LevelX2 @@ -207,7 +202,7 @@ class ShurikenControlEffect extends OneShotEffect { if (equipment != null) { Permanent creature = game.getPermanent(source.getSourceId()); if (creature != null) { - if (!creature.hasSubtype("Ninja", game)) { + if (!creature.hasSubtype(SubType.NINJA, game)) { Permanent damagedCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (damagedCreature == null) { damagedCreature = (Permanent) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.BATTLEFIELD); diff --git a/Mage.Sets/src/mage/cards/s/SilverInlaidDagger.java b/Mage.Sets/src/mage/cards/s/SilverInlaidDagger.java index b09b7398a86..9d47261ea0f 100644 --- a/Mage.Sets/src/mage/cards/s/SilverInlaidDagger.java +++ b/Mage.Sets/src/mage/cards/s/SilverInlaidDagger.java @@ -27,9 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; - -import mage.constants.CardType; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.EquippedHasSubtypeCondition; import mage.abilities.costs.mana.GenericManaCost; @@ -38,9 +35,13 @@ import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; +import java.util.UUID; + /** * @author nantuko */ @@ -59,7 +60,7 @@ public class SilverInlaidDagger extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0))); // As long as equipped creature is a Human, it gets an additional +1/+0 - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 0), new EquippedHasSubtypeCondition("Human"), staticText))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 0), new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); } public SilverInlaidDagger(final SilverInlaidDagger card) { diff --git a/Mage.Sets/src/mage/cards/s/SirensCall.java b/Mage.Sets/src/mage/cards/s/SirensCall.java index b37c988f973..447c3168bca 100644 --- a/Mage.Sets/src/mage/cards/s/SirensCall.java +++ b/Mage.Sets/src/mage/cards/s/SirensCall.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; @@ -43,11 +42,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.watchers.common.AttackedThisTurnWatcher; +import java.util.UUID; + /** * * @author emerald000 @@ -141,7 +143,7 @@ class SirensCallDestroyEffect extends OneShotEffect { } // Walls are safe. - if (permanent.hasSubtype("Wall", game)) { + if (permanent.hasSubtype(SubType.WALL, game)) { continue; } // Creatures that attacked are safe. diff --git a/Mage.Sets/src/mage/cards/s/SlayersCleaver.java b/Mage.Sets/src/mage/cards/s/SlayersCleaver.java index a504a465669..38bc577e11e 100644 --- a/Mage.Sets/src/mage/cards/s/SlayersCleaver.java +++ b/Mage.Sets/src/mage/cards/s/SlayersCleaver.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -36,13 +35,12 @@ import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -88,7 +86,7 @@ class SlayersCleaverEffect extends RequirementEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.canBlock(source.getSourceId(), game) && permanent.hasSubtype("Eldrazi", game); + return permanent.canBlock(source.getSourceId(), game) && permanent.hasSubtype(SubType.ELDRAZI, game); } @Override diff --git a/Mage.Sets/src/mage/cards/s/SlayersPlate.java b/Mage.Sets/src/mage/cards/s/SlayersPlate.java index f69c706f173..b1fac91dcfe 100644 --- a/Mage.Sets/src/mage/cards/s/SlayersPlate.java +++ b/Mage.Sets/src/mage/cards/s/SlayersPlate.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; @@ -38,6 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -46,6 +46,8 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.SpiritWhiteToken; +import java.util.UUID; + /** * * @author fireshoes @@ -100,7 +102,7 @@ class SlayersPlateTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((ZoneChangeEvent) event).isDiesEvent()) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.getAttachments().contains(this.getSourceId()) && permanent.hasSubtype("Human", game)) { + if (permanent.getAttachments().contains(this.getSourceId()) && permanent.hasSubtype(SubType.HUMAN, game)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/Standardize.java b/Mage.Sets/src/mage/cards/s/Standardize.java index c1868e0d7a6..1652782b26a 100644 --- a/Mage.Sets/src/mage/cards/s/Standardize.java +++ b/Mage.Sets/src/mage/cards/s/Standardize.java @@ -27,8 +27,6 @@ */ package mage.cards.s; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffect; @@ -37,23 +35,24 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author EvilGeek */ public class Standardize extends CardImpl { public Standardize(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{U}"); // Choose a creature type other than Wall. Each creature becomes that type until end of turn. this.getSpellAbility().addEffect(new StandardizeEffect()); @@ -87,11 +86,9 @@ class StandardizeEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); String chosenType = ""; if (player != null && sourceObject != null) { - Choice typeChoice = new ChoiceImpl(true); + Choice typeChoice = new ChoiceCreatureType(); typeChoice.setMessage("Choose a creature type other than Wall"); - Set types = CardRepository.instance.getCreatureTypes(); - types.remove("Wall"); - typeChoice.setChoices(types); + typeChoice.getChoices().remove("Wall"); while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { if (!player.canRespond()) { return false; @@ -101,7 +98,7 @@ class StandardizeEffect extends OneShotEffect { chosenType = typeChoice.getChoice(); if (chosenType != null && !chosenType.isEmpty()) { // ADD TYPE TO TARGET - ContinuousEffect effect = new BecomesSubtypeAllEffect(Duration.EndOfTurn, chosenType); + ContinuousEffect effect = new BecomesSubtypeAllEffect(Duration.EndOfTurn, SubType.byDescription(chosenType)); game.addEffect(effect, source); return true; } diff --git a/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java b/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java index fb58d780ecb..dfaba884541 100644 --- a/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java +++ b/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -40,6 +39,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; @@ -51,6 +51,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author LevelX2 @@ -113,7 +115,7 @@ class StensiaMasqueradeTriggeredAbility extends TriggeredAbilityImpl { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent permanent = game.getPermanent(event.getSourceId()); if (damageEvent.isCombatDamage() && permanent != null - && permanent.hasSubtype("Vampire", game) && permanent.getControllerId().equals(controllerId)) { + && permanent.hasSubtype(SubType.VAMPIRE, game) && permanent.getControllerId().equals(controllerId)) { this.getEffects().clear(); AddCountersTargetEffect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setTargetPointer(new FixedTarget(permanent.getId())); diff --git a/Mage.Sets/src/mage/cards/t/TalusPaladin.java b/Mage.Sets/src/mage/cards/t/TalusPaladin.java index 80f85a9f759..d037491bb89 100644 --- a/Mage.Sets/src/mage/cards/t/TalusPaladin.java +++ b/Mage.Sets/src/mage/cards/t/TalusPaladin.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -46,6 +45,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.UUID; + /** * * @author jeffwadsworth @@ -107,7 +108,7 @@ class TalusPaladinTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent ally = game.getPermanent(event.getTargetId()); if (ally != null) { - if (ally.hasSubtype("Ally", game) + if (ally.hasSubtype(SubType.ALLY, game) && ally.getControllerId().equals(this.getControllerId())) { if (event.getTargetId().equals(this.getSourceId()) || event.getTargetId().equals(ally.getId())) { diff --git a/Mage.Sets/src/mage/cards/t/Tetravus.java b/Mage.Sets/src/mage/cards/t/Tetravus.java index 7b3bfd2b8ec..bc549384311 100644 --- a/Mage.Sets/src/mage/cards/t/Tetravus.java +++ b/Mage.Sets/src/mage/cards/t/Tetravus.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.StaticAbility; @@ -44,6 +43,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; @@ -52,6 +52,8 @@ import mage.game.Game; import mage.game.permanent.token.TetraviteToken; import mage.target.common.TargetControlledPermanent; +import java.util.UUID; + /** * * @author MarcoMarin @@ -105,7 +107,7 @@ class CantBeEnchantedAbility extends StaticAbility { public boolean canTarget(MageObject source, Game game) { if (source.isEnchantment() - && source.hasSubtype("Aura", game)) { + && source.hasSubtype(SubType.AURA, game)) { return false; } return true; diff --git a/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java b/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java index b5f7e8db226..66fa010e0a7 100644 --- a/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java +++ b/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java @@ -27,20 +27,22 @@ */ package mage.cards.t; -import java.util.Set; -import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.Set; +import java.util.UUID; + /** * * @author North @@ -90,7 +92,7 @@ class TrapfindersTrickEffect extends OneShotEffect { player.revealCards("Trapfinder's Trick", hand, game); Set cards = hand.getCards(game); for (Card card : cards) { - if (card != null && card.hasSubtype("Trap", game)) { + if (card != null && card.hasSubtype(SubType.TRAP, game)) { player.discard(card, source, game); } } diff --git a/Mage.Sets/src/mage/cards/t/TribalUnity.java b/Mage.Sets/src/mage/cards/t/TribalUnity.java index 43d2602aa09..7b7b30802a0 100644 --- a/Mage.Sets/src/mage/cards/t/TribalUnity.java +++ b/Mage.Sets/src/mage/cards/t/TribalUnity.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; @@ -36,7 +35,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -48,14 +46,16 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author anonymous */ public class TribalUnity extends CardImpl { public TribalUnity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{2}{G}"); // Creatures of the creature type of your choice get +X/+X until end of turn. this.getSpellAbility().addEffect(new TribalUnityEffect(new ManacostVariableValue())); @@ -72,7 +72,6 @@ public class TribalUnity extends CardImpl { } - class TribalUnityEffect extends OneShotEffect { protected DynamicValue amount; @@ -95,7 +94,7 @@ class TribalUnityEffect extends OneShotEffect { if (player != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/t/TrueFaithCenser.java b/Mage.Sets/src/mage/cards/t/TrueFaithCenser.java index 4b64b30697b..d530309ae51 100644 --- a/Mage.Sets/src/mage/cards/t/TrueFaithCenser.java +++ b/Mage.Sets/src/mage/cards/t/TrueFaithCenser.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.EquippedHasSubtypeCondition; @@ -40,10 +39,9 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; + +import java.util.UUID; /** * @@ -69,7 +67,7 @@ public class TrueFaithCenser extends CardImpl { // As long as equipped creature is a Human, it gets an additional +1/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostEquippedEffect(1, 0), - new EquippedHasSubtypeCondition("Human"), staticText))); + new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); // Equip {2} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); diff --git a/Mage.Sets/src/mage/cards/t/TsabosDecree.java b/Mage.Sets/src/mage/cards/t/TsabosDecree.java index 8b3db974347..78216d84e48 100644 --- a/Mage.Sets/src/mage/cards/t/TsabosDecree.java +++ b/Mage.Sets/src/mage/cards/t/TsabosDecree.java @@ -27,18 +27,14 @@ */ package mage.cards.t; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -50,6 +46,10 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * * @author fireshoes @@ -91,9 +91,7 @@ class TsabosDecreeEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/t/TuktukScrapper.java b/Mage.Sets/src/mage/cards/t/TuktukScrapper.java index b8d66149c41..6055013d833 100644 --- a/Mage.Sets/src/mage/cards/t/TuktukScrapper.java +++ b/Mage.Sets/src/mage/cards/t/TuktukScrapper.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -46,6 +45,8 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetArtifactPermanent; +import java.util.UUID; + /** * * @author jeffwadsworth @@ -103,7 +104,7 @@ class TuktukScrapperTriggeredAbility extends TriggeredAbilityImpl { if (permanent.getId().equals(this.getSourceId())) { return true; } - if (permanent.hasSubtype("Ally", game) + if (permanent.hasSubtype(SubType.ALLY, game) && permanent.getControllerId().equals(this.getControllerId())) { return true; } diff --git a/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java b/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java index 07077586bc6..0e8b929d1b2 100644 --- a/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java +++ b/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java @@ -27,7 +27,6 @@ */ package mage.cards.v; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.effects.common.DamageTargetEffect; @@ -47,6 +46,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.common.TargetCreatureOrPlayer; +import java.util.UUID; + /** * * @author Viserion @@ -107,7 +108,7 @@ class ValakutTheMoltenPinnacleTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isLand() && permanent.getControllerId().equals(this.getControllerId())) { - if (permanent.hasSubtype("Mountain", game)) { + if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/v/Venom.java b/Mage.Sets/src/mage/cards/v/Venom.java index cedb4690878..e5597521d28 100644 --- a/Mage.Sets/src/mage/cards/v/Venom.java +++ b/Mage.Sets/src/mage/cards/v/Venom.java @@ -27,8 +27,6 @@ */ package mage.cards.v; -import java.util.Objects; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; @@ -41,6 +39,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -50,6 +49,9 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; +import java.util.Objects; +import java.util.UUID; + /** * @author Backfir3 */ @@ -112,13 +114,13 @@ class VenomTriggeredAbility extends TriggeredAbilityImpl { Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); if (enchantedCreature != null) { if (blocker != null && !Objects.equals(blocker, enchantedCreature) - && !blocker.hasSubtype("Wall", game) + && !blocker.hasSubtype(SubType.WALL, game) && Objects.equals(blocked, enchantedCreature)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(blocker.getId())); return true; } if (blocker != null && Objects.equals(blocker, enchantedCreature) - && !blocked.hasSubtype("Wall", game)) { + && !blocked.hasSubtype(SubType.WALL, game)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(blocked.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/v/VillageCannibals.java b/Mage.Sets/src/mage/cards/v/VillageCannibals.java index 739986b20e2..735a0976207 100644 --- a/Mage.Sets/src/mage/cards/v/VillageCannibals.java +++ b/Mage.Sets/src/mage/cards/v/VillageCannibals.java @@ -27,13 +27,13 @@ */ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -42,6 +42,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** * * @author North @@ -94,7 +96,7 @@ class VillageCannibalsTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && permanent.isCreature() && permanent.hasSubtype("Human", game) + if (permanent != null && permanent.isCreature() && permanent.hasSubtype(SubType.HUMAN, game) && !permanent.getId().equals(this.getSourceId())) { return true; } diff --git a/Mage.Sets/src/mage/cards/v/VizierOfManyFaces.java b/Mage.Sets/src/mage/cards/v/VizierOfManyFaces.java index 5f2c8e813d2..824fe9ec24a 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfManyFaces.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfManyFaces.java @@ -27,9 +27,6 @@ */ package mage.cards.v; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.MageObjectReference; @@ -43,6 +40,7 @@ import mage.abilities.keyword.EmbalmAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; @@ -51,6 +49,10 @@ import mage.game.permanent.PermanentToken; import mage.util.functions.ApplyToPermanent; import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author LevelX2 @@ -102,8 +104,8 @@ class VizierOfManyFacesApplyToPermanent extends ApplyToPermanent { for (MageObjectReference mor : watcher.getEmbalmedThisTurnCards()) { if (mor.getSourceId().equals(originalCardId) && game.getState().getZoneChangeCounter(originalCardId) == mor.getZoneChangeCounter()) { permanent.getManaCost().clear(); - if (!permanent.hasSubtype("Zombie", game)) { - permanent.getSubtype(game).add("Zombie"); + if (!permanent.hasSubtype(SubType.ZOMBIE, game)) { + permanent.getSubtype(game).add(SubType.ZOMBIE); } permanent.getColor(game).setColor(ObjectColor.WHITE); diff --git a/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java b/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java index b91eb925cac..7155777aa08 100644 --- a/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java +++ b/Mage.Sets/src/mage/cards/v/VolrathsShapeshifter.java @@ -108,7 +108,7 @@ class VolrathsShapeshifterEffect extends ContinuousEffectImpl { } permanent.getSubtype(game).clear(); - for (String type : card.getSubtype(game)) { + for (SubType type : card.getSubtype(game)) { if (!permanent.getSubtype(game).contains(type)) { permanent.getSubtype(game).add(type); } diff --git a/Mage.Sets/src/mage/cards/w/WalkingDesecration.java b/Mage.Sets/src/mage/cards/w/WalkingDesecration.java index 37c753a675e..6ddbee0cad1 100644 --- a/Mage.Sets/src/mage/cards/w/WalkingDesecration.java +++ b/Mage.Sets/src/mage/cards/w/WalkingDesecration.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -39,15 +38,16 @@ import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.repository.CardRepository; import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.choices.ChoiceCreatureType; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** * * @author fireshoes @@ -92,9 +92,7 @@ class WalkingDesecrationEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(SubType.getCreatureTypes(false)); + Choice typeChoice = new ChoiceCreatureType(); while (!player.choose(outcome, typeChoice, game)) { if (!player.canRespond()) { return false; diff --git a/Mage.Sets/src/mage/cards/w/WarrenPilferers.java b/Mage.Sets/src/mage/cards/w/WarrenPilferers.java index f6250944edc..a88641389d0 100644 --- a/Mage.Sets/src/mage/cards/w/WarrenPilferers.java +++ b/Mage.Sets/src/mage/cards/w/WarrenPilferers.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -37,14 +36,13 @@ import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * * @author LevelX2 @@ -96,7 +94,7 @@ class WarrenPilferersReturnEffect extends OneShotEffect { Card card = game.getCard(source.getFirstTarget()); if (card != null) { card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - if (card.hasSubtype("Goblin", game)) { + if (card.hasSubtype(SubType.GOBLIN, game)) { game.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), source); } return true; diff --git a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java index 04f48c5cf57..326520264c0 100644 --- a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java +++ b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java @@ -47,7 +47,6 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; import java.util.HashSet; import java.util.Objects; @@ -141,9 +140,9 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent { // Choosing first target if (this.getTargets().isEmpty()) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) { - for (String subtype : permanent.getSubtype(game)) { - if (!CardUtil.isNonCreatureSubtype(subtype)) { - if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(SubType.byDescription(subtype), subtype), sourceControllerId, game, 2)) { + for (SubType subtype : permanent.getSubtype(game)) { + if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) { + if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), sourceControllerId, game, 2)) { possibleTargets.add(permanent.getId()); } } @@ -185,9 +184,9 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent { if (targetPermanent != null) { if (this.getTargets().isEmpty()) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, source.getControllerId(), game)) { - for (String subtype : permanent.getSubtype(game)) { - if (!CardUtil.isNonCreatureSubtype(subtype)) { - if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(SubType.byDescription(subtype), subtype), source.getControllerId(), game, 2)) { + for (SubType subtype : permanent.getSubtype(game)) { + if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) { + if (game.getBattlefield().contains(new FilterControlledCreaturePermanent(subtype, subtype.toString()), source.getControllerId(), game, 2)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WoodenStake.java b/Mage.Sets/src/mage/cards/w/WoodenStake.java index db156b80359..538a3811cab 100644 --- a/Mage.Sets/src/mage/cards/w/WoodenStake.java +++ b/Mage.Sets/src/mage/cards/w/WoodenStake.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; @@ -39,6 +38,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -46,6 +46,8 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * @author nantuko */ @@ -96,7 +98,7 @@ class WoodenStakeBlocksOrBecomesBlockedTriggeredAbility extends TriggeredAbility if (equipment != null && equipment.getAttachedTo() != null) { if (event.getSourceId().equals(equipment.getAttachedTo())) { Permanent blocks = game.getPermanent(event.getTargetId()); - if (blocks != null && blocks.hasSubtype("Vampire", game)) { + if (blocks != null && blocks.hasSubtype(SubType.VAMPIRE, game)) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); } @@ -106,7 +108,7 @@ class WoodenStakeBlocksOrBecomesBlockedTriggeredAbility extends TriggeredAbility } if (event.getTargetId().equals(equipment.getAttachedTo())) { Permanent blockedBy = game.getPermanent(event.getSourceId()); - if (blockedBy != null && blockedBy.hasSubtype("Vampire", game)) { + if (blockedBy != null && blockedBy.hasSubtype(SubType.VAMPIRE, game)) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getSourceId())); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ChangelingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ChangelingTest.java new file mode 100644 index 00000000000..9f655f8a99e --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ChangelingTest.java @@ -0,0 +1,58 @@ +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; + +public class ChangelingTest extends CardTestPlayerBase { + + // Mistform Ultimus is every creature type + private final String ultimus = "Mistform Ultimus"; + // each creature gets +1/+1 for each creature you control that shares a creatureype + private final String coatOfArms = "Coat of Arms"; + // all merfolk get +1/+1 + private final String lordOfAtlantis = "Lord of Atlantis"; + // all illusions get +1/+1 + private final String lordOfUnreal = "Lord of the Unreal"; + // mutavault becomes a token that is all creature types + private final String mutavault = "Mutavault"; + + // 2/2 changeling + private final String woodlandChangeling = "Woodland Changeling"; + + @Test + public void coatOfArmsTest(){ + addCard(Zone.BATTLEFIELD, playerA, ultimus); + addCard(Zone.BATTLEFIELD, playerA, coatOfArms); + addCard(Zone.BATTLEFIELD, playerA, lordOfAtlantis); + addCard(Zone.BATTLEFIELD, playerA, lordOfUnreal); + addCard(Zone.BATTLEFIELD, playerA, mutavault); + addCard(Zone.BATTLEFIELD, playerA, woodlandChangeling, 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: Until end of turn {this} becomes"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + /* + ultimus; +3 + atlantis +1 + unreal: +1 + coat of arms: +5 + */ + assertPowerToughness(playerA, ultimus, 10, 10); + /* + atlantis : +2 + coat of arms: + 4 + */ + assertPowerToughness(playerA, lordOfAtlantis, 6, 6); + /* + mutavault token; +3 + atlantis +1 + unreal: +1 + coat of arms: +5 + */ + assertPowerToughness(playerA, mutavault, 9, 9); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/TerastodonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/TerastodonTest.java new file mode 100644 index 00000000000..a0ec36086e7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/TerastodonTest.java @@ -0,0 +1,33 @@ +package org.mage.test.cards.single; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class TerastodonTest extends CardTestPlayerBase { + + + public final String terastodon = "Terastodon"; + public final String parallelLives = "Parallel Lives"; + + @Test + public void testAmountTokens() { + addCard(Zone.HAND, playerA, terastodon); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + addCard(Zone.BATTLEFIELD, playerA, parallelLives); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, terastodon); + + addTarget(playerA, parallelLives + "^Mountain^Swamp"); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, 3); + assertPermanentCount(playerA, "Elephant", 3); + } +} diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 8df6a730581..e715c8bfef8 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -152,20 +152,20 @@ public class VerifyCardDataTest { Collection expected = ref.subtypes; if (expected != null && expected.contains("Urza’s")) { expected = new ArrayList<>(expected); - for (ListIterator it = ((List) expected).listIterator(); it.hasNext();) { + for (ListIterator it = ((List) expected).listIterator(); it.hasNext(); ) { if (it.next().equals("Urza’s")) { it.set("Urza's"); } } } - if (!eqSet(card.getSubtype(null), expected)) { + if (!eqSet(card.getSubtype(null).stream().map(p -> p.toString()).collect(Collectors.toSet()), expected)) { fail(card, "subtypes", card.getSubtype(null) + " != " + expected); } } private void checkSupertypes(Card card, JsonCard ref) { Collection expected = ref.supertypes; - if (!eqSet(card.getSuperType().stream().map(s->s.toString()).collect(Collectors.toList()), expected)) { + if (!eqSet(card.getSuperType().stream().map(s -> s.toString()).collect(Collectors.toList()), expected)) { fail(card, "supertypes", card.getSuperType() + " != " + expected); } } diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index 0aa2be0cf05..4a5bdd20eae 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -8,13 +8,14 @@ import mage.abilities.keyword.ChangelingAbility; import mage.cards.Card; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.Game; import mage.game.events.ZoneChangeEvent; +import mage.util.SubTypeList; import java.io.Serializable; import java.util.EnumSet; -import java.util.List; import java.util.UUID; public interface MageObject extends MageItem, Serializable { @@ -31,9 +32,13 @@ public interface MageObject extends MageItem, Serializable { EnumSet getCardType(); - List getSubtype(Game game); + SubTypeList getSubtype(Game game); - boolean hasSubtype(String subtype, Game game); + boolean hasSubtype(SubType subtype, Game game); + + default boolean hasSubtype(String subtype, Game game){ + return hasSubtype(SubType.byDescription(subtype), game); + } EnumSet getSuperType(); @@ -171,13 +176,13 @@ public interface MageObject extends MageItem, Serializable { if (this.isCreature() && otherCard.isCreature()) { if (this.getAbilities().contains(ChangelingAbility.getInstance()) - || this.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE) + || this.isAllCreatureTypes() || otherCard.getAbilities().contains(ChangelingAbility.getInstance()) - || otherCard.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + || otherCard.isAllCreatureTypes()) { return true; } } - for (String subtype : this.getSubtype(game)) { + for (SubType subtype : this.getSubtype(game)) { if (otherCard.getSubtype(game).contains(subtype)) { return true; } @@ -186,6 +191,10 @@ public interface MageObject extends MageItem, Serializable { return false; } + boolean isAllCreatureTypes(); + + void setIsAllCreatureTypes(boolean value); + default void addCardTypes(EnumSet cardType){ getCardType().addAll(cardType); } diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java index ff3c659be98..461a3fccd6b 100644 --- a/Mage/src/main/java/mage/MageObjectImpl.java +++ b/Mage/src/main/java/mage/MageObjectImpl.java @@ -27,8 +27,6 @@ */ package mage; -import java.util.*; - import mage.abilities.Abilities; import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; @@ -40,11 +38,17 @@ import mage.abilities.keyword.ChangelingAbility; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SubTypeSet; import mage.constants.SuperType; import mage.game.Game; import mage.game.events.ZoneChangeEvent; -import mage.util.CardUtil; import mage.util.GameLog; +import mage.util.SubTypeList; + +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; public abstract class MageObjectImpl implements MageObject { @@ -56,7 +60,8 @@ public abstract class MageObjectImpl implements MageObject { protected ObjectColor frameColor; protected FrameStyle frameStyle; protected EnumSet cardType = EnumSet.noneOf(CardType.class); - protected List subtype = new ArrayList<>(); + protected SubTypeList subtype = new SubTypeList(); + protected boolean isAllCreatureTypes; protected EnumSet supertype = EnumSet.noneOf(SuperType.class); protected Abilities abilities; protected String text; @@ -132,7 +137,7 @@ public abstract class MageObjectImpl implements MageObject { } @Override - public List getSubtype(Game game) { + public SubTypeList getSubtype(Game game) { return subtype; } @@ -253,22 +258,22 @@ public abstract class MageObjectImpl implements MageObject { } @Override - public boolean hasSubtype(String value, Game game) { + public boolean hasSubtype(SubType value, Game game) { if (value == null) { return false; } - List subtypes = this.getSubtype(game); + SubTypeList subtypes = this.getSubtype(game); if (subtypes.contains(value)) { return true; } else { // checking for Changeling // first make sure input parameter is a creature subtype // if not, then ChangelingAbility doesn't matter - if (CardUtil.isNonCreatureSubtype(value)) { + if (value.getSubTypeSet() != SubTypeSet.CreatureType) { return false; } // as it is creature subtype, then check the existence of Changeling - return abilities.contains(ChangelingAbility.getInstance()) || subtypes.contains(ChangelingAbility.ALL_CREATURE_TYPE); + return abilities.contains(ChangelingAbility.getInstance()) || isAllCreatureTypes(); } } @@ -297,4 +302,14 @@ public abstract class MageObjectImpl implements MageObject { game.getState().setZoneChangeCounter(objectId, value); } + @Override + public boolean isAllCreatureTypes(){ + return isAllCreatureTypes; + } + + @Override + public void setIsAllCreatureTypes(boolean value){ + isAllCreatureTypes = value; + } + } diff --git a/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java index 512b881b524..7ecbabb1904 100644 --- a/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java @@ -29,6 +29,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; @@ -58,7 +59,7 @@ public class AllyEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl EntersTheBattlefieldEvent ebe = (EntersTheBattlefieldEvent) event; if (ebe.getTarget().getControllerId().equals(this.controllerId) && (event.getTargetId().equals(this.getSourceId()) - || (ebe.getTarget().hasSubtype("Ally", game) && !event.getTargetId().equals(this.getSourceId())))) { + || (ebe.getTarget().hasSubtype(SubType.ALLY, game) && !event.getTargetId().equals(this.getSourceId())))) { return true; } return false; diff --git a/Mage/src/main/java/mage/abilities/condition/common/EquippedHasSubtypeCondition.java b/Mage/src/main/java/mage/abilities/condition/common/EquippedHasSubtypeCondition.java index 3f2bf3cdc02..1f0c30b1b95 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/EquippedHasSubtypeCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/EquippedHasSubtypeCondition.java @@ -29,9 +29,11 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.SubTypeList; /** * Describes condition when equipped permanent has subType @@ -40,17 +42,19 @@ import mage.game.permanent.Permanent; */ public class EquippedHasSubtypeCondition implements Condition { - private String subType; - private String[] subTypes; // scope = Any + private SubTypeList subTypes; // scope = Any - public EquippedHasSubtypeCondition(String subType) { - this.subType = subType; + public EquippedHasSubtypeCondition(SubTypeList subType) { + this.subTypes = subType; } - public EquippedHasSubtypeCondition(String... subTypes) { - this.subTypes = subTypes; + + public EquippedHasSubtypeCondition(SubType subType){ + subTypes = new SubTypeList(); + subTypes.add(subType); } + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); @@ -60,17 +64,13 @@ public class EquippedHasSubtypeCondition implements Condition { attachedTo = (Permanent) game.getLastKnownInformation(permanent.getAttachedTo(), Zone.BATTLEFIELD); } if (attachedTo != null) { - if (subType != null) { - if (attachedTo.hasSubtype(this.subType, game)) { + + for (SubType s : subTypes) { + if (attachedTo.hasSubtype(s, game)) { return true; } - } else { - for (String s : subTypes) { - if (attachedTo.hasSubtype(s, game)) { - return true; - } - } } + } } return false; diff --git a/Mage/src/main/java/mage/abilities/condition/common/SourceHasSubtypeCondition.java b/Mage/src/main/java/mage/abilities/condition/common/SourceHasSubtypeCondition.java index 3d246b24178..dd8b2ecd3c4 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/SourceHasSubtypeCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/SourceHasSubtypeCondition.java @@ -1,10 +1,11 @@ package mage.abilities.condition.common; -import java.util.List; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.SubTypeList; /** * @@ -12,17 +13,22 @@ import mage.game.permanent.Permanent; */ public class SourceHasSubtypeCondition implements Condition { - private final List subtypes; + private final SubTypeList subtypes; - public SourceHasSubtypeCondition(List subtypes) { + public SourceHasSubtypeCondition(SubTypeList subtypes) { this.subtypes = subtypes; } + public SourceHasSubtypeCondition(SubType subType){ + subtypes = new SubTypeList(); + subtypes.add(subType); + } + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { - for (String subtype : subtypes) { + for (SubType subtype : subtypes) { if (permanent.hasSubtype(subtype, game)) { return true; } diff --git a/Mage/src/main/java/mage/abilities/condition/common/TargetHasSubtypeCondition.java b/Mage/src/main/java/mage/abilities/condition/common/TargetHasSubtypeCondition.java index cecd3593e96..36b147b919c 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/TargetHasSubtypeCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/TargetHasSubtypeCondition.java @@ -29,6 +29,7 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -39,9 +40,9 @@ import mage.game.permanent.Permanent; public class TargetHasSubtypeCondition implements Condition { - private final String subtype; + private final SubType subtype; - public TargetHasSubtypeCondition(String subtype) { + public TargetHasSubtypeCondition(SubType subtype) { this.subtype = subtype; } diff --git a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java index 337ca43d5d9..60e5c3af96f 100644 --- a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java @@ -27,19 +27,13 @@ */ package mage.abilities.effects; -import java.util.UUID; - import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.Card; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SpellAbilityType; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -50,6 +44,8 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** * Cards with the Aura subtype don't change the zone they are in, if there is no * valid target on the battlefield. Also, when entering the battlefield and it @@ -208,12 +204,12 @@ public class AuraReplacementEffect extends ReplacementEffectImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD && (((ZoneChangeEvent) event).getFromZone() != Zone.STACK)) { Card card = game.getCard(event.getTargetId()); - if (card != null && (card.isEnchantment() && card.hasSubtype("Aura", game) + if (card != null && (card.isEnchantment() && card.hasSubtype(SubType.AURA, game) || // in case of transformable enchantments (game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()) != null && card.getSecondCardFace() != null && card.getSecondCardFace().isEnchantment() - && card.getSecondCardFace().hasSubtype("Aura", game)))) { + && card.getSecondCardFace().hasSubtype(SubType.AURA, game)))) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/AmplifyEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AmplifyEffect.java index fcdde7dafe3..2ae6968b89d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AmplifyEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AmplifyEffect.java @@ -5,8 +5,6 @@ */ package mage.abilities.effects.common; -import java.util.ArrayList; -import java.util.List; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ReplacementEffectImpl; @@ -26,6 +24,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.ArrayList; +import java.util.List; + /** * Effect for the AmplifyAbility * @@ -101,8 +102,8 @@ public class AmplifyEffect extends ReplacementEffectImpl { if (controller != null && sourceCreature != null) { FilterCreatureCard filter = new FilterCreatureCard("creatures cards to reveal"); List filterSubtypes = new ArrayList<>(); - for (String subtype : sourceCreature.getSubtype(game)) { - filterSubtypes.add(new SubtypePredicate(SubType.byDescription(subtype))); + for (SubType subtype : sourceCreature.getSubtype(game)) { + filterSubtypes.add(new SubtypePredicate(subtype)); } if (filterSubtypes.size() > 1) { filter.add(Predicates.or(filterSubtypes)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java index 52f59bc85f7..442205ca314 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ChooseCreatureTypeEffect.java @@ -30,17 +30,18 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; +import java.util.stream.Collectors; + /** - * * @author LevelX2 */ public class ChooseCreatureTypeEffect extends OneShotEffect { @@ -64,7 +65,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect { if (controller != null && mageObject != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); + typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!controller.choose(outcome, typeChoice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChooseLandTypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChooseLandTypeEffect.java index bd59c25c334..d2a687ef758 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ChooseLandTypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ChooseLandTypeEffect.java @@ -8,15 +8,17 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; +import java.util.stream.Collectors; + /** * * @author fireshoes @@ -42,7 +44,7 @@ public class ChooseLandTypeEffect extends OneShotEffect { if (controller != null && mageObject != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose land type"); - typeChoice.setChoices(CardRepository.instance.getLandTypes()); + typeChoice.setChoices(SubType.getLandTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); while (!controller.choose(outcome, typeChoice, game)) { if (!controller.canRespond()) { return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyEffect.java index d57ffbce5c7..e9477b8fa10 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyEffect.java @@ -126,7 +126,7 @@ public class CopyEffect extends ContinuousEffectImpl { permanent.addCardType(type); } permanent.getSubtype(game).clear(); - for (String type : copyFromObject.getSubtype(game)) { + for (SubType type : copyFromObject.getSubtype(game)) { permanent.getSubtype(game).add(type); } permanent.getSuperType().clear(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java index 66e162eedf1..3207be060e2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java @@ -31,7 +31,7 @@ public class CopyTokenEffect extends ContinuousEffectImpl { permanent.addCardType(type); } permanent.getSubtype(game).clear(); - for (String type: token.getSubtype(game)) { + for (SubType type: token.getSubtype(game)) { permanent.getSubtype(game).add(type); } permanent.getSuperType().clear(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java index 2ff1d23aad3..891f486d8f4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java @@ -42,6 +42,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.util.SubTypeList; import java.util.ArrayList; import java.util.Collections; @@ -113,7 +114,7 @@ public class DevourEffect extends ReplacementEffectImpl { if (controller.chooseUse(Outcome.Detriment, "Devour creatures?", source, game)) { controller.chooseTarget(Outcome.Detriment, target, source, game); if (!target.getTargets().isEmpty()) { - List> cardSubtypes = new ArrayList<>(); + List cardSubtypes = new ArrayList<>(); int devouredCreatures = target.getTargets().size(); if (!game.isSimulation()) { game.informPlayers(creature.getLogName() + " devours " + devouredCreatures + " creatures"); @@ -121,7 +122,7 @@ public class DevourEffect extends ReplacementEffectImpl { for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature != null) { - cardSubtypes.add((ArrayList) targetCreature.getSubtype(game)); + cardSubtypes.add(targetCreature.getSubtype(game)); } if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) { return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java index a32141d8c74..58eeb806a2c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java @@ -30,10 +30,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -42,9 +39,9 @@ import mage.game.permanent.Permanent; */ public class AddCardSubTypeTargetEffect extends ContinuousEffectImpl { - private final String addedSubType; + private final SubType addedSubType; - public AddCardSubTypeTargetEffect(String addedSubType, Duration duration) { + public AddCardSubTypeTargetEffect(SubType addedSubType, Duration duration) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.addedSubType = addedSubType; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java index a34d51a7345..7218444c0f4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java @@ -27,15 +27,9 @@ */ package mage.abilities.effects.common.continuous; -import java.util.ArrayList; -import java.util.Arrays; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.mana.BlackManaAbility; -import mage.abilities.mana.BlueManaAbility; -import mage.abilities.mana.GreenManaAbility; -import mage.abilities.mana.RedManaAbility; -import mage.abilities.mana.WhiteManaAbility; +import mage.abilities.mana.*; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; @@ -43,25 +37,13 @@ import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.ArrayList; +import java.util.Arrays; + public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl { protected final static ArrayList allLandTypes = new ArrayList<>(); - static { // 205.3i - allLandTypes.add("Forest"); - allLandTypes.add("Swamp"); - allLandTypes.add("Plains"); - allLandTypes.add("Mountain"); - allLandTypes.add("Island"); - allLandTypes.add("Urza's"); - allLandTypes.add("Mine"); - allLandTypes.add("Power-Plant"); - allLandTypes.add("Tower"); - allLandTypes.add("Desert"); - allLandTypes.add("Gate"); - allLandTypes.add("Lair"); - allLandTypes.add("Locus"); - } protected ArrayList landTypes = new ArrayList<>(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java index c559f5cd5cc..5d57ecdb8d2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java @@ -27,29 +27,20 @@ */ package mage.abilities.effects.common.continuous; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.mana.BlackManaAbility; -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.abilities.mana.*; import mage.choices.Choice; import mage.choices.ChoiceBasicLandType; -import mage.constants.CardType; -import mage.constants.DependencyType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.UUID; + /** * http://mtgsalvation.gamepedia.com/Land_changers * @@ -152,7 +143,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl { // So the ability removing has to be done before Layer 6 land.removeAllAbilities(source.getSourceId(), game); // 305.7 - land.getSubtype(game).removeAll(CardRepository.instance.getLandTypes()); + land.getSubtype(game).removeAll(SubType.getLandTypes(false)); land.getSubtype(game).addAll(landTypes); } else { landTypesToAdd.clear(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBlackZombieAdditionEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBlackZombieAdditionEffect.java index 212be8591b4..7fdfb4f7c0c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBlackZombieAdditionEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBlackZombieAdditionEffect.java @@ -29,10 +29,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -66,8 +63,8 @@ public class BecomesBlackZombieAdditionEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { - if (!creature.hasSubtype("Zombie", game)) { - creature.getSubtype(game).add("Zombie"); + if (!creature.hasSubtype(SubType.ZOMBIE, game)) { + creature.getSubtype(game).add(SubType.ZOMBIE); } } break; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index 538a4841fbd..bc2d2f1df82 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -1,20 +1,21 @@ package mage.abilities.effects.common.continuous; -import java.util.Set; - import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; -import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import mage.util.SubTypeList; + +import java.util.stream.Collectors; public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { @@ -53,11 +54,11 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { msg += " other than Wall"; } typeChoice.setMessage(msg); - Set types = CardRepository.instance.getCreatureTypes(); + SubTypeList types = SubType.getCreatureTypes(false); if(nonWall) { - types.remove("Wall"); + types.remove(SubType.WALL); } - typeChoice.setChoices(types); + typeChoice.setChoices(types.stream().map(SubType::toString).collect(Collectors.toSet())); while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { if (!player.canRespond()) { return false; @@ -67,7 +68,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { chosenType = typeChoice.getChoice(); if (chosenType != null && !chosenType.isEmpty()) { // ADD TYPE TO TARGET - ContinuousEffect effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, chosenType); + ContinuousEffect effect = new BecomesCreatureTypeTargetEffect(Duration.EndOfTurn, SubType.byDescription(chosenType)); effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); game.addEffect(effect, source); return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java index b7dfb71df61..6310cc71155 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedEffect.java @@ -29,7 +29,6 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -101,10 +100,10 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl { case ALL: case ALL_BUT_COLOR: case ABILITIES_SUBTYPE_AND_PT: - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); break; } - for (String t : token.getSubtype(game)) { + for (SubType t : token.getSubtype(game)) { if (!permanent.getSubtype(game).contains(t)) { permanent.getSubtype(game).add(t); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedWithActivatedAbilityOrSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedWithActivatedAbilityOrSpellEffect.java index 169ee278e37..5e2f4087535 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedWithActivatedAbilityOrSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAttachedWithActivatedAbilityOrSpellEffect.java @@ -30,7 +30,6 @@ package mage.abilities.effects.common.continuous; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.cards.repository.CardRepository; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -117,10 +116,10 @@ public class BecomesCreatureAttachedWithActivatedAbilityOrSpellEffect extends Co case ALL: case ALL_BUT_COLOR: case ABILITIES_SUBTYPE_AND_PT: - permanentAttachedTo.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanentAttachedTo.getSubtype(game).retainAll(SubType.getLandTypes(false)); break; } - for (String subType : token.getSubtype(game)) { + for (SubType subType : token.getSubtype(game)) { if (!permanentAttachedTo.getSubtype(game).contains(subType)) { permanentAttachedTo.getSubtype(game).add(subType); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java index b4a562073d8..344b38bb32a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java @@ -31,12 +31,7 @@ import mage.MageObjectReference; 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; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; @@ -116,11 +111,12 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements permanent.addCardType(t); } if (type != null && type.isEmpty() || type == null && permanent.isLand()) { - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); } if (!token.getSubtype(game).isEmpty()) { permanent.getSubtype(game).addAll(token.getSubtype(game)); } + permanent.setIsAllCreatureTypes(token.isAllCreatureTypes()); } break; case ColorChangingEffects_5: diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java index 8d12dd02895..0872acbf64b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTargetEffect.java @@ -27,22 +27,18 @@ */ 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.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; import mage.target.Target; import mage.util.CardUtil; +import java.util.UUID; + /** * @author BetaSteward_at_googlemail.com */ @@ -88,11 +84,11 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { if (loseAllAbilities) { - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); permanent.getSubtype(game).addAll(token.getSubtype(game)); } else { if (!token.getSubtype(game).isEmpty()) { - for (String subtype : token.getSubtype(game)) { + for (SubType subtype : token.getSubtype(game)) { if (!permanent.getSubtype(game).contains(subtype)) { permanent.getSubtype(game).add(subtype); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java index ed1d1e817e8..04702ba86ba 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureTypeTargetEffect.java @@ -5,17 +5,14 @@ */ package mage.abilities.effects.common.continuous; -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 mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.SubTypeList; + +import java.util.UUID; /** * @@ -23,26 +20,30 @@ import mage.game.permanent.Permanent; */ public class BecomesCreatureTypeTargetEffect extends ContinuousEffectImpl { - protected ArrayList subtypes = new ArrayList(); + protected SubTypeList subtypes = new SubTypeList(); protected boolean loseOther; // loses other creature types - public BecomesCreatureTypeTargetEffect(Duration duration, String subtype) { + public BecomesCreatureTypeTargetEffect(Duration duration, SubType subtype) { this(duration, createArrayList(subtype)); } - public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList subtypes) { + public BecomesCreatureTypeTargetEffect(Duration duration, SubType subtype, boolean loseOther) { + this(duration, createArrayList(subtype), loseOther); + } + + public BecomesCreatureTypeTargetEffect(Duration duration, SubTypeList subtypes) { this(duration, subtypes, true); } - public BecomesCreatureTypeTargetEffect(Duration duration, ArrayList subtypes, boolean loseOther) { + public BecomesCreatureTypeTargetEffect(Duration duration, SubTypeList subtypes, boolean loseOther) { super(duration, Outcome.Detriment); this.subtypes = subtypes; this.staticText = setText(); this.loseOther = loseOther; } - private static ArrayList createArrayList(String subtype) { - ArrayList subtypes = new ArrayList<>(); + private static SubTypeList createArrayList(SubType subtype) { + SubTypeList subtypes = new SubTypeList(); subtypes.add(subtype); return subtypes; } @@ -72,10 +73,10 @@ public class BecomesCreatureTypeTargetEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (loseOther) { - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); permanent.getSubtype(game).addAll(subtypes); } else { - for (String subtype : subtypes) { + for (SubType subtype : subtypes) { if (!permanent.getSubtype(game).contains(subtype)) { permanent.getSubtype(game).add(subtype); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java index 56d365283fc..0758cd85194 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesSubtypeAllEffect.java @@ -5,38 +5,33 @@ */ package mage.abilities.effects.common.continuous; -import java.util.ArrayList; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.cards.repository.CardRepository; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.SubTypeList; /** - * * @author LevelX2 */ public class BecomesSubtypeAllEffect extends ContinuousEffectImpl { - protected ArrayList subtypes = new ArrayList(); + protected SubTypeList subtypes = new SubTypeList(); protected boolean loseOther; // loses other subtypes protected FilterCreaturePermanent filter; - public BecomesSubtypeAllEffect(Duration duration, String subtype) { + public BecomesSubtypeAllEffect(Duration duration, SubType subtype) { this(duration, createArrayList(subtype)); } - public BecomesSubtypeAllEffect(Duration duration, ArrayList subtypes) { + public BecomesSubtypeAllEffect(Duration duration, SubTypeList subtypes) { this(duration, subtypes, new FilterCreaturePermanent("All creatures"), true); } public BecomesSubtypeAllEffect(Duration duration, - ArrayList subtypes, FilterCreaturePermanent filter, boolean loseOther) { + SubTypeList subtypes, FilterCreaturePermanent filter, boolean loseOther) { super(duration, Outcome.Detriment); this.subtypes = subtypes; this.staticText = setText(); @@ -44,8 +39,8 @@ public class BecomesSubtypeAllEffect extends ContinuousEffectImpl { this.filter = filter; } - private static ArrayList createArrayList(String subtype) { - ArrayList subtypes = new ArrayList<>(); + private static SubTypeList createArrayList(SubType subtype) { + SubTypeList subtypes = new SubTypeList(); subtypes.add(subtype); return subtypes; } @@ -69,16 +64,16 @@ public class BecomesSubtypeAllEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, - Game game) { + Game game) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { if (permanent != null) { switch (layer) { case TypeChangingEffects_4: if (loseOther) { - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); permanent.getSubtype(game).addAll(subtypes); } else { - for (String subtype : subtypes) { + for (SubType subtype : subtypes) { if (!permanent.getSubtype(game).contains(subtype)) { permanent.getSubtype(game).add(subtype); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllOfChosenSubtypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllOfChosenSubtypeEffect.java index 5fd13d97e02..08223c5779d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllOfChosenSubtypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostAllOfChosenSubtypeEffect.java @@ -7,6 +7,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -17,7 +18,7 @@ import mage.game.permanent.Permanent; */ public class BoostAllOfChosenSubtypeEffect extends BoostAllEffect { - String subtype = null; + SubType subtype = null; public BoostAllOfChosenSubtypeEffect(int power, int toughness, Duration duration, boolean excludeSource) { super(power, toughness, duration, new FilterCreaturePermanent("All creatures of the chosen type"), excludeSource); @@ -47,7 +48,8 @@ public class BoostAllOfChosenSubtypeEffect extends BoostAllEffect { @Override protected void setRuntimeData(Ability source, Game game) { - subtype = (String) game.getState().getValue(source.getSourceId() + "_type"); + String s = (String) game.getState().getValue(source.getSourceId() + "_type"); + subtype = SubType.byDescription(s); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAllOfChosenSubtypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAllOfChosenSubtypeEffect.java index 9d6030bfd30..f7447035579 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAllOfChosenSubtypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAllOfChosenSubtypeEffect.java @@ -7,6 +7,7 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -17,7 +18,7 @@ import mage.game.permanent.Permanent; */ public class GainAbilityAllOfChosenSubtypeEffect extends GainAbilityAllEffect { - String subtype = null; + SubType subtype = null; public GainAbilityAllOfChosenSubtypeEffect(Ability ability, Duration duration, FilterPermanent filter) { super(ability, duration, filter); @@ -43,7 +44,8 @@ public class GainAbilityAllOfChosenSubtypeEffect extends GainAbilityAllEffect { @Override protected void setRuntimeData(Ability source, Game game) { - subtype = (String) game.getState().getValue(source.getSourceId() + "_type"); + String s = (String) game.getState().getValue(source.getSourceId() + "_type"); + subtype = SubType.byDescription(s); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java index 26181be4d3c..65538272f95 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllCreatureTypesTargetEffect.java @@ -30,11 +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; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -61,7 +57,8 @@ public class LoseAllCreatureTypesTargetEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { - return permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.setIsAllCreatureTypes(false); + return permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); } return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java index 533b2f8393c..c1170ddc95d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java @@ -30,12 +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; -import mage.constants.Outcome; -import mage.constants.SubLayer; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; @@ -85,7 +80,7 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { permanent.getCardType().remove(CardType.CREATURE); - permanent.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); if (permanent.isAttacking() || permanent.getBlocking() > 0) { permanent.removeFromCombat(game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index f9c06e4bf7e..fafe47f2667 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -27,29 +27,24 @@ */ 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.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.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.SubTypeList; + +import java.util.List; /** * @author nantuko */ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { - private List setSubtypes = new ArrayList<>(); + private SubTypeList setSubtypes = new SubTypeList(); private final AttachmentType attachmentType; - public SetCardSubtypeAttachedEffect(String setSubtype, Duration duration, AttachmentType attachmentType) { + public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; @@ -75,7 +70,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { if (equipment != null && equipment.getAttachedTo() != null) { Permanent target = game.getPermanent(equipment.getAttachedTo()); if (target != null) { - target.getSubtype(game).retainAll(CardRepository.instance.getLandTypes()); + target.getSubtype(game).retainAll(SubType.getLandTypes(false)); target.getSubtype(game).addAll(setSubtypes); } } @@ -91,7 +86,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { StringBuilder sb = new StringBuilder(); sb.append(attachmentType.verb()); sb.append(" creature is a"); - for (String subtype : this.setSubtypes) { + for (SubType subtype : this.setSubtypes) { sb.append(' ').append(subtype); } staticText = sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllOfChosenSubtypeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllOfChosenSubtypeEffect.java index 83731edbf58..8c5bef6861b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllOfChosenSubtypeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllOfChosenSubtypeEffect.java @@ -7,6 +7,7 @@ package mage.abilities.effects.common.cost; import mage.abilities.Ability; import mage.cards.Card; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.game.Game; @@ -33,7 +34,7 @@ public class SpellsCostReductionAllOfChosenSubtypeEffect extends SpellsCostReduc protected boolean selectedByRuntimeData(Card card, Ability source, Game game) { String subtype = (String) game.getState().getValue(source.getSourceId() + "_type"); if (subtype != null) { - return card.hasSubtype(subtype, game); + return card.hasSubtype(SubType.byDescription(subtype), game); } return false; } diff --git a/Mage/src/main/java/mage/abilities/keyword/ChangelingAbility.java b/Mage/src/main/java/mage/abilities/keyword/ChangelingAbility.java index f5fd5047c3b..009d3a2ea72 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ChangelingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ChangelingAbility.java @@ -28,11 +28,12 @@ package mage.abilities.keyword; -import java.io.ObjectStreamException; import mage.abilities.MageSingleton; import mage.abilities.StaticAbility; import mage.constants.Zone; +import java.io.ObjectStreamException; + /** * October 1, 2012 @@ -44,7 +45,6 @@ import mage.constants.Zone; * @author nantuko */ public class ChangelingAbility extends StaticAbility implements MageSingleton { - public static final String ALL_CREATURE_TYPE = "All Creature Type"; private static final ChangelingAbility instance = new ChangelingAbility(); private Object readResolve() throws ObjectStreamException { diff --git a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java index db40c8646f5..f075acca4a7 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java @@ -35,6 +35,7 @@ import mage.abilities.costs.common.ExileSourceFromGraveCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TimingRule; import mage.constants.Zone; import mage.game.Game; @@ -78,7 +79,7 @@ public class EmbalmAbility extends ActivatedAbilityImpl { StringBuilder sb = new StringBuilder("Embalm ").append(cost.getText()); sb.append(" (").append(cost.getText()); sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a white Zombie "); - for (String subtype : card.getSubtype(null)) { + for (SubType subtype : card.getSubtype(null)) { sb.append(subtype).append(" "); } sb.append(" with no mana cost. Embalm only as a sorcery.)"); diff --git a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java index c6fa5c08100..f6ae708cf97 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java @@ -27,11 +27,11 @@ */ package mage.abilities.keyword; -import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.effects.common.AttachEffect; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TimingRule; import mage.constants.Zone; import mage.game.Game; @@ -39,6 +39,8 @@ import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * @author BetaSteward_at_googlemail.com */ @@ -58,7 +60,7 @@ public class EquipAbility extends ActivatedAbilityImpl { public boolean canActivate(UUID playerId, Game game) { if (super.canActivate(playerId, game)) { Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.hasSubtype("Equipment", game)) { + if (permanent != null && permanent.hasSubtype(SubType.EQUIPMENT, game)) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java index 0fa338038b0..998b12bd507 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java @@ -35,6 +35,7 @@ import mage.abilities.costs.common.ExileSourceFromGraveCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TimingRule; import mage.constants.Zone; import mage.game.Game; @@ -83,7 +84,7 @@ public class EternalizeAbility extends ActivatedAbilityImpl { StringBuilder sb = new StringBuilder("Eternalize ").append(cost.getText()); sb.append(" (").append(cost.getText()); sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a 4/4 black Zombie "); - for (String subtype : card.getSubtype(null)) { + for (SubType subtype : card.getSubtype(null)) { sb.append(subtype).append(" "); } sb.append(" with no mana cost. Eternalize only as a sorcery.)"); diff --git a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java index fd14febbe89..86d243c6753 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java @@ -28,16 +28,17 @@ package mage.abilities.keyword; -import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.EvasionAbility; import mage.abilities.MageSingleton; import mage.abilities.effects.RestrictionEffect; +import mage.constants.AsThoughEffectType; +import mage.constants.Duration; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import java.io.ObjectStreamException; -import mage.constants.AsThoughEffectType; /** * @@ -90,7 +91,7 @@ class FlyingEffect extends RestrictionEffect implements MageSingleton { public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { return blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId()) || blocker.getAbilities().containsKey(ReachAbility.getInstance().getId()) - || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype("Dragon", game)) ; + || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype(SubType.DRAGON, game)) ; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/ProwlAbility.java b/Mage/src/main/java/mage/abilities/keyword/ProwlAbility.java index 40462bb1aab..479dadf6d52 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ProwlAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ProwlAbility.java @@ -42,6 +42,7 @@ import mage.abilities.costs.CostsImpl; import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.Card; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -123,7 +124,7 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost throw new IllegalArgumentException("Params can't be null"); } boolean canProwl = false; - for (String subtype : card.getSubtype(game)) { + for (SubType subtype : card.getSubtype(game)) { if (prowlWatcher.hasSubtypeMadeCombatDamage(ability.getControllerId(), subtype)) { canProwl = true; break; diff --git a/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java b/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java index 2d592dc32b3..e36fa4a498f 100644 --- a/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/TransformAbility.java @@ -80,7 +80,7 @@ public class TransformAbility extends SimpleStaticAbility { permanent.addCardType(type); } permanent.getSubtype(game).clear(); - for (String type : sourceCard.getSubtype(game)) { + for (SubType type : sourceCard.getSubtype(game)) { permanent.getSubtype(game).add(type); } permanent.getSuperType().clear(); diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index 9f18f5371d6..b7914738780 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -27,11 +27,6 @@ */ package mage.cards; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.MageObjectImpl; import mage.Mana; @@ -49,9 +44,16 @@ import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.util.GameLog; +import mage.util.SubTypeList; import mage.watchers.Watcher; import org.apache.log4j.Logger; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + public abstract class CardImpl extends MageObjectImpl implements Card { private static final long serialVersionUID = 1L; @@ -74,6 +76,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { protected boolean usesVariousArt = false; protected boolean splitCard; protected boolean morphCard; + protected boolean allCreatureTypes; public CardImpl(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, String costs) { this(ownerId, setInfo, cardTypes, costs, SpellAbilityType.BASE); @@ -705,7 +708,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } @Override - public List getSubtype(Game game) { + public SubTypeList getSubtype(Game game) { if (game != null) { CardAttribute cardAttribute = game.getState().getCardAttribute(getId()); if (cardAttribute != null) { @@ -714,4 +717,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } return super.getSubtype(game); } + + public boolean isAllCreatureTypes() { + return allCreatureTypes; + } + + public void setIsAllCreatureTypes(boolean value) { + allCreatureTypes = value; + } } diff --git a/Mage/src/main/java/mage/cards/repository/CardInfo.java b/Mage/src/main/java/mage/cards/repository/CardInfo.java index 651a83424a3..87a6d5b9d8c 100644 --- a/Mage/src/main/java/mage/cards/repository/CardInfo.java +++ b/Mage/src/main/java/mage/cards/repository/CardInfo.java @@ -30,24 +30,20 @@ package mage.cards.repository; import com.j256.ormlite.field.DataType; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; -import java.util.*; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; -import mage.cards.Card; -import mage.cards.CardGraphicInfo; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.FrameStyle; +import mage.cards.*; import mage.cards.mock.MockCard; import mage.cards.mock.MockSplitCard; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.SpellAbilityType; -import mage.constants.SuperType; +import mage.constants.*; +import mage.util.SubTypeList; import org.apache.log4j.Logger; +import java.util.*; +import java.util.stream.Collectors; + /** * @author North */ @@ -156,7 +152,7 @@ public class CardInfo { this.white = card.getColor(null).isWhite(); this.setTypes(card.getCardType()); - this.setSubtypes(card.getSubtype(null)); + this.setSubtypes(card.getSubtype(null).stream().map(SubType::toString).collect(Collectors.toList())); this.setSuperTypes(card.getSuperType()); this.setManaCosts(card.getManaCost().getSymbols()); @@ -308,8 +304,15 @@ public class CardInfo { this.rules = joinList(rules); } - public final List getSubTypes() { - return parseList(subtypes); + public final SubTypeList getSubTypes() { + SubTypeList sl = new SubTypeList(); + if(subtypes.trim().isEmpty()){ + return sl; + } + for (String s : subtypes.split(SEPARATOR)) { + sl.add(s); + } + return sl; } public final void setSubtypes(List subtypes) { diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 947ef323cf6..d2fa7275ce4 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -37,15 +37,16 @@ import com.j256.ormlite.stmt.Where; import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.support.DatabaseConnection; import com.j256.ormlite.table.TableUtils; -import java.io.File; -import java.sql.SQLException; -import java.util.*; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SetType; import mage.util.RandomUtil; import org.apache.log4j.Logger; +import java.io.File; +import java.sql.SQLException; +import java.util.*; + /** * @author North */ @@ -273,68 +274,9 @@ public enum CardRepository { return names; } - public Set getCreatureTypes() { - TreeSet subtypes = new TreeSet<>(); - try { - QueryBuilder qb = cardDao.queryBuilder(); - qb.distinct().selectColumns("subtypes"); - qb.where().like("types", new SelectArg('%' + CardType.CREATURE.name() + '%')); - List results = cardDao.query(qb.prepare()); - for (CardInfo card : results) { - subtypes.addAll(card.getSubTypes()); - } - // Removing Forest because of Dryad Arbor - subtypes.remove("Forest"); - // Some creature types are not directly included in card types and are added here manually - subtypes.add("Blinkmoth"); - subtypes.add("Camarid"); - subtypes.add("Caribou"); - subtypes.add("Citizen"); - subtypes.add("Coward"); - subtypes.add("Deserter"); - subtypes.add("Germ"); - subtypes.add("Graveborn"); - subtypes.add("Orb"); - subtypes.add("Pentavite"); - subtypes.add("Pincher"); - subtypes.add("Prism"); - subtypes.add("Reflection"); - subtypes.add("Sand"); - subtypes.add("Saproling"); - subtypes.add("Scion"); - subtypes.add("Serf"); - subtypes.add("Servo"); - subtypes.add("Splinter"); - subtypes.add("Survivor"); - subtypes.add("Tetravite"); - subtypes.add("Triskelavite"); - } catch (SQLException ex) { - Logger.getLogger(CardRepository.class).error("Error getting creaturetypes from DB : " + ex); - } - return subtypes; - } - public Set getLandTypes() { - 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) { - Logger.getLogger(CardRepository.class).error("Error getting landtypes from DB : " + ex); - } - } - return landTypes; - } public CardInfo findCard(String setCode, String cardNumber) { try { diff --git a/Mage/src/main/java/mage/choices/ChoiceCreatureType.java b/Mage/src/main/java/mage/choices/ChoiceCreatureType.java new file mode 100644 index 00000000000..0947edf1b17 --- /dev/null +++ b/Mage/src/main/java/mage/choices/ChoiceCreatureType.java @@ -0,0 +1,23 @@ +package mage.choices; + +import mage.constants.SubType; + +import java.util.stream.Collectors; + +public class ChoiceCreatureType extends ChoiceImpl { + + public ChoiceCreatureType() { + super(true); + this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); + this.message = "Choose a creature type:"; + } + + public ChoiceCreatureType(final ChoiceCreatureType choice) { + super(choice); + } + + @Override + public ChoiceCreatureType copy() { + return new ChoiceCreatureType(this); + } +} diff --git a/Mage/src/main/java/mage/choices/ChoiceLandType.java b/Mage/src/main/java/mage/choices/ChoiceLandType.java index f9a3e740851..d06da999f17 100644 --- a/Mage/src/main/java/mage/choices/ChoiceLandType.java +++ b/Mage/src/main/java/mage/choices/ChoiceLandType.java @@ -28,17 +28,18 @@ package mage.choices; -import mage.cards.repository.CardRepository; +import mage.constants.SubType; + +import java.util.stream.Collectors; /** - * * @author tre3qwerty */ public class ChoiceLandType extends ChoiceImpl { public ChoiceLandType() { super(true); - this.setChoices(CardRepository.instance.getLandTypes()); + this.setChoices(SubType.getLandTypes(false).stream().map(SubType::toString).collect(Collectors.toSet())); this.message = "Choose a land type"; } diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 37e548dea35..9f8dc09547e 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -1,6 +1,8 @@ package mage.constants; +import mage.util.SubTypeList; + import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; @@ -46,14 +48,19 @@ public enum SubType { ALLY("Ally", SubTypeSet.CreatureType, false), ANGEL("Angel", SubTypeSet.CreatureType, false), ANTELOPE("Antelope", SubTypeSet.CreatureType, false), + AQUALISH("Aqualish", SubTypeSet.CreatureType, true), // Star Wars APE("Ape", SubTypeSet.CreatureType, false), + ARCONA("Arcona", SubTypeSet.CreatureType, true), ARCHER("Archer", SubTypeSet.CreatureType, false), ARCHON("Archon", SubTypeSet.CreatureType, false), ARTIFICER("Artificer", SubTypeSet.CreatureType, false), + ARTIFICIER("Artificier", SubTypeSet.CreatureType, true), ASSASSIN("Assassin", SubTypeSet.CreatureType, false), ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType, false), ATOG("Atog", SubTypeSet.CreatureType, false), + ATAT("AT-AT", SubTypeSet.CreatureType, true), AUROCHS("Aurochs", SubTypeSet.CreatureType, false), + AVATAR("Avatar", SubTypeSet.CreatureType, false), BADGER("Badger", SubTypeSet.CreatureType, false), BARBARIAN("Barbarian", SubTypeSet.CreatureType, false), @@ -64,19 +71,23 @@ public enum SubType { BEEBLE("Beeble", SubTypeSet.CreatureType, false), BERSERKER("Berserker", SubTypeSet.CreatureType, false), BIRD("Bird", SubTypeSet.CreatureType, false), + BITH("Bith", SubTypeSet.CreatureType, true), // Star Wars BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType, false), BOARD("Boar", SubTypeSet.CreatureType, false), BRINGER("Bringer", SubTypeSet.CreatureType, false), BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType, false), + CALAMARI("Calamari", SubTypeSet.CreatureType, true), // Star Wars CAMARID("Camarid", SubTypeSet.CreatureType, false), CAMEL("Camel", SubTypeSet.CreatureType, false), CARIBOU("Caribou", SubTypeSet.CreatureType, false), CARRIER("Carrier", SubTypeSet.CreatureType, false), CAT("Cat", SubTypeSet.CreatureType, false), CENTAUR("Centaur", SubTypeSet.CreatureType, false), + CEREAN("Cerean", SubTypeSet.CreatureType, true), // Star Wars CEPHALID("Cephalid", SubTypeSet.CreatureType, false), CHIMERA("Chimera", SubTypeSet.CreatureType, false), + CHISS("Chiss", SubTypeSet.CreatureType, true), CITIZEN("Citizen", SubTypeSet.CreatureType, false), CLERIC("Cleric", SubTypeSet.CreatureType, false), COCKATRICE("Cockatrice", SubTypeSet.CreatureType, false), @@ -84,8 +95,10 @@ public enum SubType { COWARD("Coward", SubTypeSet.CreatureType, false), CRAB("Crab", SubTypeSet.CreatureType, false), CROCODILE("Crocodile", SubTypeSet.CreatureType, false), + CYBORG("Cyborg", SubTypeSet.CreatureType, true), // Star Wars CYCLOPS("Cyclops", SubTypeSet.CreatureType, false), + DATHOMIRIAN("Dathomirian", SubTypeSet.CreatureType, true), // Star Wars DAUTHI("Dauthi", SubTypeSet.CreatureType, false), DEMON("Demon", SubTypeSet.CreatureType, false), DESERTER("Deserter", SubTypeSet.CreatureType, false), @@ -96,7 +109,7 @@ public enum SubType { DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType, false), DRONE("Drone", SubTypeSet.CreatureType, false), DRUID("Druid", SubTypeSet.CreatureType, false), - DROID("Droid", SubTypeSet.CreatureType, true), + DROID("Droid", SubTypeSet.CreatureType, true), // Star Wars DRYAD("Dryad", SubTypeSet.CreatureType, false), DWARF("Dwarf", SubTypeSet.CreatureType, false), @@ -108,7 +121,7 @@ public enum SubType { ELF("Elf", SubTypeSet.CreatureType, false), ELK("Elk", SubTypeSet.CreatureType, false), EYE("Eye", SubTypeSet.CreatureType, false), - EWOK("Ewok", SubTypeSet.CreatureType, true), + EWOK("Ewok", SubTypeSet.CreatureType, true), // Star Wars FAERIE("Faerie", SubTypeSet.CreatureType, false), FERRET("Ferret", SubTypeSet.CreatureType, false), @@ -118,6 +131,8 @@ public enum SubType { FROG("Frog", SubTypeSet.CreatureType, false), FUNGUS("Fungus", SubTypeSet.CreatureType, false), + GAMORREAN("Gamorrean", SubTypeSet.CreatureType, true), // Star Wars + GAND("Gand", SubTypeSet.CreatureType, true), // Star Wars GARGOYLE("Gargoyle", SubTypeSet.CreatureType, false), GERM("Germ", SubTypeSet.CreatureType, false), GIANT("Giant", SubTypeSet.CreatureType, false), @@ -130,6 +145,7 @@ public enum SubType { GRAVEBORN("Graveborn", SubTypeSet.CreatureType, false), GREMLIN("Gremlin", SubTypeSet.CreatureType, false), GRIFFIN("Griffin", SubTypeSet.CreatureType, false), + GUNGAN("Gungan", SubTypeSet.CreatureType, true), // Star Wars HAG("Hag", SubTypeSet.CreatureType, false), HARPY("Harpy", SubTypeSet.CreatureType, false), @@ -143,6 +159,7 @@ public enum SubType { HOUND("Hound", SubTypeSet.CreatureType, false), HUMAN("Human", SubTypeSet.CreatureType, false), HUNTER("Hunter", SubTypeSet.CreatureType, false), + HUTT("Hutt", SubTypeSet.CreatureType, true), // Star Wars HYDRA("Hydra", SubTypeSet.CreatureType, false), HYENA("Hyena", SubTypeSet.CreatureType, false), @@ -150,16 +167,22 @@ public enum SubType { IMP("Imp", SubTypeSet.CreatureType, false), INCARNATION("Incarnation", SubTypeSet.CreatureType, false), INSECT("Insect", SubTypeSet.CreatureType, false), + ITHORIAN("Ithorian", SubTypeSet.CreatureType, true), // Star Wars - JEDI("Jedi", SubTypeSet.CreatureType, true), + JACKAL("Jackal", SubTypeSet.CreatureType, false), + JAWA("Jawa", SubTypeSet.CreatureType, true), + JEDI("Jedi", SubTypeSet.CreatureType, true), // Star Wars JELLYFISH("Jellyfish", SubTypeSet.CreatureType, false), JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType, false), + KALEESH("Kaleesh", SubTypeSet.CreatureType, true), // Star Wars KAVU("Kavu", SubTypeSet.CreatureType, false), + KELDOR("KelDor", SubTypeSet.CreatureType, true), KIRIN("Kirin", SubTypeSet.CreatureType, false), KITHKIN("Kithkin", SubTypeSet.CreatureType, false), KNIGHT("Knight", SubTypeSet.CreatureType, false), KOBOLD("Kobold", SubTypeSet.CreatureType, false), + KOORIVAR("Koorivar", SubTypeSet.CreatureType, true), KOR("Kor", SubTypeSet.CreatureType, false), KRAKEN("Kraken", SubTypeSet.CreatureType, false), @@ -171,6 +194,8 @@ public enum SubType { LICID("Licid", SubTypeSet.CreatureType, false), LIZARD("Lizard", SubTypeSet.CreatureType, false), + +MANTELLIAN("Mantellian", SubTypeSet.CreatureType, true), // Star Wars MANTICORE("Manticore", SubTypeSet.CreatureType, false), MASTICORE("Masticore", SubTypeSet.CreatureType, false), MERCENARY("Mercenary", SubTypeSet.CreatureType, false), @@ -178,6 +203,7 @@ public enum SubType { METATHRAN("Metathran", SubTypeSet.CreatureType, false), MINION("Minion", SubTypeSet.CreatureType, false), MINOTAUR("Minotaur", SubTypeSet.CreatureType, false), + MIRIALAN("Mirialan", SubTypeSet.CreatureType, true), // Star Wars MOLE("Mole", SubTypeSet.CreatureType, false), MONGER("Monger", SubTypeSet.CreatureType, false), MONGOOSE("Mongoose", SubTypeSet.CreatureType, false), @@ -191,6 +217,8 @@ public enum SubType { NAGA("Naga", SubTypeSet.CreatureType, false), NAUTILUS("Nautilus", SubTypeSet.CreatureType, false), + NAUTOLAN("Nautolan", SubTypeSet.CreatureType, true), // Star Wars + NEIMOIDIAN("Neimoidian", SubTypeSet.CreatureType, true), // Star Wars NEPHILIM("Nephilim", SubTypeSet.CreatureType, false), NIGHTMARE("Nightmare", SubTypeSet.CreatureType, false), NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType, false), @@ -205,6 +233,7 @@ public enum SubType { ORB("Orb", SubTypeSet.CreatureType, false), ORC("Orc", SubTypeSet.CreatureType, false), ORGG("Orgg", SubTypeSet.CreatureType, false), + ORTOLAN("Ortolan", SubTypeSet.CreatureType, true), OUPHE("Ouphe", SubTypeSet.CreatureType, false), OX("Ox", SubTypeSet.CreatureType, false), OYSTER("Oyster", SubTypeSet.CreatureType, false), @@ -212,7 +241,7 @@ public enum SubType { PEGASUS("Pegasus", SubTypeSet.CreatureType, false), PENTAVITE("Pentavite", SubTypeSet.CreatureType, false), PEST("Pest", SubTypeSet.CreatureType, false), - PHELDAGRIFF("Pheldagriff", SubTypeSet.CreatureType, false), + PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType, false), PHOENIX("Phoenix", SubTypeSet.CreatureType, false), PILOT("Pilot", SubTypeSet.CreatureType, false), PINCHER("Pincher", SubTypeSet.CreatureType, false), @@ -221,6 +250,9 @@ public enum SubType { PRAETOR("Praetor", SubTypeSet.CreatureType, false), PRISM("Prism", SubTypeSet.CreatureType, false), PROCESSOR("Processor", SubTypeSet.CreatureType, false), + PUREBLOOD("Pureblood", SubTypeSet.CreatureType, true), + + QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars RABBIT("Rabbit", SubTypeSet.CreatureType, false), RAT("Rat", SubTypeSet.CreatureType, false), @@ -228,6 +260,7 @@ public enum SubType { REFLECTION("Reflection", SubTypeSet.CreatureType, false), RHINO("Rhino", SubTypeSet.CreatureType, false), RIGGER("Rigger", SubTypeSet.CreatureType, false), + RODIAN("Rodian", SubTypeSet.CreatureType, true), // Star Wars ROGUE("Rogue", SubTypeSet.CreatureType, false), @@ -269,21 +302,25 @@ public enum SubType { SQUID("Squid", SubTypeSet.CreatureType, false), SQUIRREL("Squirrel", SubTypeSet.CreatureType, false), STARFISH("Starfish", SubTypeSet.CreatureType, false), - STARSHIP("Starship", SubTypeSet.CreatureType, true), + STARSHIP("Starship", SubTypeSet.CreatureType, true), // Star Wars + SULLUSTAN("Sullustan", SubTypeSet.CreatureType, true), // Star Wars SURRAKAR("Surrakar", SubTypeSet.CreatureType, false), SURVIVOR("Survivor", SubTypeSet.CreatureType, false), TETRAVITE("Tetravite", SubTypeSet.CreatureType, false), THALAKOS("Thalakos", SubTypeSet.CreatureType, false), THOPTER("Thopter", SubTypeSet.CreatureType, false), + TRANDOSHAN("Trandoshan", SubTypeSet.CreatureType, true), // Star Wars THRULL("Thrull", SubTypeSet.CreatureType, false), TREEFOLK("Treefolk", SubTypeSet.CreatureType, false), TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType, false), TROLL("Troll", SubTypeSet.CreatureType, false), TURTLE("Turtle", SubTypeSet.CreatureType, false), - TROOPER("Trooper", SubTypeSet.CreatureType, true), + TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars + TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars + UGNAUGHT("Ugnaught",SubTypeSet.CreatureType, true), UNICORN("Unicorn", SubTypeSet.CreatureType, false), VAMPIRE("Vampire", SubTypeSet.CreatureType, false), @@ -292,6 +329,7 @@ public enum SubType { VOLVER("Volver", SubTypeSet.CreatureType, false), WALL("Wall", SubTypeSet.CreatureType, false), WARRIOR("Warrior", SubTypeSet.CreatureType, false), + WEEQUAY("Weequay", SubTypeSet.CreatureType, true), WEIRD("Weird", SubTypeSet.CreatureType, false), WEREWOLF("Werewolf", SubTypeSet.CreatureType, false), WHALE("Whale", SubTypeSet.CreatureType, false), @@ -299,22 +337,27 @@ public enum SubType { WOLF("Wolf", SubTypeSet.CreatureType, false), WOLVERINE("Wolverine", SubTypeSet.CreatureType, false), WOMBAT("Wombat", SubTypeSet.CreatureType, false), + WOOKIEE("Wookiee", SubTypeSet.CreatureType, true), // Star Wars + WORM("Worm", SubTypeSet.CreatureType, false), WRAITH("Wraith", SubTypeSet.CreatureType, false), WURM("Wurm", SubTypeSet.CreatureType, false), YETI("Yeti", SubTypeSet.CreatureType, false), + ZABRAK("Zabrak", SubTypeSet.CreatureType, true), // Star Wars ZOMBIE("Zombie", SubTypeSet.CreatureType, false), ZUBERA("Zubera", SubTypeSet.CreatureType, false), AJANI("Ajani", SubTypeSet.PlaneswalkerType, false), ARLINN("Arlinn", SubTypeSet.PlaneswalkerType, false), ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType, false), + AURRA("Aurra", SubTypeSet.PlaneswalkerType, true), // Star Wars BOLAS("Bolas", SubTypeSet.PlaneswalkerType, false), CHANDRA("Chandra", SubTypeSet.PlaneswalkerType, false), DACK("Dack", SubTypeSet.PlaneswalkerType, false), DARETTI("Daretti", SubTypeSet.PlaneswalkerType, false), DOMRI("Domri", SubTypeSet.PlaneswalkerType, false), + DOOKU("Dooku", SubTypeSet.PlaneswalkerType, true), // Star Wars DOVIN("Dovin", SubTypeSet.PlaneswalkerType, false), ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType, false), FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType, false), @@ -329,11 +372,13 @@ public enum SubType { NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType, false), NARSET("Narset", SubTypeSet.PlaneswalkerType, false), NISSA("Nissa", SubTypeSet.PlaneswalkerType, false), - NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType,false), + NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType, false), + OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars RAL("Ral", SubTypeSet.PlaneswalkerType, false), SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType, false), SAMUT("Samut", SubTypeSet.PlaneswalkerType, false), SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType, false), + SIDIOUS("Sidious", SubTypeSet.PlaneswalkerType, true), // Star Wars SORIN("Sorin", SubTypeSet.PlaneswalkerType, false), TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType, false), TEFERI("Teferi", SubTypeSet.PlaneswalkerType, false), @@ -342,7 +387,8 @@ public enum SubType { UGIN("Ugin", SubTypeSet.PlaneswalkerType, false), VENSER("Venser", SubTypeSet.PlaneswalkerType, false), VRASKA("Vraska", SubTypeSet.PlaneswalkerType, false), - XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType, false); + XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType, false), + YODA("Yoda", SubTypeSet.PlaneswalkerType, true); private final SubTypeSet subTypeSet; @@ -354,6 +400,11 @@ public enum SubType { private final boolean customSet; + @Override + public String toString() { + return description; + } + SubType(String description, SubTypeSet subTypeSet, boolean customSet) { this.description = description; this.subTypeSet = subTypeSet; @@ -373,17 +424,28 @@ public enum SubType { return subTypeSet; } - public static Set getCreatureTypes(boolean customSet) { - - return Arrays.stream(values()).filter(s -> s.customSet == customSet).filter(p -> p.getSubTypeSet() == SubTypeSet.CreatureType).map(SubType::getDescription).collect(Collectors.toSet()); + public static SubTypeList getCreatureTypes(boolean customSet) { + SubTypeList subTypes = new SubTypeList(); + for (SubType s : values()) { + if (!s.customSet) { + subTypes.add(s); + } + } + return subTypes; } public static Set getBasicLands(boolean customSet) { return Arrays.stream(values()).filter(s -> s.customSet == customSet).filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType).map(SubType::getDescription).collect(Collectors.toSet()); } - public static Set getLandTypes(boolean customSet){ - return Arrays.stream(values()).filter(s->s.customSet==customSet).filter(p->p.getSubTypeSet() == SubTypeSet.BasicLandType || p.getSubTypeSet() == SubTypeSet.NonBasicLandType).map(SubType::getDescription).collect(Collectors.toSet()); + public static SubTypeList getLandTypes(boolean customSet) { + SubTypeList landTypes = new SubTypeList(); + for (SubType s : values()) { + if (s.getSubTypeSet() == SubTypeSet.BasicLandType || s.getSubTypeSet() == SubTypeSet.NonBasicLandType) { + landTypes.add(s); + } + } + return landTypes; } } diff --git a/Mage/src/main/java/mage/designations/Designation.java b/Mage/src/main/java/mage/designations/Designation.java index 856c0f2e607..e1ba4ab45a9 100644 --- a/Mage/src/main/java/mage/designations/Designation.java +++ b/Mage/src/main/java/mage/designations/Designation.java @@ -5,8 +5,6 @@ */ package mage.designations; -import java.util.*; - import mage.MageInt; import mage.MageObject; import mage.ObjectColor; @@ -18,10 +16,17 @@ import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.util.GameLog; +import mage.util.SubTypeList; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; /** * @@ -124,12 +129,12 @@ public abstract class Designation implements MageObject { } @Override - public List getSubtype(Game game) { - return emptyList; + public SubTypeList getSubtype(Game game) { + return new SubTypeList(); } @Override - public boolean hasSubtype(String subtype, Game game) { + public boolean hasSubtype(SubType subtype, Game game) { return false; } diff --git a/Mage/src/main/java/mage/designations/Monarch.java b/Mage/src/main/java/mage/designations/Monarch.java index 8420faa392a..7563f8956b2 100644 --- a/Mage/src/main/java/mage/designations/Monarch.java +++ b/Mage/src/main/java/mage/designations/Monarch.java @@ -27,13 +27,11 @@ */ package mage.designations; -import java.util.UUID; import mage.MageObject; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.effects.common.BecomesMonarchTargetEffect; import mage.abilities.effects.common.DrawCardTargetEffect; -import mage.constants.CardType; import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; @@ -42,6 +40,8 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * * @author LevelX2 @@ -64,6 +64,15 @@ public class Monarch extends Designation { } + @Override + public boolean isAllCreatureTypes() { + return false; + } + + @Override + public void setIsAllCreatureTypes(boolean value) { + + } } // At the beginning of the monarch’s end step, that player draws a card @@ -149,4 +158,6 @@ class MonarchDealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility public String getRule() { return "Whenever a creature deals combat damage to the monarch, its controller becomes the monarch."; } + + } diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java index 3b8e30b0c95..a05900fe051 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenSubtypePredicate.java @@ -27,11 +27,13 @@ */ package mage.filter.predicate.mageobject; -import java.util.UUID; import mage.MageObject; +import mage.constants.SubType; import mage.filter.predicate.Predicate; import mage.game.Game; +import java.util.UUID; + /** * * @author LoneFox @@ -47,7 +49,7 @@ public class ChosenSubtypePredicate implements Predicate { @Override public boolean apply(MageObject input, Game game) { String subtype = (String) game.getState().getValue(cardID + "_type"); - return input.hasSubtype(subtype, game); + return input.hasSubtype(SubType.byDescription(subtype), game); } @Override diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/SubtypePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/SubtypePredicate.java index 8207a85985c..f3e83b645d4 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/SubtypePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/SubtypePredicate.java @@ -47,7 +47,7 @@ public class SubtypePredicate implements Predicate { @Override public boolean apply(MageObject input, Game game) { - return input.hasSubtype(subtype.getDescription(), game); + return input.hasSubtype(subtype, game); } @Override diff --git a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java index 0456fdfc951..c6603f41566 100644 --- a/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/other/CardTextPredicate.java @@ -28,6 +28,7 @@ package mage.filter.predicate.other; import mage.cards.Card; +import mage.constants.SubType; import mage.filter.predicate.Predicate; import mage.game.Game; @@ -66,8 +67,8 @@ public class CardTextPredicate implements Predicate { } } - for (String subType : input.getSubtype(game)) { - if (subType.equalsIgnoreCase(token)) { + for (SubType subType : input.getSubtype(game)) { + if (subType.toString().equalsIgnoreCase(token)) { found = true; break; } diff --git a/Mage/src/main/java/mage/game/CardAttribute.java b/Mage/src/main/java/mage/game/CardAttribute.java index 0289d11b1fc..5aa24b9e5fd 100644 --- a/Mage/src/main/java/mage/game/CardAttribute.java +++ b/Mage/src/main/java/mage/game/CardAttribute.java @@ -7,10 +7,9 @@ package mage.game; import mage.ObjectColor; import mage.cards.Card; +import mage.util.SubTypeList; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; /** * This class saves changed attributes of cards (e.g. in graveyard, exile or player hands or libraries). @@ -20,11 +19,11 @@ import java.util.List; public class CardAttribute implements Serializable { protected ObjectColor color; - protected List subtype; + protected SubTypeList subtype; public CardAttribute(Card card) { color = card.getColor(null).copy(); - subtype = new ArrayList<>(card.getSubtype(null)); + subtype = card.getSubtype(null); } public CardAttribute(CardAttribute cardAttribute) { @@ -40,7 +39,7 @@ public class CardAttribute implements Serializable { return color; } - public List getSubtype() { + public SubTypeList getSubtype() { return subtype; } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 9c90a1466c1..bf327ab6786 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -27,10 +27,6 @@ */ package mage.game; -import java.io.IOException; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; import mage.MageException; import mage.MageObject; import mage.abilities.*; @@ -96,6 +92,11 @@ import mage.watchers.Watchers; import mage.watchers.common.*; import org.apache.log4j.Logger; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; + public abstract class GameImpl implements Game, Serializable { private static final int ROLLBACK_TURNS_MAX = 4; @@ -1949,9 +1950,9 @@ public abstract class GameImpl implements Game, Serializable { // This is called the "planeswalker uniqueness rule." if (planeswalkers.size() > 1) { //don't bother checking if less than 2 planeswalkers in play for (Permanent planeswalker : planeswalkers) { - for (String planeswalkertype : planeswalker.getSubtype(this)) { + for (SubType planeswalkertype : planeswalker.getSubtype(this)) { FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent(); - filterPlaneswalker.add(new SubtypePredicate(SubType.byDescription(planeswalkertype))); + filterPlaneswalker.add(new SubtypePredicate(planeswalkertype)); filterPlaneswalker.add(new ControllerIdPredicate(planeswalker.getControllerId())); if (getBattlefield().contains(filterPlaneswalker, planeswalker.getControllerId(), this, 2)) { Player controller = this.getPlayer(planeswalker.getControllerId()); diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java index ae95ae00be7..6fe81c42817 100644 --- a/Mage/src/main/java/mage/game/command/Commander.java +++ b/Mage/src/main/java/mage/game/command/Commander.java @@ -39,13 +39,14 @@ import mage.abilities.costs.mana.ManaCosts; import mage.cards.Card; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.util.GameLog; +import mage.util.SubTypeList; import java.util.EnumSet; -import java.util.List; import java.util.UUID; public class Commander implements CommandObject { @@ -118,12 +119,12 @@ public class Commander implements CommandObject { } @Override - public List getSubtype(Game game) { + public SubTypeList getSubtype(Game game) { return sourceObject.getSubtype(game); } @Override - public boolean hasSubtype(String subtype, Game game) { + public boolean hasSubtype(SubType subtype, Game game) { return sourceObject.hasSubtype(subtype, game); } @@ -228,4 +229,7 @@ public class Commander implements CommandObject { sourceObject.setZoneChangeCounter(value, game); } + public boolean isAllCreatureTypes() { return false;} + + public void setIsAllCreatureTypes(boolean value){} } diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java index 599fb8efcff..b0c0e671075 100644 --- a/Mage/src/main/java/mage/game/command/Emblem.java +++ b/Mage/src/main/java/mage/game/command/Emblem.java @@ -39,10 +39,12 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.Card; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.util.GameLog; +import mage.util.SubTypeList; import java.util.ArrayList; import java.util.EnumSet; @@ -157,12 +159,12 @@ public class Emblem implements CommandObject { } @Override - public List getSubtype(Game game) { - return emptyList; + public SubTypeList getSubtype(Game game) { + return new SubTypeList(); } @Override - public boolean hasSubtype(String subtype, Game game) { + public boolean hasSubtype(SubType subtype, Game game) { return false; } @@ -266,4 +268,8 @@ public class Emblem implements CommandObject { throw new UnsupportedOperationException("Unsupported operation"); } + public boolean isAllCreatureTypes(){ return false;} + + public void setIsAllCreatureTypes(boolean value){} + } diff --git a/Mage/src/main/java/mage/game/permanent/token/TetraviteToken.java b/Mage/src/main/java/mage/game/permanent/token/TetraviteToken.java index 77cb3670c0d..4cf1dea7a50 100644 --- a/Mage/src/main/java/mage/game/permanent/token/TetraviteToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/TetraviteToken.java @@ -32,6 +32,7 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.StaticAbility; import mage.abilities.keyword.FlyingAbility; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; @@ -71,7 +72,7 @@ class CantBeEnchantedAbility extends StaticAbility { public boolean canTarget(MageObject source, Game game) { if (source.isEnchantment() - && source.hasSubtype("Aura", game)) { + && source.hasSubtype(SubType.AURA, game)) { return false; } return true; diff --git a/Mage/src/main/java/mage/game/permanent/token/Token.java b/Mage/src/main/java/mage/game/permanent/token/Token.java index c741fd4a997..55f23dacdd7 100644 --- a/Mage/src/main/java/mage/game/permanent/token/Token.java +++ b/Mage/src/main/java/mage/game/permanent/token/Token.java @@ -27,9 +27,6 @@ */ package mage.game.permanent.token; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.MageObjectImpl; import mage.ObjectColor; @@ -46,6 +43,11 @@ import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.util.RandomUtil; +import mage.util.SubTypeList; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; public class Token extends MageObjectImpl { @@ -89,7 +91,7 @@ public class Token extends MageObjectImpl { this.toughness.modifyBaseValue(toughness); } - public Token(String name, String description, ObjectColor color, List subtype, int power, int toughness, Abilities abilities) { + public Token(String name, String description, ObjectColor color, SubTypeList subtype, int power, int toughness, Abilities abilities) { this(name, description); this.cardType.add(CardType.CREATURE); this.color = color.copy(); @@ -113,6 +115,7 @@ public class Token extends MageObjectImpl { this.expansionSetCodeChecked = token.expansionSetCodeChecked; this.copySourceCard = token.copySourceCard; // will never be changed this.availableImageSetCodes = token.availableImageSetCodes; + this.isAllCreatureTypes = token.isAllCreatureTypes; } private void setTokenDescriptor() { @@ -307,4 +310,8 @@ public class Token extends MageObjectImpl { this.setExpansionSetCodeForImage(setCode); return true; } + + + + } diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index 2874708cfc4..889b6179250 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -57,6 +57,12 @@ import mage.game.permanent.Permanent; import mage.game.permanent.PermanentCard; import mage.players.Player; import mage.util.GameLog; +import mage.util.SubTypeList; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; import java.util.ArrayList; import java.util.EnumSet; @@ -472,10 +478,9 @@ public class Spell extends StackObjImpl implements Card { } @Override - public List getSubtype(Game game) { + public SubTypeList getSubtype(Game game) { if (this.getSpellAbility() instanceof BestowAbility) { - List subtypes = new ArrayList<>(); - subtypes.addAll(card.getSubtype(game)); + SubTypeList subtypes = card.getSubtype(game); subtypes.add("Aura"); return subtypes; } @@ -483,10 +488,9 @@ public class Spell extends StackObjImpl implements Card { } @Override - public boolean hasSubtype(String subtype, Game game) { + public boolean hasSubtype(SubType subtype, Game game) { if (this.getSpellAbility() instanceof BestowAbility) { // workaround for Bestow (don't like it) - List subtypes = new ArrayList<>(); - subtypes.addAll(card.getSubtype(game)); + SubTypeList subtypes = card.getSubtype(game); subtypes.add("Aura"); if (subtypes.contains(subtype)) { return true; @@ -918,4 +922,10 @@ public class Spell extends StackObjImpl implements Card { game.fireEvent(new GameEvent(EventType.COPIED_STACKOBJECT, copy.getId(), this.getId(), newControllerId)); return copy; } + + public boolean isAllCreatureTypes(){ + return false; + } + + public void setIsAllCreatureTypes(boolean value){} } diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 8c8577dbf3e..3a6158ede3b 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -27,17 +27,10 @@ */ package mage.game.stack; -import java.util.*; import mage.MageInt; import mage.MageObject; import mage.ObjectColor; -import mage.abilities.Abilities; -import mage.abilities.AbilitiesImpl; -import mage.abilities.Ability; -import mage.abilities.MageSingleton; -import mage.abilities.Mode; -import mage.abilities.Modes; -import mage.abilities.StateTriggeredAbility; +import mage.abilities.*; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.CostsImpl; @@ -56,8 +49,14 @@ import mage.players.Player; import mage.target.Target; import mage.target.Targets; import mage.util.GameLog; +import mage.util.SubTypeList; import mage.watchers.Watcher; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -157,12 +156,12 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public List getSubtype(Game game) { - return emptyString; + public SubTypeList getSubtype(Game game) { + return new SubTypeList(); } @Override - public boolean hasSubtype(String subtype, Game game) { + public boolean hasSubtype(SubType subtype, Game game) { return false; } @@ -593,4 +592,10 @@ public class StackAbility extends StackObjImpl implements Ability { game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, newStackAbility.getId(), this.getId(), newControllerId)); return newStackAbility; } + + public boolean isAllCreatureTypes(){ + return false; + } + + public void setIsAllCreatureTypes(boolean value){} } diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 3155da8ae2f..a91dd87bd07 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -40,9 +40,6 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; import mage.util.functions.CopyTokenFunction; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -54,24 +51,7 @@ public final class CardUtil { private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone"; static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", - "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; - - private static final String[] NON_CHANGELING_SUBTYPES_VALUES = new String[]{ - // basic lands subtypes - "Mountain", "Forest", "Plains", "Swamp", "Island", - // Enchantment subtypes - "Aura", "Cartouche", "Curse", "Shrine", - // Artifact subtypes - "Clue", "Equipment", "Fortification", "Contraption", "Vehicle", - // Land subtypes - "Desert", "Gate", "Lair", "Locus", "Urza's", "Mine", "Power-Plant", "Tower", - // Planeswalker subtypes - "Ajani", "Arlinn", "Ashiok", "Bolas", "Chandra", "Dack", "Daretti", "Domri", "Dovin", "Elspeth", "Freyalise", "Garruk", "Gideon", "Jace", - "Karn", "Kiora", "Koth", "Liliana", "Nahiri", "Nissa", "Narset", "Nixilis", "Ral", "Saheeli", "Sarkhan", "Sorin", "Tamiyo", "Teferi", - "Tezzeret", "Tibalt", "Ugin", "Venser", "Vraska", "Xenagos", - // Instant sorcery subtypes - "Trap", "Arcane"}; - private static final Set NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; /** * Increase spell or ability cost to be paid. @@ -502,12 +482,6 @@ public final class CardUtil { return "" + text + ""; } - - - public static boolean isNonCreatureSubtype(String subtype) { - return NON_CREATURE_SUBTYPES.contains(subtype); - } - public static boolean cardCanBePlayedNow(Card card, UUID playerId, Game game) { if (card.isLand()) { return game.canPlaySorcery(playerId) && game.getPlayer(playerId).canPlayLand(); diff --git a/Mage/src/main/java/mage/util/SubTypeList.java b/Mage/src/main/java/mage/util/SubTypeList.java new file mode 100644 index 00000000000..7009f1338b8 --- /dev/null +++ b/Mage/src/main/java/mage/util/SubTypeList.java @@ -0,0 +1,39 @@ +package mage.util; + +import mage.constants.SubType; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class SubTypeList extends ArrayList { + + + public void add(int index, String s) { + add(index, SubType.byDescription(s)); + } + + public void add(int index, SubType s) { + super.add(index, s); + } + + public boolean addAll(List subtypes) { + return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + } + + public boolean removeAll(List subtypes){ + return removeAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + } + + public boolean add(SubType s) { + return super.add(s); + } + + public boolean add(String s) { + return add(SubType.byDescription(s)); + } + + public boolean contains(String s) { + return contains(SubType.byDescription(s)); + } +} diff --git a/Mage/src/main/java/mage/util/functions/CopyTokenFunction.java b/Mage/src/main/java/mage/util/functions/CopyTokenFunction.java index 57dce0835cf..81830b77442 100644 --- a/Mage/src/main/java/mage/util/functions/CopyTokenFunction.java +++ b/Mage/src/main/java/mage/util/functions/CopyTokenFunction.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.keyword.MorphAbility; import mage.cards.Card; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentToken; @@ -96,7 +97,7 @@ public class CopyTokenFunction implements Function { target.addCardType(type); } target.getSubtype(null).clear(); - for (String type : sourceObj.getSubtype(null)) { + for (SubType type : sourceObj.getSubtype(null)) { target.getSubtype(null).add(type); } target.getSuperType().clear(); diff --git a/Mage/src/main/java/mage/watchers/common/ProwlWatcher.java b/Mage/src/main/java/mage/watchers/common/ProwlWatcher.java index e61ea01bb07..751f0f15b83 100644 --- a/Mage/src/main/java/mage/watchers/common/ProwlWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/ProwlWatcher.java @@ -27,14 +27,8 @@ */ package mage.watchers.common; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.UUID; import mage.abilities.keyword.ChangelingAbility; +import mage.constants.SubType; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; @@ -43,6 +37,9 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.watchers.Watcher; +import java.util.*; +import java.util.Map.Entry; + /** * Watcher stores with which creature subtypes a player made combat damage to * other players during a turn. @@ -51,7 +48,7 @@ import mage.watchers.Watcher; */ public class ProwlWatcher extends Watcher { - private final Map> damagingSubtypes = new HashMap<>(); + private final Map> damagingSubtypes = new HashMap<>(); private final Set allSubtypes = new HashSet<>(); public ProwlWatcher() { @@ -60,7 +57,7 @@ public class ProwlWatcher extends Watcher { public ProwlWatcher(final ProwlWatcher watcher) { super(watcher); - for (Entry> entry : watcher.damagingSubtypes.entrySet()) { + for (Entry> entry : watcher.damagingSubtypes.entrySet()) { damagingSubtypes.put(entry.getKey(), entry.getValue()); } } @@ -77,10 +74,10 @@ public class ProwlWatcher extends Watcher { if (dEvent.isCombatDamage()) { Permanent creature = game.getPermanent(dEvent.getSourceId()); if (creature != null && !allSubtypes.contains(creature.getControllerId())) { - if (creature.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + if (creature.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature.isAllCreatureTypes()) { allSubtypes.add(creature.getControllerId()); } else { - Set subtypes = damagingSubtypes.getOrDefault(creature.getControllerId(), new LinkedHashSet<>()); + Set subtypes = damagingSubtypes.getOrDefault(creature.getControllerId(), new LinkedHashSet<>()); subtypes.addAll(creature.getSubtype(game)); damagingSubtypes.put(creature.getControllerId(), subtypes); @@ -97,11 +94,11 @@ public class ProwlWatcher extends Watcher { allSubtypes.clear(); } - public boolean hasSubtypeMadeCombatDamage(UUID playerId, String subtype) { + public boolean hasSubtypeMadeCombatDamage(UUID playerId, SubType subtype) { if (allSubtypes.contains(playerId)) { return true; } - Set subtypes = damagingSubtypes.get(playerId); + Set subtypes = damagingSubtypes.get(playerId); return subtypes != null && subtypes.contains(subtype); } diff --git a/Mage/src/main/java/mage/watchers/common/ZuberasDiedWatcher.java b/Mage/src/main/java/mage/watchers/common/ZuberasDiedWatcher.java index b3e3bcfea93..d176bdd186d 100644 --- a/Mage/src/main/java/mage/watchers/common/ZuberasDiedWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/ZuberasDiedWatcher.java @@ -1,6 +1,7 @@ package mage.watchers.common; import mage.MageObject; +import mage.constants.SubType; import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; @@ -33,7 +34,7 @@ public class ZuberasDiedWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { MageObject card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera", game)) { + if (card != null && card.hasSubtype(SubType.ZUBERA, game)) { zuberasDiedThisTurn++; } }