Merge branch 'validCardTraitBase' into 'master'

isValid cardTraitBase

See merge request core-developers/forge!4202
This commit is contained in:
Michael Kamensky
2021-03-15 18:22:24 +00:00
187 changed files with 806 additions and 1448 deletions

View File

@@ -20,7 +20,6 @@ package forge.ai;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardStateName;
import forge.game.CardTraitBase;
import forge.game.GameEntity;
import forge.game.card.*;
import forge.game.combat.Combat;
@@ -263,14 +262,14 @@ public class AiBlockController {
if (mode == TriggerType.DamageDone) {
if ((!trigParams.containsKey("ValidSource")
|| CardTraitBase.matchesValid(attacker, trigParams.get("ValidSource").split(","), attacker))
|| trigger.matchesValid(attacker, trigParams.get("ValidSource").split(",")))
&& attacker.getNetCombatDamage() > 0
&& (!trigParams.containsKey("ValidTarget")
|| CardTraitBase.matchesValid(combat.getDefenderByAttacker(attacker), trigParams.get("ValidTarget").split(","), attacker))) {
|| trigger.matchesValid(combat.getDefenderByAttacker(attacker), trigParams.get("ValidTarget").split(",")))) {
value += 50;
}
} else if (mode == TriggerType.AttackerUnblocked) {
if (CardTraitBase.matchesValid(attacker, trigParams.get("ValidCard").split(","), attacker)) {
if (trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","))) {
value += 50;
}
}

View File

@@ -2056,8 +2056,8 @@ public class ComputerUtil {
final CardCollection candidates = new CardCollection();
final CardCollectionView handList = ai.getCardsIn(ZoneType.Hand);
final CardCollection lands = CardLists.getValidCards(handList, "Card.Land", ai, null);
final CardCollection nonLands = CardLists.getValidCards(handList, "Card.nonLand", ai, null);
final CardCollection lands = CardLists.getValidCards(handList, "Card.Land", ai, null, null);
final CardCollection nonLands = CardLists.getValidCards(handList, "Card.nonLand", ai, null, null);
CardLists.sortByCmcDesc(nonLands);
if (lands.size() >= 3 && lands.size() <= 4) {
@@ -2996,7 +2996,7 @@ public class ComputerUtil {
}
});
} else {
list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source);
list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa);
}
if (!list.isEmpty() || sa.hasParam("AITgtsStrict") || alwaysStrict) {

View File

@@ -25,7 +25,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import forge.game.CardTraitBase;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.ability.AbilityKey;
@@ -790,9 +789,9 @@ public class ComputerUtilCombat {
return false; // The trigger should have triggered already
}
if (trigParams.containsKey("ValidCard")) {
if (!CardTraitBase.matchesValid(attacker, trigParams.get("ValidCard").split(","), source)
&& !(combat.isAttacking(source) && CardTraitBase.matchesValid(source,
trigParams.get("ValidCard").split(","), source)
if (!trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","))
&& !(combat.isAttacking(source) && trigger.matchesValid(source,
trigParams.get("ValidCard").split(","))
&& !trigParams.containsKey("Alone"))) {
return false;
}
@@ -800,7 +799,7 @@ public class ComputerUtilCombat {
if (trigParams.containsKey("Attacked")) {
if (combat.isAttacking(attacker)) {
GameEntity attacked = combat.getDefenderByAttacker(attacker);
if (!CardTraitBase.matchesValid(attacked, trigParams.get("Attacked").split(","), source)) {
if (!trigger.matchesValid(attacked, trigParams.get("Attacked").split(","))) {
return false;
}
} else {
@@ -820,7 +819,7 @@ public class ComputerUtilCombat {
if ((defender == null) && mode == TriggerType.AttackerUnblocked) {
willTrigger = true;
if (trigParams.containsKey("ValidCard")) {
if (!CardTraitBase.matchesValid(attacker, trigParams.get("ValidCard").split(","), source)) {
if (!trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","))) {
return false;
}
}
@@ -842,7 +841,7 @@ public class ComputerUtilCombat {
return false;
}
}
if (!CardTraitBase.matchesValid(attacker, validBlocked.split(","), source)) {
if (!trigger.matchesValid(attacker, validBlocked.split(","))) {
return false;
}
}
@@ -856,35 +855,35 @@ public class ComputerUtilCombat {
return false;
}
}
if (!CardTraitBase.matchesValid(defender, validBlocker.split(","), source)) {
if (!trigger.matchesValid(defender, validBlocker.split(","))) {
return false;
}
}
} else if (mode == TriggerType.AttackerBlocked || mode == TriggerType.AttackerBlockedByCreature) {
willTrigger = true;
if (trigParams.containsKey("ValidBlocker")) {
if (!CardTraitBase.matchesValid(defender, trigParams.get("ValidBlocker").split(","), source)) {
if (!trigger.matchesValid(defender, trigParams.get("ValidBlocker").split(","))) {
return false;
}
}
if (trigParams.containsKey("ValidCard")) {
if (!CardTraitBase.matchesValid(attacker, trigParams.get("ValidCard").split(","), source)) {
if (!trigger.matchesValid(attacker, trigParams.get("ValidCard").split(","))) {
return false;
}
}
} else if (mode == TriggerType.DamageDone) {
willTrigger = true;
if (trigParams.containsKey("ValidSource")) {
if (!(CardTraitBase.matchesValid(defender, trigParams.get("ValidSource").split(","), source)
if (!(trigger.matchesValid(defender, trigParams.get("ValidSource").split(","))
&& defender.getNetCombatDamage() > 0
&& (!trigParams.containsKey("ValidTarget")
|| CardTraitBase.matchesValid(attacker, trigParams.get("ValidTarget").split(","), source)))) {
|| trigger.matchesValid(attacker, trigParams.get("ValidTarget").split(","))))) {
return false;
}
if (!(CardTraitBase.matchesValid(attacker, trigParams.get("ValidSource").split(","), source)
if (!(trigger.matchesValid(attacker, trigParams.get("ValidSource").split(","))
&& attacker.getNetCombatDamage() > 0
&& (!trigParams.containsKey("ValidTarget")
|| CardTraitBase.matchesValid(defender, trigParams.get("ValidTarget").split(","), source)))) {
|| trigger.matchesValid(defender, trigParams.get("ValidTarget").split(","))))) {
return false;
}
}

View File

@@ -1159,7 +1159,7 @@ public class PlayerControllerAi extends PlayerController {
} else if (logic.equals("MostProminentInHumanDeck")) {
return ComputerUtilCard.getMostProminentCardName(oppLibrary);
} else if (logic.equals("MostProminentCreatureInComputerDeck")) {
CardCollectionView cards = CardLists.getValidCards(aiLibrary, "Creature", player, sa.getHostCard());
CardCollectionView cards = CardLists.getValidCards(aiLibrary, "Creature", player, sa.getHostCard(), sa);
return ComputerUtilCard.getMostProminentCardName(cards);
} else if (logic.equals("BestCreatureInComputerDeck")) {
Card bestCreature = ComputerUtilCard.getBestCreatureAI(aiLibrary);
@@ -1167,7 +1167,7 @@ public class PlayerControllerAi extends PlayerController {
} else if (logic.equals("RandomInComputerDeck")) {
return Aggregates.random(aiLibrary).getName();
} else if (logic.equals("MostProminentSpellInComputerDeck")) {
CardCollectionView cards = CardLists.getValidCards(aiLibrary, "Card.Instant,Card.Sorcery", player, sa.getHostCard());
CardCollectionView cards = CardLists.getValidCards(aiLibrary, "Card.Instant,Card.Sorcery", player, sa.getHostCard(), sa);
return ComputerUtilCard.getMostProminentCardName(cards);
} else if (logic.equals("CursedScroll")) {
return SpecialCardAi.CursedScroll.chooseCard(player, sa);

View File

@@ -357,7 +357,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
if (type != null && p == ai) {
// AI only "knows" about his information
list = CardLists.getValidCards(list, type, source.getController(), source);
list = CardLists.getValidCards(list, type, source.getController(), source, sa);
list = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
@@ -370,7 +370,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
// TODO: prevent ai seaching its own library when Ob Nixilis, Unshackled is in play
if (origin != null && origin.isKnown()) {
list = CardLists.getValidCards(list, type, source.getController(), source);
list = CardLists.getValidCards(list, type, source.getController(), source, sa);
}
if (!activateForCost && list.isEmpty()) {
@@ -1107,7 +1107,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// Only care about combatants during combat
if (game.getPhaseHandler().inCombat() && origin.contains(ZoneType.Battlefield)) {
CardCollection newList = CardLists.getValidCards(list, "Card.attacking,Card.blocking", null, null);
CardCollection newList = CardLists.getValidCards(list, "Card.attacking,Card.blocking", null, null, null);
if (!newList.isEmpty() || !sa.isTrigger()) {
list = newList;
}
@@ -1705,7 +1705,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
Card source = sa.getHostCard();
String definedSac = StringUtils.split(source.getSVar("AIPreference"), "$")[1];
CardCollection listToSac = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.restriction(definedSac.split(","), ai, source, sa));
CardCollection listToSac = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), definedSac, ai, source, sa);
listToSac.sort(Collections.reverseOrder(CardLists.CmcComparatorInv));
CardCollection listToRet = CardLists.filter(ai.getCardsIn(ZoneType.Graveyard), Presets.CREATURES);
@@ -1742,7 +1742,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
String definedGoal = sa.getParam("ChangeType");
boolean anyCMC = !definedGoal.contains(".cmc");
CardCollection listToSac = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.restriction(definedSac.split(","), ai, source, sa));
CardCollection listToSac = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), definedSac, ai, source, sa);
listToSac.sort(!sacWorst ? CardLists.CmcComparatorInv : Collections.reverseOrder(CardLists.CmcComparatorInv));
for (Card sacCandidate : listToSac) {
@@ -1756,12 +1756,12 @@ public class ChangeZoneAi extends SpellAbilityAi {
curGoal = definedGoal.replace("X", String.format("%d", goalCMC));
}
CardCollection listGoal = CardLists.filter(ai.getCardsIn(ZoneType.Library), CardPredicates.restriction(curGoal.split(","), ai, source, sa));
CardCollection listGoal = CardLists.getValidCards(ai.getCardsIn(ZoneType.Library), curGoal, ai, source, sa);
if (!anyCMC) {
listGoal = CardLists.getValidCards(listGoal, curGoal, source.getController(), source);
listGoal = CardLists.getValidCards(listGoal, curGoal, source.getController(), source, sa);
} else {
listGoal = CardLists.getValidCards(listGoal, curGoal + (curGoal.contains(".") ? "+" : ".") + "cmcGE" + goalCMC, source.getController(), source);
listGoal = CardLists.getValidCards(listGoal, curGoal + (curGoal.contains(".") ? "+" : ".") + "cmcGE" + goalCMC, source.getController(), source, sa);
}
listGoal = CardLists.filter(listGoal, new Predicate<Card>() {

View File

@@ -66,7 +66,7 @@ public class ChooseCardAi extends SpellAbilityAi {
}
CardCollectionView choices = ai.getGame().getCardsIn(choiceZone);
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), host.getController(), host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), host.getController(), host, sa);
}
if (sa.hasParam("TargetControls")) {
choices = CardLists.filterControlledBy(choices, ai.getOpponents());
@@ -79,7 +79,7 @@ public class ChooseCardAi extends SpellAbilityAi {
final String filter = aiLogic.equals("Clone") ? "Permanent.YouDontCtrl,Permanent.nonLegendary"
: "Permanent.YouDontCtrl+notnamedVesuva,Permanent.nonLegendary+notnamedVesuva";
choices = CardLists.getValidCards(choices, filter, host.getController(), host);
choices = CardLists.getValidCards(choices, filter, host.getController(), host, sa);
return !choices.isEmpty();
} else if (aiLogic.equals("Never")) {
return false;
@@ -112,7 +112,7 @@ public class ChooseCardAi extends SpellAbilityAi {
return !choices.isEmpty();
} else if (aiLogic.equals("RandomNonLand")) {
return !CardLists.getValidCards(choices, "Card.nonLand", host.getController(), host).isEmpty();
return !CardLists.getValidCards(choices, "Card.nonLand", host.getController(), host, sa).isEmpty();
} else if (aiLogic.equals("Duneblast")) {
CardCollection aiCreatures = ai.getCreaturesInPlay();
CardCollection oppCreatures = ai.getWeakestOpponent().getCreaturesInPlay();
@@ -186,7 +186,7 @@ public class ChooseCardAi extends SpellAbilityAi {
choice = null;
}
} else if ("RandomNonLand".equals(logic)) {
options = CardLists.getValidCards(options, "Card.nonLand", host.getController(), host);
options = CardLists.getValidCards(options, "Card.nonLand", host.getController(), host, sa);
choice = Aggregates.random(options);
} else if (logic.equals("Untap")) {
final String filter = "Permanent.YouCtrl,Permanent.tapped";

View File

@@ -105,7 +105,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
}
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), host.getController(), host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), host.getController(), host, sa);
}
final Combat combat = game.getCombat();
choices = CardLists.filter(choices, new Predicate<Card>() {

View File

@@ -124,11 +124,11 @@ public class CloneAi extends SpellAbilityAi {
private boolean cloneTgtAI(final SpellAbility sa) {
// Specific logic for cards
if ("CloneAttacker".equals(sa.getParam("AILogic"))) {
CardCollection valid = CardLists.getValidCards(sa.getHostCard().getController().getCardsIn(ZoneType.Battlefield), sa.getParam("ValidTgts"), sa.getHostCard().getController(), sa.getHostCard());
CardCollection valid = CardLists.getValidCards(sa.getHostCard().getController().getCardsIn(ZoneType.Battlefield), sa.getParam("ValidTgts"), sa.getHostCard().getController(), sa.getHostCard(), sa);
sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(valid));
return true;
} else if ("CloneBestCreature".equals(sa.getParam("AILogic"))) {
CardCollection valid = CardLists.getValidCards(sa.getHostCard().getController().getGame().getCardsIn(ZoneType.Battlefield), sa.getParam("ValidTgts"), sa.getHostCard().getController(), sa.getHostCard());
CardCollection valid = CardLists.getValidCards(sa.getHostCard().getController().getGame().getCardsIn(ZoneType.Battlefield), sa.getParam("ValidTgts"), sa.getHostCard().getController(), sa.getHostCard(), sa);
sa.getTargets().add(ComputerUtilCard.getBestCreatureAI(valid));
return true;
}

View File

@@ -173,7 +173,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
} else if (sa.hasParam("Choices")) {
// only check for options, does not select there
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
Collection<Card> betterChoices = getBetterOptions(aiPlayer, sa, choices, !mandatory);
if (betterChoices.isEmpty()) {
return mandatory;

View File

@@ -38,11 +38,11 @@ public class CountersPutAllAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
if ("OwnCreatsAndOtherPWs".equals(sa.getParam("AILogic"))) {
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source);
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.YouCtrl,Planeswalker.YouCtrl+Other", source.getController(), source, sa);
} else {
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
hList = CardLists.getValidCards(ai.getWeakestOpponent().getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);
cList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);
}
if (abCost != null) {

View File

@@ -161,7 +161,7 @@ public class DamageDealAi extends DamageAiBase {
}
} else if ("WildHunt".equals(logic)) {
// This dummy ability will just deal 0 damage, but holds the logic for the AI for Master of Wild Hunt
List<Card> wolves = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.Wolf+untapped+YouCtrl+Other", ai, source);
List<Card> wolves = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), "Creature.Wolf+untapped+YouCtrl+Other", ai, source, sa);
dmg = Aggregates.sum(wolves, CardPredicates.Accessors.fnGetNetPower);
} else if ("Triskelion".equals(logic)) {
final int n = source.getCounters(CounterEnumType.P1P1);

View File

@@ -141,7 +141,7 @@ public class ManifestAi extends SpellAbilityAi {
}
CardCollection choices = new CardCollection(game.getCardsIn(choiceZone));
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), ai, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), ai, host, sa);
}
if (choices.isEmpty()) {
return false;

View File

@@ -69,8 +69,8 @@ public class PumpAllAi extends PumpAiBase {
}
final Player opp = ai.getWeakestOpponent();
CardCollection comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
CardCollection human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source);
CardCollection comp = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);
CardCollection human = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid, source.getController(), source, sa);
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && sa.canTarget(opp) && sa.hasParam("IsCurse")) {
@@ -144,7 +144,7 @@ public class PumpAllAi extends PumpAiBase {
return (ComputerUtilCard.evaluateCreatureList(comp) + 200) < ComputerUtilCard.evaluateCreatureList(human);
} // end Curse
return !CardLists.getValidCards(getPumpCreatures(ai, sa, defense, power, keywords, false), valid, source.getController(), source).isEmpty();
return !CardLists.getValidCards(getPumpCreatures(ai, sa, defense, power, keywords, false), valid, source.getController(), source, sa).isEmpty();
} // pumpAllCanPlayAI()
@Override

View File

@@ -48,7 +48,7 @@ public class TapAllAi extends SpellAbilityAi {
validTappables = opp.getCardsIn(ZoneType.Battlefield);
}
validTappables = CardLists.getValidCards(validTappables, valid, source.getController(), source);
validTappables = CardLists.getValidCards(validTappables, valid, source.getController(), source, sa);
validTappables = CardLists.filter(validTappables, Presets.UNTAPPED);
if (sa.hasParam("AILogic")) {
@@ -98,10 +98,10 @@ public class TapAllAi extends SpellAbilityAi {
return true;
}
private CardCollectionView getTapAllTargets(final String valid, final Card source) {
private CardCollectionView getTapAllTargets(final String valid, final Card source, SpellAbility sa) {
final Game game = source.getGame();
CardCollectionView tmpList = game.getCardsIn(ZoneType.Battlefield);
tmpList = CardLists.getValidCards(tmpList, valid, source.getController(), source);
tmpList = CardLists.getValidCards(tmpList, valid, source.getController(), source, sa);
tmpList = CardLists.filter(tmpList, Presets.UNTAPPED);
return tmpList;
}
@@ -115,7 +115,7 @@ public class TapAllAi extends SpellAbilityAi {
valid = sa.getParam("ValidCards");
}
CardCollectionView validTappables = getTapAllTargets(valid, source);
CardCollectionView validTappables = getTapAllTargets(valid, source, sa);
final TargetRestrictions tgt = sa.getTargetRestrictions();

View File

@@ -50,7 +50,7 @@ public class TwoPilesAi extends SpellAbilityAi {
else {
pool = p.getCardsIn(zone);
}
pool = CardLists.getValidCards(pool, valid, card.getController(), card);
pool = CardLists.getValidCards(pool, valid, card.getController(), card, sa);
int size = pool.size();
return size > 2;
}

View File

@@ -24,7 +24,7 @@ public class VoteAi extends SpellAbilityAi {
return true;
} else if ("Judgment".equals(logic)) {
return !CardLists.getValidCards(host.getGame().getCardsIn(ZoneType.Battlefield),
sa.getParam("VoteCard"), host.getController(), host).isEmpty();
sa.getParam("VoteCard"), host.getController(), host, sa).isEmpty();
} else if ("Torture".equals(logic)) {
return aiPlayer.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.MAIN1);
}

View File

@@ -31,7 +31,7 @@ public class ZoneExchangeAi extends SpellAbilityAi {
final ZoneType zone2 = sa.hasParam("Zone2") ? ZoneType.smartValueOf(sa.getParam("Zone2")) : ZoneType.Hand;
CardCollection list = new CardCollection(ai.getCardsIn(zone2));
if (type != null) {
list = CardLists.getValidCards(list, type, ai, source);
list = CardLists.getValidCards(list, type, ai, source, sa);
}
object2 = ComputerUtilCard.getBestAI(list);
if (object1 == null || object2 == null || !object1.isInZone(zone1) || !object1.getOwner().equals(ai)) {

View File

@@ -159,15 +159,32 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
* a {@link forge.game.card.Card} object.
* @return a boolean.
*/
public static boolean matchesValid(final Object o, final String[] valids, final Card srcCard) {
public boolean matchesValid(final Object o, final String[] valids, final Card srcCard) {
if (o instanceof GameObject) {
final GameObject c = (GameObject) o;
return c.isValid(valids, srcCard.getController(), srcCard, null);
return c.isValid(valids, srcCard.getController(), srcCard, this);
} else if (o instanceof Iterable<?>) {
for (Object o2 : (Iterable<?>)o) {
if (matchesValid(o2, valids, srcCard)) {
return true;
}
}
}
return false;
}
public boolean matchesValid(final Object o, final String[] valids) {
return matchesValid(o, valids, getHostCard());
}
public boolean matchesValidParam(String param, final Object o) {
if (hasParam(param) && !matchesValid(o, getParam(param).split(","))) {
return false;
}
return true;
}
/**
* Sets the suppressed.
*
@@ -312,7 +329,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
list.addAll(p.getCardsIn(presentZone));
}
}
list = CardLists.getValidCards(list, sIsPresent.split(","), this.getHostCard().getController(), this.getHostCard(), null);
list = CardLists.getValidCards(list, sIsPresent.split(","), this.getHostCard().getController(), this.getHostCard(), this);
final String rightString = presentCompare.substring(2);
@@ -349,7 +366,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
}
}
list = CardLists.getValidCards(list, sIsPresent.split(","), this.getHostCard().getController(), this.getHostCard(), null);
list = CardLists.getValidCards(list, sIsPresent.split(","), this.getHostCard().getController(), this.getHostCard(), this);
final String rightString = presentCompare.substring(2);
int right = AbilityUtils.calculateAmount(getHostCard(), rightString, this);
@@ -361,32 +378,29 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
}
if (params.containsKey("CheckDefinedPlayer")) {
SpellAbility mockAbility = this.getHostCard().getFirstSpellAbility();
mockAbility.setActivatingPlayer(hostController);
final String sIsPresent = params.get("CheckDefinedPlayer");
int playersize = AbilityUtils.getDefinedPlayers(game.getCardState(this.getHostCard()), sIsPresent,
mockAbility).size();
int playersize = AbilityUtils.getDefinedPlayers(getHostCard(), sIsPresent, this).size();
String comparator = "GE1";
if (params.containsKey("DefinedPlayerCompare")) {
comparator = params.get("DefinedPlayerCompare");
}
final String svarOperator = comparator.substring(0, 2);
final String svarOperand = comparator.substring(2);
final int operandValue = AbilityUtils.calculateAmount(game.getCardState(this.getHostCard()), svarOperand, this);
final int operandValue = AbilityUtils.calculateAmount(getHostCard(), svarOperand, this);
if (!Expressions.compare(playersize, svarOperator, operandValue)) {
return false;
}
}
if (params.containsKey("CheckSVar")) {
final int sVar = AbilityUtils.calculateAmount(game.getCardState(this.getHostCard()), params.get("CheckSVar"), this);
final int sVar = AbilityUtils.calculateAmount(getHostCard(), params.get("CheckSVar"), this);
String comparator = "GE1";
if (params.containsKey("SVarCompare")) {
comparator = params.get("SVarCompare");
}
final String svarOperator = comparator.substring(0, 2);
final String svarOperand = comparator.substring(2);
final int operandValue = AbilityUtils.calculateAmount(game.getCardState(this.getHostCard()), svarOperand, this);
final int operandValue = AbilityUtils.calculateAmount(getHostCard(), svarOperand, this);
if (!Expressions.compare(sVar, svarOperator, operandValue)) {
return false;
}

View File

@@ -14,7 +14,7 @@ import forge.util.Expressions;
public class ForgeScript {
public static boolean cardStateHasProperty(CardState cardState, String property, Player sourceController,
Card source, SpellAbility spellAbility) {
Card source, CardTraitBase spellAbility) {
final boolean isColorlessSource = cardState.getCard().hasKeyword("Colorless Damage Source", cardState);
final ColorSet colors = cardState.getCard().determineColor(cardState);
@@ -125,7 +125,7 @@ public class ForgeScript {
public static boolean spellAbilityHasProperty(SpellAbility sa, String property, Player sourceController,
Card source, SpellAbility spellAbility) {
Card source, CardTraitBase spellAbility) {
if (property.equals("ManaAbility")) {
return sa.isManaAbility();
} else if (property.equals("nonManaAbility")) {

View File

@@ -1042,15 +1042,15 @@ public class Game {
}
}
public int getCounterAddedThisTurn(CounterType cType, String validPlayer, String validCard, Card source, Player sourceController, SpellAbility spellAbility) {
public int getCounterAddedThisTurn(CounterType cType, String validPlayer, String validCard, Card source, Player sourceController, CardTraitBase ctb) {
int result = 0;
if (!countersAddedThisTurn.containsRow(cType)) {
return result;
}
for (Map.Entry<Player, List<Pair<Card, Integer>>> e : countersAddedThisTurn.row(cType).entrySet()) {
if (e.getKey().isValid(validPlayer.split(","), sourceController, source, spellAbility)) {
if (e.getKey().isValid(validPlayer.split(","), sourceController, source, ctb)) {
for (Pair<Card, Integer> p : e.getValue()) {
if (p.getKey().isValid(validCard.split(","), sourceController, source, spellAbility)) {
if (p.getKey().isValid(validCard.split(","), sourceController, source, ctb)) {
result += p.getValue();
}
}

View File

@@ -1149,7 +1149,7 @@ public class GameAction {
}
if (c.hasKeyword("The number of loyalty counters on CARDNAME is equal to the number of Beebles you control.")) {
int beeble = CardLists.getValidCardCount(game.getCardsIn(ZoneType.Battlefield), "Beeble.YouCtrl", c.getController(), c);
int beeble = CardLists.getValidCardCount(game.getCardsIn(ZoneType.Battlefield), "Beeble.YouCtrl", c.getController(), c, null);
int loyal = c.getCounters(CounterEnumType.LOYALTY);
if (loyal < beeble) {
GameEntityCounterTable counterTable = new GameEntityCounterTable();

View File

@@ -10,7 +10,6 @@ import com.google.common.collect.Table;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.card.CounterType;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
public class GameEntityCounterTable extends ForwardingTable<GameEntity, CounterType, Integer> {
@@ -63,7 +62,7 @@ public class GameEntityCounterTable extends ForwardingTable<GameEntity, CounterT
return result;
}
public Map<GameEntity, Integer> filterTable(CounterType type, String valid, Card host, SpellAbility sa) {
public Map<GameEntity, Integer> filterTable(CounterType type, String valid, Card host, CardTraitBase sa) {
Map<GameEntity, Integer> result = Maps.newHashMap();
for (Map.Entry<GameEntity, Integer> e : column(type).entrySet()) {

View File

@@ -22,7 +22,7 @@ public abstract class GameObject {
* @param spellAbility
* @return true, if is valid
*/
public boolean isValid(final String[] restrictions, final Player sourceController, final Card source, SpellAbility spellAbility) {
public boolean isValid(final String[] restrictions, final Player sourceController, final Card source, CardTraitBase spellAbility) {
for (final String restriction : restrictions) {
if (this.isValid(restriction, sourceController, source, spellAbility)) {
return true;
@@ -43,7 +43,7 @@ public abstract class GameObject {
* @param spellAbility
* @return true, if is valid
*/
public boolean isValid(final String restriction, final Player sourceController, final Card source, SpellAbility spellAbility) {
public boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
return false;
}
@@ -59,7 +59,7 @@ public abstract class GameObject {
* @param spellAbility
* @return true, if successful
*/
public boolean hasProperty(final String property, final Player sourceController, final Card source, SpellAbility spellAbility) {
public boolean hasProperty(final String property, final Player sourceController, final Card source, CardTraitBase spellAbility) {
return false;
}
}

View File

@@ -21,7 +21,6 @@ import com.google.common.base.Predicate;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
/**
@@ -33,7 +32,7 @@ import forge.game.spellability.SpellAbility;
*/
public final class GameObjectPredicates {
public static final Predicate<GameObject> restriction(final String[] restrictions, final Player sourceController, final Card source, final SpellAbility spellAbility) {
public static final Predicate<GameObject> restriction(final String[] restrictions, final Player sourceController, final Card source, final CardTraitBase spellAbility) {
return new Predicate<GameObject>() {
@Override
public boolean apply(final GameObject c) {

View File

@@ -18,7 +18,6 @@ import forge.game.CardTraitBase;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.TriggerReplacementBase;
import forge.game.ability.AbilityFactory.AbilityRecordType;
import forge.game.card.*;
import forge.game.cost.Cost;
@@ -86,7 +85,7 @@ public class AbilityUtils {
// But then we only need update one function at a time once the casting is
// everywhere.
// Probably will move to One function solution sometime in the future
public static CardCollection getDefinedCards(final Card hostCard, final String def, final SpellAbility sa) {
public static CardCollection getDefinedCards(final Card hostCard, final String def, final CardTraitBase sa) {
CardCollection cards = new CardCollection();
String defined = (def == null) ? "Self" : applyAbilityTextChangeEffects(def, sa); // default to Self
final String[] incR = defined.split("\\.", 2);
@@ -101,7 +100,11 @@ public class AbilityUtils {
c = game.getCardState(hostCard);
}
else if (defined.equals("OriginalHost")) {
c = sa.getRootAbility().getOriginalHost();
if (sa instanceof SpellAbility) {
c = ((SpellAbility)sa).getRootAbility().getOriginalHost();
} else {
c = sa.getOriginalHost();
}
}
else if (defined.equals("EffectSource")) {
if (hostCard.isEmblem() || hostCard.getType().hasSubtype("Effect")) {
@@ -129,10 +132,12 @@ public class AbilityUtils {
}
else if (defined.equals("Enchanted")) {
c = hostCard.getEnchantingCard();
if ((c == null) && (sa != null) && (sa.getRootAbility() != null)
&& (sa.getRootAbility().getPaidList("Sacrificed") != null)
&& !sa.getRootAbility().getPaidList("Sacrificed").isEmpty()) {
c = sa.getRootAbility().getPaidList("Sacrificed").get(0).getEnchantingCard();
if (c == null && sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
CardCollection sacrificed = root.getPaidList("Sacrificed");
if (sacrificed != null && !sacrificed.isEmpty()) {
c = sacrificed.getFirst().getEnchantingCard();
}
}
}
else if (defined.endsWith("OfLibrary")) {
@@ -144,26 +149,26 @@ public class AbilityUtils {
return cards;
}
}
else if (defined.equals("Targeted")) {
final SpellAbility saTargeting = sa.getSATargetingCard();
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingCard();
if (saTargeting != null) {
Iterables.addAll(cards, saTargeting.getTargets().getTargetCards());
}
}
else if (defined.equals("ThisTargetedCard")) { // do not add parent targeted
if (sa != null && sa.getTargets() != null) {
Iterables.addAll(cards, sa.getTargets().getTargetCards());
else if (defined.equals("ThisTargetedCard") && sa instanceof SpellAbility) { // do not add parent targeted
if (((SpellAbility)sa).getTargets() != null) {
Iterables.addAll(cards, ((SpellAbility)sa).getTargets().getTargetCards());
}
}
else if (defined.equals("ParentTarget")) {
final SpellAbility parent = sa.getParentTargetingCard();
else if (defined.equals("ParentTarget") && sa instanceof SpellAbility) {
final SpellAbility parent = ((SpellAbility)sa).getParentTargetingCard();
if (parent != null) {
Iterables.addAll(cards, parent.getTargets().getTargetCards());
}
}
else if (defined.startsWith("Triggered") && (sa != null)) {
final SpellAbility root = sa.getRootAbility();
else if (defined.startsWith("Triggered") && sa instanceof SpellAbility) {
final SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (defined.contains("LKICopy")) { //Triggered*LKICopy
int lkiPosition = defined.indexOf("LKICopy");
AbilityKey type = AbilityKey.fromString(defined.substring(9, lkiPosition));
@@ -192,8 +197,8 @@ public class AbilityUtils {
}
}
}
else if (defined.startsWith("Replaced") && (sa != null)) {
final SpellAbility root = sa.getRootAbility();
else if (defined.startsWith("Replaced") && sa instanceof SpellAbility) {
final SpellAbility root = ((SpellAbility)sa).getRootAbility();
AbilityKey type = AbilityKey.fromString(defined.substring(8));
final Object crd = root.getReplacingObject(type);
@@ -239,8 +244,8 @@ public class AbilityUtils {
cards.add((Card) o);
}
}
} else if (defined.equals("DelayTriggerRememberedLKI")) {
SpellAbility root = sa.getRootAbility();
} else if (defined.equals("DelayTriggerRememberedLKI") && sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (root != null) {
for (Object o : root.getTriggerRemembered()) {
if (o instanceof Card) {
@@ -250,8 +255,8 @@ public class AbilityUtils {
} else {
System.err.println("Warning: couldn't find trigger SA in the chain of SpellAbility " + sa);
}
} else if (defined.equals("DelayTriggerRemembered")) {
SpellAbility root = sa.getRootAbility();
} else if (defined.equals("DelayTriggerRemembered") && sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (root != null) {
for (Object o : root.getTriggerRemembered()) {
if (o instanceof Card) {
@@ -313,31 +318,36 @@ public class AbilityUtils {
}
} else {
CardCollection list = null;
if (defined.startsWith("SacrificedCards")) {
list = sa.getRootAbility().getPaidList("SacrificedCards");
} else if (defined.startsWith("Sacrificed")) {
list = sa.getRootAbility().getPaidList("Sacrificed");
} else if (defined.startsWith("Revealed")) {
list = sa.getRootAbility().getPaidList("Revealed");
} else if (defined.startsWith("DiscardedCards")) {
list = sa.getRootAbility().getPaidList("DiscardedCards");
} else if (defined.startsWith("Discarded")) {
list = sa.getRootAbility().getPaidList("Discarded");
} else if (defined.startsWith("ExiledCards")) {
list = sa.getRootAbility().getPaidList("ExiledCards");
} else if (defined.startsWith("Exiled")) {
list = sa.getRootAbility().getPaidList("Exiled");
} else if (defined.startsWith("Milled")) {
list = sa.getRootAbility().getPaidList("Milled");
} else if (defined.startsWith("TappedCards")) {
list = sa.getRootAbility().getPaidList("TappedCards");
} else if (defined.startsWith("Tapped")) {
list = sa.getRootAbility().getPaidList("Tapped");
} else if (defined.startsWith("UntappedCards")) {
list = sa.getRootAbility().getPaidList("UntappedCards");
} else if (defined.startsWith("Untapped")) {
list = sa.getRootAbility().getPaidList("Untapped");
} else if (defined.startsWith("Valid ")) {
if (sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (defined.startsWith("SacrificedCards")) {
list = root.getPaidList("SacrificedCards");
} else if (defined.startsWith("Sacrificed")) {
list = root.getPaidList("Sacrificed");
} else if (defined.startsWith("Revealed")) {
list = root.getPaidList("Revealed");
} else if (defined.startsWith("DiscardedCards")) {
list = root.getPaidList("DiscardedCards");
} else if (defined.startsWith("Discarded")) {
list = root.getPaidList("Discarded");
} else if (defined.startsWith("ExiledCards")) {
list = root.getPaidList("ExiledCards");
} else if (defined.startsWith("Exiled")) {
list = root.getPaidList("Exiled");
} else if (defined.startsWith("Milled")) {
list = root.getPaidList("Milled");
} else if (defined.startsWith("TappedCards")) {
list = root.getPaidList("TappedCards");
} else if (defined.startsWith("Tapped")) {
list = root.getPaidList("Tapped");
} else if (defined.startsWith("UntappedCards")) {
list = root.getPaidList("UntappedCards");
} else if (defined.startsWith("Untapped")) {
list = root.getPaidList("Untapped");
}
}
if (defined.startsWith("Valid ")) {
String validDefined = defined.substring("Valid ".length());
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), validDefined.split(","), hostCard.getController(), hostCard, sa);
} else if (defined.startsWith("ValidAll ")) {
@@ -348,8 +358,6 @@ public class AbilityUtils {
String zone = s[0].substring("Valid".length());
String validDefined = s[1];
list = CardLists.getValidCards(game.getCardsIn(ZoneType.smartValueOf(zone)), validDefined.split(","), hostCard.getController(), hostCard, sa);
} else {
return cards;
}
if (list != null) {
@@ -806,7 +814,7 @@ public class AbilityUtils {
* a {@link forge.game.spellability.SpellAbility} object.
* @return a {@link java.util.ArrayList} object.
*/
public static FCollection<GameObject> getDefinedObjects(final Card card, final String def, final SpellAbility sa) {
public static FCollection<GameObject> getDefinedObjects(final Card card, final String def, final CardTraitBase sa) {
final FCollection<GameObject> objects = new FCollection<>();
final String defined = (def == null) ? "Self" : def;
@@ -816,7 +824,7 @@ public class AbilityUtils {
return objects;
}
public static FCollection<GameEntity> getDefinedEntities(final Card card, final String def, final SpellAbility sa) {
public static FCollection<GameEntity> getDefinedEntities(final Card card, final String def, final CardTraitBase sa) {
final FCollection<GameEntity> objects = new FCollection<>();
final String defined = (def == null) ? "Self" : def;
@@ -965,32 +973,32 @@ public class AbilityUtils {
* a {@link forge.game.spellability.SpellAbility} object.
* @return a {@link java.util.ArrayList} object.
*/
public static PlayerCollection getDefinedPlayers(final Card card, final String def, final SpellAbility sa) {
public static PlayerCollection getDefinedPlayers(final Card card, final String def, final CardTraitBase sa) {
final PlayerCollection players = new PlayerCollection();
final String defined = (def == null) ? "You" : applyAbilityTextChangeEffects(def, sa);
final Game game = card == null ? null : card.getGame();
final Player player = sa == null ? card.getController() : sa.getActivatingPlayer();
final Player player = sa instanceof SpellAbility ? ((SpellAbility)sa).getActivatingPlayer() : card.getController();
if (defined.equals("TargetedOrController")) {
players.addAll(getDefinedPlayers(card, "Targeted", sa));
players.addAll(getDefinedPlayers(card, "TargetedController", sa));
}
else if (defined.equals("Targeted") || defined.equals("TargetedPlayer")) {
final SpellAbility saTargeting = sa.getSATargetingPlayer();
else if ((defined.equals("Targeted") || defined.equals("TargetedPlayer")) && sa instanceof SpellAbility) {
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingPlayer();
if (saTargeting != null) {
players.addAll(saTargeting.getTargets().getTargetPlayers());
}
}
else if (defined.equals("ParentTarget")) {
final SpellAbility parent = sa.getParentTargetingPlayer();
else if (defined.equals("ParentTarget") && sa instanceof SpellAbility) {
final SpellAbility parent = ((SpellAbility)sa).getParentTargetingPlayer();
if (parent != null) {
players.addAll(parent.getTargets().getTargetPlayers());
}
}
else if (defined.equals("ThisTargetedPlayer")) { // do not add parent targeted
if (sa != null && sa.getTargets() != null) {
Iterables.addAll(players, sa.getTargets().getTargetPlayers());
else if (defined.equals("ThisTargetedPlayer") && sa instanceof SpellAbility) { // do not add parent targeted
if (((SpellAbility)sa).getTargets() != null) {
Iterables.addAll(players, ((SpellAbility)sa).getTargets().getTargetPlayers());
}
}
else if (defined.equals("TargetedController")) {
@@ -1006,11 +1014,11 @@ public class AbilityUtils {
players.add(c.getOwner());
}
}
else if (defined.equals("TargetedAndYou")) {
final SpellAbility saTargeting = sa.getSATargetingPlayer();
else if (defined.equals("TargetedAndYou") && sa instanceof SpellAbility) {
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingPlayer();
if (saTargeting != null) {
players.addAll(saTargeting.getTargets().getTargetPlayers());
players.add(sa.getActivatingPlayer());
players.add(((SpellAbility)sa).getActivatingPlayer());
}
}
else if (defined.equals("ParentTargetedController")) {
@@ -1024,8 +1032,8 @@ public class AbilityUtils {
else if (defined.startsWith("Remembered")) {
addPlayer(card.getRemembered(), defined, players);
}
else if (defined.startsWith("DelayTriggerRemembered")) {
SpellAbility root = sa.getRootAbility();
else if (defined.startsWith("DelayTriggerRemembered") && sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (root != null) {
addPlayer(root.getTriggerRemembered(), defined, players);
} else {
@@ -1042,12 +1050,12 @@ public class AbilityUtils {
players.add(rem.getOwner());
}
}
else if (defined.startsWith("Triggered")) {
else if (defined.startsWith("Triggered") && sa instanceof SpellAbility) {
String defParsed = defined.endsWith("AndYou") ? defined.substring(0, defined.indexOf("AndYou")) : defined;
if (defined.endsWith("AndYou")) {
players.add(sa.getActivatingPlayer());
players.add(((SpellAbility)sa).getActivatingPlayer());
}
final SpellAbility root = sa.getRootAbility();
final SpellAbility root = ((SpellAbility)sa).getRootAbility();
Object o = null;
if (defParsed.endsWith("Controller")) {
String triggeringType = defParsed.substring(9);
@@ -1108,8 +1116,8 @@ public class AbilityUtils {
players.addAll(player.getOpponents());
players.removeAll(getDefinedPlayers(card, defined.substring(6), sa));
}
else if (defined.startsWith("Replaced")) {
final SpellAbility root = sa.getRootAbility();
else if (defined.startsWith("Replaced") && sa instanceof SpellAbility) {
final SpellAbility root = ((SpellAbility)sa).getRootAbility();
Object o = null;
if (defined.endsWith("Controller")) {
String replacingType = defined.substring(8);
@@ -1252,7 +1260,7 @@ public class AbilityUtils {
* @return a {@link java.util.ArrayList} object.
*/
public static FCollection<SpellAbility> getDefinedSpellAbilities(final Card card, final String def,
final SpellAbility sa) {
final CardTraitBase sa) {
final FCollection<SpellAbility> sas = new FCollection<>();
final String defined = (def == null) ? "Self" : applyAbilityTextChangeEffects(def, sa); // default to Self
final Game game = card.getGame();
@@ -1261,14 +1269,14 @@ public class AbilityUtils {
// TODO - this probably needs to be fleshed out a bit, but the basics
// work
if (defined.equals("Self")) {
s = sa;
if (defined.equals("Self") && sa instanceof SpellAbility) {
s = (SpellAbility)sa;
}
else if (defined.equals("Parent")) {
s = sa.getRootAbility();
else if (defined.equals("Parent") && sa instanceof SpellAbility) {
s = ((SpellAbility)sa).getRootAbility();
}
else if (defined.equals("Targeted")) {
final SpellAbility saTargeting = sa.getSATargetingSA();
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingSA();
if (saTargeting != null) {
for (SpellAbility targetSpell : saTargeting.getTargets().getTargetSpells()) {
SpellAbilityStackInstance stackInstance = game.getStack().getInstanceFromSpellAbility(targetSpell);
@@ -1284,8 +1292,8 @@ public class AbilityUtils {
}
}
}
else if (defined.startsWith("Triggered")) {
final SpellAbility root = sa.getRootAbility();
else if (defined.startsWith("Triggered") && sa instanceof SpellAbility) {
final SpellAbility root = ((SpellAbility)sa).getRootAbility();
final String triggeringType = defined.substring(9);
final Object o = root.getTriggeringObject(AbilityKey.fromString(triggeringType));
@@ -1584,6 +1592,7 @@ public class AbilityUtils {
final String s2 = AbilityUtils.applyAbilityTextChangeEffects(s, ctb);
final String[] l = s2.split("/");
final String expr = CardFactoryUtil.extractOperators(s2);
final Player player = ctb instanceof SpellAbility ? ((SpellAbility)ctb).getActivatingPlayer() : ctb.getHostCard().getController();
final String[] sq;
sq = l[0].split("\\.");
@@ -1781,13 +1790,6 @@ public class AbilityUtils {
}
}
if (l[0].startsWith("CountersAddedThisTurn")) {
final String[] parts = l[0].split(" ");
CounterType cType = CounterType.getType(parts[1]);
return CardFactoryUtil.doXMath(game.getCounterAddedThisTurn(cType, parts[2], parts[3], c, sa.getActivatingPlayer(), sa), expr, c);
}
if (sq[0].startsWith("CastTotalManaSpent")) {
return CardFactoryUtil.doXMath(c.getCastSA() != null ? c.getCastSA().getTotalManaSpent() : 0, expr, c);
}
@@ -1804,12 +1806,13 @@ public class AbilityUtils {
return CardFactoryUtil.doXMath(v, expr, c);
}
}
if (ctb instanceof TriggerReplacementBase) {
if (ctb instanceof CardTraitBase) {
if (l[0].startsWith("CountersAddedThisTurn")) {
final String[] parts = l[0].split(" ");
CounterType cType = CounterType.getType(parts[1]);
return CardFactoryUtil.doXMath(game.getCounterAddedThisTurn(cType, parts[2], parts[3], c, ctb.getHostCard().getController(), null), expr, c);
return CardFactoryUtil.doXMath(game.getCounterAddedThisTurn(cType, parts[2], parts[3], c, player, ctb), expr, c);
}
}
}

View File

@@ -199,7 +199,7 @@ public class AttachEffect extends SpellAbilityEffect {
final FCollection<Player> players = new FCollection<>();
for (Player player : game.getPlayers()) {
if (player.isValid(tgt.getValidTgts(), aura.getActivatingPlayer(), source, null)) {
if (player.isValid(tgt.getValidTgts(), aura.getActivatingPlayer(), source, aura)) {
players.add(player);
}
}

View File

@@ -41,7 +41,7 @@ public class BalanceEffect extends SpellAbilityEffect {
for(int i = 0; i < players.size(); i++) {
// Find the minimum of each Valid per player
validCards.add(CardLists.getValidCards(players.get(i).getCardsIn(zone), valid, activator, source));
validCards.add(CardLists.getValidCards(players.get(i).getCardsIn(zone), valid, activator, source, sa));
min = Math.min(min, validCards.get(i).size());
}

View File

@@ -79,7 +79,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
}
if (origin.contains(ZoneType.Library) && sa.hasParam("Search") && sa.getActivatingPlayer().canSearchLibraryWith(sa, null)) {
CardCollection libCards = CardLists.getValidCards(cards, "Card.inZoneLibrary", sa.getActivatingPlayer(), source);
CardCollection libCards = CardLists.getValidCards(cards, "Card.inZoneLibrary", sa.getActivatingPlayer(), source, sa);
CardCollection libCardsYouOwn = CardLists.filterControlledBy(libCards, sa.getActivatingPlayer());
if (!libCardsYouOwn.isEmpty()) { // Only searching one's own library would fire Archive Trap's altcost
sa.getActivatingPlayer().incLibrarySearched();
@@ -93,7 +93,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
game.getTriggerHandler().runTrigger(TriggerType.SearchedLibrary, runParams, false);
}
if (origin.contains(ZoneType.Hand) && sa.hasParam("Search")) {
CardCollection handCards = CardLists.filterControlledBy(CardLists.getValidCards(cards, "Card.inZoneHand", sa.getActivatingPlayer(), source),
CardCollection handCards = CardLists.filterControlledBy(CardLists.getValidCards(cards, "Card.inZoneHand", sa.getActivatingPlayer(), source, sa),
sa.getActivatingPlayer().getOpponents());
if (!handCards.isEmpty()) {
sa.getActivatingPlayer().getController().reveal(handCards, ZoneType.Hand, handCards.get(0).getOwner());

View File

@@ -583,7 +583,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("AttachedTo")) {
CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa);
if (list.isEmpty()) {
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachedTo"), gameCard.getController(), gameCard);
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachedTo"), gameCard.getController(), gameCard, sa);
}
if (!list.isEmpty()) {
Map<String, Object> params = Maps.newHashMap();
@@ -1104,7 +1104,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
if (totalcmc != null) {
if (totcmc >= 0) {
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + totcmc, source.getController(), source);
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + totcmc, source.getController(), source, sa);
}
}
@@ -1213,7 +1213,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("AttachedTo")) {
CardCollection list = AbilityUtils.getDefinedCards(source, sa.getParam("AttachedTo"), sa);
if (list.isEmpty()) {
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachedTo"), c.getController(), c);
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachedTo"), c.getController(), c, sa);
}
if (!list.isEmpty()) {
Card attachedTo = null;

View File

@@ -99,7 +99,7 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
}
} else if (chooseFromDefined) {
CardCollection choices = AbilityUtils.getDefinedCards(host, sa.getParam("ChooseFromDefinedCards"), sa);
choices = CardLists.getValidCards(choices, valid, host.getController(), host);
choices = CardLists.getValidCards(choices, valid, host.getController(), host, sa);
List<ICardFace> faces = Lists.newArrayList();
// get Card
for (final Card c : choices) {

View File

@@ -10,7 +10,6 @@ import forge.game.card.CardLists;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
@@ -36,7 +35,6 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
final Card host = sa.getHostCard();
final Game game = sa.getActivatingPlayer().getGame();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final List<Player> tgtPlayers = getTargetPlayers(sa);
CardCollection stackSources = new CardCollection();
@@ -85,11 +83,11 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
}
if (sa.hasParam("Choices")) {
permanentSources = CardLists.getValidCards(permanentSources, sa.getParam("Choices"), host.getController(), host);
permanentSources = CardLists.getValidCards(permanentSources, sa.getParam("Choices"), host.getController(), host, sa);
stackSources = CardLists.getValidCards(stackSources, sa.getParam("Choices"), host.getController(), host);
referencedSources = CardLists.getValidCards(referencedSources, sa.getParam("Choices"), host.getController(), host);
commandZoneSources = CardLists.getValidCards(commandZoneSources, sa.getParam("Choices"), host.getController(), host);
stackSources = CardLists.getValidCards(stackSources, sa.getParam("Choices"), host.getController(), host, sa);
referencedSources = CardLists.getValidCards(referencedSources, sa.getParam("Choices"), host.getController(), host, sa);
commandZoneSources = CardLists.getValidCards(commandZoneSources, sa.getParam("Choices"), host.getController(), host, sa);
}
if (sa.hasParam("TargetControls")) {
permanentSources = CardLists.filterControlledBy(permanentSources, tgtPlayers.get(0));
@@ -133,7 +131,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
for (final Player p : tgtPlayers) {
final CardCollection chosen = new CardCollection();
if (tgt == null || p.canBeTargetedBy(sa)) {
if (!sa.usesTargeting() || p.canBeTargetedBy(sa)) {
for (int i = 0; i < validAmount; i++) {
final String choiceTitle = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseSource") + " ";
Card o = null;

View File

@@ -81,7 +81,7 @@ public class CloneEffect extends SpellAbilityEffect {
}
}
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") + " ";
cardToCopy = activator.getController().chooseSingleEntityForEffect(choices, sa, title, false, null);

View File

@@ -44,7 +44,7 @@ public class ControlGainVariantEffect extends SpellAbilityEffect {
}
CardCollection tgtCards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield),
sa.getParam("AllValid"), source.getController(), source);
sa.getParam("AllValid"), source.getController(), source, sa);
if ("NextPlayerInChosenDirection".equals(controller) && (source.getChosenDirection() != null) ) {// Aminatou, the Fateshifter
for (final Player p : players) {

View File

@@ -136,7 +136,7 @@ public class CopyPermanentEffect extends TokenEffectBase {
// For Mimic Vat with mutated creature, need to choose one imprinted card
CardCollectionView choices = sa.hasParam("Defined") ? getDefinedCardsOrTargeted(sa) : game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
if (!choices.isEmpty()) {
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard");

View File

@@ -51,7 +51,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
}
CardCollectionView cards = game.getCardsIn(zone);
cards = CardLists.getValidCards(cards, valid, host.getController(), sa.getHostCard());
cards = CardLists.getValidCards(cards, valid, host.getController(), sa.getHostCard(), sa);
if (sa.usesTargeting()) {
final Player pl = sa.getTargets().getFirstTargetedPlayer();

View File

@@ -52,7 +52,7 @@ public class CountersRemoveAllEffect extends SpellAbilityEffect {
final Game game = sa.getActivatingPlayer().getGame();
CardCollectionView cards = game.getCardsIn(zone);
cards = CardLists.getValidCards(cards, valid, sa.getHostCard().getController(), sa.getHostCard());
cards = CardLists.getValidCards(cards, valid, sa.getHostCard().getController(), sa.getHostCard(), sa);
if (sa.usesTargeting()) {
final Player pl = sa.getTargets().getFirstTargetedPlayer();

View File

@@ -66,7 +66,7 @@ public class DamageEachEffect extends DamageBaseEffect {
FCollectionView<Card> sources = game.getCardsIn(ZoneType.Battlefield);
if (sa.hasParam("ValidCards")) {
sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), card.getController(), card);
sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), card.getController(), card, sa);
}
final List<GameObject> tgts = getTargets(sa, "DefinedPlayers");

View File

@@ -135,7 +135,7 @@ public class DigEffect extends SpellAbilityEffect {
}
else if (sa.hasParam("RevealValid")) {
final String revealValid = sa.getParam("RevealValid");
final CardCollection toReveal = CardLists.getValidCards(top, revealValid, host.getController(), host);
final CardCollection toReveal = CardLists.getValidCards(top, revealValid, host.getController(), host, sa);
if (!toReveal.isEmpty()) {
game.getAction().reveal(toReveal, host.getController());
if (sa.hasParam("RememberRevealed")) {

View File

@@ -179,7 +179,7 @@ public class DiscardEffect extends SpellAbilityEffect {
if (!p.canDiscardBy(sa)) {
continue;
}
CardCollectionView dPHand = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), "Card.IsNotRemembered", p, source);
CardCollectionView dPHand = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), "Card.IsNotRemembered", p, source, sa);
if (dPHand.size() > 1) {
dPHand = GameActionUtil.orderCardsByTheirOwners(game, dPHand, ZoneType.Graveyard, sa);
}
@@ -207,7 +207,7 @@ public class DiscardEffect extends SpellAbilityEffect {
if (runDiscard) {
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source);
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source, sa);
list = CardLists.filter(list, Presets.NON_TOKEN);
CardCollection toDiscard = new CardCollection();
for (int i = 0; i < numCards; i++) {

View File

@@ -33,7 +33,7 @@ public class ManifestEffect extends SpellAbilityEffect {
}
CardCollection choices = new CardCollection(game.getCardsIn(choiceZone));
if (sa.hasParam("Choices")) {
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, source);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, source, sa);
}
if (choices.isEmpty()) {
continue;

View File

@@ -80,7 +80,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
} else {
pool = new CardCollection(p.getCardsIn(zone));
}
pool = CardLists.getValidCards(pool, valid, source.getController(), source);
pool = CardLists.getValidCards(pool, valid, source.getController(), source, sa);
List<CardCollectionView> pileList = Lists.newArrayList();

View File

@@ -41,7 +41,7 @@ public class MustBlockEffect extends SpellAbilityEffect {
}
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host, sa);
if (!choices.isEmpty()) {
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") +" ";
Map<String, Object> params = Maps.newHashMap();

View File

@@ -54,7 +54,7 @@ public class PeekAndRevealEffect extends SpellAbilityEffect {
peekCards.add(library.get(i));
}
CardCollectionView revealableCards = CardLists.getValidCards(peekCards, revealValid, sa.getActivatingPlayer(), sa.getHostCard());
CardCollectionView revealableCards = CardLists.getValidCards(peekCards, revealValid, sa.getActivatingPlayer(), sa.getHostCard(), sa);
boolean doReveal = !sa.hasParam("NoReveal") && !revealableCards.isEmpty();
if (!sa.hasParam("NoPeek")) {
peekingPlayer.getController().reveal(peekCards, ZoneType.Library, peekingPlayer, CardTranslation.getTranslatedName(source.getName()) + " - " + Localizer.getInstance().getMessage("lblRevealingCardFrom") + " ");

View File

@@ -87,7 +87,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
}
if (!valid.equals("")) {
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), host);
list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), host, sa);
for (final Card tgtC : list) {
if (tgtC.isInPlay()) {

View File

@@ -54,7 +54,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
zone.add(ZoneType.Battlefield);
}
repeatCards = CardLists.getValidCards(game.getCardsIn(zone),
sa.getParam("RepeatCards"), source.getController(), source);
sa.getParam("RepeatCards"), source.getController(), source, sa);
}
else if (sa.hasParam(("RepeatSpellAbilities"))) {
repeatSas = Lists.newArrayList();
@@ -70,7 +70,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
repeatCards = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
if (sa.hasParam("AdditionalRestriction")) { // lki cards might not be in game
repeatCards = CardLists.getValidCards(repeatCards,
sa.getParam("AdditionalRestriction"), source.getController(), source);
sa.getParam("AdditionalRestriction"), source.getController(), source, sa);
}
}
boolean loopOverCards = repeatCards != null && !repeatCards.isEmpty();

View File

@@ -42,7 +42,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
List<Card> filteredCards = null;
if (leaveZone != null) {
filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction.split(","), p, sa.getHostCard(), null);
filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction, p, sa.getHostCard(), sa);
newLibrary.addAll(filteredCards);
}

View File

@@ -53,7 +53,7 @@ public class RevealEffect extends SpellAbilityEffect {
CardCollection valid = new CardCollection(cardsInHand);
if (sa.hasParam("RevealValid")) {
valid = CardLists.getValidCards(valid, sa.getParam("RevealValid"), p, host);
valid = CardLists.getValidCards(valid, sa.getParam("RevealValid"), p, host, sa);
}
if (valid.isEmpty())

View File

@@ -83,7 +83,7 @@ public class TwoPilesEffect extends SpellAbilityEffect {
} else {
pool0 = p.getCardsIn(zone);
}
CardCollection pool = CardLists.getValidCards(pool0, valid, card.getController(), card);
CardCollection pool = CardLists.getValidCards(pool0, valid, card.getController(), card, sa);
int size = pool.size();
if (size == 0) {
return;

View File

@@ -72,7 +72,7 @@ public class UntapEffect extends SpellAbilityEffect {
for (final Player p : AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Defined"), sa)) {
CardCollectionView list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield),
valid, sa.getActivatingPlayer(), sa.getHostCard());
valid, sa.getActivatingPlayer(), sa.getHostCard(), sa);
list = CardLists.filter(list, Presets.TAPPED);
final CardCollectionView selected = p.getController().chooseCardsForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectCardToUntap"), mandatory ? num : 0, num, !mandatory, null);

View File

@@ -59,7 +59,7 @@ public class VoteEffect extends SpellAbilityEffect {
voteType.addAll(Arrays.asList(sa.getParam("VoteType").split(",")));
} else if (sa.hasParam("VoteCard")) {
ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield;
voteType.addAll(CardLists.getValidCards(game.getCardsIn(zone), sa.getParam("VoteCard"), host.getController(), host));
voteType.addAll(CardLists.getValidCards(game.getCardsIn(zone), sa.getParam("VoteCard"), host.getController(), host, sa));
}
if (voteType.isEmpty()) {
return;

View File

@@ -64,7 +64,7 @@ public class ZoneExchangeEffect extends SpellAbilityEffect {
filter = "Card";
}
list = CardLists.getValidCards(list, filter, p, source);
list = CardLists.getValidCards(list, filter, p, source, sa);
if (list.isEmpty()) {
// Nothing to exchange the object?
return;

View File

@@ -2265,7 +2265,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
continue;
}
final Card host = stAb.getHostCard();
if (isValid(stAb.getParam("ValidAttacker").split(","), host.getController(), host, null)) {
if (isValid(stAb.getParam("ValidAttacker").split(","), host.getController(), host, stAb)) {
String currentName = (host.getName());
String desc1 = TextUtil.fastReplace(stAb.toString(), "CARDNAME", currentName);
String desc = TextUtil.fastReplace(desc1,"NICKNAME", currentName.split(",")[0]);
@@ -4678,7 +4678,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// Takes one argument like Permanent.Blue+withFlying
@Override
public final boolean isValid(final String restriction, final Player sourceController, final Card source, SpellAbility spellAbility) {
public final boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
if (isImmutable() && source != null && !source.isRemembered(this) &&
!(restriction.startsWith("Emblem") || restriction.startsWith("Effect"))) { // special case exclusion
return false;
@@ -4718,7 +4718,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// Takes arguments like Blue or withFlying
@Override
public boolean hasProperty(final String property, final Player sourceController, final Card source, SpellAbility spellAbility) {
public boolean hasProperty(final String property, final Player sourceController, final Card source, CardTraitBase spellAbility) {
return CardProperty.cardHasProperty(this, property, sourceController, source, spellAbility);
}

View File

@@ -13,6 +13,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import forge.game.CardTraitBase;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameObjectPredicates;
@@ -114,7 +115,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
return result;
}
public CardDamageMap filteredMap(String validSource, String validTarget, Card host, SpellAbility sa) {
public CardDamageMap filteredMap(String validSource, String validTarget, Card host, CardTraitBase sa) {
CardDamageMap result = new CardDamageMap();
Set<Card> filteredSource = null;
Set<GameEntity> filteredTarget = null;

View File

@@ -821,13 +821,13 @@ public class CardFactoryUtil {
if (l[0].startsWith("MostProminentCreatureType")) {
String restriction = l[0].split(" ")[1];
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, cc, c);
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, cc, c, null);
return doXMath(getMostProminentCreatureTypeSize(list), m, c);
}
if (l[0].startsWith("SecondMostProminentColor")) {
String restriction = l[0].split(" ")[1];
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, cc, c);
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, cc, c, null);
int[] colorSize = SortColorsFromList(list);
return doXMath(colorSize[colorSize.length - 2], m, c);
}
@@ -986,7 +986,7 @@ public class CardFactoryUtil {
if (sq[0].contains("YourDamageSourcesThisTurn")) {
Iterable<Card> allSrc = cc.getAssignedDamageSources();
String restriction = sq[0].split(" ")[1];
CardCollection filtered = CardLists.getValidCards(allSrc, restriction, cc, c);
CardCollection filtered = CardLists.getValidCards(allSrc, restriction, cc, c, null);
return doXMath(filtered.size(), m, c);
}
@@ -1831,7 +1831,7 @@ public class CardFactoryUtil {
final String[] splitString = string.split("/", 2);
String valid = splitString[0].substring(6);
final List<Card> list = CardLists.getValidCardsAsList(paidList, valid, source.getController(), source);
final List<Card> list = CardLists.getValidCardsAsList(paidList, valid, source.getController(), source, null);
return doXMath(list.size(), splitString.length > 1 ? splitString[1] : null, source);
}

View File

@@ -26,6 +26,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.game.CardTraitBase;
import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
@@ -212,32 +213,20 @@ public class CardLists {
return CardLists.filterAsList(cardList, CardPredicates.isControlledByAnyOf(player));
}
public static CardCollection getValidCards(Iterable<Card> cardList, String[] restrictions, Player sourceController, Card source, SpellAbility spellAbility) {
public static CardCollection getValidCards(Iterable<Card> cardList, String[] restrictions, Player sourceController, Card source, CardTraitBase spellAbility) {
return CardLists.filter(cardList, CardPredicates.restriction(restrictions, sourceController, source, spellAbility));
}
public static List<Card> getValidCardsAsList(Iterable<Card> cardList, String[] restrictions, Player sourceController, Card source) {
return CardLists.filterAsList(cardList, CardPredicates.restriction(restrictions, sourceController, source, null));
}
public static int getValidCardCount(Iterable<Card> cardList, String[] restrictions, Player sourceController, Card source) {
return CardLists.count(cardList, CardPredicates.restriction(restrictions, sourceController, source, null));
}
public static CardCollection getValidCards(Iterable<Card> cardList, String restriction, Player sourceController, Card source) {
return CardLists.filter(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, null));
}
public static CardCollection getValidCards(Iterable<Card> cardList, String restriction, Player sourceController, Card source, SpellAbility sa) {
public static CardCollection getValidCards(Iterable<Card> cardList, String restriction, Player sourceController, Card source, CardTraitBase sa) {
return CardLists.filter(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, sa));
}
public static List<Card> getValidCardsAsList(Iterable<Card> cardList, String restriction, Player sourceController, Card source) {
return CardLists.filterAsList(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, null));
public static List<Card> getValidCardsAsList(Iterable<Card> cardList, String restriction, Player sourceController, Card source, CardTraitBase sa) {
return CardLists.filterAsList(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, sa));
}
public static int getValidCardCount(Iterable<Card> cardList, String restriction, Player sourceController, Card source) {
return CardLists.count(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, null));
public static int getValidCardCount(Iterable<Card> cardList, String restriction, Player sourceController, Card source, CardTraitBase sa) {
return CardLists.count(cardList, CardPredicates.restriction(restriction.split(","), sourceController, source, sa));
}
public static CardCollection getTargetableCards(Iterable<Card> cardList, SpellAbility source) {

View File

@@ -22,6 +22,7 @@ import java.util.Comparator;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import forge.game.CardTraitBase;
import forge.game.combat.CombatUtil;
import forge.game.keyword.Keyword;
import forge.game.keyword.KeywordInterface;
@@ -207,7 +208,7 @@ public final class CardPredicates {
};
}
public static final Predicate<Card> restriction(final String[] restrictions, final Player sourceController, final Card source, final SpellAbility spellAbility) {
public static final Predicate<Card> restriction(final String[] restrictions, final Player sourceController, final Card source, final CardTraitBase spellAbility) {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {

View File

@@ -7,6 +7,7 @@ import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.game.CardTraitBase;
import forge.game.Direction;
import forge.game.EvenOdd;
import forge.game.Game;
@@ -35,7 +36,7 @@ import java.util.List;
public class CardProperty {
public static boolean cardHasProperty(Card card, String property, Player sourceController, Card source, SpellAbility spellAbility) {
public static boolean cardHasProperty(Card card, String property, Player sourceController, Card source, CardTraitBase spellAbility) {
final Game game = card.getGame();
final Combat combat = game.getCombat();
// lki can't be null but it does return this
@@ -407,8 +408,8 @@ public class CardProperty {
if (!card.equals(source.getEffectSource())) {
return false;
}
} else if (property.equals("CanBeSacrificedBy")) {
if (!card.canBeSacrificedBy(spellAbility)) {
} else if (property.equals("CanBeSacrificedBy") && spellAbility instanceof SpellAbility) {
if (!card.canBeSacrificedBy((SpellAbility)spellAbility)) {
return false;
}
} else if (property.startsWith("AttachedBy")) {
@@ -886,13 +887,13 @@ public class CardProperty {
} else {
final String restriction = property.split("sharesNameWith ")[1];
if (restriction.equals("YourGraveyard")) {
return !CardLists.filter(sourceController.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card)).isEmpty();
return Iterables.any(sourceController.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card));
} else if (restriction.equals(ZoneType.Graveyard.toString())) {
return !CardLists.filter(game.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card)).isEmpty();
return Iterables.any(game.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card));
} else if (restriction.equals(ZoneType.Battlefield.toString())) {
return !CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.sharesNameWith(card)).isEmpty();
return Iterables.any(game.getCardsIn(ZoneType.Battlefield), CardPredicates.sharesNameWith(card));
} else if (restriction.equals("ThisTurnCast")) {
return !CardLists.filter(CardUtil.getThisTurnCast("Card", source), CardPredicates.sharesNameWith(card)).isEmpty();
return Iterables.any(CardUtil.getThisTurnCast("Card", source), CardPredicates.sharesNameWith(card));
} else if (restriction.equals("MovedToGrave")) {
for (final SpellAbility sa : source.getCurrentState().getNonManaAbilities()) {
final SpellAbility root = sa.getRootAbility();
@@ -915,10 +916,10 @@ public class CardProperty {
return !CardLists.filter(game.getCardsIn(ZoneType.Battlefield),
Presets.NON_TOKEN, CardPredicates.sharesNameWith(card)).isEmpty();
} else if (restriction.equals("TriggeredCard")) {
if (spellAbility == null) {
if (!(spellAbility instanceof SpellAbility)) {
System.out.println("Looking at TriggeredCard but no SA?");
} else {
Card triggeredCard = ((Card) spellAbility.getTriggeringObject(AbilityKey.Card));
Card triggeredCard = ((Card)((SpellAbility)spellAbility).getTriggeringObject(AbilityKey.Card));
if (triggeredCard != null && card.sharesNameWith(triggeredCard)) {
return true;
}
@@ -939,9 +940,9 @@ public class CardProperty {
final String restriction = property.split("doesNotShareNameWith ")[1];
if (restriction.startsWith("Remembered") || restriction.startsWith("Imprinted")) {
CardCollection list = AbilityUtils.getDefinedCards(source, restriction, spellAbility);
return CardLists.filter(list, CardPredicates.sharesNameWith(card)).isEmpty();
return !Iterables.any(list, CardPredicates.sharesNameWith(card));
} else if (restriction.equals("YourGraveyard")) {
return CardLists.filter(sourceController.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card)).isEmpty();
return !Iterables.any(sourceController.getCardsIn(ZoneType.Graveyard), CardPredicates.sharesNameWith(card));
} else if (restriction.equals("OtherYourBattlefield")) {
// Obviously it's going to share a name with itself, so consider that in the
CardCollection list = CardLists.filter(sourceController.getCardsIn(ZoneType.Battlefield), CardPredicates.sharesNameWith(card));
@@ -1807,8 +1808,11 @@ public class CardProperty {
return false;
} else if (property.startsWith("NotTriggered")) {
final String key = property.substring("NotTriggered".length());
Object obj = spellAbility.getTriggeringObject(AbilityKey.fromString(key));
if (card.equals(obj)) {
if (spellAbility instanceof SpellAbility) {
if (card.equals(((SpellAbility)spellAbility).getTriggeringObject(AbilityKey.fromString(key)))) {
return false;
}
} else {
return false;
}
} else if (property.startsWith("NotDefined")) {
@@ -1817,6 +1821,9 @@ public class CardProperty {
return false;
}
} else if (property.equals("CanPayManaCost")) {
if (!(spellAbility instanceof SpellAbility)) {
return false;
}
final class CheckCanPayManaCost {
private List<Mana> manaPaid;
private List<ManaCostShard> manaCost;
@@ -1857,7 +1864,7 @@ public class CardProperty {
return false;
}
boolean check() {
manaPaid = Lists.newArrayList(spellAbility.getPayingMana());
manaPaid = Lists.newArrayList(((SpellAbility)spellAbility).getPayingMana());
manaCost = Lists.newArrayList(card.getManaCost());
Collections.sort(manaCost);
//It seems the above codes didn't add generic mana cost ?

View File

@@ -640,7 +640,7 @@ public class CardState extends GameObject implements IHasSVars {
* @see forge.game.GameObject#hasProperty(java.lang.String, forge.game.player.Player, forge.game.card.Card, forge.game.spellability.SpellAbility)
*/
@Override
public boolean hasProperty(String property, Player sourceController, Card source, SpellAbility spellAbility) {
public boolean hasProperty(String property, Player sourceController, Card source, CardTraitBase spellAbility) {
return ForgeScript.cardStateHasProperty(this, property, sourceController, source, spellAbility);
}

View File

@@ -119,7 +119,7 @@ public final class CardUtil {
else {
res.addAll(game.getStackZone().getCardsAddedThisTurn(from));
}
res = CardLists.getValidCardsAsList(res, valid, src.getController(), src);
res = CardLists.getValidCardsAsList(res, valid, src.getController(), src, null);
return res;
}
@@ -143,16 +143,16 @@ public final class CardUtil {
else {
res.addAll(game.getStackZone().getCardsAddedLastTurn(from));
}
res = CardLists.getValidCardsAsList(res, valid, src.getController(), src);
res = CardLists.getValidCardsAsList(res, valid, src.getController(), src, null);
return res;
}
public static List<Card> getThisTurnCast(final String valid, final Card src) {
return CardLists.getValidCardsAsList(src.getGame().getStack().getSpellsCastThisTurn(), valid, src.getController(), src);
return CardLists.getValidCardsAsList(src.getGame().getStack().getSpellsCastThisTurn(), valid, src.getController(), src, null);
}
public static List<Card> getLastTurnCast(final String valid, final Card src) {
return CardLists.getValidCardsAsList(src.getGame().getStack().getSpellsCastLastTurn(), valid, src.getController(), src);
return CardLists.getValidCardsAsList(src.getGame().getStack().getSpellsCastLastTurn(), valid, src.getController(), src, null);
}
@@ -410,7 +410,7 @@ public final class CardUtil {
sa.setActivatingPlayer(sa.getHostCard().getController());
}
final Game game = sa.getActivatingPlayer().getGame();
cards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), validCard, abMana.getActivatingPlayer(), card);
cards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), validCard, abMana.getActivatingPlayer(), card, sa);
}
// remove anything cards that is already in parents

View File

@@ -10,9 +10,9 @@ import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Table;
import forge.game.CardTraitBase;
import forge.game.Game;
import forge.game.ability.AbilityKey;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
@@ -61,7 +61,7 @@ public class CardZoneTable extends ForwardingTable<ZoneType, ZoneType, CardColle
}
}
public CardCollection filterCards(Iterable<ZoneType> origin, ZoneType destination, String valid, Card host, SpellAbility sa) {
public CardCollection filterCards(Iterable<ZoneType> origin, ZoneType destination, String valid, Card host, CardTraitBase sa) {
CardCollection allCards = new CardCollection();
if (destination != null) {
if (!containsColumn(destination)) {

View File

@@ -55,7 +55,7 @@ public class AttackingBand {
// Check if a bands with other keyword exists in band, and each creature in the band fits the valid quality
if (!CardLists.getKeyword(band, keyword).isEmpty() &&
CardLists.getValidCards(band, valid, source.getController(), source).size() == band.size()) {
CardLists.getValidCards(band, valid, source.getController(), source, null).size() == band.size()) {
return true;
}
}

View File

@@ -833,7 +833,7 @@ public class CombatUtil {
if (keyword.startsWith("MustBeBlockedBy ")) {
final String valid = keyword.substring("MustBeBlockedBy ".length());
if (blocker.isValid(valid, null, null, null) &&
CardLists.getValidCardCount(combat.getBlockers(attacker), valid, null, null) == 0) {
CardLists.getValidCardCount(combat.getBlockers(attacker), valid, null, null, null) == 0) {
attackersWithLure.add(attacker);
break;
}
@@ -954,7 +954,7 @@ public class CombatUtil {
if (keyword.startsWith("MustBeBlockedBy ")) {
final String valid = keyword.substring("MustBeBlockedBy ".length());
if (blocker.isValid(valid, null, null, null) &&
CardLists.getValidCardCount(combat.getBlockers(attacker), valid, null, null) == 0) {
CardLists.getValidCardCount(combat.getBlockers(attacker), valid, null, null, null) == 0) {
mustBeBlockedBy = true;
break;
}

View File

@@ -421,17 +421,13 @@ public class CostAdjustment {
final Card card = sa.getHostCard();
final Game game = hostCard.getGame();
if (st.hasParam("ValidCard")
&& !card.isValid(st.getParam("ValidCard").split(","), controller, hostCard, sa)) {
if (st.hasParam("ValidCard") && !st.matchesValid(card, st.getParam("ValidCard").split(","))) {
return false;
}
if (st.hasParam("ValidSpell")) {
if (!sa.isValid(st.getParam("ValidSpell").split(","), controller, hostCard, sa)) {
return false;
}
if (st.hasParam("ValidSpell") && !st.matchesValid(sa, st.getParam("ValidSpell").split(","))) {
return false;
}
if (st.hasParam("Activator") && ((activator == null)
|| !activator.isValid(st.getParam("Activator"), controller, hostCard, sa))) {
if (st.hasParam("Activator") && !st.matchesValid(activator, st.getParam("Activator").split(","))) {
return false;
}
if (st.hasParam("NonActivatorTurn") && ((activator == null)
@@ -458,7 +454,7 @@ public class CostAdjustment {
if (st.hasParam("ValidSpell")) {
list = CardLists.filterAsList(list, CardPredicates.castSA(
SpellAbilityPredicates.isValid(st.getParam("ValidSpell").split(","), controller, hostCard, sa))
SpellAbilityPredicates.isValid(st.getParam("ValidSpell").split(","), controller, hostCard, st))
);
}

View File

@@ -79,7 +79,7 @@ public class CostUnattach extends CostPartWithList {
Card originalEquipment = ability.getOriginalHost();
return originalEquipment.isEquipping();
} else {
return CardLists.getValidCards(source.getEquippedBy(), type, payer, source).size() > 0;
return CardLists.getValidCards(source.getEquippedBy(), type, payer, source, ability).size() > 0;
}
}
@@ -95,7 +95,7 @@ public class CostUnattach extends CostPartWithList {
return originalEquipment;
}
} else {
List<Card> attachees = CardLists.getValidCards(source.getEquippedBy(), this.getType(), activator, source);
List<Card> attachees = CardLists.getValidCards(source.getEquippedBy(), this.getType(), activator, source, ability);
if (attachees.size() > 0) {
// Just pick the first one, although maybe give a dialog
return attachees.get(0);

View File

@@ -182,7 +182,7 @@ public class Untap extends Phase {
Map<String, Integer> remaining = Maps.newHashMap(restrictUntap);
for (Entry<String, Integer> entry : remaining.entrySet()) {
if (entry.getValue() == 0) {
cardList.removeAll(CardLists.getValidCards(cardList, entry.getKey(), player, null));
cardList.removeAll(CardLists.getValidCards(cardList, entry.getKey(), player, null, null));
restrictUntap.remove(entry.getKey());
}
}

View File

@@ -2242,7 +2242,7 @@ public class Player extends GameEntity implements Comparable<Player> {
}
@Override
public final boolean isValid(final String restriction, final Player sourceController, final Card source, SpellAbility spellAbility) {
public final boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
final String[] incR = restriction.split("\\.", 2);
@@ -2283,7 +2283,7 @@ public class Player extends GameEntity implements Comparable<Player> {
}
@Override
public final boolean hasProperty(final String property, final Player sourceController, final Card source, SpellAbility spellAbility) {
public final boolean hasProperty(final String property, final Player sourceController, final Card source, CardTraitBase spellAbility) {
return PlayerProperty.playerHasProperty(this, property, sourceController, source, spellAbility);
}

View File

@@ -1,12 +1,12 @@
package forge.game.player;
import forge.game.CardTraitBase;
import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
import forge.game.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Expressions;
import forge.util.TextUtil;
@@ -16,7 +16,7 @@ import java.util.List;
public class PlayerProperty {
public static boolean playerHasProperty(Player player, String property, Player sourceController, Card source, SpellAbility spellAbility) {
public static boolean playerHasProperty(Player player, String property, Player sourceController, Card source, CardTraitBase spellAbility) {
Game game = player.getGame();
if (property.equals("You")) {
@@ -236,7 +236,7 @@ public class PlayerProperty {
}
} else if (property.startsWith("controls")) {
final String[] type = property.substring(8).split("_");
final CardCollectionView list = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type[0], sourceController, source);
final CardCollectionView list = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type[0], sourceController, source, spellAbility);
String comparator = type[1];
int y = AbilityUtils.calculateAmount(source, comparator.substring(2), null);
if (!Expressions.compare(list.size(), comparator, y)) {
@@ -244,7 +244,7 @@ public class PlayerProperty {
}
} else if (property.startsWith("HasCardsIn")) { // HasCardsIn[zonetype]_[cardtype]_[comparator]
final String[] type = property.substring(10).split("_");
final CardCollectionView list = CardLists.getValidCards(player.getCardsIn(ZoneType.smartValueOf(type[0])), type[1], sourceController, source);
final CardCollectionView list = CardLists.getValidCards(player.getCardsIn(ZoneType.smartValueOf(type[0])), type[1], sourceController, source, spellAbility);
String comparator = type[2];
int y = AbilityUtils.calculateAmount(source, comparator.substring(2), null);
if (!Expressions.compare(list.size(), comparator, y)) {

View File

@@ -40,32 +40,18 @@ public class ReplaceAddCounter extends ReplacementEffect {
}
}
if (hasParam("ValidCard")) {
Object o = runParams.get(AbilityKey.Affected);
if (!(o instanceof Card)) {
return false;
}
if (!matchesValid(o, getParam("ValidCard").split(","), getHostCard())) {
return false;
}
} else if (hasParam("ValidPlayer")) {
Object o = runParams.get(AbilityKey.Affected);
if (!(o instanceof Player)) {
return false;
}
if (!matchesValid(o, getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
} else if (hasParam("ValidObject")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidObject").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (!matchesValidParam("ValidObject", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidSource")) {
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Source))) {
return false;
}
if (hasParam("ValidCounterType")) {

View File

@@ -27,10 +27,8 @@ public class ReplaceAssignDealDamage extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -27,15 +27,11 @@ public class ReplaceAttached extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidTarget")) {
if (!matchesValid(runParams.get(AbilityKey.AttachTarget), getParam("ValidTarget").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.AttachTarget))) {
return false;
}
return true;
}

View File

@@ -14,10 +14,8 @@ public class ReplaceBeginTurn extends ReplacementEffect {
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ExtraTurn")) {
if (!(boolean) runParams.get(AbilityKey.ExtraTurn)) {

View File

@@ -20,15 +20,11 @@ public class ReplaceCopySpell extends ReplacementEffect {
if (((int) runParams.get(AbilityKey.Amount)) <= 0) {
return false;
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidSpell")) {
if (!matchesValid(runParams.get(AbilityKey.SpellAbility), getParam("ValidSpell").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSpell", runParams.get(AbilityKey.SpellAbility))) {
return false;
}
return true;
}

View File

@@ -44,18 +44,15 @@ public class ReplaceCounter extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
final SpellAbility spellAbility = (SpellAbility) runParams.get(AbilityKey.TgtSA);
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidCause")) {
if (!matchesValid(runParams.get(AbilityKey.Cause), getParam("ValidCause").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
return false;
}
if (hasParam("ValidType")) {
final SpellAbility spellAbility = (SpellAbility) runParams.get(AbilityKey.TgtSA);
String type = getParam("ValidType");
if (type.equals("Spell") && !spellAbility.isSpell()) {
return false;

View File

@@ -58,40 +58,24 @@ public class ReplaceDamage extends ReplacementEffect {
// If no actual damage is dealt, there is nothing to replace
return false;
}
if (hasParam("ValidSource")) {
String validSource = getParam("ValidSource");
validSource = AbilityUtils.applyAbilityTextChangeEffects(validSource, this);
if (!matchesValid(runParams.get(AbilityKey.DamageSource), validSource.split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.DamageSource))) {
return false;
}
if (hasParam("ValidTarget")) {
String validTarget = getParam("ValidTarget");
validTarget = AbilityUtils.applyAbilityTextChangeEffects(validTarget, this);
if (!matchesValid(runParams.get(AbilityKey.Affected), validTarget.split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidCause")) {
if (!runParams.containsKey(AbilityKey.Cause)) {
return false;
}
if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
return false;
}
if (hasParam("CauseIsSource")) {
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
String validCause = getParam("ValidCause");
validCause = AbilityUtils.applyAbilityTextChangeEffects(validCause, this);
if (!matchesValid(cause, validCause.split(","), getHostCard())) {
if (!cause.getHostCard().equals(runParams.get(AbilityKey.DamageSource))) {
return false;
}
if (hasParam("CauseIsSource")) {
if (!cause.getHostCard().equals(runParams.get(AbilityKey.DamageSource))) {
return false;
}
}
}
if (hasParam("RelativeToSource")) {
Card source = (Card) runParams.get(AbilityKey.DamageSource);
String validRelative = getParam("RelativeToSource");
validRelative = AbilityUtils.applyAbilityTextChangeEffects(validRelative, this);
if (!matchesValid(runParams.get(AbilityKey.DamageTarget), validRelative.split(","), source)) {
return false;
}
@@ -107,14 +91,8 @@ public class ReplaceDamage extends ReplacementEffect {
}
}
if (hasParam("IsCombat")) {
if (getParam("IsCombat").equals("True")) {
if (!((Boolean) runParams.get(AbilityKey.IsCombat))) {
return false;
}
} else {
if ((Boolean) runParams.get(AbilityKey.IsCombat)) {
return false;
}
if (getParam("IsCombat").equals("True") != ((Boolean) runParams.get(AbilityKey.IsCombat))) {
return false;
}
}
if (hasParam("IsEquipping") && !getHostCard().isEquipping()) {

View File

@@ -27,10 +27,8 @@ public class ReplaceDealtDamage extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -44,37 +44,30 @@ public class ReplaceDestroy extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
return false;
}
// extra check for Regeneration
if (hasParam("Regeneration")) {
Card card = (Card) runParams.get(AbilityKey.Card);
if (!runParams.containsKey(AbilityKey.Regeneration) || !(Boolean)runParams.get(AbilityKey.Regeneration)) {
return false;
}
if (!card.canBeShielded()) {
return false;
}
if (card.isCreature()) {
if (card.getNetToughness() <= 0)
return false;
}
}
if (hasParam("ValidCard")) {
Card card = (Card)runParams.get(AbilityKey.Card);
if (!matchesValid(card, getParam("ValidCard").split(","), getHostCard())) {
return false;
}
// extra check for Regeneration
if (hasParam("Regeneration")) {
if (!runParams.containsKey(AbilityKey.Regeneration)) {
return false;
}
if (!(Boolean)runParams.get(AbilityKey.Regeneration)) {
return false;
}
if (!card.canBeShielded()) {
return false;
}
if (card.isCreature()) {
if (card.getNetToughness() <= 0)
return false;
}
}
}
if (hasParam("ValidSource")) {
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Source))) {
return false;
}
return true;

View File

@@ -44,21 +44,17 @@ public class ReplaceDiscard extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Card), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
return false;
}
if (hasParam("ValidSource")) {
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Source))) {
return false;
}
if (hasParam("Cycling")) {
if (getParam("Cycling").equalsIgnoreCase("True") != runParams.containsKey(AbilityKey.Cycling)) {
return false;

View File

@@ -47,27 +47,16 @@ public class ReplaceDraw extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
final Game game = this.getHostCard().getGame();
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidCause")) {
if (!runParams.containsKey(AbilityKey.Cause)) {
return false;
}
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
if (cause == null) {
return false;
}
if (!matchesValid(cause, getParam("ValidCause").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
return false;
}
if (hasParam("NotFirstCardInDrawStep")) {
final Game game = getHostCard().getGame();
final Player p = (Player)runParams.get(AbilityKey.Affected);
if (p.numDrawnThisDrawStep() == 0 && game.getPhaseHandler().is(PhaseType.DRAW, p)) {
return false;

View File

@@ -45,10 +45,8 @@ public class ReplaceDrawCards extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("Number")) {
final int n = (Integer)runParams.get(AbilityKey.Number);

View File

@@ -47,15 +47,11 @@ public class ReplaceGainLife extends ReplacementEffect {
if (((int)runParams.get(AbilityKey.LifeGained)) <= 0) {
return false;
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidSource")) {
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Source))) {
return false;
}
if ("True".equals(getParam("SourceController"))) {
if (runParams.get(AbilityKey.Source) == null || !runParams.get(AbilityKey.Affected).equals(((Card)runParams.get(AbilityKey.Source)).getController())) {

View File

@@ -26,10 +26,8 @@ public class ReplaceGameLoss extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -43,11 +43,8 @@ public class ReplaceMill extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -30,16 +30,17 @@ public class ReplaceMoved extends ReplacementEffect {
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidLKI")) {
if (!matchesValid(runParams.get(AbilityKey.CardLKI), getParam("ValidLKI").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidLKI", runParams.get(AbilityKey.CardLKI))) {
return false;
}
if (!matchesValidParam("ValidStackSa", runParams.get(AbilityKey.StackSa))) {
return false;
}
if (!matchesValidParam("Cause", runParams.get(AbilityKey.Cause))) {
return false;
}
if (hasParam("Origin")) {
@@ -74,24 +75,6 @@ public class ReplaceMoved extends ReplacementEffect {
}
}
if (hasParam("ValidStackSa")) {
if (!matchesValid(runParams.get(AbilityKey.StackSa), getParam("ValidStackSa").split(","), getHostCard())) {
return false;
}
}
if (hasParam("Cause")) {
if (!matchesValid(runParams.get(AbilityKey.Cause), getParam("Cause").split(","), getHostCard())) {
return false;
}
}
if (hasParam("NotCause")) {
if (matchesValid(runParams.get(AbilityKey.Cause), getParam("NotCause").split(","), getHostCard())) {
return false;
}
}
if (hasParam("Cycling")) { // Cycling is by cost, not by effect so cause is null
if (getParam("Cycling").equalsIgnoreCase("True") != runParams.containsKey(AbilityKey.Cycling)) {
return false;

View File

@@ -32,11 +32,14 @@ public class ReplaceProduceMana extends ReplacementEffect {
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidAbility")) {
final SpellAbility manaAbility = (SpellAbility) runParams.get(AbilityKey.AbilityMana);
if (!matchesValid(manaAbility, getParam("ValidAbility").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) {
return false;
}
if (!matchesValidParam("ValidAbility", runParams.get(AbilityKey.AbilityMana))) {
return false;
}
if (hasParam("ManaAmount")) {
@@ -52,18 +55,6 @@ public class ReplaceProduceMana extends ReplacementEffect {
}
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Player), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
}
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), getHostCard())) {
return false;
}
}
return true;
}

View File

@@ -30,10 +30,8 @@ public class ReplaceScry extends ReplacementEffect {
return false;
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -43,10 +43,8 @@ public class ReplaceSetInMotion extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -30,11 +30,8 @@ public class ReplaceSurveil extends ReplacementEffect {
if (((int) runParams.get(AbilityKey.SurveilNum)) <= 0) {
return false;
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -27,10 +27,8 @@ public class ReplaceTap extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;

View File

@@ -38,22 +38,13 @@ public class ReplaceToken extends ReplacementEffect {
}
}
if (hasParam("ValidPlayer")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
return false;
}
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
return false;
}
if (!matchesValidParam("ValidToken", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("ValidToken")) {
if (runParams.containsKey(AbilityKey.Token)) {
if (!matchesValid(runParams.get(AbilityKey.Token), getParam("ValidToken").split(","), getHostCard())) {
return false;
}
} else {
// in case RE is not updated yet
return false;
}
}
return true;
}

View File

@@ -27,10 +27,8 @@ public class ReplaceTurnFaceUp extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;
}

View File

@@ -46,10 +46,8 @@ public class ReplaceUntap extends ReplacementEffect {
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (hasParam("ValidCard")) {
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidCard").split(","), this.getHostCard())) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
if (hasParam("UntapStep")) {
final Object o = runParams.get(AbilityKey.Affected);

View File

@@ -1906,7 +1906,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
// Takes one argument like Permanent.Blue+withFlying
@Override
public final boolean isValid(final String restriction, final Player sourceController, final Card source, SpellAbility spellAbility) {
public final boolean isValid(final String restriction, final Player sourceController, final Card source, CardTraitBase spellAbility) {
// Inclusive restrictions are Card types
final String[] incR = restriction.split("\\.", 2);
SpellAbility root = getRootAbility();
@@ -1949,7 +1949,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
// Takes arguments like Blue or withFlying
@Override
public boolean hasProperty(final String property, final Player sourceController, final Card source, SpellAbility spellAbility) {
public boolean hasProperty(final String property, final Player sourceController, final Card source, CardTraitBase spellAbility) {
return ForgeScript.spellAbilityHasProperty(this, property, sourceController, source, spellAbility);
}

View File

@@ -2,6 +2,7 @@ package forge.game.spellability;
import com.google.common.base.Predicate;
import forge.game.CardTraitBase;
import forge.game.CardTraitPredicates;
import forge.game.ability.ApiType;
import forge.game.card.Card;
@@ -62,7 +63,7 @@ public final class SpellAbilityPredicates extends CardTraitPredicates {
};
}
public static final Predicate<SpellAbility> isValid(String[] restrictions, Player sourceController, Card source, SpellAbility spellAbility) {
public static final Predicate<SpellAbility> isValid(String[] restrictions, Player sourceController, Card source, CardTraitBase spellAbility) {
return new Predicate<SpellAbility>() {
@Override
public boolean apply(final SpellAbility sa) {

View File

@@ -340,7 +340,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
// legendary sorcery
if (c.isSorcery() && c.getType().isLegendary() && CardLists.getValidCardCount(
activator.getCardsIn(ZoneType.Battlefield),
"Creature.Legendary,Planeswalker.Legendary", c.getController(), c) <= 0) {
"Creature.Legendary,Planeswalker.Legendary", c.getController(), c, sa) <= 0) {
return false;
}

View File

@@ -554,14 +554,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
}
if (hasParam("PlayerTurn")) {
List<Player> players = AbilityUtils.getDefinedPlayers(hostCard, getParam("PlayerTurn"), null);
List<Player> players = AbilityUtils.getDefinedPlayers(hostCard, getParam("PlayerTurn"), this);
if (!players.contains(ph.getPlayerTurn())) {
return false;
}
}
if (hasParam("UnlessDefinedPlayer")) {
List<Player> players = AbilityUtils.getDefinedPlayers(hostCard, getParam("UnlessDefinedPlayer"), null);
List<Player> players = AbilityUtils.getDefinedPlayers(hostCard, getParam("UnlessDefinedPlayer"), this);
if (!players.isEmpty()) {
return false;
}
@@ -572,7 +572,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
return false;
}
final Card topCard = controller.getCardsIn(ZoneType.Library).get(0);
if (!topCard.isValid(getParam("TopCardOfLibraryIs").split(","), controller, this.hostCard, null)) {
if (!topCard.isValid(getParam("TopCardOfLibraryIs").split(","), controller, this.hostCard, this)) {
return false;
}
}
@@ -583,7 +583,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
CardCollectionView list = game.getCardsIn(zone);
final String present = getParam("IsPresent");
list = CardLists.getValidCards(list, present.split(","), controller, hostCard, null);
list = CardLists.getValidCards(list, present.split(","), controller, hostCard, this);
int right = 1;
final String rightString = compare.substring(2);

View File

@@ -6,15 +6,11 @@ import forge.game.card.Card;
public class StaticAbilityCantAttach {
public static boolean applyCantAttachAbility(final StaticAbility stAb, final Card card, final GameEntity target) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
if (stAb.hasParam("Target")
&& !target.isValid(stAb.getParam("Target").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Target", target)) {
return false;
}
@@ -24,7 +20,7 @@ public class StaticAbilityCantAttach {
}
Card tcard = (Card) target;
if (!card.isValid(stAb.getParam("ValidCardToTarget").split(","), tcard.getController(), tcard, null)) {
if (!stAb.matchesValid(card, stAb.getParam("ValidCardToTarget").split(","), tcard)) {
return false;
}
}

View File

@@ -46,13 +46,11 @@ public class StaticAbilityCantAttackBlock {
public static boolean applyCantAttackAbility(final StaticAbility stAb, final Card card, final GameEntity target) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
if (stAb.hasParam("Target")
&& !target.isValid(stAb.getParam("Target").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Target", target)) {
return false;
}
@@ -61,14 +59,14 @@ public class StaticAbilityCantAttackBlock {
if (stAb.hasParam("UnlessDefenderControls")) {
String type = stAb.getParam("UnlessDefenderControls");
CardCollectionView list = defender.getCardsIn(ZoneType.Battlefield);
if (Iterables.any(list, CardPredicates.restriction(type.split(","), hostCard.getController(), hostCard, null))) {
if (Iterables.any(list, CardPredicates.restriction(type.split(","), hostCard.getController(), hostCard, stAb))) {
return false;
}
}
if (stAb.hasParam("IfDefenderControls")) {
String type = stAb.getParam("IfDefenderControls");
CardCollectionView list = defender.getCardsIn(ZoneType.Battlefield);
if (!Iterables.any(list, CardPredicates.restriction(type.split(","), hostCard.getController(), hostCard, null))) {
if (!Iterables.any(list, CardPredicates.restriction(type.split(","), hostCard.getController(), hostCard, stAb))) {
return false;
}
}
@@ -79,7 +77,7 @@ public class StaticAbilityCantAttackBlock {
}
if (stAb.hasParam("UnlessDefender")) {
final String type = stAb.getParam("UnlessDefender");
if (defender.hasProperty(type, hostCard.getController(), hostCard, null)) {
if (defender.hasProperty(type, hostCard.getController(), hostCard, stAb)) {
return false;
}
}
@@ -96,14 +94,12 @@ public class StaticAbilityCantAttackBlock {
*/
public static boolean applyCantBlockByAbility(final StaticAbility stAb, final Card attacker, final Card blocker) {
final Card host = stAb.getHostCard();
if (stAb.hasParam("ValidAttacker")) {
if (!attacker.isValid(stAb.getParam("ValidAttacker").split(","), host.getController(), host, null)) {
return false;
}
if (!stAb.matchesValidParam("ValidAttacker", attacker)) {
return false;
}
if (stAb.hasParam("ValidBlocker")) {
for (final String v : stAb.getParam("ValidBlocker").split(",")) {
if (blocker.isValid(v, host.getController(), host, null)) {
if (blocker.isValid(v, host.getController(), host, stAb)) {
boolean stillblock = false;
//Dragon Hunter check
if (v.contains("withoutReach") && blocker.hasStartOfKeyword("IfReach")) {
@@ -139,13 +135,11 @@ public class StaticAbilityCantAttackBlock {
public static Cost getAttackCost(final StaticAbility stAb, final Card card, final GameEntity target) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return null;
}
if (stAb.hasParam("Target")
&& !target.isValid(stAb.getParam("Target").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Target", target)) {
return null;
}
String costString = stAb.getParam("Cost");
@@ -168,13 +162,11 @@ public class StaticAbilityCantAttackBlock {
public static Cost getBlockCost(final StaticAbility stAb, final Card blocker, final GameEntity attacker) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !blocker.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", blocker)) {
return null;
}
if (stAb.hasParam("Attacker") && attacker != null
&& !attacker.isValid(stAb.getParam("Attacker").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Attacker", attacker)) {
return null;
}
String costString = stAb.getParam("Cost");
@@ -186,20 +178,16 @@ public class StaticAbilityCantAttackBlock {
}
public static boolean applyCanAttackHasteAbility(final StaticAbility stAb, final Card card, final GameEntity target) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
if (stAb.hasParam("ValidTarget")
&& !target.isValid(stAb.getParam("ValidTarget").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidTarget", target)) {
return false;
}
final Player defender = target instanceof Card ? ((Card) target).getController() : (Player) target;
if (stAb.hasParam("ValidDefender")
&& !defender.isValid(stAb.getParam("ValidDefender").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidDefender", defender)) {
return false;
}
return true;

View File

@@ -98,15 +98,12 @@ public class StaticAbilityCantBeCast {
* @return true, if successful
*/
public static boolean applyCantBeCastAbility(final StaticAbility stAb, final SpellAbility spell, final Card card, final Player activator) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
if (stAb.hasParam("Caster") && (activator != null)
&& !activator.isValid(stAb.getParam("Caster"), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Caster", activator)) {
return false;
}
@@ -156,15 +153,12 @@ public class StaticAbilityCantBeCast {
* @return true, if successful
*/
public static boolean applyCantBeActivatedAbility(final StaticAbility stAb, final SpellAbility spellAbility, final Card card, final Player activator) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
if (stAb.hasParam("ValidSA")
&& !spellAbility.isValid(stAb.getParam("ValidSA").split(","), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("ValidSA", spellAbility)) {
return false;
}
@@ -173,8 +167,7 @@ public class StaticAbilityCantBeCast {
return false;
}
if (stAb.hasParam("Activator") && (activator != null)
&& !activator.isValid(stAb.getParam("Activator"), hostCard.getController(), hostCard, spellAbility)) {
if (!stAb.matchesValidParam("Activator", activator)) {
return false;
}
@@ -215,10 +208,7 @@ public class StaticAbilityCantBeCast {
* @return true, if successful
*/
public static boolean applyCantPlayLandAbility(final StaticAbility stAb, final Card card, final Player player) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& (card == null || !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null))) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
}
@@ -230,8 +220,7 @@ public class StaticAbilityCantBeCast {
}
}
if (stAb.hasParam("Player") && (player != null)
&& !player.isValid(stAb.getParam("Player"), hostCard.getController(), hostCard, null)) {
if (!stAb.matchesValidParam("Player", player)) {
return false;
}

View File

@@ -8,19 +8,15 @@ public class StaticAbilityCantPreventDamage {
}
public static boolean applyCantPreventDamage(final StaticAbility st, final Card source, final boolean isCombat) {
final Card hostCard = st.getHostCard();
if (st.hasParam("IsCombat")) {
if (st.getParamOrDefault("IsCombat", "False").equals("True") != isCombat) {
public static boolean applyCantPreventDamage(final StaticAbility stAb, final Card source, final boolean isCombat) {
if (stAb.hasParam("IsCombat")) {
if (stAb.getParamOrDefault("IsCombat", "False").equals("True") != isCombat) {
return false;
}
}
if (st.hasParam("ValidSource")) {
if (!source.isValid(st.getParam("ValidSource").split(","), hostCard.getController(), hostCard, null)) {
return false;
}
if (!stAb.matchesValidParam("ValidSource", source)) {
return false;
}
return true;
}

View File

@@ -6,46 +6,38 @@ import forge.game.player.Player;
public class StaticAbilityCantPutCounter {
public static boolean applyCantPutCounter(final StaticAbility staticAbility, final Card card,
final CounterType type) {
final Card hostCard = staticAbility.getHostCard();
public static boolean applyCantPutCounter(final StaticAbility stAb, final Card card, final CounterType type) {
if (staticAbility.hasParam("CounterType")) {
CounterType t = CounterType.getType(staticAbility.getParam("CounterType"));
if (stAb.hasParam("CounterType")) {
CounterType t = CounterType.getType(stAb.getParam("CounterType"));
if (t != null && !type.equals(t)) {
return false;
}
}
// for the other part
if (staticAbility.hasParam("ValidCard")) {
if (!card.isValid(staticAbility.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
return false;
}
} else if (staticAbility.hasParam("ValidPlayer")) {
if (!stAb.matchesValidParam("ValidCard", card)) {
return false;
} else if (stAb.hasParam("ValidPlayer")) {
// for the other part
return false;
}
return true;
}
public static boolean applyCantPutCounter(final StaticAbility staticAbility, final Player player,
final CounterType type) {
final Card hostCard = staticAbility.getHostCard();
public static boolean applyCantPutCounter(final StaticAbility stAb, final Player player, final CounterType type) {
if (staticAbility.hasParam("CounterType")) {
CounterType t = CounterType.getType(staticAbility.getParam("CounterType"));
if (stAb.hasParam("CounterType")) {
CounterType t = CounterType.getType(stAb.getParam("CounterType"));
if (t != null && !type.equals(t)) {
return false;
}
}
// for the other part
if (staticAbility.hasParam("ValidPlayer")) {
if (!player.isValid(staticAbility.getParam("ValidPlayer").split(","), hostCard.getController(), hostCard, null)) {
return false;
}
} else if (staticAbility.hasParam("ValidCard")) {
if (!stAb.matchesValidParam("ValidPlayer", player)) {
return false;
} else if (stAb.hasParam("ValidCard")) {
// for the other part
return false;
}

Some files were not shown because too many files have changed in this diff Show More