mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 17:58:01 +00:00
Merge branch 'master' of git.cardforge.org:core-developers/forge into agetian-master
This commit is contained in:
@@ -1354,7 +1354,7 @@ public class AiController {
|
|||||||
|
|
||||||
public AiPlayDecision canPlayFromEffectAI(Spell spell, boolean mandatory, boolean withoutPayingManaCost) {
|
public AiPlayDecision canPlayFromEffectAI(Spell spell, boolean mandatory, boolean withoutPayingManaCost) {
|
||||||
int damage = ComputerUtil.getDamageForPlaying(player, spell);
|
int damage = ComputerUtil.getDamageForPlaying(player, spell);
|
||||||
if (damage >= player.getLife() && !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
if (!mandatory && damage >= player.getLife() && !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
|
||||||
return AiPlayDecision.CurseEffects;
|
return AiPlayDecision.CurseEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2636,7 +2636,7 @@ public class ComputerUtil {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (trigger.hasParam("ValidCard")) {
|
if (trigger.hasParam("ValidCard")) {
|
||||||
if (!card.isValid(trigger.getParam("ValidCard"), source.getController(), source, sa)) {
|
if (!card.isValid(trigger.getParam("ValidCard").split(","), source.getController(), source, sa)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ public class PermanentAi extends SpellAbilityAi {
|
|||||||
if (!checkPhaseRestrictions(ai, sa, ai.getGame().getPhaseHandler())) {
|
if (!checkPhaseRestrictions(ai, sa, ai.getGame().getPhaseHandler())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mandatory || checkApiLogic(ai, sa);
|
return checkApiLogic(ai, sa) || mandatory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ public class PlayAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
spell = (Spell) spell.copyWithDefinedCost(abCost);
|
spell = (Spell) spell.copyWithDefinedCost(abCost);
|
||||||
}
|
}
|
||||||
if( AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlayFromEffectAI(spell, !isOptional, true)) {
|
if (AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlayFromEffectAI(spell, !isOptional, true)) {
|
||||||
// Before accepting, see if the spell has a valid number of targets (it should at this point).
|
// Before accepting, see if the spell has a valid number of targets (it should at this point).
|
||||||
// Proceeding past this point if the spell is not correctly targeted will result
|
// Proceeding past this point if the spell is not correctly targeted will result
|
||||||
// in "Failed to add to stack" error and the card disappearing from the game completely.
|
// in "Failed to add to stack" error and the card disappearing from the game completely.
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ import forge.util.storage.StorageReaderFolder;
|
|||||||
* @author Forge
|
* @author Forge
|
||||||
* @version $Id: CardSet.java 9708 2011-08-09 19:34:12Z jendave $
|
* @version $Id: CardSet.java 9708 2011-08-09 19:34:12Z jendave $
|
||||||
*/
|
*/
|
||||||
public final class CardEdition implements Comparable<CardEdition> { // immutable
|
public final class CardEdition implements Comparable<CardEdition> {
|
||||||
|
|
||||||
|
// immutable
|
||||||
public enum Type {
|
public enum Type {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
|
|
||||||
@@ -234,6 +236,8 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
private String code;
|
private String code;
|
||||||
private String code2;
|
private String code2;
|
||||||
private String mciCode;
|
private String mciCode;
|
||||||
|
private String scryfallCode;
|
||||||
|
private String cardsLanguage;
|
||||||
private Type type;
|
private Type type;
|
||||||
private String name;
|
private String name;
|
||||||
private String alias = null;
|
private String alias = null;
|
||||||
@@ -323,6 +327,8 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
public String getCode() { return code; }
|
public String getCode() { return code; }
|
||||||
public String getCode2() { return code2; }
|
public String getCode2() { return code2; }
|
||||||
public String getMciCode() { return mciCode; }
|
public String getMciCode() { return mciCode; }
|
||||||
|
public String getScryfallCode() { return scryfallCode.toLowerCase(); }
|
||||||
|
public String getCardsLangCode() { return cardsLanguage.toLowerCase(); }
|
||||||
public Type getType() { return type; }
|
public Type getType() { return type; }
|
||||||
public String getName() { return name; }
|
public String getName() { return name; }
|
||||||
public String getAlias() { return alias; }
|
public String getAlias() { return alias; }
|
||||||
@@ -475,7 +481,8 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
* rarity - grouping #4
|
* rarity - grouping #4
|
||||||
* name - grouping #5
|
* name - grouping #5
|
||||||
*/
|
*/
|
||||||
"(^([0-9A-Z]+.?) )?(([SCURML]) )?(.*)$"
|
// "(^(.?[0-9A-Z]+.?))?(([SCURML]) )?(.*)$"
|
||||||
|
"(^(.?[0-9A-Z]+\\S?[A-Z]*)\\s)?(([SCURML])\\s)?(.*)$"
|
||||||
);
|
);
|
||||||
|
|
||||||
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();
|
ListMultimap<String, CardInSet> cardMap = ArrayListMultimap.create();
|
||||||
@@ -541,6 +548,14 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
|||||||
if (res.mciCode == null) {
|
if (res.mciCode == null) {
|
||||||
res.mciCode = res.code2.toLowerCase();
|
res.mciCode = res.code2.toLowerCase();
|
||||||
}
|
}
|
||||||
|
res.scryfallCode = section.get("ScryfallCode");
|
||||||
|
if (res.scryfallCode == null){
|
||||||
|
res.scryfallCode = res.code;
|
||||||
|
}
|
||||||
|
res.cardsLanguage = section.get("CardLang");
|
||||||
|
if (res.cardsLanguage == null){
|
||||||
|
res.cardsLanguage = "en";
|
||||||
|
}
|
||||||
|
|
||||||
res.boosterArts = section.getInt("BoosterCovers", 1);
|
res.boosterArts = section.getInt("BoosterCovers", 1);
|
||||||
String boosterDesc = section.get("Booster");
|
String boosterDesc = section.get("Booster");
|
||||||
|
|||||||
@@ -118,10 +118,6 @@ public class ImageUtil {
|
|||||||
return getImageRelativePath(cp, backFace, true, true);
|
return getImageRelativePath(cp, backFace, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getScryfallDownloadUrl(PaperCard cp, boolean backFace, String setCode){
|
|
||||||
return getScryfallDownloadUrl(cp, backFace, setCode, "en");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getScryfallDownloadUrl(PaperCard cp, boolean backFace, String setCode, String langCode){
|
public static String getScryfallDownloadUrl(PaperCard cp, boolean backFace, String setCode, String langCode){
|
||||||
String editionCode;
|
String editionCode;
|
||||||
if ((setCode != null) && (setCode.length() > 0))
|
if ((setCode != null) && (setCode.length() > 0))
|
||||||
|
|||||||
@@ -807,6 +807,8 @@ public class AbilityUtils {
|
|||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
list = new CardCollection((Card) root.getReplacingObject(AbilityKey.fromString(calcX[0].substring(8))));
|
list = new CardCollection((Card) root.getReplacingObject(AbilityKey.fromString(calcX[0].substring(8))));
|
||||||
}
|
}
|
||||||
|
// there could be null inside!
|
||||||
|
list = Iterables.filter(list, Card.class);
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
val = handlePaid(list, calcX[1], card, ability);
|
val = handlePaid(list, calcX[1], card, ability);
|
||||||
}
|
}
|
||||||
@@ -3424,7 +3426,6 @@ public class AbilityUtils {
|
|||||||
} else {
|
} else {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.startsWith("DifferentCMC")) {
|
if (string.startsWith("DifferentCMC")) {
|
||||||
@@ -3437,14 +3438,13 @@ public class AbilityUtils {
|
|||||||
|
|
||||||
if (string.startsWith("SumCMC")) {
|
if (string.startsWith("SumCMC")) {
|
||||||
int sumCMC = 0;
|
int sumCMC = 0;
|
||||||
for(Card c : paidList) {
|
for (Card c : paidList) {
|
||||||
sumCMC += c.getCMC();
|
sumCMC += c.getCMC();
|
||||||
}
|
}
|
||||||
return sumCMC;
|
return sumCMC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.startsWith("Valid")) {
|
if (string.startsWith("Valid")) {
|
||||||
|
|
||||||
final String[] splitString = string.split("/", 2);
|
final String[] splitString = string.split("/", 2);
|
||||||
String valid = splitString[0].substring(6);
|
String valid = splitString[0].substring(6);
|
||||||
final List<Card> list = CardLists.getValidCardsAsList(paidList, valid, source.getController(), source, ctb);
|
final List<Card> list = CardLists.getValidCardsAsList(paidList, valid, source.getController(), source, ctb);
|
||||||
@@ -3464,6 +3464,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
|
|
||||||
for (final Card c : filteredList) {
|
for (final Card c : filteredList) {
|
||||||
tot += xCount(c, filteredString, ctb);
|
tot += xCount(c, filteredString, ctb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -704,8 +704,8 @@ public abstract class SpellAbilityEffect {
|
|||||||
Card host = sa.getHostCard();
|
Card host = sa.getHostCard();
|
||||||
final Game game = host.getGame();
|
final Game game = host.getGame();
|
||||||
final String duration = sa.getParam("Duration");
|
final String duration = sa.getParam("Duration");
|
||||||
// in case host was LKI
|
// in case host was LKI or still resolving
|
||||||
if (host.isLKI()) {
|
if (host.isLKI() || host.getZone().is(ZoneType.Stack)) {
|
||||||
host = game.getCardState(host);
|
host = game.getCardState(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -243,5 +243,4 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,6 +63,7 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
boolean randomChoice = sa.hasParam("AtRandom");
|
boolean randomChoice = sa.hasParam("AtRandom");
|
||||||
boolean chooseFromDefined = sa.hasParam("ChooseFromDefinedCards");
|
boolean chooseFromDefined = sa.hasParam("ChooseFromDefinedCards");
|
||||||
|
boolean chooseFromOneTimeList = sa.hasParam("ChooseFromOneTimeList");
|
||||||
|
|
||||||
if (!randomChoice) {
|
if (!randomChoice) {
|
||||||
if (sa.hasParam("SelectPrompt")) {
|
if (sa.hasParam("SelectPrompt")) {
|
||||||
@@ -100,7 +102,7 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
|
|||||||
} else if (chooseFromDefined) {
|
} else if (chooseFromDefined) {
|
||||||
CardCollection choices = AbilityUtils.getDefinedCards(host, sa.getParam("ChooseFromDefinedCards"), sa);
|
CardCollection choices = AbilityUtils.getDefinedCards(host, sa.getParam("ChooseFromDefinedCards"), sa);
|
||||||
choices = CardLists.getValidCards(choices, valid, host.getController(), host, sa);
|
choices = CardLists.getValidCards(choices, valid, host.getController(), host, sa);
|
||||||
List<ICardFace> faces = Lists.newArrayList();
|
List<ICardFace> faces = new ArrayList<>();
|
||||||
// get Card
|
// get Card
|
||||||
for (final Card c : choices) {
|
for (final Card c : choices) {
|
||||||
final CardRules rules = c.getRules();
|
final CardRules rules = c.getRules();
|
||||||
@@ -114,6 +116,22 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
Collections.sort(faces);
|
Collections.sort(faces);
|
||||||
chosen = p.getController().chooseCardName(sa, faces, message);
|
chosen = p.getController().chooseCardName(sa, faces, message);
|
||||||
|
} else if (chooseFromOneTimeList) {
|
||||||
|
String [] names = sa.getParam("ChooseFromOneTimeList").split(",");
|
||||||
|
List<ICardFace> faces = new ArrayList<>();
|
||||||
|
for (String name : names) {
|
||||||
|
faces.add(StaticData.instance().getCommonCards().getFaceByName(name));
|
||||||
|
}
|
||||||
|
chosen = p.getController().chooseCardName(sa, faces, message);
|
||||||
|
|
||||||
|
// Remove chosen Name from List
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String name : names) {
|
||||||
|
if (chosen.equals(name)) continue;
|
||||||
|
if (sb.length() > 0) sb.append(',');
|
||||||
|
sb.append(name);
|
||||||
|
}
|
||||||
|
sa.putParam("ChooseFromOneTimeList", sb.toString());
|
||||||
} else {
|
} else {
|
||||||
// use CardFace because you might name a alternate names
|
// use CardFace because you might name a alternate names
|
||||||
Predicate<ICardFace> cpp = Predicates.alwaysTrue();
|
Predicate<ICardFace> cpp = Predicates.alwaysTrue();
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
|||||||
if (sa.hasParam("RandomCopied")) {
|
if (sa.hasParam("RandomCopied")) {
|
||||||
List<PaperCard> copysource = Lists.newArrayList(cards);
|
List<PaperCard> copysource = Lists.newArrayList(cards);
|
||||||
List<Card> choice = Lists.newArrayList();
|
List<Card> choice = Lists.newArrayList();
|
||||||
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
|
final String num = sa.getParamOrDefault("RandomNum","1");
|
||||||
int ncopied = AbilityUtils.calculateAmount(host, num, sa);
|
int ncopied = AbilityUtils.calculateAmount(host, num, sa);
|
||||||
while(ncopied > 0 && !copysource.isEmpty()) {
|
while (ncopied > 0 && !copysource.isEmpty()) {
|
||||||
final PaperCard cp = Aggregates.random(copysource);
|
final PaperCard cp = Aggregates.random(copysource);
|
||||||
Card possibleCard = Card.fromPaperCard(cp, activator); // Need to temporarily set the Owner so the Game is set
|
Card possibleCard = Card.fromPaperCard(cp, activator); // Need to temporarily set the Owner so the Game is set
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ public class MustAttackEffect extends SpellAbilityEffect {
|
|||||||
final Card host = sa.getHostCard();
|
final Card host = sa.getHostCard();
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
|
||||||
// end standard pre-
|
// end standard pre-
|
||||||
|
|
||||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||||
@@ -67,7 +66,6 @@ public class MustAttackEffect extends SpellAbilityEffect {
|
|||||||
entity = defPWs.getFirst();
|
entity = defPWs.getFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//System.out.println("Setting mustAttackEntity to: "+entity);
|
|
||||||
|
|
||||||
for (final Player p : tgtPlayers) {
|
for (final Player p : tgtPlayers) {
|
||||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import forge.game.zone.Zone;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
|
import forge.util.CardTranslation;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
@@ -93,8 +94,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("ShowCards")) {
|
if (sa.hasParam("ShowCards")) {
|
||||||
showCards = new CardCollection(AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("ShowCards"), sa));
|
showCards = new CardCollection(AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("ShowCards"), sa));
|
||||||
}
|
}
|
||||||
}
|
} else if (sa.hasParam("AnySupportedCard")) {
|
||||||
else if (sa.hasParam("AnySupportedCard")) {
|
|
||||||
final String valid = sa.getParam("AnySupportedCard");
|
final String valid = sa.getParam("AnySupportedCard");
|
||||||
List<PaperCard> cards = null;
|
List<PaperCard> cards = null;
|
||||||
if (valid.startsWith("Names:")){
|
if (valid.startsWith("Names:")){
|
||||||
@@ -139,8 +139,14 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else if (sa.hasParam("CopyFromChosenName")) {
|
||||||
else {
|
String name = source.getChosenName();
|
||||||
|
if (name.trim().isEmpty()) return;
|
||||||
|
Card card = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name), controller);
|
||||||
|
card.setToken(true);
|
||||||
|
tgtCards = new CardCollection();
|
||||||
|
tgtCards.add(card);
|
||||||
|
} else {
|
||||||
tgtCards = new CardCollection();
|
tgtCards = new CardCollection();
|
||||||
// filter only cards that didn't changed zones
|
// filter only cards that didn't changed zones
|
||||||
for (Card c : getTargetCards(sa)) {
|
for (Card c : getTargetCards(sa)) {
|
||||||
@@ -179,7 +185,16 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
while (!tgtCards.isEmpty() && amount > 0) {
|
while (!tgtCards.isEmpty() && amount > 0) {
|
||||||
activator.getController().tempShowCards(showCards);
|
activator.getController().tempShowCards(showCards);
|
||||||
Card tgtCard = controller.getController().chooseSingleEntityForEffect(tgtCards, sa, Localizer.getInstance().getMessage("lblSelectCardToPlay"), optional, null);
|
Card tgtCard = null;
|
||||||
|
if (tgtCards.size() == 1 && amount == 1 && optional) {
|
||||||
|
tgtCard = tgtCards.get(0);
|
||||||
|
if (!controller.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantPlayCard", CardTranslation.getTranslatedName(tgtCard.getName())))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tgtCard = controller.getController().chooseSingleEntityForEffect(tgtCards, sa, Localizer.getInstance().getMessage("lblSelectCardToPlay"), optional, null);
|
||||||
|
}
|
||||||
|
|
||||||
activator.getController().endTempShowCards();
|
activator.getController().endTempShowCards();
|
||||||
if (tgtCard == null) {
|
if (tgtCard == null) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package forge.game.ability.effects;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.GameCommand;
|
import forge.GameCommand;
|
||||||
@@ -154,20 +155,27 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
game.getUntap().addUntil(p, new GameCommand() {
|
game.getUntap().addUntil(p, new GameCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
List<Object> tempRemembered = Lists.newArrayList(Iterables.filter(source.getRemembered(), Player.class));
|
||||||
|
source.removeRemembered(tempRemembered);
|
||||||
source.addRemembered(p);
|
source.addRemembered(p);
|
||||||
AbilityUtils.resolve(repeat);
|
AbilityUtils.resolve(repeat);
|
||||||
source.removeRemembered(p);
|
source.removeRemembered(p);
|
||||||
|
source.addRemembered(tempRemembered);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// to avoid risk of collision with other abilities swap out other Remembered Player while resolving
|
||||||
|
List<Object> tempRemembered = Lists.newArrayList(Iterables.filter(source.getRemembered(), Player.class));
|
||||||
|
source.removeRemembered(tempRemembered);
|
||||||
source.addRemembered(p);
|
source.addRemembered(p);
|
||||||
AbilityUtils.resolve(repeat);
|
AbilityUtils.resolve(repeat);
|
||||||
source.removeRemembered(p);
|
source.removeRemembered(p);
|
||||||
|
source.addRemembered(tempRemembered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sa.hasParam("DamageMap")) {
|
if (sa.hasParam("DamageMap")) {
|
||||||
game.getAction().dealDamage(false, sa.getDamageMap(), sa.getPreventMap(), sa.getCounterTable(), sa);
|
game.getAction().dealDamage(false, sa.getDamageMap(), sa.getPreventMap(), sa.getCounterTable(), sa);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("ChangeZoneTable")) {
|
if (sa.hasParam("ChangeZoneTable")) {
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class ReplaceManaEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// need to log Updated events there, or the log is wrong order
|
// need to log Updated events there, or the log is wrong order
|
||||||
String message = sa.getReplacementEffect().toString();
|
String message = sa.getReplacementEffect().toString();
|
||||||
if ( !StringUtils.isEmpty(message)) {
|
if (!StringUtils.isEmpty(message)) {
|
||||||
message = TextUtil.fastReplace(message, "CARDNAME", card.getName());
|
message = TextUtil.fastReplace(message, "CARDNAME", card.getName());
|
||||||
game.getGameLog().add(GameLogEntryType.EFFECT_REPLACED, message);
|
game.getGameLog().add(GameLogEntryType.EFFECT_REPLACED, message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1708,6 +1708,9 @@ public class CardProperty {
|
|||||||
}
|
}
|
||||||
} else if (property.startsWith("set")) {
|
} else if (property.startsWith("set")) {
|
||||||
final String setCode = property.substring(3, 6);
|
final String setCode = property.substring(3, 6);
|
||||||
|
if (card.getName().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final PaperCard setCard = StaticData.instance().getCommonCards().getCardFromEdition(card.getName(), CardDb.SetPreference.Earliest);
|
final PaperCard setCard = StaticData.instance().getCommonCards().getCardFromEdition(card.getName(), CardDb.SetPreference.Earliest);
|
||||||
if (setCard != null && !setCard.getEdition().equals(setCode)) {
|
if (setCard != null && !setCard.getEdition().equals(setCode)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1086,7 +1086,7 @@ public class CardView extends GameEntityView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CardTypeView getType() {
|
public CardTypeView getType() {
|
||||||
if (isFaceDown() && !isInZone(EnumSet.of(ZoneType.Battlefield, ZoneType.Stack))) {
|
if (getState() != CardStateName.Original && isFaceDown() && !isInZone(EnumSet.of(ZoneType.Battlefield, ZoneType.Stack))) {
|
||||||
return CardType.EMPTY;
|
return CardType.EMPTY;
|
||||||
}
|
}
|
||||||
return get(TrackableProperty.Type);
|
return get(TrackableProperty.Type);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import forge.card.mana.ManaCost;
|
|||||||
import forge.card.mana.ManaCostParser;
|
import forge.card.mana.ManaCostParser;
|
||||||
import forge.game.CardTraitBase;
|
import forge.game.CardTraitBase;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CounterEnumType;
|
||||||
import forge.game.card.CounterType;
|
import forge.game.card.CounterType;
|
||||||
import forge.game.mana.ManaCostBeingPaid;
|
import forge.game.mana.ManaCostBeingPaid;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -876,15 +877,30 @@ public class Cost implements Serializable {
|
|||||||
costParts.add(0, new CostPartMana(oldManaCost.toManaCost(), r));
|
costParts.add(0, new CostPartMana(oldManaCost.toManaCost(), r));
|
||||||
}
|
}
|
||||||
} else if (part instanceof CostDiscard || part instanceof CostTapType ||
|
} else if (part instanceof CostDiscard || part instanceof CostTapType ||
|
||||||
part instanceof CostAddMana || part instanceof CostPayLife) {
|
part instanceof CostAddMana || part instanceof CostPayLife
|
||||||
|
|| part instanceof CostPutCounter) {
|
||||||
boolean alreadyAdded = false;
|
boolean alreadyAdded = false;
|
||||||
for (final CostPart other : costParts) {
|
for (final CostPart other : costParts) {
|
||||||
if (other.getClass().equals(part.getClass()) &&
|
if ((other.getClass().equals(part.getClass()) || (part instanceof CostPutCounter && ((CostPutCounter)part).getCounter().is(CounterEnumType.LOYALTY))) &&
|
||||||
part.getType().equals(other.getType()) &&
|
part.getType().equals(other.getType()) &&
|
||||||
StringUtils.isNumeric(part.getAmount()) &&
|
StringUtils.isNumeric(part.getAmount()) &&
|
||||||
StringUtils.isNumeric(other.getAmount())) {
|
StringUtils.isNumeric(other.getAmount())) {
|
||||||
final String amount = String.valueOf(Integer.parseInt(part.getAmount()) + Integer.parseInt(other.getAmount()));
|
String amount = String.valueOf(Integer.parseInt(part.getAmount()) + Integer.parseInt(other.getAmount()));
|
||||||
if (part instanceof CostDiscard) {
|
if (part instanceof CostPutCounter) { // path for Carth
|
||||||
|
if (other instanceof CostPutCounter && ((CostPutCounter)other).getCounter().is(CounterEnumType.LOYALTY)) {
|
||||||
|
costParts.add(new CostPutCounter(amount, CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription()));
|
||||||
|
} else if (other instanceof CostRemoveCounter && ((CostRemoveCounter)other).counter.is(CounterEnumType.LOYALTY)) {
|
||||||
|
Integer counters = Integer.parseInt(other.getAmount()) - Integer.parseInt(part.getAmount());
|
||||||
|
// the cost can turn positive if multiple Carth raise it
|
||||||
|
if (counters < 0) {
|
||||||
|
costParts.add(new CostPutCounter(String.valueOf(counters *-1), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription()));
|
||||||
|
} else {
|
||||||
|
costParts.add(new CostRemoveCounter(String.valueOf(counters), CounterType.get(CounterEnumType.LOYALTY), part.getType(), part.getTypeDescription(), ZoneType.Battlefield));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (part instanceof CostDiscard) {
|
||||||
costParts.add(new CostDiscard(amount, part.getType(), part.getTypeDescription()));
|
costParts.add(new CostDiscard(amount, part.getType(), part.getTypeDescription()));
|
||||||
} else if (part instanceof CostTapType) {
|
} else if (part instanceof CostTapType) {
|
||||||
CostTapType tappart = (CostTapType)part;
|
CostTapType tappart = (CostTapType)part;
|
||||||
|
|||||||
@@ -86,11 +86,12 @@ public class CostPayment extends ManaConversionMatrix {
|
|||||||
* a {@link forge.game.spellability.SpellAbility} object.
|
* a {@link forge.game.spellability.SpellAbility} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canPayAdditionalCosts(final Cost cost, final SpellAbility ability) {
|
public static boolean canPayAdditionalCosts(Cost cost, final SpellAbility ability) {
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cost = CostAdjustment.adjust(cost, ability);
|
||||||
return cost.canPay(ability);
|
return cost.canPay(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class CostPutCounter extends CostPartWithList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int paymentOrder() { return 8; }
|
public int paymentOrder() { return 6; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReusable() {
|
public boolean isReusable() {
|
||||||
|
|||||||
@@ -1762,7 +1762,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
public final boolean playLand(final Card land, final boolean ignoreZoneAndTiming) {
|
public final boolean playLand(final Card land, final boolean ignoreZoneAndTiming) {
|
||||||
// Dakkon Blackblade Avatar will use a similar effect
|
// Dakkon Blackblade Avatar will use a similar effect
|
||||||
if (canPlayLand(land, ignoreZoneAndTiming)) {
|
if (canPlayLand(land, ignoreZoneAndTiming)) {
|
||||||
this.playLandNoCheck(land);
|
playLandNoCheck(land);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1775,8 +1775,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
if (land.isFaceDown()) {
|
if (land.isFaceDown()) {
|
||||||
land.turnFaceUp(null);
|
land.turnFaceUp(null);
|
||||||
}
|
}
|
||||||
final Card c = game.getAction().moveTo(getZone(ZoneType.Battlefield), land, null);
|
|
||||||
game.copyLastState();
|
game.copyLastState();
|
||||||
|
final Card c = game.getAction().moveTo(getZone(ZoneType.Battlefield), land, null);
|
||||||
game.updateLastStateForCard(c);
|
game.updateLastStateForCard(c);
|
||||||
|
|
||||||
// play a sound
|
// play a sound
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class ReplaceProduceMana extends ReplacementEffect {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -765,6 +765,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
resetTriggeringObjects();
|
resetTriggeringObjects();
|
||||||
resetTriggerRemembered();
|
resetTriggerRemembered();
|
||||||
|
|
||||||
|
if (isActivatedAbility()) {
|
||||||
|
setXManaCostPaid(null);
|
||||||
|
}
|
||||||
|
|
||||||
// reset last state when finished resolving
|
// reset last state when finished resolving
|
||||||
setLastStateBattlefield(CardCollection.EMPTY);
|
setLastStateBattlefield(CardCollection.EMPTY);
|
||||||
setLastStateGraveyard(CardCollection.EMPTY);
|
setLastStateGraveyard(CardCollection.EMPTY);
|
||||||
|
|||||||
@@ -195,7 +195,6 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean checkZoneRestrictions(final Card c, final SpellAbility sa) {
|
public final boolean checkZoneRestrictions(final Card c, final SpellAbility sa) {
|
||||||
|
|
||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
final Zone cardZone = c.getLastKnownZone();
|
final Zone cardZone = c.getLastKnownZone();
|
||||||
Card cp = c;
|
Card cp = c;
|
||||||
|
|||||||
@@ -366,7 +366,6 @@ public class TargetRestrictions {
|
|||||||
return this.saValidTargeting;
|
return this.saValidTargeting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* canOnlyTgtOpponent.
|
* canOnlyTgtOpponent.
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ public class StaticAbilityCantBeCast {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean cantBeActivatedAbility(final SpellAbility spell, final Card card, final Player activator) {
|
public static boolean cantBeActivatedAbility(final SpellAbility spell, final Card card, final Player activator) {
|
||||||
|
if (spell.isTrigger()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final Game game = activator.getGame();
|
final Game game = activator.getGame();
|
||||||
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
||||||
for (final StaticAbility stAb : ca.getStaticAbilities()) {
|
for (final StaticAbility stAb : ca.getStaticAbilities()) {
|
||||||
@@ -98,7 +101,6 @@ public class StaticAbilityCantBeCast {
|
|||||||
* @return true, if successful
|
* @return true, if successful
|
||||||
*/
|
*/
|
||||||
public static boolean applyCantBeCastAbility(final StaticAbility stAb, final SpellAbility spell, final Card card, final Player activator) {
|
public static boolean applyCantBeCastAbility(final StaticAbility stAb, final SpellAbility spell, final Card card, final Player activator) {
|
||||||
|
|
||||||
if (!stAb.matchesValidParam("ValidCard", card)) {
|
if (!stAb.matchesValidParam("ValidCard", card)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -153,7 +155,6 @@ public class StaticAbilityCantBeCast {
|
|||||||
* @return true, if successful
|
* @return true, if successful
|
||||||
*/
|
*/
|
||||||
public static boolean applyCantBeActivatedAbility(final StaticAbility stAb, final SpellAbility spellAbility, final Card card, final Player activator) {
|
public static boolean applyCantBeActivatedAbility(final StaticAbility stAb, final SpellAbility spellAbility, final Card card, final Player activator) {
|
||||||
|
|
||||||
if (!stAb.matchesValidParam("ValidCard", card)) {
|
if (!stAb.matchesValidParam("ValidCard", card)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -543,7 +543,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final void finishResolving(final SpellAbility sa, final boolean fizzle) {
|
private final void finishResolving(final SpellAbility sa, final boolean fizzle) {
|
||||||
|
|
||||||
// SpellAbility is removed from the stack here
|
// SpellAbility is removed from the stack here
|
||||||
// temporarily removed removing SA after resolution
|
// temporarily removed removing SA after resolution
|
||||||
final SpellAbilityStackInstance si = getInstanceFromSpellAbility(sa);
|
final SpellAbilityStackInstance si = getInstanceFromSpellAbility(sa);
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ PT:0/0
|
|||||||
K:Menace
|
K:Menace
|
||||||
K:Modular:2
|
K:Modular:2
|
||||||
T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | CheckSVar$ YouCastThisTurn | SVarCompare$ GT1 | NoResolvingCheck$ True | TriggerDescription$ Whenever you cast a spell other than your first spell each turn, put a +1/+1 counter on CARDNAME.
|
T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | CheckSVar$ YouCastThisTurn | SVarCompare$ GT1 | NoResolvingCheck$ True | TriggerDescription$ Whenever you cast a spell other than your first spell each turn, put a +1/+1 counter on CARDNAME.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBDealDamage
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||||
SVar:YouCastThisTurn:Count$ThisTurnCast_Card.YouCtrl
|
SVar:YouCastThisTurn:Count$ThisTurnCast_Card.YouCtrl
|
||||||
DeckHas:Ability$Counters
|
DeckHas:Ability$Counters
|
||||||
DeckHints:Type$Artifact & Ability$Counters
|
DeckHints:Type$Artifact
|
||||||
Oracle:Menace\nModular 2 (This creature enters the battlefield with two +1/+1 counters on it. When it dies, you may put its +1/+1 counters on target artifact creature.)\nWhenever you cast a spell other than your first spell each turn, put a +1/+1 counter on Arcbound Tracker.
|
Oracle:Menace\nModular 2 (This creature enters the battlefield with two +1/+1 counters on it. When it dies, you may put its +1/+1 counters on target artifact creature.)\nWhenever you cast a spell other than your first spell each turn, put a +1/+1 counter on Arcbound Tracker.
|
||||||
@@ -4,7 +4,7 @@ Types:Legendary Planeswalker Basri
|
|||||||
Loyalty:4
|
Loyalty:4
|
||||||
A:AB$ PutCounter | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | CounterNum$ 1 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target creature | ValidTgts$ Creature | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on up to one target creature. It gains vigilance until end of turn.
|
A:AB$ PutCounter | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | CounterNum$ 1 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target creature | ValidTgts$ Creature | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on up to one target creature. It gains vigilance until end of turn.
|
||||||
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Vigilance
|
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Vigilance
|
||||||
A:AB$ Effect | Cost$ SubCounter<1/LOYALTY> | Triggers$ TrigAttack | SpellDescription$ Whenever a creature attacks this turn, put a +1/+1 counter on it.
|
A:AB$ Effect | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Triggers$ TrigAttack | SpellDescription$ Whenever a creature attacks this turn, put a +1/+1 counter on it.
|
||||||
SVar:TrigAttack:Mode$ Attacks | ValidCard$ Creature | Execute$ TrigPutCounter | TriggerDescription$ Whenever a creature attacks this turn, put a +1/+1 counter on it.
|
SVar:TrigAttack:Mode$ Attacks | ValidCard$ Creature | Execute$ TrigPutCounter | TriggerDescription$ Whenever a creature attacks this turn, put a +1/+1 counter on it.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredAttackerLKICopy | CounterType$ P1P1 | CounterNum$ 1
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredAttackerLKICopy | CounterType$ P1P1 | CounterNum$ 1
|
||||||
A:AB$ PumpAll | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Creature.YouCtrl | NumAtt$ +2 | NumDef$ +2 | KW$ Flying | SpellDescription$ Creatures you control get +2/+2 and gain flying until end of turn.
|
A:AB$ PumpAll | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Creature.YouCtrl | NumAtt$ +2 | NumDef$ +2 | KW$ Flying | SpellDescription$ Creatures you control get +2/+2 and gain flying until end of turn.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
Name:Burning Rootwalla
|
Name:Blazing Rootwalla
|
||||||
ManaCost:R
|
ManaCost:R
|
||||||
Types:Creature Lizard
|
Types:Creature Lizard
|
||||||
PT:1/1
|
PT:1/1
|
||||||
A:AB$ Pump | Cost$ R | NumAtt$ +2 | ActivationLimit$ 1 | SpellDescription$ CARDNAME gets +2/+0 until end of turn. Activate only once per turn.
|
A:AB$ Pump | Cost$ R | NumAtt$ +2 | ActivationLimit$ 1 | SpellDescription$ CARDNAME gets +2/+0 until end of turn. Activate only once per turn.
|
||||||
K:Madness:0
|
K:Madness:0
|
||||||
Oracle:{R}: Burning Rootwalla gets +2/+0 until end of turn. Activate only once per turn.\nMadness {0} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)
|
DeckHints:Ability$Discard
|
||||||
|
Oracle:{R}: Blazing Rootwalla gets +2/+0 until end of turn. Activate only once per turn.\nMadness {0} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
Name:Bog Rats
|
Name:Bog Rats
|
||||||
ManaCost:B
|
ManaCost:B
|
||||||
Types:Creature Rat
|
Types:Creature Rat
|
||||||
|
PT:1/1
|
||||||
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.Wall | Description$ CARDNAME can't be blocked by Walls.
|
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.Wall | Description$ CARDNAME can't be blocked by Walls.
|
||||||
Oracle:Bog Rats can't be blocked by Walls.
|
Oracle:Bog Rats can't be blocked by Walls.
|
||||||
13
forge-gui/res/cardsfolder/b/breathless_knight.txt
Normal file
13
forge-gui/res/cardsfolder/b/breathless_knight.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Name:Breathless Knight
|
||||||
|
ManaCost:1 W B
|
||||||
|
Types:Creature Spirit Knight
|
||||||
|
PT:2/2
|
||||||
|
K:Flying
|
||||||
|
K:Lifelink
|
||||||
|
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Battlefield | TriggerZones$ Battlefield | ValidCard$ Creature.YouOwn+Other | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, if it entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on CARDNAME.
|
||||||
|
T:Mode$ ChangesZone | Destination$ Battlefield | TriggerZones$ Battlefield | ValidCard$ Creature.YouOwn+Other+wasCastFromGraveyard | Execute$ TrigPutCounter | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, if it entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on CARDNAME.
|
||||||
|
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigPutCounter | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, if it entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on CARDNAME.
|
||||||
|
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Creature.Self+wasCastFromGraveyard | Execute$ TrigPutCounter | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another creature enters the battlefield under your control, if it entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on CARDNAME.
|
||||||
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterNum$ 1 | CounterType$ P1P1
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:Flying, lifelink\nWhenever Breathless Knight or another creature enters the battlefield under your control, if it entered from a graveyard or you cast it from a graveyard, put a +1/+1 counter on Breathless Knight.
|
||||||
10
forge-gui/res/cardsfolder/c/carth_the_lion.txt
Normal file
10
forge-gui/res/cardsfolder/c/carth_the_lion.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Carth the Lion
|
||||||
|
ManaCost:2 B G
|
||||||
|
Types:Legendary Creature Human Warrior
|
||||||
|
PT:3/5
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Planeswalker.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDig | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
|
SVar:TrigDig:DB$ Dig | DigNum$ 7 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Planeswalker | RestRandomOrder$ True | Reveal$ True
|
||||||
|
S:Mode$ RaiseCost | ValidCard$ Planeswalker.YouCtrl | Type$ Loyalty | Cost$ AddCounter<1/LOYALTY> | Description$ Planeswalkers' loyalty abilities you activate cost an additional [+1] to activate.
|
||||||
|
DeckNeeds:Type$Planeswalker
|
||||||
|
Oracle:Whenever Carth the Lion enters the battlefield or a planeswalker you control dies, look at the top seven cards of your library. You may reveal a planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.\nPlaneswalkers' loyalty abilities you activate cost an additional [+1] to activate.
|
||||||
@@ -2,6 +2,6 @@ Name:Diamond Lion
|
|||||||
ManaCost:2
|
ManaCost:2
|
||||||
Types:Artifact Creature Lion
|
Types:Artifact Creature Lion
|
||||||
PT:2/2
|
PT:2/2
|
||||||
A:AB$ Mana | Cost$ Discard<0/Hand> Sac<1/CARDNAME> | Produced$ Any | Amount$ 3 | InstantSpeed$ True | SpellDescription$ Add three mana of any one color. Activate only as an instant.
|
A:AB$ Mana | Cost$ T Discard<0/Hand> Sac<1/CARDNAME> | Produced$ Any | Amount$ 3 | InstantSpeed$ True | SpellDescription$ Add three mana of any one color. Activate only as an instant.
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:{T}, Discard your hand, Sacrifice Diamond Lion: Add three mana of any one color. Activate only as an instant.
|
Oracle:{T}, Discard your hand, Sacrifice Diamond Lion: Add three mana of any one color. Activate only as an instant.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Name:Drake Stone
|
Name:Drake Stone
|
||||||
ManaCost:U
|
ManaCost:3 U B
|
||||||
Types:Planeswalker Stone
|
Types:Planeswalker Stone
|
||||||
Loyalty:4
|
Loyalty:4
|
||||||
A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 1 | SubAbility$ DBDiscard | SpellDescription$ Draw a card, then each player discards a card.
|
A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 1 | SubAbility$ DBDiscard | SpellDescription$ Draw a card, then each player discards a card.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
Name:Emergent Growth
|
Name:Emergent Growth
|
||||||
ManaCost:3 G
|
ManaCost:3 G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Pump | Cost$ 3 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +5 | NumDef$ +5 | KW$ HIDDEN CARDNAME must be blocked if able. | AILogic$ Pump | SpellDescription$ Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
|
A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +5 | NumDef$ +5 | KW$ HIDDEN CARDNAME must be blocked if able. | AILogic$ Pump | StackDescription$ {c:Targeted} gets +5/+5 until end of turn and must be blocked this turn if able. | SpellDescription$ Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/emergent_growth.jpg
|
|
||||||
Oracle:Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
|
Oracle:Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user