Merge remote-tracking branch 'remotes/upstream/master'

This commit is contained in:
ciaccona007 2017-07-16 21:47:25 -04:00
commit 3d24f0a0de
185 changed files with 1068 additions and 906 deletions

View file

@ -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<CardType> getCardType();
List<String> 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<SuperType> 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> cardType){
getCardType().addAll(cardType);
}

View file

@ -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> cardType = EnumSet.noneOf(CardType.class);
protected List<String> subtype = new ArrayList<>();
protected SubTypeList subtype = new SubTypeList();
protected boolean isAllCreatureTypes;
protected EnumSet<SuperType> supertype = EnumSet.noneOf(SuperType.class);
protected Abilities<Ability> abilities;
protected String text;
@ -132,7 +137,7 @@ public abstract class MageObjectImpl implements MageObject {
}
@Override
public List<String> 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<String> 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;
}
}

View file

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

View file

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

View file

@ -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<String> subtypes;
private final SubTypeList subtypes;
public SourceHasSubtypeCondition(List<String> 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;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<ArrayList<String>> cardSubtypes = new ArrayList<>();
List<SubTypeList> 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<String>) targetCreature.getSubtype(game));
cardSubtypes.add(targetCreature.getSubtype(game));
}
if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) {
return false;

View file

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

View file

@ -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<String> 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<String> landTypes = new ArrayList<>();

View file

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

View file

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

View file

@ -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<String> 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;

View file

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

View file

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

View file

@ -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:

View file

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

View file

@ -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<String> 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<String> 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<String> 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<String> createArrayList(String subtype) {
ArrayList<String> 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);
}

View file

@ -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<String> 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<String> subtypes) {
public BecomesSubtypeAllEffect(Duration duration, SubTypeList subtypes) {
this(duration, subtypes, new FilterCreaturePermanent("All creatures"), true);
}
public BecomesSubtypeAllEffect(Duration duration,
ArrayList<String> 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<String> createArrayList(String subtype) {
ArrayList<String> 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);
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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<String> 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();

View file

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

View file

@ -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 {

View file

@ -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(" <i>(").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.)</i>");

View file

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

View file

@ -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(" <i>(").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.)</i>");

View file

@ -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

View file

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

View file

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

View file

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

View file

@ -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<String> 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<String> subtypes) {

View file

@ -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<String> getCreatureTypes() {
TreeSet<String> subtypes = new TreeSet<>();
try {
QueryBuilder<CardInfo, Object> qb = cardDao.queryBuilder();
qb.distinct().selectColumns("subtypes");
qb.where().like("types", new SelectArg('%' + CardType.CREATURE.name() + '%'));
List<CardInfo> 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<String> getLandTypes() {
if (landTypes.isEmpty()) {
try {
QueryBuilder<CardInfo, Object> qb = cardDao.queryBuilder();
qb.distinct().selectColumns("subtypes");
qb.where().like("types", new SelectArg('%' + CardType.LAND.name() + '%'));
List<CardInfo> 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 {

View file

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

View file

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

View file

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

View file

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

View file

@ -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 monarchs 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.";
}
}

View file

@ -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<MageObject> {
@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

View file

@ -47,7 +47,7 @@ public class SubtypePredicate implements Predicate<MageObject> {
@Override
public boolean apply(MageObject input, Game game) {
return input.hasSubtype(subtype.getDescription(), game);
return input.hasSubtype(subtype, game);
}
@Override

View file

@ -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<Card> {
}
}
for (String subType : input.getSubtype(game)) {
if (subType.equalsIgnoreCase(token)) {
for (SubType subType : input.getSubtype(game)) {
if (subType.toString().equalsIgnoreCase(token)) {
found = true;
break;
}

View file

@ -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<String> 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<String> getSubtype() {
public SubTypeList getSubtype() {
return subtype;
}

View file

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

View file

@ -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<String> 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){}
}

View file

@ -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<String> 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){}
}

View file

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

View file

@ -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<String> subtype, int power, int toughness, Abilities<Ability> abilities) {
public Token(String name, String description, ObjectColor color, SubTypeList subtype, int power, int toughness, Abilities<Ability> 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;
}
}

View file

@ -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<String> getSubtype(Game game) {
public SubTypeList getSubtype(Game game) {
if (this.getSpellAbility() instanceof BestowAbility) {
List<String> 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<String> 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){}
}

View file

@ -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<String> 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){}
}

View file

@ -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<String> 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 "<font color = 'blue'>" + text + "</font>";
}
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();

View file

@ -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<SubType> {
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<String> subtypes) {
return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList()));
}
public boolean removeAll(List<String> 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));
}
}

View file

@ -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<Token, Card> {
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();

View file

@ -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<UUID, Set<String>> damagingSubtypes = new HashMap<>();
private final Map<UUID, Set<SubType>> damagingSubtypes = new HashMap<>();
private final Set<UUID> allSubtypes = new HashSet<>();
public ProwlWatcher() {
@ -60,7 +57,7 @@ public class ProwlWatcher extends Watcher {
public ProwlWatcher(final ProwlWatcher watcher) {
super(watcher);
for (Entry<UUID, Set<String>> entry : watcher.damagingSubtypes.entrySet()) {
for (Entry<UUID, Set<SubType>> 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<String> subtypes = damagingSubtypes.getOrDefault(creature.getControllerId(), new LinkedHashSet<>());
Set<SubType> 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<String> subtypes = damagingSubtypes.get(playerId);
Set<SubType> subtypes = damagingSubtypes.get(playerId);
return subtypes != null && subtypes.contains(subtype);
}

View file

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