mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
*Added Color Identity checks
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
Name:Bosh, Iron Golem
|
Name:Bosh, Iron Golem
|
||||||
ManaCost:8
|
ManaCost:8
|
||||||
|
ColorIdentity:Red
|
||||||
Types:Legendary Artifact Creature Golem
|
Types:Legendary Artifact Creature Golem
|
||||||
PT:6/7
|
PT:6/7
|
||||||
K:Trample
|
K:Trample
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
Name:Memnarch
|
Name:Memnarch
|
||||||
ManaCost:7
|
ManaCost:7
|
||||||
|
ColorIdentity:Blue
|
||||||
Types:Legendary Artifact Creature Wizard
|
Types:Legendary Artifact Creature Wizard
|
||||||
PT:4/5
|
PT:4/5
|
||||||
A:AB$ Animate | Cost$ 1 U U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | Types$ Artifact | Permanent$ True | SpellDescription$ Target permanent becomes an artifact in addition to its other types. (This effect lasts indefinitely.)
|
A:AB$ Animate | Cost$ 1 U U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | Types$ Artifact | Permanent$ True | SpellDescription$ Target permanent becomes an artifact in addition to its other types. (This effect lasts indefinitely.)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
Name:Rhys the Exiled
|
Name:Rhys the Exiled
|
||||||
ManaCost:2 G
|
ManaCost:2 G
|
||||||
|
ColorIdentity:Green,Black
|
||||||
Types:Legendary Creature Elf Warrior
|
Types:Legendary Creature Elf Warrior
|
||||||
PT:3/2
|
PT:3/2
|
||||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ Whenever CARDNAME attacks, you gain 1 life for each Elf you control.
|
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ Whenever CARDNAME attacks, you gain 1 life for each Elf you control.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
Name:Thelon of Havenwood
|
Name:Thelon of Havenwood
|
||||||
ManaCost:G G
|
ManaCost:G G
|
||||||
|
ColorIdentity:Green,Black
|
||||||
Types:Legendary Creature Elf Druid
|
Types:Legendary Creature Elf Druid
|
||||||
PT:2/2
|
PT:2/2
|
||||||
S:Mode$ Continuous | Affected$ Creature.Fungus | AffectedZone$ Battlefield | AddPower$ AffectedX | AddToughness$ AffectedX | Description$ Each Fungus creature gets +1/+1 for each spore counter on it.
|
S:Mode$ Continuous | Affected$ Creature.Fungus | AffectedZone$ Battlefield | AddPower$ AffectedX | AddToughness$ AffectedX | Description$ Each Fungus creature gets +1/+1 for each spore counter on it.
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ final class CardFace implements ICardFace {
|
|||||||
private CardType type = null;
|
private CardType type = null;
|
||||||
private ManaCost manaCost = ManaCost.NO_COST;
|
private ManaCost manaCost = ManaCost.NO_COST;
|
||||||
private ColorSet color = null;
|
private ColorSet color = null;
|
||||||
|
private ColorSet colorIdentity = null;
|
||||||
|
|
||||||
private String oracleText = null;
|
private String oracleText = null;
|
||||||
private int iPower = -1;
|
private int iPower = -1;
|
||||||
@@ -59,6 +60,14 @@ final class CardFace implements ICardFace {
|
|||||||
@Override public ManaCost getManaCost() { return this.manaCost; }
|
@Override public ManaCost getManaCost() { return this.manaCost; }
|
||||||
@Override public ColorSet getColor() { return this.color; }
|
@Override public ColorSet getColor() { return this.color; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColorSet getColorIdentity() {
|
||||||
|
if(this.colorIdentity != null)
|
||||||
|
return this.colorIdentity;
|
||||||
|
|
||||||
|
return this.color;
|
||||||
|
}
|
||||||
|
|
||||||
// these are raw and unparsed used for Card creation
|
// these are raw and unparsed used for Card creation
|
||||||
@Override public Iterable<String> getKeywords() { return keywords; }
|
@Override public Iterable<String> getKeywords() { return keywords; }
|
||||||
@Override public Iterable<String> getAbilities() { return abilities; }
|
@Override public Iterable<String> getAbilities() { return abilities; }
|
||||||
@@ -77,6 +86,7 @@ final class CardFace implements ICardFace {
|
|||||||
public void setType(CardType type0) { this.type = type0; }
|
public void setType(CardType type0) { this.type = type0; }
|
||||||
public void setManaCost(ManaCost manaCost0) { this.manaCost = manaCost0; }
|
public void setManaCost(ManaCost manaCost0) { this.manaCost = manaCost0; }
|
||||||
public void setColor(ColorSet color0) { this.color = color0; }
|
public void setColor(ColorSet color0) { this.color = color0; }
|
||||||
|
public void setColorIdentity(ColorSet color0) { this.colorIdentity = color0; }
|
||||||
public void setOracleText(String text) { this.oracleText = text; }
|
public void setOracleText(String text) { this.oracleText = text; }
|
||||||
public void setInitialLoyalty(int value) { this.initialLoyalty = value; }
|
public void setInitialLoyalty(int value) { this.initialLoyalty = value; }
|
||||||
|
|
||||||
@@ -114,6 +124,4 @@ final class CardFace implements ICardFace {
|
|||||||
if ( variables == null ) variables = emptyMap;
|
if ( variables == null ) variables = emptyMap;
|
||||||
if ( null == nonAbilityText ) nonAbilityText = "";
|
if ( null == nonAbilityText ) nonAbilityText = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,4 +177,17 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
public final List<String> getAbilities() {
|
public final List<String> getAbilities() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColorSet getColorIdentity() {
|
||||||
|
if(this.otherPart != null)
|
||||||
|
{
|
||||||
|
return ColorSet.fromMask(mainPart.getColorIdentity().getColor() | otherPart.getColorIdentity().getColor());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mainPart.getColorIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -456,6 +456,9 @@ public final class CardRulesPredicates {
|
|||||||
public static final Predicate<CardRules> IS_CREATURE = CardRulesPredicates
|
public static final Predicate<CardRules> IS_CREATURE = CardRulesPredicates
|
||||||
.coreType(true, CardCoreType.Creature);
|
.coreType(true, CardCoreType.Creature);
|
||||||
|
|
||||||
|
public static final Predicate<CardRules> IS_LEGENDARY = CardRulesPredicates
|
||||||
|
.superType(true, CardSuperType.Legendary);
|
||||||
|
|
||||||
/** The Constant isArtifact. */
|
/** The Constant isArtifact. */
|
||||||
public static final Predicate<CardRules> IS_ARTIFACT = CardRulesPredicates
|
public static final Predicate<CardRules> IS_ARTIFACT = CardRulesPredicates
|
||||||
.coreType(true, CardCoreType.Artifact);
|
.coreType(true, CardCoreType.Artifact);
|
||||||
|
|||||||
@@ -138,6 +138,12 @@ public class CardRulesReader {
|
|||||||
ColorSet newCol = ColorSet.fromNames(value.split(","));
|
ColorSet newCol = ColorSet.fromNames(value.split(","));
|
||||||
this.faces[this.curFace].setColor(newCol);
|
this.faces[this.curFace].setColor(newCol);
|
||||||
}
|
}
|
||||||
|
else if ("ColorIdentity".equals(key)) {
|
||||||
|
// This is forge.card.CardColor not forge.CardColor.
|
||||||
|
// Why do we have two classes with the same name?
|
||||||
|
ColorSet newCol = ColorSet.fromNames(value.split(","));
|
||||||
|
this.faces[this.curFace].setColorIdentity(newCol);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public interface ICardCharacteristics {
|
|||||||
CardType getType();
|
CardType getType();
|
||||||
ManaCost getManaCost();
|
ManaCost getManaCost();
|
||||||
ColorSet getColor();
|
ColorSet getColor();
|
||||||
|
ColorSet getColorIdentity();
|
||||||
|
|
||||||
int getIntPower();
|
int getIntPower();
|
||||||
int getIntToughness();
|
int getIntToughness();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -25,6 +26,7 @@ import org.apache.commons.lang.math.IntRange;
|
|||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardCoreType;
|
import forge.card.CardCoreType;
|
||||||
|
import forge.card.ColorSet;
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
@@ -137,18 +139,47 @@ public enum DeckFormat {
|
|||||||
if (null == cmd || cmd.isEmpty()) {
|
if (null == cmd || cmd.isEmpty()) {
|
||||||
return "is missing a commander";
|
return "is missing a commander";
|
||||||
}
|
}
|
||||||
if (!cmd.get(0).getRules().getType().isLegendary()) {
|
if (!cmd.get(0).getRules().getType().isLegendary()
|
||||||
|
|| !cmd.get(0).getRules().getType().isCreature()) {
|
||||||
return "has a commander that is not a legendary creature";
|
return "has a commander that is not a legendary creature";
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:Enforce color identity
|
ColorSet cmdCI = cmd.get(0).getRules().getColorIdentity();
|
||||||
|
List<CardPrinted> erroneousCI = new ArrayList<CardPrinted>();
|
||||||
|
|
||||||
|
for(Entry<CardPrinted, Integer> cp : deck.get(DeckSection.Main)) {
|
||||||
|
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||||
|
{
|
||||||
|
erroneousCI.add(cp.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Entry<CardPrinted, Integer> cp : deck.get(DeckSection.Sideboard)) {
|
||||||
|
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||||
|
{
|
||||||
|
erroneousCI.add(cp.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(erroneousCI.size() > 0)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder("contains the cards " + System.lineSeparator());
|
||||||
|
|
||||||
|
for(CardPrinted cp : erroneousCI)
|
||||||
|
{
|
||||||
|
sb.append(cp.getName() + ", " + System.lineSeparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(" that do not match the commanders color identity.");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Planechase: //Must contain at least 10 planes/phenomenons, but max 2 phenomenons. Singleton.
|
case Planechase: //Must contain at least 10 planes/phenomenons, but max 2 phenomenons. Singleton.
|
||||||
final CardPool planes = deck.get(DeckSection.Planes);
|
final CardPool planes = deck.get(DeckSection.Planes);
|
||||||
if (planes == null || planes.countAll() < 10) {
|
if (planes == null || planes.countAll() < 10) {
|
||||||
return "should gave at least 10 planes";
|
return "should have at least 10 planes";
|
||||||
}
|
}
|
||||||
int phenoms = 0;
|
int phenoms = 0;
|
||||||
for (Entry<CardPrinted, Integer> cp : planes) {
|
for (Entry<CardPrinted, Integer> cp : planes) {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public final class CEditorConstructed extends ACEditorBase<CardPrinted, Deck> {
|
|||||||
private final ItemPoolView<CardPrinted> avatarPool;
|
private final ItemPoolView<CardPrinted> avatarPool;
|
||||||
private final ItemPoolView<CardPrinted> planePool;
|
private final ItemPoolView<CardPrinted> planePool;
|
||||||
private final ItemPoolView<CardPrinted> schemePool;
|
private final ItemPoolView<CardPrinted> schemePool;
|
||||||
|
private final ItemPoolView<CardPrinted> commanderPool;
|
||||||
|
|
||||||
//=========== Constructor
|
//=========== Constructor
|
||||||
/**
|
/**
|
||||||
@@ -89,6 +90,7 @@ public final class CEditorConstructed extends ACEditorBase<CardPrinted, Deck> {
|
|||||||
avatarPool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_VANGUARD, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
avatarPool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_VANGUARD, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
||||||
planePool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_PLANE_OR_PHENOMENON, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
planePool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_PLANE_OR_PHENOMENON, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
||||||
schemePool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_SCHEME, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
schemePool = ItemPool.createFrom(CardDb.variants().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_SCHEME, CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
||||||
|
commanderPool = ItemPool.createFrom(CardDb.instance().getAllCards(Predicates.compose(Predicates.and(CardRulesPredicates.Presets.IS_CREATURE,CardRulesPredicates.Presets.IS_LEGENDARY), CardPrinted.FN_GET_RULES)),CardPrinted.class);
|
||||||
|
|
||||||
boolean wantUnique = SEditorIO.getPref(EditorPreference.display_unique_only);
|
boolean wantUnique = SEditorIO.getPref(EditorPreference.display_unique_only);
|
||||||
|
|
||||||
@@ -276,6 +278,15 @@ public final class CEditorConstructed extends ACEditorBase<CardPrinted, Deck> {
|
|||||||
title = "Scheme";
|
title = "Scheme";
|
||||||
tabtext = "Card Catalog";
|
tabtext = "Card Catalog";
|
||||||
break;
|
break;
|
||||||
|
case Commander:
|
||||||
|
lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY));
|
||||||
|
this.getTableCatalog().setAvailableColumns(lstCatalogCols);
|
||||||
|
this.getTableCatalog().setDeck(commanderPool,true);
|
||||||
|
this.getTableDeck().setDeck(this.controller.getModel().getOrCreate(DeckSection.Commander));
|
||||||
|
showOptions = false;
|
||||||
|
title = "Commander";
|
||||||
|
tabtext = "Card Catalog";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText(tabtext);
|
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText(tabtext);
|
||||||
|
|||||||
Reference in New Issue
Block a user