diff --git a/forge-core/src/main/java/forge/card/CardType.java b/forge-core/src/main/java/forge/card/CardType.java index 09d6abbd2f9..99ceaefa3c5 100644 --- a/forge-core/src/main/java/forge/card/CardType.java +++ b/forge-core/src/main/java/forge/card/CardType.java @@ -52,6 +52,8 @@ public final class CardType implements Comparable, CardTypeView { public static final CardTypeView EMPTY = new CardType(); + public static final String AllCreatureTypes = "AllCreatureTypes"; + public enum CoreType { Artifact(true), Conspiracy(false), @@ -152,6 +154,7 @@ public final class CardType implements Comparable, CardTypeView { changed = true; } } + sanisfySubtypes(); return changed; } public boolean addAll(final CardType type) { @@ -159,6 +162,7 @@ public final class CardType implements Comparable, CardTypeView { if (coreTypes.addAll(type.coreTypes)) { changed = true; } if (supertypes.addAll(type.supertypes)) { changed = true; } if (subtypes.addAll(type.subtypes)) { changed = true; } + sanisfySubtypes(); return changed; } public boolean addAll(final CardTypeView type) { @@ -166,6 +170,7 @@ public final class CardType implements Comparable, CardTypeView { if (Iterables.addAll(coreTypes, type.getCoreTypes())) { changed = true; } if (Iterables.addAll(supertypes, type.getSupertypes())) { changed = true; } if (Iterables.addAll(subtypes, type.getSubtypes())) { changed = true; } + sanisfySubtypes(); return changed; } @@ -175,6 +180,7 @@ public final class CardType implements Comparable, CardTypeView { if (supertypes.removeAll(type.supertypes)) { changed = true; } if (subtypes.removeAll(type.subtypes)) { changed = true; } if (changed) { + sanisfySubtypes(); calculatedType = null; return true; } @@ -211,6 +217,7 @@ public final class CardType implements Comparable, CardTypeView { } if (changed) { + sanisfySubtypes(); calculatedType = null; } return changed; @@ -223,7 +230,7 @@ public final class CardType implements Comparable, CardTypeView { } boolean changed = Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE); // need to remove AllCreatureTypes too when setting Creature Type - if (subtypes.remove("AllCreatureTypes")) { + if (subtypes.remove(AllCreatureTypes)) { changed = true; } subtypes.addAll(ctypes); @@ -252,7 +259,7 @@ public final class CardType implements Comparable, CardTypeView { final Set creatureTypes = Sets.newHashSet(); if (isCreature() || isTribal()) { for (final String t : subtypes) { - if (isACreatureType(t) || t.equals("AllCreatureTypes")) { + if (isACreatureType(t) || t.equals(AllCreatureTypes)) { creatureTypes.add(t); } } @@ -302,7 +309,7 @@ public final class CardType implements Comparable, CardTypeView { } @Override public boolean hasSubtype(final String subtype) { - if (isACreatureType(subtype) && subtypes.contains("AllCreatureTypes")) { + if (isACreatureType(subtype) && subtypes.contains(AllCreatureTypes)) { return true; } return subtypes.contains(subtype); @@ -315,7 +322,7 @@ public final class CardType implements Comparable, CardTypeView { creatureType = toMixedCase(creatureType); if (!isACreatureType(creatureType)) { return false; } - return subtypes.contains(creatureType) || subtypes.contains("AllCreatureTypes"); + return subtypes.contains(creatureType) || subtypes.contains(AllCreatureTypes); } private static String toMixedCase(final String s) { if (s.isEmpty()) { @@ -485,7 +492,7 @@ public final class CardType implements Comparable, CardTypeView { if (ct.isRemoveCreatureTypes()) { Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE); // need to remove AllCreatureTypes too when removing creature Types - newType.subtypes.remove("AllCreatureTypes"); + newType.subtypes.remove(AllCreatureTypes); } if (ct.isRemoveArtifactTypes()) { Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE); @@ -503,29 +510,33 @@ public final class CardType implements Comparable, CardTypeView { } // sanisfy subtypes if (newType != null && !newType.subtypes.isEmpty()) { - if (!newType.isCreature() && !newType.isTribal()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE); - newType.subtypes.remove("AllCreatureTypes"); - } - if (!newType.isLand()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_LAND_TYPE); - } - if (!newType.isArtifact()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE); - } - if (!newType.isEnchantment()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_ENCHANTMENT_TYPE); - } - if (!newType.isInstant() && !newType.isSorcery()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_SPELL_TYPE); - } - if (!newType.isPlaneswalker() && !newType.isEmblem()) { - Iterables.removeIf(newType.subtypes, Predicates.IS_WALKER_TYPE); - } + newType.sanisfySubtypes(); } return newType == null ? this : newType; } + public void sanisfySubtypes() { + if (!isCreature() && !isTribal()) { + Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE); + subtypes.remove(AllCreatureTypes); + } + if (!isLand()) { + Iterables.removeIf(subtypes, Predicates.IS_LAND_TYPE); + } + if (!isArtifact()) { + Iterables.removeIf(subtypes, Predicates.IS_ARTIFACT_TYPE); + } + if (!isEnchantment()) { + Iterables.removeIf(subtypes, Predicates.IS_ENCHANTMENT_TYPE); + } + if (!isInstant() && !isSorcery()) { + Iterables.removeIf(subtypes, Predicates.IS_SPELL_TYPE); + } + if (!isPlaneswalker() && !isEmblem()) { + Iterables.removeIf(subtypes, Predicates.IS_WALKER_TYPE); + } + } + @Override public Iterator iterator() { final Iterator coreTypeIterator = coreTypes.iterator(); @@ -560,7 +571,64 @@ public final class CardType implements Comparable, CardTypeView { return toString().compareTo(o.toString()); } - public boolean sharesSubtypeWith(final CardType ctOther) { + public boolean sharesCreaturetypeWith(final CardTypeView ctOther) { + if (ctOther == null) { + return false; + } + if (this.subtypes.contains(AllCreatureTypes) && ctOther.hasSubtype(AllCreatureTypes)) { + return true; + } + for (final String type : getCreatureTypes()) { + if (ctOther.hasCreatureType(type)) { + return true; + } + } + return false; + } + + public boolean sharesLandTypeWith(final CardTypeView ctOther) { + if (ctOther == null) { + return false; + } + + for (final String type : getLandTypes()) { + if (ctOther.hasSubtype(type)) { + return true; + } + } + return false; + } + + public boolean sharesPermanentTypeWith(final CardTypeView ctOther) { + if (ctOther == null) { + return false; + } + + for (final CoreType type : getCoreTypes()) { + if (type.isPermanent && ctOther.hasType(type)) { + return true; + } + } + return false; + } + + public boolean sharesCardTypeWith(final CardTypeView ctOther) { + if (ctOther == null) { + return false; + } + + for (final CoreType type : getCoreTypes()) { + if (ctOther.hasType(type)) { + return true; + } + } + return false; + } + + public boolean sharesSubtypeWith(final CardTypeView ctOther) { + if (ctOther == null) { + return false; + } for (final String t : ctOther.getSubtypes()) { if (hasSubtype(t)) { return true; diff --git a/forge-core/src/main/java/forge/card/CardTypeView.java b/forge-core/src/main/java/forge/card/CardTypeView.java index b1c01369b2b..e9b65aeac81 100644 --- a/forge-core/src/main/java/forge/card/CardTypeView.java +++ b/forge-core/src/main/java/forge/card/CardTypeView.java @@ -19,6 +19,12 @@ public interface CardTypeView extends Iterable, Serializable { boolean hasSupertype(Supertype supertype); boolean hasSubtype(String subtype); boolean hasCreatureType(String creatureType); + + public boolean sharesCreaturetypeWith(final CardTypeView ctOther); + public boolean sharesLandTypeWith(final CardTypeView ctOther); + public boolean sharesPermanentTypeWith(final CardTypeView ctOther); + public boolean sharesCardTypeWith(final CardTypeView ctOther); + boolean isPermanent(); boolean isCreature(); boolean isPlaneswalker(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 58cafdaa90b..e14d819863b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -37,6 +37,7 @@ import forge.util.collect.FCollectionView; import forge.util.Localizer; import forge.util.CardTranslation; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -1179,9 +1180,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } if (sa.hasParam("FaceDownAddType")) { - for (String type : sa.getParam("FaceDownAddType").split(",")) { - c.addType(type); - } + c.addType(Arrays.asList(sa.getParam("FaceDownAddType").split(" & "))); } if (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness") 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 75bcc36ae3a..b1ae887b9a5 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -26,7 +26,6 @@ import forge.ImageKeys; import forge.StaticData; import forge.card.*; import forge.card.CardDb.SetPreference; -import forge.card.CardType.CoreType; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostParser; import forge.game.*; @@ -3098,6 +3097,10 @@ public class Card extends GameEntity implements Comparable { currentState.addType(type0); } + public final void addType(final Iterable type0) { + currentState.addType(type0); + } + public final void removeType(final CardType.Supertype st) { currentState.removeType(st); } @@ -4601,84 +4604,34 @@ public class Card extends GameEntity implements Comparable { if (c1 == null) { return false; } - - for (final String type : getType().getCreatureTypes()) { - if (type.equals("AllCreatureTypes") && c1.hasACreatureType()) { - return true; - } - if (c1.getType().hasCreatureType(type)) { - return true; - } - } - return false; + return getType().sharesCreaturetypeWith(c1.getType()); } public final boolean sharesLandTypeWith(final Card c1) { if (c1 == null) { return false; } - - for (final String type : getType().getLandTypes()) { - if (c1.getType().hasSubtype(type)) { - return true; - } - } - return false; + return getType().sharesLandTypeWith(c1.getType()); } public final boolean sharesPermanentTypeWith(final Card c1) { if (c1 == null) { return false; } - - for (final CoreType type : getType().getCoreTypes()) { - if (type.isPermanent && c1.getType().hasType(type)) { - return true; - } - } - return false; + return getType().sharesPermanentTypeWith(c1.getType()); } public final boolean sharesCardTypeWith(final Card c1) { - for (final CoreType type : getType().getCoreTypes()) { - if (c1.getType().hasType(type)) { - return true; - } + if (c1 == null) { + return false; } - return false; - } - - public final boolean sharesTypeWith(final Card c1) { - for (final String type : getType()) { - if (c1.getType().hasStringType(type)) { - return true; - } - } - return false; + return getType().sharesCardTypeWith(c1.getType()); } public final boolean sharesControllerWith(final Card c1) { return c1 != null && getController().equals(c1.getController()); } - public final boolean hasACreatureType() { - for (final String type : getType().getSubtypes()) { - if (forge.card.CardType.isACreatureType(type) || type.equals("AllCreatureTypes")) { - return true; - } - } - return false; - } - - public final boolean hasALandType() { - for (final String type : getType().getSubtypes()) { - if (forge.card.CardType.isALandType(type) || forge.card.CardType.isABasicLandType(type)) { - return true; - } - } - return false; - } - public final boolean hasABasicLandType() { for (final String type : getType().getSubtypes()) { if (forge.card.CardType.isABasicLandType(type)) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 81caaaabe59..d73dae2bc8f 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -587,7 +587,7 @@ public class CardFactory { String shortColors = ""; if (sa.hasParam("AddTypes")) { - types.addAll(Arrays.asList(sa.getParam("AddTypes").split(","))); + types.addAll(Arrays.asList(sa.getParam("AddTypes").split(" & "))); } if (sa.hasParam("AddKeywords")) { @@ -654,9 +654,7 @@ public class CardFactory { state.removeType(CardType.Supertype.Legendary); } - for (final String type : types) { - state.addType(type); - } + state.addType(types); if (creatureTypes != null) { state.setCreatureTypes(creatureTypes); @@ -795,7 +793,7 @@ public class CardFactory { if (sa.hasParam("SetCreatureTypes")) { // currently only Changeling and similar should be affected by that // other cards using AddType$ ChosenType should not - if (sta.hasParam("AddType") && "AllCreatureTypes".equals(sta.getParam("AddType"))) { + if (sta.hasParam("AddType") && CardType.AllCreatureTypes.equals(sta.getParam("AddType"))) { state.removeStaticAbility(sta); } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index e3a56020921..91ea26ba9ea 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1116,7 +1116,7 @@ public class CardFactoryUtil { for (Card card : cards) { Iterables.addAll(creatTypes, card.getType().getCreatureTypes()); } - int n = creatTypes.contains("AllCreatureTypes") ? CardType.getAllCreatureTypes().size() : creatTypes.size(); + int n = creatTypes.contains(CardType.AllCreatureTypes) ? CardType.getAllCreatureTypes().size() : creatTypes.size(); return doXMath(n, m, c); } @@ -1198,7 +1198,7 @@ public class CardFactoryUtil { // Figure out how to count each class separately. for (Card card : adventurers) { Set creatureTypes = card.getType().getCreatureTypes(); - boolean anyType = creatureTypes.contains("AllCreatureTypes"); + boolean anyType = creatureTypes.contains(CardType.AllCreatureTypes); creatureTypes.retainAll(partyTypes); if (anyType || creatureTypes.size() == 4) { @@ -1997,7 +1997,7 @@ public class CardFactoryUtil { // Remove Duplicated types final Set creatureTypes = c.getType().getCreatureTypes(); for (String creatureType : creatureTypes) { - if (creatureType.equals("AllCreatureTypes")) { + if (creatureType.equals(CardType.AllCreatureTypes)) { allCreatureType++; } else { 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 b11c967504e..e4f7337a8c7 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -116,6 +116,11 @@ public class CardState extends GameObject { view.updateType(this); } } + public final void addType(Iterable type0) { + if (type.addAll(type0)) { + view.updateType(this); + } + } public final void setType(final CardType type0) { if (type0 == type) { // Logic below would incorrectly clear the type if it's the same object. diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 322c564b284..2503a669e52 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -2117,7 +2117,7 @@ public class Player extends GameEntity implements Comparable { } public final boolean hasProwl(final String type) { - if (prowl.contains("AllCreatureTypes")) { + if (prowl.contains(CardType.AllCreatureTypes)) { return true; } return prowl.contains(type); diff --git a/forge-gui/res/cardsfolder/g/glasspool_mimic_glasspool_shore.txt b/forge-gui/res/cardsfolder/g/glasspool_mimic_glasspool_shore.txt index 5e1cfa87a32..55fdbc6cee5 100644 --- a/forge-gui/res/cardsfolder/g/glasspool_mimic_glasspool_shore.txt +++ b/forge-gui/res/cardsfolder/g/glasspool_mimic_glasspool_shore.txt @@ -3,7 +3,7 @@ ManaCost:2 U Types:Creature Shapeshifter Rogue PT:0/0 K:ETBReplacement:Copy:DBCopy:Optional -SVar:DBCopy:DB$ Clone | Choices$ Creature.YouCtrl | AddTypes$ Shapeshifter,Rogue | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of a creature you control, except it’s a Shapeshifter Rogue in addition to its other types. +SVar:DBCopy:DB$ Clone | Choices$ Creature.YouCtrl | AddTypes$ Shapeshifter & Rogue | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of a creature you control, except it’s a Shapeshifter Rogue in addition to its other types. AlternateMode:Modal Oracle:You may have Glasspool Mimic enter the battlefield as a copy of a creature you control, except it’s a Shapeshifter Rogue in addition to its other types. diff --git a/forge-gui/res/cardsfolder/t/tezzeret_cruel_machinist.txt b/forge-gui/res/cardsfolder/t/tezzeret_cruel_machinist.txt index 8334739ca06..cd8dd60919a 100644 --- a/forge-gui/res/cardsfolder/t/tezzeret_cruel_machinist.txt +++ b/forge-gui/res/cardsfolder/t/tezzeret_cruel_machinist.txt @@ -4,6 +4,6 @@ Loyalty:4 Types:Legendary Planeswalker Tezzeret A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 1 | Defined$ You | SpellDescription$ Draw a card. A:AB$ Animate | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | ValidTgts$ Artifact.YouCtrl | TgtPrompt$ Select target artifact you control | Power$ 5 | Toughness$ 5 | Types$ Creature | UntilYourNextTurn$ True | SpellDescription$ Until your next turn, target artifact you control becomes a 5/5 creature in addition to its other types. -A:AB$ ChangeZone | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | Origin$ Hand | Destination$ Battlefield | ChangeType$ Card | ChangeNum$ X | References$ X | FaceDown$ True | FaceDownPower$ 5 | FaceDownToughness$ 5 | FaceDownAddType$ Artifact,Creature | StackDescription$ SpellDescription | SpellDescription$ Put any number of cards from your hand onto the battlefield face down. They're 5/5 artifact creatures. +A:AB$ ChangeZone | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | Origin$ Hand | Destination$ Battlefield | ChangeType$ Card | ChangeNum$ X | References$ X | FaceDown$ True | FaceDownPower$ 5 | FaceDownToughness$ 5 | FaceDownAddType$ Artifact & Creature | StackDescription$ SpellDescription | SpellDescription$ Put any number of cards from your hand onto the battlefield face down. They're 5/5 artifact creatures. SVar:X:Count$InYourHand Oracle:[+1]: Draw a card.\n[0]: Until your next turn, target artifact you control becomes a 5/5 creature in addition to its other types.\n[-7]: Put any number of cards from your hand onto the battlefield face down. They're 5/5 artifact creatures. diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 7b4c4c86d2e..277690a6cf9 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -27,11 +27,7 @@ import forge.StaticData; import forge.achievement.AchievementCollection; import forge.ai.GameState; import forge.assets.FSkinProp; -import forge.card.CardDb; -import forge.card.CardType; -import forge.card.ColorSet; -import forge.card.ICardFace; -import forge.card.MagicColor; +import forge.card.*; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; import forge.control.FControlGamePlayback; @@ -39,26 +35,11 @@ import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; import forge.events.UiEventNextGameDecision; -import forge.game.Game; -import forge.game.GameEntity; -import forge.game.GameEntityView; -import forge.game.GameEntityViewMap; -import forge.game.GameLogEntryType; -import forge.game.GameObject; -import forge.game.GameType; -import forge.game.PlanarDice; -import forge.game.ability.AbilityFactory; +import forge.game.*; import forge.game.ability.AbilityKey; import forge.game.ability.ApiType; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardFaceView; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; -import forge.game.card.CardView; -import forge.game.card.CounterEnumType; -import forge.game.card.CounterType; +import forge.game.card.*; +import forge.game.card.token.TokenInfo; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.cost.Cost; @@ -69,20 +50,10 @@ import forge.game.keyword.Keyword; import forge.game.keyword.KeywordInterface; import forge.game.mana.Mana; import forge.game.mana.ManaConversionMatrix; -import forge.game.player.DelayedReveal; -import forge.game.player.Player; -import forge.game.player.PlayerActionConfirmMode; -import forge.game.player.PlayerController; -import forge.game.player.PlayerView; +import forge.game.player.*; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; -import forge.game.spellability.AbilityManaPart; -import forge.game.spellability.AbilitySub; -import forge.game.spellability.OptionalCostValue; -import forge.game.spellability.SpellAbility; -import forge.game.spellability.SpellAbilityStackInstance; -import forge.game.spellability.SpellAbilityView; -import forge.game.spellability.TargetChoices; +import forge.game.spellability.*; import forge.game.trigger.Trigger; import forge.game.trigger.WrappedAbility; import forge.game.zone.MagicStack; @@ -96,19 +67,7 @@ import forge.interfaces.IMacroSystem; import forge.item.IPaperCard; import forge.item.PaperCard; import forge.match.NextGameDecision; -import forge.match.input.Input; -import forge.match.input.InputAttack; -import forge.match.input.InputBlock; -import forge.match.input.InputConfirm; -import forge.match.input.InputConfirmMulligan; -import forge.match.input.InputLondonMulligan; -import forge.match.input.InputPassPriority; -import forge.match.input.InputPayMana; -import forge.match.input.InputProxy; -import forge.match.input.InputQueue; -import forge.match.input.InputSelectCardsForConvokeOrImprovise; -import forge.match.input.InputSelectCardsFromList; -import forge.match.input.InputSelectEntitiesFromList; +import forge.match.input.*; import forge.model.FModel; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences.FPref; @@ -1157,17 +1116,20 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont private void sortCreatureTypes(List types) { // build map of creature types in player's main deck against the // occurrences of each - CardCollection pool = CardLists.filterControlledBy(game.getCardsInGame(), player); Map typesInDeck = Maps.newHashMap(); // TODO JAVA 8 use getOrDefault - for (Card c : pool) { + for (Card c : player.getAllCards()) { // Changeling are all creature types, they are not interesting for // counting creature types if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) { continue; } + // same is true if it somehow has all creature types + if (c.getType().hasSubtype(CardType.AllCreatureTypes)) { + continue; + } // ignore cards that does enter the battlefield as clones boolean isClone = false; for (ReplacementEffect re : c.getReplacementEffects()) { @@ -1180,8 +1142,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont continue; } - Set cardCreatureTypes = c.getType().getCreatureTypes(); - for (String type : cardCreatureTypes) { + for (String type : c.getType().getCreatureTypes()) { Integer count = typesInDeck.get(type); if (count == null) { count = 0; @@ -1193,54 +1154,31 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (sa.getApi() != ApiType.Token) { continue; } - if (sa.hasParam("TokenTypes")) { - for (String var : sa.getParam("TokenTypes").split(",")) { - if (!CardType.isACreatureType(var)) { - continue; - } - Integer count = typesInDeck.get(var); + if (sa.hasParam("TokenScript")) { + Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa); + for (String type : protoType.getType().getCreatureTypes()) { + Integer count = typesInDeck.get(type); if (count == null) { count = 0; } - typesInDeck.put(var, count + 1); + typesInDeck.put(type, count + 1); } } } // same for Trigger that does make Tokens for (Trigger t : c.getTriggers()) { - SpellAbility sa = t.getOverridingAbility(); - String sTokenTypes = null; + SpellAbility sa = t.ensureAbility(); if (sa != null) { - if (sa.getApi() != ApiType.Token || !sa.hasParam("TokenTypes")) { - continue; + if (sa.hasParam("TokenScript")) { + Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa); + for (String type : protoType.getType().getCreatureTypes()) { + Integer count = typesInDeck.get(type); + if (count == null) { + count = 0; + } + typesInDeck.put(type, count + 1); + } } - sTokenTypes = sa.getParam("TokenTypes"); - } else if (t.hasParam("Execute")) { - String name = t.getParam("Execute"); - if (!c.hasSVar(name)) { - continue; - } - - Map params = AbilityFactory.getMapParams(c.getSVar(name)); - if (!params.containsKey("TokenTypes")) { - continue; - } - sTokenTypes = params.get("TokenTypes"); - } - - if (sTokenTypes == null) { - continue; - } - - for (String var : sTokenTypes.split(",")) { - if (!CardType.isACreatureType(var)) { - continue; - } - Integer count = typesInDeck.get(var); - if (count == null) { - count = 0; - } - typesInDeck.put(var, count + 1); } } // special rule for Fabricate and Servo @@ -3086,8 +3024,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont public void handleLandPlayed(Card land, Zone zone) { IGuiGame guiGame = getGui(); guiGame.handleLandPlayed(land,zone); - } + } + - }