diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index 8396405f6ed..36dffae2242 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -275,7 +275,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { tgt = sa.getTargetRestrictions(); } - return !((tgt != null) && !isValid(tgt.getValidTgts(), aura.getController(), aura, sa)); + return tgt != null && isValid(tgt.getValidTgts(), aura.getController(), aura, sa); } // Counters! diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index d0e54806fa5..7b8bb812bcd 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1450,7 +1450,11 @@ public class AbilityUtils { // Needed - Equip an untapped creature with Sword of the Paruns then cast Deadshot on it. Should deal 2 more damage. game.getAction().checkStaticAbilities(); // this will refresh continuous abilities for players and permanents. - game.getTriggerHandler().collectTriggerForWaiting(); + if (sa.isReplacementAbility()) { + game.getTriggerHandler().collectTriggerForWaiting(); + } else { + game.getTriggerHandler().resetActiveTriggers(); + } AbilityUtils.resolveApiAbility(abSub, game); } 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 532d79ead14..af414760705 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -6340,7 +6340,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return isValid(tgt.getValidTgts(), aura.getController(), aura, sa); } - return true; + return false; } @Override diff --git a/forge-gui-mobile/src/forge/adventure/scene/DeckSelectScene.java b/forge-gui-mobile/src/forge/adventure/scene/DeckSelectScene.java index bc21ed3329f..f2a75c51e49 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DeckSelectScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DeckSelectScene.java @@ -2,11 +2,7 @@ package forge.adventure.scene; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.scenes.scene2d.ui.Dialog; -import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextField; -import com.badlogic.gdx.scenes.scene2d.ui.Window; +import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.IntMap; @@ -14,6 +10,7 @@ import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraLabel; import forge.Forge; import forge.adventure.player.AdventurePlayer; +import forge.adventure.stage.GameHUD; import forge.adventure.util.Controls; import forge.adventure.util.Current; @@ -168,6 +165,8 @@ public class DeckSelectScene extends UIScene { buttons.get(i).layout(); } } + GameHUD.getInstance().pauseMusic(); + GameHUD.getInstance().playAudio(); select(Current.player().getSelectedDeckIndex()); performTouch(scrollPane); //can use mouse wheel if available to scroll after selection super.enter(); diff --git a/forge-gui-mobile/src/forge/adventure/scene/DraftScene.java b/forge-gui-mobile/src/forge/adventure/scene/DraftScene.java index d3caa502bb0..28abdec2c81 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DraftScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DraftScene.java @@ -3,8 +3,6 @@ package forge.adventure.scene; import forge.adventure.data.AdventureEventData; import forge.adventure.stage.GameHUD; import forge.screens.FScreen; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; /** * DraftScene @@ -34,7 +32,7 @@ public class DraftScene extends ForgeScene { public void enter() { GameHUD.getInstance().getTouchpad().setVisible(false); GameHUD.getInstance().pauseMusic(); - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); + GameHUD.getInstance().playAudio(); screen = null; getScreen(); screen.refresh(); diff --git a/forge-gui-mobile/src/forge/adventure/scene/EventScene.java b/forge-gui-mobile/src/forge/adventure/scene/EventScene.java index e0a72afba68..1489c1fce7c 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/EventScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/EventScene.java @@ -1,7 +1,10 @@ package forge.adventure.scene; import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.Window; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; @@ -11,17 +14,18 @@ import com.github.tommyettinger.textra.TextraLabel; import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; import forge.adventure.character.EnemySprite; -import forge.adventure.data.*; +import forge.adventure.data.AdventureEventData; +import forge.adventure.data.DialogData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.GameHUD; import forge.adventure.stage.IAfterMatch; import forge.adventure.stage.WorldStage; -import forge.adventure.util.*; +import forge.adventure.util.AdventureEventController; +import forge.adventure.util.Controls; +import forge.adventure.util.Current; import forge.adventure.world.WorldSave; import forge.gui.FThreads; import forge.screens.TransitionScreen; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; import forge.util.Callback; import forge.util.MyRandom; @@ -381,7 +385,7 @@ public class EventScene extends MenuScene implements IAfterMatch { public void enter() { super.enter(); GameHUD.getInstance().pauseMusic(); - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); + GameHUD.getInstance().playAudio(); scrollContainer.clear(); if (money != null) { diff --git a/forge-gui-mobile/src/forge/adventure/scene/InnScene.java b/forge-gui-mobile/src/forge/adventure/scene/InnScene.java index 3477ea49476..da33a4bd209 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/InnScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/InnScene.java @@ -12,8 +12,6 @@ import forge.adventure.util.AdventureEventController; import forge.adventure.util.Controls; import forge.adventure.util.Current; import forge.adventure.world.WorldSave; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; /** * Scene for the Inn in towns @@ -101,7 +99,7 @@ public class InnScene extends UIScene { super.enter(); refreshStatus(); GameHUD.getInstance().pauseMusic(); - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.TOWN); + GameHUD.getInstance().playAudio(); } private void refreshStatus(){ diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index 696150e8d28..7ada1616077 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -32,8 +32,6 @@ import forge.localinstance.achievements.CardActivationAchievements; import forge.localinstance.achievements.PlaneswalkerAchievements; import forge.model.FModel; import forge.player.GamePlayerUtil; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; import org.apache.commons.lang3.tuple.Pair; import java.util.Map; @@ -191,7 +189,7 @@ public class PlayerStatisticScene extends UIScene { super.enter(); GameHUD.getInstance().pauseMusic(); - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); + GameHUD.getInstance().playAudio(); achievementContainer.clear(); updateAchievements(cardActivation, true); diff --git a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java index fb654eb360c..54fd5febf0b 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java @@ -52,7 +52,7 @@ public class RewardScene extends UIScene { Type type; Array generated = new Array<>(); - static public final float CARD_WIDTH =550f ; + static public final float CARD_WIDTH = 550f ; static public final float CARD_HEIGHT = 400f; static public final float CARD_WIDTH_TO_HEIGHT = CARD_WIDTH / CARD_HEIGHT; diff --git a/forge-gui-mobile/src/forge/adventure/scene/SpellSmithScene.java b/forge-gui-mobile/src/forge/adventure/scene/SpellSmithScene.java index d3fdb19104b..917e961c4c0 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SpellSmithScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SpellSmithScene.java @@ -152,6 +152,11 @@ public class SpellSmithScene extends UIScene { if (it.size() == 0) return false; return (!Arrays.asList(Config.instance().getConfigData().restrictedEditions).contains(input.getCode())); + }).sorted(new Comparator() { + @Override + public int compare(CardEdition e1, CardEdition e2) { + return e1.getName().compareTo(e2.getName()); + } }).collect(Collectors.toList()); } diff --git a/forge-gui/res/cardsfolder/a/arixmethes_slumbering_isle.txt b/forge-gui/res/cardsfolder/a/arixmethes_slumbering_isle.txt index 503883960e0..5d70f96525e 100644 --- a/forge-gui/res/cardsfolder/a/arixmethes_slumbering_isle.txt +++ b/forge-gui/res/cardsfolder/a/arixmethes_slumbering_isle.txt @@ -5,8 +5,8 @@ PT:12/12 K:ETBReplacement:Other:LandTapped SVar:LandTapped:DB$ Tap | Defined$ Self | SubAbility$ DBAddCounter | ETB$ True | SpellDescription$ CARDNAME enters the battlefield tapped with five slumber counters on it. SVar:DBAddCounter:DB$ PutCounter | Defined$ Self | ETB$ True | CounterType$ SLUMBER | CounterNum$ 5 -S:Mode$ Continuous | Affected$ Card.Self+counters_GE1_SLUMBER | AddType$ Land | RemoveCardTypes$ True | Description$ As long as CARDNAME has a slumber counter on it, it's a land. (It's not a creature.) -T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigRemoveCounter | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, you may remove a slumber counter from CARDNAME. +S:Mode$ Continuous | Affected$ Card.Self+counters_GE1_SLUMBER | AddType$ Land | RemoveCardTypes$ True | Description$ As long as NICKNAME has a slumber counter on it, it's a land. (It's not a creature.) +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigRemoveCounter | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, you may remove a slumber counter from NICKNAME. SVar:TrigRemoveCounter:DB$ RemoveCounter | Defined$ Self | CounterType$ SLUMBER | CounterNum$ 1 | AILogic$ Always A:AB$ Mana | Cost$ T | Produced$ G U | SpellDescription$ Add {G}{U}. Oracle:Arixmethes, Slumbering Isle enters the battlefield tapped with five slumber counters on it.\nAs long as Arixmethes has a slumber counter on it, it's a land. (It's not a creature.)\nWhenever you cast a spell, you may remove a slumber counter from Arixmethes.\n{T}: Add {G}{U}. diff --git a/forge-gui/res/cardsfolder/upcoming/elven_farsight.txt b/forge-gui/res/cardsfolder/upcoming/elven_farsight.txt new file mode 100644 index 00000000000..1fa56b68fc7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/elven_farsight.txt @@ -0,0 +1,8 @@ +Name:Elven Farsight +ManaCost:G +Types:Sorcery +A:SP$ Scry | ScryNum$ 3 | SubAbility$ DBPeekAndReveal | SpellDescription$ Scry 3, then you may reveal the top card of your library. If it's a creature card, draw a card. +SVar:DBPeekAndReveal:DB$ PeekAndReveal | RevealOptional$ True | NoPeek$ True | RememberRevealed$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | ConditionDefined$ Remembered | ConditionPresent$ Card.Creature | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Scry 3, then you may reveal the top card of your library. If it's a creature card, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/ent_draught_basin.txt b/forge-gui/res/cardsfolder/upcoming/ent_draught_basin.txt new file mode 100644 index 00000000000..e2f308de2f9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ent_draught_basin.txt @@ -0,0 +1,7 @@ +Name:Ent-Draught Basin +ManaCost:2 +Types:Artifact +A:AB$ PutCounter | Cost$ X | CounterType$ P1P1 | ValidTgts$ Creature.powerEQX | TgtPrompt$ Select target creature with power X | CounterNum$ 1 | SorcerySpeed$ True | SpellDescription$ Put a +1/+1 counter on target creature with power X. Activate only as a sorcery. +SVar:X:Count$xPaid +DeckHas:Ability$Counters +Oracle:{X}, {T}: Put a +1/+1 counter on target creature with power X. Activate only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/entish_restoration.txt b/forge-gui/res/cardsfolder/upcoming/entish_restoration.txt new file mode 100644 index 00000000000..8ba9ae8a496 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/entish_restoration.txt @@ -0,0 +1,10 @@ +Name:Entish Restoration +ManaCost:2 G +Types:Instant +A:SP$ Sacrifice | Defined$ You | SacValid$ Land | SubAbility$ DBChangeZone | SpellDescription$ Sacrifice a land. Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle. If you control a creature with power 4 or greater, instead search your library for up to three basic land cards, put them onto the battlefield tapped, then shuffle. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | Tapped$ True +SVar:AIPreference:SacCost$Land.Basic+tapped +SVar:X:Count$Compare Y GE1.3.2 +SVar:Y:Count$Valid Creature.YouCtrl+powerGE4 +DeckHas:Ability$Sacrifice +Oracle:Sacrifice a land. Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle. If you control a creature with power 4 or greater, instead search your library for up to three basic land cards, put them onto the battlefield tapped, then shuffle. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/eomer_of_the_riddermark.txt b/forge-gui/res/cardsfolder/upcoming/eomer_of_the_riddermark.txt new file mode 100644 index 00000000000..c9464451be8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/eomer_of_the_riddermark.txt @@ -0,0 +1,10 @@ +Name:Eomer of the Riddermark +ManaCost:4 R +Types:Legendary Creature Human Knight +PT:5/4 +K:Haste +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | IsPresent$ Creature.greatestPower+YouCtrl | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, if you control a creature with the greatest power among creatures on the battlefield, create a 1/1 white Human Soldier creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human_soldier | TokenOwner$ You +DeckHas:Ability$Token & Type$Soldier +SVar:HasAttackEffect:TRUE +Oracle:Haste\nWhenever Eomer of the Riddermark attacks, if you control a creature with the greatest power among creatures on the battlefield, create a 1/1 white Human Soldier creature token. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/eowyn_lady_of_rohan.txt b/forge-gui/res/cardsfolder/upcoming/eowyn_lady_of_rohan.txt new file mode 100644 index 00000000000..9d54eec7f52 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/eowyn_lady_of_rohan.txt @@ -0,0 +1,13 @@ +Name:Eowyn, Lady of Rohan +ManaCost:2 W +Types:Legendary Creature Human Noble +PT:2/4 +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ At the beginning of combat on your turn, target creature gains your choice of first strike or vigilance until end of turn. If that creature is equipped, it gains first strike and vigilance until end of turn instead. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | SubAbility$ DBBranch +SVar:DBBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ EQ1 | TrueSubAbility$ Equipped | FalseSubAbility$ NotEquipped +SVar:Equipped:DB$ Pump | Defined$ Targeted | KW$ First Strike & Vigilance +SVar:NotEquipped:DB$ Pump | KWChoice$ First Strike,Vigilance | Defined$ Targeted +SVar:X:Targeted$Valid Card.equipped +S:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 1 | Description$ Equip abilities you activate cost {1} less to activate. +DeckHints:Type$Equipment +Oracle:At the beginning of combat on your turn, target creature gains your choice of first strike or vigilance until end of turn. If that creature is equipped, it gains first strike and vigilance until end of turn instead.\nEquip abilities you activate cost {1} less to activate. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/erebor_flamesmith.txt b/forge-gui/res/cardsfolder/upcoming/erebor_flamesmith.txt new file mode 100644 index 00000000000..67632349b33 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/erebor_flamesmith.txt @@ -0,0 +1,8 @@ +Name:Erebor Flamesmith +ManaCost:1 R +Types:Creature Dwarf Artificer +PT:2/1 +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever you cast an instant or sorcery spell, CARDNAME deals 1 damage to each opponent. +SVar:TrigDamage:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 1 +DeckHints:Type$Instant|Sorcery +Oracle:Whenever you cast an instant or sorcery spell, Erebor Flamesmith deals 1 damage to each opponent. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/errand_rider_of_gondor.txt b/forge-gui/res/cardsfolder/upcoming/errand_rider_of_gondor.txt new file mode 100644 index 00000000000..37f7131fc41 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/errand_rider_of_gondor.txt @@ -0,0 +1,9 @@ +Name:Errand-Rider of Gondor +ManaCost:2 W +Types:Creature Human Soldier +PT:3/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, draw a card. Then if you don't control a legendary creature, put a card from your hand on the bottom of your library. +SVar:TrigDraw:DB$ Draw | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Library | ChangeNum$ 1 | Mandatory$ True | LibraryPosition$ -1 | ConditionPresent$ Creature.Legendary+YouCtrl | ConditionCompare$ EQ0 +DeckHints:Type$Legendary & Type$Creature +Oracle:When Errand-Rider of Gondor enters the battlefield, draw a card. Then if you don't control a legendary creature, put a card from your hand on the bottom of your library. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/escape_from_orthanc.txt b/forge-gui/res/cardsfolder/upcoming/escape_from_orthanc.txt new file mode 100644 index 00000000000..131a14ff70d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/escape_from_orthanc.txt @@ -0,0 +1,6 @@ +Name:Escape from Orthanc +ManaCost:2 W +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | NumAtt$ 1 | NumDef$ 3 | KW$ Flying | SubAbility$ DBUntap | SpellDescription$ Target creature gets +1/+3 and gains flying until end of turn. Untap it. +SVar:DBUntap:DB$ Untap | Defined$ Targeted +Oracle:Target creature gets +1/+3 and gains flying until end of turn. Untap it. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/esquire_of_the_king.txt b/forge-gui/res/cardsfolder/upcoming/esquire_of_the_king.txt new file mode 100644 index 00000000000..12474efae9a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/esquire_of_the_king.txt @@ -0,0 +1,10 @@ +Name:Esquire of the King +ManaCost:W +Types:Creature Human Soldier +PT:1/1 +K:Flying +A:AB$ PumpAll | NumAtt$ +1 | NumDef$ +1 | Cost$ 4 W T | ValidCards$ Creature.YouCtrl | ReduceCost$ X | SpellDescription$ Creatures you control get +1/+1 until end of turn. This ability costs {2} less to activate if you control a legendary creature. +SVar:X:Count$Compare Y GE1.2.0 +SVar:Y:Count$Valid Creature.Legendary+YouCtrl +DeckHints:Type$Legendary & Type$Creature +Oracle:{4}{W}, {T}: Creatures you control get +1/+1 until end of turn. This ability costs {2} less to activate if you control a legendary creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fall_of_cair_andros.txt b/forge-gui/res/cardsfolder/upcoming/fall_of_cair_andros.txt new file mode 100644 index 00000000000..aef2193a32c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fall_of_cair_andros.txt @@ -0,0 +1,9 @@ +Name:Fall of Cair Andros +ManaCost:2 R +Types:Enchantment +T:Mode$ ExcessDamage | ValidTarget$ Creature.OppCtrl | CombatDamage$ False | TriggerZones$ Battlefield | Execute$ TrigAmass | TriggerDescription$ Whenever a creature an opponent controls is dealt excess noncombat damage, amass Orcs X, where X is that excess damage. (Put X +1/+1 counters on an Army you control. It's also an Orc. If you don't control an Army, create a 0/0 black Orc Army creature token first.) +SVar:TrigAmass:DB$ Amass | Type$ Orc | Num$ X +SVar:X:TriggerCount$DamageAmount +A:AB$ DealDamage | Cost$ 7 R | ValidTgts$ Creature | NumDmg$ 7 | SpellDescription$ CARDNAME deals 7 damage to target creature. +DeckHas:Ability$Token|Counters & Type$Orc|Army +Oracle:Whenever a creature an opponent controls is dealt excess noncombat damage, amass Orcs X, where X is that excess damage. (Put X +1/+1 counters on an Army you control. It's also an Orc. If you don't control an Army, create a 0/0 black Orc Army creature token first.)\n{7}{R}: Fall of Cair Andros deals 7 damage to target creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/grey_havens_navigator.txt b/forge-gui/res/cardsfolder/upcoming/grey_havens_navigator.txt new file mode 100644 index 00000000000..7e477dc2043 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/grey_havens_navigator.txt @@ -0,0 +1,8 @@ +Name:Grey Havens Navigator +ManaCost:2 U +Types:Creature Elf Pilot +PT:3/2 +K:Flash +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 1. +SVar:TrigScry:DB$ Scry | ScryNum$ 1 +Oracle:Flash\nWhen Grey Havens Navigator enters the battlefield, scry 1. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/haradrim_spearmaster.txt b/forge-gui/res/cardsfolder/upcoming/haradrim_spearmaster.txt new file mode 100644 index 00000000000..ecca8663b3d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/haradrim_spearmaster.txt @@ -0,0 +1,9 @@ +Name:Haradrim Spearmaster +ManaCost:2 R +Types:Creature Human Warrior +PT:2/3 +K:Reach +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, another target creature you control gets +1/+0 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control | NumAtt$ 1 +SVar:PlayMain1:TRUE +Oracle:Reach\nAt the beginning of combat on your turn, another target creature you control gets +1/+0 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/hithlain_knots.txt b/forge-gui/res/cardsfolder/upcoming/hithlain_knots.txt new file mode 100644 index 00000000000..b973ee7a8b4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hithlain_knots.txt @@ -0,0 +1,7 @@ +Name:Hithlain Knots +ManaCost:1 U +Types:Instant +A:SP$ Tap | ValidTgts$ Creature | SubAbility$ DBScry | SpellDescription$ Tap target creature. Scry 1. +SVar:DBScry:DB$ Scry | ScryNum$ 1 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card. +Oracle:Tap target creature. Scry 1.\nDraw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ioreth_of_the_healing_house.txt b/forge-gui/res/cardsfolder/upcoming/ioreth_of_the_healing_house.txt new file mode 100644 index 00000000000..0f4160e750f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ioreth_of_the_healing_house.txt @@ -0,0 +1,8 @@ +Name:Ioreth of the Healing House +ManaCost:2 U +Types:Legendary Creature Human Cleric +PT:1/4 +A:AB$ Untap | Cost$ T | ValidTgts$ Permanent.Other | TgtPrompt$ Select another target permanent | SpellDescription$ Untap another target permanent. +A:AB$ Untap | Cost$ T | ValidTgts$ Creature.Legendary | TgtPrompt$ Select two other legendary creatures | SpellDescription$ Untap two other target legendary creatures. +DeckHints:Type$Legendary & Type$Creature +Oracle:{T}: Untap another target permanent.\n{T}: Untap two other target legendary creatures. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/isolation_at_orthanc.txt b/forge-gui/res/cardsfolder/upcoming/isolation_at_orthanc.txt new file mode 100644 index 00000000000..07c35fdf101 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/isolation_at_orthanc.txt @@ -0,0 +1,5 @@ +Name:Isolation at Orthanc +ManaCost:3 U +Types:Instant +A:SP$ ChangeZone | Origin$ Battlefield | Destination$ Library | ValidTgts$ Creature | LibraryPosition$ 1 | SpellDescription$ Put target creature into its owner's library second from the top. +Oracle:Put target creature into its owner's library second from the top. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ithilien_kingfisher.txt b/forge-gui/res/cardsfolder/upcoming/ithilien_kingfisher.txt new file mode 100644 index 00000000000..b183f8e284e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ithilien_kingfisher.txt @@ -0,0 +1,9 @@ +Name:Ithilien Kingfisher +ManaCost:2 U +Types:Creature Bird +PT:2/1 +K:Flying +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME dies, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ TriggeredCardController | NumCards$ 1 +SVar:SacMe:1 +Oracle:Flying\nWhen Ithilien Kingfisher dies, draw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/lorien_revealed.txt b/forge-gui/res/cardsfolder/upcoming/lorien_revealed.txt new file mode 100644 index 00000000000..e35a04af11a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lorien_revealed.txt @@ -0,0 +1,7 @@ +Name:Lorien Revealed +ManaCost:3 U U +Types:Sorcery +A:SP$ Draw | NumCards$ 3 | SpellDescription$ Draw three cards. +K:TypeCycling:Island:1 +DeckHas:Ability$Discard +Oracle:Draw three cards.\nIslandcycling {1} ({1}, Discard this card: Search your library for an Island card, reveal it, put it into your hand, then shuffle.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_balrog_flame_of_udun.txt b/forge-gui/res/cardsfolder/upcoming/the_balrog_flame_of_udun.txt new file mode 100644 index 00000000000..1370c80163c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_balrog_flame_of_udun.txt @@ -0,0 +1,8 @@ +Name:The Balrog, Flame of Udun +ManaCost:3 B R +Types:Legendary Creature Avatar Demon +PT:7/7 +K:Trample +T:Mode$ ChangesZone | Origin$ Battlefield | TriggerZones$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Legendary+OppCtrl | Execute$ TrigChange | TriggerDescription$ When a legendary creature an opponent controls dies, put CARDNAME on the bottom of its owner's library. +SVar:TrigChange:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Library | LibraryPosition$ -1 +Oracle:Trample\nWhen a legendary creature an opponent controls dies, put The Balrog, Flame of Udûn on the bottom of its owner's library. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_bath_song.txt b/forge-gui/res/cardsfolder/upcoming/the_bath_song.txt new file mode 100644 index 00000000000..70e0cddcd97 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_bath_song.txt @@ -0,0 +1,11 @@ +Name:The Bath Song +ManaCost:3 U +Types:Enchantment Saga +K:Saga:3:DBDraw,DBDraw,DBShuffle +SVar:DBDraw:DB$ Draw | NumCards$ 2 | SubAbility$ DBDiscard | SpellDescription$ Draw two cards, then discard a card. +SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose +SVar:DBShuffle:DB$ ChangeZone | TargetMin$ 0 | TargetMax$ X | Origin$ Graveyard | Destination$ Library | Shuffle$ True | SubAbility$ DBAdd | TgtPrompt$ Choose any target cards in your graveyard | ValidTgts$ Card.YouCtrl | SpellDescription$ Shuffle any number of target cards from your graveyard into your library. Add {U}{U}. +SVar:DBAdd:DB$ Mana | Produced$ U | Amount$ 2 +SVar:X:Count$InYourYard +DeckHas:Ability$Discard|Graveyard +Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI, II — Draw two cards, then discard a card.\nIII — Shuffle any number of target cards from your graveyard into your library. Add {U}{U}. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/witch_king_bringer_of_ruin.txt b/forge-gui/res/cardsfolder/upcoming/witch_king_bringer_of_ruin.txt new file mode 100644 index 00000000000..02243aeb62d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/witch_king_bringer_of_ruin.txt @@ -0,0 +1,10 @@ +Name:Witch-king, Bringer of Ruin +ManaCost:4 B B +Types:Legendary Creature Wraith Noble +PT:5/3 +K:Flying +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ Whenever CARDNAME attacks, defending player sacrifices a creature with the least power among creatures they control. +SVar:TrigSac:DB$ Sacrifice | Defined$ TriggeredDefendingPlayer | SacValid$ Creature.leastPowerControlledBy TriggeredDefendingPlayer +SVar:HasAttackEffect:True +DeckHas:Ability$Sacrifice +Oracle:Flying\nWhenever Witch-king, Bringer of Ruin attacks, defending player sacrifices a creature with the least power among creatures they control. \ No newline at end of file diff --git a/forge-gui/res/editions/Store Championships.txt b/forge-gui/res/editions/Store Championships.txt index b6a7da28857..3ee21af0fe1 100644 --- a/forge-gui/res/editions/Store Championships.txt +++ b/forge-gui/res/editions/Store Championships.txt @@ -18,3 +18,5 @@ ScryfallCode=SCH 10 R Strangle @Sidharth Chaturvedi 11 R Aether Channeler @Olivier Bernard 12 M Thalia and The Gitrog Monster @PINDURSKI +13 R Gifted Aetherborn @Lie Setiawan +14 R Eidolon of the Great Revel @Yigit Koroglu diff --git a/forge-gui/res/puzzle/MTGP_01.pzl b/forge-gui/res/puzzle/MTGP_01.pzl new file mode 100644 index 00000000000..66860aaa406 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_01.pzl @@ -0,0 +1,19 @@ +[metadata] +Name:MTG Puzzles #01 - Gaining Experience +URL:https://mtgpuzzles.com/puzzle/1 +Goal:Win +Turns:1 +Difficulty:Medium +Description:Defeat your opponent before their next turn. You currently have 0 experience counters. Your opponent flashed in a Nebelgast Herald on your upkeep step, tapping your Mizzix of the Izmagnus. Can you find 4 damage to win? +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=5 +p0hand=Banners Raised;Electrickery;Temporary Insanity +p0graveyard=Opt;Volcanic Spray +p0battlefield=Mizzix of the Izmagnus|Tapped;Mountain;Mountain;Sulfur Falls|NoETBTrigs;Sulfur Falls|NoETBTrigs +p1life=4 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Nebelgast Herald;Treetop Ambusher diff --git a/forge-gui/res/puzzle/MTGP_02.pzl b/forge-gui/res/puzzle/MTGP_02.pzl new file mode 100644 index 00000000000..a59d71a5c96 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_02.pzl @@ -0,0 +1,21 @@ +[metadata] +Name:MTG Puzzles #02 - It's a Trap! +URL:https://mtgpuzzles.com/puzzle/2 +Goal:Survive +Turns:1 +Difficulty:Easy +Description:Survive until your next turn. It's your opponents turn and they have attacked with 5 Construct tokens! It's their declare blockers step, can you find a way to survive this turn? Don't forget about Throne of the God-Pharaoh! +[state] +turn=1 +activeplayer=p1 +activephase=MAIN1 +activephaseadvance=COMBAT_DECLARE_BLOCKERS +p0life=7 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Arrow Volley Trap;Pitfall Trap;Inferno Trap +p0battlefield=Viashino Fangtail;Rockslide Sorcerer;Mountain;Mountain;Plains;Plains +p1life=20 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Throne of the God-Pharaoh;T:c_4_4_a_construct;T:c_4_4_a_construct;T:c_4_4_a_construct;T:c_4_4_a_construct;T:c_4_4_a_construct diff --git a/forge-gui/res/puzzle/MTGP_03.pzl b/forge-gui/res/puzzle/MTGP_03.pzl new file mode 100644 index 00000000000..8f514bee12a --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_03.pzl @@ -0,0 +1,20 @@ +[metadata] +Name:MTG Puzzles #03 - Crews Control +URL:https://mtgpuzzles.com/puzzle/3 +Goal:Win +Turns:1 +Difficulty:Medium +Description:Win this turn. The Illusions are winning! Saddle up your creatures and become victorious! +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=3 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Renegade Wheelsmith;Chaos Charm +p0battlefield=Mobile Garrison;Granger Guildmage;Knotvine Paladin;Mountain;Mountain;Mountain;Temple Garden|NoETBTrigs;Temple Garden|NoETBTrigs +p1life=8 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=T:u_1_1_illusion_flying;T:u_1_1_illusion_flying;T:u_1_1_illusion_flying diff --git a/forge-gui/res/puzzle/MTGP_04.pzl b/forge-gui/res/puzzle/MTGP_04.pzl new file mode 100644 index 00000000000..f8a6e837051 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_04.pzl @@ -0,0 +1,20 @@ +[metadata] +Name:MTG Puzzles #04 - Enrage Against the Machine +URL:https://mtgpuzzles.com/puzzle/4 +Goal:Win +Turns:1 +Difficulty:Very Hard +Description:Win this turn. Your spirit-engrage tribal deck is not doing as well as you planned. Your opponent played a Jin-Gitaxias on their turn and you must find a way to win before its too late! The solution should not depend on how Jin-Gitaxias, Core Augur blocks. +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=5 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Dark Withering;Tahngarth's Rage;Alms of the Vein +p0battlefield=Frilled Deathspitter;Niblis of Dusk;Supreme Phantom;Pyrohemia;Mountain;Mountain;Mountain;Mountain;Mountain;Watery Grave|NoETBTrigs;Watery Grave|NoETBTrigs +p1life=23 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Jin-Gitaxias, Core Augur diff --git a/forge-gui/res/puzzle/MTGP_05.pzl b/forge-gui/res/puzzle/MTGP_05.pzl new file mode 100644 index 00000000000..d2a5f3da9cc --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_05.pzl @@ -0,0 +1,21 @@ +[metadata] +Name:MTG Puzzles #05 - Miracles of Nature +URL:https://mtgpuzzles.com/puzzle/5 +Goal:Win +Turns:1 +Difficulty:Hard +Description:Win this turn. After a Gruuling match you're down to the last card in your library - can you get through your opponent's defenses to secure the win? It's the beginning of your Upkeep Step. Your library consists of only Blessings of Nature. Damping Sphere still increases the casting cost for any card's alternative casting cost. Your solution should not depend on how your opponent will block. +[state] +turn=1 +activeplayer=p0 +activephase=UPKEEP +p0life=6 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Electrostatic Bolt;Inner Calm, Outer Strength;Crash +p0library=Blessings of Nature +p0battlefield=Goblin Spy;Frontline Devastator;Forest;Forest;Forest;Mountain;Mountain;Mountain +p1life=6 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Butcher Ghoul;Guardian Automaton;Damping Sphere diff --git a/forge-gui/res/puzzle/MTGP_06.pzl b/forge-gui/res/puzzle/MTGP_06.pzl new file mode 100644 index 00000000000..8b29b2138b4 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_06.pzl @@ -0,0 +1,21 @@ +[metadata] +Name:MTG Puzzles #06 - Lucky Number 13 +URL:https://mtgpuzzles.com/puzzle/6 +Goal:Win +Turns:1 +Difficulty:Hard +Description:Win this turn. It is your untap step and you and your opponent are dancing around 13 life. Can you find a way to win this turn? It's the beginning of your Untap Step. Assume the card you draw in your draw step is not necessary to solve this puzzle. +[state] +turn=1 +activeplayer=p1 +activephase=CLEANUP +p0life=10 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Blazing Salvo +p0battlefield=Oreskos Sun Guide|Tapped;Nocturnal Feeder;Axis of Mortality;Triskaidekaphobia;Savai Triome|Tapped|NoETBTrigs;Savai Triome|Tapped|NoETBTrigs;Savai Triome|Tapped|NoETBTrigs +p0library=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt +p1life=14 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Bogardan Firefiend diff --git a/forge-gui/res/puzzle/MTGP_08.pzl.disabled b/forge-gui/res/puzzle/MTGP_08.pzl.disabled new file mode 100644 index 00000000000..bda9c199595 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_08.pzl.disabled @@ -0,0 +1,21 @@ +# Needs AI support for Ashling the Pilgrim to work correctly. +[metadata] +Name:MTG Puzzles #08 - Counter Intelligence +URL:https://mtgpuzzles.com/puzzle/8 +Goal:Win +Turns:1 +Difficulty:Medium +Description:Win this turn. It's the eternal struggle between +1/+1 counters and -1/-1 counters, can you force your opponent's hand to secure the victory? Your opponent could activate Ashling at any point they have priority. +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=2 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Scar +p0battlefield=Dread Shade;Carnifex Demon|Counters:M1M1=2;Dread Shade;Swamp;Swamp;Swamp +p1life=10 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Ashling the Pilgrim;Cascade Bluffs;Cascade Bluffs;Cascade Bluffs;Shivan Reef;Shivan Reef;Shivan Reef diff --git a/forge-gui/res/puzzle/MTGP_09.pzl b/forge-gui/res/puzzle/MTGP_09.pzl new file mode 100644 index 00000000000..84ef9d9a605 --- /dev/null +++ b/forge-gui/res/puzzle/MTGP_09.pzl @@ -0,0 +1,20 @@ +[metadata] +Name:MTG Puzzles #09 - Aqua Regia +URL:https://mtgpuzzles.com/puzzle/9 +Goal:Win +Turns:1 +Difficulty:Easy +Description:Win this turn. You've done the hard work of getting your opponent below 0, now to actually win the game! Can you rustle up enough mana for your ultimate weapon and win this turn? Your opponent's life total is -1 (yes it's negative). Fungal Reaches does not have any storage counters. +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=3 +p0landsplayed=0 +p0landsplayedlastturn=0 +p0hand=Watery Grave;Talisman of Impulse;Mana Crypt +p0battlefield=Legacy Weapon;Nimbus Maze;City of Traitors;Fungal Reaches;River of Tears;Caves of Koilos +p1life=-1 +p1landsplayed=0 +p1landsplayedlastturn=0 +p1battlefield=Platinum Angel