mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'master' into newmaster2
This commit is contained in:
@@ -101,7 +101,6 @@ public class CardStorageReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.charset = Charset.forName(CardStorageReader.DEFAULT_CHARSET_NAME);
|
this.charset = Charset.forName(CardStorageReader.DEFAULT_CHARSET_NAME);
|
||||||
|
|
||||||
} // CardReader()
|
} // CardReader()
|
||||||
|
|
||||||
private List<CardRules> loadCardsInRange(final List<File> files, final int from, final int to) {
|
private List<CardRules> loadCardsInRange(final List<File> files, final int from, final int to) {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public class StaticData {
|
|||||||
variantCards.initialize(false, false, enableUnknownCards);
|
variantCards.initialize(false, false, enableUnknownCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tokenReader != null){
|
if (this.tokenReader != null) {
|
||||||
final Map<String, CardRules> tokens = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
final Map<String, CardRules> tokens = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
for (CardRules card : this.tokenReader.loadCards()) {
|
for (CardRules card : this.tokenReader.loadCards()) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.util.*;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import forge.card.mana.IParserManaCost;
|
import forge.card.mana.IParserManaCost;
|
||||||
@@ -385,6 +386,12 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
private int deltaHand;
|
private int deltaHand;
|
||||||
private int deltaLife;
|
private int deltaLife;
|
||||||
|
|
||||||
|
private List<String> tokens;
|
||||||
|
|
||||||
|
public List<String> getTokens() {
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
public int getHand() { return deltaHand; }
|
public int getHand() { return deltaHand; }
|
||||||
public int getLife() { return deltaLife; }
|
public int getLife() { return deltaLife; }
|
||||||
public void setVanguardProperties(String pt) {
|
public void setVanguardProperties(String pt) {
|
||||||
@@ -420,6 +427,8 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
private String handLife = null;
|
private String handLife = null;
|
||||||
private String normalizedName = "";
|
private String normalizedName = "";
|
||||||
|
|
||||||
|
private List<String> tokens = Lists.newArrayList();
|
||||||
|
|
||||||
// fields to build CardAiHints
|
// fields to build CardAiHints
|
||||||
private boolean removedFromAIDecks = false;
|
private boolean removedFromAIDecks = false;
|
||||||
private boolean removedFromRandomDecks = false;
|
private boolean removedFromRandomDecks = false;
|
||||||
@@ -453,6 +462,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
this.meldWith = "";
|
this.meldWith = "";
|
||||||
this.partnerWith = "";
|
this.partnerWith = "";
|
||||||
this.normalizedName = "";
|
this.normalizedName = "";
|
||||||
|
this.tokens = Lists.newArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -474,6 +484,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
result.setNormalizedName(this.normalizedName);
|
result.setNormalizedName(this.normalizedName);
|
||||||
result.meldWith = this.meldWith;
|
result.meldWith = this.meldWith;
|
||||||
result.partnerWith = this.partnerWith;
|
result.partnerWith = this.partnerWith;
|
||||||
|
result.tokens = tokens.isEmpty() ? Collections.emptyList() : tokens;
|
||||||
if (StringUtils.isNotBlank(handLife))
|
if (StringUtils.isNotBlank(handLife))
|
||||||
result.setVanguardProperties(handLife);
|
result.setVanguardProperties(handLife);
|
||||||
return result;
|
return result;
|
||||||
@@ -506,6 +517,18 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
String key = colonPos > 0 ? line.substring(0, colonPos) : line;
|
String key = colonPos > 0 ? line.substring(0, colonPos) : line;
|
||||||
String value = colonPos > 0 ? line.substring(1+colonPos).trim() : null;
|
String value = colonPos > 0 ? line.substring(1+colonPos).trim() : null;
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
int tokIdx = value.indexOf("TokenScript$");
|
||||||
|
if (tokIdx > 0) {
|
||||||
|
String tokenParam = value.substring(tokIdx + 12).trim();
|
||||||
|
int endIdx = tokenParam.indexOf("|");
|
||||||
|
if (endIdx > 0) {
|
||||||
|
tokenParam = tokenParam.substring(0, endIdx).trim();
|
||||||
|
}
|
||||||
|
this.tokens.addAll(Arrays.asList(tokenParam.split(",")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (key.charAt(0)) {
|
switch (key.charAt(0)) {
|
||||||
case 'A':
|
case 'A':
|
||||||
if ("A".equals(key)) {
|
if ("A".equals(key)) {
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import com.google.common.base.Predicate;
|
|||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.StaticData;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
|
import forge.token.TokenDb;
|
||||||
import forge.util.PredicateString.StringOp;
|
import forge.util.PredicateString.StringOp;
|
||||||
import forge.util.collect.FCollection;
|
import forge.util.collect.FCollection;
|
||||||
|
|
||||||
@@ -27,6 +29,8 @@ public class DeckHints {
|
|||||||
* Enum of types of DeckHints.
|
* Enum of types of DeckHints.
|
||||||
*/
|
*/
|
||||||
public enum Type {
|
public enum Type {
|
||||||
|
/** extra logic */
|
||||||
|
MODIFIER,
|
||||||
/** The Ability */
|
/** The Ability */
|
||||||
ABILITY,
|
ABILITY,
|
||||||
/** The Color. */
|
/** The Color. */
|
||||||
@@ -42,7 +46,8 @@ public class DeckHints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = false;
|
private boolean valid = false;
|
||||||
public List<Pair<Type, String>> filters = null;
|
private boolean tokens = true;
|
||||||
|
private List<Pair<Type, String>> filters = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a DeckHints from the SVar string.
|
* Construct a DeckHints from the SVar string.
|
||||||
@@ -56,6 +61,12 @@ public class DeckHints {
|
|||||||
for (String piece : pieces) {
|
for (String piece : pieces) {
|
||||||
Pair<Type, String> pair = parseHint(piece.trim());
|
Pair<Type, String> pair = parseHint(piece.trim());
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
|
if (pair.getKey() == Type.MODIFIER) {
|
||||||
|
if (pair.getRight().contains("NoToken")) {
|
||||||
|
tokens = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (filters == null) {
|
if (filters == null) {
|
||||||
filters = new ArrayList<>();
|
filters = new ArrayList<>();
|
||||||
}
|
}
|
||||||
@@ -196,7 +207,32 @@ public class DeckHints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<PaperCard> getMatchingItems(Iterable<PaperCard> source, Predicate<CardRules> predicate, Function<PaperCard, CardRules> fn) {
|
private Iterable<PaperCard> getMatchingItems(Iterable<PaperCard> source, Predicate<CardRules> predicate, Function<PaperCard, CardRules> fn) {
|
||||||
return Iterables.filter(source, Predicates.compose(predicate, fn));
|
// TODO should token generators be counted differently for their potential?
|
||||||
|
return Iterables.filter(source, Predicates.compose(tokens ? rulesWithTokens(predicate) : predicate, fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Predicate<CardRules> rulesWithTokens(final Predicate<CardRules> predicate) {
|
||||||
|
final TokenDb tdb;
|
||||||
|
if (StaticData.instance() != null) {
|
||||||
|
// not available on some test setups
|
||||||
|
tdb = StaticData.instance().getAllTokens();
|
||||||
|
} else {
|
||||||
|
tdb = null;
|
||||||
|
}
|
||||||
|
return new Predicate<CardRules>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final CardRules card) {
|
||||||
|
if (predicate.apply(card)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (String tok : card.getTokens()) {
|
||||||
|
if (tdb != null && tdb.containsRule(tok) && predicate.apply(tdb.getToken(tok).getRules())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public enum TrackableProperty {
|
|||||||
ChosenMode(TrackableTypes.StringType),
|
ChosenMode(TrackableTypes.StringType),
|
||||||
ChosenSector(TrackableTypes.StringType),
|
ChosenSector(TrackableTypes.StringType),
|
||||||
Sector(TrackableTypes.StringListType),
|
Sector(TrackableTypes.StringListType),
|
||||||
DraftAction(TrackableTypes.StringType),
|
DraftAction(TrackableTypes.StringListType),
|
||||||
ClassLevel(TrackableTypes.IntegerType),
|
ClassLevel(TrackableTypes.IntegerType),
|
||||||
RingLevel(TrackableTypes.IntegerType),
|
RingLevel(TrackableTypes.IntegerType),
|
||||||
CurrentRoom(TrackableTypes.StringType),
|
CurrentRoom(TrackableTypes.StringType),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:2 U U
|
|||||||
Types:Legendary Creature Leviathan Crab
|
Types:Legendary Creature Leviathan Crab
|
||||||
PT:0/17
|
PT:0/17
|
||||||
S:Mode$ RaiseCost | ValidTarget$ Card.Self | Activator$ Opponent | Type$ Spell | Amount$ 2 | Description$ Spells your opponents cast that target CARDNAME cost {2} more to cast.
|
S:Mode$ RaiseCost | ValidTarget$ Card.Self | Activator$ Opponent | Type$ Spell | Amount$ 2 | Description$ Spells your opponents cast that target CARDNAME cost {2} more to cast.
|
||||||
A:AB$ Pump | Cost$ 3 | NumAtt$ +X | NumDef$ -X | SpellDescription$ CARDNAME gets +X/-X until end of turn, where X is the number of Islands you control.
|
A:AB$ Pump | Cost$ 3 | NumAtt$ +X | NumDef$ -X | SpellDescription$ NICKNAME gets +X/-X until end of turn, where X is the number of Islands you control.
|
||||||
SVar:X:Count$Valid Island.YouCtrl
|
SVar:X:Count$Valid Island.YouCtrl
|
||||||
DeckHints:Type$Island
|
DeckHints:Type$Island
|
||||||
Oracle:Spells your opponents cast that target Charix, the Raging Isle cost {2} more to cast.\n{3}: Charix gets +X/-X until end of turn, where X is the number of Islands you control.
|
Oracle:Spells your opponents cast that target Charix, the Raging Isle cost {2} more to cast.\n{3}: Charix gets +X/-X until end of turn, where X is the number of Islands you control.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Ecological Appreciation
|
Name:Ecological Appreciation
|
||||||
ManaCost:X 2 G
|
ManaCost:X 2 G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ ChangeZone | Origin$ Library,Graveyard | Destination$ Library | ChangeType$ Creature.cmcLEX | ChangeNum$ 4 | DifferentNames$ True | Shuffle$ False | RememberChanged$ True | Reveal$ True | AILogic$ Intuition | SubAbility$ DBChangeZone1 | StackDescription$ SpellDescription | SpellDescription$ Search your library and graveyard for up to four creature cards with different names that each have mana value X or less and reveal them.
|
A:SP$ ChangeZone | Origin$ Library,Graveyard | Destination$ Library | ChangeType$ Creature.cmcLEX | ChangeNum$ 4 | DifferentNames$ True | Shuffle$ False | RememberChanged$ True | Reveal$ True | SubAbility$ DBChangeZone1 | StackDescription$ SpellDescription | SpellDescription$ Search your library and graveyard for up to four creature cards with different names that each have mana value X or less and reveal them.
|
||||||
SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Library | ChangeType$ Card.IsRemembered | Chooser$ Opponent | ChangeNum$ 2 | Mandatory$ True | NoLooking$ True | ForgetChanged$ True | Shuffle$ False | SelectPrompt$ Select two cards to shuffle into the library | SubAbility$ DBChangeZone2 | StackDescription$ SpellDescription | SpellDescription$ An opponent chooses two of those cards. Shuffle the chosen cards into your library
|
SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Library | ChangeType$ Card.IsRemembered | Chooser$ Opponent | ChangeNum$ 2 | Mandatory$ True | NoLooking$ True | ForgetChanged$ True | Shuffle$ False | SelectPrompt$ Select two cards to shuffle into the library | SubAbility$ DBChangeZone2 | StackDescription$ SpellDescription | SpellDescription$ An opponent chooses two of those cards. Shuffle the chosen cards into your library
|
||||||
SVar:DBChangeZone2:DB$ ChangeZoneAll | Origin$ Library | Destination$ Battlefield | ChangeType$ Card.IsRemembered | Shuffle$ True | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ and put the rest onto the battlefield.
|
SVar:DBChangeZone2:DB$ ChangeZoneAll | Origin$ Library | Destination$ Battlefield | ChangeType$ Card.IsRemembered | Shuffle$ True | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ and put the rest onto the battlefield.
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBExileSelf
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBExileSelf
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ T:Mode$ SpellCast | ValidCard$ Dragon.wasCastFromYourGraveyard | ValidActivating
|
|||||||
SVar:DBAnimate:DB$ Animate | Defined$ TriggeredCard | Duration$ Permanent | Triggers$ TrigDieExile
|
SVar:DBAnimate:DB$ Animate | Defined$ TriggeredCard | Duration$ Permanent | Triggers$ TrigDieExile
|
||||||
SVar:TrigDieExile:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When this creature dies, exile it.
|
SVar:TrigDieExile:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When this creature dies, exile it.
|
||||||
SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Exile
|
SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Exile
|
||||||
DeckNeeds:Type$Dragon
|
DeckNeeds:Type$Dragon & Modifier$NoToken
|
||||||
DeckHas:Ability$Graveyard
|
DeckHas:Ability$Graveyard
|
||||||
Oracle:Menace\n{T}: Add two mana in any combination of colors. Spend this mana only to cast Dragon creature spells.\nOnce during each of your turns, you may cast a Dragon creature spell from your graveyard.\nWhenever you cast a Dragon creature spell from your graveyard, it gains "When this creature dies, exile it."
|
Oracle:Menace\n{T}: Add two mana in any combination of colors. Spend this mana only to cast Dragon creature spells.\nOnce during each of your turns, you may cast a Dragon creature spell from your graveyard.\nWhenever you cast a Dragon creature spell from your graveyard, it gains "When this creature dies, exile it."
|
||||||
|
|||||||
Reference in New Issue
Block a user