Merge branch 'master' into newmaster2

This commit is contained in:
Anthony Calosa
2024-06-06 18:48:36 +08:00
8 changed files with 66 additions and 8 deletions

View File

@@ -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) {

View File

@@ -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()) {

View File

@@ -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)) {

View File

@@ -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;
}
};
}
}

View File

@@ -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),

View File

@@ -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.

View File

@@ -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

View File

@@ -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."