diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index 76c8ed3b6a8..63a8536f1ff 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -150,6 +150,19 @@ public class CountersPutEffect extends SpellAbilityEffect { CardCollection leastToughness = new CardCollection(Aggregates.listWithMin(creatsYouCtrl, CardPredicates.Accessors.fnGetDefense)); tgtCards.addAll(pc.chooseCardsForEffect(leastToughness, sa, Localizer.getInstance().getMessage("lblChooseACreatureWithLeastToughness"), 1, 1, false)); tgtObjects.addAll(tgtCards); + } else if (sa.hasParam("Choices")) { + ZoneType choiceZone = ZoneType.Battlefield; + if (sa.hasParam("ChoiceZone")) { + choiceZone = ZoneType.smartValueOf(sa.getParam("ChoiceZone")); + } + CardCollection choices = new CardCollection(game.getCardsIn(choiceZone)); + + int n = sa.hasParam("ChoiceAmount") ? Integer.parseInt(sa.getParam("ChoiceAmount")) : 1; + + choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, card); + + String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") + " "; + tgtObjects.addAll(new CardCollection(pc.chooseCardsForEffect(choices, sa, title, n, n, !sa.hasParam("ChoiceOptional")))); } else { tgtObjects.addAll(getDefinedOrTargeted(sa, "Defined")); } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index d89ebcdaaf7..722b532282e 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -129,6 +129,8 @@ public class Card extends GameEntity implements Comparable { private final Multimap cantHaveKeywords = MultimapBuilder.hashKeys().enumSetValues(Keyword.class).build(); + private final Map counterTypeTimestamps = Maps.newEnumMap(CounterType.class); + private final Map canBlockAdditional = Maps.newTreeMap(); private final Set canBlockAny = Sets.newHashSet(); @@ -1305,12 +1307,44 @@ public class Card extends GameEntity implements Comparable { getController().addCounterToPermThisTurn(counterType, addAmount); view.updateCounters(this); } + if (newValue <= 0) { + removeCounterTimestamp(counterType); + } else { + addCounterTimestamp(counterType); + } if (table != null) { table.put(this, counterType, addAmount); } return addAmount; } + public boolean addCounterTimestamp(CounterType counterType) { + return addCounterTimestamp(counterType, true); + } + public boolean addCounterTimestamp(CounterType counterType, boolean updateView) { + if (!counterType.isKeywordCounter()) { + return false; + } + removeCounterTimestamp(counterType); + + long timestamp = game.getNextTimestamp(); + counterTypeTimestamps.put(counterType, timestamp); + addChangedCardKeywords(List.of(counterType.getKeyword().toString()), null, false, false, timestamp, updateView); + return true; + } + + public boolean removeCounterTimestamp(CounterType counterType) { + return removeCounterTimestamp(counterType, true); + } + + public boolean removeCounterTimestamp(CounterType counterType, boolean updateView) { + Long old = counterTypeTimestamps.remove(counterType); + if (old != null) { + removeChangedCardKeywords(old, updateView); + } + return old != null; + } + /** *

* addCountersAddedBy. @@ -1358,6 +1392,10 @@ public class Card extends GameEntity implements Comparable { setCounters(counterName, newValue); view.updateCounters(this); + if (newValue <= 0) { + this.removeCounterTimestamp(counterName); + } + //fire card stats changed event if p/t bonuses or loyalty changed from subtracted counters if (powerBonusBefore != getPowerBonusFromCounters() || toughnessBonusBefore != getToughnessBonusFromCounters() || loyaltyBefore != getCurrentLoyalty()) { getGame().fireEvent(new GameEventCardStatsChanged(this)); @@ -1380,8 +1418,23 @@ public class Card extends GameEntity implements Comparable { @Override public final void setCounters(final Map allCounters) { + boolean changed = false; + for (CounterType ct : counters.keySet()) { + if (removeCounterTimestamp(ct, false)) { + changed = true; + } + } counters = allCounters; view.updateCounters(this); + + for (CounterType ct : counters.keySet()) { + if (addCounterTimestamp(ct, false)) { + changed = true; + } + } + if (changed) { + updateKeywords(); + } } @Override @@ -1389,6 +1442,16 @@ public class Card extends GameEntity implements Comparable { if (counters.isEmpty()) { return; } counters.clear(); view.updateCounters(this); + + boolean changed = false; + for (CounterType ct : counterTypeTimestamps.keySet()) { + if (removeCounterTimestamp(ct, false)) { + changed = true; + } + } + if (changed) { + updateKeywords(); + } } public final String getSVar(final String var) { diff --git a/forge-game/src/main/java/forge/game/card/CounterType.java b/forge-game/src/main/java/forge/game/card/CounterType.java index 5d9fd5970d6..80825fa1f03 100644 --- a/forge-game/src/main/java/forge/game/card/CounterType.java +++ b/forge-game/src/main/java/forge/game/card/CounterType.java @@ -20,6 +20,8 @@ package forge.game.card; import com.google.common.collect.ImmutableList; +import forge.game.keyword.Keyword; + /** * The class Counters. * @@ -309,7 +311,23 @@ public enum CounterType { EXPERIENCE("EXP"), - POISON("POISN"); + POISON("POISN"), + + // Keyword Counters + + FLYING("Flying"), + FIRST_STRIKE("First Strike"), + DOUBLE_STRIKE("Double Strike"), + DEATHTOUCH("Deathtouch"), + HEXPROOF("Hexproof"), + INDESTRUCTIBLE("Indestructible"), + LIFELINK("Lifelink"), + MENACE("Menace"), + REACH("Reach"), + TRAMPLE("Trample"), + VIGILANCE("Vigilance") + + ; private String name, counterOnCardDisplayName; private int red, green, blue; @@ -365,6 +383,39 @@ public enum CounterType { return Enum.valueOf(CounterType.class, replacedName); } + public boolean isKeywordCounter() { + return this.getKeyword() != null; + } + + public Keyword getKeyword() { + switch (this) { + case FLYING: + return Keyword.FLYING; + case FIRST_STRIKE: + return Keyword.FIRST_STRIKE; + case DOUBLE_STRIKE: + return Keyword.DOUBLE_STRIKE; + case DEATHTOUCH: + return Keyword.DEATHTOUCH; + case HEXPROOF: + return Keyword.HEXPROOF; + case INDESTRUCTIBLE: + return Keyword.INDESTRUCTIBLE; + case LIFELINK: + return Keyword.LIFELINK; + case MENACE: + return Keyword.MENACE; + case REACH: + return Keyword.REACH; + case TRAMPLE: + return Keyword.TRAMPLE; + case VIGILANCE: + return Keyword.VIGILANCE; + default: + return null; + } + } + public static final ImmutableList values = ImmutableList.copyOf(values()); } diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java index a3f9715730e..752253cd617 100644 --- a/forge-gui-android/src/forge/app/Main.java +++ b/forge-gui-android/src/forge/app/Main.java @@ -76,7 +76,7 @@ public class Main extends AndroidApplication { text.setTypeface(Typeface.SERIF); String title="Forge needs Storage Permission to run properly...\n" + - "Follow this simple steps below:\n\n"; + "Follow these simple steps:\n\n"; String steps = " 1) Tap \"Open App Details\" Button.\n" + " 2) Tap Permissions\n"+ " 3) Turn on the Storage Permission.\n\n"+ diff --git a/forge-gui/res/cardsfolder/d/dismantle.txt b/forge-gui/res/cardsfolder/d/dismantle.txt index c39d32dfd26..69a7d4e4fb4 100644 --- a/forge-gui/res/cardsfolder/d/dismantle.txt +++ b/forge-gui/res/cardsfolder/d/dismantle.txt @@ -1,13 +1,9 @@ Name:Dismantle ManaCost:2 R Types:Sorcery -A:SP$ Destroy | Cost$ 2 R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | RememberTargets$ True | SubAbility$ DBChoice | SpellDescription$ Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control. -SVar:DBChoice:DB$ GenericChoice | Choices$ DBP1P1,DBCharge | ConditionDefined$ Targeted | ConditionPresent$ Card.HasCounters | ConditionCompare$ GE1 | StackDescription$ put that many +1/+1 counters or charge counters on an artifact you control. -SVar:DBP1P1:DB$ ChooseCard | Choices$ Artifact.YouCtrl | Amount$ 1 | SpellDescription$ +1/+1 | SubAbility$ DBPutP1P1 -SVar:DBPutP1P1:DB$ PutCounter | Defined$ ChosenCard | CounterType$ P1P1 | CounterNum$ X | References$ X | SubAbility$ DBCleanup -SVar:DBCharge:DB$ ChooseCard | Choices$ Artifact.YouCtrl | Amount$ 1 | SpellDescription$ charge | SubAbility$ DBPutCharge -SVar:DBPutCharge:DB$ PutCounter | Defined$ ChosenCard | CounterType$ CHARGE | CounterNum$ X | References$ X | SpellDescription$ Charge | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:RememberedLKI$CardCounters.ALL -SVar:Picture:http://www.wizards.com/global/images/magic/general/dismantle.jpg +A:SP$ Destroy | Cost$ 2 R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SubAbility$ DBChoice | SpellDescription$ Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control. +SVar:DBChoice:DB$ GenericChoice | Choices$ DBPutP1P1,DBPutCharge | ConditionDefined$ Targeted | ConditionPresent$ Card.HasCounters | ConditionCompare$ GE1 | StackDescription$ put that many +1/+1 counters or charge counters on an artifact you control. +SVar:DBPutP1P1:DB$ PutCounter | Choices$ Artifact.YouCtrl | CounterType$ P1P1 | CounterNum$ X | References$ X | SpellDescription$ +1/+1 +SVar:DBPutCharge:DB$ PutCounter | Choices$ Artifact.YouCtrl | CounterType$ CHARGE | CounterNum$ X | References$ X | SpellDescription$ Charge +SVar:X:TargetedLKI$CardCounters.ALL Oracle:Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control. diff --git a/forge-gui/res/cardsfolder/f/find_finality.txt b/forge-gui/res/cardsfolder/f/find_finality.txt index 2b85d2313fd..a4c41981640 100644 --- a/forge-gui/res/cardsfolder/f/find_finality.txt +++ b/forge-gui/res/cardsfolder/f/find_finality.txt @@ -10,9 +10,7 @@ ALTERNATE Name:Finality ManaCost:4 B G Types:Sorcery -A:SP$ ChooseCard | Cost$ 4 B G | Defined$ You | Amount$ 1 | MinAmount$ 0 | Choices$ Creature.YouCtrl | SubAbility$ DBPutCounter | SpellDescription$ You may put two +1/+1 counters on a creature you control. Then all creatures get -4/-4 until end of turn. -SVar:DBPutCounter:DB$ PutCounter | Defined$ ChosenCard | CounterType$ P1P1 | CounterNum$ 2 | SubAbility$ DBPumpAll -SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature | NumAtt$ -4 | NumDef$ -4 | IsCurse$ True | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +A:SP$ PutCounter | Cost$ 4 B G | Choices$ Creature.YouCtrl | ChoiceOptional$ True | CounterType$ P1P1 | CounterNum$ 2 | SubAbility$ DBPumpAll | StackDescription$ SpellDescription | SpellDescription$ You may put two +1/+1 counters on a creature you control. Then all creatures get -4/-4 until end of turn. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature | NumAtt$ -4 | NumDef$ -4 | IsCurse$ True DeckHas:Ability$Counters Oracle:You may put two +1/+1 counters on a creature you control. Then all creatures get -4/-4 until end of turn. diff --git a/forge-gui/res/cardsfolder/h/haphazard_bombardment.txt b/forge-gui/res/cardsfolder/h/haphazard_bombardment.txt index d598dd69a28..eccf46ba889 100644 --- a/forge-gui/res/cardsfolder/h/haphazard_bombardment.txt +++ b/forge-gui/res/cardsfolder/h/haphazard_bombardment.txt @@ -1,12 +1,10 @@ Name:Haphazard Bombardment ManaCost:5 R Types:Enchantment -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters the battlefield, choose four nonenchantment permanents you don't control and put an aim counter on each of them. -SVar:TrigChoose:DB$ ChooseCard | Defined$ You | Amount$ 4 | Choices$ Permanent.YouDontCtrl+nonEnchantment | SubAbility$ DBPutCounter | AILogic$ AtLeast1 | Mandatory$ True -SVar:DBPutCounter:DB$ PutCounter | Defined$ ChosenCard | CounterType$ AIM | CounterNum$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBPutCounter | TriggerDescription$ When CARDNAME enters the battlefield, choose four nonenchantment permanents you don't control and put an aim counter on each of them. +SVar:DBPutCounter:DB$ PutCounter | Choices$ Permanent.YouDontCtrl+nonEnchantment | ChoiceAmount§ 4 | Defined$ ChosenCard | CounterType$ AIM | CounterNum$ 1 T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Permanent.YouDontCtrl+counters_GE1_AIM | PresentCompare$ GE2 | Execute$ TrigDestroy | TriggerDescription$ At the beginning of your end step, if two or more permanents you don't control have an aim counter on them, destroy one of those permanents at random. SVar:TrigDestroy:DB$ ChooseCard | Amount$ 1 | AtRandom$ True | Choices$ Permanent.YouDontCtrl+counters_GE1_AIM | SubAbility$ DBDestroy SVar:DBDestroy:DB$ Destroy | Defined$ ChosenCard | SubAbility$ DBCleanup -SVar:Picture:http://www.wizards.com/global/images/magic/general/haphazard_bombardment.jpg +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True Oracle:When Haphazard Bombardment enters the battlefield, choose four nonenchantment permanents you don't control and put an aim counter on each of them.\nAt the beginning of your end step, if two or more permanents you don't control have an aim counter on them, destroy one of those permanents at random. diff --git a/forge-gui/res/cardsfolder/s/settle_the_score.txt b/forge-gui/res/cardsfolder/s/settle_the_score.txt index 08d18bef014..4820ed006f0 100644 --- a/forge-gui/res/cardsfolder/s/settle_the_score.txt +++ b/forge-gui/res/cardsfolder/s/settle_the_score.txt @@ -1,7 +1,6 @@ Name:Settle the Score ManaCost:2 B B Types:Sorcery -A:SP$ ChangeZone | Cost$ 2 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBChoice | SpellDescription$ Exile target creature. Put two loyalty counters on a planeswalker you control. -SVar:DBChoice:DB$ ChooseCard | Choices$ Planeswalker.YouCtrl | Amount$ 1 | Mandatory$ True | SubAbility$ DBPutLoyalty -SVar:DBPutLoyalty:DB$ PutCounter | Defined$ ChosenCard | CounterType$ LOYALTY | CounterNum$ 2 +A:SP$ ChangeZone | Cost$ 2 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBPutLoyalty | SpellDescription$ Exile target creature. Put two loyalty counters on a planeswalker you control. +SVar:DBPutLoyalty:DB$ PutCounter | Choices$ Planeswalker.YouCtrl | CounterType$ LOYALTY | CounterNum$ 2 Oracle:Exile target creature. Put two loyalty counters on a planeswalker you control. diff --git a/forge-gui/res/cardsfolder/t/the_elderspell.txt b/forge-gui/res/cardsfolder/t/the_elderspell.txt index ec0e5f85773..2255b8d308f 100644 --- a/forge-gui/res/cardsfolder/t/the_elderspell.txt +++ b/forge-gui/res/cardsfolder/t/the_elderspell.txt @@ -1,9 +1,8 @@ Name:The Elderspell ManaCost:B B Types:Sorcery -A:SP$ Destroy | Cost$ B B | ValidTgts$ Planeswalker | TgtPrompt$ Select target planeswalker | TargetMin$ 0 | TargetMax$ MaxTargets | References$ MaxTargets | SubAbility$ DBChooseCard | RememberDestroyed$ True | SpellDescription$ Destroy any number of target planeswalkers. Choose a planeswalker you control. Put two loyalty counters on it for each planeswalker destroyed this way. -SVar:DBChooseCard:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Planeswalker.YouCtrl | Mandatory$ True | SubAbility$ DBPutLoyalty -SVar:DBPutLoyalty:DB$ PutCounter | Defined$ ChosenCard | CounterType$ LOYALTY | CounterNum$ X | References$ X | SubAbility$ DBCleanup +A:SP$ Destroy | Cost$ B B | ValidTgts$ Planeswalker | TgtPrompt$ Select target planeswalker | TargetMin$ 0 | TargetMax$ MaxTargets | References$ MaxTargets | SubAbility$ DBPutLoyalty | RememberDestroyed$ True | SpellDescription$ Destroy any number of target planeswalkers. Choose a planeswalker you control. Put two loyalty counters on it for each planeswalker destroyed this way. +SVar:DBPutLoyalty:DB$ PutCounter | Choices$ Planeswalker.YouCtrl | CounterType$ LOYALTY | CounterNum$ X | References$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:MaxTargets:Count$Valid Planeswalker SVar:X:Count$RememberedSize/Twice diff --git a/forge-gui/res/cardsfolder/upcoming/C2020/jirina_kudro.txt b/forge-gui/res/cardsfolder/upcoming/C2020/jirina_kudro.txt new file mode 100755 index 00000000000..5f91feb2e00 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/C2020/jirina_kudro.txt @@ -0,0 +1,11 @@ +Name:Jirina Kudro +ManaCost:1 R W B +Types:Legendary Creature Human Soldier +PT:3/3 +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 1/1 white Human Soldier creature token for each time you've cast a commander from the command zone this game. +SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ w_1_1_human | TokenOwner$ You | LegacyImage$ w 1 1 human c20 | References$ X +SVar:X:Count$TotalCommanderCastFromCommandZone +S:Mode$ Continuous | Affected$ Human.Other+YouCtrl | AddPower$ 2 | Description$ Other Humans you control get +2/+0. +SVar:PlayMain1:TRUE +DeckHints:Type$Human +Oracle:When Jirina Kudro enters the battlefield, create a 1/1 white Human Soldier creature token for each time you've cast a commander from the command zone this game.\nOther Humans you control get +2/+0. diff --git a/forge-gui/res/cardsfolder/upcoming/C2020/kalamax_the_stormsire.txt b/forge-gui/res/cardsfolder/upcoming/C2020/kalamax_the_stormsire.txt new file mode 100755 index 00000000000..ac646c3d73a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/C2020/kalamax_the_stormsire.txt @@ -0,0 +1,10 @@ +Name:Kalamax, the Stormsire +ManaCost:1 G U R +Types:Legendary Creature Elemental Dinosaur +PT:4/4 +T:Mode$ SpellCast | ValidCard$ Instant | ValidActivatingPlayer$ You | ActivatorThisTurnCast$ EQ1 | NoResolvingCheck$ True | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast your first instant spell each turn, if CARDNAME is tapped, copy that spell. You may choose new targets for the copy. +SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | IsPresent$ Card.Self+tapped | AILogic$ Always +SVar:BuffedBy:Instant +T:Mode$ SpellCopy | ValidCard$ Instant | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you copy an instant spell, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +Oracle:Whenever you cast your first instant spell each turn, if Kalamax, the Stormsire is tapped, copy that spell. You may choose new targets for the copy.\nWhenever you copy an instant spell, put a +1/+1 counter on Kalamax. diff --git a/forge-gui/res/cardsfolder/upcoming/back_for_more.txt b/forge-gui/res/cardsfolder/upcoming/back_for_more.txt new file mode 100755 index 00000000000..3ccf437129a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/back_for_more.txt @@ -0,0 +1,6 @@ +Name:Back for More +ManaCost:4 B G +Types:Instant +A:SP$ ChangeZone | Cost$ 4 B G | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | SubAbility$ DBFight | StackDescription$ SpellDescription | SpellDescription$ Return target creature card from your graveyard to the battlefield. When you do, it fights up to one target creature you don't control. +SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control | SubAbility$ DBCleanup | StackDescription$ None +Oracle:Return target creature card from your graveyard to the battlefield. When you do, it fights up to one target creature you don't control. (Each deals damage equal to its power to the other.) diff --git a/forge-gui/res/cardsfolder/upcoming/boon_of_the_wish_giver.txt b/forge-gui/res/cardsfolder/upcoming/boon_of_the_wish_giver.txt new file mode 100755 index 00000000000..34f8037b47a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/boon_of_the_wish_giver.txt @@ -0,0 +1,6 @@ +Name:Boon of the Wish-Giver +ManaCost:4 U U +Types:Sorcery +A:SP$ Draw | Cost$ 4 U U | NumCards$ 4 | SpellDescription$ Draw four cards. +K:Cycling:1 +Oracle:Draw four cards.\nCycling {1} ({1}, Discard this card: Draw a card.) diff --git a/forge-gui/res/cardsfolder/upcoming/channeled_force.txt b/forge-gui/res/cardsfolder/upcoming/channeled_force.txt new file mode 100755 index 00000000000..3d6aae1c6bf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/channeled_force.txt @@ -0,0 +1,7 @@ +Name:Channeled Force +ManaCost:2 U R +Types:Instant +A:SP$ Draw | Cost$ 2 U R Discard | CostDesc$ As an additional cost to cast this spell, discard X cards. | NumCards$ ChosenX | ValidTgts$ Player | TgtPrompt$ Choose a player | References$ X | SubAbility$ DBDamage | SpellDescription$ Target player draws X cards. CARDNAME deals X damage to up to one target creature or planeswalker. +SVar:DBDamage:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target creature or planeswalker. | NumDmg$ ChosenX | References$ X +SVar:X:XChoice +Oracle:As an additional cost to cast this spell, discard X cards.\nTarget player draws X cards. Channeled Force deals X damage to up to one target creature or planeswalker. diff --git a/forge-gui/res/cardsfolder/upcoming/chevill_bane_of_monsters.txt b/forge-gui/res/cardsfolder/upcoming/chevill_bane_of_monsters.txt new file mode 100755 index 00000000000..f2a537b3240 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/chevill_bane_of_monsters.txt @@ -0,0 +1,13 @@ +Name:Chevill, Bane of Monsters +ManaCost:B G +Types:Legendary Creature Human Rogue +PT:1/3 +K:Deathtouch +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Permanent.OppCtrl+counters_GE1_BOUNTY | PresentCompare$ EQ0 | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, if your opponents control no permanents with bounty counters on them, put a bounty counter on target creature or planeswalker an opponent controls. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.OppCtrl,Planeswalker.OppCtrl | TgtPrompt$ Select target creature or planeswalker an opponent controls | CounterType$ BOUNTY | CounterNum$ 1 | IsCurse$ True +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Permanent.OppCtrl+counters_GE1_BOUNTY | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever a permanent an opponent controls with a bounty counter on it dies, you gain 3 life and draw a card. +SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 +SVar:PlayMain1:TRUE +DeckHints:Ability$Counters +Oracle:Deathtouch\nAt the beginning of your upkeep, if your opponents control no permanents with bounty counters on them, put a bounty counter on target creature or planeswalker an opponent controls.\nWhenever a permanent an opponent controls with a bounty counter on it dies, you gain 3 life and draw card. diff --git a/forge-gui/res/cardsfolder/upcoming/deaths_oasis.txt b/forge-gui/res/cardsfolder/upcoming/deaths_oasis.txt new file mode 100755 index 00000000000..c0ee84512b7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/deaths_oasis.txt @@ -0,0 +1,10 @@ +Name:Death's Oasis +ManaCost:W B G +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl+nonToken | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Whenever a nontoken creature you control dies, put the top two cards of your library into your graveyard. Then return a creature card with lesser converted mana cost than the creature that died from the graveyard to your hand. +SVar:TrigMill:DB$ Mill | NumCards$ 2 | Defined$ You | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeType$ Creature.YouOwn+cmcLTY | References$ Y | Hidden$ True | ChangeNum$ 1 +SVar:Y:TriggeredCard$CardManaCost +A:AB$ GainLife | Cost$ 1 Sac<1/CARDNAME> | LifeAmount$ X | References$ X | SpellDescription$ You gain life equal to the greatest converted mana cost among creatures you control. +SVar:X:Count$HighestCMC_Creature.YouCtrl+inZoneBattlefield +Oracle:Whenever a nontoken creature you control dies, put the top two cards of your library into your graveyard. Then return a creature card with lesser converted mana cost than the creature that died from the graveyard to your hand.\n{1}, Sacrifice Death's Oasis: You gain life equal to the greatest converted mana cost among creatures you control. diff --git a/forge-gui/res/cardsfolder/upcoming/dire_tactics.txt b/forge-gui/res/cardsfolder/upcoming/dire_tactics.txt new file mode 100755 index 00000000000..e9fde96bc74 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dire_tactics.txt @@ -0,0 +1,7 @@ +Name:Dire Tactics +ManaCost:W B +Types:Instant +A:SP$ ChangeZone | Cost$ W B | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBLoseLife | StackDescription$ SpellDescription | SpellDescription$ Exile target creature. If you don't control a Human, you lose life equal to that creature's toughness. +SVar:DBLoseLife:DB$ LoseLife | ConditionPresent$ Human.YouCtrl | ConditionCompare$ EQ0 | Defined$ You | LifeAmount$ X | References$ X | StackDescription$ None +SVar:X:Targeted$CardToughness +Oracle:Exile target creature. If you don't control a Human, you lose life equal to that creature's toughness. diff --git a/forge-gui/res/cardsfolder/upcoming/drannith_magistrate.txt b/forge-gui/res/cardsfolder/upcoming/drannith_magistrate.txt new file mode 100755 index 00000000000..c4121042a56 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/drannith_magistrate.txt @@ -0,0 +1,6 @@ +Name:Drannith Magistrate +ManaCost:1 W +Types:Creature Human Wizard +PT:1/3 +S:Mode$ CantBeCast | ValidCard$ Card | Caster$ Opponent | Origin$ Library,Graveyard,Exile | Description$ Your opponents can't cast spells from anywhere other than their hands. +Oracle:Your opponents can't cast spells from anywhere other than their hands. diff --git a/forge-gui/res/cardsfolder/upcoming/fiend_artisan.txt b/forge-gui/res/cardsfolder/upcoming/fiend_artisan.txt new file mode 100755 index 00000000000..3300037e039 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fiend_artisan.txt @@ -0,0 +1,11 @@ +Name:Fiend Artisan +ManaCost:B/G B/G +Types:Creature Nightmare +PT:1/1 +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ Y | AddToughness$ Y | Description$ CARDNAME gets +1/+1 for each creature card in your graveyard. +A:AB$ ChangeZone | Cost$ X BG T Sac<1/Creature.Other/another creature> | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLEX | ChangeNum$ 1 | References$ X | ChangeNum$ 1 | SorcerySpeed$ True | StackDescription$ SpellDescription | SpellDescription$ Search your library for a creature card with converted mana cost X or less, put it onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery. +SVar:Y:Count$TypeInYourYard.Creature +SVar:X:Count$xPaid +AI:RemoveDeck:All +DeckHints:Ability$Graveyard +Oracle:Fiend Artisan gets +1/+1 for each creature card in your graveyard.\n{X}{B/G}, {T}, Sacrifice another creature: Search your library for a creature card with converted mana cost X or less, put it onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery. diff --git a/forge-gui/res/cardsfolder/upcoming/flourishing_fox.txt b/forge-gui/res/cardsfolder/upcoming/flourishing_fox.txt new file mode 100755 index 00000000000..c74da09394e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/flourishing_fox.txt @@ -0,0 +1,8 @@ +Name:Flourishing Fox +ManaCost:W +Types:Creature Fox +PT:1/1 +T:Mode$ Cycled | ValidCard$ Card.Other | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cycle another card, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +K:Cycling:1 +Oracle:Whenever you cycle another card, put a +1/+1 counter on Flourishing Fox.\nCycling {1} ({1}, Discard this card: Draw a card.) diff --git a/forge-gui/res/cardsfolder/upcoming/fully_grown.txt b/forge-gui/res/cardsfolder/upcoming/fully_grown.txt new file mode 100644 index 00000000000..edfefc1522a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fully_grown.txt @@ -0,0 +1,6 @@ +Name:Fully Grown +ManaCost:2 G +Types:Instant +A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +3 | NumDef$ +3 | SubAbility$ PutCounter | SpellDescription$ Target creature gets +3/+3 until end of turn. Put a trample counter on it. +SVar:PutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ TRAMPLE | CounterNum$ 1 +Oracle:Target creature gets +3/+3 until end of turn. Put a trample counter on it. diff --git a/forge-gui/res/cardsfolder/upcoming/general_kudro_of_drannith.txt b/forge-gui/res/cardsfolder/upcoming/general_kudro_of_drannith.txt new file mode 100755 index 00000000000..54765c7e001 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/general_kudro_of_drannith.txt @@ -0,0 +1,11 @@ +Name:General Kudro of Drannith +ManaCost:1 W B +Types:Legendary Creature Human Soldier +PT:3/3 +S:Mode$ Continuous | Affected$ Human.Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other Humans you control get +1/+1. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ Whenever CARDNAME or another Human enters the battlefield under your control, exile target card from an opponent's graveyard. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+Human+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigExile | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another Human enters the battlefield under your control, exile target card from an opponent's graveyard. +SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target card in an opponent's graveyard | ValidTgts$ Card.OppOwn +A:AB$ Destroy | Cost$ 2 Sac<2/Human> | ValidTgts$ Creature.powerGE4 | TgtPrompt$ Select target creature with power 4 or greater | SpellDescription$ Destroy target creature with power 4 or greater. +DeckHints:Type$Human +Oracle:Other Humans you control get +1/+1.\nWhenever General Kudro of Drannith or another Human enters the battlefield under your control, exile target card from an opponent's graveyard.\n{2}, Sacrifice two Humans: Destroy target creature with power 4 or greater.