Merge remote-tracking branch 'upstream/master' into patch-carddb-performance

This commit is contained in:
leriomaggio
2021-08-26 03:03:25 +01:00
26 changed files with 46 additions and 82 deletions

View File

@@ -716,7 +716,7 @@ public class AiAttackController {
} }
if (attackMax == 0) { if (attackMax == 0) {
// can't attack anymore // can't attack anymore
return; return;
} }

View File

@@ -2704,7 +2704,6 @@ public class ComputerUtil {
for (Trigger trigger : theTriggers) { for (Trigger trigger : theTriggers) {
final Card source = trigger.getHostCard(); final Card source = trigger.getHostCard();
if (!trigger.zonesCheck(game.getZoneOf(source))) { if (!trigger.zonesCheck(game.getZoneOf(source))) {
continue; continue;
} }

View File

@@ -89,7 +89,7 @@ public class ComputerUtilCombat {
return ComputerUtilCombat.canAttackNextTurn(attacker, input); return ComputerUtilCombat.canAttackNextTurn(attacker, input);
} }
}); });
} // canAttackNextTurn(Card) }
/** /**
* <p> * <p>
@@ -176,7 +176,6 @@ public class ComputerUtilCombat {
return n; return n;
} }
// Returns the damage an unblocked attacker would deal // Returns the damage an unblocked attacker would deal
/** /**
* <p> * <p>
@@ -494,7 +493,6 @@ public class ComputerUtilCombat {
final List<Card> attackers = combat.getAttackersOf(ai); final List<Card> attackers = combat.getAttackersOf(ai);
for (final Card attacker : attackers) { for (final Card attacker : attackers) {
final List<Card> blockers = combat.getBlockers(attacker); final List<Card> blockers = combat.getBlockers(attacker);
if (blockers.isEmpty()) { if (blockers.isEmpty()) {
@@ -502,7 +500,7 @@ public class ComputerUtilCombat {
return true; return true;
} }
} }
if(threateningCommanders.contains(attacker)) { if (threateningCommanders.contains(attacker)) {
return true; return true;
} }
} }
@@ -696,7 +694,6 @@ public class ComputerUtilCombat {
* @return a boolean. * @return a boolean.
*/ */
public static boolean combatantWouldBeDestroyed(Player ai, final Card combatant, Combat combat) { public static boolean combatantWouldBeDestroyed(Player ai, final Card combatant, Combat combat) {
if (combat.isAttacking(combatant)) { if (combat.isAttacking(combatant)) {
return ComputerUtilCombat.attackerWouldBeDestroyed(ai, combatant, combat); return ComputerUtilCombat.attackerWouldBeDestroyed(ai, combatant, combat);
} }
@@ -2221,7 +2218,6 @@ public class ComputerUtilCombat {
return killDamage; return killDamage;
} }
/** /**
* <p> * <p>
* predictDamage. * predictDamage.

View File

@@ -530,7 +530,7 @@ public class ComputerUtilMana {
continue; continue;
} }
if (ApiType.Mana.equals(trSA.getApi())) { if (ApiType.Mana.equals(trSA.getApi())) {
int pAmount = AbilityUtils.calculateAmount(trSA.getHostCard(), trSA.getParamOrDefault("Amount", "1"), trSA); int pAmount = AbilityUtils.calculateAmount(trSA.getHostCard(), trSA.getParamOrDefault("Amount", "1"), trSA);
String produced = trSA.getParam("Produced"); String produced = trSA.getParam("Produced");
if (produced.equals("Chosen")) { if (produced.equals("Chosen")) {
produced = MagicColor.toShortString(trSA.getHostCard().getChosenColor()); produced = MagicColor.toShortString(trSA.getHostCard().getChosenColor());
@@ -1505,7 +1505,7 @@ public class ComputerUtilMana {
} }
if (manaToAdd < 1 && !payCosts.getCostMana().canXbe0()) { if (manaToAdd < 1 && !payCosts.getCostMana().canXbe0()) {
// AI cannot really handle X costs properly but this keeps AI form violating rules // AI cannot really handle X costs properly but this keeps AI from violating rules
manaToAdd = 1; manaToAdd = 1;
} }

View File

@@ -60,7 +60,6 @@ public class CopySpellAbilityAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) { if (tgt != null) {
// Filter AI-specific targets if provided // Filter AI-specific targets if provided
if ("OnlyOwned".equals(sa.getParam("AITgts"))) { if ("OnlyOwned".equals(sa.getParam("AITgts"))) {
if (!top.getActivatingPlayer().equals(aiPlayer)) { if (!top.getActivatingPlayer().equals(aiPlayer)) {
@@ -148,4 +147,3 @@ public class CopySpellAbilityAi extends SpellAbilityAi {
} }
} }

View File

@@ -219,7 +219,6 @@ public class DestroyAi extends SpellAbilityAi {
return false; return false;
} }
// target loop // target loop
// TODO use can add more Targets // TODO use can add more Targets
while (sa.getTargets().size() < maxTargets) { while (sa.getTargets().size() < maxTargets) {
@@ -411,7 +410,6 @@ public class DestroyAi extends SpellAbilityAi {
} else { } else {
return mandatory; return mandatory;
} }
} }
public boolean doLandForLandRemovalLogic(SpellAbility sa, Player ai, Card tgtLand, String logic) { public boolean doLandForLandRemovalLogic(SpellAbility sa, Player ai, Card tgtLand, String logic) {

View File

@@ -17,7 +17,6 @@ import forge.game.spellability.SpellAbility;
public class TapAi extends TapAiBase { public class TapAi extends TapAiBase {
@Override @Override
protected boolean canPlayAI(Player ai, SpellAbility sa) { protected boolean canPlayAI(Player ai, SpellAbility sa) {
final PhaseHandler phase = ai.getGame().getPhaseHandler(); final PhaseHandler phase = ai.getGame().getPhaseHandler();
final Player turn = phase.getPlayerTurn(); final Player turn = phase.getPlayerTurn();
@@ -71,7 +70,6 @@ public class TapAi extends TapAiBase {
sa.resetTargets(); sa.resetTargets();
return tapPrefTargeting(ai, source, sa, false); return tapPrefTargeting(ai, source, sa, false);
} }
} }
} }

View File

@@ -63,7 +63,7 @@ public class BoosterGenerator {
private final static Map<String, PrintSheet> cachedSheets = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private final static Map<String, PrintSheet> cachedSheets = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
private static synchronized PrintSheet getPrintSheet(String key) { private static synchronized PrintSheet getPrintSheet(String key) {
if( !cachedSheets.containsKey(key) ) if (!cachedSheets.containsKey(key))
cachedSheets.put(key, makeSheet(key, StaticData.instance().getCommonCards().getAllCards())); cachedSheets.put(key, makeSheet(key, StaticData.instance().getCommonCards().getAllCards()));
return cachedSheets.get(key); return cachedSheets.get(key);
} }
@@ -369,7 +369,7 @@ public class BoosterGenerator {
} }
String boosterReplaceSlotFromPrintSheet = edition.getBoosterReplaceSlotFromPrintSheet(); String boosterReplaceSlotFromPrintSheet = edition.getBoosterReplaceSlotFromPrintSheet();
if(!boosterReplaceSlotFromPrintSheet.isEmpty()) { if (!boosterReplaceSlotFromPrintSheet.isEmpty()) {
replaceCardFromExtraSheet(result, boosterReplaceSlotFromPrintSheet); replaceCardFromExtraSheet(result, boosterReplaceSlotFromPrintSheet);
} }
} }
@@ -448,7 +448,7 @@ public class BoosterGenerator {
*/ */
public static void replaceCard(List<PaperCard> booster, PaperCard toAdd) { public static void replaceCard(List<PaperCard> booster, PaperCard toAdd) {
Predicate<PaperCard> rarityPredicate = null; Predicate<PaperCard> rarityPredicate = null;
switch(toAdd.getRarity()){ switch (toAdd.getRarity()) {
case BasicLand: case BasicLand:
rarityPredicate = Presets.IS_BASIC_LAND; rarityPredicate = Presets.IS_BASIC_LAND;
break; break;
@@ -469,7 +469,7 @@ public class BoosterGenerator {
PaperCard toReplace = null; PaperCard toReplace = null;
// Find first card in booster that matches the rarity // Find first card in booster that matches the rarity
for (PaperCard card : booster) { for (PaperCard card : booster) {
if(rarityPredicate.apply(card)) { if (rarityPredicate.apply(card)) {
toReplace = card; toReplace = card;
break; break;
} }
@@ -506,7 +506,6 @@ public class BoosterGenerator {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static PrintSheet makeSheet(String sheetKey, Iterable<PaperCard> src) { public static PrintSheet makeSheet(String sheetKey, Iterable<PaperCard> src) {
PrintSheet ps = new PrintSheet(sheetKey); PrintSheet ps = new PrintSheet(sheetKey);
String[] sKey = TextUtil.splitWithParenthesis(sheetKey, ' ', 2); String[] sKey = TextUtil.splitWithParenthesis(sheetKey, ' ', 2);
Predicate<PaperCard> setPred = (Predicate<PaperCard>) (sKey.length > 1 ? IPaperCard.Predicates.printedInSets(sKey[1].split(" ")) : Predicates.alwaysTrue()); Predicate<PaperCard> setPred = (Predicate<PaperCard>) (sKey.length > 1 ? IPaperCard.Predicates.printedInSets(sKey[1].split(" ")) : Predicates.alwaysTrue());
@@ -516,8 +515,7 @@ public class BoosterGenerator {
// source replacement operators - if one is applied setPredicate will be ignored // source replacement operators - if one is applied setPredicate will be ignored
Iterator<String> itMod = operators.iterator(); Iterator<String> itMod = operators.iterator();
while(itMod.hasNext()) { while (itMod.hasNext()) {
String mainCode = itMod.next(); String mainCode = itMod.next();
if (mainCode.regionMatches(true, 0, "fromSheet", 0, 9) || if (mainCode.regionMatches(true, 0, "fromSheet", 0, 9) ||
@@ -529,43 +527,38 @@ public class BoosterGenerator {
setPred = Predicates.alwaysTrue(); setPred = Predicates.alwaysTrue();
} else if (mainCode.startsWith("promo") || mainCode.startsWith("name")) { // get exactly the named cards, that's a tiny inlined print sheet } else if (mainCode.startsWith("promo") || mainCode.startsWith("name")) { // get exactly the named cards, that's a tiny inlined print sheet
String list = StringUtils.strip(mainCode.substring(5), "() "); String list = StringUtils.strip(mainCode.substring(5), "() ");
String[] cardNames = TextUtil.splitWithParenthesis(list, ',', '"', '"'); String[] cardNames = TextUtil.splitWithParenthesis(list, ',', '"', '"');
List<PaperCard> srcList = new ArrayList<>(); List<PaperCard> srcList = new ArrayList<>();
for(String cardName: cardNames) { for (String cardName: cardNames) {
srcList.add(StaticData.instance().getCommonCards().getCard(cardName)); srcList.add(StaticData.instance().getCommonCards().getCard(cardName));
} }
src = srcList; src = srcList;
setPred = Predicates.alwaysTrue(); setPred = Predicates.alwaysTrue();
} else { } else {
continue; continue;
} }
itMod.remove(); itMod.remove();
} }
// only special operators should remain by now - the ones that could not be turned into one predicate // only special operators should remain by now - the ones that could not be turned into one predicate
String mainCode = operators.isEmpty() ? null : operators.get(0).trim(); String mainCode = operators.isEmpty() ? null : operators.get(0).trim();
if( null == mainCode || mainCode.equalsIgnoreCase(BoosterSlots.ANY) ) { // no restriction on rarity if (null == mainCode || mainCode.equalsIgnoreCase(BoosterSlots.ANY)) { // no restriction on rarity
Predicate<PaperCard> predicate = Predicates.and(setPred, extraPred); Predicate<PaperCard> predicate = Predicates.and(setPred, extraPred);
ps.addAll(Iterables.filter(src, predicate)); ps.addAll(Iterables.filter(src, predicate));
} else if ( mainCode.equalsIgnoreCase(BoosterSlots.UNCOMMON_RARE) ) { // for sets like ARN, where U1 cards are considered rare and U3 are uncommon } else if (mainCode.equalsIgnoreCase(BoosterSlots.UNCOMMON_RARE)) { // for sets like ARN, where U1 cards are considered rare and U3 are uncommon
Predicate<PaperCard> predicateRares = Predicates.and(setPred, IPaperCard.Predicates.Presets.IS_RARE, extraPred); Predicate<PaperCard> predicateRares = Predicates.and(setPred, IPaperCard.Predicates.Presets.IS_RARE, extraPred);
ps.addAll(Iterables.filter(src, predicateRares)); ps.addAll(Iterables.filter(src, predicateRares));
Predicate<PaperCard> predicateUncommon = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_UNCOMMON, extraPred); Predicate<PaperCard> predicateUncommon = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_UNCOMMON, extraPred);
ps.addAll(Iterables.filter(src, predicateUncommon), 3); ps.addAll(Iterables.filter(src, predicateUncommon), 3);
} else if ( mainCode.equalsIgnoreCase(BoosterSlots.RARE_MYTHIC) ) { } else if (mainCode.equalsIgnoreCase(BoosterSlots.RARE_MYTHIC)) {
// Typical ratio of rares to mythics is 53:15, changing to 35:10 in smaller sets. // Typical ratio of rares to mythics is 53:15, changing to 35:10 in smaller sets.
// To achieve the desired 1:8 are all mythics are added once, and all rares added twice per print sheet. // To achieve the desired 1:8 are all mythics are added once, and all rares added twice per print sheet.
@@ -574,32 +567,28 @@ public class BoosterGenerator {
Predicate<PaperCard> predicateRare = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_RARE, extraPred); Predicate<PaperCard> predicateRare = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_RARE, extraPred);
ps.addAll(Iterables.filter(src, predicateRare), 2); ps.addAll(Iterables.filter(src, predicateRare), 2);
} else { } else {
throw new IllegalArgumentException("Booster generator: operator could not be parsed - " + mainCode); throw new IllegalArgumentException("Booster generator: operator could not be parsed - " + mainCode);
} }
return ps; return ps;
} }
/** /**
* This method also modifies passed parameter * This method also modifies passed parameter
*/ */
private static Predicate<PaperCard> buildExtraPredicate(List<String> operators) { private static Predicate<PaperCard> buildExtraPredicate(List<String> operators) {
List<Predicate<PaperCard>> conditions = new ArrayList<>(); List<Predicate<PaperCard>> conditions = new ArrayList<>();
Iterator<String> itOp = operators.iterator(); Iterator<String> itOp = operators.iterator();
while(itOp.hasNext()) { while (itOp.hasNext()) {
String operator = itOp.next(); String operator = itOp.next();
if(StringUtils.isEmpty(operator)) { if (StringUtils.isEmpty(operator)) {
itOp.remove(); itOp.remove();
continue; continue;
} }
if(operator.endsWith("s")) { if (operator.endsWith("s")) {
operator = operator.substring(0, operator.length() - 1); operator = operator.substring(0, operator.length() - 1);
} }
@@ -669,7 +658,6 @@ public class BoosterGenerator {
toAdd = Predicates.not(toAdd); toAdd = Predicates.not(toAdd);
} }
conditions.add(toAdd); conditions.add(toAdd);
} }
if (conditions.isEmpty()) { if (conditions.isEmpty()) {

View File

@@ -273,7 +273,7 @@ public class GameAction {
copied.setState(CardStateName.Original, false); copied.setState(CardStateName.Original, false);
copied.setBackSide(false); copied.setBackSide(false);
// reset timestamp in changezone effects so they have same timestamp if ETB simutaneously // reset timestamp in changezone effects so they have same timestamp if ETB simultaneously
copied.setTimestamp(game.getNextTimestamp()); copied.setTimestamp(game.getNextTimestamp());
} }
@@ -376,7 +376,7 @@ public class GameAction {
} }
cards.set(cards.indexOf(copied), c); cards.set(cards.indexOf(copied), c);
if (zoneTo.is(ZoneType.Library)) { if (zoneTo.is(ZoneType.Library)) {
java.util.Collections.reverse(cards); Collections.reverse(cards);
} }
mergedCards = cards; mergedCards = cards;
if (cause != null) { if (cause != null) {
@@ -805,6 +805,12 @@ public class GameAction {
Card result = moveTo(game.getStackZone(), c, cause, params); Card result = moveTo(game.getStackZone(), c, cause, params);
if (cause != null && cause.isSpell() && result.equals(cause.getHostCard())) { if (cause != null && cause.isSpell() && result.equals(cause.getHostCard())) {
result.setSplitStateToPlayAbility(cause); result.setSplitStateToPlayAbility(cause);
// CR 112.2 A spells controller is, by default, the player who put it on the stack.
result.setController(cause.getActivatingPlayer(), 0);
// for triggers like from Wild-Magic Sorcerer
game.getAction().checkStaticAbilities(false);
game.getTriggerHandler().resetActiveTriggers();
} }
return result; return result;
} }
@@ -1842,11 +1848,11 @@ public class GameAction {
private float getLandRatio(List<Card> deck) { private float getLandRatio(List<Card> deck) {
int landCount = 0; int landCount = 0;
for (Card c:deck) { for (Card c:deck) {
if (c.isLand()){ if (c.isLand()) {
landCount++; landCount++;
} }
} }
if(landCount == 0) { if (landCount == 0) {
return 0; return 0;
} }
return Float.valueOf(landCount)/Float.valueOf(deck.size()); return Float.valueOf(landCount)/Float.valueOf(deck.size());
@@ -1854,7 +1860,7 @@ public class GameAction {
private float getHandScore(List<Card> hand, float landRatio) { private float getHandScore(List<Card> hand, float landRatio) {
int landCount = 0; int landCount = 0;
for (Card c:hand) { for (Card c : hand) {
if (c.isLand()) { if (c.isLand()) {
landCount++; landCount++;
} }

View File

@@ -218,8 +218,7 @@ public class AbilityUtils {
if (o instanceof SpellAbility) { if (o instanceof SpellAbility) {
c = ((SpellAbility) o).getHostCard(); c = ((SpellAbility) o).getHostCard();
} }
} } else {
else {
AbilityKey type = AbilityKey.fromString(defined.substring(9)); AbilityKey type = AbilityKey.fromString(defined.substring(9));
final Object crd = root.getTriggeringObject(type); final Object crd = root.getTriggeringObject(type);
if (crd instanceof Card) { if (crd instanceof Card) {

View File

@@ -126,7 +126,7 @@ public abstract class SpellAbilityEffect {
int amount = AbilityUtils.calculateAmount(sa.getHostCard(), svar, sa); int amount = AbilityUtils.calculateAmount(sa.getHostCard(), svar, sa);
sb.append(" "); sb.append(" ");
sb.append(TextUtil.enclosedParen(TextUtil.concatNoSpace(svar,"=",String.valueOf(amount)))); sb.append(TextUtil.enclosedParen(TextUtil.concatNoSpace(svar,"=",String.valueOf(amount))));
} else{ } else {
if (sa.costHasManaX()) { if (sa.costHasManaX()) {
int amount = sa.getXManaCostPaid() == null ? 0 : sa.getXManaCostPaid(); int amount = sa.getXManaCostPaid() == null ? 0 : sa.getXManaCostPaid();
sb.append(" "); sb.append(" ");

View File

@@ -42,7 +42,6 @@ public class CopyPermanentEffect extends TokenEffectBase {
} }
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final List<Card> tgtCards = getTargetCards(sa); final List<Card> tgtCards = getTargetCards(sa);
sb.append("Copy "); sb.append("Copy ");
@@ -100,7 +99,7 @@ public class CopyPermanentEffect extends TokenEffectBase {
if (sa.hasParam("RandomCopied")) { if (sa.hasParam("RandomCopied")) {
List<PaperCard> copysource = Lists.newArrayList(cards); List<PaperCard> copysource = Lists.newArrayList(cards);
List<Card> choice = Lists.newArrayList(); List<Card> choice = Lists.newArrayList();
final String num = sa.getParamOrDefault("RandomNum","1"); final String num = sa.getParamOrDefault("RandomNum", "1");
int ncopied = AbilityUtils.calculateAmount(host, num, sa); int ncopied = AbilityUtils.calculateAmount(host, num, sa);
while (ncopied > 0 && !copysource.isEmpty()) { while (ncopied > 0 && !copysource.isEmpty()) {
final PaperCard cp = Aggregates.random(copysource); final PaperCard cp = Aggregates.random(copysource);

View File

@@ -120,7 +120,7 @@ public class PlayEffect extends SpellAbilityEffect {
} }
if (sa.hasParam("RandomCopied")) { if (sa.hasParam("RandomCopied")) {
final CardCollection choice = new CardCollection(); final CardCollection choice = new CardCollection();
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1"; final String num = sa.getParamOrDefault("RandomNum", "1");
int ncopied = AbilityUtils.calculateAmount(source, num, sa); int ncopied = AbilityUtils.calculateAmount(source, num, sa);
for (PaperCard cp : Aggregates.random(cards, ncopied)) { for (PaperCard cp : Aggregates.random(cards, ncopied)) {
final Card possibleCard = Card.fromPaperCard(cp, sa.getActivatingPlayer()); final Card possibleCard = Card.fromPaperCard(cp, sa.getActivatingPlayer());
@@ -138,13 +138,11 @@ public class PlayEffect extends SpellAbilityEffect {
source + " - " + Localizer.getInstance().getMessage("lblChooseUpTo") + " " + Lang.nounWithNumeral(choicenum, "card"), 0, choicenum, true, null source + " - " + Localizer.getInstance().getMessage("lblChooseUpTo") + " " + Lang.nounWithNumeral(choicenum, "card"), 0, choicenum, true, null
) )
); );
} } else {
else {
tgtCards = choice; tgtCards = choice;
} }
System.err.println("Copying random spell(s): " + tgtCards.toString()); System.err.println("Copying random spell(s): " + tgtCards.toString());
} } else {
else {
return; return;
} }
} else if (sa.hasParam("CopyFromChosenName")) { } else if (sa.hasParam("CopyFromChosenName")) {

View File

@@ -64,7 +64,7 @@ public class SetStateEffect extends SpellAbilityEffect {
} }
// Cards which are not on the battlefield should not be able to transform. // Cards which are not on the battlefield should not be able to transform.
// TurnFace should be allowed in other zones like Exil too // TurnFace should be allowed in other zones like Exile too
if (!"TurnFace".equals(mode) && !gameCard.isInZone(ZoneType.Battlefield)) { if (!"TurnFace".equals(mode) && !gameCard.isInZone(ZoneType.Battlefield)) {
continue; continue;
} }

View File

@@ -4116,7 +4116,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// of lists. Optimizes common operations such as hasKeyword(). // of lists. Optimizes common operations such as hasKeyword().
public final void visitKeywords(CardState state, Visitor<KeywordInterface> visitor) { public final void visitKeywords(CardState state, Visitor<KeywordInterface> visitor) {
visitUnhiddenKeywords(state, visitor); visitUnhiddenKeywords(state, visitor);
visitHiddenExtreinsicKeywords(visitor); visitHiddenExtrinsicKeywords(visitor);
} }
@Override @Override
@@ -4417,10 +4417,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// Hidden Keywords will be returned without the indicator HIDDEN // Hidden Keywords will be returned without the indicator HIDDEN
public final List<KeywordInterface> getHiddenExtrinsicKeywords() { public final List<KeywordInterface> getHiddenExtrinsicKeywords() {
ListKeywordVisitor visitor = new ListKeywordVisitor(); ListKeywordVisitor visitor = new ListKeywordVisitor();
visitHiddenExtreinsicKeywords(visitor); visitHiddenExtrinsicKeywords(visitor);
return visitor.getKeywords(); return visitor.getKeywords();
} }
private void visitHiddenExtreinsicKeywords(Visitor<KeywordInterface> visitor) { private void visitHiddenExtrinsicKeywords(Visitor<KeywordInterface> visitor) {
for (KeywordInterface inst : hiddenExtrinsicKeyword.getValues()) { for (KeywordInterface inst : hiddenExtrinsicKeyword.getValues()) {
if (!visitor.visit(inst)) { if (!visitor.visit(inst)) {
return; return;
@@ -5492,7 +5492,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final void animateBestow() { public final void animateBestow() {
animateBestow(true); animateBestow(true);
} }
public final void animateBestow(final boolean updateView) { public final void animateBestow(final boolean updateView) {
if (isBestowed()) { if (isBestowed()) {
return; return;
@@ -5509,7 +5508,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final void unanimateBestow() { public final void unanimateBestow() {
unanimateBestow(true); unanimateBestow(true);
} }
public final void unanimateBestow(final boolean updateView) { public final void unanimateBestow(final boolean updateView) {
if (!isBestowed()) { if (!isBestowed()) {
return; return;
@@ -5602,7 +5600,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public boolean hasProtectionFrom(final Card source, final boolean checkSBA) { public boolean hasProtectionFrom(final Card source, final boolean checkSBA) {
return hasProtectionFrom(source, checkSBA, false); return hasProtectionFrom(source, checkSBA, false);
} }
public boolean hasProtectionFrom(final Card source, final boolean checkSBA, final boolean damageSource) { public boolean hasProtectionFrom(final Card source, final boolean checkSBA, final boolean damageSource) {
if (source == null) { if (source == null) {
return false; return false;
@@ -5805,6 +5802,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
Collections.sort(ability); Collections.sort(ability);
return StringUtils.join(ability.toArray(), ","); //fix nosuchmethod on some android devices... return StringUtils.join(ability.toArray(), ","); //fix nosuchmethod on some android devices...
} }
public Zone getZone() { public Zone getZone() {
return currentZone; return currentZone;
} }

View File

@@ -1615,7 +1615,6 @@ public class CardFactoryUtil {
replicateTrigger.setOverridingAbility(replicateAbility); replicateTrigger.setOverridingAbility(replicateAbility);
replicateTrigger.setSVar("ReplicateAmount", "0"); replicateTrigger.setSVar("ReplicateAmount", "0");
inst.addTrigger(replicateTrigger); inst.addTrigger(replicateTrigger);
} else if (keyword.startsWith("Ripple")) { } else if (keyword.startsWith("Ripple")) {
final String[] k = keyword.split(":"); final String[] k = keyword.split(":");
final String num = k[1]; final String num = k[1];

View File

@@ -147,8 +147,7 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
//store zones to open and players to open them for at the time the SpellAbility first goes on the stack based on the selected targets //store zones to open and players to open them for at the time the SpellAbility first goes on the stack based on the selected targets
if (tc == null) { if (tc == null) {
playersWithValidTargets = null; playersWithValidTargets = null;
} } else {
else {
playersWithValidTargets = Maps.newHashMap(); playersWithValidTargets = Maps.newHashMap();
for (Card card : tc.getTargetCards()) { for (Card card : tc.getTargetCards()) {
ZoneType zoneType = card.getZone() != null ? card.getZone().getZoneType() : null; ZoneType zoneType = card.getZone() != null ? card.getZone().getZoneType() : null;

View File

@@ -698,7 +698,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
return layers; return layers;
} }
public int getMayPlayTurn() { public int getMayPlayTurn() {
return mayPlayTurn; return mayPlayTurn;
} }

View File

@@ -7,7 +7,6 @@ import forge.game.player.Player;
public class StaticAbilityCantPutCounter { public class StaticAbilityCantPutCounter {
public static boolean applyCantPutCounter(final StaticAbility stAb, final Card card, final CounterType type) { public static boolean applyCantPutCounter(final StaticAbility stAb, final Card card, final CounterType type) {
if (stAb.hasParam("CounterType")) { if (stAb.hasParam("CounterType")) {
CounterType t = CounterType.getType(stAb.getParam("CounterType")); CounterType t = CounterType.getType(stAb.getParam("CounterType"));
if (t != null && !type.equals(t)) { if (t != null && !type.equals(t)) {
@@ -26,7 +25,6 @@ public class StaticAbilityCantPutCounter {
} }
public static boolean applyCantPutCounter(final StaticAbility stAb, final Player player, final CounterType type) { public static boolean applyCantPutCounter(final StaticAbility stAb, final Player player, final CounterType type) {
if (stAb.hasParam("CounterType")) { if (stAb.hasParam("CounterType")) {
CounterType t = CounterType.getType(stAb.getParam("CounterType")); CounterType t = CounterType.getType(stAb.getParam("CounterType"));
if (t != null && !type.equals(t)) { if (t != null && !type.equals(t)) {

View File

@@ -135,8 +135,7 @@ public abstract class Trigger extends TriggerReplacementBase {
String currentName; String currentName;
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) { if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
currentName = cardState.getName(); currentName = cardState.getName();
} } else {
else {
currentName = getHostCard().getName(); currentName = getHostCard().getName();
} }
String desc = getParam("TriggerDescription"); String desc = getParam("TriggerDescription");
@@ -146,7 +145,7 @@ public abstract class Trigger extends TriggerReplacementBase {
desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName)));
} }
if (getHostCard().getEffectSource() != null) { if (getHostCard().getEffectSource() != null) {
if(active) if (active)
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString()); desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString());
else else
desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().getName()); desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().getName());
@@ -169,7 +168,6 @@ public abstract class Trigger extends TriggerReplacementBase {
SpellAbility sa = ensureAbility(); SpellAbility sa = ensureAbility();
return replaceAbilityText(desc, sa); return replaceAbilityText(desc, sa);
} }
public final String replaceAbilityText(final String desc, SpellAbility sa) { public final String replaceAbilityText(final String desc, SpellAbility sa) {
@@ -355,7 +353,6 @@ public abstract class Trigger extends TriggerReplacementBase {
return true; return true;
} }
public boolean meetsRequirementsOnTriggeredObjects(Game game, final Map<AbilityKey, Object> runParams) { public boolean meetsRequirementsOnTriggeredObjects(Game game, final Map<AbilityKey, Object> runParams) {
if ("True".equals(getParam("EvolveCondition"))) { if ("True".equals(getParam("EvolveCondition"))) {
final Card moved = (Card) runParams.get(AbilityKey.Card); final Card moved = (Card) runParams.get(AbilityKey.Card);

View File

@@ -455,10 +455,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
game.getPhaseHandler().setPriority(sp.getActivatingPlayer()); game.getPhaseHandler().setPriority(sp.getActivatingPlayer());
} }
//FIXME: additional check cmc, etc..
game.getTriggerHandler().resetActiveTriggers();
game.getAction().checkStaticAbilities();
if (sp.isSpell() && !sp.isCopied()) { if (sp.isSpell() && !sp.isCopied()) {
thisTurnCast.add(CardUtil.getLKICopy(sp.getHostCard())); thisTurnCast.add(CardUtil.getLKICopy(sp.getHostCard()));
sp.getActivatingPlayer().addSpellCastThisTurn(); sp.getActivatingPlayer().addSpellCastThisTurn();

View File

@@ -312,7 +312,6 @@ public class ImageCache {
if (1 == bestFitScale) { if (1 == bestFitScale) {
result = original; result = original;
} else { } else {
int destWidth = (int)(original.getWidth() * bestFitScale); int destWidth = (int)(original.getWidth() * bestFitScale);
int destHeight = (int)(original.getHeight() * bestFitScale); int destHeight = (int)(original.getHeight() * bestFitScale);

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Naga Wizard
PT:3/7 PT:3/7
K:Menace K:Menace
T:Mode$ DamageDone | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | TriggerZones$ Battlefield | CombatDamage$ True | Execute$ TrigGainLife | TriggerDescription$ Whenever a creature you control deals combat damage to a player, you gain life equal to that creature's toughness. T:Mode$ DamageDone | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | TriggerZones$ Battlefield | CombatDamage$ True | Execute$ TrigGainLife | TriggerDescription$ Whenever a creature you control deals combat damage to a player, you gain life equal to that creature's toughness.
SVar:TrigGainLife:DB$GainLife | Defined$ You | LifeAmount$ X SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ X
SVar:X:TriggeredSource$CardToughness SVar:X:TriggeredSource$CardToughness
K:Partner K:Partner
DeckHas:Ability$LifeGain DeckHas:Ability$LifeGain

View File

@@ -3,7 +3,7 @@ ManaCost:5
Types:Artifact Creature Juggernaut Types:Artifact Creature Juggernaut
PT:10/10 PT:10/10
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExileYourLibrary | TriggerDescription$ When CARDNAME enters the battlefield, exile all cards from your library. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExileYourLibrary | TriggerDescription$ When CARDNAME enters the battlefield, exile all cards from your library.
SVar:TrigExileYourLibrary:DB$ChangeZoneAll | ChangeType$ Card.YouOwn | Origin$ Library | Destination$ Exile SVar:TrigExileYourLibrary:DB$ ChangeZoneAll | ChangeType$ Card.YouOwn | Origin$ Library | Destination$ Exile
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/leveler.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/leveler.jpg
Oracle:When Leveler enters the battlefield, exile all cards from your library. Oracle:When Leveler enters the battlefield, exile all cards from your library.

View File

@@ -4,7 +4,7 @@ Types:Creature Tiefling Rogue
PT:3/2 PT:3/2
T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | Execute$ DBToken | TriggerDescription$ Whenever one or more creatures you control deal combat damage to a player, create two Treasure tokens. T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | Execute$ DBToken | TriggerDescription$ Whenever one or more creatures you control deal combat damage to a player, create two Treasure tokens.
SVar:DBToken:DB$ Token | TokenAmount$ 2 | TokenScript$ c_a_treasure_sac | TokenOwner$ You SVar:DBToken:DB$ Token | TokenAmount$ 2 | TokenScript$ c_a_treasure_sac | TokenOwner$ You
A:AB$ Pump | Cost$ 4 B Sac<X/Treasure> | SorcerySpeed$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | IsCurse$ True | NumAtt$ -X | NumDef$ -X | SpellDescription$ Target creature gets -X/-X until end of turn. Activate only as a sorcery. A:AB$ Pump | Cost$ B Sac<X/Treasure> | SorcerySpeed$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | IsCurse$ True | NumAtt$ -X | NumDef$ -X | SpellDescription$ Target creature gets -X/-X until end of turn. Activate only as a sorcery.
SVar:X:Count$xPaid SVar:X:Count$xPaid
DeckHas:Ability$Token & Ability$Sacrifice DeckHas:Ability$Token & Ability$Sacrifice
Oracle:Whenever one or more creatures you control deal combat damage to a player, create two Treasure tokens.\n{B}, Sacrifice X Treasures: Target creature gets -X/-X until end of turn. Activate only as a sorcery. Oracle:Whenever one or more creatures you control deal combat damage to a player, create two Treasure tokens.\n{B}, Sacrifice X Treasures: Target creature gets -X/-X until end of turn. Activate only as a sorcery.

View File

@@ -3,7 +3,7 @@ ManaCost:1 B
Types:Creature Zombie Frog Beast Types:Creature Zombie Frog Beast
PT:3/3 PT:3/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever another creature enters the battlefield, you lose 1 life. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever another creature enters the battlefield, you lose 1 life.
SVar:TrigLoseLife:DB$LoseLife | Defined$ You | LifeAmount$ 1 SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 1
SVar:AntiBuffedBy:Creature SVar:AntiBuffedBy:Creature
SVar:Picture:http://www.wizards.com/global/images/magic/general/wretched_anurid.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/wretched_anurid.jpg
Oracle:Whenever another creature enters the battlefield, you lose 1 life. Oracle:Whenever another creature enters the battlefield, you lose 1 life.