Merge remote-tracking branch 'upstream/master' into MAGETOWER-UPDATE
@@ -69,6 +69,7 @@ public class DeckHints {
|
|||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(Type type, String hint) {
|
public boolean contains(Type type, String hint) {
|
||||||
if (filters == null) {
|
if (filters == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -84,15 +85,19 @@ public class DeckHints {
|
|||||||
if (filters == null) {
|
if (filters == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int num = 0;
|
||||||
for (String hint : hints) {
|
for (String hint : hints) {
|
||||||
for (Pair<Type, String> filter : filters) {
|
for (Pair<Type, String> filter : filters) {
|
||||||
|
System.out.println(filter.getLeft() + " = type = " + type + " "+ filter.getRight() + " =filter= " + hint);
|
||||||
if (filter.getLeft() == type && filter.getRight().equals(hint)) {
|
if (filter.getLeft() == type && filter.getRight().equals(hint)) {
|
||||||
continue;
|
num++;
|
||||||
|
if (num == hints.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +116,7 @@ public class DeckHints {
|
|||||||
Iterable<PaperCard> cards = getCardsForFilter(cardList, type, param);
|
Iterable<PaperCard> cards = getCardsForFilter(cardList, type, param);
|
||||||
if (cards != null) {
|
if (cards != null) {
|
||||||
// if a type is used more than once intersect respective matches
|
// if a type is used more than once intersect respective matches
|
||||||
if (ret.get(type) != null) {
|
if (ret.containsKey(type)) {
|
||||||
Iterables.retainAll(cards, new FCollection<>(ret.get(type)));
|
Iterables.retainAll(cards, new FCollection<>(ret.get(type)));
|
||||||
}
|
}
|
||||||
ret.put(type, cards);
|
ret.put(type, cards);
|
||||||
@@ -128,17 +133,8 @@ public class DeckHints {
|
|||||||
* list of cards to be filtered
|
* list of cards to be filtered
|
||||||
* @return List<PaperCard> of Cards that match this DeckHints.
|
* @return List<PaperCard> of Cards that match this DeckHints.
|
||||||
*/
|
*/
|
||||||
public List<PaperCard> filter(Iterable<PaperCard> cardList) {
|
public Iterable<PaperCard> filter(Iterable<PaperCard> cardList) {
|
||||||
List<PaperCard> ret = new ArrayList<>();
|
return Iterables.concat(filterByType(cardList).values());
|
||||||
for (Pair<Type, String> pair : filters) {
|
|
||||||
Type type = pair.getLeft();
|
|
||||||
String param = pair.getRight();
|
|
||||||
Iterable<PaperCard> cards = getCardsForFilter(cardList, type, param);
|
|
||||||
if (cards != null) {
|
|
||||||
Iterables.addAll(ret, cards);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<Type, String> parseHint(String hint) {
|
private Pair<Type, String> parseHint(String hint) {
|
||||||
@@ -164,57 +160,38 @@ public class DeckHints {
|
|||||||
List<PaperCard> cards = new ArrayList<>();
|
List<PaperCard> cards = new ArrayList<>();
|
||||||
|
|
||||||
// this is case ABILITY, but other types can also use this when the implicit parsing would miss
|
// this is case ABILITY, but other types can also use this when the implicit parsing would miss
|
||||||
String[] abilities = param.split("\\|");
|
String[] params = param.split("\\|");
|
||||||
for (String ability : abilities) {
|
for (String ability : params) {
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHas(type, ability), PaperCard.FN_GET_RULES));
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHas(type, ability), PaperCard.FN_GET_RULES));
|
||||||
}
|
}
|
||||||
// bonus if a DeckHas can satisfy the type with multiple ones
|
// bonus if a DeckHas can satisfy the type with multiple ones
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHasExactly(type, abilities), PaperCard.FN_GET_RULES));
|
if (params.length > 1) {
|
||||||
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHasExactly(type, params), PaperCard.FN_GET_RULES));
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
for (String p : params) {
|
||||||
|
switch (type) {
|
||||||
case COLOR:
|
case COLOR:
|
||||||
String[] colors = param.split("\\|");
|
ColorSet cc = ColorSet.fromNames(p);
|
||||||
for (String color : colors) {
|
if (cc.isColorless()) {
|
||||||
ColorSet cc = ColorSet.fromNames(color);
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.Presets.IS_COLORLESS, PaperCard.FN_GET_RULES));
|
||||||
if (cc.isColorless()) {
|
} else {
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.Presets.IS_COLORLESS, PaperCard.FN_GET_RULES));
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.isColor(cc.getColor()), PaperCard.FN_GET_RULES));
|
||||||
} else {
|
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.isColor(cc.getColor()), PaperCard.FN_GET_RULES));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYWORD:
|
case KEYWORD:
|
||||||
String[] keywords = param.split("\\|");
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.hasKeyword(p), PaperCard.FN_GET_RULES));
|
||||||
for (String keyword : keywords) {
|
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.hasKeyword(keyword), PaperCard.FN_GET_RULES));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NAME:
|
case NAME:
|
||||||
String[] names = param.split("\\|");
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.name(StringOp.EQUALS, p), PaperCard.FN_GET_RULES));
|
||||||
for (String name : names) {
|
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard.FN_GET_RULES));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case TYPE:
|
case TYPE:
|
||||||
String[] types = param.split("\\|");
|
Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, p), PaperCard.FN_GET_RULES));
|
||||||
for (String t : types) {
|
|
||||||
Predicate<CardRules> op;
|
|
||||||
if (t.contains(".")) {
|
|
||||||
String[] typeParts = t.split("\\.");
|
|
||||||
if (CardType.isASupertype(typeParts[0])) {
|
|
||||||
op = Predicates.and(CardRulesPredicates.superType(true, typeParts[0]), CardRulesPredicates.coreType(true, typeParts[1]));
|
|
||||||
} else {
|
|
||||||
op = Predicates.and(CardRulesPredicates.coreType(true, typeParts[0]), CardRulesPredicates.subType(typeParts[1]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
op = CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, t);
|
|
||||||
}
|
|
||||||
Iterables.addAll(cards, getMatchingItems(cardList, op, PaperCard.FN_GET_RULES));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
case ABILITY: // already done above
|
case ABILITY: // already done above
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ public final class ManaCost implements Comparable<ManaCost>, Iterable<ManaCostSh
|
|||||||
public Iterator<ManaCostShard> iterator() {
|
public Iterator<ManaCostShard> iterator() {
|
||||||
return this.shards.iterator();
|
return this.shards.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGlyphCount() { // counts all colored shards or 1 for {0} costs
|
public int getGlyphCount() { // counts all colored shards or 1 for {0} costs
|
||||||
int width = shards.size();
|
int width = shards.size();
|
||||||
if (genericCost > 0 || (genericCost == 0 && width == 0)) {
|
if (genericCost > 0 || (genericCost == 0 && width == 0)) {
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ public final class GameActionUtil {
|
|||||||
for (KeywordInterface inst : source.getKeywords()) {
|
for (KeywordInterface inst : source.getKeywords()) {
|
||||||
final String keyword = inst.getOriginal();
|
final String keyword = inst.getOriginal();
|
||||||
if (keyword.startsWith("AlternateAdditionalCost")) {
|
if (keyword.startsWith("AlternateAdditionalCost")) {
|
||||||
final List<SpellAbility> newAbilities = Lists.newArrayList();
|
abilities.clear();
|
||||||
|
|
||||||
for (String s : keyword.split(":", 2)[1].split(":")) {
|
for (String s : keyword.split(":", 2)[1].split(":")) {
|
||||||
final SpellAbility newSA = sa.copy();
|
final SpellAbility newSA = sa.copy();
|
||||||
@@ -539,24 +539,21 @@ public final class GameActionUtil {
|
|||||||
newSA.setDescription(sa.getDescription() + " (Additional cost: " + cost.toSimpleString() + ")");
|
newSA.setDescription(sa.getDescription() + " (Additional cost: " + cost.toSimpleString() + ")");
|
||||||
newSA.setPayCosts(cost.add(sa.getPayCosts()));
|
newSA.setPayCosts(cost.add(sa.getPayCosts()));
|
||||||
if (newSA.canPlay()) {
|
if (newSA.canPlay()) {
|
||||||
newAbilities.add(newSA);
|
abilities.add(newSA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abilities.clear();
|
|
||||||
abilities.addAll(newAbilities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sa.isActivatedAbility() && sa.hasParam("AlternateCost")) {
|
} else if (sa.isActivatedAbility() && sa.hasParam("AlternateCost")) {
|
||||||
// need to be handled there because it needs to rebuilt the description for the original ability
|
// need to be handled there because it needs to rebuilt the description for the original ability
|
||||||
|
|
||||||
final List<SpellAbility> newAbilities = Lists.newArrayList();
|
abilities.clear();
|
||||||
|
|
||||||
SpellAbility newSA = sa.copy();
|
SpellAbility newSA = sa.copy();
|
||||||
newSA.removeParam("AlternateCost");
|
newSA.removeParam("AlternateCost");
|
||||||
newSA.rebuiltDescription();
|
newSA.rebuiltDescription();
|
||||||
if (newSA.canPlay()) {
|
if (newSA.canPlay()) {
|
||||||
newAbilities.add(newSA);
|
abilities.add(newSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the cost to this directly to bypass non mana cost
|
// set the cost to this directly to bypass non mana cost
|
||||||
@@ -565,11 +562,8 @@ public final class GameActionUtil {
|
|||||||
newSA2.removeParam("AlternateCost");
|
newSA2.removeParam("AlternateCost");
|
||||||
newSA2.rebuiltDescription();
|
newSA2.rebuiltDescription();
|
||||||
if (newSA2.canPlay()) {
|
if (newSA2.canPlay()) {
|
||||||
newAbilities.add(newSA2);
|
abilities.add(newSA2);
|
||||||
}
|
}
|
||||||
|
|
||||||
abilities.clear();
|
|
||||||
abilities.addAll(newAbilities);
|
|
||||||
}
|
}
|
||||||
return abilities;
|
return abilities;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3934,38 +3934,32 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
currentState.setBaseLoyalty(Integer.toString(n));
|
currentState.setBaseLoyalty(Integer.toString(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
// values that are printed on card
|
|
||||||
public final int getBasePower() {
|
public final int getBasePower() {
|
||||||
return currentState.getBasePower();
|
return currentState.getBasePower();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getBaseToughness() {
|
public final int getBaseToughness() {
|
||||||
return currentState.getBaseToughness();
|
return currentState.getBaseToughness();
|
||||||
}
|
}
|
||||||
|
|
||||||
// values that are printed on card
|
|
||||||
public final void setBasePower(final int n) {
|
public final void setBasePower(final int n) {
|
||||||
currentState.setBasePower(n);
|
currentState.setBasePower(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setBaseToughness(final int n) {
|
public final void setBaseToughness(final int n) {
|
||||||
currentState.setBaseToughness(n);
|
currentState.setBaseToughness(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// values that are printed on card
|
// values that are printed on card
|
||||||
public final String getBasePowerString() {
|
public final String getBasePowerString() {
|
||||||
return currentState.getBasePowerString();
|
return (null == currentState.getBasePowerString()) ? String.valueOf(getBasePower()) : currentState.getBasePowerString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getBaseToughnessString() {
|
public final String getBaseToughnessString() {
|
||||||
return currentState.getBaseToughnessString();
|
return (null == currentState.getBaseToughnessString()) ? String.valueOf(getBaseToughness()) : currentState.getBaseToughnessString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// values that are printed on card
|
// values that are printed on card
|
||||||
public final void setBasePowerString(final String s) {
|
public final void setBasePowerString(final String s) {
|
||||||
currentState.setBasePowerString(s);
|
currentState.setBasePowerString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setBaseToughnessString(final String s) {
|
public final void setBaseToughnessString(final String s) {
|
||||||
currentState.setBaseToughnessString(s);
|
currentState.setBaseToughnessString(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -568,7 +568,7 @@ public class CardFactory {
|
|||||||
c.setRules(in.getRules());
|
c.setRules(in.getRules());
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
} // copyStats()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy characteristics of a particular state of one card to those of a
|
* Copy characteristics of a particular state of one card to those of a
|
||||||
@@ -764,12 +764,14 @@ public class CardFactory {
|
|||||||
state.removeIntrinsicKeyword(kw);
|
state.removeIntrinsicKeyword(kw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.getType().isCreature()) {
|
// CR 208.3 A noncreature object not on the battlefield has power or toughness only if it has a power and toughness printed on it.
|
||||||
|
// currently only LKI can be trusted?
|
||||||
|
if (state.getType().isCreature() || in.getOriginalState(originalState.getStateName()).getBasePowerString() != null) {
|
||||||
if (sa.hasParam("SetPower")) {
|
if (sa.hasParam("SetPower")) {
|
||||||
state.setBasePower(AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("SetPower"), sa));
|
state.setBasePower(AbilityUtils.calculateAmount(host, sa.getParam("SetPower"), sa));
|
||||||
}
|
}
|
||||||
if (sa.hasParam("SetToughness")) {
|
if (sa.hasParam("SetToughness")) {
|
||||||
state.setBaseToughness(AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("SetToughness"), sa));
|
state.setBaseToughness(AbilityUtils.calculateAmount(host, sa.getParam("SetToughness"), sa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -202,10 +202,10 @@ public class CardState extends GameObject implements IHasSVars {
|
|||||||
|
|
||||||
// values that are printed on card
|
// values that are printed on card
|
||||||
public final String getBasePowerString() {
|
public final String getBasePowerString() {
|
||||||
return (null == basePowerString) ? "" + getBasePower() : basePowerString;
|
return basePowerString;
|
||||||
}
|
}
|
||||||
public final String getBaseToughnessString() {
|
public final String getBaseToughnessString() {
|
||||||
return (null == baseToughnessString) ? "" + getBaseToughness() : baseToughnessString;
|
return baseToughnessString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// values that are printed on card
|
// values that are printed on card
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ public final class CardUtil {
|
|||||||
newCopy.addAlternateState(CardStateName.Cloner, false);
|
newCopy.addAlternateState(CardStateName.Cloner, false);
|
||||||
newCopy.getState(CardStateName.Cloner).copyFrom(in.getState(CardStateName.Cloner), true);
|
newCopy.getState(CardStateName.Cloner).copyFrom(in.getState(CardStateName.Cloner), true);
|
||||||
}
|
}
|
||||||
//*/
|
*/
|
||||||
|
|
||||||
newCopy.setToken(in.isToken());
|
newCopy.setToken(in.isToken());
|
||||||
newCopy.setCopiedSpell(in.isCopiedSpell());
|
newCopy.setCopiedSpell(in.isCopiedSpell());
|
||||||
@@ -233,6 +233,10 @@ public final class CardUtil {
|
|||||||
newCopy.setBasePower(in.getCurrentPower());
|
newCopy.setBasePower(in.getCurrentPower());
|
||||||
newCopy.setBaseToughness(in.getCurrentToughness());
|
newCopy.setBaseToughness(in.getCurrentToughness());
|
||||||
|
|
||||||
|
// printed P/T
|
||||||
|
newCopy.setBasePowerString(in.getCurrentState().getBasePowerString());
|
||||||
|
newCopy.setBaseToughnessString(in.getCurrentState().getBaseToughnessString());
|
||||||
|
|
||||||
// extra copy PT boost
|
// extra copy PT boost
|
||||||
newCopy.setPTBoost(in.getPTBoostTable());
|
newCopy.setPTBoost(in.getPTBoostTable());
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ public class Cost implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public final ManaCost getTotalMana() {
|
public final ManaCost getTotalMana() {
|
||||||
CostPartMana manapart = getCostMana();
|
CostPartMana manapart = getCostMana();
|
||||||
return manapart == null ? ManaCost.ZERO : manapart.getManaToPay();
|
return manapart == null ? ManaCost.ZERO : manapart.getMana();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -943,7 +943,8 @@ public class Cost implements Serializable {
|
|||||||
} else if (part instanceof CostPutCounter || (mergeAdditional && // below usually not desired because they're from different causes
|
} else if (part instanceof CostPutCounter || (mergeAdditional && // below usually not desired because they're from different causes
|
||||||
(part instanceof CostDiscard || part instanceof CostDraw ||
|
(part instanceof CostDiscard || part instanceof CostDraw ||
|
||||||
part instanceof CostAddMana || part instanceof CostPayLife ||
|
part instanceof CostAddMana || part instanceof CostPayLife ||
|
||||||
part instanceof CostSacrifice || part instanceof CostTapType))) {
|
part instanceof CostSacrifice || part instanceof CostTapType||
|
||||||
|
part instanceof CostExile))) {
|
||||||
boolean alreadyAdded = false;
|
boolean alreadyAdded = false;
|
||||||
for (final CostPart other : costParts) {
|
for (final CostPart other : costParts) {
|
||||||
if ((other.getClass().equals(part.getClass()) || (part instanceof CostPutCounter && ((CostPutCounter)part).getCounter().is(CounterEnumType.LOYALTY))) &&
|
if ((other.getClass().equals(part.getClass()) || (part instanceof CostPutCounter && ((CostPutCounter)part).getCounter().is(CounterEnumType.LOYALTY))) &&
|
||||||
@@ -952,6 +953,7 @@ public class Cost implements Serializable {
|
|||||||
StringUtils.isNumeric(other.getAmount())) {
|
StringUtils.isNumeric(other.getAmount())) {
|
||||||
String amount = String.valueOf(part.convertAmount() + other.convertAmount());
|
String amount = String.valueOf(part.convertAmount() + other.convertAmount());
|
||||||
if (part instanceof CostPutCounter) { // CR 606.5 path for Carth
|
if (part instanceof CostPutCounter) { // CR 606.5 path for Carth
|
||||||
|
// TODO support X
|
||||||
if (other instanceof CostPutCounter && ((CostPutCounter)other).getCounter().equals(((CostPutCounter) part).getCounter())) {
|
if (other instanceof CostPutCounter && ((CostPutCounter)other).getCounter().equals(((CostPutCounter) part).getCounter())) {
|
||||||
costParts.add(new CostPutCounter(amount, ((CostPutCounter) part).getCounter(), part.getType(), part.getTypeDescription()));
|
costParts.add(new CostPutCounter(amount, ((CostPutCounter) part).getCounter(), part.getType(), part.getTypeDescription()));
|
||||||
} else if (other instanceof CostRemoveCounter && ((CostRemoveCounter)other).counter.is(CounterEnumType.LOYALTY)) {
|
} else if (other instanceof CostRemoveCounter && ((CostRemoveCounter)other).counter.is(CounterEnumType.LOYALTY)) {
|
||||||
@@ -978,6 +980,8 @@ public class Cost implements Serializable {
|
|||||||
costParts.add(new CostAddMana(amount, part.getType(), part.getTypeDescription()));
|
costParts.add(new CostAddMana(amount, part.getType(), part.getTypeDescription()));
|
||||||
} else if (part instanceof CostPayLife) {
|
} else if (part instanceof CostPayLife) {
|
||||||
costParts.add(new CostPayLife(amount, part.getTypeDescription()));
|
costParts.add(new CostPayLife(amount, part.getTypeDescription()));
|
||||||
|
} else if (part instanceof CostExile) {
|
||||||
|
costParts.add(new CostExile(amount, part.getType(), part.getTypeDescription(), ((CostExile) part).getFrom()));
|
||||||
}
|
}
|
||||||
toRemove.add(other);
|
toRemove.add(other);
|
||||||
alreadyAdded = true;
|
alreadyAdded = true;
|
||||||
|
|||||||
@@ -115,7 +115,13 @@ public class CostAdjustment {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (st.hasParam("ForEachShard")) {
|
if (st.hasParam("ForEachShard")) {
|
||||||
ManaCost mc = sa.getHostCard().getManaCost();
|
ManaCost mc = ManaCost.ZERO;
|
||||||
|
if (sa.isSpell()) {
|
||||||
|
mc = sa.getHostCard().getManaCost();
|
||||||
|
} else if (sa.isAbility() && sa.getPayCosts().hasManaCost()) {
|
||||||
|
// TODO check for AlternateCost$, it should always be part of the activation cost too
|
||||||
|
mc = sa.getPayCosts().getCostMana().getMana();
|
||||||
|
}
|
||||||
byte atom = ManaAtom.fromName(st.getParam("ForEachShard").toLowerCase());
|
byte atom = ManaAtom.fromName(st.getParam("ForEachShard").toLowerCase());
|
||||||
for (ManaCostShard shard : mc) {
|
for (ManaCostShard shard : mc) {
|
||||||
if ((shard.getColorMask() & atom) != 0) {
|
if ((shard.getColorMask() & atom) != 0) {
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ public class CostPartMana extends CostPart {
|
|||||||
* @return the mana
|
* @return the mana
|
||||||
*/
|
*/
|
||||||
public final ManaCost getMana() {
|
public final ManaCost getMana() {
|
||||||
// Only used for Human to pay for non-X cost first
|
|
||||||
return this.cost;
|
return this.cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +89,6 @@ public class CostPartMana extends CostPart {
|
|||||||
return !xCantBe0;
|
return !xCantBe0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the mana to pay.
|
|
||||||
*
|
|
||||||
* @return the mana to pay
|
|
||||||
*/
|
|
||||||
public final ManaCost getManaToPay() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the isExiledCreatureCost
|
* @return the isExiledCreatureCost
|
||||||
*/
|
*/
|
||||||
@@ -149,13 +139,13 @@ public class CostPartMana extends CostPart {
|
|||||||
if (timesToPay == 0) {
|
if (timesToPay == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getManaToPay());
|
ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getMana());
|
||||||
for (int i = 1; i < timesToPay; i++) {
|
for (int i = 1; i < timesToPay; i++) {
|
||||||
totalMana.addManaCost(getManaToPay());
|
totalMana.addManaCost(getMana());
|
||||||
}
|
}
|
||||||
return totalMana.toManaCost();
|
return totalMana.toManaCost();
|
||||||
}
|
}
|
||||||
return getManaToPay();
|
return getMana();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ public class AbilityManaPart implements java.io.Serializable {
|
|||||||
if (restriction.endsWith("X") && sa.costHasManaX()) {
|
if (restriction.endsWith("X") && sa.costHasManaX()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (restriction.endsWith("C") && sa.getPayCosts().hasManaCost() && sa.getPayCosts().getCostMana().getManaToPay().getShardCount(ManaCostShard.COLORLESS) > 0) {
|
if (restriction.endsWith("C") && sa.getPayCosts().hasManaCost() && sa.getPayCosts().getCostMana().getMana().getShardCount(ManaCostShard.COLORLESS) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -618,7 +618,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
payingMana.clear();
|
payingMana.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//getSpendPhyrexianMana
|
|
||||||
public final int getSpendPhyrexianMana() {
|
public final int getSpendPhyrexianMana() {
|
||||||
return this.spentPhyrexian;
|
return this.spentPhyrexian;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public class DeckHintsTest {
|
|||||||
list.add(readCard("assault_griffin.txt"));
|
list.add(readCard("assault_griffin.txt"));
|
||||||
list.add(readCard("auramancer.txt"));
|
list.add(readCard("auramancer.txt"));
|
||||||
|
|
||||||
List<PaperCard> filtered = hints.filter(list);
|
Iterable<PaperCard> filtered = hints.filter(list);
|
||||||
Assert.assertEquals(1, filtered.size());
|
Assert.assertEquals(1, Iterables.size(filtered));
|
||||||
Assert.assertEquals("Assault Griffin", filtered.get(0).getName());
|
Assert.assertEquals("Assault Griffin", Iterables.getLast(filtered).getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,7 +65,7 @@ public class DeckHintsTest {
|
|||||||
list.add(readCard("scepter_of_empires.txt"));
|
list.add(readCard("scepter_of_empires.txt"));
|
||||||
list.add(readCard("crown_of_empires.txt"));
|
list.add(readCard("crown_of_empires.txt"));
|
||||||
|
|
||||||
Assert.assertEquals(2, hints.filter(list).size());
|
Assert.assertEquals(2, Iterables.size(hints.filter(list)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +82,7 @@ public class DeckHintsTest {
|
|||||||
list.add(readCard("acidic_slime.txt"));
|
list.add(readCard("acidic_slime.txt"));
|
||||||
list.add(readCard("ajanis_sunstriker.txt"));
|
list.add(readCard("ajanis_sunstriker.txt"));
|
||||||
|
|
||||||
Assert.assertEquals(1, hints.filter(list).size());
|
Assert.assertEquals(1, Iterables.size(hints.filter(list)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +99,7 @@ public class DeckHintsTest {
|
|||||||
list.add(readCard("llanowar_elves.txt"));
|
list.add(readCard("llanowar_elves.txt"));
|
||||||
list.add(readCard("unsummon.txt"));
|
list.add(readCard("unsummon.txt"));
|
||||||
|
|
||||||
Assert.assertEquals(1, hints.filter(list).size());
|
Assert.assertEquals(1, Iterables.size(hints.filter(list)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,7 +150,7 @@ public class DeckHintsTest {
|
|||||||
list.add(pc);
|
list.add(pc);
|
||||||
list.add(readCard("assault_griffin.txt"));
|
list.add(readCard("assault_griffin.txt"));
|
||||||
|
|
||||||
Assert.assertEquals(1, hints.filter(list).size());
|
Assert.assertEquals(1, Iterables.size(hints.filter(list)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<property name="waypoints" value="68,69,70"/>
|
<property name="waypoints" value="68,69,70"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="54" template="../obj/enemy.tx" x="303.907" y="143.112">
|
<object id="54" template="../obj/enemy.tx" x="273" y="145.112">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="enemy" value="Gitaxian Underling"/>
|
<property name="enemy" value="Gitaxian Underling"/>
|
||||||
<property name="threatRange" value="20"/>
|
<property name="threatRange" value="20"/>
|
||||||
@@ -109,13 +109,13 @@
|
|||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
<objectgroup id="7" name="Waypoints">
|
<objectgroup id="7" name="Waypoints">
|
||||||
<object id="64" template="../obj/waypoint.tx" x="272.667" y="143.333"/>
|
<object id="64" template="../obj/waypoint.tx" x="273" y="145"/>
|
||||||
<object id="65" template="../obj/waypoint.tx" x="367.667" y="143.667"/>
|
<object id="65" template="../obj/waypoint.tx" x="367.667" y="145"/>
|
||||||
<object id="66" template="../obj/waypoint.tx" x="367.333" y="160.667"/>
|
<object id="66" template="../obj/waypoint.tx" x="367.333" y="157"/>
|
||||||
<object id="67" template="../obj/waypoint.tx" x="272.667" y="159"/>
|
<object id="67" template="../obj/waypoint.tx" x="272.667" y="157"/>
|
||||||
<object id="68" template="../obj/waypoint.tx" x="162" y="62"/>
|
<object id="68" template="../obj/waypoint.tx" x="163" y="61"/>
|
||||||
<object id="69" template="../obj/waypoint.tx" x="192" y="62"/>
|
<object id="69" template="../obj/waypoint.tx" x="192" y="61"/>
|
||||||
<object id="70" template="../obj/waypoint.tx" x="192" y="33"/>
|
<object id="70" template="../obj/waypoint.tx" x="192" y="34"/>
|
||||||
<object id="73" template="../obj/gate.tx" x="208.25" y="96.5">
|
<object id="73" template="../obj/gate.tx" x="208.25" y="96.5">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="dialog">[{
|
<property name="dialog">[{
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -4,5 +4,5 @@ Types:Artifact Equipment
|
|||||||
K:Equip:2
|
K:Equip:2
|
||||||
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 1 | Description$ Equipped creature gets +2/+1.
|
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 1 | Description$ Equipped creature gets +2/+1.
|
||||||
S:Mode$ Continuous | Affected$ Card.EquippedBy+Legendary | AddKeyword$ Trample & Haste | Description$ As long as equipped creature is legendary, it has trample and haste.
|
S:Mode$ Continuous | Affected$ Card.EquippedBy+Legendary | AddKeyword$ Trample & Haste | Description$ As long as equipped creature is legendary, it has trample and haste.
|
||||||
DeckNeeds:Type$Creature.Legendary
|
DeckNeeds:Type$Legendary & Type$Creature
|
||||||
Oracle:Equipped creature gets +2/+1.\nAs long as equipped creature is legendary, it has trample and haste.\nEquip {2}
|
Oracle:Equipped creature gets +2/+1.\nAs long as equipped creature is legendary, it has trample and haste.\nEquip {2}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Phyrexian Purge
|
Name:Phyrexian Purge
|
||||||
ManaCost:2 B R
|
ManaCost:2 B R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 2 B R PayLife<X> | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ MaxPayLifeLimit | SpellDescription$ This spell costs 3 life more to cast for each target. Destroy any number of target creatures.
|
A:SP$ Destroy | Cost$ 2 B R PayLife<X> | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ MaxPayLifeLimit | CostDesc$ This spell costs 3 life more to cast for each target. | SpellDescription$ Destroy any number of target creatures.
|
||||||
SVar:MaxPayLifeLimit:Count$YourLifeTotal/DivideEvenlyDown.3
|
SVar:MaxPayLifeLimit:Count$YourLifeTotal/DivideEvenlyDown.3
|
||||||
SVar:X:SVar$Y/Times.3
|
SVar:X:SVar$Y/Times.3
|
||||||
SVar:Y:Targeted$Amount
|
SVar:Y:Targeted$Amount
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ A:AB$ Mana | Cost$ T PayLife<1> | Produced$ Combo B R | SpellDescription$ Add {B
|
|||||||
A:AB$ DealDamage | Cost$ 1 B R T | Defined$ Opponent | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to each opponent.
|
A:AB$ DealDamage | Cost$ 1 B R T | Defined$ Opponent | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to each opponent.
|
||||||
A:AB$ ChooseCard | Cost$ 5 B R T Sac<1/CARDNAME> Sac<1/Artifact.Legendary/legendary artifact> | Defined$ You | Amount$ 2 | Choices$ Creature | ChoiceTitle$ Choose up to two creatures | SorcerySpeed$ True | AILogic$ Duneblast | SubAbility$ DBDestroyAll | StackDescription$ {p:You} chooses up to two creatures. Destroy the rest. | SpellDescription$ Choose up to two creatures, then destroy the rest. Activate only as a sorcery.
|
A:AB$ ChooseCard | Cost$ 5 B R T Sac<1/CARDNAME> Sac<1/Artifact.Legendary/legendary artifact> | Defined$ You | Amount$ 2 | Choices$ Creature | ChoiceTitle$ Choose up to two creatures | SorcerySpeed$ True | AILogic$ Duneblast | SubAbility$ DBDestroyAll | StackDescription$ {p:You} chooses up to two creatures. Destroy the rest. | SpellDescription$ Choose up to two creatures, then destroy the rest. Activate only as a sorcery.
|
||||||
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Creature.nonChosenCard | StackDescription$ None
|
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Creature.nonChosenCard | StackDescription$ None
|
||||||
DeckNeeds:Type$Legendary.Artifact
|
DeckNeeds:Type$Legendary & Type$Artifact
|
||||||
Oracle:{T}, Pay 1 life: Add {B} or {R}.\n{1}{B}{R}, {T}: Mount Doom deals 1 damage to each opponent.\n{5}{B}{R}, {T}, Sacrifice Mount Doom and a legendary artifact: Choose up to two creatures, then destroy the rest. Activate only as a sorcery.
|
Oracle:{T}, Pay 1 life: Add {B} or {R}.\n{1}{B}{R}, {T}: Mount Doom deals 1 damage to each opponent.\n{5}{B}{R}, {T}, Sacrifice Mount Doom and a legendary artifact: Choose up to two creatures, then destroy the rest. Activate only as a sorcery.
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ Name:You Cannot Pass!
|
|||||||
ManaCost:W
|
ManaCost:W
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Destroy | ValidTgts$ Creature.blockedValidThisTurn Creature.Legendary,Creature.blockedByValidThisTurn Creature.Legendary | TgtPrompt$ Select target creature that blocked or was blocked by a legendary creature this turn | SpellDescription$ Destroy target creature that blocked or was blocked by a legendary creature this turn.
|
A:SP$ Destroy | ValidTgts$ Creature.blockedValidThisTurn Creature.Legendary,Creature.blockedByValidThisTurn Creature.Legendary | TgtPrompt$ Select target creature that blocked or was blocked by a legendary creature this turn | SpellDescription$ Destroy target creature that blocked or was blocked by a legendary creature this turn.
|
||||||
DeckNeeds:Type$Legendary.Creature
|
DeckNeeds:Type$Legendary & Type$Creature
|
||||||
Oracle:Destroy target creature that blocked or was blocked by a legendary creature this turn.
|
Oracle:Destroy target creature that blocked or was blocked by a legendary creature this turn.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Human Warlock
|
|||||||
PT:1/1
|
PT:1/1
|
||||||
S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
|
S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
|
||||||
T:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPut | TriggerDescription$ Whenever you roll one or more dice, put a +1/+1 counter on CARDNAME.
|
T:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPut | TriggerDescription$ Whenever you roll one or more dice, put a +1/+1 counter on CARDNAME.
|
||||||
SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1
|
SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1
|
||||||
K:Choose a Background
|
K:Choose a Background
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
DeckHas:Ability$Counters
|
DeckHas:Ability$Counters
|
||||||
|
|||||||
@@ -6,8 +6,17 @@ Type=Commander
|
|||||||
ScryfallCode=MOC
|
ScryfallCode=MOC
|
||||||
|
|
||||||
[cards]
|
[cards]
|
||||||
|
1 M Bright-Palm, Soul Awakener @Mila Pesic
|
||||||
|
2 M Brimaz, Blight of Oreskos @Uriah Voth
|
||||||
|
3 M Gimbal, Gremlin Prodigy @Fajareka Setiawan
|
||||||
|
4 M Kasla, the Broken Halo @Martina Fackova
|
||||||
|
5 M Sidar Jabari of Zhalfir @Simon Dominic
|
||||||
|
49 C Esper @Bruce Brenneise
|
||||||
|
61 C Nyx @Piotr Dura
|
||||||
67 C Towashi @Kamila Szutenberg
|
67 C Towashi @Kamila Szutenberg
|
||||||
147 C Isle of Vesuva @Zoltan Boros & Gabor Szikszai
|
147 C Isle of Vesuva @Zoltan Boros & Gabor Szikszai
|
||||||
|
148 C Jund @Aleksi Briclot
|
||||||
|
153 C Panopticon @John Avon
|
||||||
158 C Spatial Merging @Gabor Szikszai
|
158 C Spatial Merging @Gabor Szikszai
|
||||||
445 M Goro-Goro and Satoru @Johannes Voss
|
445 M Goro-Goro and Satoru @Johannes Voss
|
||||||
446 M Katilda and Lier @Justyna Dura
|
446 M Katilda and Lier @Justyna Dura
|
||||||
|
|||||||
@@ -6,15 +6,25 @@ Type=Expansion
|
|||||||
ScryfallCode=MOM
|
ScryfallCode=MOM
|
||||||
|
|
||||||
[cards]
|
[cards]
|
||||||
|
9 R Boon-Bringer Valkyrie @Heonhwa Choe
|
||||||
17 R Heliod, the Radiant Dawn @Victor Adame Minguez
|
17 R Heliod, the Radiant Dawn @Victor Adame Minguez
|
||||||
58 R Faerie Mastermind @Joshua Raphael
|
58 R Faerie Mastermind @Joshua Raphael
|
||||||
65 M Jin-Gitaxias @Ekaterina Burmak
|
65 M Jin-Gitaxias @Ekaterina Burmak
|
||||||
67 C Moment of Truth @Rovina Cai
|
67 C Moment of Truth @Rovina Cai
|
||||||
|
89 R Archpriest of Shadows @Fariba Khamseh
|
||||||
94 R Breach the Multiverse @Liiga Smilshkalne
|
94 R Breach the Multiverse @Liiga Smilshkalne
|
||||||
|
114 R Invasion of Fiora @Joshua Raphael
|
||||||
|
117 U Merciless Repurposing @Artur Nakhodkin
|
||||||
134 M Chandra, Hope's Beacon @Kieran Yanner
|
134 M Chandra, Hope's Beacon @Kieran Yanner
|
||||||
|
190 R Invasion of Ikoria @Antonio José Manzanedo
|
||||||
|
191 R Invasion of Ixalan @Viktor Titov
|
||||||
|
194 U Invasion of Zendikar @Diego Gisbert
|
||||||
217 M Wrenn and Realmbreaker @Cristi Balanescu
|
217 M Wrenn and Realmbreaker @Cristi Balanescu
|
||||||
222 R Drana and Linvala @Raluca Marinescu
|
222 R Drana and Linvala @Raluca Marinescu
|
||||||
225 R Ghalta and Mavren @Zezhou Chen
|
225 R Ghalta and Mavren @Zezhou Chen
|
||||||
|
227 U Halo Forager @Kevin Sidharta
|
||||||
|
233 U Invasion of Ergamon @Manuel Castañón
|
||||||
|
239 M Invasion of New Phyrexia @Chris Rallis
|
||||||
249 R Omnath, Locus of All @Bryan Sola
|
249 R Omnath, Locus of All @Bryan Sola
|
||||||
255 M Thalia and The Gitrog Monster @Howard Lyon
|
255 M Thalia and The Gitrog Monster @Howard Lyon
|
||||||
256 R Yargle and Multani @Slawomir Maniak
|
256 R Yargle and Multani @Slawomir Maniak
|
||||||
@@ -40,5 +50,9 @@ ScryfallCode=MOM
|
|||||||
339 M Jin-Gitaxias @Julian Kok Joon Wen
|
339 M Jin-Gitaxias @Julian Kok Joon Wen
|
||||||
352 R Faerie Mastermind @Joshua Raphael
|
352 R Faerie Mastermind @Joshua Raphael
|
||||||
358 R Breach the Multiverse @Liiga Smilshkalne
|
358 R Breach the Multiverse @Liiga Smilshkalne
|
||||||
|
381 U Norn's Inquisitor @Denis Zhbankov
|
||||||
|
382 U Scrappy Bruiser @David Auden Nash
|
||||||
|
383 U Kami of Whispered Hopes @Filipe Pagliuso
|
||||||
|
384 U Botanical Brawler @Jesper Ejsing
|
||||||
386 R Ghalta and Mavren @Betty Jiang
|
386 R Ghalta and Mavren @Betty Jiang
|
||||||
387 R Omnath, Locus of All @Helge C. Balzer
|
387 R Omnath, Locus of All @Helge C. Balzer
|
||||||
|
|||||||
@@ -6,5 +6,16 @@ Type=Collector_Edition
|
|||||||
ScryfallCode=MUL
|
ScryfallCode=MUL
|
||||||
|
|
||||||
[cards]
|
[cards]
|
||||||
|
3 M Elesh Norn, Grand Cenobite @Flavio Girón
|
||||||
|
9 R Emry, Lurker of the Loch @Wylie Beckert
|
||||||
|
11 M Jin-Gitaxias, Core Augur @Kekai Kotaki
|
||||||
|
16 M Sheoldred, Whispering One @Flavio Girón
|
||||||
|
17 M Skithiryx, the Blight Dragon @Kekai Kotaki
|
||||||
|
19 U Yargle, Glutton of Urborg @Serena Malyon
|
||||||
21 M Ragavan, Nimble Pilferer @Magali Villeneuve
|
21 M Ragavan, Nimble Pilferer @Magali Villeneuve
|
||||||
|
23 M Urabrask the Hidden @Flavio Girón
|
||||||
|
25 U Zada, Hedron Grinder @Dominik Mayer
|
||||||
|
29 M Vorinclex, Voice of Hunger @JungShan
|
||||||
33 M Atraxa, Praetors' Voice @Justin Hernandez & Alexis Hernandez
|
33 M Atraxa, Praetors' Voice @Justin Hernandez & Alexis Hernandez
|
||||||
|
49 M Kroxa, Titan of Death's Hunger @Jason A. Engle
|
||||||
|
53 M Niv-Mizzet Reborn @Illustranesia
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import forge.card.CardEdition;
|
|||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
import forge.card.CardRulesPredicates;
|
import forge.card.CardRulesPredicates;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.DeckHints;
|
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
@@ -591,12 +590,10 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
|
|||||||
if (ai.getRemRandomDecks()) {
|
if (ai.getRemRandomDecks()) {
|
||||||
final List<PaperCard> comboCards = new ArrayList<>();
|
final List<PaperCard> comboCards = new ArrayList<>();
|
||||||
if (ai.getDeckNeeds() != null && ai.getDeckNeeds().isValid()) {
|
if (ai.getDeckNeeds() != null && ai.getDeckNeeds().isValid()) {
|
||||||
final DeckHints needs = ai.getDeckNeeds();
|
Iterables.addAll(comboCards, ai.getDeckNeeds().filter(deckList));
|
||||||
comboCards.addAll(needs.filter(deckList));
|
|
||||||
}
|
}
|
||||||
if (ai.getDeckHints() != null && ai.getDeckHints().isValid()) {
|
if (ai.getDeckHints() != null && ai.getDeckHints().isValid()) {
|
||||||
final DeckHints hints = ai.getDeckHints();
|
Iterables.addAll(comboCards, ai.getDeckHints().filter(deckList));
|
||||||
comboCards.addAll(hints.filter(deckList));
|
|
||||||
}
|
}
|
||||||
if (comboCards.isEmpty()) {
|
if (comboCards.isEmpty()) {
|
||||||
if (logToConsole) {
|
if (logToConsole) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import forge.game.card.Card;
|
|||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.gui.GuiBase;
|
import forge.gui.GuiBase;
|
||||||
|
import forge.item.IPaperCard;
|
||||||
import forge.localinstance.properties.ForgePreferences;
|
import forge.localinstance.properties.ForgePreferences;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.player.PlayerControllerHuman;
|
import forge.player.PlayerControllerHuman;
|
||||||
@@ -78,8 +79,12 @@ public class InputConfirm extends InputSyncronizedBase {
|
|||||||
return controller.getGui().confirm(null, message, defaultIsYes, options);
|
return controller.getGui().confirm(null, message, defaultIsYes, options);
|
||||||
if (sa.getTargets() != null && sa.getTargets().isTargetingAnyCard() && sa.getTargets().size() == 1)
|
if (sa.getTargets() != null && sa.getTargets().isTargetingAnyCard() && sa.getTargets().size() == 1)
|
||||||
return controller.getGui().confirm((sa.getTargetCard()==null)?null:CardView.get(sa.getTargetCard()), message, defaultIsYes, options);
|
return controller.getGui().confirm((sa.getTargetCard()==null)?null:CardView.get(sa.getTargetCard()), message, defaultIsYes, options);
|
||||||
if (ApiType.Play.equals(sa.getApi()) && sa.getPlayEffectCard() != null)
|
if (ApiType.Play.equals(sa.getApi()) && sa.getPlayEffectCard() != null) {
|
||||||
|
IPaperCard iPaperCard = sa.getPlayEffectCard().getPaperCard();
|
||||||
|
if (iPaperCard != null) //getcardforUI regardless of zone if it's hidden or not...
|
||||||
|
return controller.getGui().confirm(CardView.getCardForUi(iPaperCard), message, defaultIsYes, options);
|
||||||
return controller.getGui().confirm(CardView.get(sa.getPlayEffectCard()), message, defaultIsYes, options);
|
return controller.getGui().confirm(CardView.get(sa.getPlayEffectCard()), message, defaultIsYes, options);
|
||||||
|
}
|
||||||
return controller.getGui().confirm(CardView.get(sa.getHostCard()), message, defaultIsYes, options);
|
return controller.getGui().confirm(CardView.get(sa.getHostCard()), message, defaultIsYes, options);
|
||||||
} else {
|
} else {
|
||||||
InputConfirm inp;
|
InputConfirm inp;
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
// 0 mana costs were slipping through because CostPart.getAmount returns 1
|
// 0 mana costs were slipping through because CostPart.getAmount returns 1
|
||||||
else if (costPart instanceof CostPartMana && parts.size() < 2) {
|
else if (costPart instanceof CostPartMana && parts.size() < 2) {
|
||||||
if (((CostPartMana) costPart).getManaToPay().isZero()) {
|
if (((CostPartMana) costPart).getMana().isZero()) {
|
||||||
return p.getController().confirmPayment(costPart, Localizer.getInstance().getMessage("lblDoYouWantPay") + " {0}?" + orString, sourceAbility);
|
return p.getController().confirmPayment(costPart, Localizer.getInstance().getMessage("lblDoYouWantPay") + " {0}?" + orString, sourceAbility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,7 +438,7 @@ public class HumanPlay {
|
|||||||
if (!hasPaid) { return false; }
|
if (!hasPaid) { return false; }
|
||||||
}
|
}
|
||||||
else if (part instanceof CostPartMana) {
|
else if (part instanceof CostPartMana) {
|
||||||
if (!((CostPartMana) part).getManaToPay().isZero()) { // non-zero costs require input
|
if (!((CostPartMana) part).getMana().isZero()) { // non-zero costs require input
|
||||||
mayRemovePart = false;
|
mayRemovePart = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||