diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index b33948b293b..e32abaa4a5e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -251,7 +251,7 @@ public class AnimateAi extends SpellAbilityAi { && sa.getTargetRestrictions() != null && sa.getTargetRestrictions().getMinTargets(sa.getHostCard(), sa) == 0; - final CardType types = new CardType(); + final CardType types = new CardType(true); if (sa.hasParam("Types")) { types.addAll(Arrays.asList(sa.getParam("Types").split(","))); } @@ -383,12 +383,12 @@ public class AnimateAi extends SpellAbilityAi { } } - final CardType types = new CardType(); + final CardType types = new CardType(true); if (sa.hasParam("Types")) { types.addAll(Arrays.asList(sa.getParam("Types").split(","))); } - final CardType removeTypes = new CardType(); + final CardType removeTypes = new CardType(true); if (sa.hasParam("RemoveTypes")) { removeTypes.addAll(Arrays.asList(sa.getParam("RemoveTypes").split(","))); } diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index c759785b37a..1023b6a13d4 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -487,7 +487,7 @@ public final class CardRules implements ICardCharacteristics { if ("T".equals(key)) { this.faces[this.curFace].addTrigger(value); } else if ("Types".equals(key)) { - this.faces[this.curFace].setType(CardType.parse(value)); + this.faces[this.curFace].setType(CardType.parse(value, false)); } else if ("Text".equals(key) && !"no text".equals(value) && StringUtils.isNotBlank(value)) { this.faces[this.curFace].setNonAbilityText(value); } @@ -557,7 +557,7 @@ public final class CardRules implements ICardCharacteristics { CardAiHints cah = new CardAiHints(true, true, true, null, null, null); CardFace[] faces = { new CardFace(name), null}; faces[0].setColor(ColorSet.fromMask(0)); - faces[0].setType(CardType.parse("")); + faces[0].setType(CardType.parse("", false)); faces[0].setOracleText("This card is not supported by Forge. Whenever you start a game with this card, it will be bugged."); faces[0].setNonAbilityText("This card is not supported by Forge.\nWhenever you start a game with this card, it will be bugged."); faces[0].assignMissingFields(); diff --git a/forge-core/src/main/java/forge/card/CardType.java b/forge-core/src/main/java/forge/card/CardType.java index 99ceaefa3c5..a7af692822c 100644 --- a/forge-core/src/main/java/forge/card/CardType.java +++ b/forge-core/src/main/java/forge/card/CardType.java @@ -50,7 +50,7 @@ import forge.util.Settable; public final class CardType implements Comparable, CardTypeView { private static final long serialVersionUID = 4629853583167022151L; - public static final CardTypeView EMPTY = new CardType(); + public static final CardTypeView EMPTY = new CardType(false); public static final String AllCreatureTypes = "AllCreatureTypes"; @@ -111,11 +111,14 @@ public final class CardType implements Comparable, CardTypeView { private final Set coreTypes = EnumSet.noneOf(CoreType.class); private final Set supertypes = EnumSet.noneOf(Supertype.class); private final Set subtypes = Sets.newLinkedHashSet(); + private boolean incomplete = false; private transient String calculatedType = null; - public CardType() { + public CardType(boolean incomplete) { + this.incomplete = incomplete; } - public CardType(final Iterable from0) { + public CardType(final Iterable from0, boolean incomplete) { + this.incomplete = incomplete; addAll(from0); } public CardType(final CardType from0) { @@ -516,6 +519,10 @@ public final class CardType implements Comparable, CardTypeView { } public void sanisfySubtypes() { + // incomplete types are used for changing effects + if (this.incomplete) { + return; + } if (!isCreature() && !isTribal()) { Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE); subtypes.remove(AllCreatureTypes); @@ -637,11 +644,11 @@ public final class CardType implements Comparable, CardTypeView { return false; } - public static CardType parse(final String typeText) { + public static CardType parse(final String typeText, boolean incomplete) { // Most types and subtypes, except "Serra's Realm" and // "Bolas's Meditation Realm" consist of only one word final char space = ' '; - final CardType result = new CardType(); + final CardType result = new CardType(incomplete); int iTypeStart = 0; int iSpace = typeText.indexOf(space); @@ -661,7 +668,7 @@ public final class CardType implements Comparable, CardTypeView { } public static CardType combine(final CardType a, final CardType b) { - final CardType result = new CardType(); + final CardType result = new CardType(false); result.supertypes.addAll(a.supertypes); result.supertypes.addAll(b.supertypes); result.coreTypes.addAll(a.coreTypes); diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java index 9e23a7a7183..d777368c2d6 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java @@ -51,12 +51,12 @@ public class AnimateAllEffect extends AnimateEffectBase { final boolean permanent = sa.hasParam("Permanent"); - final CardType types = new CardType(); + final CardType types = new CardType(true); if (sa.hasParam("Types")) { types.addAll(Arrays.asList(sa.getParam("Types").split(","))); } - final CardType removeTypes = new CardType(); + final CardType removeTypes = new CardType(true); if (sa.hasParam("RemoveTypes")) { removeTypes.addAll(Arrays.asList(sa.getParam("RemoveTypes").split(","))); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java index b319e84f37f..8be2736c313 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java @@ -64,12 +64,12 @@ public class AnimateEffect extends AnimateEffectBase { final boolean permanent = sa.hasParam("Permanent"); - final CardType types = new CardType(); + final CardType types = new CardType(true); if (sa.hasParam("Types")) { types.addAll(Arrays.asList(sa.getParam("Types").split(","))); } - final CardType removeTypes = new CardType(); + final CardType removeTypes = new CardType(true); if (sa.hasParam("RemoveTypes")) { removeTypes.addAll(Arrays.asList(sa.getParam("RemoveTypes").split(","))); } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 327d21c3f4a..929dcc0e3c4 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3199,11 +3199,11 @@ public class Card extends GameEntity implements Comparable { CardType addType = null; CardType removeType = null; if (types != null) { - addType = new CardType(types); + addType = new CardType(types, true); } if (removeTypes != null) { - removeType = new CardType(removeTypes); + removeType = new CardType(removeTypes, true); } addChangedCardTypes(addType, removeType, removeSuperTypes, removeCardTypes, removeSubTypes, @@ -3964,7 +3964,7 @@ public class Card extends GameEntity implements Comparable { public final void addChangedTextTypeWord(final String originalWord, final String newWord, final Long timestamp) { changedTextTypes.add(timestamp, originalWord, newWord); if (getType().hasSubtype(originalWord)) { - addChangedCardTypes(CardType.parse(newWord), CardType.parse(originalWord), + addChangedCardTypes(CardType.parse(newWord, true), CardType.parse(originalWord, true), false, false, false, false, false, false, false, timestamp); } updateKeywordsChangedText(timestamp); @@ -5268,8 +5268,8 @@ public class Card extends GameEntity implements Comparable { public final void animateBestow(final boolean updateView) { bestowTimestamp = getGame().getNextTimestamp(); - addChangedCardTypes(new CardType(Collections.singletonList("Aura")), - new CardType(Collections.singletonList("Creature")), + addChangedCardTypes(new CardType(Collections.singletonList("Aura"), true), + new CardType(Collections.singletonList("Creature"), true), false, false, false, false, false, false, true, bestowTimestamp, updateView); addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(), false, false, bestowTimestamp, updateView); diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index e4f7337a8c7..6563317225b 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -48,7 +48,7 @@ import io.sentry.event.BreadcrumbBuilder; public class CardState extends GameObject { private String name = ""; - private CardType type = new CardType(); + private CardType type = new CardType(false); private ManaCost manaCost = ManaCost.NO_COST; private byte color = MagicColor.COLORLESS; private int basePower = 0; diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index 47c5d8211b7..3bf6a1c092d 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -327,7 +327,7 @@ public final class CardUtil { } public static CardState getFaceDownCharacteristic(Card c) { - final CardType type = new CardType(); + final CardType type = new CardType(false); type.add("Creature"); final CardState ret = new CardState(c, CardStateName.FaceDown);