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 CardTypeView EMPTY = new CardType();
|
||||||
|
|
||||||
|
public static final String AllCreatureTypes = "AllCreatureTypes";
|
||||||
|
|
||||||
public enum CoreType {
|
public enum CoreType {
|
||||||
Artifact(true),
|
Artifact(true),
|
||||||
Conspiracy(false),
|
Conspiracy(false),
|
||||||
@@ -152,6 +154,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sanisfySubtypes();
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
public boolean addAll(final CardType type) {
|
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 (coreTypes.addAll(type.coreTypes)) { changed = true; }
|
||||||
if (supertypes.addAll(type.supertypes)) { changed = true; }
|
if (supertypes.addAll(type.supertypes)) { changed = true; }
|
||||||
if (subtypes.addAll(type.subtypes)) { changed = true; }
|
if (subtypes.addAll(type.subtypes)) { changed = true; }
|
||||||
|
sanisfySubtypes();
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
public boolean addAll(final CardTypeView type) {
|
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(coreTypes, type.getCoreTypes())) { changed = true; }
|
||||||
if (Iterables.addAll(supertypes, type.getSupertypes())) { changed = true; }
|
if (Iterables.addAll(supertypes, type.getSupertypes())) { changed = true; }
|
||||||
if (Iterables.addAll(subtypes, type.getSubtypes())) { changed = true; }
|
if (Iterables.addAll(subtypes, type.getSubtypes())) { changed = true; }
|
||||||
|
sanisfySubtypes();
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +180,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
if (supertypes.removeAll(type.supertypes)) { changed = true; }
|
if (supertypes.removeAll(type.supertypes)) { changed = true; }
|
||||||
if (subtypes.removeAll(type.subtypes)) { changed = true; }
|
if (subtypes.removeAll(type.subtypes)) { changed = true; }
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
sanisfySubtypes();
|
||||||
calculatedType = null;
|
calculatedType = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -211,6 +217,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
sanisfySubtypes();
|
||||||
calculatedType = null;
|
calculatedType = null;
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
@@ -223,7 +230,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
}
|
}
|
||||||
boolean changed = Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE);
|
boolean changed = Iterables.removeIf(subtypes, Predicates.IS_CREATURE_TYPE);
|
||||||
// need to remove AllCreatureTypes too when setting Creature Type
|
// need to remove AllCreatureTypes too when setting Creature Type
|
||||||
if (subtypes.remove("AllCreatureTypes")) {
|
if (subtypes.remove(AllCreatureTypes)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
subtypes.addAll(ctypes);
|
subtypes.addAll(ctypes);
|
||||||
@@ -252,7 +259,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
final Set<String> creatureTypes = Sets.newHashSet();
|
final Set<String> creatureTypes = Sets.newHashSet();
|
||||||
if (isCreature() || isTribal()) {
|
if (isCreature() || isTribal()) {
|
||||||
for (final String t : subtypes) {
|
for (final String t : subtypes) {
|
||||||
if (isACreatureType(t) || t.equals("AllCreatureTypes")) {
|
if (isACreatureType(t) || t.equals(AllCreatureTypes)) {
|
||||||
creatureTypes.add(t);
|
creatureTypes.add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,7 +309,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSubtype(final String subtype) {
|
public boolean hasSubtype(final String subtype) {
|
||||||
if (isACreatureType(subtype) && subtypes.contains("AllCreatureTypes")) {
|
if (isACreatureType(subtype) && subtypes.contains(AllCreatureTypes)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return subtypes.contains(subtype);
|
return subtypes.contains(subtype);
|
||||||
@@ -315,7 +322,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
creatureType = toMixedCase(creatureType);
|
creatureType = toMixedCase(creatureType);
|
||||||
if (!isACreatureType(creatureType)) { return false; }
|
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) {
|
private static String toMixedCase(final String s) {
|
||||||
if (s.isEmpty()) {
|
if (s.isEmpty()) {
|
||||||
@@ -485,7 +492,7 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
if (ct.isRemoveCreatureTypes()) {
|
if (ct.isRemoveCreatureTypes()) {
|
||||||
Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE);
|
Iterables.removeIf(newType.subtypes, Predicates.IS_CREATURE_TYPE);
|
||||||
// need to remove AllCreatureTypes too when removing creature Types
|
// need to remove AllCreatureTypes too when removing creature Types
|
||||||
newType.subtypes.remove("AllCreatureTypes");
|
newType.subtypes.remove(AllCreatureTypes);
|
||||||
}
|
}
|
||||||
if (ct.isRemoveArtifactTypes()) {
|
if (ct.isRemoveArtifactTypes()) {
|
||||||
Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE);
|
Iterables.removeIf(newType.subtypes, Predicates.IS_ARTIFACT_TYPE);
|
||||||
@@ -503,29 +510,33 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
}
|
}
|
||||||
// sanisfy subtypes
|
// sanisfy subtypes
|
||||||
if (newType != null && !newType.subtypes.isEmpty()) {
|
if (newType != null && !newType.subtypes.isEmpty()) {
|
||||||
if (!newType.isCreature() && !newType.isTribal()) {
|
newType.sanisfySubtypes();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return newType == null ? this : newType;
|
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
|
@Override
|
||||||
public Iterator<String> iterator() {
|
public Iterator<String> iterator() {
|
||||||
final Iterator<CoreType> coreTypeIterator = coreTypes.iterator();
|
final Iterator<CoreType> coreTypeIterator = coreTypes.iterator();
|
||||||
@@ -560,7 +571,64 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
return toString().compareTo(o.toString());
|
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()) {
|
for (final String t : ctOther.getSubtypes()) {
|
||||||
if (hasSubtype(t)) {
|
if (hasSubtype(t)) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ public interface CardTypeView extends Iterable<String>, Serializable {
|
|||||||
boolean hasSupertype(Supertype supertype);
|
boolean hasSupertype(Supertype supertype);
|
||||||
boolean hasSubtype(String subtype);
|
boolean hasSubtype(String subtype);
|
||||||
boolean hasCreatureType(String creatureType);
|
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 isPermanent();
|
||||||
boolean isCreature();
|
boolean isCreature();
|
||||||
boolean isPlaneswalker();
|
boolean isPlaneswalker();
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import forge.util.collect.FCollectionView;
|
|||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -1179,9 +1180,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("FaceDownAddType")) {
|
if (sa.hasParam("FaceDownAddType")) {
|
||||||
for (String type : sa.getParam("FaceDownAddType").split(",")) {
|
c.addType(Arrays.asList(sa.getParam("FaceDownAddType").split(" & ")));
|
||||||
c.addType(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness")
|
if (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness")
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import forge.ImageKeys;
|
|||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.*;
|
import forge.card.*;
|
||||||
import forge.card.CardDb.SetPreference;
|
import forge.card.CardDb.SetPreference;
|
||||||
import forge.card.CardType.CoreType;
|
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostParser;
|
import forge.card.mana.ManaCostParser;
|
||||||
import forge.game.*;
|
import forge.game.*;
|
||||||
@@ -3098,6 +3097,10 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
currentState.addType(type0);
|
currentState.addType(type0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void addType(final Iterable<String> type0) {
|
||||||
|
currentState.addType(type0);
|
||||||
|
}
|
||||||
|
|
||||||
public final void removeType(final CardType.Supertype st) {
|
public final void removeType(final CardType.Supertype st) {
|
||||||
currentState.removeType(st);
|
currentState.removeType(st);
|
||||||
}
|
}
|
||||||
@@ -4601,84 +4604,34 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
if (c1 == null) {
|
if (c1 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return getType().sharesCreaturetypeWith(c1.getType());
|
||||||
for (final String type : getType().getCreatureTypes()) {
|
|
||||||
if (type.equals("AllCreatureTypes") && c1.hasACreatureType()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (c1.getType().hasCreatureType(type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean sharesLandTypeWith(final Card c1) {
|
public final boolean sharesLandTypeWith(final Card c1) {
|
||||||
if (c1 == null) {
|
if (c1 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return getType().sharesLandTypeWith(c1.getType());
|
||||||
for (final String type : getType().getLandTypes()) {
|
|
||||||
if (c1.getType().hasSubtype(type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean sharesPermanentTypeWith(final Card c1) {
|
public final boolean sharesPermanentTypeWith(final Card c1) {
|
||||||
if (c1 == null) {
|
if (c1 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return getType().sharesPermanentTypeWith(c1.getType());
|
||||||
for (final CoreType type : getType().getCoreTypes()) {
|
|
||||||
if (type.isPermanent && c1.getType().hasType(type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean sharesCardTypeWith(final Card c1) {
|
public final boolean sharesCardTypeWith(final Card c1) {
|
||||||
for (final CoreType type : getType().getCoreTypes()) {
|
if (c1 == null) {
|
||||||
if (c1.getType().hasType(type)) {
|
return false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return getType().sharesCardTypeWith(c1.getType());
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean sharesTypeWith(final Card c1) {
|
|
||||||
for (final String type : getType()) {
|
|
||||||
if (c1.getType().hasStringType(type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean sharesControllerWith(final Card c1) {
|
public final boolean sharesControllerWith(final Card c1) {
|
||||||
return c1 != null && getController().equals(c1.getController());
|
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() {
|
public final boolean hasABasicLandType() {
|
||||||
for (final String type : getType().getSubtypes()) {
|
for (final String type : getType().getSubtypes()) {
|
||||||
if (forge.card.CardType.isABasicLandType(type)) {
|
if (forge.card.CardType.isABasicLandType(type)) {
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ public class CardFactory {
|
|||||||
String shortColors = "";
|
String shortColors = "";
|
||||||
|
|
||||||
if (sa.hasParam("AddTypes")) {
|
if (sa.hasParam("AddTypes")) {
|
||||||
types.addAll(Arrays.asList(sa.getParam("AddTypes").split(",")));
|
types.addAll(Arrays.asList(sa.getParam("AddTypes").split(" & ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("AddKeywords")) {
|
if (sa.hasParam("AddKeywords")) {
|
||||||
@@ -654,9 +654,7 @@ public class CardFactory {
|
|||||||
state.removeType(CardType.Supertype.Legendary);
|
state.removeType(CardType.Supertype.Legendary);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final String type : types) {
|
state.addType(types);
|
||||||
state.addType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (creatureTypes != null) {
|
if (creatureTypes != null) {
|
||||||
state.setCreatureTypes(creatureTypes);
|
state.setCreatureTypes(creatureTypes);
|
||||||
@@ -795,7 +793,7 @@ public class CardFactory {
|
|||||||
if (sa.hasParam("SetCreatureTypes")) {
|
if (sa.hasParam("SetCreatureTypes")) {
|
||||||
// currently only Changeling and similar should be affected by that
|
// currently only Changeling and similar should be affected by that
|
||||||
// other cards using AddType$ ChosenType should not
|
// 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);
|
state.removeStaticAbility(sta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1116,7 +1116,7 @@ public class CardFactoryUtil {
|
|||||||
for (Card card : cards) {
|
for (Card card : cards) {
|
||||||
Iterables.addAll(creatTypes, card.getType().getCreatureTypes());
|
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);
|
return doXMath(n, m, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1198,7 +1198,7 @@ public class CardFactoryUtil {
|
|||||||
// Figure out how to count each class separately.
|
// Figure out how to count each class separately.
|
||||||
for (Card card : adventurers) {
|
for (Card card : adventurers) {
|
||||||
Set<String> creatureTypes = card.getType().getCreatureTypes();
|
Set<String> creatureTypes = card.getType().getCreatureTypes();
|
||||||
boolean anyType = creatureTypes.contains("AllCreatureTypes");
|
boolean anyType = creatureTypes.contains(CardType.AllCreatureTypes);
|
||||||
creatureTypes.retainAll(partyTypes);
|
creatureTypes.retainAll(partyTypes);
|
||||||
|
|
||||||
if (anyType || creatureTypes.size() == 4) {
|
if (anyType || creatureTypes.size() == 4) {
|
||||||
@@ -1997,7 +1997,7 @@ public class CardFactoryUtil {
|
|||||||
// Remove Duplicated types
|
// Remove Duplicated types
|
||||||
final Set<String> creatureTypes = c.getType().getCreatureTypes();
|
final Set<String> creatureTypes = c.getType().getCreatureTypes();
|
||||||
for (String creatureType : creatureTypes) {
|
for (String creatureType : creatureTypes) {
|
||||||
if (creatureType.equals("AllCreatureTypes")) {
|
if (creatureType.equals(CardType.AllCreatureTypes)) {
|
||||||
allCreatureType++;
|
allCreatureType++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ public class CardState extends GameObject {
|
|||||||
view.updateType(this);
|
view.updateType(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public final void addType(Iterable<String> type0) {
|
||||||
|
if (type.addAll(type0)) {
|
||||||
|
view.updateType(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
public final void setType(final CardType type0) {
|
public final void setType(final CardType type0) {
|
||||||
if (type0 == type) {
|
if (type0 == type) {
|
||||||
// Logic below would incorrectly clear the type if it's the same object.
|
// 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) {
|
public final boolean hasProwl(final String type) {
|
||||||
if (prowl.contains("AllCreatureTypes")) {
|
if (prowl.contains(CardType.AllCreatureTypes)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return prowl.contains(type);
|
return prowl.contains(type);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:2 U
|
|||||||
Types:Creature Shapeshifter Rogue
|
Types:Creature Shapeshifter Rogue
|
||||||
PT:0/0
|
PT:0/0
|
||||||
K:ETBReplacement:Copy:DBCopy:Optional
|
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
|
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.
|
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
|
Types:Legendary Planeswalker Tezzeret
|
||||||
A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 1 | Defined$ You | SpellDescription$ Draw a card.
|
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$ 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
|
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.
|
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.achievement.AchievementCollection;
|
||||||
import forge.ai.GameState;
|
import forge.ai.GameState;
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.card.CardDb;
|
import forge.card.*;
|
||||||
import forge.card.CardType;
|
|
||||||
import forge.card.ColorSet;
|
|
||||||
import forge.card.ICardFace;
|
|
||||||
import forge.card.MagicColor;
|
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.control.FControlGamePlayback;
|
import forge.control.FControlGamePlayback;
|
||||||
@@ -39,26 +35,11 @@ import forge.deck.CardPool;
|
|||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
import forge.events.UiEventNextGameDecision;
|
import forge.events.UiEventNextGameDecision;
|
||||||
import forge.game.Game;
|
import forge.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.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.*;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.token.TokenInfo;
|
||||||
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.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
import forge.game.combat.CombatUtil;
|
import forge.game.combat.CombatUtil;
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
@@ -69,20 +50,10 @@ import forge.game.keyword.Keyword;
|
|||||||
import forge.game.keyword.KeywordInterface;
|
import forge.game.keyword.KeywordInterface;
|
||||||
import forge.game.mana.Mana;
|
import forge.game.mana.Mana;
|
||||||
import forge.game.mana.ManaConversionMatrix;
|
import forge.game.mana.ManaConversionMatrix;
|
||||||
import forge.game.player.DelayedReveal;
|
import forge.game.player.*;
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.player.PlayerActionConfirmMode;
|
|
||||||
import forge.game.player.PlayerController;
|
|
||||||
import forge.game.player.PlayerView;
|
|
||||||
import forge.game.replacement.ReplacementEffect;
|
import forge.game.replacement.ReplacementEffect;
|
||||||
import forge.game.replacement.ReplacementLayer;
|
import forge.game.replacement.ReplacementLayer;
|
||||||
import forge.game.spellability.AbilityManaPart;
|
import forge.game.spellability.*;
|
||||||
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.trigger.Trigger;
|
import forge.game.trigger.Trigger;
|
||||||
import forge.game.trigger.WrappedAbility;
|
import forge.game.trigger.WrappedAbility;
|
||||||
import forge.game.zone.MagicStack;
|
import forge.game.zone.MagicStack;
|
||||||
@@ -96,19 +67,7 @@ import forge.interfaces.IMacroSystem;
|
|||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.match.NextGameDecision;
|
import forge.match.NextGameDecision;
|
||||||
import forge.match.input.Input;
|
import forge.match.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.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
@@ -1157,17 +1116,20 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
private void sortCreatureTypes(List<String> types) {
|
private void sortCreatureTypes(List<String> types) {
|
||||||
// build map of creature types in player's main deck against the
|
// build map of creature types in player's main deck against the
|
||||||
// occurrences of each
|
// occurrences of each
|
||||||
CardCollection pool = CardLists.filterControlledBy(game.getCardsInGame(), player);
|
|
||||||
Map<String, Integer> typesInDeck = Maps.newHashMap();
|
Map<String, Integer> typesInDeck = Maps.newHashMap();
|
||||||
|
|
||||||
// TODO JAVA 8 use getOrDefault
|
// TODO JAVA 8 use getOrDefault
|
||||||
for (Card c : pool) {
|
for (Card c : player.getAllCards()) {
|
||||||
|
|
||||||
// Changeling are all creature types, they are not interesting for
|
// Changeling are all creature types, they are not interesting for
|
||||||
// counting creature types
|
// counting creature types
|
||||||
if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) {
|
if (c.hasStartOfKeyword(Keyword.CHANGELING.toString())) {
|
||||||
continue;
|
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
|
// ignore cards that does enter the battlefield as clones
|
||||||
boolean isClone = false;
|
boolean isClone = false;
|
||||||
for (ReplacementEffect re : c.getReplacementEffects()) {
|
for (ReplacementEffect re : c.getReplacementEffects()) {
|
||||||
@@ -1180,8 +1142,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> cardCreatureTypes = c.getType().getCreatureTypes();
|
for (String type : c.getType().getCreatureTypes()) {
|
||||||
for (String type : cardCreatureTypes) {
|
|
||||||
Integer count = typesInDeck.get(type);
|
Integer count = typesInDeck.get(type);
|
||||||
if (count == null) {
|
if (count == null) {
|
||||||
count = 0;
|
count = 0;
|
||||||
@@ -1193,54 +1154,31 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
if (sa.getApi() != ApiType.Token) {
|
if (sa.getApi() != ApiType.Token) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sa.hasParam("TokenTypes")) {
|
if (sa.hasParam("TokenScript")) {
|
||||||
for (String var : sa.getParam("TokenTypes").split(",")) {
|
Card protoType = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa);
|
||||||
if (!CardType.isACreatureType(var)) {
|
for (String type : protoType.getType().getCreatureTypes()) {
|
||||||
continue;
|
Integer count = typesInDeck.get(type);
|
||||||
}
|
|
||||||
Integer count = typesInDeck.get(var);
|
|
||||||
if (count == null) {
|
if (count == null) {
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
typesInDeck.put(var, count + 1);
|
typesInDeck.put(type, count + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// same for Trigger that does make Tokens
|
// same for Trigger that does make Tokens
|
||||||
for (Trigger t : c.getTriggers()) {
|
for (Trigger t : c.getTriggers()) {
|
||||||
SpellAbility sa = t.getOverridingAbility();
|
SpellAbility sa = t.ensureAbility();
|
||||||
String sTokenTypes = null;
|
|
||||||
if (sa != null) {
|
if (sa != null) {
|
||||||
if (sa.getApi() != ApiType.Token || !sa.hasParam("TokenTypes")) {
|
if (sa.hasParam("TokenScript")) {
|
||||||
continue;
|
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<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 (count == null) {
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
typesInDeck.put(var, count + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// special rule for Fabricate and Servo
|
// special rule for Fabricate and Servo
|
||||||
@@ -3086,8 +3024,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
public void handleLandPlayed(Card land, Zone zone) {
|
public void handleLandPlayed(Card land, Zone zone) {
|
||||||
IGuiGame guiGame = getGui();
|
IGuiGame guiGame = getGui();
|
||||||
guiGame.handleLandPlayed(land,zone);
|
guiGame.handleLandPlayed(land,zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user