mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58: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);
|
||||
|
||||
} // CardReader()
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (this.tokenReader != null){
|
||||
if (this.tokenReader != null) {
|
||||
final Map<String, CardRules> tokens = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (CardRules card : this.tokenReader.loadCards()) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.card.mana.IParserManaCost;
|
||||
@@ -385,6 +386,12 @@ public final class CardRules implements ICardCharacteristics {
|
||||
private int deltaHand;
|
||||
private int deltaLife;
|
||||
|
||||
private List<String> tokens;
|
||||
|
||||
public List<String> getTokens() {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public int getHand() { return deltaHand; }
|
||||
public int getLife() { return deltaLife; }
|
||||
public void setVanguardProperties(String pt) {
|
||||
@@ -420,6 +427,8 @@ public final class CardRules implements ICardCharacteristics {
|
||||
private String handLife = null;
|
||||
private String normalizedName = "";
|
||||
|
||||
private List<String> tokens = Lists.newArrayList();
|
||||
|
||||
// fields to build CardAiHints
|
||||
private boolean removedFromAIDecks = false;
|
||||
private boolean removedFromRandomDecks = false;
|
||||
@@ -453,6 +462,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
this.meldWith = "";
|
||||
this.partnerWith = "";
|
||||
this.normalizedName = "";
|
||||
this.tokens = Lists.newArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,6 +484,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
result.setNormalizedName(this.normalizedName);
|
||||
result.meldWith = this.meldWith;
|
||||
result.partnerWith = this.partnerWith;
|
||||
result.tokens = tokens.isEmpty() ? Collections.emptyList() : tokens;
|
||||
if (StringUtils.isNotBlank(handLife))
|
||||
result.setVanguardProperties(handLife);
|
||||
return result;
|
||||
@@ -506,6 +517,18 @@ public final class CardRules implements ICardCharacteristics {
|
||||
String key = colonPos > 0 ? line.substring(0, colonPos) : line;
|
||||
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)) {
|
||||
case 'A':
|
||||
if ("A".equals(key)) {
|
||||
|
||||
@@ -12,7 +12,9 @@ import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.StaticData;
|
||||
import forge.item.PaperCard;
|
||||
import forge.token.TokenDb;
|
||||
import forge.util.PredicateString.StringOp;
|
||||
import forge.util.collect.FCollection;
|
||||
|
||||
@@ -27,6 +29,8 @@ public class DeckHints {
|
||||
* Enum of types of DeckHints.
|
||||
*/
|
||||
public enum Type {
|
||||
/** extra logic */
|
||||
MODIFIER,
|
||||
/** The Ability */
|
||||
ABILITY,
|
||||
/** The Color. */
|
||||
@@ -42,7 +46,8 @@ public class DeckHints {
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -56,6 +61,12 @@ public class DeckHints {
|
||||
for (String piece : pieces) {
|
||||
Pair<Type, String> pair = parseHint(piece.trim());
|
||||
if (pair != null) {
|
||||
if (pair.getKey() == Type.MODIFIER) {
|
||||
if (pair.getRight().contains("NoToken")) {
|
||||
tokens = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (filters == null) {
|
||||
filters = new ArrayList<>();
|
||||
}
|
||||
@@ -196,7 +207,32 @@ public class DeckHints {
|
||||
}
|
||||
|
||||
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),
|
||||
ChosenSector(TrackableTypes.StringType),
|
||||
Sector(TrackableTypes.StringListType),
|
||||
DraftAction(TrackableTypes.StringType),
|
||||
DraftAction(TrackableTypes.StringListType),
|
||||
ClassLevel(TrackableTypes.IntegerType),
|
||||
RingLevel(TrackableTypes.IntegerType),
|
||||
CurrentRoom(TrackableTypes.StringType),
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 U U
|
||||
Types:Legendary Creature Leviathan Crab
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Ecological Appreciation
|
||||
ManaCost:X 2 G
|
||||
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: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
|
||||
|
||||
@@ -9,6 +9,6 @@ T:Mode$ SpellCast | ValidCard$ Dragon.wasCastFromYourGraveyard | ValidActivating
|
||||
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:TrigExile:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Exile
|
||||
DeckNeeds:Type$Dragon
|
||||
DeckNeeds:Type$Dragon & Modifier$NoToken
|
||||
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."
|
||||
|
||||
Reference in New Issue
Block a user