mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
CardType: sanisfySubtypes each time its changed, moved shareTypeWith functions into CardType
This commit is contained in:
@@ -52,6 +52,8 @@ public final class CardType implements Comparable<CardType>, 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<CardType>, CardTypeView {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
sanisfySubtypes();
|
||||
return changed;
|
||||
}
|
||||
public boolean addAll(final CardType type) {
|
||||
@@ -159,6 +162,7 @@ public final class CardType implements Comparable<CardType>, 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<CardType>, 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<CardType>, 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<CardType>, CardTypeView {
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
sanisfySubtypes();
|
||||
calculatedType = null;
|
||||
}
|
||||
return changed;
|
||||
@@ -223,7 +230,7 @@ public final class CardType implements Comparable<CardType>, 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<CardType>, CardTypeView {
|
||||
final Set<String> 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<CardType>, 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<CardType>, 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<CardType>, 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<CardType>, 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<String> iterator() {
|
||||
final Iterator<CoreType> coreTypeIterator = coreTypes.iterator();
|
||||
@@ -560,7 +571,64 @@ public final class CardType implements Comparable<CardType>, 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;
|
||||
|
||||
@@ -19,6 +19,12 @@ public interface CardTypeView extends Iterable<String>, 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();
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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<Card> {
|
||||
currentState.addType(type0);
|
||||
}
|
||||
|
||||
public final void addType(final Iterable<String> 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<Card> {
|
||||
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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> 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<String> creatureTypes = c.getType().getCreatureTypes();
|
||||
for (String creatureType : creatureTypes) {
|
||||
if (creatureType.equals("AllCreatureTypes")) {
|
||||
if (creatureType.equals(CardType.AllCreatureTypes)) {
|
||||
allCreatureType++;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -116,6 +116,11 @@ public class CardState extends GameObject {
|
||||
view.updateType(this);
|
||||
}
|
||||
}
|
||||
public final void addType(Iterable<String> 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.
|
||||
|
||||
@@ -2117,7 +2117,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final boolean hasProwl(final String type) {
|
||||
if (prowl.contains("AllCreatureTypes")) {
|
||||
if (prowl.contains(CardType.AllCreatureTypes)) {
|
||||
return true;
|
||||
}
|
||||
return prowl.contains(type);
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<String> types) {
|
||||
// build map of creature types in player's main deck against the
|
||||
// occurrences of each
|
||||
CardCollection pool = CardLists.filterControlledBy(game.getCardsInGame(), player);
|
||||
Map<String, Integer> 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<String> 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;
|
||||
}
|
||||
sTokenTypes = sa.getParam("TokenTypes");
|
||||
} else if (t.hasParam("Execute")) {
|
||||
String name = t.getParam("Execute");
|
||||
if (!c.hasSVar(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, String> 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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// special rule for Fabricate and Servo
|
||||
|
||||
Reference in New Issue
Block a user