mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Refactor/Code Cleanup
This commit is contained in:
@@ -27,7 +27,7 @@ package forge;
|
||||
*/
|
||||
public interface GameCommand extends java.io.Serializable, Runnable {
|
||||
/** Constant <code>Blank</code>. */
|
||||
public final GameCommand BLANK = new GameCommand() {
|
||||
GameCommand BLANK = new GameCommand() {
|
||||
|
||||
private static final long serialVersionUID = 2689172297036001710L;
|
||||
|
||||
|
||||
@@ -159,9 +159,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
||||
*/
|
||||
public final boolean isSecondary() {
|
||||
if (this.mapParams.containsKey("Secondary")) {
|
||||
if (this.mapParams.get("Secondary").equals("True")) {
|
||||
return true;
|
||||
}
|
||||
return this.mapParams.get("Secondary").equals("True");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -451,9 +449,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
||||
|
||||
if (params.containsKey("ActivateNoLoyaltyAbilitiesCondition")) {
|
||||
final Player active = game.getPhaseHandler().getPlayerTurn();
|
||||
if (active.getActivateLoyaltyAbilityThisTurn()) {
|
||||
return false;
|
||||
}
|
||||
return !active.getActivateLoyaltyAbilityThisTurn();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ public class ForgeScript {
|
||||
|
||||
int desiredColor = MagicColor.fromName(colorName);
|
||||
boolean hasColor = colors.hasAnyColor(desiredColor);
|
||||
if (mustHave != hasColor)
|
||||
return false;
|
||||
return mustHave == hasColor;
|
||||
|
||||
} else if (property.contains("Colorless")) { // ... Card is colorless
|
||||
boolean non = property.startsWith("non");
|
||||
@@ -38,66 +37,48 @@ public class ForgeScript {
|
||||
if (non && withSource && isColorlessSource) {
|
||||
return false;
|
||||
}
|
||||
if (non == colors.isColorless()) return false;
|
||||
return non != colors.isColorless();
|
||||
|
||||
} else if (property.contains("MultiColor")) {
|
||||
// ... Card is multicolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMulticolor())
|
||||
return false;
|
||||
return property.startsWith("non") != colors.isMulticolor();
|
||||
|
||||
} else if (property.contains("MonoColor")) { // ... Card is monocolored
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (property.startsWith("non") == colors.isMonoColor())
|
||||
return false;
|
||||
return property.startsWith("non") != colors.isMonoColor();
|
||||
|
||||
} else if (property.startsWith("ChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor() || !colors.hasAnyColor(MagicColor.fromName(source.getChosenColor())))
|
||||
return false;
|
||||
return source.hasChosenColor() && colors.hasAnyColor(MagicColor.fromName(source.getChosenColor()));
|
||||
|
||||
} else if (property.startsWith("AnyChosenColor")) {
|
||||
if (property.endsWith("Source") && isColorlessSource)
|
||||
return false;
|
||||
if (!source.hasChosenColor()
|
||||
|| !colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()))
|
||||
return false;
|
||||
return source.hasChosenColor()
|
||||
&& colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor());
|
||||
|
||||
} else if (property.startsWith("non")) {
|
||||
// ... Other Card types
|
||||
if (cardState.getTypeWithChanges().hasStringType(property.substring(3))) {
|
||||
return false;
|
||||
}
|
||||
return !cardState.getTypeWithChanges().hasStringType(property.substring(3));
|
||||
} else if (property.equals("CostsPhyrexianMana")) {
|
||||
if (!cardState.getManaCost().hasPhyrexian()) {
|
||||
return false;
|
||||
}
|
||||
return cardState.getManaCost().hasPhyrexian();
|
||||
} else if (property.startsWith("HasSVar")) {
|
||||
final String svar = property.substring(8);
|
||||
if (!cardState.hasSVar(svar)) {
|
||||
return false;
|
||||
}
|
||||
return cardState.hasSVar(svar);
|
||||
} else if (property.equals("ChosenType")) {
|
||||
if (!cardState.getTypeWithChanges().hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
return cardState.getTypeWithChanges().hasStringType(source.getChosenType());
|
||||
} else if (property.equals("IsNotChosenType")) {
|
||||
if (cardState.getTypeWithChanges().hasStringType(source.getChosenType())) {
|
||||
return false;
|
||||
}
|
||||
return !cardState.getTypeWithChanges().hasStringType(source.getChosenType());
|
||||
} else if (property.startsWith("HasSubtype")) {
|
||||
final String subType = property.substring(11);
|
||||
if (!cardState.getTypeWithChanges().hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
return cardState.getTypeWithChanges().hasSubtype(subType);
|
||||
} else if (property.startsWith("HasNoSubtype")) {
|
||||
final String subType = property.substring(13);
|
||||
if (cardState.getTypeWithChanges().hasSubtype(subType)) {
|
||||
return false;
|
||||
}
|
||||
return !cardState.getTypeWithChanges().hasSubtype(subType);
|
||||
} else if (property.equals("hasActivatedAbilityWithTapCost")) {
|
||||
for (final SpellAbility sa : cardState.getSpellAbilities()) {
|
||||
if (sa.isAbility() && (sa.getPayCosts() != null) && sa.getPayCosts().hasTapCost()) {
|
||||
@@ -136,80 +117,47 @@ public class ForgeScript {
|
||||
x = AbilityUtils.calculateAmount(source, rhs, spellAbility);
|
||||
}
|
||||
|
||||
if (!Expressions.compare(y, property, x)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!cardState.getTypeWithChanges().hasStringType(property)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return Expressions.compare(y, property, x);
|
||||
} else return cardState.getTypeWithChanges().hasStringType(property);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static boolean spellAbilityHasProperty(SpellAbility sa, String property, Player sourceController,
|
||||
Card source, SpellAbility spellAbility) {
|
||||
if (property.equals("ManaAbility")) {
|
||||
if (!sa.isManaAbility()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isManaAbility();
|
||||
} else if (property.equals("nonManaAbility")) {
|
||||
if (sa.isManaAbility()) {
|
||||
return false;
|
||||
}
|
||||
return !sa.isManaAbility();
|
||||
} else if (property.equals("Buyback")) {
|
||||
if (!sa.isBuyBackAbility()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isBuyBackAbility();
|
||||
} else if (property.equals("Cycling")) {
|
||||
if (!sa.isCycling()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isCycling();
|
||||
} else if (property.equals("Dash")) {
|
||||
if (!sa.isDash()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isDash();
|
||||
} else if (property.equals("Flashback")) {
|
||||
if (!sa.isFlashBackAbility()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isFlashBackAbility();
|
||||
} else if (property.equals("Jumpstart")) {
|
||||
if (!sa.isJumpstart()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isJumpstart();
|
||||
} else if (property.equals("Kicked")) {
|
||||
if (!sa.isKicked()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isKicked();
|
||||
} else if (property.equals("Loyalty")) {
|
||||
if (!sa.isPwAbility()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isPwAbility();
|
||||
} else if (property.equals("Aftermath")) {
|
||||
if (!sa.isAftermath()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isAftermath();
|
||||
} else if (property.equals("MorphUp")) {
|
||||
if (!sa.isMorphUp()) {
|
||||
return false;
|
||||
}
|
||||
return sa.isMorphUp();
|
||||
} else if (property.equals("Equip")) {
|
||||
if (!sa.hasParam("Equip")) {
|
||||
return false;
|
||||
}
|
||||
return sa.hasParam("Equip");
|
||||
} else if (property.equals("MayPlaySource")) {
|
||||
StaticAbility m = sa.getMayPlay();
|
||||
if (m == null) {
|
||||
return false;
|
||||
}
|
||||
if (!source.equals(m.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return source.equals(m.getHostCard());
|
||||
} else if (property.startsWith("IsTargeting")) {
|
||||
String k[] = property.split(" ", 2);
|
||||
String[] k = property.split(" ", 2);
|
||||
boolean found = false;
|
||||
for (GameObject o : AbilityUtils.getDefinedObjects(source, k[1], spellAbility)) {
|
||||
if (sa.isTargeting(o)) {
|
||||
@@ -217,15 +165,11 @@ public class ForgeScript {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
return found;
|
||||
} else if (property.equals("YouCtrl")) {
|
||||
return sa.getActivatingPlayer().equals(sourceController);
|
||||
} else if (sa.getHostCard() != null) {
|
||||
if (!sa.getHostCard().hasProperty(property, sourceController, source, spellAbility)) {
|
||||
return false;
|
||||
}
|
||||
return sa.getHostCard().hasProperty(property, sourceController, source, spellAbility);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -845,7 +845,7 @@ public class Game {
|
||||
}
|
||||
}
|
||||
|
||||
library.removeAll((Collection<?>)toRemove);
|
||||
library.removeAll(toRemove);
|
||||
|
||||
if (library.size() > 0) { //Make sure that matches were found. If not, use the original method to choose antes
|
||||
Card ante = library.get(MyRandom.getRandom().nextInt(library.size()));
|
||||
|
||||
@@ -763,7 +763,7 @@ public class GameAction {
|
||||
checkStaticAbilities(true);
|
||||
}
|
||||
public final void checkStaticAbilities(final boolean runEvents) {
|
||||
checkStaticAbilities(runEvents, Sets.<Card>newHashSet(), CardCollection.EMPTY);
|
||||
checkStaticAbilities(runEvents, Sets.newHashSet(), CardCollection.EMPTY);
|
||||
}
|
||||
public final void checkStaticAbilities(final boolean runEvents, final Set<Card> affectedCards, final CardCollectionView preList) {
|
||||
if (isCheckingStaticAbilitiesOnHold()) {
|
||||
@@ -929,7 +929,7 @@ public class GameAction {
|
||||
}
|
||||
|
||||
public final void checkStateEffects(final boolean runEvents) {
|
||||
checkStateEffects(runEvents, Sets.<Card>newHashSet());
|
||||
checkStateEffects(runEvents, Sets.newHashSet());
|
||||
}
|
||||
public final void checkStateEffects(final boolean runEvents, final Set<Card> affectedCards) {
|
||||
// sol(10/29) added for Phase updates, state effects shouldn't be
|
||||
|
||||
@@ -234,7 +234,7 @@ public final class GameActionUtil {
|
||||
|
||||
// there is a flashback cost (and not the cards cost)
|
||||
if (keyword.contains(":")) {
|
||||
final String k[] = keyword.split(":");
|
||||
final String[] k = keyword.split(":");
|
||||
flashback.setPayCosts(new Cost(k[1], false));
|
||||
}
|
||||
alternatives.add(flashback);
|
||||
|
||||
@@ -407,11 +407,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
}
|
||||
|
||||
// true for all
|
||||
if (hasProtectionFrom(attach, checkSBA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !hasProtectionFrom(attach, checkSBA);
|
||||
}
|
||||
|
||||
protected boolean canBeEquippedBy(final Card aura) {
|
||||
|
||||
@@ -368,7 +368,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
||||
if ( strCars != null ) {
|
||||
CardRarity cr;
|
||||
rarities = Lists.newArrayList();
|
||||
for (String s: Arrays.asList(strCars.split(", "))) {
|
||||
for (String s: strCars.split(", ")) {
|
||||
cr = CardRarity.smartValueOf(s);
|
||||
if (!cr.name().equals("Unknown")) {
|
||||
rarities.add(cr);
|
||||
|
||||
@@ -20,7 +20,7 @@ public enum GameLogEntryType {
|
||||
PHASE("Phase");
|
||||
|
||||
private final String caption;
|
||||
private GameLogEntryType(String name) {
|
||||
GameLogEntryType(String name) {
|
||||
this.caption = name;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
|
||||
if (event.type == DamageType.LoyaltyLoss) {
|
||||
additionalLog = " (Removing " + Lang.nounWithAmount(event.amount, "loyalty counter") + ")";
|
||||
}
|
||||
String message = event.source.toString() + " deals " + String.valueOf(event.amount) + " damage" + additionalLog + " to " + event.card.toString() + ".";
|
||||
String message = event.source.toString() + " deals " + event.amount + " damage" + additionalLog + " to " + event.card.toString() + ".";
|
||||
return new GameLogEntry(GameLogEntryType.DAMAGE, message);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
|
||||
|
||||
@Override
|
||||
public GameLogEntry visit(GameEventTurnBegan event) {
|
||||
String message = "Turn " + String.valueOf(event.turnNumber) + " (" + event.turnOwner.toString() + ")";
|
||||
String message = "Turn " + event.turnNumber + " (" + event.turnOwner.toString() + ")";
|
||||
return new GameLogEntry(GameLogEntryType.TURN, message);
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
|
||||
public GameLogEntry visit(GameEventPlayerDamaged ev) {
|
||||
String extra = ev.infect ? " (as poison counters)" : "";
|
||||
String damageType = ev.combat ? "combat" : "non-combat";
|
||||
String message = ev.source.toString() + " deals " + String.valueOf(ev.amount) + " " + damageType + " damage to " + ev.target.toString() + extra + ".";
|
||||
String message = ev.source.toString() + " deals " + ev.amount + " " + damageType + " damage to " + ev.target.toString() + extra + ".";
|
||||
return new GameLogEntry(GameLogEntryType.DAMAGE, message);
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
|
||||
|
||||
@Override
|
||||
public GameLogEntry visit(GameEventMulligan ev) {
|
||||
String message = ev.player.toString() + " has mulliganed down to " + String.valueOf(ev.player.getZone(ZoneType.Hand).size()) + " cards.";
|
||||
String message = ev.player.toString() + " has mulliganed down to " + ev.player.getZone(ZoneType.Hand).size() + " cards.";
|
||||
return new GameLogEntry(GameLogEntryType.MULLIGAN, message);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ public enum GameStage {
|
||||
Mulligan,
|
||||
Play,
|
||||
RestartedByKarn,
|
||||
GameOver;
|
||||
GameOver
|
||||
}
|
||||
@@ -71,11 +71,11 @@ public enum GameType {
|
||||
private final String name, description;
|
||||
private final Function<RegisteredPlayer, Deck> deckAutoGenerator;
|
||||
|
||||
private GameType(DeckFormat deckFormat0, boolean isCardPoolLimited0, boolean canSideboard0, boolean addWonCardsMidgame0, String name0, String description0) {
|
||||
GameType(DeckFormat deckFormat0, boolean isCardPoolLimited0, boolean canSideboard0, boolean addWonCardsMidgame0, String name0, String description0) {
|
||||
|
||||
this(deckFormat0, isCardPoolLimited0, canSideboard0, addWonCardsMidgame0, name0, description0, null);
|
||||
}
|
||||
private GameType(DeckFormat deckFormat0, boolean isCardPoolLimited0, boolean canSideboard0, boolean addWonCardsMidgame0, String name0, String description0, Function<RegisteredPlayer, Deck> deckAutoGenerator0) {
|
||||
GameType(DeckFormat deckFormat0, boolean isCardPoolLimited0, boolean canSideboard0, boolean addWonCardsMidgame0, String name0, String description0, Function<RegisteredPlayer, Deck> deckAutoGenerator0) {
|
||||
final Localizer localizer = forge.util.Localizer.getInstance();
|
||||
deckFormat = deckFormat0;
|
||||
isCardPoolLimited = isCardPoolLimited0;
|
||||
|
||||
@@ -40,7 +40,7 @@ public enum GlobalRuleChange {
|
||||
|
||||
private final String ruleText;
|
||||
|
||||
private GlobalRuleChange(String text) {
|
||||
GlobalRuleChange(String text) {
|
||||
ruleText = text;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ package forge.game;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public interface IIdentifiable {
|
||||
public abstract int getId();
|
||||
public static final Function<IIdentifiable, Integer> FN_GET_ID = new Function<IIdentifiable, Integer>() {
|
||||
int getId();
|
||||
Function<IIdentifiable, Integer> FN_GET_ID = new Function<IIdentifiable, Integer>() {
|
||||
@Override
|
||||
public Integer apply(final IIdentifiable input) {
|
||||
return Integer.valueOf(input.getId());
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class AbilityFactory {
|
||||
SubAbility("DB");
|
||||
|
||||
private final String prefix;
|
||||
private AbilityRecordType(String prefix) {
|
||||
AbilityRecordType(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
public String getPrefix() {
|
||||
|
||||
@@ -35,7 +35,6 @@ import io.sentry.event.BreadcrumbBuilder;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -1063,7 +1062,7 @@ public class AbilityUtils {
|
||||
}
|
||||
else if (defined.startsWith("OppNon")) {
|
||||
players.addAll(player.getOpponents());
|
||||
players.removeAll((Collection<?>)getDefinedPlayers(card, defined.substring(6), sa));
|
||||
players.removeAll(getDefinedPlayers(card, defined.substring(6), sa));
|
||||
}
|
||||
else if (defined.startsWith("Replaced")) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
@@ -1800,7 +1799,7 @@ public class AbilityUtils {
|
||||
public static final String getSVar(final CardTraitBase ability, final String sVarName) {
|
||||
String val = null;
|
||||
if (ability instanceof SpellAbility) {
|
||||
val = ((SpellAbility) ability).getSVar(sVarName);
|
||||
val = ability.getSVar(sVarName);
|
||||
}
|
||||
if (StringUtils.isEmpty(val)) {
|
||||
Card host = null;
|
||||
@@ -1857,7 +1856,7 @@ public class AbilityUtils {
|
||||
public boolean apply(Card input) {
|
||||
for (final KeywordInterface inst : input.getKeywords(Keyword.SPLICE)) {
|
||||
String k = inst.getOriginal();
|
||||
final String n[] = k.split(":");
|
||||
final String[] n = k.split(":");
|
||||
if (source.isValid(n[1].split(","), player, input, sa)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1890,7 +1889,7 @@ public class AbilityUtils {
|
||||
// This Function thinks that Splice exist only once on the card
|
||||
for (final KeywordInterface inst : c.getKeywords(Keyword.SPLICE)) {
|
||||
final String k = inst.getOriginal();
|
||||
final String n[] = k.split(":");
|
||||
final String[] n = k.split(":");
|
||||
spliceCost = new Cost(n[2], false);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ActivateAbilityEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
SpellAbility manaAb = p.getController().chooseSingleSpellForEffect(
|
||||
possibleAb, sa, "Choose a mana ability:", ImmutableMap.<String, Object>of());
|
||||
possibleAb, sa, "Choose a mana ability:", ImmutableMap.of());
|
||||
p.getController().playChosenSpellAbility(manaAb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AssignGroupEffect extends SpellAbilityEffect {
|
||||
|
||||
List<GameObject> defined = getDefinedOrTargeted(sa, "Defined");
|
||||
|
||||
final List<SpellAbility> abilities = Lists.<SpellAbility>newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
final List<SpellAbility> abilities = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
|
||||
Player chooser = sa.getActivatingPlayer();
|
||||
if (sa.hasParam("Chooser")) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class BidLifeEffect extends SpellAbilityEffect {
|
||||
willBid = false;
|
||||
for (final Player p : bidPlayers) {
|
||||
final boolean result = p.getController().confirmBidAction(sa, PlayerActionConfirmMode.BidLife,
|
||||
"Do you want to top bid? Current Bid =" + String.valueOf(bid), bid, winner);
|
||||
"Do you want to top bid? Current Bid =" + bid, bid, winner);
|
||||
willBid |= result;
|
||||
if (result) { // a different choose number
|
||||
bid += p.getController().chooseNumber(sa, "Bid life:", 1, 9);
|
||||
|
||||
@@ -71,13 +71,13 @@ public class ChangeTextEffect extends SpellAbilityEffect {
|
||||
validTypes.addAll(CardType.Constant.CREATURE_TYPES);
|
||||
kindOfType = "creature";
|
||||
}
|
||||
changedTypeWordOriginal = sa.getActivatingPlayer().getController().chooseSomeType(kindOfType, sa, validTypes, Lists.<String>newArrayList());
|
||||
changedTypeWordOriginal = sa.getActivatingPlayer().getController().chooseSomeType(kindOfType, sa, validTypes, Lists.newArrayList());
|
||||
} else {
|
||||
changedTypeWordOriginal = changedTypeWordsArray[0];
|
||||
}
|
||||
|
||||
validTypes.clear();
|
||||
final List<String> forbiddenTypes = sa.hasParam("ForbiddenNewTypes") ? Lists.newArrayList(sa.getParam("ForbiddenNewTypes").split(",")) : Lists.<String>newArrayList();
|
||||
final List<String> forbiddenTypes = sa.hasParam("ForbiddenNewTypes") ? Lists.newArrayList(sa.getParam("ForbiddenNewTypes").split(",")) : Lists.newArrayList();
|
||||
forbiddenTypes.add(changedTypeWordOriginal);
|
||||
if (changedTypeWordsArray[1].startsWith("Choose")) {
|
||||
if (changedTypeWordsArray[1].equals("ChooseBasicLandType")) {
|
||||
|
||||
@@ -908,7 +908,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
if (totalcmc != null) {
|
||||
if (totcmc >= 0) {
|
||||
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + Integer.toString(totcmc), source.getController(), source);
|
||||
fetchList = CardLists.getValidCards(fetchList, "Card.cmcLE" + totcmc, source.getController(), source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
int chosenP = 0;
|
||||
while (!creature.isEmpty()) {
|
||||
Card c = p.getController().chooseSingleEntityForEffect(creature, sa,
|
||||
"Select creature(s) with total power less than or equal to " + Integer.toString(totP - chosenP - negativeNum)
|
||||
"Select creature(s) with total power less than or equal to " + (totP - chosenP - negativeNum)
|
||||
+ "\r\n(Selected:" + chosenPool + ")\r\n" + "(Total Power: " + chosenP + ")", chosenP <= totP);
|
||||
if (c == null) {
|
||||
if (p.getController().confirmAction(sa, PlayerActionConfirmMode.OptionalChoose, "Cancel Choose?")) {
|
||||
|
||||
@@ -30,14 +30,14 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
|
||||
final List<SpellAbility> abilities = Lists.<SpellAbility>newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
final List<SpellAbility> abilities = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
final SpellAbility fallback = sa.getAdditionalAbility("FallbackAbility");
|
||||
|
||||
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
// determine if any of the choices are not valid
|
||||
List<SpellAbility> saToRemove = Lists.<SpellAbility>newArrayList();
|
||||
List<SpellAbility> saToRemove = Lists.newArrayList();
|
||||
|
||||
for (SpellAbility saChoice : abilities) {
|
||||
if (!saChoice.getRestrictions().checkOtherRestrictions(host, saChoice, sa.getActivatingPlayer()) ) {
|
||||
|
||||
@@ -124,7 +124,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (!pumpKeywords.isEmpty()) {
|
||||
tgtCard.addChangedCardKeywords(pumpKeywords, Lists.<String>newArrayList(), false, false, ts);
|
||||
tgtCard.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, false, ts);
|
||||
}
|
||||
|
||||
tgtCard.updateStateForView();
|
||||
|
||||
@@ -142,7 +142,7 @@ public class ControlGainEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (!kws.isEmpty()) {
|
||||
tgtC.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, tStamp);
|
||||
tgtC.addChangedCardKeywords(kws, Lists.newArrayList(), false, false, tStamp);
|
||||
game.fireEvent(new GameEventCardStatsChanged(tgtC));
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
|
||||
copyInPlay.setCloneOrigin(host);
|
||||
if (!pumpKeywords.isEmpty()) {
|
||||
copyInPlay.addChangedCardKeywords(pumpKeywords, Lists.<String>newArrayList(), false, false, timestamp);
|
||||
copyInPlay.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, false, timestamp);
|
||||
}
|
||||
crds.add(copyInPlay);
|
||||
if (sa.hasParam("RememberCopied")) {
|
||||
|
||||
@@ -32,7 +32,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
|
||||
int amount = 0;
|
||||
if (!num.equals("All") && !num.equals("Remembered")) {
|
||||
amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);
|
||||
};
|
||||
}
|
||||
|
||||
sb.append("Remove ");
|
||||
if (sa.hasParam("UpTo")) {
|
||||
|
||||
@@ -30,9 +30,7 @@ public class DelayedTriggerEffect extends SpellAbilityEffect {
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
Map<String, String> mapParams = Maps.newHashMap(sa.getMapParams());
|
||||
if (mapParams.containsKey("Cost")) {
|
||||
mapParams.remove("Cost");
|
||||
}
|
||||
mapParams.remove("Cost");
|
||||
|
||||
if (mapParams.containsKey("SpellDescription")) {
|
||||
mapParams.put("TriggerDescription", mapParams.get("SpellDescription"));
|
||||
|
||||
@@ -29,9 +29,7 @@ public class ImmediateTriggerEffect extends SpellAbilityEffect {
|
||||
public void resolve(SpellAbility sa) {
|
||||
Map<String, String> mapParams = Maps.newHashMap(sa.getMapParams());
|
||||
|
||||
if (mapParams.containsKey("Cost")) {
|
||||
mapParams.remove("Cost");
|
||||
}
|
||||
mapParams.remove("Cost");
|
||||
|
||||
if (mapParams.containsKey("SpellDescription")) {
|
||||
mapParams.put("TriggerDescription", mapParams.get("SpellDescription"));
|
||||
|
||||
@@ -43,12 +43,12 @@ public class LifeLoseEffect extends SpellAbilityEffect {
|
||||
lifeLost += p.loseLife(lifeAmount);
|
||||
}
|
||||
}
|
||||
sa.getHostCard().setSVar("AFLifeLost", "Number$" + Integer.toString(lifeLost));
|
||||
sa.getHostCard().setSVar("AFLifeLost", "Number$" + lifeLost);
|
||||
|
||||
// Exceptional case for Extort: must propagate the amount of life lost to subability,
|
||||
// otherwise the first Extort trigger per game won't work
|
||||
if (sa.getSubAbility() != null && ApiType.GainLife.equals(sa.getSubAbility().getApi())) {
|
||||
sa.getSubAbility().setSVar("AFLifeLost", "Number$" + Integer.toString(lifeLost));
|
||||
sa.getSubAbility().setSVar("AFLifeLost", "Number$" + lifeLost);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public class ProtectAllEffect extends SpellAbilityEffect {
|
||||
final List<Player> playerList = AbilityUtils.getDefinedPlayers(host, players, sa);
|
||||
for (final Player player : playerList) {
|
||||
for (final String gain : gains) {
|
||||
player.addChangedKeywords(ImmutableList.of("Protection from " + gain), ImmutableList.<String>of(), timestamp);
|
||||
player.addChangedKeywords(ImmutableList.of("Protection from " + gain), ImmutableList.of(), timestamp);
|
||||
}
|
||||
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
||||
protected String getStackDescription(SpellAbility sa) {
|
||||
|
||||
final List<String> gains = getProtectionList(sa);
|
||||
final boolean choose = (sa.hasParam("Choices")) ? true : false;
|
||||
final boolean choose = sa.hasParam("Choices");
|
||||
final String joiner = choose ? "or" : "and";
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
@@ -60,7 +60,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
redrawPT = true;
|
||||
}
|
||||
|
||||
gameCard.addChangedCardKeywords(kws, Lists.<String>newArrayList(), false, false, timestamp);
|
||||
gameCard.addChangedCardKeywords(kws, Lists.newArrayList(), false, false, timestamp);
|
||||
if (redrawPT) {
|
||||
gameCard.updatePowerToughnessForView();
|
||||
}
|
||||
@@ -106,7 +106,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
&& !(host.isInPlay() || host.isInZone(ZoneType.Stack))) {
|
||||
return;
|
||||
}
|
||||
p.addChangedKeywords(keywords, ImmutableList.<String>of(), timestamp);
|
||||
p.addChangedKeywords(keywords, ImmutableList.of(), timestamp);
|
||||
|
||||
if (!sa.hasParam("Permanent")) {
|
||||
// If not Permanent, remove Pumped at EOT
|
||||
@@ -252,7 +252,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
if (defined.equals("ChosenType")) {
|
||||
replaced = host.getChosenType();
|
||||
} else if (defined.equals("CardUIDSource")) {
|
||||
replaced = "CardUID_" + String.valueOf(host.getId());
|
||||
replaced = "CardUID_" + host.getId();
|
||||
} else if (defined.equals("ActivatorName")) {
|
||||
replaced = sa.getActivatingPlayer().getName();
|
||||
}
|
||||
@@ -277,9 +277,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("NoRepetition")) {
|
||||
for (KeywordInterface inst : tgtCards.get(0).getKeywords()) {
|
||||
final String kws = inst.getOriginal();
|
||||
if (total.contains(kws)) {
|
||||
total.remove(kws);
|
||||
}
|
||||
total.remove(kws);
|
||||
}
|
||||
}
|
||||
final int min = Math.min(total.size(), numkw);
|
||||
|
||||
@@ -113,7 +113,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
private final Map<StaticAbility, CardPlayOption> mayPlay = Maps.newHashMap();
|
||||
|
||||
private final Multimap<Long, Player> withFlash = HashMultimap.<Long, Player>create();
|
||||
private final Multimap<Long, Player> withFlash = HashMultimap.create();
|
||||
|
||||
// changes by AF animate and continuous static effects - timestamp is the key of maps
|
||||
private final Map<Long, CardChangedType> changedCardTypes = Maps.newTreeMap();
|
||||
@@ -1196,9 +1196,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
if (type == CounterType.DREAM) {
|
||||
// need to be done extra because it is also a state based action
|
||||
if (hasKeyword("CARDNAME can't have more than seven dream counters on it.") && getCounters(CounterType.DREAM) > 6) {
|
||||
return false;
|
||||
}
|
||||
return !hasKeyword("CARDNAME can't have more than seven dream counters on it.") || getCounters(CounterType.DREAM) <= 6;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1709,7 +1707,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
sbLong.append(sbx).append("\r\n");
|
||||
}
|
||||
} else if (keyword.startsWith("Hexproof:")) {
|
||||
final String k[] = keyword.split(":");
|
||||
final String[] k = keyword.split(":");
|
||||
sbLong.append("Hexproof from ").append(k[2])
|
||||
.append(" (").append(inst.getReminderText()).append(")").append("\r\n");
|
||||
} else if (keyword.endsWith(".") && !keyword.startsWith("Haunt")) {
|
||||
@@ -1803,7 +1801,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
} else if (keyword.equals("AllNonLegendaryCreatureNames")) {
|
||||
sbLong.append(getName()).append(" has all names of nonlegendary creature cards.\r\n");
|
||||
} else if (keyword.startsWith("IfReach")) {
|
||||
String k[] = keyword.split(":");
|
||||
String[] k = keyword.split(":");
|
||||
sbLong.append(getName()).append(" can block ")
|
||||
.append(CardType.getPluralType(k[1]))
|
||||
.append(" as though it had reach.\r\n");
|
||||
@@ -1813,7 +1811,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
String desc = AbilityFactory.getMapParams(getSVar(k[1])).get("SpellDescription");
|
||||
sbLong.append(desc);
|
||||
} else if (keyword.startsWith("Saga")) {
|
||||
String k[] = keyword.split(":");
|
||||
String[] k = keyword.split(":");
|
||||
String desc = "(As this Saga enters and after your draw step, "
|
||||
+ " add a lore counter. Sacrifice after " + Strings.repeat("I", Integer.valueOf(k[1])) + ".)";
|
||||
sbLong.append(desc);
|
||||
@@ -2201,7 +2199,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (n.length > 3) {
|
||||
desc = n[3];
|
||||
} else {
|
||||
String k[] = n[1].split(",");
|
||||
String[] k = n[1].split(",");
|
||||
for (int i = 0; i < k.length; i++) {
|
||||
if (CardType.isACardType(k[i])) {
|
||||
k[i] = k[i].toLowerCase();
|
||||
@@ -3392,7 +3390,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return TextUtil.concatWithSpace("c:"+String.valueOf(currentValue),"tb:"+String.valueOf(tempBoost),"bfc:"+String.valueOf(bonusFromCounters));
|
||||
return TextUtil.concatWithSpace("c:"+ currentValue,"tb:"+ tempBoost,"bfc:"+ bonusFromCounters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4785,7 +4783,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
CardCollection newCardsInCommand = (CardCollection)getGame().getCardsIn(ZoneType.Command);
|
||||
newCardsInCommand.removeAll(cardsInCommand);
|
||||
if (!newCardsInCommand.isEmpty()) {
|
||||
newCardsInCommand.get(0).setSVar("PreventedDamage", "Number$" + Integer.toString(dmgToBePrevented));
|
||||
newCardsInCommand.get(0).setSVar("PreventedDamage", "Number$" + dmgToBePrevented);
|
||||
}
|
||||
}
|
||||
subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
@@ -5080,7 +5078,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
addChangedCardTypes(new CardType(Collections.singletonList("Aura")),
|
||||
new CardType(Collections.singletonList("Creature")),
|
||||
false, false, false, false, false, false, true, bestowTimestamp, updateView);
|
||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.<String>newArrayList(),
|
||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(),
|
||||
false, false, bestowTimestamp, updateView);
|
||||
}
|
||||
|
||||
@@ -5384,7 +5382,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
switch (kw.getOriginal()) {
|
||||
case "Shroud":
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Can target CardUID_").append(String.valueOf(getId()));
|
||||
sb.append("Can target CardUID_").append(getId());
|
||||
sb.append(" with spells and abilities as though it didn't have shroud.");
|
||||
if (sa.getActivatingPlayer() == null) {
|
||||
System.err.println("Unexpected behavior: SA activator was null when trying to determine if the activating player could target a card with Shroud. SA host card = " + source + ", SA = " + sa);
|
||||
@@ -5447,9 +5445,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
|
||||
// check valid
|
||||
if (!isValid(tgt.getValidTgts(), aura.getController(), aura, sa)) {
|
||||
return false;
|
||||
}
|
||||
return isValid(tgt.getValidTgts(), aura.getController(), aura, sa);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -5457,18 +5453,12 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
@Override
|
||||
protected final boolean canBeEquippedBy(final Card equip) {
|
||||
if (!isCreature() || !isInPlay()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return isCreature() && isInPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeFortifiedBy(final Card fort) {
|
||||
if (!isLand() || !isInPlay() || fort.isLand()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return isLand() && isInPlay() && !fort.isLand();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -5727,11 +5717,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!getController().canSacrificeBy(source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getController().canSacrificeBy(source);
|
||||
}
|
||||
|
||||
public CardRules getRules() {
|
||||
@@ -6130,10 +6116,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (hasKeyword(Keyword.FLASH)) {
|
||||
return true;
|
||||
}
|
||||
if (withFlash.containsValue(p)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return withFlash.containsValue(p);
|
||||
}
|
||||
|
||||
public void addWithFlash(Long timestamp, Iterable<Player> players) {
|
||||
@@ -6170,11 +6153,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getOwner().canDiscardBy(sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return getOwner().canDiscardBy(sa);
|
||||
}
|
||||
|
||||
public void addAbilityActivated(SpellAbility ability) {
|
||||
|
||||
@@ -645,7 +645,7 @@ public class CardFactory {
|
||||
Trigger t = null;
|
||||
if (sa.isWrapper()) {
|
||||
// copy trigger?
|
||||
t = ((WrappedAbility) sa).getTrigger();
|
||||
t = sa.getTrigger();
|
||||
} else { // some keyword ability, e.g. Exalted, Annihilator
|
||||
return sa.copy();
|
||||
}
|
||||
@@ -677,7 +677,7 @@ public class CardFactory {
|
||||
|
||||
WrappedAbility wrapperAbility = new WrappedAbility(t, trig, ((WrappedAbility) sa).getDecider());
|
||||
wrapperAbility.setTrigger(true);
|
||||
wrapperAbility.setMandatory(((WrappedAbility) sa).isMandatory());
|
||||
wrapperAbility.setMandatory(sa.isMandatory());
|
||||
wrapperAbility.setDescription(wrapperAbility.getStackDescription());
|
||||
t.setTriggeredSA(wrapperAbility);
|
||||
return wrapperAbility;
|
||||
@@ -774,7 +774,7 @@ public class CardFactory {
|
||||
|
||||
// triggers to add to clone
|
||||
if (sa.hasParam("AddTriggers")) {
|
||||
for (final String s : Arrays.asList(sa.getParam("AddTriggers").split(","))) {
|
||||
for (final String s : sa.getParam("AddTriggers").split(",")) {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualTrigger = origSVars.get(s);
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, out, true);
|
||||
@@ -786,7 +786,7 @@ public class CardFactory {
|
||||
// SVars to add to clone
|
||||
if (sa.hasParam("AddSVars") || sa.hasParam("GainTextSVars")) {
|
||||
final String str = sa.getParamOrDefault("GainTextSVars", sa.getParam("AddSVars"));
|
||||
for (final String s : Arrays.asList(str.split(","))) {
|
||||
for (final String s : str.split(",")) {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualsVar = origSVars.get(s);
|
||||
state.setSVar(s, actualsVar);
|
||||
@@ -797,7 +797,7 @@ public class CardFactory {
|
||||
// abilities to add to clone
|
||||
if (sa.hasParam("AddAbilities") || sa.hasParam("GainTextAbilities")) {
|
||||
final String str = sa.getParamOrDefault("GainTextAbilities", sa.getParam("AddAbilities"));
|
||||
for (final String s : Arrays.asList(str.split(","))) {
|
||||
for (final String s : str.split(",")) {
|
||||
if (origSVars.containsKey(s)) {
|
||||
final String actualAbility = origSVars.get(s);
|
||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, out);
|
||||
|
||||
@@ -147,7 +147,7 @@ public class CardFactoryUtil {
|
||||
sbCost.append("— ");
|
||||
}
|
||||
// get rid of the ": " at the end
|
||||
sbCost.append(costDesc.substring(0, costDesc.length() - 2));
|
||||
sbCost.append(costDesc, 0, costDesc.length() - 2);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("ST$ SetState | Cost$ ").append(costStr).append(" | CostDesc$ ").append(sbCost);
|
||||
@@ -292,11 +292,7 @@ public class CardFactoryUtil {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean isCounterable(final Card c) {
|
||||
if (c.hasKeyword("CARDNAME can't be countered.") || !c.getCanCounter()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !c.hasKeyword("CARDNAME can't be countered.") && c.getCanCounter();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +314,7 @@ public class CardFactoryUtil {
|
||||
for (KeywordInterface k : c.getKeywords()) {
|
||||
final String o = k.getOriginal();
|
||||
if (o.startsWith("CantBeCounteredBy")) {
|
||||
final String m[] = o.split(":");
|
||||
final String[] m = o.split(":");
|
||||
if (sa.isValid(m[1].split(","), c.getController(), c, null)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2186,12 +2182,12 @@ public class CardFactoryUtil {
|
||||
final String abStringAfflict = "DB$ LoseLife | Defined$ TriggeredDefendingPlayer" +
|
||||
" | LifeAmount$ " + n;
|
||||
|
||||
final Trigger afflictTrigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger afflictTrigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
afflictTrigger.setOverridingAbility(AbilityFactory.getAbility(abStringAfflict, card));
|
||||
|
||||
inst.addTrigger(afflictTrigger);
|
||||
} else if (keyword.startsWith("Afterlife")) {
|
||||
final String k[] = keyword.split(":");
|
||||
final String[] k = keyword.split(":");
|
||||
final String name = StringUtils.join(k, " ");
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
@@ -2435,7 +2431,7 @@ public class CardFactoryUtil {
|
||||
final String effect = "DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | "
|
||||
+ "CounterNum$ 1 | Evolve$ True";
|
||||
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
||||
|
||||
inst.addTrigger(trigger);
|
||||
@@ -2731,7 +2727,7 @@ public class CardFactoryUtil {
|
||||
" | TriggerDescription$ Melee (" + inst.getReminderText() + ")";
|
||||
|
||||
final String effect = "DB$ Pump | Defined$ TriggeredAttackerLKICopy | NumAtt$ MeleeX | NumDef$ MeleeX";
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
|
||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("MeleeX", "TriggeredPlayersDefenders$Amount");
|
||||
@@ -2746,7 +2742,7 @@ public class CardFactoryUtil {
|
||||
final String effect = "DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1"
|
||||
+ " | ValidTgts$ Creature.attacking+powerLTX"
|
||||
+ " | TgtPrompt$ Select target attacking creature with less power";
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
|
||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("X", "Count$CardPower");
|
||||
@@ -2854,7 +2850,7 @@ public class CardFactoryUtil {
|
||||
final String trigStr = "Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Secondary$ True"
|
||||
+ " | TriggerZones$ Battlefield | TriggerDescription$ Poisonous " + n + " (" + inst.getReminderText() + ")";
|
||||
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
|
||||
final String effect = "DB$ Poison | Defined$ TriggeredTarget | Num$ " + n;
|
||||
parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
||||
@@ -2902,7 +2898,7 @@ public class CardFactoryUtil {
|
||||
final String effect = "DB$ Pump | Defined$ TriggeredAttackerLKICopy" +
|
||||
" | NumAtt$ Rampage" + n + " | NumDef$ Rampage" + n;
|
||||
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
|
||||
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setSVar("Rampage" + n, "SVar$RampageCount/Times." + n);
|
||||
@@ -3070,7 +3066,7 @@ public class CardFactoryUtil {
|
||||
inst.addTrigger(parsedTrigger);
|
||||
} else if (keyword.startsWith("Suspend")) {
|
||||
//upkeep trigger
|
||||
StringBuilder upkeepTrig = new StringBuilder();;
|
||||
StringBuilder upkeepTrig = new StringBuilder();
|
||||
|
||||
upkeepTrig.append("Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Exile ");
|
||||
upkeepTrig.append(" | IsPresent$ Card.Self+suspended | PresentZone$ Exile");
|
||||
@@ -3201,7 +3197,7 @@ public class CardFactoryUtil {
|
||||
|
||||
SpellAbility saDelay = AbilityFactory.getAbility(strDelay, card);
|
||||
saDelay.setAdditionalAbility("Execute", (AbilitySub) AbilityFactory.getAbility(strSac, card));
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(strTrig.toString(), card, intrinsic);
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(strTrig, card, intrinsic);
|
||||
trigger.setOverridingAbility(saDelay);
|
||||
inst.addTrigger(trigger);
|
||||
}
|
||||
@@ -3404,7 +3400,7 @@ public class CardFactoryUtil {
|
||||
sb.append("| ValidStackSa$ Spell.Flashback | Description$ Flashback");
|
||||
|
||||
if (keyword.contains(":")) {
|
||||
final String k[] = keyword.split(":");
|
||||
final String[] k = keyword.split(":");
|
||||
final Cost cost = new Cost(k[1], false);
|
||||
sb.append( cost.isOnlyManaCost() ? " " : "—");
|
||||
|
||||
@@ -3896,7 +3892,7 @@ public class CardFactoryUtil {
|
||||
// Add the Epic effect as a subAbility
|
||||
String dbStr = "DB$ Effect | Triggers$ EpicTrigger | SVars$ EpicCopy | StaticAbilities$ EpicCantBeCast | Duration$ Permanent | Epic$ True";
|
||||
|
||||
final AbilitySub newSA = (AbilitySub) AbilityFactory.getAbility(dbStr.toString(), card);
|
||||
final AbilitySub newSA = (AbilitySub) AbilityFactory.getAbility(dbStr, card);
|
||||
|
||||
newSA.setSVar("EpicCantBeCast", "Mode$ CantBeCast | ValidCard$ Card | Caster$ You | EffectZone$ Command | Description$ For the rest of the game, you can't cast spells.");
|
||||
newSA.setSVar("EpicTrigger", "Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ EpicCopy | TriggerDescription$ "
|
||||
@@ -3964,7 +3960,7 @@ public class CardFactoryUtil {
|
||||
// don't use SimpleString there because it does has "and" between cost i dont want that
|
||||
costStr = cost.toString();
|
||||
// but now it has ": " at the end i want to remove
|
||||
sb.append("| CostDesc$ ").append(costStr.substring(0, costStr.length() - 2));
|
||||
sb.append("| CostDesc$ ").append(costStr, 0, costStr.length() - 2);
|
||||
if (!cost.isOnlyManaCost()) {
|
||||
sb.append(".");
|
||||
}
|
||||
@@ -4542,7 +4538,7 @@ public class CardFactoryUtil {
|
||||
final StringBuilder sbValid = new StringBuilder();
|
||||
|
||||
if (!keyword.equals("Hexproof")) {
|
||||
final String k[] = keyword.split(":");
|
||||
final String[] k = keyword.split(":");
|
||||
|
||||
sbDesc.append(" from ").append(k[2]);
|
||||
sbValid.append("| ValidSource$ ").append(k[1]);
|
||||
|
||||
@@ -11,7 +11,7 @@ public final class CardPlayOption {
|
||||
/** Indicates the mana cost must be paid. */
|
||||
YES,
|
||||
/** Indicates the mana cost may not be paid. */
|
||||
NO;
|
||||
NO
|
||||
}
|
||||
|
||||
private final Player player;
|
||||
|
||||
@@ -214,7 +214,7 @@ public final class CardPredicates {
|
||||
return c.canBeSacrificedBy(sa);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<Card> canBeAttached(final Card aura) {
|
||||
return new Predicate<Card>() {
|
||||
@@ -223,7 +223,7 @@ public final class CardPredicates {
|
||||
return c.canBeAttached(aura);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<Card> isColor(final byte color) {
|
||||
return new Predicate<Card>() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -471,9 +471,7 @@ public class CardState extends GameObject {
|
||||
view.updateFoilIndex(card.getState(CardStateName.Original));
|
||||
}
|
||||
public final void removeSVar(final String var) {
|
||||
if (sVars.containsKey(var)) {
|
||||
sVars.remove(var);
|
||||
}
|
||||
sVars.remove(var);
|
||||
}
|
||||
|
||||
public final int getFoil() {
|
||||
|
||||
@@ -80,7 +80,7 @@ public final class CardUtil {
|
||||
}
|
||||
|
||||
public static boolean isStackingKeyword(final String keyword) {
|
||||
String kw = new String(keyword);
|
||||
String kw = keyword;
|
||||
if (kw.startsWith("HIDDEN")) {
|
||||
kw = kw.substring(7);
|
||||
}
|
||||
@@ -345,7 +345,7 @@ public final class CardUtil {
|
||||
|
||||
// a nice entry point with minimum parameters
|
||||
public static Set<String> getReflectableManaColors(final SpellAbility sa) {
|
||||
return getReflectableManaColors(sa, sa, Sets.<String>newHashSet(), new CardCollection());
|
||||
return getReflectableManaColors(sa, sa, Sets.newHashSet(), new CardCollection());
|
||||
}
|
||||
|
||||
private static Set<String> getReflectableManaColors(final SpellAbility abMana, final SpellAbility sa,
|
||||
@@ -390,9 +390,7 @@ public final class CardUtil {
|
||||
|
||||
// remove anything cards that is already in parents
|
||||
for (final Card p : parents) {
|
||||
if (cards.contains(p)) {
|
||||
cards.remove(p);
|
||||
}
|
||||
cards.remove(p);
|
||||
}
|
||||
|
||||
if ((cards.size() == 0) && !reflectProperty.equals("Produced")) {
|
||||
@@ -506,9 +504,7 @@ public final class CardUtil {
|
||||
// Remove cards already targeted
|
||||
final List<Card> targeted = Lists.newArrayList(ability.getTargets().getTargetCards());
|
||||
for (final Card c : targeted) {
|
||||
if (choices.contains(c)) {
|
||||
choices.remove(c);
|
||||
}
|
||||
choices.remove(c);
|
||||
}
|
||||
|
||||
// Remove cards exceeding total CMC
|
||||
|
||||
@@ -345,10 +345,7 @@ public class CardView extends GameEntityView {
|
||||
return true;
|
||||
}
|
||||
col = get(TrackableProperty.PlayerMayLookTemp);
|
||||
if (col != null && col.contains(pv)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return col != null && col.contains(pv);
|
||||
}
|
||||
void setPlayerMayLook(Player p, boolean mayLook, boolean temp) {
|
||||
TrackableProperty prop = temp ? TrackableProperty.PlayerMayLookTemp : TrackableProperty.PlayerMayLook;
|
||||
@@ -380,7 +377,7 @@ public class CardView extends GameEntityView {
|
||||
return Iterables.any(viewers, new Predicate<PlayerView>() {
|
||||
public final boolean apply(final PlayerView input) {
|
||||
return canBeShownTo(input);
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -462,10 +459,7 @@ public class CardView extends GameEntityView {
|
||||
if (mindSlaveMaster != null && canFaceDownBeShownTo(mindSlaveMaster)) {
|
||||
return true;
|
||||
}
|
||||
if (isInZone(EnumSet.of(ZoneType.Battlefield, ZoneType.Stack, ZoneType.Sideboard)) && getController().equals(viewer)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return isInZone(EnumSet.of(ZoneType.Battlefield, ZoneType.Stack, ZoneType.Sideboard)) && getController().equals(viewer);
|
||||
}
|
||||
|
||||
public FCollectionView<CardView> getEncodedCards() {
|
||||
@@ -1067,7 +1061,7 @@ public class CardView extends GameEntityView {
|
||||
TrackableCollection<CardView> views = get(key);
|
||||
if (views == null) {
|
||||
views = new TrackableCollection<CardView>();
|
||||
views.add(cardToAdd.getView());;
|
||||
views.add(cardToAdd.getView());
|
||||
set(key, views);
|
||||
}
|
||||
else if (views.add(cardToAdd.getView())) {
|
||||
|
||||
@@ -320,7 +320,7 @@ public class TokenInfo {
|
||||
if (!CardUtil.isKeywordModifiable(o)) {
|
||||
continue;
|
||||
}
|
||||
String r = new String(o);
|
||||
String r = o;
|
||||
// replace types
|
||||
for (final Map.Entry<String, String> e : typeMap.entrySet()) {
|
||||
final String key = e.getKey();
|
||||
|
||||
@@ -94,7 +94,7 @@ public class AttackConstraints {
|
||||
final int globalMax = globalRestrictions.getMax();
|
||||
final int myMax = Ints.min(globalMax == -1 ? Integer.MAX_VALUE : globalMax, possibleAttackers.size());
|
||||
if (myMax == 0) {
|
||||
return Pair.of(Collections.<Card, GameEntity>emptyMap(), Integer.valueOf(0));
|
||||
return Pair.of(Collections.emptyMap(), Integer.valueOf(0));
|
||||
}
|
||||
|
||||
final MapToAmount<Map<Card, GameEntity>> possible = new LinkedHashMapToAmount<Map<Card, GameEntity>>();
|
||||
@@ -163,8 +163,8 @@ public class AttackConstraints {
|
||||
// Now try all others (plus empty attack) and count their violations
|
||||
final FCollection<Map<Card, GameEntity>> legalAttackers = collectLegalAttackers(reqs, myMax);
|
||||
possible.putAll(Maps.asMap(legalAttackers.asSet(), FN_COUNT_VIOLATIONS));
|
||||
if (countViolations(Collections.<Card, GameEntity>emptyMap()) != -1) {
|
||||
possible.put(Collections.<Card, GameEntity>emptyMap(), countViolations(Collections.<Card, GameEntity>emptyMap()));
|
||||
if (countViolations(Collections.emptyMap()) != -1) {
|
||||
possible.put(Collections.emptyMap(), countViolations(Collections.emptyMap()));
|
||||
}
|
||||
|
||||
// take the case with the fewest violations
|
||||
@@ -173,7 +173,7 @@ public class AttackConstraints {
|
||||
|
||||
private final FCollection<Map<Card, GameEntity>> collectLegalAttackers(final List<Attack> reqs, final int maximum) {
|
||||
return new FCollection<Map<Card, GameEntity>>
|
||||
(collectLegalAttackers(Collections.<Card, GameEntity>emptyMap(), deepClone(reqs), new CardCollection(), maximum));
|
||||
(collectLegalAttackers(Collections.emptyMap(), deepClone(reqs), new CardCollection(), maximum));
|
||||
}
|
||||
|
||||
private final List<Map<Card, GameEntity>> collectLegalAttackers(final Map<Card, GameEntity> attackers, final List<Attack> reqs, final CardCollection reserved, final int maximum) {
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AttackRequirement {
|
||||
for (Card pw : CardLists.filter(c.getController().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.PLANESWALKERS)) {
|
||||
// Add the attack alternatives that suffice (planeswalkers that can be attacked instead of the player)
|
||||
if (!defenderSpecificAlternatives.containsKey(c.getController())) {
|
||||
defenderSpecificAlternatives.put(c.getController(), Lists.<GameEntity>newArrayList());
|
||||
defenderSpecificAlternatives.put(c.getController(), Lists.newArrayList());
|
||||
}
|
||||
defenderSpecificAlternatives.get(c.getController()).add(pw);
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public class AttackRequirement {
|
||||
int violations = 0;
|
||||
|
||||
// first. check to see if "must attack X or Y with at least one creature" requirements are satisfied
|
||||
List<GameEntity> toRemoveFromDefSpecific = Lists.<GameEntity>newArrayList();
|
||||
List<GameEntity> toRemoveFromDefSpecific = Lists.newArrayList();
|
||||
if (!defenderOrPWSpecific.isEmpty()) {
|
||||
for (GameEntity def : defenderOrPWSpecific.keySet()) {
|
||||
if (defenderSpecificAlternatives.containsKey(def)) {
|
||||
|
||||
@@ -54,8 +54,8 @@ public class Combat {
|
||||
private final FCollection<GameEntity> attackableEntries = new FCollection<GameEntity>();
|
||||
|
||||
// Keyed by attackable defender (player or planeswalker)
|
||||
private final Multimap<GameEntity, AttackingBand> attackedByBands = Multimaps.synchronizedMultimap(ArrayListMultimap.<GameEntity, AttackingBand>create());
|
||||
private final Multimap<AttackingBand, Card> blockedBands = Multimaps.synchronizedMultimap(ArrayListMultimap.<AttackingBand, Card>create());
|
||||
private final Multimap<GameEntity, AttackingBand> attackedByBands = Multimaps.synchronizedMultimap(ArrayListMultimap.create());
|
||||
private final Multimap<AttackingBand, Card> blockedBands = Multimaps.synchronizedMultimap(ArrayListMultimap.create());
|
||||
|
||||
private final Map<Card, Integer> defendingDamageMap = Maps.newHashMap();
|
||||
|
||||
@@ -353,7 +353,7 @@ public class Combat {
|
||||
|
||||
public final boolean isBlocked(final Card attacker) {
|
||||
AttackingBand band = getBandOfAttacker(attacker);
|
||||
return band == null ? false : Boolean.TRUE.equals(band.isBlocked());
|
||||
return band != null && Boolean.TRUE.equals(band.isBlocked());
|
||||
}
|
||||
|
||||
// Some cards in Alpha may UNBLOCK an attacker, so second parameter is not always-true
|
||||
@@ -804,7 +804,7 @@ public class Combat {
|
||||
for (final Entry<Card, Integer> entry : defendingDamageMap.entrySet()) {
|
||||
GameEntity defender = getDefenderByAttacker(entry.getKey());
|
||||
if (defender instanceof Player) { // player
|
||||
((Player) defender).addCombatDamage(entry.getValue(), entry.getKey(), dealtDamageTo, preventMap, counterTable);
|
||||
defender.addCombatDamage(entry.getValue(), entry.getKey(), dealtDamageTo, preventMap, counterTable);
|
||||
}
|
||||
else if (defender instanceof Card) { // planeswalker
|
||||
((Card) defender).getController().addCombatDamage(entry.getValue(), entry.getKey(), dealtDamageTo, preventMap, counterTable);
|
||||
@@ -843,7 +843,7 @@ public class Combat {
|
||||
|
||||
public final boolean isUnblocked(final Card att) {
|
||||
AttackingBand band = getBandOfAttacker(att);
|
||||
return band == null ? false : Boolean.FALSE.equals(band.isBlocked());
|
||||
return band != null && Boolean.FALSE.equals(band.isBlocked());
|
||||
}
|
||||
|
||||
public final CardCollection getUnblockedAttackers() {
|
||||
@@ -875,7 +875,7 @@ public class Combat {
|
||||
public boolean isBlocking(Card blocker) {
|
||||
if (blockedBands.containsValue(blocker)) {
|
||||
return true; // is blocking something at the moment
|
||||
};
|
||||
}
|
||||
|
||||
CombatLki lki = lkiCache.get(blocker);
|
||||
return null != lki && !lki.isAttacker; // was blocking something anyway
|
||||
|
||||
@@ -14,7 +14,7 @@ public class CombatLki {
|
||||
|
||||
public CombatLki(boolean isAttacker, FCollectionView<AttackingBand> relatedBands) {
|
||||
this.isAttacker = isAttacker;
|
||||
this.relatedBands = new FCollection<AttackingBand>(relatedBands);;
|
||||
this.relatedBands = new FCollection<AttackingBand>(relatedBands);
|
||||
}
|
||||
|
||||
public AttackingBand getFirstBand() {
|
||||
|
||||
@@ -426,11 +426,7 @@ public class CombatUtil {
|
||||
}
|
||||
|
||||
final List<Card> list = blocker.getController().getCreaturesInPlay();
|
||||
if (list.size() < 2 && blocker.hasKeyword("CARDNAME can't attack or block alone.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return list.size() >= 2 || !blocker.hasKeyword("CARDNAME can't attack or block alone.");
|
||||
}
|
||||
|
||||
public static boolean canBlockMoreCreatures(final Card blocker, final CardCollectionView blockedBy) {
|
||||
@@ -500,8 +496,7 @@ public class CombatUtil {
|
||||
|
||||
// Landwalk
|
||||
if (isUnblockableFromLandwalk(attacker, defender)) {
|
||||
if (CardLists.getAmountOfKeyword(defender.getCreaturesInPlay(), "CARDNAME can block creatures with landwalk abilities as though they didn't have those abilities.") == 0)
|
||||
return false;
|
||||
return CardLists.getAmountOfKeyword(defender.getCreaturesInPlay(), "CARDNAME can block creatures with landwalk abilities as though they didn't have those abilities.") != 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -518,7 +513,7 @@ public class CombatUtil {
|
||||
IGNORE_LANDWALK_KEYWORDS = new String[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String basic = MagicColor.Constant.BASIC_LANDS.get(i);
|
||||
final String landwalk = basic + "walk";;
|
||||
final String landwalk = basic + "walk";
|
||||
LANDWALK_KEYWORDS[i] = landwalk;
|
||||
SNOW_LANDWALK_KEYWORDS[i] = "Snow " + landwalk.toLowerCase();
|
||||
IGNORE_LANDWALK_KEYWORDS[i] = "May be blocked as though it doesn't have " + landwalk + ".";
|
||||
@@ -1053,7 +1048,7 @@ public class CombatUtil {
|
||||
for (KeywordInterface inst : blocker.getKeywords()) {
|
||||
String k = inst.getOriginal();
|
||||
if (k.startsWith("IfReach")) {
|
||||
String n[] = k.split(":");
|
||||
String[] n = k.split(":");
|
||||
if (attacker.getType().hasCreatureType(n[1])) {
|
||||
stillblock = true;
|
||||
break;
|
||||
@@ -1074,11 +1069,7 @@ public class CombatUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attacker.hasKeyword(Keyword.INTIMIDATE) && !blocker.isArtifact() && !blocker.sharesColorWith(attacker)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !attacker.hasKeyword(Keyword.INTIMIDATE) || blocker.isArtifact() || blocker.sharesColorWith(attacker);
|
||||
} // canBlock()
|
||||
|
||||
public static boolean canAttackerBeBlockedWithAmount(Card attacker, int amount, Combat combat) {
|
||||
@@ -1114,9 +1105,7 @@ public class CombatUtil {
|
||||
System.out.println("Warning: it was impossible to deduce the defending player in CombatUtil#canAttackerBeBlockedWithAmount, returning 'true' (safest default).");
|
||||
return true;
|
||||
}
|
||||
if (amount < defender.getCreaturesInPlay().size()) {
|
||||
return false;
|
||||
}
|
||||
return amount >= defender.getCreaturesInPlay().size();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class GlobalAttackRestrictions {
|
||||
private GlobalAttackRestrictionViolations getViolations(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers, final boolean returnQuickly) {
|
||||
final int nTooMany = max < 0 ? 0 : attackers.size() - max;
|
||||
if (returnQuickly && nTooMany > 0) {
|
||||
return new GlobalAttackRestrictionViolations(nTooMany, MapToAmountUtil.<GameEntity>emptyMap(), MapToAmountUtil.<GameEntity>emptyMap());
|
||||
return new GlobalAttackRestrictionViolations(nTooMany, MapToAmountUtil.emptyMap(), MapToAmountUtil.emptyMap());
|
||||
}
|
||||
|
||||
final MapToAmount<GameEntity> defenderTooMany = new LinkedHashMapToAmount<GameEntity>(defenderMax.size());
|
||||
|
||||
@@ -13,7 +13,6 @@ import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilityActivated;
|
||||
import forge.game.spellability.Spell;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
@@ -40,7 +39,7 @@ public class CostAdjustment {
|
||||
Cost result = cost.copy();
|
||||
|
||||
boolean isStateChangeToFaceDown = false;
|
||||
if (sa.isSpell() && ((Spell) sa).isCastFaceDown()) {
|
||||
if (sa.isSpell() && sa.isCastFaceDown()) {
|
||||
// Turn face down to apply cost modifiers correctly
|
||||
host.turnFaceDownNoUpdate();
|
||||
isStateChangeToFaceDown = true;
|
||||
@@ -159,7 +158,7 @@ public class CostAdjustment {
|
||||
|
||||
boolean isStateChangeToFaceDown = false;
|
||||
if (sa.isSpell()) {
|
||||
if (((Spell) sa).isCastFaceDown()) {
|
||||
if (sa.isCastFaceDown()) {
|
||||
// Turn face down to apply cost modifiers correctly
|
||||
originalCard.turnFaceDownNoUpdate();
|
||||
isStateChangeToFaceDown = true;
|
||||
@@ -490,7 +489,7 @@ public class CostAdjustment {
|
||||
return false;
|
||||
}
|
||||
} else if (type.equals("MorphDown")) {
|
||||
if (!sa.isSpell() || !((Spell) sa).isCastFaceDown()) {
|
||||
if (!sa.isSpell() || !sa.isCastFaceDown()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -546,9 +545,7 @@ public class CostAdjustment {
|
||||
}
|
||||
curSa = curSa.getSubAbility();
|
||||
}
|
||||
if (!targetValid) {
|
||||
return false;
|
||||
}
|
||||
return targetValid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,15 +112,11 @@ public class CostDiscard extends CostPartWithList {
|
||||
final Integer amount = this.convertAmount();
|
||||
|
||||
if (this.payCostFromSource()) {
|
||||
if (!source.canBeDiscardedBy(ability)) {
|
||||
return false;
|
||||
}
|
||||
return source.canBeDiscardedBy(ability);
|
||||
}
|
||||
else {
|
||||
if (type.equals("Hand")) {
|
||||
if (!payer.canDiscardBy(ability)) {
|
||||
return false;
|
||||
}
|
||||
return payer.canDiscardBy(ability);
|
||||
// this will always work
|
||||
}
|
||||
else if (type.equals("LastDrawn")) {
|
||||
@@ -153,14 +149,11 @@ public class CostDiscard extends CostPartWithList {
|
||||
}
|
||||
}
|
||||
|
||||
if ((amount != null) && (amount > handList.size() - adjustment)) {
|
||||
// not enough cards in hand to pay
|
||||
return false;
|
||||
}
|
||||
// not enough cards in hand to pay
|
||||
return (amount == null) || (amount <= handList.size() - adjustment);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -93,9 +93,7 @@ public class CostExert extends CostPartWithList {
|
||||
final Integer amount = this.convertAmount();
|
||||
|
||||
|
||||
if (!needsAnnoucement && (amount != null) && (typeList.size() < amount)) {
|
||||
return false;
|
||||
}
|
||||
return needsAnnoucement || (amount == null) || (typeList.size() >= amount);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -146,9 +146,7 @@ public class CostExile extends CostPartWithList {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundPayable) {
|
||||
return false;
|
||||
}
|
||||
return foundPayable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -94,11 +94,7 @@ public class CostExileFromStack extends CostPart {
|
||||
list = CardLists.getValidCards(list, type.split(";"), payer, source, ability);
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
if ((amount != null) && (list.size() < amount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (amount == null) || (list.size() >= amount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -83,10 +83,7 @@ public class CostGainControl extends CostPartWithList {
|
||||
if (amount == null) {
|
||||
amount = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
||||
}
|
||||
if (typeList.size() < amount) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return typeList.size() >= amount;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -144,7 +144,7 @@ public abstract class CostPartWithList extends CostPart {
|
||||
protected abstract Card doPayment(SpellAbility ability, Card targetCard);
|
||||
// Overload these two only together, set to true and perform payment on list
|
||||
protected boolean canPayListAtOnce() { return false; }
|
||||
protected CardCollectionView doListPayment(SpellAbility ability, CardCollectionView targetCards) { return CardCollection.EMPTY; };
|
||||
protected CardCollectionView doListPayment(SpellAbility ability, CardCollectionView targetCards) { return CardCollection.EMPTY; }
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
|
||||
@@ -78,11 +78,7 @@ public class CostPayLife extends CostPart {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (payer.hasKeyword("You can't pay life to cast spells or activate abilities.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !payer.hasKeyword("You can't pay life to cast spells or activate abilities.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -160,9 +160,7 @@ public class CostPutCardToLib extends CostPartWithList {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundPayable) {
|
||||
return false;
|
||||
}
|
||||
return foundPayable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -140,9 +140,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
public final boolean canPay(final SpellAbility ability, final Player payer) {
|
||||
final Card source = ability.getHostCard();
|
||||
if (this.payCostFromSource()) {
|
||||
if (!source.canReceiveCounters(this.counter)) {
|
||||
return false;
|
||||
}
|
||||
return source.canReceiveCounters(this.counter);
|
||||
} else {
|
||||
// 3 Cards have Put a -1/-1 Counter on a Creature you control.
|
||||
List<Card> typeList = CardLists.getValidCards(source.getGame().getCardsIn(ZoneType.Battlefield),
|
||||
@@ -150,12 +148,9 @@ public class CostPutCounter extends CostPartWithList {
|
||||
|
||||
typeList = CardLists.filter(typeList, CardPredicates.canReceiveCounters(this.counter));
|
||||
|
||||
if (typeList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return !typeList.isEmpty();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -133,9 +133,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
if (this.payCostFromSource()) {
|
||||
if ((amount != null) && ((source.getCounters(cntrs) - amount) < 0)) {
|
||||
return false;
|
||||
}
|
||||
return (amount == null) || ((source.getCounters(cntrs) - amount) >= 0);
|
||||
}
|
||||
else {
|
||||
List<Card> typeList;
|
||||
@@ -152,9 +150,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
||||
for (Card c : typeList) {
|
||||
totalCounters += c.getCounters(cntrs);
|
||||
}
|
||||
if (totalCounters >= amount) {
|
||||
return true;
|
||||
}
|
||||
return totalCounters >= amount;
|
||||
|
||||
} else {
|
||||
// (default logic) remove X counters from a single permanent
|
||||
|
||||
@@ -102,14 +102,9 @@ public class CostReturn extends CostPartWithList {
|
||||
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), payer, source, ability);
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
if (!needsAnnoucement && amount != null && typeList.size() < amount) {
|
||||
return false;
|
||||
}
|
||||
} else if (!source.isInPlay()) {
|
||||
return false;
|
||||
}
|
||||
return needsAnnoucement || amount == null || typeList.size() >= amount;
|
||||
} else return source.isInPlay();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -57,9 +57,7 @@ public class CostReveal extends CostPartWithList {
|
||||
final Integer amount = this.convertAmount();
|
||||
|
||||
if (this.payCostFromSource()) {
|
||||
if (!source.isInZone(ZoneType.Hand)) {
|
||||
return false;
|
||||
}
|
||||
return source.isInZone(ZoneType.Hand);
|
||||
} else if (this.getType().equals("Hand")) {
|
||||
return true;
|
||||
} else if (this.getType().equals("SameColor")) {
|
||||
@@ -85,14 +83,11 @@ public class CostReveal extends CostPartWithList {
|
||||
handList = modifiedHand;
|
||||
}
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability);
|
||||
if ((amount != null) && (amount > handList.size())) {
|
||||
// not enough cards in hand to pay
|
||||
return false;
|
||||
}
|
||||
// not enough cards in hand to pay
|
||||
return (amount == null) || (amount <= handList.size());
|
||||
//System.out.println("revealcost - " + amount + type + handList);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -103,19 +103,14 @@ public class CostSacrifice extends CostPartWithList {
|
||||
|
||||
typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability));
|
||||
|
||||
if (!needsAnnoucement && (amount != null) && (typeList.size() < amount)) {
|
||||
return false;
|
||||
}
|
||||
return needsAnnoucement || (amount == null) || (typeList.size() >= amount);
|
||||
|
||||
// If amount is null, it's either "ALL" or "X"
|
||||
// if X is defined, it needs to be calculated and checked, if X is
|
||||
// choice, it can be Paid even if it's 0
|
||||
}
|
||||
else if (!source.canBeSacrificedBy(ability)) {
|
||||
return false;
|
||||
}
|
||||
else return source.canBeSacrificedBy(ability);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -150,11 +150,7 @@ public class CostTapType extends CostPartWithList {
|
||||
}
|
||||
|
||||
final Integer amount = this.convertAmount();
|
||||
if ((typeList.size() == 0) || ((amount != null) && (typeList.size() < amount))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (typeList.size() != 0) && ((amount == null) || (typeList.size() >= amount));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -74,21 +74,14 @@ public class CostUnattach extends CostPartWithList {
|
||||
|
||||
final String type = this.getType();
|
||||
if (type.equals("CARDNAME")) {
|
||||
if (source.isEquipping()) {
|
||||
return true;
|
||||
}
|
||||
return source.isEquipping();
|
||||
} else if (type.equals("OriginalHost")) {
|
||||
Card originalEquipment = ability.getOriginalHost();
|
||||
if (originalEquipment.isEquipping()) {
|
||||
return true;
|
||||
}
|
||||
return originalEquipment.isEquipping();
|
||||
} else {
|
||||
if (CardLists.getValidCards(source.getEquippedBy(), type, payer, source).size() > 0) {
|
||||
return true;
|
||||
}
|
||||
return CardLists.getValidCards(source.getEquippedBy(), type, payer, source).size() > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Card findCardToUnattach(final Card source, Player activator, SpellAbility ability) {
|
||||
|
||||
@@ -89,10 +89,7 @@ public class CostUntapType extends CostPartWithList {
|
||||
typeList = CardLists.filter(typeList, Presets.TAPPED);
|
||||
|
||||
final Integer amount = convertAmount();
|
||||
if ((typeList.size() == 0) || ((amount != null) && (typeList.size() < amount))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (typeList.size() != 0) && ((amount == null) || (typeList.size() >= amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,36 +2,36 @@ package forge.game.cost;
|
||||
|
||||
public interface ICostVisitor<T> {
|
||||
|
||||
public T visit(CostGainControl cost);
|
||||
public T visit(CostChooseCreatureType cost);
|
||||
public T visit(CostDiscard cost);
|
||||
public T visit(CostDamage cost);
|
||||
public T visit(CostDraw cost);
|
||||
public T visit(CostExile cost);
|
||||
public T visit(CostExileFromStack cost);
|
||||
public T visit(CostExiledMoveToGrave cost);
|
||||
public T visit(CostExert cost);
|
||||
public T visit(CostFlipCoin cost);
|
||||
public T visit(CostMill cost);
|
||||
public T visit(CostAddMana cost);
|
||||
public T visit(CostPayLife cost);
|
||||
public T visit(CostPayEnergy cost);
|
||||
public T visit(CostGainLife cost);
|
||||
public T visit(CostPartMana cost);
|
||||
public T visit(CostPutCardToLib cost);
|
||||
public T visit(CostTap cost);
|
||||
public T visit(CostSacrifice cost);
|
||||
public T visit(CostReturn cost);
|
||||
public T visit(CostReveal cost);
|
||||
public T visit(CostRemoveAnyCounter cost);
|
||||
public T visit(CostRemoveCounter cost);
|
||||
public T visit(CostPutCounter cost);
|
||||
public T visit(CostUntapType cost);
|
||||
public T visit(CostUntap cost);
|
||||
public T visit(CostUnattach cost);
|
||||
public T visit(CostTapType cost);
|
||||
T visit(CostGainControl cost);
|
||||
T visit(CostChooseCreatureType cost);
|
||||
T visit(CostDiscard cost);
|
||||
T visit(CostDamage cost);
|
||||
T visit(CostDraw cost);
|
||||
T visit(CostExile cost);
|
||||
T visit(CostExileFromStack cost);
|
||||
T visit(CostExiledMoveToGrave cost);
|
||||
T visit(CostExert cost);
|
||||
T visit(CostFlipCoin cost);
|
||||
T visit(CostMill cost);
|
||||
T visit(CostAddMana cost);
|
||||
T visit(CostPayLife cost);
|
||||
T visit(CostPayEnergy cost);
|
||||
T visit(CostGainLife cost);
|
||||
T visit(CostPartMana cost);
|
||||
T visit(CostPutCardToLib cost);
|
||||
T visit(CostTap cost);
|
||||
T visit(CostSacrifice cost);
|
||||
T visit(CostReturn cost);
|
||||
T visit(CostReveal cost);
|
||||
T visit(CostRemoveAnyCounter cost);
|
||||
T visit(CostRemoveCounter cost);
|
||||
T visit(CostPutCounter cost);
|
||||
T visit(CostUntapType cost);
|
||||
T visit(CostUntap cost);
|
||||
T visit(CostUnattach cost);
|
||||
T visit(CostTapType cost);
|
||||
|
||||
public static class Base<T> implements ICostVisitor<T> {
|
||||
class Base<T> implements ICostVisitor<T> {
|
||||
|
||||
@Override
|
||||
public T visit(CostGainControl cost) {
|
||||
|
||||
@@ -8,7 +8,7 @@ public class GameEventCardDamaged extends GameEvent {
|
||||
Normal,
|
||||
M1M1Counters,
|
||||
Deathtouch,
|
||||
LoyaltyLoss;
|
||||
LoyaltyLoss
|
||||
}
|
||||
|
||||
public final Card card;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class GameEventCardStatsChanged extends GameEvent {
|
||||
return "Card state changes: " + card.getName() +
|
||||
" (" + StringUtils.join(card.getType(), ' ') + ") " +
|
||||
card.getNetPower() + "/" + card.getNetToughness() +
|
||||
" and " + String.valueOf(cards.size() - 1) + " more";
|
||||
" and " + (cards.size() - 1) + " more";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface IGameEventVisitor<T> {
|
||||
|
||||
|
||||
// This is base class for all visitors.
|
||||
public static class Base<T> implements IGameEventVisitor<T>{
|
||||
class Base<T> implements IGameEventVisitor<T>{
|
||||
public T visit(GameEventAnteCardsSelected event) { return null; }
|
||||
public T visit(GameEventAttackersDeclared event) { return null; }
|
||||
public T visit(GameEventBlockersDeclared event) { return null; }
|
||||
|
||||
@@ -164,7 +164,7 @@ public enum Keyword {
|
||||
protected final boolean isMultipleRedundant;
|
||||
protected final String reminderText, displayName;
|
||||
|
||||
private Keyword(Class<? extends KeywordInstance<?>> type0, boolean isMultipleRedundant0, String reminderText0) {
|
||||
Keyword(Class<? extends KeywordInstance<?>> type0, boolean isMultipleRedundant0, String reminderText0) {
|
||||
type = type0;
|
||||
isMultipleRedundant = isMultipleRedundant0;
|
||||
reminderText = reminderText0;
|
||||
@@ -176,7 +176,7 @@ public enum Keyword {
|
||||
String details = k;
|
||||
// try to get real part
|
||||
if (k.contains(":")) {
|
||||
final String x[] = k.split(":", 2);
|
||||
final String[] x = k.split(":", 2);
|
||||
keyword = smartValueOf(x[0]);
|
||||
details = x[1];
|
||||
} else if (k.contains(" ")) {
|
||||
@@ -186,7 +186,7 @@ public enum Keyword {
|
||||
|
||||
// other keywords that contains other stuff like Enchant
|
||||
if (keyword == Keyword.UNDEFINED) {
|
||||
final String x[] = k.split(" ", 2);
|
||||
final String[] x = k.split(" ", 2);
|
||||
|
||||
final Keyword k2 = smartValueOf(x[0]);
|
||||
// Keywords that needs to be undefined
|
||||
|
||||
@@ -24,10 +24,10 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
|
||||
|
||||
private boolean hidden;
|
||||
|
||||
private List<Trigger> triggers = Lists.<Trigger>newArrayList();
|
||||
private List<ReplacementEffect> replacements = Lists.<ReplacementEffect>newArrayList();
|
||||
private List<SpellAbility> abilities = Lists.<SpellAbility>newArrayList();
|
||||
private List<StaticAbility> staticAbilities = Lists.<StaticAbility>newArrayList();
|
||||
private List<Trigger> triggers = Lists.newArrayList();
|
||||
private List<ReplacementEffect> replacements = Lists.newArrayList();
|
||||
private List<SpellAbility> abilities = Lists.newArrayList();
|
||||
private List<StaticAbility> staticAbilities = Lists.newArrayList();
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -21,36 +21,36 @@ public interface KeywordInterface extends Cloneable {
|
||||
boolean getHidden();
|
||||
void setHidden(boolean val);
|
||||
|
||||
public void createTraits(final Card host, final boolean intrinsic);
|
||||
void createTraits(final Card host, final boolean intrinsic);
|
||||
void createTraits(final Card host, final boolean intrinsic, final boolean clear);
|
||||
|
||||
public void addTrigger(final Trigger trg);
|
||||
void addTrigger(final Trigger trg);
|
||||
|
||||
public void addReplacement(final ReplacementEffect trg);
|
||||
void addReplacement(final ReplacementEffect trg);
|
||||
|
||||
public void addSpellAbility(final SpellAbility s);
|
||||
public void addStaticAbility(final StaticAbility st);
|
||||
void addSpellAbility(final SpellAbility s);
|
||||
void addStaticAbility(final StaticAbility st);
|
||||
|
||||
public void setHostCard(final Card host);
|
||||
void setHostCard(final Card host);
|
||||
|
||||
/**
|
||||
* @return the triggers
|
||||
*/
|
||||
public Collection<Trigger> getTriggers();
|
||||
Collection<Trigger> getTriggers();
|
||||
/**
|
||||
* @return the replacements
|
||||
*/
|
||||
public Collection<ReplacementEffect> getReplacements();
|
||||
Collection<ReplacementEffect> getReplacements();
|
||||
/**
|
||||
* @return the abilities
|
||||
*/
|
||||
public Collection<SpellAbility> getAbilities();
|
||||
Collection<SpellAbility> getAbilities();
|
||||
/**
|
||||
* @return the staticAbilities
|
||||
*/
|
||||
public Collection<StaticAbility> getStaticAbilities();
|
||||
Collection<StaticAbility> getStaticAbilities();
|
||||
|
||||
public KeywordInterface copy(final Card host, final boolean lki);
|
||||
KeywordInterface copy(final Card host, final boolean lki);
|
||||
|
||||
public boolean redundant(final Collection<KeywordInterface> list);
|
||||
boolean redundant(final Collection<KeywordInterface> list);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public class KeywordWithCostAndType extends KeywordInstance<KeywordWithCostAndTy
|
||||
if (k.length > 2) {
|
||||
strType = k[2];
|
||||
} else {
|
||||
String n[] = type.split(",");
|
||||
String[] n = type.split(",");
|
||||
for (int i = 0; i < n.length; i++) {
|
||||
if (CardType.isACardType(n[i])) {
|
||||
n[i] = n[i].toLowerCase();
|
||||
|
||||
@@ -10,7 +10,7 @@ public class Ninjutsu extends KeywordWithCost {
|
||||
@Override
|
||||
protected void parse(String details) {
|
||||
if (details.contains(":")) {
|
||||
String k[] = details.split(":");
|
||||
String[] k = details.split(":");
|
||||
details = k[0];
|
||||
if (k[1].equals("Commander")) {
|
||||
commander = true;
|
||||
|
||||
@@ -95,10 +95,7 @@ public class ManaPool extends ManaConversionMatrix implements Iterable<Mana> {
|
||||
}
|
||||
}
|
||||
|
||||
if (totalMana() == safeMana) {
|
||||
return false; //won't lose floating mana if all mana is of colors that aren't going to be emptied
|
||||
}
|
||||
return true;
|
||||
return totalMana() != safeMana; //won't lose floating mana if all mana is of colors that aren't going to be emptied
|
||||
}
|
||||
|
||||
public final List<Mana> clearPool(boolean isEndOfPhase) {
|
||||
@@ -370,7 +367,7 @@ public class ManaPool extends ManaConversionMatrix implements Iterable<Mana> {
|
||||
}
|
||||
|
||||
// TODO The following may not be needed anymore?
|
||||
if (((color & (byte) ManaAtom.COLORLESS) != 0) && shard.canBePaidWithManaOfColor((byte) (byte)ManaAtom.COLORLESS)) {
|
||||
if (((color & (byte) ManaAtom.COLORLESS) != 0) && shard.canBePaidWithManaOfColor((byte)ManaAtom.COLORLESS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class MulliganService {
|
||||
continue;
|
||||
}
|
||||
Player p = mulligan.getPlayer();
|
||||
boolean keep = mulligan.canMulligan() ? p.getController().mulliganKeepHand(firstPlayer, mulligan.tuckCardsAfterKeepHand()) : true;
|
||||
boolean keep = !mulligan.canMulligan() || p.getController().mulliganKeepHand(firstPlayer, mulligan.tuckCardsAfterKeepHand());
|
||||
|
||||
if (game.isGameOver()) { // conceded on mulligan prompt
|
||||
return;
|
||||
|
||||
@@ -663,7 +663,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
// map: defender => (many) attacker => (many) blocker
|
||||
Map<GameEntity, MapOfLists<Card, Card>> blockers = Maps.newHashMap();
|
||||
for (GameEntity ge : combat.getDefendersControlledBy(p)) {
|
||||
MapOfLists<Card, Card> protectThisDefender = new HashMapOfLists<Card, Card>(CollectionSuppliers.<Card>arrayLists());
|
||||
MapOfLists<Card, Card> protectThisDefender = new HashMapOfLists<Card, Card>(CollectionSuppliers.arrayLists());
|
||||
for (Card att : combat.getAttackersOf(ge)) {
|
||||
protectThisDefender.addAll(att, combat.getBlockers(att));
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ public enum PhaseType {
|
||||
public final String nameForUi;
|
||||
public final String nameForScripts;
|
||||
|
||||
private PhaseType(String name) {
|
||||
PhaseType(String name) {
|
||||
this(name, name);
|
||||
}
|
||||
private PhaseType(String name, String name_for_scripts) {
|
||||
PhaseType(String name, String name_for_scripts) {
|
||||
nameForUi = name;
|
||||
nameForScripts = name_for_scripts;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -93,11 +92,8 @@ public class Untap extends Phase {
|
||||
}
|
||||
//exerted need current player turn
|
||||
final Player playerTurn = c.getGame().getPhaseHandler().getPlayerTurn();
|
||||
|
||||
if (c.isExertedBy(playerTurn)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return !c.isExertedBy(playerTurn);
|
||||
}
|
||||
|
||||
public static final Predicate<Card> CANUNTAP = new Predicate<Card>() {
|
||||
@@ -125,7 +121,7 @@ public class Untap extends Phase {
|
||||
for (final Card c : bounceList) {
|
||||
game.getAction().moveToHand(c, null);
|
||||
}
|
||||
list.removeAll((Collection<?>)bounceList);
|
||||
list.removeAll(bounceList);
|
||||
|
||||
final Map<String, Integer> restrictUntap = Maps.newHashMap();
|
||||
boolean hasChosen = false;
|
||||
@@ -154,10 +150,7 @@ public class Untap extends Phase {
|
||||
if (!Untap.canUntap(c)) {
|
||||
return false;
|
||||
}
|
||||
if (c.isValid(restrict, player, null, null)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return !c.isValid(restrict, player, null, null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -187,7 +180,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((Collection<?>)CardLists.getValidCards(cardList, entry.getKey(), player, null));
|
||||
cardList.removeAll(CardLists.getValidCards(cardList, entry.getKey(), player, null));
|
||||
restrictUntap.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,10 +461,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final boolean canGainLife() {
|
||||
if (hasKeyword("You can't gain life.") || hasKeyword("Your life total can't change.")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return !hasKeyword("You can't gain life.") && !hasKeyword("Your life total can't change.");
|
||||
}
|
||||
|
||||
public final int loseLife(final int toLose) {
|
||||
@@ -513,20 +510,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final boolean canLoseLife() {
|
||||
if (hasKeyword("Your life total can't change.")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return !hasKeyword("Your life total can't change.");
|
||||
}
|
||||
|
||||
public final boolean canPayLife(final int lifePayment) {
|
||||
if (life < lifePayment) {
|
||||
return false;
|
||||
}
|
||||
if ((lifePayment > 0) && hasKeyword("Your life total can't change.")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (lifePayment <= 0) || !hasKeyword("Your life total can't change.");
|
||||
}
|
||||
|
||||
public final boolean payLife(final int lifePayment, final Card source) {
|
||||
@@ -826,7 +817,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
CardCollection newCardsInCommand = new CardCollection(getGame().getCardsIn(ZoneType.Command));
|
||||
newCardsInCommand.removeAll(cardsInCommand);
|
||||
if (!newCardsInCommand.isEmpty()) {
|
||||
newCardsInCommand.get(0).setSVar("PreventedDamage", "Number$" + Integer.toString(dmgToBePrevented));
|
||||
newCardsInCommand.get(0).setSVar("PreventedDamage", "Number$" + dmgToBePrevented);
|
||||
}
|
||||
}
|
||||
subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
@@ -1067,7 +1058,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
* @param keyword the keyword to add.
|
||||
*/
|
||||
public final void addKeyword(final String keyword) {
|
||||
addChangedKeywords(ImmutableList.of(keyword), ImmutableList.<String>of(), getGame().getNextTimestamp());
|
||||
addChangedKeywords(ImmutableList.of(keyword), ImmutableList.of(), getGame().getNextTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1185,7 +1176,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
PlayerZone com = getZone(ZoneType.Command);
|
||||
for (DetachedCardEffect eff : staticAbilities.values()) {
|
||||
com.remove(eff);
|
||||
eff.setStaticAbilities(Lists.<StaticAbility>newArrayList());
|
||||
eff.setStaticAbilities(Lists.newArrayList());
|
||||
}
|
||||
this.updateZoneForView(com);
|
||||
}
|
||||
@@ -1201,7 +1192,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
boolean cancelHexproof = false;
|
||||
for (String k : a.getKeywords()) {
|
||||
if (k.startsWith("IgnoreHexproof")) {
|
||||
String m[] = k.split(":");
|
||||
String[] m = k.split(":");
|
||||
if (isValid(m[1].split(","), a, sa.getHostCard(), sa)) {
|
||||
cancelHexproof = true;
|
||||
break;
|
||||
@@ -1218,10 +1209,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((hasKeyword("You can't be the targets of spells or activated abilities") && (sa.isSpell() || (sa instanceof AbilityActivated)))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (!hasKeyword("You can't be the targets of spells or activated abilities") || (!sa.isSpell() && (!(sa instanceof AbilityActivated))));
|
||||
}
|
||||
|
||||
|
||||
@@ -1783,10 +1771,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
adjMax += Integer.valueOf(k[1]);
|
||||
}
|
||||
}
|
||||
if (landsPlayedThisTurn < adjMax) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return landsPlayedThisTurn < adjMax;
|
||||
}
|
||||
|
||||
public final ManaPool getManaPool() {
|
||||
@@ -2491,10 +2476,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
"Skip all combat phases of this turn.");
|
||||
return true;
|
||||
}
|
||||
if (hasKeyword("Skip all combat phases of this turn.")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return hasKeyword("Skip all combat phases of this turn.");
|
||||
}
|
||||
|
||||
public boolean isSkippingMain() {
|
||||
@@ -2614,10 +2596,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
removeKeyword("Skip your next draw step.");
|
||||
return true;
|
||||
}
|
||||
if (hasKeyword("Skip your draw step.")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return hasKeyword("Skip your draw step.");
|
||||
}
|
||||
|
||||
public CardCollectionView getInboundTokens() {
|
||||
@@ -2957,11 +2936,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isOpponentOf(sa.getActivatingPlayer()) && hasKeyword("Spells and abilities your opponents control can't cause you to discard cards.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !isOpponentOf(sa.getActivatingPlayer()) || !hasKeyword("Spells and abilities your opponents control can't cause you to discard cards.");
|
||||
}
|
||||
|
||||
public boolean canSacrificeBy(SpellAbility sa) {
|
||||
@@ -2969,11 +2944,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isOpponentOf(sa.getActivatingPlayer()) && hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !isOpponentOf(sa.getActivatingPlayer()) || !hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.");
|
||||
}
|
||||
|
||||
public boolean canSearchLibraryWith(SpellAbility sa, Player targetPlayer) {
|
||||
@@ -2983,11 +2954,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
|
||||
if (this.hasKeyword("CantSearchLibrary")) {
|
||||
return false;
|
||||
} else if (targetPlayer != null && targetPlayer.equals(sa.getActivatingPlayer())
|
||||
&& hasKeyword("Spells and abilities you control can't cause you to search your library.")) {
|
||||
return false;
|
||||
}
|
||||
} else return targetPlayer == null || !targetPlayer.equals(sa.getActivatingPlayer())
|
||||
|| !hasKeyword("Spells and abilities you control can't cause you to search your library.");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import java.util.Map;
|
||||
*/
|
||||
public abstract class PlayerController {
|
||||
|
||||
public static enum ManaPaymentPurpose {
|
||||
public enum ManaPaymentPurpose {
|
||||
DeclareAttacker,
|
||||
DeclareBlocker,
|
||||
Echo,
|
||||
@@ -51,7 +51,7 @@ public abstract class PlayerController {
|
||||
CumulativeUpkeep,
|
||||
}
|
||||
|
||||
public static enum BinaryChoiceType {
|
||||
public enum BinaryChoiceType {
|
||||
HeadsOrTails, // coin
|
||||
TapOrUntap,
|
||||
PlayOrDraw,
|
||||
|
||||
@@ -23,13 +23,9 @@ public class PlayerProperty {
|
||||
|
||||
Game game = player.getGame();
|
||||
if (property.equals("You")) {
|
||||
if (!player.equals(sourceController)) {
|
||||
return false;
|
||||
}
|
||||
return player.equals(sourceController);
|
||||
} else if (property.equals("Opponent")) {
|
||||
if (player.equals(sourceController) || !player.isOpponentOf(sourceController)) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(sourceController) && player.isOpponentOf(sourceController);
|
||||
} else if (property.startsWith("OpponentOf ")) {
|
||||
final String v = property.split(" ")[1];
|
||||
final List<Player> players = AbilityUtils.getDefinedPlayers(source, v, spellAbility);
|
||||
@@ -39,42 +35,24 @@ public class PlayerProperty {
|
||||
}
|
||||
}
|
||||
} else if (property.equals("YourTeam")) {
|
||||
if (!player.sameTeam(sourceController)) {
|
||||
return false;
|
||||
}
|
||||
return player.sameTeam(sourceController);
|
||||
} else if (property.equals("Allies")) {
|
||||
if (player.equals(sourceController) || player.isOpponentOf(sourceController)) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(sourceController) && !player.isOpponentOf(sourceController);
|
||||
} else if (property.equals("Active")) {
|
||||
if (!player.equals(game.getPhaseHandler().getPlayerTurn())) {
|
||||
return false;
|
||||
}
|
||||
return player.equals(game.getPhaseHandler().getPlayerTurn());
|
||||
} else if (property.equals("NonActive")) {
|
||||
if (player.equals(game.getPhaseHandler().getPlayerTurn())) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(game.getPhaseHandler().getPlayerTurn());
|
||||
} else if (property.equals("OpponentToActive")) {
|
||||
final Player active = game.getPhaseHandler().getPlayerTurn();
|
||||
if (player.equals(active) || !player.isOpponentOf(active)) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(active) && player.isOpponentOf(active);
|
||||
} else if (property.equals("Other")) {
|
||||
if (player.equals(sourceController)) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(sourceController);
|
||||
} else if (property.equals("OtherThanSourceOwner")) {
|
||||
if (player.equals(source.getOwner())) {
|
||||
return false;
|
||||
}
|
||||
return !player.equals(source.getOwner());
|
||||
} else if (property.equals("isMonarch")) {
|
||||
if (!player.equals(game.getMonarch())) {
|
||||
return false;
|
||||
}
|
||||
return player.equals(game.getMonarch());
|
||||
} else if (property.equals("hasBlessing")) {
|
||||
if (!player.hasBlessing()) {
|
||||
return false;
|
||||
}
|
||||
return player.hasBlessing();
|
||||
} else if (property.startsWith("wasDealtCombatDamageThisCombatBy ")) {
|
||||
String v = property.split(" ")[1];
|
||||
|
||||
@@ -91,9 +69,7 @@ public class PlayerProperty {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < count) {
|
||||
return false;
|
||||
}
|
||||
return found >= count;
|
||||
} else if (property.startsWith("wasDealtDamageThisGameBy ")) {
|
||||
String v = property.split(" ")[1];
|
||||
|
||||
@@ -110,9 +86,7 @@ public class PlayerProperty {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < count) {
|
||||
return false;
|
||||
}
|
||||
return found >= count;
|
||||
} else if (property.startsWith("wasDealtDamageThisTurnBy ")) {
|
||||
String v = property.split(" ")[1];
|
||||
int count = 1;
|
||||
@@ -129,9 +103,7 @@ public class PlayerProperty {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < count) {
|
||||
return false;
|
||||
}
|
||||
return found >= count;
|
||||
} else if (property.startsWith("wasDealtCombatDamageThisTurnBy ")) {
|
||||
String v = property.split(" ")[1];
|
||||
|
||||
@@ -149,90 +121,54 @@ public class PlayerProperty {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < count) {
|
||||
return false;
|
||||
}
|
||||
return found >= count;
|
||||
} else if (property.equals("attackedBySourceThisCombat")) {
|
||||
if (game.getCombat() == null || !player.equals(game.getCombat().getDefenderPlayerByAttacker(source))) {
|
||||
return false;
|
||||
}
|
||||
return game.getCombat() != null && player.equals(game.getCombat().getDefenderPlayerByAttacker(source));
|
||||
} else if (property.equals("wasDealtDamageThisTurn")) {
|
||||
if (player.getAssignedDamage() == 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getAssignedDamage() != 0;
|
||||
} else if (property.equals("wasDealtCombatDamageThisTurn")) {
|
||||
if (player.getAssignedCombatDamage() == 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getAssignedCombatDamage() != 0;
|
||||
} else if (property.equals("LostLifeThisTurn")) {
|
||||
if (player.getLifeLostThisTurn() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getLifeLostThisTurn() > 0;
|
||||
} else if (property.equals("DeclaredAttackerThisTurn")) {
|
||||
if (player.getAttackersDeclaredThisTurn() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getAttackersDeclaredThisTurn() > 0;
|
||||
} else if (property.equals("TappedLandForManaThisTurn")) {
|
||||
if (!player.hasTappedLandForManaThisTurn()) {
|
||||
return false;
|
||||
}
|
||||
return player.hasTappedLandForManaThisTurn();
|
||||
} else if (property.equals("NoCardsInHandAtBeginningOfTurn")) {
|
||||
if (player.getNumCardsInHandStartedThisTurnWith() > 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getNumCardsInHandStartedThisTurnWith() <= 0;
|
||||
} else if (property.equals("CardsInHandAtBeginningOfTurn")) {
|
||||
if (player.getNumCardsInHandStartedThisTurnWith() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getNumCardsInHandStartedThisTurnWith() > 0;
|
||||
} else if (property.startsWith("WithCardsInHand")) {
|
||||
if (property.contains("AtLeast")) {
|
||||
int amount = Integer.parseInt(property.split("AtLeast")[1]);
|
||||
if (player.getCardsIn(ZoneType.Hand).size() < amount) {
|
||||
return false;
|
||||
}
|
||||
return player.getCardsIn(ZoneType.Hand).size() >= amount;
|
||||
}
|
||||
} else if (property.equals("IsRemembered")) {
|
||||
if (!source.isRemembered(player)) {
|
||||
return false;
|
||||
}
|
||||
return source.isRemembered(player);
|
||||
} else if (property.equals("IsNotRemembered")) {
|
||||
if (source.isRemembered(player)) {
|
||||
return false;
|
||||
}
|
||||
return !source.isRemembered(player);
|
||||
} else if (property.equals("EnchantedBy")) {
|
||||
if (!player.isEnchantedBy(source)) {
|
||||
return false;
|
||||
}
|
||||
return player.isEnchantedBy(source);
|
||||
} else if (property.equals("Chosen")) {
|
||||
if (source.getChosenPlayer() == null || !source.getChosenPlayer().equals(player)) {
|
||||
return false;
|
||||
}
|
||||
return source.getChosenPlayer() != null && source.getChosenPlayer().equals(player);
|
||||
} else if (property.startsWith("LifeEquals_")) {
|
||||
int life = AbilityUtils.calculateAmount(source, property.substring(11), null);
|
||||
if (player.getLife() != life) {
|
||||
return false;
|
||||
}
|
||||
return player.getLife() == life;
|
||||
} else if (property.equals("IsPoisoned")) {
|
||||
if (player.getPoisonCounters() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return player.getPoisonCounters() > 0;
|
||||
} 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);
|
||||
String comparator = type[1];
|
||||
String compareTo = comparator.substring(2);
|
||||
int y = StringUtils.isNumeric(compareTo) ? Integer.parseInt(compareTo) : 0;
|
||||
if (!Expressions.compare(list.size(), comparator, y)) {
|
||||
return false;
|
||||
}
|
||||
return Expressions.compare(list.size(), comparator, y);
|
||||
} else if (property.startsWith("withMore")) {
|
||||
final String cardType = property.split("sThan")[0].substring(8);
|
||||
final Player controller = "Active".equals(property.split("sThan")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
|
||||
final CardCollectionView oppList = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(cardType));
|
||||
final CardCollectionView yourList = CardLists.filter(controller.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(cardType));
|
||||
if (oppList.size() <= yourList.size()) {
|
||||
return false;
|
||||
}
|
||||
return oppList.size() > yourList.size();
|
||||
} else if (property.startsWith("withAtLeast")) {
|
||||
final String cardType = property.split("More")[1].split("sThan")[0];
|
||||
final int amount = Integer.parseInt(property.substring(11, 12));
|
||||
@@ -240,25 +176,19 @@ public class PlayerProperty {
|
||||
final CardCollectionView oppList = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(cardType));
|
||||
final CardCollectionView yourList = CardLists.filter(controller.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(cardType));
|
||||
System.out.println(yourList.size());
|
||||
if (oppList.size() < yourList.size() + amount) {
|
||||
return false;
|
||||
}
|
||||
return oppList.size() >= yourList.size() + amount;
|
||||
} else if (property.startsWith("hasMore")) {
|
||||
final Player controller = property.contains("Than") && "Active".equals(property.split("Than")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
|
||||
if (property.substring(7).startsWith("Life") && player.getLife() <= controller.getLife()) {
|
||||
return false;
|
||||
} else if (property.substring(7).startsWith("CardsInHand")
|
||||
&& player.getCardsIn(ZoneType.Hand).size() <= controller.getCardsIn(ZoneType.Hand).size()) {
|
||||
return false;
|
||||
}
|
||||
} else return !property.substring(7).startsWith("CardsInHand")
|
||||
|| player.getCardsIn(ZoneType.Hand).size() > controller.getCardsIn(ZoneType.Hand).size();
|
||||
} else if (property.startsWith("hasFewer")) {
|
||||
final Player controller = "Active".equals(property.split("Than")[1]) ? game.getPhaseHandler().getPlayerTurn() : sourceController;
|
||||
final ZoneType zt = property.substring(8).startsWith("CreaturesInYard") ? ZoneType.Graveyard : ZoneType.Battlefield;
|
||||
final CardCollectionView oppList = CardLists.filter(player.getCardsIn(zt), Presets.CREATURES);
|
||||
final CardCollectionView yourList = CardLists.filter(controller.getCardsIn(zt), Presets.CREATURES);
|
||||
if (oppList.size() >= yourList.size()) {
|
||||
return false;
|
||||
}
|
||||
return oppList.size() < yourList.size();
|
||||
} else if (property.startsWith("withMost")) {
|
||||
final String kind = property.substring(8);
|
||||
if (kind.equals("Life")) {
|
||||
@@ -268,9 +198,7 @@ public class PlayerProperty {
|
||||
highestLife = p.getLife();
|
||||
}
|
||||
}
|
||||
if (player.getLife() != highestLife) {
|
||||
return false;
|
||||
}
|
||||
return player.getLife() == highestLife;
|
||||
}
|
||||
else if (kind.equals("PermanentInPlay")) {
|
||||
int typeNum = 0;
|
||||
@@ -286,9 +214,7 @@ public class PlayerProperty {
|
||||
}
|
||||
}
|
||||
|
||||
if (controlmost.size() != 1 || !controlmost.contains(player)) {
|
||||
return false;
|
||||
}
|
||||
return controlmost.size() == 1 && controlmost.contains(player);
|
||||
}
|
||||
else if (kind.equals("CardsInHand")) {
|
||||
int largestHand = 0;
|
||||
@@ -299,9 +225,7 @@ public class PlayerProperty {
|
||||
withLargestHand = p;
|
||||
}
|
||||
}
|
||||
if (!player.equals(withLargestHand)) {
|
||||
return false;
|
||||
}
|
||||
return player.equals(withLargestHand);
|
||||
}
|
||||
else if (kind.startsWith("Type")) {
|
||||
String type = property.split("Type")[1];
|
||||
@@ -325,9 +249,7 @@ public class PlayerProperty {
|
||||
if (checkOnly && controlmost.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
if (!controlmost.contains(player)) {
|
||||
return false;
|
||||
}
|
||||
return controlmost.contains(player);
|
||||
}
|
||||
} else if (property.startsWith("withLowest")) {
|
||||
if (property.substring(10).equals("Life")) {
|
||||
@@ -342,18 +264,12 @@ public class PlayerProperty {
|
||||
lowestlifep.add(p);
|
||||
}
|
||||
}
|
||||
if (!lowestlifep.contains(player)) {
|
||||
return false;
|
||||
}
|
||||
return lowestlifep.contains(player);
|
||||
}
|
||||
} else if (property.startsWith("LessThanHalfStartingLifeTotal")) {
|
||||
if (player.getLife() >= (int) Math.ceil(player.getStartingLife() / 2.0)) {
|
||||
return false;
|
||||
}
|
||||
return player.getLife() < (int) Math.ceil(player.getStartingLife() / 2.0);
|
||||
} else if (property.startsWith("Triggered")) {
|
||||
if (!AbilityUtils.getDefinedPlayers(source, property, spellAbility).contains(player)) {
|
||||
return false;
|
||||
}
|
||||
return AbilityUtils.getDefinedPlayers(source, property, spellAbility).contains(player);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,9 +59,7 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
||||
|
||||
if (mapParams.containsKey("ValidCounterType")) {
|
||||
String type = this.getMapParams().get("ValidCounterType");
|
||||
if (CounterType.getType(type) != runParams.get("CounterType")) {
|
||||
return false;
|
||||
}
|
||||
return CounterType.getType(type) == runParams.get("CounterType");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -59,9 +59,7 @@ public class ReplaceCounter extends ReplacementEffect {
|
||||
}
|
||||
if (this.getMapParams().containsKey("ValidType")) {
|
||||
String type = this.getMapParams().get("ValidType");
|
||||
if (type.equals("Spell") && !spellAbility.isSpell()) {
|
||||
return false;
|
||||
}
|
||||
return !type.equals("Spell") || spellAbility.isSpell();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,9 +74,7 @@ public class ReplaceDestroy extends ReplacementEffect {
|
||||
}
|
||||
}
|
||||
if (hasParam("ValidSource")) {
|
||||
if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), getHostCard());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -62,9 +62,7 @@ public class ReplaceDiscard extends ReplacementEffect {
|
||||
}
|
||||
}
|
||||
if (this.getMapParams().containsKey("DiscardFromEffect")) {
|
||||
if (null == runParams.get("Source")) {
|
||||
return false;
|
||||
}
|
||||
return null != runParams.get("Source");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -55,11 +55,9 @@ public class ReplaceDraw extends ReplacementEffect {
|
||||
}
|
||||
if (this.getMapParams().containsKey("NotFirstCardInDrawStep")) {
|
||||
final Player p = (Player)runParams.get("Affected");
|
||||
if (p.numDrawnThisDrawStep() == 0
|
||||
&& this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW)
|
||||
&& this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p)) {
|
||||
return false;
|
||||
}
|
||||
return p.numDrawnThisDrawStep() != 0
|
||||
|| !this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW)
|
||||
|| !this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -57,9 +57,7 @@ public class ReplaceDrawCards extends ReplacementEffect {
|
||||
String comparator = this.getMapParams().get("Number");
|
||||
final String operator = comparator.substring(0, 2);
|
||||
final int operandValue = Integer.parseInt(comparator.substring(2));
|
||||
if (!Expressions.compare(n, operator, operandValue)) {
|
||||
return false;
|
||||
}
|
||||
return Expressions.compare(n, operator, operandValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -57,9 +57,7 @@ public class ReplaceGainLife extends ReplacementEffect {
|
||||
}
|
||||
}
|
||||
if ("True".equals(this.getMapParams().get("SourceController"))) {
|
||||
if (runParams.get("Source") == null || !runParams.get("Affected").equals(((Card)runParams.get("Source")).getController())) {
|
||||
return false;
|
||||
}
|
||||
return runParams.get("Source") != null && runParams.get("Affected").equals(((Card) runParams.get("Source")).getController());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -29,9 +29,7 @@ public class ReplaceGameLoss extends ReplacementEffect {
|
||||
return false;
|
||||
}
|
||||
if (this.getMapParams().containsKey("ValidPlayer")) {
|
||||
if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -105,9 +105,7 @@ public class ReplaceMoved extends ReplacementEffect {
|
||||
if (runParams.containsKey("Cause")) {
|
||||
SpellAbility cause = (SpellAbility) runParams.get("Cause");
|
||||
if (cause != null) {
|
||||
if (cause.isValid(getParam("NotCause").split(","), controller, getHostCard(), null)) {
|
||||
return false;
|
||||
}
|
||||
return !cause.isValid(getParam("NotCause").split(","), controller, getHostCard(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,9 +58,7 @@ public class ReplaceProduceMana extends ReplacementEffect {
|
||||
}
|
||||
|
||||
if (this.getMapParams().containsKey("ValidCard")) {
|
||||
if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -46,9 +46,7 @@ public class ReplaceSetInMotion extends ReplacementEffect {
|
||||
return false;
|
||||
}
|
||||
if (this.getMapParams().containsKey("ValidPlayer")) {
|
||||
if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -31,9 +31,7 @@ public class ReplaceSurveil extends ReplacementEffect {
|
||||
}
|
||||
|
||||
if (hasParam("ValidPlayer")) {
|
||||
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -45,9 +45,7 @@ public class ReplaceToken extends ReplacementEffect {
|
||||
|
||||
if (hasParam("ValidToken")) {
|
||||
if (runParams.containsKey("Token")) {
|
||||
if (!matchesValid(runParams.get("Token"), getParam("ValidToken").split(","), getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Token"), getParam("ValidToken").split(","), getHostCard());
|
||||
} else {
|
||||
// in case RE is not updated yet
|
||||
return false;
|
||||
|
||||
@@ -30,9 +30,7 @@ public class ReplaceTurnFaceUp extends ReplacementEffect {
|
||||
return false;
|
||||
}
|
||||
if (this.getMapParams().containsKey("ValidCard")) {
|
||||
if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
return matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidCard").split(","), this.getHostCard());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,9 +63,7 @@ public class ReplaceUntap extends ReplacementEffect {
|
||||
final Card card = (Card) o;
|
||||
// all replace untap with untapStep does have "your untap step"
|
||||
final Player player = card.getController();
|
||||
if (!player.getGame().getPhaseHandler().is(PhaseType.UNTAP, player)) {
|
||||
return false;
|
||||
}
|
||||
return player.getGame().getPhaseHandler().is(PhaseType.UNTAP, player);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -8,5 +8,5 @@ public enum ReplacementResult {
|
||||
Replaced,
|
||||
NotReplaced,
|
||||
Prevented,
|
||||
Updated;
|
||||
Updated
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public enum ReplacementType {
|
||||
Untap(ReplaceUntap.class);
|
||||
|
||||
Class<? extends ReplacementEffect> clasz;
|
||||
private ReplacementType(Class<? extends ReplacementEffect> cls) {
|
||||
ReplacementType(Class<? extends ReplacementEffect> cls) {
|
||||
clasz = cls;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user