From e4fddafc104664b7548896ba08f4e9b0abb5c20d Mon Sep 17 00:00:00 2001 From: tehdiplomat Date: Tue, 28 Aug 2018 12:24:04 -0400 Subject: [PATCH 01/48] Fixing Mana types being inappropriately referenced in relation to Matrices --- .../src/main/java/forge/ai/ComputerUtilMana.java | 4 ++++ .../src/main/java/forge/card/MagicColor.java | 9 --------- .../src/main/java/forge/card/mana/ManaAtom.java | 5 ++++- .../java/forge/game/ability/AbilityUtils.java | 3 ++- .../java/forge/game/mana/ManaCostBeingPaid.java | 6 ++++-- .../src/main/java/forge/game/mana/ManaPool.java | 15 +++++++++------ 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 98df78bf24a..02ffc322634 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -913,6 +913,10 @@ public class ComputerUtilMana { // Make mana needed to avoid negative effect a mandatory cost for the AI for (String manaPart : card.getSVar("ManaNeededToAvoidNegativeEffect").split(",")) { // convert long color strings to short color strings + if (manaPart.isEmpty()) { + continue; + } + byte mask = ManaAtom.fromName(manaPart); // make mana mandatory for AI diff --git a/forge-core/src/main/java/forge/card/MagicColor.java b/forge-core/src/main/java/forge/card/MagicColor.java index bc452e19520..37e6294a056 100644 --- a/forge-core/src/main/java/forge/card/MagicColor.java +++ b/forge-core/src/main/java/forge/card/MagicColor.java @@ -103,15 +103,6 @@ public final class MagicColor { } } - public static int getIndexOfFirstColor(final byte color){ - for (int i = 0; i < NUMBER_OR_COLORS; i++) { - if ((color & WUBRG[i]) != 0) { - return i; - } - } - return -1; // colorless - } - /** * The Interface Color. */ diff --git a/forge-core/src/main/java/forge/card/mana/ManaAtom.java b/forge-core/src/main/java/forge/card/mana/ManaAtom.java index 1416139cda5..5a38b3a3310 100644 --- a/forge-core/src/main/java/forge/card/mana/ManaAtom.java +++ b/forge-core/src/main/java/forge/card/mana/ManaAtom.java @@ -14,6 +14,9 @@ public abstract class ManaAtom { public static final byte[] MANACOLORS = new byte[] { WHITE, BLUE, BLACK, RED, GREEN }; public static final byte[] MANATYPES = new byte[] { WHITE, BLUE, BLACK, RED, GREEN, COLORLESS }; + public static final byte ALL_MANA_COLORS = WHITE | BLUE | BLACK | RED | GREEN; + public static final byte ALL_MANA_TYPES = ALL_MANA_COLORS | COLORLESS; + public static final int GENERIC = 1 << 6; // Below here skip due to byte conversion shenanigans @@ -62,6 +65,6 @@ public abstract class ManaAtom { return i; } } - return -1; // colorless + return -1; // somehow the mana is not colored or colorless? } } \ No newline at end of file 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 ab4032c090a..46486599224 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1655,7 +1655,8 @@ public class AbilityUtils { String convertTo = params.get(key); byte convertByte = 0; if ("All".equals(convertTo)) { - convertByte = ColorSet.ALL_COLORS.getColor(); + // IMPORTANT! We need to use Mana Color here not Card Color. + convertByte = ManaAtom.ALL_MANA_TYPES; } else { for (final String convertColor : convertTo.split(",")) { convertByte |= ManaAtom.fromName(convertColor); diff --git a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java index f1f43259799..f5c381fb9ca 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java @@ -586,6 +586,7 @@ public class ManaCostBeingPaid { // Boolean addX used to add Xs into the returned value final StringBuilder sb = new StringBuilder(); + // TODO Prepend a line about paying with any type/color if available if (addX) { for (int i = 0; i < this.getXcounter(); i++) { sb.append("{X}"); @@ -595,10 +596,11 @@ public class ManaCostBeingPaid { int nGeneric = getGenericManaAmount(); List shards = new ArrayList(unpaidShards.keySet()); - if (pool != null) { //replace shards with generic mana if they can be paid with any color mana + // TODO Fix this. Should we really be changing Shards here? + if (false && pool != null) { //replace shards with generic mana if they can be paid with any color mana for (int i = 0; i < shards.size(); i++) { ManaCostShard shard = shards.get(i); - if (shard != ManaCostShard.GENERIC && pool.getPossibleColorUses(shard.getColorMask()) == MagicColor.ALL_COLORS) { + if (shard != ManaCostShard.GENERIC && pool.getPossibleColorUses(shard.getColorMask()) == ManaAtom.ALL_MANA_TYPES) { nGeneric += unpaidShards.get(shard).totalCount; shards.remove(i); i--; diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java index 2d2de63d968..d76c2145973 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -22,7 +22,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import forge.GameCommand; -import forge.card.ColorSet; import forge.card.MagicColor; import forge.card.mana.ManaAtom; import forge.card.mana.ManaCostShard; @@ -364,7 +363,7 @@ public class ManaPool implements Iterable { public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { // Fix the index without hardcodes - int rowIdx = MagicColor.getIndexOfFirstColor(originalColor); + int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; if (additive) { colorConversionMatrix[rowIdx] |= replacementColor; @@ -375,17 +374,19 @@ public class ManaPool implements Iterable { } public void restoreColorReplacements() { + // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} for (int i = 0; i < colorConversionMatrix.length; i++) { colorConversionMatrix[i] = identityMatrix[i]; } + // By default all mana types are unrestricted for (int i = 0; i < colorRestrictionMatrix.length; i++) { - colorRestrictionMatrix[i] = ColorSet.ALL_COLORS.getColor(); + colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; } } public byte getPossibleColorUses(byte color) { // Take the current conversion value, AND with restrictions to get mana usage - int rowIdx = MagicColor.getIndexOfFirstColor(color); + int rowIdx = ManaAtom.getIndexOfFirstManaType(color); int matrixIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; byte colorUse = colorConversionMatrix[matrixIdx]; @@ -394,14 +395,16 @@ public class ManaPool implements Iterable { } public boolean canPayForShardWithColor(ManaCostShard shard, byte color) { + // TODO Debug this for Paying Gonti, byte line = getPossibleColorUses(color); - for (int i = 0; i < MagicColor.NUMBER_OR_COLORS; i++) { - byte outColor = MagicColor.WUBRG[i]; + + for(byte outColor : ManaAtom.MANATYPES) { if ((line & outColor) != 0 && shard.canBePaidWithManaOfColor(outColor)) { return true; } } + // TODO The following may not be needed anymore? if (((color & (byte) ManaAtom.COLORLESS) != 0) && shard.canBePaidWithManaOfColor((byte) (byte)ManaAtom.COLORLESS)) { return true; } From 210896b64e5650f6bb97150ecc62c07e81e334d1 Mon Sep 17 00:00:00 2001 From: Chris H Date: Sun, 7 Oct 2018 22:07:53 -0400 Subject: [PATCH 02/48] Pull ManaConversion out to be reused for SpellAbilityStackInstance --- .../src/main/java/forge/game/GameAction.java | 3 +- .../java/forge/game/ability/AbilityUtils.java | 3 +- .../game/mana/IManaConversionMatrix.java | 11 +++++ .../game/mana/ManaConversionService.java | 36 ++++++++++++++++ .../main/java/forge/game/mana/ManaPool.java | 43 ++----------------- .../forge/player/HumanPlaySpellAbility.java | 25 +++++------ 6 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java create mode 100644 forge-game/src/main/java/forge/game/mana/ManaConversionService.java diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 12d19649791..1ba4cfb501e 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -29,6 +29,7 @@ import forge.game.ability.effects.AttachEffect; import forge.game.card.*; import forge.game.event.*; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaConversionService; import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; @@ -786,7 +787,7 @@ public class GameAction { game.getReplacementHandler().cleanUpTemporaryReplacements(); for (final Player p : game.getPlayers()) { - p.getManaPool().restoreColorReplacements(); + new ManaConversionService(p.getManaPool()).restoreColorReplacements(); p.clearStaticAbilities(); } 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 46486599224..639e8781377 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -18,6 +18,7 @@ import forge.game.ability.AbilityFactory.AbilityRecordType; import forge.game.card.*; import forge.game.cost.Cost; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaConversionService; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerCollection; @@ -1663,7 +1664,7 @@ public class AbilityUtils { } } // AdjustColorReplacement has two different matrices handling final mana conversion under the covers - p.getManaPool().adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); + new ManaConversionService(p.getManaPool()).adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); } } } diff --git a/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java b/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java new file mode 100644 index 00000000000..0a047f766d7 --- /dev/null +++ b/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java @@ -0,0 +1,11 @@ +package forge.game.mana; + +import forge.card.mana.ManaAtom; + +public interface IManaConversionMatrix { + // Conversion matrix ORs byte values to make mana more payable + // Restrictive matrix ANDs byte values to make mana less payable + byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length]; + byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length]; + +} diff --git a/forge-game/src/main/java/forge/game/mana/ManaConversionService.java b/forge-game/src/main/java/forge/game/mana/ManaConversionService.java new file mode 100644 index 00000000000..513d47cd5db --- /dev/null +++ b/forge-game/src/main/java/forge/game/mana/ManaConversionService.java @@ -0,0 +1,36 @@ +package forge.game.mana; + +import forge.card.mana.ManaAtom; + +public class ManaConversionService { + static byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS }; + + IManaConversionMatrix matrix; + + public ManaConversionService(IManaConversionMatrix mtrx) { + matrix = mtrx; + } + + public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { + // Fix the index without hardcodes + int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); + rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; + if (additive) { + matrix.colorConversionMatrix[rowIdx] |= replacementColor; + } + else { + matrix.colorRestrictionMatrix[rowIdx] &= replacementColor; + } + } + + public void restoreColorReplacements() { + // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} + for (int i = 0; i < matrix.colorConversionMatrix.length; i++) { + matrix.colorConversionMatrix[i] = identityMatrix[i]; + } + // By default all mana types are unrestricted + for (int i = 0; i < matrix.colorRestrictionMatrix.length; i++) { + matrix.colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; + } + } +} diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java index d76c2145973..0b0c4f3924c 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -20,7 +20,6 @@ package forge.game.mana; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; - import forge.GameCommand; import forge.card.MagicColor; import forge.card.mana.ManaAtom; @@ -36,14 +35,9 @@ import forge.game.player.Player; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; - import org.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** *

@@ -53,13 +47,13 @@ import java.util.List; * @author Forge * @version $Id$ */ -public class ManaPool implements Iterable { +public class ManaPool implements Iterable, IManaConversionMatrix { private final Player owner; private final Multimap floatingMana = ArrayListMultimap.create(); public ManaPool(final Player player) { owner = player; - restoreColorReplacements(); + new ManaConversionService(this).restoreColorReplacements(); } public final int getAmountOfColor(final byte color) { @@ -354,40 +348,11 @@ public class ManaPool implements Iterable { Player p = sa.getActivatingPlayer(); p.getGame().fireEvent(new GameEventZone(ZoneType.Battlefield, p, EventValueChangeType.ComplexUpdate, null)); } - - // Conversion matrix ORs byte values to make mana more payable - // Restrictive matrix ANDs byte values to make mana less payable - private final byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length]; - private final byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length]; - private static final byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS }; - - public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { - // Fix the index without hardcodes - int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); - rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; - if (additive) { - colorConversionMatrix[rowIdx] |= replacementColor; - } - else { - colorRestrictionMatrix[rowIdx] &= replacementColor; - } - } - - public void restoreColorReplacements() { - // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} - for (int i = 0; i < colorConversionMatrix.length; i++) { - colorConversionMatrix[i] = identityMatrix[i]; - } - // By default all mana types are unrestricted - for (int i = 0; i < colorRestrictionMatrix.length; i++) { - colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; - } - } public byte getPossibleColorUses(byte color) { // Take the current conversion value, AND with restrictions to get mana usage int rowIdx = ManaAtom.getIndexOfFirstManaType(color); - int matrixIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; + int matrixIdx = rowIdx < 0 ? ManaConversionService.identityMatrix.length - 1 : rowIdx; byte colorUse = colorConversionMatrix[matrixIdx]; colorUse &= colorRestrictionMatrix[matrixIdx]; diff --git a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java index e03c8d89251..02b4bf64ea8 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java +++ b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java @@ -17,14 +17,8 @@ */ package forge.player; -import java.util.Collections; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - import com.google.common.collect.Iterables; import com.google.common.collect.Maps; - import forge.card.CardStateName; import forge.card.CardType; import forge.card.MagicColor; @@ -38,16 +32,17 @@ import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.cost.CostPayment; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaConversionService; import forge.game.mana.ManaPool; import forge.game.player.Player; import forge.game.player.PlayerController; -import forge.game.spellability.AbilityActivated; -import forge.game.spellability.AbilitySub; -import forge.game.spellability.Spell; -import forge.game.spellability.SpellAbility; -import forge.game.spellability.TargetRestrictions; +import forge.game.spellability.*; import forge.game.zone.Zone; import forge.util.collect.FCollection; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.Map; /** *

@@ -81,6 +76,7 @@ public class HumanPlaySpellAbility { final Card c = ability.getHostCard(); final CardPlayOption option = c.mayPlay(ability.getMayPlay()); + ManaConversionService service = new ManaConversionService(manapool); boolean manaTypeConversion = false; boolean manaColorConversion = false; @@ -169,11 +165,12 @@ public class HumanPlaySpellAbility { ability.getHostCard().unanimateBestow(); } } + if (manaTypeConversion || manaColorConversion || keywordColor) { - manapool.restoreColorReplacements(); + service.restoreColorReplacements(); } if (playerManaConversion) { - manapool.restoreColorReplacements(); + service.restoreColorReplacements(); human.decNumManaConversion(); } return false; @@ -196,7 +193,7 @@ public class HumanPlaySpellAbility { clearTargets(ability); } if (manaTypeConversion || manaColorConversion || keywordColor) { - manapool.restoreColorReplacements(); + service.restoreColorReplacements(); } } return true; From 62a11481abf6f48d5f2aa4ac7b9fead0a224a167 Mon Sep 17 00:00:00 2001 From: swordshine Date: Tue, 9 Oct 2018 14:42:58 +0800 Subject: [PATCH 03/48] - Fixed more cards --- forge-gui/res/cardsfolder/s/saheeli_the_gifted.txt | 4 ++-- forge-gui/res/cardsfolder/t/tuvasa_the_sunlit.txt | 2 +- .../res/cardsfolder/v/varchild_betrayer_of_kjeldor.txt | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/forge-gui/res/cardsfolder/s/saheeli_the_gifted.txt b/forge-gui/res/cardsfolder/s/saheeli_the_gifted.txt index acb0906840c..86f5b00299f 100644 --- a/forge-gui/res/cardsfolder/s/saheeli_the_gifted.txt +++ b/forge-gui/res/cardsfolder/s/saheeli_the_gifted.txt @@ -10,7 +10,7 @@ SVar:RemoveEffect:DB$ ChangeZone | Origin$ Command | Destination$ Exile SVar:X:Count$Valid Artifact.YouCtrl SVar:RemRandomDeck A:AB$ RepeatEach | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | RepeatSubAbility$ DBClone | RepeatCards$ Artifact.YouCtrl | AtEOT$ ExileCombat | AddSVars$ SneakAttackEOT | SpellDescription$ For each artifact you control, create a token that's a copy of it. Those tokens gain haste. Exile those tokens at the beginning of the next end step. -SVar:DBClone:DB$ CopyPermanent | Defined$ Remembered | Keywords$ Haste | AtEOT$ Exile | AddSVars$ SneakAttackEOT | AtEOT$ Exile +SVar:DBClone:DB$ CopyPermanent | Defined$ Remembered | Keywords$ Haste | AtEOT$ Exile | AddSVars$ SneakAttackEOT SVar:SneakAttackEOT:SVar:EndOfTurnLeavePlay:True K:CARDNAME can be your commander. -Oracle:[+1]: Create a 1/1 colorless Servo artifact creature token.\n[+1]: The next spell you cast this turn costs {1} less to cast for each artifact you control as you cast it.\n[-7]: For each artifact you control, create a token that's a copy of it. Those tokens gain haste. Exile those tokens at the beginning of the next end step.\nSaheeli, the Gifted can be your commander. \ No newline at end of file +Oracle:[+1]: Create a 1/1 colorless Servo artifact creature token.\n[+1]: The next spell you cast this turn costs {1} less to cast for each artifact you control as you cast it.\n[-7]: For each artifact you control, create a token that's a copy of it. Those tokens gain haste. Exile those tokens at the beginning of the next end step.\nSaheeli, the Gifted can be your commander. diff --git a/forge-gui/res/cardsfolder/t/tuvasa_the_sunlit.txt b/forge-gui/res/cardsfolder/t/tuvasa_the_sunlit.txt index 54e048fd514..49c79afd743 100644 --- a/forge-gui/res/cardsfolder/t/tuvasa_the_sunlit.txt +++ b/forge-gui/res/cardsfolder/t/tuvasa_the_sunlit.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Merfolk Shaman PT:1/1 S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | Description$ CARDNAME gets +1/+1 for each enchantment you control. SVar:X:Count$Valid Enchantment.YouCtrl -T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | CheckSVar$ Y | SVarCompare$ EQ1 | References$ Y | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you cast your first enchantment spell each turn, draw a card. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | CheckSVar$ Y | SVarCompare$ EQ1 | References$ Y | NoResolvingCheck$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you cast your first enchantment spell each turn, draw a card. SVar:Y:Count$ThisTurnCast_Enchantment.YouCtrl SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You SVar:BuffedBy:Enchantment diff --git a/forge-gui/res/cardsfolder/v/varchild_betrayer_of_kjeldor.txt b/forge-gui/res/cardsfolder/v/varchild_betrayer_of_kjeldor.txt index 667ecd11252..9c248f8890d 100644 --- a/forge-gui/res/cardsfolder/v/varchild_betrayer_of_kjeldor.txt +++ b/forge-gui/res/cardsfolder/v/varchild_betrayer_of_kjeldor.txt @@ -5,8 +5,8 @@ PT:3/3 T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigToken | TriggerDescription$ When CARDNAME deals combat damage to a player, that player creates that many 1/1 red Survivor creature tokens. SVar:TrigToken:DB$ Token | TokenOwner$ TriggeredTarget | TokenAmount$ X | References$ X | TokenName$ Survivor | TokenTypes$ Creature,Survivor | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 | TokenImage$ r 1 1 survivor C18 SVar:X:TriggerCount$DamageAmount -S:Mode$ Continuous | Affected$ Survivor | AddHiddenKeyword$ CantBlock Creature | Description$ Survivors can't block. -S:Mode$ CantAttack | ValidCard$ Creature.Survivor | Target$ You,Planeswalker.YouCtrl | Description$ Survivors your opponent control can't attack you or planeswalkers you control. +S:Mode$ Continuous | Affected$ Survivor.OppCtrl | AddHiddenKeyword$ CantBlock Creature | Description$ Survivors your opponents control can't block. +S:Mode$ CantAttack | ValidCard$ Creature.Survivor+OppCtrl | Target$ You,Planeswalker.YouCtrl | Description$ Survivors your opponents control can't attack you or planeswalkers you control. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigGainControl | TriggerDescription$ When CARDNAME leaves the battlefield, gain control of all Survivors. SVar:TrigGainControl:DB$ GainControl | AllValid$ Survivor | NewController$ You -Oracle:When Varchild, Betrayer of Kjeldor deals combat damage to a player, that player creates that many 1/1 red Survivor creature tokens.\nSurvivors your opponent control can't attack you or planeswalkers you control.\nWhen Varchild, Betrayer of Kjeldor leaves the battlefield, gain control of all Survivors. \ No newline at end of file +Oracle:When Varchild, Betrayer of Kjeldor deals combat damage to a player, that player creates that many 1/1 red Survivor creature tokens.\nSurvivors your opponents control can't block, and they can't attack you or a planeswalker you control.\nWhen Varchild, Betrayer of Kjeldor leaves the battlefield, gain control of all Survivors. From 09e46ee8bddbc47f1a9cd4452ab79402a62688a8 Mon Sep 17 00:00:00 2001 From: swordshine Date: Tue, 9 Oct 2018 15:55:06 +0800 Subject: [PATCH 04/48] - migrate Aminatou, the Fateshifter --- .../forge/game/ability/effects/ControlGainVariantEffect.java | 2 ++ .../cardsfolder/{upcoming => a}/aminatou_the_fateshifter.txt | 0 2 files changed, 2 insertions(+) rename forge-gui/res/cardsfolder/{upcoming => a}/aminatou_the_fateshifter.txt (100%) diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlGainVariantEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlGainVariantEffect.java index 48123229288..44c2deddebe 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlGainVariantEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlGainVariantEffect.java @@ -21,6 +21,8 @@ public class ControlGainVariantEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { // Aminatou, the Fateshifter (multiple players gain control of multiple permanents in an effect) + // Consider migrating cards with similar effects + // GainControl embedded in RepeatEach effects don't work well with timestamps final Card source = sa.getHostCard(); final Game game = source.getGame(); diff --git a/forge-gui/res/cardsfolder/upcoming/aminatou_the_fateshifter.txt b/forge-gui/res/cardsfolder/a/aminatou_the_fateshifter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/aminatou_the_fateshifter.txt rename to forge-gui/res/cardsfolder/a/aminatou_the_fateshifter.txt From 962576b987cde9f5bee3cff7f71dc77b6103de99 Mon Sep 17 00:00:00 2001 From: swordshine Date: Tue, 9 Oct 2018 16:58:57 +0800 Subject: [PATCH 05/48] - Fixed Darkblade Agent's description --- forge-gui/res/cardsfolder/d/darkblade_agent.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/d/darkblade_agent.txt b/forge-gui/res/cardsfolder/d/darkblade_agent.txt index 0f933fee1e8..a3ce8c4a4ae 100644 --- a/forge-gui/res/cardsfolder/d/darkblade_agent.txt +++ b/forge-gui/res/cardsfolder/d/darkblade_agent.txt @@ -2,7 +2,7 @@ Name:Darkblade Agent ManaCost:1 U B Types:Creature Human Assassin PT:2/3 -S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Deathtouch | AddTrigger$ Trig1 | AddSVar$ TrigDraw | CheckSVar$ X | SVarCompare$ GE1 | Description$ As long as you've surveilled this turn, CARDNAME has deathtouch and and whenever Whenever this creature deals combat damage to a player, draw a card. +S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Deathtouch | AddTrigger$ Trig1 | AddSVar$ TrigDraw | CheckSVar$ X | SVarCompare$ GE1 | Description$ As long as you've surveilled this turn, CARDNAME has deathtouch and "Whenever this creature deals combat damage to a player, draw a card." SVar:Trig1:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:X:Count$YouSurveilThisTurn From e0f79a6d71934d9e41c5c8001d0b4f03ca8692b7 Mon Sep 17 00:00:00 2001 From: swordshine Date: Tue, 9 Oct 2018 17:58:16 +0800 Subject: [PATCH 06/48] - Fixed more cards --- forge-gui/res/cardsfolder/d/disinformation_campaign.txt | 2 +- forge-gui/res/cardsfolder/g/guild_summit.txt | 2 +- forge-gui/res/cardsfolder/r/ravenous_slime.txt | 2 +- forge-gui/res/cardsfolder/t/turntimber_sower.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/forge-gui/res/cardsfolder/d/disinformation_campaign.txt b/forge-gui/res/cardsfolder/d/disinformation_campaign.txt index 3af7a783fff..17be691d384 100644 --- a/forge-gui/res/cardsfolder/d/disinformation_campaign.txt +++ b/forge-gui/res/cardsfolder/d/disinformation_campaign.txt @@ -4,6 +4,6 @@ Types:Enchantment T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, you draw a card and each opponent discards a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBDiscard SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | NumCards$ 1 | Mode$ TgtChoose -T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ Whenever you surveil, return Disinformation Campaign to its owner's hand. +T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ Whenever you surveil, return CARDNAME to its owner's hand. SVar:TrigBounce:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Defined$ Self Oracle:When Disinformation Campaign enters the battlefield, you draw a card and each opponent discards a card.\nWhenever you surveil, return Disinformation Campaign to its owner's hand. diff --git a/forge-gui/res/cardsfolder/g/guild_summit.txt b/forge-gui/res/cardsfolder/g/guild_summit.txt index 8d3e5aefb68..24608dbed49 100644 --- a/forge-gui/res/cardsfolder/g/guild_summit.txt +++ b/forge-gui/res/cardsfolder/g/guild_summit.txt @@ -6,7 +6,7 @@ SVar:GuestList:DB$ ChooseCard | Defined$ You | MinAmount$ 0 | Amount$ X | Refere SVar:TrigTap:DB$ Tap | Defined$ Remembered | SubAbility$ DBDraw SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ Y | SubAbility$ DBCleanup | References$ Y SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:Count$Valid Creature.YouCtrl +SVar:X:Count$Valid Gate.untapped+YouCtrl SVar:Y:Remembered$Amount T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Gate.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a Gate enters the battlefield under your control, draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 diff --git a/forge-gui/res/cardsfolder/r/ravenous_slime.txt b/forge-gui/res/cardsfolder/r/ravenous_slime.txt index 39d9a888cb1..8714289faff 100644 --- a/forge-gui/res/cardsfolder/r/ravenous_slime.txt +++ b/forge-gui/res/cardsfolder/r/ravenous_slime.txt @@ -6,5 +6,5 @@ K:CantBeBlockedBy Creature.powerLE2 R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidLKI$ Creature.OppCtrl | ReplaceWith$ Exile | Description$ If a creature an opponent controls would die, instead exile it and put a number of +1/+1 counters equal to that creature's power on CARDNAME. SVar:Exile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBPutCounter SVar:DBPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ X | References$ X | Defined$ Self -SVar:X:ReplacedCard$CardPower +SVar:X:ReplacedCardLKI$CardPower Oracle:Ravenous Slime can't be blocked by creatures with power 2 or less.\nIf a creature an opponent controls would die, instead exile it and put a number of +1/+1 counters equal to that creature's power on Ravenous Slime. diff --git a/forge-gui/res/cardsfolder/t/turntimber_sower.txt b/forge-gui/res/cardsfolder/t/turntimber_sower.txt index b8c871a0564..972f5da9136 100644 --- a/forge-gui/res/cardsfolder/t/turntimber_sower.txt +++ b/forge-gui/res/cardsfolder/t/turntimber_sower.txt @@ -2,7 +2,7 @@ Name:Turntimber Sower ManaCost:2 G Types:Creature Elf Druid PT:3/3 -T:Mode$ ChangesZone | ValidCard$ Land.YouOwn | Origin$ Any | Destination$ Graveyard | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more land cards are put into your graveyard from anywhere, create a 0/1 green Plant creature token. +T:Mode$ ChangesZone | ValidCard$ Land.YouOwn | Origin$ Any | Destination$ Graveyard | Execute$ TrigToken | OncePerEffect$ True | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more land cards are put into your graveyard from anywhere, create a 0/1 green Plant creature token. SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenName$ Plant | TokenTypes$ Creature,Plant | TokenOwner$ You | TokenColors$ Green | TokenPower$ 0 | TokenToughness$ 1 | TokenImage$ g 0 1 plant c18 SVar:RemRandomDeck:True A:AB$ ChangeZone | Cost$ G Sac<3/Creature> | TgtPrompt$ Choose target land card in your graveyard | ValidTgts$ Land.YouCtrl | Origin$ Graveyard | Destination$ Hand | SpellDescription$ Return target land card from your graveyard to your hand. From 5b295261d742e4572e0efdcd23b70100de191020 Mon Sep 17 00:00:00 2001 From: swordshine Date: Tue, 9 Oct 2018 20:51:00 +0800 Subject: [PATCH 07/48] - Commander Storm cards --- .../main/java/forge/game/card/CardFactoryUtil.java | 6 +++++- .../src/main/java/forge/game/player/Player.java | 8 ++++++++ .../src/main/java/forge/game/zone/MagicStack.java | 3 ++- forge-gui/res/cardsfolder/e/echo_storm.txt | 9 +++++++++ forge-gui/res/cardsfolder/e/empyrial_storm.txt | 8 ++++---- forge-gui/res/cardsfolder/f/fury_storm.txt | 8 ++++++++ forge-gui/res/cardsfolder/g/genesis_storm.txt | 8 ++++++++ forge-gui/res/cardsfolder/s/skull_storm.txt | 13 +++++++++++++ 8 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 forge-gui/res/cardsfolder/e/echo_storm.txt create mode 100644 forge-gui/res/cardsfolder/f/fury_storm.txt create mode 100644 forge-gui/res/cardsfolder/g/genesis_storm.txt create mode 100644 forge-gui/res/cardsfolder/s/skull_storm.txt diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 452f49d69ea..6f0b68c466f 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -842,7 +842,11 @@ public class CardFactoryUtil { // only used by Opal Palace, and it does add the trigger to the card return doXMath(cc.getCommanderCast(c), m, c); } - + + if (l[0].startsWith("TotalCommanderCastFromCommandZone")) { + return doXMath(cc.getTotalCommanderCast(), m, c); + } + if (l[0].startsWith("MostProminentCreatureType")) { String restriction = l[0].split(" ")[1]; CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, cc, c); diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 56415c518bc..e4e5bfe45ce 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -2665,6 +2665,14 @@ public class Player extends GameEntity implements Comparable { commanderCast.put(commander, getCommanderCast(commander) + 1); } + public int getTotalCommanderCast() { + int result = 0; + for (Integer i : commanderCast.values()) { + result += i; + } + return result; + } + public boolean isPlayingExtraTurn() { return isPlayingExtraTrun; } diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 357cbfd44de..53e8e676291 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -368,7 +368,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable Date: Tue, 9 Oct 2018 23:10:31 +0800 Subject: [PATCH 08/48] - Updated more scripts --- .../src/main/java/forge/game/cost/CostAdjustment.java | 9 --------- forge-gui/res/cardsfolder/m/myth_unbound.txt | 6 +++--- forge-gui/res/cardsfolder/t/thirsting_axe.txt | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java index 455949c58d5..1ad50114869 100644 --- a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java +++ b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java @@ -503,15 +503,6 @@ public class CostAdjustment { if (!sa.isSpell() || !((Spell) sa).isCastFaceDown()) { return false; } - } else if (type.equals("SelfMonstrosity")) { - if (!(sa instanceof AbilityActivated) || !sa.hasParam("Monstrosity") || sa.isTemporary()) { - // Nemesis of Mortals - return false; - } - } else if (type.equals("SelfIntrinsicAbility")) { - if (!(sa instanceof AbilityActivated) || sa.isReplacementAbility() || sa.isTemporary()) { - return false; - } } } if (params.containsKey("AffectedZone")) { diff --git a/forge-gui/res/cardsfolder/m/myth_unbound.txt b/forge-gui/res/cardsfolder/m/myth_unbound.txt index c304efb05e6..3855b57b5b0 100644 --- a/forge-gui/res/cardsfolder/m/myth_unbound.txt +++ b/forge-gui/res/cardsfolder/m/myth_unbound.txt @@ -1,9 +1,9 @@ Name:Myth Unbound ManaCost:2 G Types:Enchantment -S:Mode$ ReduceCost | ValidCard$ Card.IsCommander | Type$ Spell | Amount$ X | EffectZone$ Command | Description$ Your commander costs {1} less to cast for each time it's been cast from the command zone this game. -T:Mode$ ChangesZone | ValidCard$ Card.IsCommander+YouOwn | TriggerZones$ Command | Origin$ Any | Destination$ Command | Execute$ TrigDraw | TriggerDescription$ Whenever your commander is put into the command zone from anywhere, draw a card. +S:Mode$ ReduceCost | ValidCard$ Card.IsCommander+YouOwn | Type$ Spell | Amount$ AffectedX | Description$ Your commander costs {1} less to cast for each time it's been cast from the command zone this game. +T:Mode$ ChangesZoneAll | ValidCard$ Card.IsCommander+YouOwn | Origin$ Any | Destination$ Command | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever your commander is put into the command zone from anywhere, draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 -SVar:X:Count$CommanderCastFromCommandZone +SVar:AffectedX:Count$CommanderCastFromCommandZone SVar:RemRandomDeck:True Oracle:Your commander costs {1} less to cast for each time it's been cast from the command zone this game.\nWhenever your commander is put into the command zone from anywhere, draw a card. diff --git a/forge-gui/res/cardsfolder/t/thirsting_axe.txt b/forge-gui/res/cardsfolder/t/thirsting_axe.txt index a1b1326de42..cce75513ddd 100644 --- a/forge-gui/res/cardsfolder/t/thirsting_axe.txt +++ b/forge-gui/res/cardsfolder/t/thirsting_axe.txt @@ -3,7 +3,7 @@ ManaCost:3 Types:Artifact Equipment K:Equip:2 S:Mode$ Continuous | Affected$ Card.EquippedBy | AddPower$ 4 | Description$ Equipped creature gets +4/+0. -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | IsPresent$ Card.EquippedBy+notDealtCombatDamageThisTurn Creature | TriggerZone$ Battlefield | Execute$ SacrificeEquippee | TriggerDescription$ At the beginning of your end step, if equipped creature didn't deal combat damage to a creature this turn, sacrifice it. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | IsPresent$ Card.EquippedBy+notDealtCombatDamageThisTurn Creature | TriggerZones$ Battlefield | Execute$ SacrificeEquippee | TriggerDescription$ At the beginning of your end step, if equipped creature didn't deal combat damage to a creature this turn, sacrifice it. SVar:SacrificeEquippee:DB$ SacrificeAll | Defined$ Equipped SVar:Picture:http://www.wizards.com/global/images/magic/general/thirsting_axe.jpg Oracle:Equipped creature gets +4/+0.\nAt the beginning of your end step, if equipped creature didn't deal combat damage to a creature this turn, sacrifice it.\nEquip {2} From 677ee26e91b1ce3d9dfaee0edb88c64db04dad3c Mon Sep 17 00:00:00 2001 From: "Jamin W. Collins" Date: Tue, 9 Oct 2018 17:35:49 -0600 Subject: [PATCH 09/48] fix Creeping Chill stack description Signed-off-by: Jamin W. Collins --- forge-gui/res/cardsfolder/c/creeping_chill.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/c/creeping_chill.txt b/forge-gui/res/cardsfolder/c/creeping_chill.txt index 48aaddf378e..8f9c247bf82 100644 --- a/forge-gui/res/cardsfolder/c/creeping_chill.txt +++ b/forge-gui/res/cardsfolder/c/creeping_chill.txt @@ -1,7 +1,7 @@ Name:Creeping Chill ManaCost:3 B Types:Sorcery -A:SP$ DamageAll | Cost$ 3 B | ValidPlayers$ Player.Opponent | NumDmg$ 3 | SubAbility$ DBGainLife | SpellDescription$ CARDNAME deals 3 damage to each opponent and you gain 3 life. +A:SP$ DamageAll | StackDescription$ CARDNAME deals 3 damage to each opponent and | Cost$ 3 B | ValidPlayers$ Player.Opponent | NumDmg$ 3 | SubAbility$ DBGainLife | SpellDescription$ CARDNAME deals 3 damage to each opponent and you gain 3 life. T:Mode$ ChangesZone | Origin$ Library | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ When CARDNAME is put into your graveyard from your library, you may exile it. If you do, then a opponent and you gain 3 life. SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Exile | SubAbility$ DBDamage SVar:DBDamage:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 3 | SubAbility$ DBGainLife From a559e05ce4afeb9e7a8cc0dfac1ff9d5454297a6 Mon Sep 17 00:00:00 2001 From: Chris H Date: Mon, 8 Oct 2018 23:35:53 -0400 Subject: [PATCH 10/48] Cross my fingers --- .../java/forge/ai/PlayerControllerAi.java | 3 +- .../src/main/java/forge/game/GameAction.java | 5 ++- .../java/forge/game/ability/AbilityUtils.java | 6 +-- .../java/forge/game/cost/CostPartMana.java | 8 +++- .../java/forge/game/cost/CostPayment.java | 9 +++- .../game/mana/IManaConversionMatrix.java | 11 ----- .../forge/game/mana/ManaConversionMatrix.java | 45 +++++++++++++++++++ .../game/mana/ManaConversionService.java | 36 --------------- .../main/java/forge/game/mana/ManaPool.java | 6 +-- .../forge/game/player/PlayerController.java | 9 +++- .../StaticAbilityContinuous.java | 3 +- .../util/PlayerControllerForTests.java | 3 +- .../input/InputPayManaOfCostPayment.java | 16 ++++++- .../src/main/java/forge/player/HumanPlay.java | 40 ++++++----------- .../forge/player/HumanPlaySpellAbility.java | 18 ++++---- .../forge/player/PlayerControllerHuman.java | 5 ++- 16 files changed, 122 insertions(+), 101 deletions(-) delete mode 100644 forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java create mode 100644 forge-game/src/main/java/forge/game/mana/ManaConversionMatrix.java delete mode 100644 forge-game/src/main/java/forge/game/mana/ManaConversionService.java diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index e230c7bd04c..9edb07ce59c 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -26,6 +26,7 @@ import forge.game.card.CardPredicates.Presets; import forge.game.combat.Combat; import forge.game.cost.*; import forge.game.mana.Mana; +import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; @@ -921,7 +922,7 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa) { + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, ManaConversionMatrix matrix, boolean isActivatedSa) { // TODO Auto-generated method stub ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0) : new ManaCostBeingPaid(toPay); return ComputerUtilMana.payManaCost(cost, sa, player); diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 1ba4cfb501e..076aa493db5 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -29,7 +29,6 @@ import forge.game.ability.effects.AttachEffect; import forge.game.card.*; import forge.game.event.*; import forge.game.keyword.KeywordInterface; -import forge.game.mana.ManaConversionService; import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; @@ -787,7 +786,9 @@ public class GameAction { game.getReplacementHandler().cleanUpTemporaryReplacements(); for (final Player p : game.getPlayers()) { - new ManaConversionService(p.getManaPool()).restoreColorReplacements(); + if (!game.getStack().isFrozen()) { + p.getManaPool().restoreColorReplacements(); + } p.clearStaticAbilities(); } 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 639e8781377..7f5be63dfd4 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -18,7 +18,7 @@ import forge.game.ability.AbilityFactory.AbilityRecordType; import forge.game.card.*; import forge.game.cost.Cost; import forge.game.keyword.KeywordInterface; -import forge.game.mana.ManaConversionService; +import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerCollection; @@ -1643,7 +1643,7 @@ public class AbilityUtils { return CardFactoryUtil.xCount(c, s2); } - public static final void applyManaColorConversion(final Player p, final Map params) { + public static final void applyManaColorConversion(ManaConversionMatrix matrix, final Map params) { String conversionType = params.get("ManaColorConversion"); // Choices are Additives(OR) or Restrictive(AND) @@ -1664,7 +1664,7 @@ public class AbilityUtils { } } // AdjustColorReplacement has two different matrices handling final mana conversion under the covers - new ManaConversionService(p.getManaPool()).adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); + matrix.adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); } } } diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index 81d94a288e2..1fd0b568131 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -19,7 +19,9 @@ package forge.game.cost; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; +import forge.game.mana.ManaConversionMatrix; import forge.game.player.Player; +import forge.game.spellability.AbilityActivated; import forge.game.spellability.SpellAbility; /** @@ -37,6 +39,9 @@ public class CostPartMana extends CostPart { private boolean isEnchantedCreatureCost = false; private final String restriction; + private ManaConversionMatrix cardMatrix = null; + public void setCardMatrix(ManaConversionMatrix mtrx) { cardMatrix = mtrx; } + public int paymentOrder() { return shouldPayLast() ? 200 : 0; } public boolean shouldPayLast() { @@ -147,8 +152,9 @@ public class CostPartMana extends CostPart { // TODO Auto-generated method stub sa.clearManaPaid(); + boolean isActivated = sa instanceof AbilityActivated; // decision not used here, the whole payment is interactive! - return payer.getController().payManaCost(this, sa, null, true); + return payer.getController().payManaCost(this, sa, null, cardMatrix, isActivated); } } diff --git a/forge-game/src/main/java/forge/game/cost/CostPayment.java b/forge-game/src/main/java/forge/game/cost/CostPayment.java index 9785a12a49b..ca002861212 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPayment.java +++ b/forge-game/src/main/java/forge/game/cost/CostPayment.java @@ -21,6 +21,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import forge.game.Game; import forge.game.card.Card; +import forge.game.mana.ManaConversionMatrix; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; @@ -35,7 +36,7 @@ import java.util.Map; * @author Forge * @version $Id$ */ -public class CostPayment { +public class CostPayment extends ManaConversionMatrix { private final Cost cost; private Cost adjustedCost; private final SpellAbility ability; @@ -70,6 +71,7 @@ public class CostPayment { this.cost = cost; this.adjustedCost = cost; this.ability = abil; + restoreColorReplacements(); } /** @@ -137,6 +139,11 @@ public class CostPayment { PaymentDecision pd = part.accept(decisionMaker); + // RIght before we start paying as decided, we need to transfer the CostPayments matrix over? + if (part instanceof CostPartMana) { + ((CostPartMana)part).setCardMatrix(this); + } + if (pd == null || !part.payAsDecided(decisionMaker.getPlayer(), pd, ability)) { game.costPaymentStack.pop(); // cost is resolved return false; diff --git a/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java b/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java deleted file mode 100644 index 0a047f766d7..00000000000 --- a/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java +++ /dev/null @@ -1,11 +0,0 @@ -package forge.game.mana; - -import forge.card.mana.ManaAtom; - -public interface IManaConversionMatrix { - // Conversion matrix ORs byte values to make mana more payable - // Restrictive matrix ANDs byte values to make mana less payable - byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length]; - byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length]; - -} diff --git a/forge-game/src/main/java/forge/game/mana/ManaConversionMatrix.java b/forge-game/src/main/java/forge/game/mana/ManaConversionMatrix.java new file mode 100644 index 00000000000..e8caf56d774 --- /dev/null +++ b/forge-game/src/main/java/forge/game/mana/ManaConversionMatrix.java @@ -0,0 +1,45 @@ +package forge.game.mana; + +import forge.card.mana.ManaAtom; + +public class ManaConversionMatrix { + static byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS }; + + // Conversion matrix ORs byte values to make mana more payable + // Restrictive matrix ANDs byte values to make mana less payable + byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length]; + byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length]; + + public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { + // Fix the index without hardcodes + int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); + rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; + if (additive) { + colorConversionMatrix[rowIdx] |= replacementColor; + } + else { + colorRestrictionMatrix[rowIdx] &= replacementColor; + } + } + + public void applyCardMatrix(ManaConversionMatrix extraMatrix) { + for (int i = 0; i < colorConversionMatrix.length; i++) { + colorConversionMatrix[i] |= extraMatrix.colorConversionMatrix[i]; + } + + for (int i = 0; i < colorRestrictionMatrix.length; i++) { + colorRestrictionMatrix[i] &= extraMatrix.colorRestrictionMatrix[i]; + } + } + + public void restoreColorReplacements() { + // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} + for (int i = 0; i < colorConversionMatrix.length; i++) { + colorConversionMatrix[i] = identityMatrix[i]; + } + // By default all mana types are unrestricted + for (int i = 0; i < colorRestrictionMatrix.length; i++) { + colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; + } + } +} \ No newline at end of file diff --git a/forge-game/src/main/java/forge/game/mana/ManaConversionService.java b/forge-game/src/main/java/forge/game/mana/ManaConversionService.java deleted file mode 100644 index 513d47cd5db..00000000000 --- a/forge-game/src/main/java/forge/game/mana/ManaConversionService.java +++ /dev/null @@ -1,36 +0,0 @@ -package forge.game.mana; - -import forge.card.mana.ManaAtom; - -public class ManaConversionService { - static byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS }; - - IManaConversionMatrix matrix; - - public ManaConversionService(IManaConversionMatrix mtrx) { - matrix = mtrx; - } - - public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { - // Fix the index without hardcodes - int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); - rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; - if (additive) { - matrix.colorConversionMatrix[rowIdx] |= replacementColor; - } - else { - matrix.colorRestrictionMatrix[rowIdx] &= replacementColor; - } - } - - public void restoreColorReplacements() { - // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} - for (int i = 0; i < matrix.colorConversionMatrix.length; i++) { - matrix.colorConversionMatrix[i] = identityMatrix[i]; - } - // By default all mana types are unrestricted - for (int i = 0; i < matrix.colorRestrictionMatrix.length; i++) { - matrix.colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; - } - } -} diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java index 0b0c4f3924c..de59a57ef21 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -47,13 +47,13 @@ import java.util.*; * @author Forge * @version $Id$ */ -public class ManaPool implements Iterable, IManaConversionMatrix { +public class ManaPool extends ManaConversionMatrix implements Iterable { private final Player owner; private final Multimap floatingMana = ArrayListMultimap.create(); public ManaPool(final Player player) { owner = player; - new ManaConversionService(this).restoreColorReplacements(); + restoreColorReplacements(); } public final int getAmountOfColor(final byte color) { @@ -352,7 +352,7 @@ public class ManaPool implements Iterable, IManaConversionMatrix { public byte getPossibleColorUses(byte color) { // Take the current conversion value, AND with restrictions to get mana usage int rowIdx = ManaAtom.getIndexOfFirstManaType(color); - int matrixIdx = rowIdx < 0 ? ManaConversionService.identityMatrix.length - 1 : rowIdx; + int matrixIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; byte colorUse = colorConversionMatrix[matrixIdx]; colorUse &= colorRestrictionMatrix[matrixIdx]; diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index adc6bd77754..f603e7656e4 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -20,6 +20,7 @@ import forge.game.cost.Cost; import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.mana.Mana; +import forge.game.mana.ManaConversionMatrix; import forge.game.replacement.ReplacementEffect; import forge.game.spellability.*; import forge.game.trigger.WrappedAbility; @@ -220,9 +221,13 @@ public abstract class PlayerController { public abstract void resetAtEndOfTurn(); // currently used by the AI to perform card memory cleanup public final boolean payManaCost(CostPartMana costPartMana, SpellAbility sa, String prompt, boolean isActivatedAbility) { - return payManaCost(costPartMana.getManaCostFor(sa), costPartMana, sa, prompt, isActivatedAbility); + return payManaCost(costPartMana, sa, prompt, null, isActivatedAbility); } - public abstract boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt, boolean isActivatedAbility); + + public final boolean payManaCost(CostPartMana costPartMana, SpellAbility sa, String prompt, ManaConversionMatrix matrix, boolean isActivatedAbility) { + return payManaCost(costPartMana.getManaCostFor(sa), costPartMana, sa, prompt, matrix, isActivatedAbility); + } + public abstract boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt, ManaConversionMatrix matrix, boolean isActivatedAbility); public abstract Map chooseCardsForConvokeOrImprovise(SpellAbility sa, ManaCost manaCost, CardCollectionView untappedCards, boolean improvise); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 30cf2ca1749..63e71ca52a1 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -41,7 +41,6 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; import forge.util.TextUtil; - import org.apache.commons.lang3.StringUtils; import java.util.*; @@ -481,7 +480,7 @@ public final class StaticAbilityContinuous { } if (params.containsKey("ManaColorConversion")) { - AbilityUtils.applyManaColorConversion(p, params); + AbilityUtils.applyManaColorConversion(p.getManaPool(), params); } } } diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 4b0afe447b1..80e3e033579 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -30,6 +30,7 @@ import forge.game.cost.Cost; import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.mana.Mana; +import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.*; import forge.game.replacement.ReplacementEffect; @@ -591,7 +592,7 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa ) { + public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, ManaConversionMatrix matrix, boolean isActivatedSa) { // TODO Auto-generated method stub ManaCostBeingPaid cost = new ManaCostBeingPaid(toPay); return ComputerUtilMana.payManaCost(cost, sa, player); diff --git a/forge-gui/src/main/java/forge/match/input/InputPayManaOfCostPayment.java b/forge-gui/src/main/java/forge/match/input/InputPayManaOfCostPayment.java index 1f3fba6da55..15da37980f1 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayManaOfCostPayment.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayManaOfCostPayment.java @@ -1,6 +1,7 @@ package forge.match.input; import forge.game.card.Card; +import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -10,13 +11,16 @@ import forge.properties.ForgePreferences; import forge.util.ITriggerEvent; public class InputPayManaOfCostPayment extends InputPayMana { - public InputPayManaOfCostPayment(final PlayerControllerHuman controller, ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer) { + public InputPayManaOfCostPayment(final PlayerControllerHuman controller, ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer, ManaConversionMatrix matrix) { super(controller, spellAbility, payer); manaCost = cost; + extraMatrix = matrix; + applyMatrix(); } private static final long serialVersionUID = 3467312982164195091L; private int phyLifeToLose = 0; + private ManaConversionMatrix extraMatrix; @Override protected final void onPlayerSelected(Player selected, final ITriggerEvent triggerEvent) { @@ -47,6 +51,8 @@ public class InputPayManaOfCostPayment extends InputPayMana { final String displayMana = manaCost.toString(false, player.getManaPool()); final StringBuilder msg = new StringBuilder(); + applyMatrix(); + if (messagePrefix != null) { msg.append(messagePrefix).append("\n"); } @@ -71,4 +77,12 @@ public class InputPayManaOfCostPayment extends InputPayMana { return msg.toString(); } + + private void applyMatrix() { + if (extraMatrix == null) { + return; + } + + player.getManaPool().applyCardMatrix(extraMatrix); + } } diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index fd96df17d56..8e7b84f42e3 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -1,21 +1,8 @@ package forge.player; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import forge.game.cost.*; -import forge.game.spellability.LandAbility; -import forge.game.spellability.OptionalCostValue; -import forge.game.spellability.Spell; -import forge.util.TextUtil; -import org.apache.commons.lang3.StringUtils; - import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; - import forge.FThreads; import forge.card.mana.ManaCost; import forge.game.Game; @@ -25,30 +12,31 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.CharmEffect; import forge.game.ability.effects.FlipCoinEffect; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardDamageMap; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; +import forge.game.card.*; import forge.game.card.CardPredicates.Presets; -import forge.game.card.CardView; -import forge.game.card.CounterType; +import forge.game.cost.*; +import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerController; import forge.game.player.PlayerView; -import forge.game.spellability.SpellAbility; -import forge.game.spellability.TargetRestrictions; +import forge.game.spellability.*; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.match.input.InputPayMana; import forge.match.input.InputPayManaOfCostPayment; import forge.match.input.InputPayManaSimple; import forge.match.input.InputSelectCardsFromList; -import forge.util.collect.FCollectionView; import forge.util.Lang; +import forge.util.TextUtil; +import forge.util.collect.FCollectionView; import forge.util.gui.SGuiChoose; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class HumanPlay { @@ -814,7 +802,7 @@ public class HumanPlay { return !manaInputCancelled; } - public static boolean payManaCost(final PlayerControllerHuman controller, final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt, boolean isActivatedSa) { + public static boolean payManaCost(final PlayerControllerHuman controller, final ManaCost realCost, final CostPartMana mc, final SpellAbility ability, final Player activator, String prompt, ManaConversionMatrix matrix, boolean isActivatedSa) { final Card source = ability.getHostCard(); ManaCostBeingPaid toPay = new ManaCostBeingPaid(realCost, mc.getRestiction()); @@ -879,7 +867,7 @@ public class HumanPlay { } if (!toPay.isPaid()) { // Input is somehow clearing out the offering card? - inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator); + inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator, matrix); inpPayment.setMessagePrefix(prompt); inpPayment.showAndWait(); if (!inpPayment.isPaid()) { diff --git a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java index 02b4bf64ea8..c349a80de42 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java +++ b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java @@ -32,7 +32,6 @@ import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.cost.CostPayment; import forge.game.keyword.KeywordInterface; -import forge.game.mana.ManaConversionService; import forge.game.mana.ManaPool; import forge.game.player.Player; import forge.game.player.PlayerController; @@ -76,7 +75,6 @@ public class HumanPlaySpellAbility { final Card c = ability.getHostCard(); final CardPlayOption option = c.mayPlay(ability.getMayPlay()); - ManaConversionService service = new ManaConversionService(manapool); boolean manaTypeConversion = false; boolean manaColorConversion = false; @@ -118,13 +116,15 @@ public class HumanPlaySpellAbility { ability.resetPaidHash(); } + // TODO Apply this to the SAStackInstance instead of the Player if (manaTypeConversion) { - AbilityUtils.applyManaColorConversion(human, MagicColor.Constant.ANY_TYPE_CONVERSION); + AbilityUtils.applyManaColorConversion(payment, MagicColor.Constant.ANY_TYPE_CONVERSION); } else if (manaColorConversion) { - AbilityUtils.applyManaColorConversion(human, MagicColor.Constant.ANY_COLOR_CONVERSION); + AbilityUtils.applyManaColorConversion(payment, MagicColor.Constant.ANY_COLOR_CONVERSION); } + if (playerManaConversion) { - AbilityUtils.applyManaColorConversion(human, MagicColor.Constant.ANY_COLOR_CONVERSION); + AbilityUtils.applyManaColorConversion(manapool, MagicColor.Constant.ANY_COLOR_CONVERSION); human.incNumManaConversion(); } @@ -142,7 +142,7 @@ public class HumanPlaySpellAbility { } if (keywordColor) { - AbilityUtils.applyManaColorConversion(human, params); + AbilityUtils.applyManaColorConversion(payment, params); } } @@ -167,10 +167,10 @@ public class HumanPlaySpellAbility { } if (manaTypeConversion || manaColorConversion || keywordColor) { - service.restoreColorReplacements(); + manapool.restoreColorReplacements(); } if (playerManaConversion) { - service.restoreColorReplacements(); + manapool.restoreColorReplacements(); human.decNumManaConversion(); } return false; @@ -193,7 +193,7 @@ public class HumanPlaySpellAbility { clearTargets(ability); } if (manaTypeConversion || manaColorConversion || keywordColor) { - service.restoreColorReplacements(); + manapool.restoreColorReplacements(); } } return true; diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index e7d05e729a2..4f12d185493 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -31,6 +31,7 @@ import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.keyword.Keyword; import forge.game.mana.Mana; +import forge.game.mana.ManaConversionMatrix; import forge.game.player.*; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; @@ -1745,8 +1746,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public boolean payManaCost(final ManaCost toPay, final CostPartMana costPartMana, final SpellAbility sa, - final String prompt, final boolean isActivatedSa) { - return HumanPlay.payManaCost(this, toPay, costPartMana, sa, player, prompt, isActivatedSa); + final String prompt, ManaConversionMatrix matrix, final boolean isActivatedSa) { + return HumanPlay.payManaCost(this, toPay, costPartMana, sa, player, prompt, matrix, isActivatedSa); } @Override From f7555d6d2a44cd8ddf00079c0db3d71e803761a4 Mon Sep 17 00:00:00 2001 From: swordshine Date: Wed, 10 Oct 2018 10:08:59 +0800 Subject: [PATCH 11/48] - Fixed Enchanter's Bane --- forge-gui/res/cardsfolder/e/enchanters_bane.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/forge-gui/res/cardsfolder/e/enchanters_bane.txt b/forge-gui/res/cardsfolder/e/enchanters_bane.txt index 2033cd0b195..4ce6a84073c 100644 --- a/forge-gui/res/cardsfolder/e/enchanters_bane.txt +++ b/forge-gui/res/cardsfolder/e/enchanters_bane.txt @@ -1,7 +1,11 @@ Name:Enchanter's Bane ManaCost:1 R Types:Enchantment -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your end step, target enchantment deals damage equal to its converted mana cost to its controller unless that player sacrifices it. -SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | NumDmg$ X | UnlessCost$ Sacrifice | UnlessPayer$ TargetedController | UnlessAI$ WhenPaid | References$ X -SVar:X:Targeted$CardManaCost +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigTarget | TriggerDescription$ At the beginning of your end step, target enchantment deals damage equal to its converted mana cost to its controller unless that player sacrifices it. +SVar:TrigTarget:DB$ Pump | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | IsCurse$ True | ImprintCards$ Targeted | SubAbility$ DBSac +SVar:DBSac:DB$ Sacrifice | Defined$ TargetedController | SacValid$ TargetedCard.Self | Optional$ True | RememberSacrificed$ True | SubAbility$ TrigDamage +SVar:TrigDamage:DB$ DealDamage | NumDmg$ X | Defined$ ImprintedController | DamageSource$ Imprinted | References$ X,Y | ConditionCheckSVar$ Y | ConditionSVarCompare$ EQ0 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True +SVar:Y:Remembered$Amount +SVar:X:Imprinted$CardManaCost Oracle:At the beginning of your end step, target enchantment deals damage equal to its converted mana cost to its controller unless that player sacrifices it. From 2dd4cc839ee80334bc448126134b13cf7f6244bb Mon Sep 17 00:00:00 2001 From: swordshine Date: Wed, 10 Oct 2018 12:21:12 +0800 Subject: [PATCH 12/48] Added Isolated Watchtower --- forge-gui/res/cardsfolder/t/tectonic_edge.txt | 3 ++- .../res/cardsfolder/upcoming/isolated_watchtower.txt | 9 +++++++++ forge-gui/res/cardsfolder/w/weathered_wayfarer.txt | 5 +++-- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt diff --git a/forge-gui/res/cardsfolder/t/tectonic_edge.txt b/forge-gui/res/cardsfolder/t/tectonic_edge.txt index 7e2c2ca78a9..d0a9c80fbfb 100644 --- a/forge-gui/res/cardsfolder/t/tectonic_edge.txt +++ b/forge-gui/res/cardsfolder/t/tectonic_edge.txt @@ -2,7 +2,8 @@ Name:Tectonic Edge ManaCost:no cost Types:Land A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. -A:AB$ Destroy | ValidTgts$ Land.nonBasic | TgtPrompt$ Select target nonbasic land. | Cost$ 1 T Sac<1/CARDNAME> | IsPresent$ Land.OppCtrl | PresentCompare$ GE4 | AILogic$ LandForLand | SpellDescription$ Destroy target nonbasic land. Activate this ability only if an opponent controls four or more lands. +A:AB$ Destroy | ValidTgts$ Land.nonBasic | TgtPrompt$ Select target nonbasic land. | Cost$ 1 T Sac<1/CARDNAME> | CheckSVar$ X | SVarCompare$ GE4 | References$ X | AILogic$ LandForLand | SpellDescription$ Destroy target nonbasic land. Activate this ability only if an opponent controls four or more lands. +SVar:X:PlayerCountOpponents$HighestValid Land.YouCtrl SVar:RemRandomDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/tectonic_edge.jpg Oracle:{T}: Add {C}.\n{1}, {T}, Sacrifice Tectonic Edge: Destroy target nonbasic land. Activate this ability only if an opponent controls four or more lands. diff --git a/forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt b/forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt new file mode 100644 index 00000000000..a4c4749c084 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt @@ -0,0 +1,9 @@ +Name:Isolated Watchtower +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +A:AB$ Scry | Cost$ 2 T | ScryNum$ 1 | SubAbility$ DBReveal | CheckSVar$ X | SVarCompare$ GEY | References$ X,Y | SpellDescription$ Scry 1, then you may reveal the top card of your library. If a basic land card is revealed this way, put it onto the battlefield tapped. Activate this ability only if an opponent controls at least two more lands than you. +SVar:DBReveal:DB$ Dig | Optional$ True | DigNum$ 1 | Reveal$ True | ChangeValid$ Land.Basic | DestinationZone$ Battlefield | Tapped$ True | DestinationZone2$ Library | LibraryPosition2$ 0 +SVar:X:PlayerCountOpponents$HighestValid Land.YouCtrl +SVar:Y:Count$Valid Land.YouCtrl/Plus.2 +Oracle:{T}: Add {C}.\n{2}, {T}: Scry 1, then you may reveal the top card of your library. If a basic land card is revealed this way, put it onto the battlefield tapped. Activate this ability only if an opponent controls at least two more lands than you. diff --git a/forge-gui/res/cardsfolder/w/weathered_wayfarer.txt b/forge-gui/res/cardsfolder/w/weathered_wayfarer.txt index aee88cebe0f..4d06df624fc 100644 --- a/forge-gui/res/cardsfolder/w/weathered_wayfarer.txt +++ b/forge-gui/res/cardsfolder/w/weathered_wayfarer.txt @@ -2,7 +2,8 @@ Name:Weathered Wayfarer ManaCost:W Types:Creature Human Nomad Cleric PT:1/1 -A:AB$ ChangeZone | Cost$ W T | Origin$ Library | Destination$ Hand | ChangeType$ Land | ChangeNum$ 1 | IsPresent$ Land.OppCtrl | PresentCompare$ GTX | References$ X | SpellDescription$ Search your library for a land card, reveal it, put it into your hand, then shuffle your library. Activate this ability only if an opponent controls more lands than you. -SVar:X:Count$Valid Land.YouCtrl +A:AB$ ChangeZone | Cost$ W T | Origin$ Library | Destination$ Hand | ChangeType$ Land | ChangeNum$ 1 | CheckSVar$ X | SVarCompare$ GTY | References$ X,Y | SpellDescription$ Search your library for a land card, reveal it, put it into your hand, then shuffle your library. Activate this ability only if an opponent controls more lands than you. +SVar:X:PlayerCountOpponents$HighestValid Land.YouCtrl +SVar:Y:Count$Valid Land.YouCtrl SVar:Picture:http://resources.wizards.com/magic/cards/9ed/en-us/card83311.jpg Oracle:{W}, {T}: Search your library for a land card, reveal it, put it into your hand, then shuffle your library. Activate this ability only if an opponent controls more lands than you. From 5210ad0a2afb924b84adfb4ff2392e3ddea1d0e9 Mon Sep 17 00:00:00 2001 From: swordshine Date: Wed, 10 Oct 2018 12:27:08 +0800 Subject: [PATCH 13/48] Added Geode Golem --- forge-gui/res/cardsfolder/g/geode_golem .txt | 8 ++++++++ .../cardsfolder/{upcoming => i}/isolated_watchtower.txt | 0 2 files changed, 8 insertions(+) create mode 100644 forge-gui/res/cardsfolder/g/geode_golem .txt rename forge-gui/res/cardsfolder/{upcoming => i}/isolated_watchtower.txt (100%) diff --git a/forge-gui/res/cardsfolder/g/geode_golem .txt b/forge-gui/res/cardsfolder/g/geode_golem .txt new file mode 100644 index 00000000000..81410cd0ff4 --- /dev/null +++ b/forge-gui/res/cardsfolder/g/geode_golem .txt @@ -0,0 +1,8 @@ +Name:Geode Golem +ManaCost:5 +Types:Artifact Creature Golem +PT:5/3 +K:Trample +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigPlay | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may cast your commander from the command zone without paying its mana cost. (You still pay any additional costs.) +SVar:TrigPlay:DB$ Play | Valid$ Card.IsCommander+YouOwn | ValidZone$ Command | WithoutManaCost$ True | Optional$ True +Oracle:Trample\nWhenever Geode Golem deals combat damage to a player, you may cast your commander from the command zone without paying its mana cost. (You still pay any additional costs.) diff --git a/forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt b/forge-gui/res/cardsfolder/i/isolated_watchtower.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/isolated_watchtower.txt rename to forge-gui/res/cardsfolder/i/isolated_watchtower.txt From 5589b4a70bda13f6194e4363bac90368ba707f68 Mon Sep 17 00:00:00 2001 From: swordshine Date: Wed, 10 Oct 2018 18:43:07 +0800 Subject: [PATCH 14/48] - Added some cards --- .../java/forge/game/ability/effects/ManaEffect.java | 2 +- forge-gui/res/cardsfolder/a/azra_bladeseeker.txt | 8 ++++++++ forge-gui/res/cardsfolder/c/cheering_fanatic.txt | 10 ++++++++++ forge-gui/res/cardsfolder/s/sentinel_tower.txt | 7 +++++++ forge-gui/res/cardsfolder/s/stadium_vendors.txt | 9 +++++++++ forge-gui/res/cardsfolder/v/victory_chimes.txt | 2 +- 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/a/azra_bladeseeker.txt create mode 100644 forge-gui/res/cardsfolder/c/cheering_fanatic.txt create mode 100644 forge-gui/res/cardsfolder/s/sentinel_tower.txt create mode 100644 forge-gui/res/cardsfolder/s/stadium_vendors.txt diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java index 5a1b9970375..7c598f302f0 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java @@ -121,7 +121,7 @@ public class ManaEffect extends SpellAbilityEffect { mask |= MagicColor.fromName(colorsNeeded.charAt(nChar)); } colorMenu = mask == 0 ? ColorSet.ALL_COLORS : ColorSet.fromMask(mask); - byte val = act.getController().chooseColor("Select Mana to Produce", sa, colorMenu); + byte val = p.getController().chooseColor("Select Mana to Produce", sa, colorMenu); if (0 == val) { throw new RuntimeException("ManaEffect::resolve() /*any mana*/ - " + act + " color mana choice is empty for " + card.getName()); } diff --git a/forge-gui/res/cardsfolder/a/azra_bladeseeker.txt b/forge-gui/res/cardsfolder/a/azra_bladeseeker.txt new file mode 100644 index 00000000000..e128d0ea276 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/azra_bladeseeker.txt @@ -0,0 +1,8 @@ +Name:Azra Bladeseeker +ManaCost:2 R +Types:Creature Azra Warrior +PT:3/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExploration | TriggerDescription$ When CARDNAME enters the battlefield, each player on your team may discard a card, then each player who discarded a card this way draws a card. +SVar:TrigExploration:DB$ RepeatEach | RepeatPlayers$ Player.YourTeam | RepeatSubAbility$ DBDiscardToDraw +SVar:DBDiscardToDraw:DB$ Draw | Defined$ Player.IsRemembered | UnlessCost$ Discard<1/Card> | UnlessPayer$ Player.IsRemembered | UnlessSwitched$ True +Oracle:When Azra Bladeseeker enters the battlefield, each player on your team may discard a card, then each player who discarded a card this way draws a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/c/cheering_fanatic.txt b/forge-gui/res/cardsfolder/c/cheering_fanatic.txt new file mode 100644 index 00000000000..e3fc1779b3f --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cheering_fanatic.txt @@ -0,0 +1,10 @@ +Name:Cheering Fanatic +ManaCost:1 R +Types:Creature Goblin +PT:2/2 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigNameCard | TriggerDescription$ Whenever CARDNAME attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn. +SVar:TrigNameCard:DB$ NameCard | Defined$ You | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | StaticAbilities$ CFReduceCost +SVar:CFReduceCost:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Card.NamedCard | Type$ Spell | Amount$ 1 | Description$ Spells with the chosen name cost {1} less to cast this turn. +SVar:RemAIDeck:True +Oracle:Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn. diff --git a/forge-gui/res/cardsfolder/s/sentinel_tower.txt b/forge-gui/res/cardsfolder/s/sentinel_tower.txt new file mode 100644 index 00000000000..50f305c32d6 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sentinel_tower.txt @@ -0,0 +1,7 @@ +Name:Sentinel Tower +ManaCost:4 +Types:Artifact +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | Execute$ TrigDmg | TriggerZones$ Battlefield | TriggerDescription$ Whenever an instant or sorcery spell is cast during your turn, CARDNAME deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. +SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X +SVar:X:TriggerObjectsCurrentCastSpells$Valid Sorcery,Instant +Oracle:Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. diff --git a/forge-gui/res/cardsfolder/s/stadium_vendors.txt b/forge-gui/res/cardsfolder/s/stadium_vendors.txt new file mode 100644 index 00000000000..25c391bdac9 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/stadium_vendors.txt @@ -0,0 +1,9 @@ +Name:Stadium Vendors +ManaCost:3 R +Types:Creature Goblin +PT:3/3 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoosePlayer | TriggerDescription$ When CARDNAME enters the battlefield, choose a player. That player adds two mana of any one color they choose. +SVar:TrigChoosePlayer:DB$ ChoosePlayer | Defined$ You | Choices$ Player | ChoiceTitle$ Choose a player | AILogic$ Pump | SubAbility$ DBMana +SVar:DBMana:DB$ Mana | Produced$ Any | Defined$ ChosenPlayer | Amount$ 2 +Oracle:When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose. diff --git a/forge-gui/res/cardsfolder/v/victory_chimes.txt b/forge-gui/res/cardsfolder/v/victory_chimes.txt index 308d832d7cb..f35a0eadea7 100644 --- a/forge-gui/res/cardsfolder/v/victory_chimes.txt +++ b/forge-gui/res/cardsfolder/v/victory_chimes.txt @@ -3,5 +3,5 @@ ManaCost:3 Types:Artifact K:CARDNAME untaps during each other player's untap step. A:AB$ ChoosePlayer | Cost$ T | Defined$ You | Choices$ Player | ChoiceTitle$ Choose an player | SubAbility$ DBMana | SpellDescription$ Choose a player. That player adds one mana of any color they choose. -SVar:DBMana:DB$ Mana | Produced$ Any | Defined$ ChosenPlayer +SVar:DBMana:DB$ Mana | Produced$ C | Defined$ ChosenPlayer Oracle:Untap Victory Chimes during each other player's untap step.\n{T}: A player of your choice adds {C}. From d76aa634c91b328a726aaea49e9179ebb65002ec Mon Sep 17 00:00:00 2001 From: Hanmac Date: Thu, 11 Oct 2018 08:09:48 +0200 Subject: [PATCH 15/48] CloneEffect: now with NewName and GainThisAbility --- .../main/java/forge/game/CardTraitBase.java | 2 +- .../game/ability/effects/CloneEffect.java | 20 +++++++++++++++++++ .../game/replacement/ReplacementHandler.java | 5 +++-- .../forge/game/spellability/SpellAbility.java | 20 +++++++++++++++++++ .../forge/game/trigger/WrappedAbility.java | 12 +++++------ 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index 59c47275a5d..aacc1d389e1 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -62,7 +62,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView { * Keys that should not changed */ private static final ImmutableList noChangeKeys = ImmutableList.builder() - .add("TokenScript", "LegacyImage", "TokenImage").build(); + .add("TokenScript", "LegacyImage", "TokenImage", "NewName").build(); /** * Sets the temporary. * diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index aa0ab0f4215..0dccc07d374 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -113,6 +113,7 @@ public class CloneEffect extends SpellAbilityEffect { } final boolean keepName = sa.hasParam("KeepName"); + final String newName = sa.getParamOrDefault("NewName", null); final String originalName = tgtCard.getName(); final boolean copyingSelf = (tgtCard == cardToCopy); final boolean isTransformed = cardToCopy.getCurrentStateName() == CardStateName.Transformed || cardToCopy.getCurrentStateName() == CardStateName.Meld; @@ -157,9 +158,13 @@ public class CloneEffect extends SpellAbilityEffect { } // restore name if it should be unchanged + // this should only be used for Sakashima the Impostor Avatar if (keepName) { tgtCard.setName(originalName); } + if (newName != null) { + tgtCard.setName(newName); + } // If target is a flip card, also set characteristics of the flipped // state. @@ -168,6 +173,9 @@ public class CloneEffect extends SpellAbilityEffect { if (keepName) { flippedState.setName(originalName); } + if (newName != null) { + tgtCard.setName(newName); + } //keep the Clone card image for the cloned card flippedState.setImageKey(imageFileName); } @@ -350,6 +358,18 @@ public class CloneEffect extends SpellAbilityEffect { tgtCard.setBasePower(4); tgtCard.setBaseToughness(4); } + + if (sa.hasParam("GainThisAbility")) { + SpellAbility root = sa.getRootAbility(); + + if (root.isTrigger() && root.getTrigger() != null) { + tgtCard.addTrigger(root.getTrigger().copy(tgtCard, false)); + } else if (root.isReplacementAbility()) { + tgtCard.addReplacementEffect(root.getReplacementEffect().copy(tgtCard, false)); + } else { + tgtCard.addSpellAbility(root.copy(tgtCard, false)); + } + } } } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index b1843c1850d..f08e0b660a7 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -181,7 +181,7 @@ public class ReplacementHandler { final String effectAbString = host.getSVar(effectSVar); // TODO: the source of replacement effect should be the source of the original effect effectSA = AbilityFactory.getAbility(effectAbString, host); - effectSA.setTrigger(true); + //effectSA.setTrigger(true); SpellAbility tailend = effectSA; do { @@ -209,8 +209,9 @@ public class ReplacementHandler { if (replacementEffect.isIntrinsic()) { effectSA.setIntrinsic(true); effectSA.changeText(); - effectSA.setReplacementAbility(true); } + effectSA.setReplacementAbility(true); + effectSA.setReplacementEffect(replacementEffect); } // Decider gets to choose whether or not to apply the replacement. diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 9eddd745b4a..3e866b91fb1 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -38,7 +38,9 @@ import forge.game.cost.CostRemoveCounter; import forge.game.keyword.Keyword; import forge.game.mana.Mana; import forge.game.player.Player; +import forge.game.replacement.ReplacementEffect; import forge.game.staticability.StaticAbility; +import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.trigger.WrappedAbility; import forge.util.Expressions; @@ -87,8 +89,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private boolean basicSpell = true; private boolean trigger = false; + private Trigger triggerObj = null; private boolean optionalTrigger = false; private boolean replacementAbility = false; + private ReplacementEffect replacementEffect = null; private int sourceTrigger = -1; private List triggerRemembered = Lists.newArrayList(); @@ -913,6 +917,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit trigger = trigger0; } + public Trigger getTrigger() { + return triggerObj; + } + + public void setTrigger(final Trigger t) { + triggerObj = t; + } + public boolean isOptionalTrigger() { return optionalTrigger; } @@ -934,6 +946,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit replacementAbility = replacement; } + public ReplacementEffect getReplacementEffect() { + return replacementEffect; + } + + public void setReplacementEffect(final ReplacementEffect re) { + this.replacementEffect = re; + } + public boolean isMandatory() { return false; } diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index 927895756f3..b59580cd366 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -27,14 +27,13 @@ import com.google.common.collect.Lists; public class WrappedAbility extends Ability { private final SpellAbility sa; - private final Trigger regtrig; private final Player decider; boolean mandatory = false; public WrappedAbility(final Trigger regtrig0, final SpellAbility sa0, final Player decider0) { super(regtrig0.getHostCard(), ManaCost.ZERO, sa0.getView()); - regtrig = regtrig0; + setTrigger(regtrig0); sa = sa0; decider = decider0; sa.setDescription(this.getStackDescription()); @@ -49,10 +48,6 @@ public class WrappedAbility extends Ability { return true; } - public Trigger getTrigger() { - return regtrig; - } - public Player getDecider() { return decider; } @@ -218,6 +213,7 @@ public class WrappedAbility extends Ability { @Override public String getStackDescription() { + final Trigger regtrig = getTrigger(); final StringBuilder sb = new StringBuilder(regtrig.replaceAbilityText(regtrig.toString(true), this)); if (usesTargeting()) { sb.append(" (Targeting "); @@ -445,6 +441,7 @@ public class WrappedAbility extends Ability { @Override public void resolve() { final Game game = sa.getActivatingPlayer().getGame(); + final Trigger regtrig = getTrigger(); Map triggerParams = regtrig.getMapParams(); if (!(regtrig instanceof TriggerAlways) && !triggerParams.containsKey("NoResolvingCheck")) { @@ -476,6 +473,9 @@ public class WrappedAbility extends Ability { return; } + // set Trigger + sa.setTrigger(regtrig); + if (!triggerParams.containsKey("NoTimestampCheck")) { timestampCheck(); } From e665df8af276fcd8560595f0a20d3d873d20bcf8 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Thu, 11 Oct 2018 08:11:26 +0200 Subject: [PATCH 16/48] cards: update Cards with GainThisAbility --- forge-gui/res/cardsfolder/a/artisan_of_forms.txt | 3 +-- forge-gui/res/cardsfolder/c/cemetery_puca.txt | 3 +-- forge-gui/res/cardsfolder/c/cryptoplasm.txt | 3 +-- forge-gui/res/cardsfolder/d/dimir_doppelganger.txt | 3 +-- forge-gui/res/cardsfolder/l/lazav_dimir_mastermind.txt | 7 +++---- forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt | 3 +-- forge-gui/res/cardsfolder/m/mizzium_transreliquat.txt | 3 +-- forge-gui/res/cardsfolder/s/sakashima_the_impostor.txt | 4 ++-- forge-gui/res/cardsfolder/t/thespians_stage.txt | 3 +-- forge-gui/res/cardsfolder/u/unstable_shapeshifter.txt | 3 +-- forge-gui/res/cardsfolder/v/vesuvan_doppelganger.txt | 2 +- 11 files changed, 14 insertions(+), 23 deletions(-) diff --git a/forge-gui/res/cardsfolder/a/artisan_of_forms.txt b/forge-gui/res/cardsfolder/a/artisan_of_forms.txt index 2f6cc398319..dd18a306a46 100644 --- a/forge-gui/res/cardsfolder/a/artisan_of_forms.txt +++ b/forge-gui/res/cardsfolder/a/artisan_of_forms.txt @@ -3,8 +3,7 @@ ManaCost:1 U Types:Creature Human Wizard PT:1/1 T:Mode$ SpellCast | ValidActivatingPlayer$ You | TargetsValid$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigArtisanCopy | TriggerDescription$ Heroic — Whenever you cast a spell that targets CARDNAME, you may have CARDNAME become a copy of target creature and gain this ability. -SVar:TrigArtisanCopy:DB$ Clone | ValidTgts$ Creature | TgtPrompt$ Select target creature to copy | Optional$ True | AddTriggers$ ArtisanHeroicTrig | AddSVars$ TrigArtisanCopy,ArtisanHeroicTrig -SVar:ArtisanHeroicTrig:Mode$ SpellCast | ValidActivatingPlayer$ You | TargetsValid$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigArtisanCopy | TriggerDescription$ Heroic — Whenever you cast a spell that targets CARDNAME, you may have CARDNAME become a copy of target creature and gain this ability. +SVar:TrigArtisanCopy:DB$ Clone | ValidTgts$ Creature | TgtPrompt$ Select target creature to copy | Optional$ True | GainThisAbility$ True SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/artisan_of_forms.jpg Oracle:Heroic — Whenever you cast a spell that targets Artisan of Forms, you may have Artisan of Forms become a copy of target creature and gain this ability. diff --git a/forge-gui/res/cardsfolder/c/cemetery_puca.txt b/forge-gui/res/cardsfolder/c/cemetery_puca.txt index 4d7ca05cb20..32881d40dc6 100644 --- a/forge-gui/res/cardsfolder/c/cemetery_puca.txt +++ b/forge-gui/res/cardsfolder/c/cemetery_puca.txt @@ -4,8 +4,7 @@ Types:Creature Shapeshifter PT:1/2 # Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature | TriggerZones$ Battlefield | Execute$ CemeteryPucaCopy | TriggerDescription$ Whenever a creature dies, you may pay {1}. If you do, CARDNAME becomes a copy of that creature and gains this ability. -SVar:CemeteryPucaCopy:AB$ Clone | Cost$ 1 | Defined$ TriggeredCardLKICopy | AddTriggers$ CemeteryPucaDiesTrig | AddSVars$ CemeteryPucaCopy,CemeteryPucaDiesTrig -SVar:CemeteryPucaDiesTrig:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature | TriggerZones$ Battlefield | Execute$ CemeteryPucaCopy | TriggerDescription$ Whenever a creature dies, you may pay {1}. If you do, CARDNAME becomes a copy of that creature and gains this ability. +SVar:CemeteryPucaCopy:AB$ Clone | Cost$ 1 | Defined$ TriggeredCardLKICopy | GainThisAbility$ True SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/cemetery_puca.jpg Oracle:Whenever a creature dies, you may pay {1}. If you do, Cemetery Puca becomes a copy of that creature and gains this ability. diff --git a/forge-gui/res/cardsfolder/c/cryptoplasm.txt b/forge-gui/res/cardsfolder/c/cryptoplasm.txt index 914174829f3..48335f9a6f7 100644 --- a/forge-gui/res/cardsfolder/c/cryptoplasm.txt +++ b/forge-gui/res/cardsfolder/c/cryptoplasm.txt @@ -4,8 +4,7 @@ Types:Creature Shapeshifter PT:2/2 # Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ CryptoplasmCopy | OptionalDecider$ You | TriggerDescription$ At the beginning of your upkeep, you may have CARDNAME become a copy of another target creature. If you do, CARDNAME gains this ability. -SVar:CryptoplasmCopy:DB$ Clone | ValidTgts$ Creature.Other | TgtPrompt$ Select another target creature to copy. | Optional$ True | AddTriggers$ CryptoplasmUpkeepTrig | AddSVars$ CryptoplasmCopy,CryptoplasmUpkeepTrig -SVar:CryptoplasmUpkeepTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ CryptoplasmCopy | TriggerDescription$ At the beginning of your upkeep, you may have CARDNAME become a copy of another target creature. If you do, CARDNAME gains this ability. +SVar:CryptoplasmCopy:DB$ Clone | ValidTgts$ Creature.Other | TgtPrompt$ Select another target creature to copy. | Optional$ True | GainThisAbility$ True SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/cryptoplasm.jpg Oracle:At the beginning of your upkeep, you may have Cryptoplasm become a copy of another target creature. If you do, Cryptoplasm gains this ability. diff --git a/forge-gui/res/cardsfolder/d/dimir_doppelganger.txt b/forge-gui/res/cardsfolder/d/dimir_doppelganger.txt index c8b7f3799a0..f12f300c4ba 100644 --- a/forge-gui/res/cardsfolder/d/dimir_doppelganger.txt +++ b/forge-gui/res/cardsfolder/d/dimir_doppelganger.txt @@ -4,8 +4,7 @@ Types:Creature Shapeshifter PT:0/2 # Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone A:AB$ ChangeZone | Cost$ 1 U B | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature | RememberTargets$ True | ForgetOtherTargets$ True | SubAbility$ DDCopy | SpellDescription$ Exile target creature card from a graveyard. CARDNAME becomes a copy of that card and gains this ability. -SVar:DDCopy:DB$ Clone | Defined$ Remembered | AddAbilities$ DDAbility | AddSVars$ DDAbility,DDCopy -SVar:DDAbility:AB$ ChangeZone | Cost$ 1 U B | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature | RememberTargets$ True | ForgetOtherTargets$ True | SubAbility$ DDCopy | SpellDescription$ Exile target creature card from a graveyard. CARDNAME becomes a copy of that card and gains this ability. +SVar:DDCopy:DB$ Clone | Defined$ Remembered | GainThisAbility$ True SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/dimir_doppelganger.jpg Oracle:{1}{U}{B}: Exile target creature card from a graveyard. Dimir Doppelganger becomes a copy of that card and gains this ability. diff --git a/forge-gui/res/cardsfolder/l/lazav_dimir_mastermind.txt b/forge-gui/res/cardsfolder/l/lazav_dimir_mastermind.txt index 547047a35a0..a0bc6751f89 100644 --- a/forge-gui/res/cardsfolder/l/lazav_dimir_mastermind.txt +++ b/forge-gui/res/cardsfolder/l/lazav_dimir_mastermind.txt @@ -3,9 +3,8 @@ ManaCost:U U B B Types:Legendary Creature Shapeshifter PT:3/3 K:Hexproof -T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.nonToken+OppOwn | TriggerZones$ Battlefield | Execute$ LazavCopy | OptionalDecider$ You | TriggerDescription$ Whenever a creature card is put into an opponent's graveyard from anywhere, you may have CARDNAME become a copy of that card except it's name is still CARDNAME, it's legendary in addition to it's other types, and it gains hexproof and this ability. -SVar:LazavCopy:DB$ Clone | Defined$ TriggeredCard | KeepName$ True | AddTypes$ Legendary | AddTriggers$ LazavTrig | AddKeywords$ Hexproof | AddSVars$ LazavCopy,LazavTrig -SVar:LazavTrig:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.OppOwn | TriggerZones$ Battlefield | Execute$ LazavCopy | OptionalDecider$ You | TriggerDescription$ Whenever a creature card is put into an opponent's graveyard from anywhere, you may have CARDNAME become a copy of that card except it's name is still CARDNAME, it's legendary in addition to it's other types, and it gains hexproof and this ability. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Creature.nonToken+OppOwn | TriggerZones$ Battlefield | Execute$ LazavCopy | OptionalDecider$ You | TriggerDescription$ Whenever a creature card is put into an opponent’s graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card, except its name is Lazav, Dimir Mastermind, it’s legendary in addition to its other types, and it has hexproof and this ability. +SVar:LazavCopy:DB$ Clone | Defined$ TriggeredCard | NewName$ Lazav, Dimir Mastermind | AddTypes$ Legendary | AddKeywords$ Hexproof | GainThisAbility$ True SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/lazav_dimir_mastermind.jpg -Oracle:Hexproof\nWhenever a creature card is put into an opponent's graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card except its name is still Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it gains hexproof and this ability. +Oracle:Hexproof\nWhenever a creature card is put into an opponent’s graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card, except its name is Lazav, Dimir Mastermind, it’s legendary in addition to its other types, and it has hexproof and this ability. diff --git a/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt b/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt index e8f35ff5bfa..57ab5d3a9fa 100644 --- a/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt +++ b/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt @@ -4,7 +4,6 @@ Types:Legendary Creature Shapeshifter PT:1/3 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters the battlefield, scry 1. (To scry 1, look at the top card of your library. You may put that card into your graveyard.) SVar:TrigSurveil:DB$ Surveil | Amount$ 1 -A:AB$ Clone | Cost$ X | ValidTgts$ Creature.YouOwn | References$ X | TgtZone$ Graveyard | TgtPrompt$ Select target creature card in your graveyard | AddTypes$ Legendary | KeepName$ True | AddSVars$ X,LazavTrig | AddAbilities$ LazavTrig | SpellDescription$ CARDNAME becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is CARDNAME, it's legendary in addition to it's other types, and it has this ability. -SVar:LazavTrig:AB$ Clone | Cost$ X | ValidTgts$ Creature.YouOwn | References$ X | TgtZone$ Graveyard | TgtPrompt$ Select target creature card in your graveyard | AddTypes$ Legendary | KeepName$ True | AddSVars$ X,LazavTrig | AddAbilities$ LazavTrig | SpellDescription$ CARDNAME becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is CARDNAME, it's legendary in addition to it's other types, and it has this ability. +A:AB$ Clone | Cost$ X | ValidTgts$ Creature.YouOwn | References$ X | TgtZone$ Graveyard | TgtPrompt$ Select target creature card in your graveyard | AddTypes$ Legendary | NewName$ Lazav, the Multifarious | GainThisAbility$ True | SpellDescription$ CARDNAME becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is CARDNAME, it's legendary in addition to it's other types, and it has this ability. SVar:X:Targeted$CardManaCost Oracle:When Lazav, the Multifarious enters the battlefield, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.)\n{X}: Lazav, the Multifarious becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is Lazav, the Multifarious, it's legendary in addition to its other types, and it has this ability. diff --git a/forge-gui/res/cardsfolder/m/mizzium_transreliquat.txt b/forge-gui/res/cardsfolder/m/mizzium_transreliquat.txt index 0888a589650..6799f7d0476 100644 --- a/forge-gui/res/cardsfolder/m/mizzium_transreliquat.txt +++ b/forge-gui/res/cardsfolder/m/mizzium_transreliquat.txt @@ -2,8 +2,7 @@ Name:Mizzium Transreliquat ManaCost:3 Types:Artifact A:AB$ Clone | Cost$ 3 | ValidTgts$ Artifact | TgtPrompt$ Select target artifact to copy until end of turn. | Duration$ UntilEndOfTurn | SpellDescription$ CARDNAME becomes a copy of target artifact until end of turn. -A:AB$ Clone | Cost$ 1 U R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact to copy. | AddAbilities$ MizzCopy | AddSVars$ MizzCopy | SpellDescription$ CARDNAME becomes a copy of target artifact and gains this ability. -SVar:MizzCopy:AB$ Clone | Cost$ 1 U R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact to copy. | AddAbilities$ MizzCopy | AddSVars$ MizzCopy | SpellDescription$ CARDNAME becomes a copy of target artifact and gains this ability. +A:AB$ Clone | Cost$ 1 U R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact to copy. | GainThisAbility$ True | SpellDescription$ CARDNAME becomes a copy of target artifact and gains this ability. SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/mizzium_transreliquat.jpg Oracle:{3}: Mizzium Transreliquat becomes a copy of target artifact until end of turn.\n{1}{U}{R}: Mizzium Transreliquat becomes a copy of target artifact and gains this ability. diff --git a/forge-gui/res/cardsfolder/s/sakashima_the_impostor.txt b/forge-gui/res/cardsfolder/s/sakashima_the_impostor.txt index db012d45c58..e9bdc7f16f1 100644 --- a/forge-gui/res/cardsfolder/s/sakashima_the_impostor.txt +++ b/forge-gui/res/cardsfolder/s/sakashima_the_impostor.txt @@ -4,8 +4,8 @@ Types:Legendary Creature Human Rogue PT:3/1 # Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone K:ETBReplacement:Copy:DBCopy:Optional -SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | KeepName$ True | AddTypes$ Legendary | AddAbilities$ ReturnSakashima | AddSVars$ TrigReturnSak | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except its name is still CARDNAME, it's legendary in addition to its other types, and it gains "{2}{U}{U}: Return CARDNAME to its owner's hand at the beginning of the next end step." +SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | NewName$ Sakashima the Impostor | AddTypes$ Legendary | AddAbilities$ ReturnSakashima | AddSVars$ TrigReturnSak | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except its name is Sakashima the Impostor, it’s legendary in addition to its other types, and it has “{2}{U}{U}: Return this creature to its owner’s hand at the beginning of the next end step.” SVar:ReturnSakashima:AB$ DelayedTrigger | Cost$ 2 U U | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturnSak | SpellDescription$ Return CARDNAME to it's owners hand at the beginning of the next end step. SVar:TrigReturnSak:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Hand SVar:Picture:http://www.wizards.com/global/images/magic/general/sakashima_the_impostor.jpg -Oracle:You may have Sakashima the Impostor enter the battlefield as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains "{2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step." +Oracle:You may have Sakashima the Impostor enter the battlefield as a copy of any creature on the battlefield, except its name is Sakashima the Impostor, it’s legendary in addition to its other types, and it has “{2}{U}{U}: Return this creature to its owner’s hand at the beginning of the next end step.” diff --git a/forge-gui/res/cardsfolder/t/thespians_stage.txt b/forge-gui/res/cardsfolder/t/thespians_stage.txt index e6673ff8a1d..2a2b3db4896 100644 --- a/forge-gui/res/cardsfolder/t/thespians_stage.txt +++ b/forge-gui/res/cardsfolder/t/thespians_stage.txt @@ -2,8 +2,7 @@ Name:Thespian's Stage ManaCost:no cost Types:Land A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. -A:AB$ Clone | Cost$ 2 T | ValidTgts$ Land | TgtPrompt$ Select target land to copy. | AddAbilities$ ThespianCopy | AddSVars$ ThespianCopy | SpellDescription$ CARDNAME becomes a copy of target land and gains this ability. -SVar:ThespianCopy:AB$ Clone | Cost$ 2 T | ValidTgts$ Land | TgtPrompt$ Select target land to copy. | AddAbilities$ ThespianCopy | AddSVars$ ThespianCopy | SpellDescription$ CARDNAME becomes a copy of target land and gains this ability. +A:AB$ Clone | Cost$ 2 T | ValidTgts$ Land | TgtPrompt$ Select target land to copy. | GainThisAbility$ True | SpellDescription$ CARDNAME becomes a copy of target land and gains this ability. SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/thespians_stage.jpg Oracle:{T}: Add {C}.\n{2}, {T}: Thespian's Stage becomes a copy of target land and gains this ability. diff --git a/forge-gui/res/cardsfolder/u/unstable_shapeshifter.txt b/forge-gui/res/cardsfolder/u/unstable_shapeshifter.txt index af412f12b6b..f78b867c0e5 100644 --- a/forge-gui/res/cardsfolder/u/unstable_shapeshifter.txt +++ b/forge-gui/res/cardsfolder/u/unstable_shapeshifter.txt @@ -4,7 +4,6 @@ Types:Creature Shapeshifter PT:0/1 # Make SVars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ USCopy | TriggerDescription$ Whenever another creature enters the battlefield, CARDNAME becomes a copy of that creature and gains this ability. -SVar:USCopy:DB$ Clone | Defined$ TriggeredCard | AddTriggers$ USTrig | AddSVars$ USCopy,USTrig -SVar:USTrig:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ USCopy | TriggerDescription$ Whenever another creature enters the battlefield, CARDNAME becomes a copy of that creature and gains this ability. +SVar:USCopy:DB$ Clone | Defined$ TriggeredCard | GainThisAbility$ True SVar:Picture:http://www.wizards.com/global/images/magic/general/unstable_shapeshifter.jpg Oracle:Whenever another creature enters the battlefield, Unstable Shapeshifter becomes a copy of that creature and gains this ability. diff --git a/forge-gui/res/cardsfolder/v/vesuvan_doppelganger.txt b/forge-gui/res/cardsfolder/v/vesuvan_doppelganger.txt index 2b6a6aba2b3..5412e1a6616 100644 --- a/forge-gui/res/cardsfolder/v/vesuvan_doppelganger.txt +++ b/forge-gui/res/cardsfolder/v/vesuvan_doppelganger.txt @@ -7,7 +7,7 @@ K:ETBReplacement:Copy:ChooseCreature:Optional SVar:ChooseCreature:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.Other | SubAbility$ DBCopy | RememberChosen$ True | AILogic$ Clone | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability." SVar:DBCopy:DB$ Clone | Defined$ Remembered | Colors$ Blue | OverwriteColors$ True | AddTriggers$ VesDopUpkeepTrig | AddSVars$ VesDopCopy,VesDopUpkeepTrig SVar:VesDopUpkeepTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ VesDopCopy | TriggerDescription$ At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability. -SVar:VesDopCopy:DB$ Clone | ValidTgts$ Creature | TgtPrompt$ Select target creature to copy. | Optional$ True | Colors$ Blue | OverwriteColors$ True | AddTriggers$ VesDopUpkeepTrig | AddSVars$ VesDopCopy,VesDopUpkeepTrig | SubAbility$ DBCleanup +SVar:VesDopCopy:DB$ Clone | ValidTgts$ Creature | TgtPrompt$ Select target creature to copy. | Optional$ True | Colors$ Blue | OverwriteColors$ True | GainThisAbility$ True | SubAbility$ DBCleanup SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/vesuvan_doppelganger.jpg Oracle:You may have Vesuvan Doppelganger enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability." From 3e4dfb3bc262b2bba356e805420976addd653d1d Mon Sep 17 00:00:00 2001 From: swordshine Date: Thu, 11 Oct 2018 16:41:41 +0800 Subject: [PATCH 17/48] - Updated Genesis Storm --- .../game/ability/effects/DigUntilEffect.java | 20 ++++++++++++------- forge-gui/res/cardsfolder/g/genesis_storm.txt | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java index 5615f70b2de..46935002a90 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java @@ -105,6 +105,7 @@ public class DigUntilEffect extends SpellAbilityEffect { final ZoneType digSite = sa.hasParam("DigZone") ? ZoneType.smartValueOf(sa.getParam("DigZone")) : ZoneType.Library; boolean shuffle = sa.hasParam("Shuffle"); final boolean optional = sa.hasParam("Optional"); + final boolean optionalFound = sa.hasParam("OptionalFoundMove"); for (final Player p : getTargetPlayers(sa)) { if (p == null) { @@ -156,15 +157,20 @@ public class DigUntilEffect extends SpellAbilityEffect { final Iterator itr = found.iterator(); while (itr.hasNext()) { final Card c = itr.next(); - if (sa.hasParam("GainControl") && foundDest.equals(ZoneType.Battlefield)) { - c.setController(sa.getActivatingPlayer(), game.getNextTimestamp()); - game.getAction().moveTo(c.getController().getZone(foundDest), c, sa); - } else if (sa.hasParam("NoMoveFound") && foundDest.equals(ZoneType.Library)) { - //Don't do anything + if (optionalFound && !p.getController().confirmAction(sa, null, + "Do you want to put that card to " + foundDest.name() + "?")) { + continue; } else { - game.getAction().moveTo(foundDest, c, foundLibPos, sa); + if (sa.hasParam("GainControl") && foundDest.equals(ZoneType.Battlefield)) { + c.setController(sa.getActivatingPlayer(), game.getNextTimestamp()); + game.getAction().moveTo(c.getController().getZone(foundDest), c, sa); + } else if (sa.hasParam("NoMoveFound") && foundDest.equals(ZoneType.Library)) { + //Don't do anything + } else { + game.getAction().moveTo(foundDest, c, foundLibPos, sa); + } + revealed.remove(c); } - revealed.remove(c); } } diff --git a/forge-gui/res/cardsfolder/g/genesis_storm.txt b/forge-gui/res/cardsfolder/g/genesis_storm.txt index 46632f96e5e..ed19640f1f0 100644 --- a/forge-gui/res/cardsfolder/g/genesis_storm.txt +++ b/forge-gui/res/cardsfolder/g/genesis_storm.txt @@ -4,5 +4,5 @@ Types:Sorcery T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigCopy | TriggerDescription$ When you cast this spell, copy it for each time you've cast your commander from the command zone this game. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ X | References$ X SVar:X:Count$TotalCommanderCastFromCommandZone -A:SP$ DigUntil | Cost$ 4 G G | Valid$ Permanent.nonland | ValidDescription$ nonland permanent | FoundDestination$ Battlefield | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | RevealRandomOrder$ True | SpellDescription$ Reveal cards from the top of your library until you reveal a nonland permanent card. You may put that card onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield on the bottom of your library in a random order. +A:SP$ DigUntil | Cost$ 4 G G | Valid$ Permanent.nonland | ValidDescription$ nonland permanent | FoundDestination$ Battlefield | OptionalFoundMove$ True | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | RevealRandomOrder$ True | SpellDescription$ Reveal cards from the top of your library until you reveal a nonland permanent card. You may put that card onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield on the bottom of your library in a random order. Oracle:When you cast this spell, copy it for each time you've cast your commander from the command zone this game. You may choose new targets for the copies.\nReveal cards from the top of your library until you reveal a nonland permanent card. You may put that card onto the battlefield. Then put all cards revealed this way that weren't put onto the battlefield on the bottom of your library in a random order. From 7fd775d5c75975f65d5b6eabe2b366131c5198ba Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 12 Oct 2018 08:50:41 +0300 Subject: [PATCH 18/48] - Added AI draft deck hints for Guilds of Ravnica. --- forge-gui/res/cardsfolder/a/arclight_phoenix.txt | 1 + forge-gui/res/cardsfolder/a/assure_assemble.txt | 3 ++- forge-gui/res/cardsfolder/a/attendant_of_vraska.txt | 1 + forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt | 1 + forge-gui/res/cardsfolder/b/barging_sergeant.txt | 1 + forge-gui/res/cardsfolder/b/barrier_of_bones.txt | 1 + forge-gui/res/cardsfolder/b/beacon_bolt.txt | 1 + forge-gui/res/cardsfolder/b/beamsplitter_mage.txt | 1 + forge-gui/res/cardsfolder/b/blade_instructor.txt | 1 + forge-gui/res/cardsfolder/b/boros_challenger.txt | 1 + forge-gui/res/cardsfolder/c/chamber_sentry.txt | 1 + forge-gui/res/cardsfolder/c/charnel_troll.txt | 2 ++ forge-gui/res/cardsfolder/c/citywatch_sphinx.txt | 1 + forge-gui/res/cardsfolder/c/connive_concoct.txt | 1 + forge-gui/res/cardsfolder/c/crackling_drake.txt | 1 + forge-gui/res/cardsfolder/d/darkblade_agent.txt | 1 + forge-gui/res/cardsfolder/d/dazzling_lights.txt | 1 + forge-gui/res/cardsfolder/d/deadly_visit.txt | 1 + forge-gui/res/cardsfolder/d/dimir_informant.txt | 1 + forge-gui/res/cardsfolder/d/dimir_spybug.txt | 2 ++ forge-gui/res/cardsfolder/d/discovery_dispersal.txt | 1 + forge-gui/res/cardsfolder/d/disinformation_campaign.txt | 1 + forge-gui/res/cardsfolder/d/doom_whisperer.txt | 1 + forge-gui/res/cardsfolder/d/dream_eater.txt | 1 + forge-gui/res/cardsfolder/d/drowned_secrets.txt | 1 + forge-gui/res/cardsfolder/e/electrostatic_field.txt | 1 + forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt | 1 + forge-gui/res/cardsfolder/e/enhanced_surveillance.txt | 1 + forge-gui/res/cardsfolder/e/erratic_cyclops.txt | 1 + forge-gui/res/cardsfolder/f/find_finality.txt | 1 + forge-gui/res/cardsfolder/f/fire_urchin.txt | 1 + forge-gui/res/cardsfolder/f/fireminds_research.txt | 1 + forge-gui/res/cardsfolder/g/gird_for_battle.txt | 1 + forge-gui/res/cardsfolder/g/glowspore_shaman.txt | 1 + forge-gui/res/cardsfolder/g/goblin_banneret.txt | 1 + forge-gui/res/cardsfolder/g/golgari_raiders.txt | 1 + forge-gui/res/cardsfolder/g/gruesome_menagerie.txt | 1 + forge-gui/res/cardsfolder/g/guildmages_forum.txt | 1 + forge-gui/res/cardsfolder/h/haazda_marshal.txt | 1 + forge-gui/res/cardsfolder/h/hammer_dropper.txt | 1 + forge-gui/res/cardsfolder/h/house_guildmage.txt | 1 + forge-gui/res/cardsfolder/i/invert_invent.txt | 1 + forge-gui/res/cardsfolder/i/ironshell_beetle.txt | 1 + forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt | 1 + forge-gui/res/cardsfolder/k/knight_of_autumn.txt | 1 + forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt | 1 + forge-gui/res/cardsfolder/l/league_guildmage.txt | 1 + forge-gui/res/cardsfolder/l/leapfrog.txt | 1 + forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt | 1 + forge-gui/res/cardsfolder/m/mephitic_vapors.txt | 1 + forge-gui/res/cardsfolder/m/mission_briefing.txt | 1 + forge-gui/res/cardsfolder/m/murmuring_mystic.txt | 2 ++ forge-gui/res/cardsfolder/n/nightveil_sprite.txt | 1 + forge-gui/res/cardsfolder/n/niv_mizzet_parun.txt | 1 + forge-gui/res/cardsfolder/n/notion_rain.txt | 1 + forge-gui/res/cardsfolder/p/parhelion_patrol.txt | 1 + forge-gui/res/cardsfolder/p/pelt_collector.txt | 1 + forge-gui/res/cardsfolder/p/piston_fist_cyclops.txt | 1 + forge-gui/res/cardsfolder/p/price_of_fame.txt | 1 + forge-gui/res/cardsfolder/r/ral_izzet_viceroy.txt | 2 ++ forge-gui/res/cardsfolder/r/rals_staticaster.txt | 1 + forge-gui/res/cardsfolder/r/rampaging_monument.txt | 1 + forge-gui/res/cardsfolder/r/rhizome_lurcher.txt | 1 + forge-gui/res/cardsfolder/r/runaway_steam_kin.txt | 1 + forge-gui/res/cardsfolder/s/sinister_sabotage.txt | 1 + forge-gui/res/cardsfolder/s/smelt_ward_minotaur.txt | 2 +- forge-gui/res/cardsfolder/s/sprouting_renewal.txt | 1 + forge-gui/res/cardsfolder/s/sunhome_stalwart.txt | 1 + forge-gui/res/cardsfolder/t/tajic_legions_edge.txt | 1 + forge-gui/res/cardsfolder/t/thought_erasure.txt | 1 + forge-gui/res/cardsfolder/t/thoughtbound_phantasm.txt | 2 ++ forge-gui/res/cardsfolder/t/thousand_year_storm.txt | 1 + forge-gui/res/cardsfolder/t/trostani_discordant.txt | 1 + forge-gui/res/cardsfolder/t/truefire_captain.txt | 1 + forge-gui/res/cardsfolder/u/unexplained_disappearance.txt | 1 + forge-gui/res/cardsfolder/v/venerated_loxodon.txt | 1 + forge-gui/res/cardsfolder/v/vraska_regal_gorgon.txt | 1 + forge-gui/res/cardsfolder/w/wand_of_vertebrae.txt | 1 + forge-gui/res/cardsfolder/w/watcher_in_the_mist.txt | 1 + forge-gui/res/cardsfolder/w/wee_dragonauts.txt | 1 + forge-gui/res/cardsfolder/w/whisper_agent.txt | 1 + forge-gui/res/cardsfolder/w/whispering_snitch.txt | 1 + forge-gui/res/cardsfolder/w/wojek_bodyguard.txt | 1 + forge-gui/res/cardsfolder/w/worldsoul_colossus.txt | 1 + 84 files changed, 90 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/a/arclight_phoenix.txt b/forge-gui/res/cardsfolder/a/arclight_phoenix.txt index f5ea5df6ed9..026a1c61c69 100644 --- a/forge-gui/res/cardsfolder/a/arclight_phoenix.txt +++ b/forge-gui/res/cardsfolder/a/arclight_phoenix.txt @@ -7,4 +7,5 @@ K:Haste T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Graveyard | CheckSVar$ X | SVarCompare$ GE3 | Execute$ TrigReturn | OptionalDecider$ You | TriggerDescription$ At the beginning of combat on your turn, if you've cast three or more instant and sorcery spells this turn, you may return CARDNAME from your graveyard to the battlefield. SVar:TrigReturn:DB$ ChangeZone | Defined$ Self | Origin$ Graveyard | Destination$ Battlefield SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl +DeckNeeds:Type$Instant|Sorcery Oracle:Flying, Haste\nAt the beginning of combat on your turn, if you've cast three or more instant and sorcery spells this turn, you may return Arclight Phoenix from your graveyard to the battlefield. diff --git a/forge-gui/res/cardsfolder/a/assure_assemble.txt b/forge-gui/res/cardsfolder/a/assure_assemble.txt index eb67e2204a3..092e54f9cc1 100644 --- a/forge-gui/res/cardsfolder/a/assure_assemble.txt +++ b/forge-gui/res/cardsfolder/a/assure_assemble.txt @@ -4,6 +4,7 @@ Types:Instant AlternateMode:Split A:SP$ PutCounter | Cost$ G/W G/W | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature. It gains indestructible until end of turn. SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Indestructible +DeckHas:Ability$Counters & Ability$Token Oracle:Put a +1/+1 counter on target creature. It gains indestructible until end of turn. ALTERNATE @@ -12,5 +13,5 @@ Name:Assemble ManaCost:4 G W Types:Instant A:SP$ Token | Cost$ 4 G W | TokenAmount$ 3 | TokenScript$ wg_2_2_elf_knight_vigilance | SpellDescription$ Create three 2/2 green and white Elf Knight creature tokens with vigilance. -DeckHas:Ability$Token +DeckHas:Ability$Counters & Ability$Token Oracle:Create three 2/2 green and white Elf Knight creature tokens with vigilance. diff --git a/forge-gui/res/cardsfolder/a/attendant_of_vraska.txt b/forge-gui/res/cardsfolder/a/attendant_of_vraska.txt index d31ef72a28f..f02fdcd7d51 100644 --- a/forge-gui/res/cardsfolder/a/attendant_of_vraska.txt +++ b/forge-gui/res/cardsfolder/a/attendant_of_vraska.txt @@ -5,4 +5,5 @@ PT:3/3 T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | IsPresent$ Planeswalker.Vraska+YouCtrl | Execute$ TrigGainLife | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, if you control a Vraska planeswalker, you gain life equal to CARDNAME's power. SVar:TrigGainLife:DB$GainLife | Defined$ You | LifeAmount$ X | References$ X SVar:X:TriggeredCard$CardPower +DeckNeeds:Type$Vraska Oracle:When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power. diff --git a/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt b/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt index 5920bd231d3..b2a20a416f1 100644 --- a/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt +++ b/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt @@ -9,4 +9,5 @@ SVar:DBPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | RememberTargets SVar:DBPump1:DB$Pump | Defined$ Remembered | KW$ Trample | ConditionDefined$ Remembered | ConditionPresent$ Card.Red | SubAbility$ DBPump2 SVar:DBPump2:DB$Pump | Defined$ Remembered | KW$ Vigilance | ConditionDefined$ Remembered | ConditionPresent$ Card.White | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Counters Oracle:Flying\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\nAt the beginning of combat on your turn, choose up to one target creature you control. Until end of turn, that creature gets +2/+0, gains trample if it's red, and gains vigilance if it's white. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/b/barging_sergeant.txt b/forge-gui/res/cardsfolder/b/barging_sergeant.txt index e0e24d93c6f..595eb1697f0 100644 --- a/forge-gui/res/cardsfolder/b/barging_sergeant.txt +++ b/forge-gui/res/cardsfolder/b/barging_sergeant.txt @@ -4,4 +4,5 @@ Types:Creature Minotaur Soldier PT:4/2 K:Haste K:Mentor +DeckHas:Ability$Counters Oracle:Haste\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.) diff --git a/forge-gui/res/cardsfolder/b/barrier_of_bones.txt b/forge-gui/res/cardsfolder/b/barrier_of_bones.txt index 4c092100c9f..ae3c126b121 100644 --- a/forge-gui/res/cardsfolder/b/barrier_of_bones.txt +++ b/forge-gui/res/cardsfolder/b/barrier_of_bones.txt @@ -5,4 +5,5 @@ PT:0/3 K:Defender T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters the battlefield, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Defender\nWhen Barrier of Bones enters the battlefield, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) diff --git a/forge-gui/res/cardsfolder/b/beacon_bolt.txt b/forge-gui/res/cardsfolder/b/beacon_bolt.txt index 76ebddf053b..52b23157897 100644 --- a/forge-gui/res/cardsfolder/b/beacon_bolt.txt +++ b/forge-gui/res/cardsfolder/b/beacon_bolt.txt @@ -5,4 +5,5 @@ K:Jump-start A:SP$ DealDamage | Cost$ 1 U R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | References$ X,Y | SpellDescription$ CARDNAME deals damage to target creature equal to the total number of instant and sorcery cards you own in exile and in your graveyard. SVar:X:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn/Plus.Y SVar:Y:Count$ValidExile Instant.YouOwn,Sorcery.YouOwn +DeckHints:Type$Instant|Sorcery Oracle:Beacon Bolt deals damage to target creature equal to the total number of instant and sorcery cards you own in exile and in your graveyard.\nJump-start (You may cast this card from your graveyard by discarding a card in addition to paying its other costs. Then exile this card.) diff --git a/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt b/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt index 66f2bc8fe77..a83584e2a6c 100644 --- a/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt +++ b/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt @@ -4,4 +4,5 @@ Types:Creature Vedalken Wizard PT:2/2 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | IsSingleTarget$ True | TargetsValid$ Card.Self | CanTargetOtherCondition$ Creature.YouCtrl | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery that targets only CARDNAME, if you control one or more other creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Controller$ You | CopyForEachCanTarget$ Creature.YouCtrl | ChooseOnlyOne$ True +DeckHints:Ability$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell that targets only Beamsplitter Mage, if you control one or more other creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature. diff --git a/forge-gui/res/cardsfolder/b/blade_instructor.txt b/forge-gui/res/cardsfolder/b/blade_instructor.txt index a8969b6e857..dc0478e63b6 100644 --- a/forge-gui/res/cardsfolder/b/blade_instructor.txt +++ b/forge-gui/res/cardsfolder/b/blade_instructor.txt @@ -3,4 +3,5 @@ ManaCost:2 W Types:Creature Human Soldier PT:3/1 K:Mentor +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.) diff --git a/forge-gui/res/cardsfolder/b/boros_challenger.txt b/forge-gui/res/cardsfolder/b/boros_challenger.txt index 5e2da20eaf6..4106f4ddc17 100644 --- a/forge-gui/res/cardsfolder/b/boros_challenger.txt +++ b/forge-gui/res/cardsfolder/b/boros_challenger.txt @@ -4,4 +4,5 @@ Types:Creature Human Soldier PT:2/3 K:Mentor A:AB$ Pump | Cost$ 2 R W | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ CARDNAME gets +1/+1 until end of turn. +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\n{2}{R}{W}: Boros Challenger gets +1/+1 until end of turn. diff --git a/forge-gui/res/cardsfolder/c/chamber_sentry.txt b/forge-gui/res/cardsfolder/c/chamber_sentry.txt index 3816568e85d..cbaa7f301cb 100644 --- a/forge-gui/res/cardsfolder/c/chamber_sentry.txt +++ b/forge-gui/res/cardsfolder/c/chamber_sentry.txt @@ -8,4 +8,5 @@ A:AB$ DealDamage | Announce$ X | Cost$ X T SubCounter | ValidTgts$ Creat SVar:X:Count$xPaid A:AB$ ChangeZone | Cost$ W U B R G | Origin$ Graveyard | Destination$ Hand | ActivationZone$ Graveyard | SpellDescription$ Return CARDNAME from your graveyard to your hand. SVar:DiscardMe:1 +DeckHas:Ability$Counters Oracle:Chamber Sentry enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.\n{X}, {T}, Remove X +1/+1 counters from Chamber Sentry: It deals X damage to any target.\n{W}{U}{B}{R}{G}: Return Chamber Sentry from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/c/charnel_troll.txt b/forge-gui/res/cardsfolder/c/charnel_troll.txt index 6ce2cf5f619..ab2e2318e6d 100644 --- a/forge-gui/res/cardsfolder/c/charnel_troll.txt +++ b/forge-gui/res/cardsfolder/c/charnel_troll.txt @@ -10,4 +10,6 @@ SVar:DBSac:DB$ Sacrifice | SacValid# Self | ConditionDefined$ Remembered | Condi SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True A:AB$ PutCounter | Cost$ B G Discard<1/Creature> | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. SVar:RemRandomDeck:True +DeckNeeds:Ability$Graveyard +DeckHas:Ability$Counters Oracle:Trample\nAt the beginning of your upkeep, exile a creature card from your graveyard. If you do, put a +1/+1 counter on Charnel Troll. Otherwise sacrifice it.\n{B}{G}, Discard a creature card: Put a +1/+1 counter on Charnel Troll. diff --git a/forge-gui/res/cardsfolder/c/citywatch_sphinx.txt b/forge-gui/res/cardsfolder/c/citywatch_sphinx.txt index 1e759f40719..9f332935c10 100644 --- a/forge-gui/res/cardsfolder/c/citywatch_sphinx.txt +++ b/forge-gui/res/cardsfolder/c/citywatch_sphinx.txt @@ -5,4 +5,5 @@ PT:5/4 K:Flying T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME dies, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) SVar:TrigSurveil:DB$Surveil | Defined$ You | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flying\nWhen Citywatch Sphinx dies, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/c/connive_concoct.txt b/forge-gui/res/cardsfolder/c/connive_concoct.txt index 3bc243c7625..1e45b353c28 100644 --- a/forge-gui/res/cardsfolder/c/connive_concoct.txt +++ b/forge-gui/res/cardsfolder/c/connive_concoct.txt @@ -12,4 +12,5 @@ ManaCost:3 U B Types:Sorcery A:SP$ Surveil | Cost$ 3 U B | Amount$ 3 | SubAbility$ DBReturn | SpellDescription$ Surveil 3, then return a creature card from your graveyard to the battlefield. SVar:DBReturn:DB$ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | ChangeNum$ 1 | Hidden$ True +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Surveil 3, then return a creature card from your graveyard to the battlefield. diff --git a/forge-gui/res/cardsfolder/c/crackling_drake.txt b/forge-gui/res/cardsfolder/c/crackling_drake.txt index a5a51fb25ad..9cdd75848e4 100644 --- a/forge-gui/res/cardsfolder/c/crackling_drake.txt +++ b/forge-gui/res/cardsfolder/c/crackling_drake.txt @@ -9,4 +9,5 @@ SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:GraveCount:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn SVar:ExileCount:Count$ValidExile Instant.YouOwn,Sorcery.YouOwn SVar:X:SVar$GraveCount/Plus.ExileCount +DeckNeeds:Type$Instant|Sorcery Oracle:Flying\nCrackling Drake's power is equal to the total number of instant and sorcery cards you own in exile and in your graveyard.\nWhen Crackling Drake enters the battlefield, draw a card. diff --git a/forge-gui/res/cardsfolder/d/darkblade_agent.txt b/forge-gui/res/cardsfolder/d/darkblade_agent.txt index a3ce8c4a4ae..d3a1b48e76e 100644 --- a/forge-gui/res/cardsfolder/d/darkblade_agent.txt +++ b/forge-gui/res/cardsfolder/d/darkblade_agent.txt @@ -6,4 +6,5 @@ S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Deathtouch | AddTrigger$ SVar:Trig1:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:X:Count$YouSurveilThisTurn +DeckHints:Ability$Surveil Oracle:As long as you've surveilled this turn, Darkblade Agent has deathtouch and "Whenever this creature deals combat damage to a player, draw a card." diff --git a/forge-gui/res/cardsfolder/d/dazzling_lights.txt b/forge-gui/res/cardsfolder/d/dazzling_lights.txt index 76b9fdb89d6..8745c904b1a 100644 --- a/forge-gui/res/cardsfolder/d/dazzling_lights.txt +++ b/forge-gui/res/cardsfolder/d/dazzling_lights.txt @@ -3,4 +3,5 @@ ManaCost:U Types:Instant A:SP$ Pump | Cost$ U | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -3 | IsCurse$ True | Subability$ DBSurveil | SpellDescription$ Target creature gets -3/-0 until end of turn. Surveil 2. SVar:DBSurveil:DB$ Surveil | Defined$ You | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Target creature gets -3/-0 until end of turn.\nSurveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/d/deadly_visit.txt b/forge-gui/res/cardsfolder/d/deadly_visit.txt index 26792d9be3a..d211ef31cfb 100644 --- a/forge-gui/res/cardsfolder/d/deadly_visit.txt +++ b/forge-gui/res/cardsfolder/d/deadly_visit.txt @@ -3,4 +3,5 @@ ManaCost:3 B B Types:Sorcery A:SP$ Destroy | Cost$ 3 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | Subability$ DBSurveil | SpellDescription$ Destroy target creature. Surveil 2 (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) SVar:DBSurveil:DB$ Surveil | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Destroy target creature.\nSurveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/d/dimir_informant.txt b/forge-gui/res/cardsfolder/d/dimir_informant.txt index 5cb18e6f8a1..cd9104c4b42 100644 --- a/forge-gui/res/cardsfolder/d/dimir_informant.txt +++ b/forge-gui/res/cardsfolder/d/dimir_informant.txt @@ -4,4 +4,5 @@ Types:Creature Human Rogue PT:1/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters the battlefield, then surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) SVar:TrigSurveil:DB$Surveil | Defined$ You | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:When Dimir Informant enters the battlefield, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/d/dimir_spybug.txt b/forge-gui/res/cardsfolder/d/dimir_spybug.txt index a0ab2b0ff30..4880d824087 100644 --- a/forge-gui/res/cardsfolder/d/dimir_spybug.txt +++ b/forge-gui/res/cardsfolder/d/dimir_spybug.txt @@ -6,4 +6,6 @@ K:Flying K:Menace T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you surveil, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +DeckHints:Ability$Surveil +DeckHas:Ability$Counters Oracle:Flying\nMenace (This creature can't be blocked except by two or more creatures.)\nWhenever you surveil, put a +1/+1 counter on Dimir Spybug. diff --git a/forge-gui/res/cardsfolder/d/discovery_dispersal.txt b/forge-gui/res/cardsfolder/d/discovery_dispersal.txt index 43176fc47dd..bcf7d315b13 100644 --- a/forge-gui/res/cardsfolder/d/discovery_dispersal.txt +++ b/forge-gui/res/cardsfolder/d/discovery_dispersal.txt @@ -4,6 +4,7 @@ Types:Sorcery AlternateMode:Split A:SP$ Surveil | Cost$ 1 U/B | Amount$ 2 | SubAbility$ DBDraw | SpellDescription$ Surveil 2, then draw a card. SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Surveil 2, then draw a card. (To surveil 2, look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) ALTERNATE diff --git a/forge-gui/res/cardsfolder/d/disinformation_campaign.txt b/forge-gui/res/cardsfolder/d/disinformation_campaign.txt index 17be691d384..4f4cc7c1072 100644 --- a/forge-gui/res/cardsfolder/d/disinformation_campaign.txt +++ b/forge-gui/res/cardsfolder/d/disinformation_campaign.txt @@ -6,4 +6,5 @@ SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBDiscard SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | NumCards$ 1 | Mode$ TgtChoose T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ Whenever you surveil, return CARDNAME to its owner's hand. SVar:TrigBounce:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Defined$ Self +DeckHints:Ability$Surveil Oracle:When Disinformation Campaign enters the battlefield, you draw a card and each opponent discards a card.\nWhenever you surveil, return Disinformation Campaign to its owner's hand. diff --git a/forge-gui/res/cardsfolder/d/doom_whisperer.txt b/forge-gui/res/cardsfolder/d/doom_whisperer.txt index ea6bdf4f39a..469af683112 100644 --- a/forge-gui/res/cardsfolder/d/doom_whisperer.txt +++ b/forge-gui/res/cardsfolder/d/doom_whisperer.txt @@ -5,4 +5,5 @@ PT:6/6 K:Flying K:Trample A:AB$ Surveil | Cost$ PayLife<2> | Amount$ 2 | SpellDescription$ Surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flying, trample\nPay 2 life: Surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/d/dream_eater.txt b/forge-gui/res/cardsfolder/d/dream_eater.txt index fddbdb90ac9..99a06b972ac 100644 --- a/forge-gui/res/cardsfolder/d/dream_eater.txt +++ b/forge-gui/res/cardsfolder/d/dream_eater.txt @@ -8,4 +8,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigSurveil:DB$ Surveil | Defined$ You | Amount$ 4 | SubAbility$ TrigImmediate SVar:TrigImmediate:DB$ ImmediateTrigger | Execute$ TrigBounce | OptionalDecider$ You | TriggerDescription$ When you do, you may return target nonland permanent an opponent controls to its owner's hand. SVar:TrigBounce:DB$ ChangeZone | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent an opponent controls | Origin$ Battlefield | Destination$ Hand +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flash\nFlying\nWhen Dream Eater enters the battlefield, surveil 4. When you do, you may return target nonland permanent an opponent controls to its owner's hand. (To surveil 4, look at the top four cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/d/drowned_secrets.txt b/forge-gui/res/cardsfolder/d/drowned_secrets.txt index 2bf1b893bc0..55e3fdba195 100644 --- a/forge-gui/res/cardsfolder/d/drowned_secrets.txt +++ b/forge-gui/res/cardsfolder/d/drowned_secrets.txt @@ -4,4 +4,5 @@ Types:Enchantment T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Whenever you cast a blue spell, target player puts the top two cards if their library into their graveyard. SVar:TrigMill:DB$Mill | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Select target player SVar:BuffedBy:Card.Blue +DeckHas:Ability$Graveyard Oracle:Whenever you cast a blue spell, target player puts the top two cards if their library into their graveyard. diff --git a/forge-gui/res/cardsfolder/e/electrostatic_field.txt b/forge-gui/res/cardsfolder/e/electrostatic_field.txt index fbb8fdd3b2d..21044c85700 100644 --- a/forge-gui/res/cardsfolder/e/electrostatic_field.txt +++ b/forge-gui/res/cardsfolder/e/electrostatic_field.txt @@ -5,4 +5,5 @@ PT:0/4 K:Defender T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ When you cast an instant or sorcery spell, CARDNAME deals 1 damage to each opponent. SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 1 +DeckHints:Type$Instant|Sorcery Oracle:Defender\nWhen you cast an instant or sorcery spell, Electrostatic Field deals 1 damage to each opponent. diff --git a/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt b/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt index 44da9af66e5..4c998fe93ce 100644 --- a/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt +++ b/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt @@ -4,4 +4,5 @@ Types:Legendary Creature Elf Cleric PT:2/2 T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME becomes tapped, create a 1/1 white Soldier creature token with lifelink. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink +DeckHas:Ability$Token Oracle:Whenever Emmara, Soul of the Accord becomes tapped, create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt b/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt index d8bb73b521c..e1f2f07462c 100644 --- a/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt +++ b/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt @@ -5,4 +5,5 @@ R:Event$ Surveil | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ Ad SVar:AddTwoMore:DB$ ReplaceEffect | VarName$ SurveilNum | VarValue$ X | References$ X SVar:X:ReplaceCount$SurveilNum/Plus.2 A:AB$ ChangeZoneAll | Cost$ Exile<1/CARDNAME> | ChangeType$ Card.YouOwn | Origin$ Graveyard | Destination$ Library | Shuffle$ True | SpellDescription$ Shuffle your graveyard into your library. +DeckNeeds:Ability$Surveil Oracle:You may look at an additional two cards each you surveil.\nExile Enhanced Surveillance: Shuffle your graveyard into your library. diff --git a/forge-gui/res/cardsfolder/e/erratic_cyclops.txt b/forge-gui/res/cardsfolder/e/erratic_cyclops.txt index 269664a5423..38c790f9854 100644 --- a/forge-gui/res/cardsfolder/e/erratic_cyclops.txt +++ b/forge-gui/res/cardsfolder/e/erratic_cyclops.txt @@ -7,4 +7,5 @@ T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Tr SVar:TrigPump:DB$ Pump | NumAtt$ +X | References$ X SVar:X:TriggerCount$CastSACMC SVar:BuffedBy:Instant,Sorcery +DeckHints:Type$Instant|Sorcery Oracle:Trample\nWhenever you cast an instant or sorcery spell, Erratic Cyclops gets +X/+0 until end of turn, where X is that spell's converted mana cost. diff --git a/forge-gui/res/cardsfolder/f/find_finality.txt b/forge-gui/res/cardsfolder/f/find_finality.txt index 28a07e6d50f..2b85d2313fd 100644 --- a/forge-gui/res/cardsfolder/f/find_finality.txt +++ b/forge-gui/res/cardsfolder/f/find_finality.txt @@ -14,4 +14,5 @@ A:SP$ ChooseCard | Cost$ 4 B G | Defined$ You | Amount$ 1 | MinAmount$ 0 | Choic 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 +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/f/fire_urchin.txt b/forge-gui/res/cardsfolder/f/fire_urchin.txt index 4e4e22a9def..02cc79bb57e 100644 --- a/forge-gui/res/cardsfolder/f/fire_urchin.txt +++ b/forge-gui/res/cardsfolder/f/fire_urchin.txt @@ -6,4 +6,5 @@ K:Trample T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast an instant or sorcery spell, CARDNAME gets +1/+0 until end of turn. SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 1 SVar:BuffedBy:Instant,Sorcery +DeckHints:Type$Instant|Sorcery Oracle:Trample\nWhenever you cast an instant or sorcery spell, Fire Urchin gets +1/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/f/fireminds_research.txt b/forge-gui/res/cardsfolder/f/fireminds_research.txt index b2a23c01b04..fc7c35836ce 100644 --- a/forge-gui/res/cardsfolder/f/fireminds_research.txt +++ b/forge-gui/res/cardsfolder/f/fireminds_research.txt @@ -8,4 +8,5 @@ DeckHints:Type$Instant | Sorcery A:AB$ Draw | Cost$ 1 U SubCounter<2/CHARGE> | NumCards$ 1 | SpellDescription$ Draw a card. A:AB$ DealDamage | Cost$ 1 R SubCounter<5/CHARGE> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 5 | SpellDescription$ CARDNAME deals 5 damage to any target. SVar:RemRandomDeck:True +DeckNeeds:Type$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell, put a charge counter on Firemind's Research.\n{1}{U}, Remove two charge counters from Firemind's Research: Draw a card.\n{1}{R}, Remove five charge counters from Firemind's Research: It deals 5 damage to any target. diff --git a/forge-gui/res/cardsfolder/g/gird_for_battle.txt b/forge-gui/res/cardsfolder/g/gird_for_battle.txt index 305c43656e3..0f10b839ce2 100644 --- a/forge-gui/res/cardsfolder/g/gird_for_battle.txt +++ b/forge-gui/res/cardsfolder/g/gird_for_battle.txt @@ -2,4 +2,5 @@ Name:Gird for Battle ManaCost:W Types:Sorcery A:SP$ PutCounter | Cost$ W | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 2 | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each of up to two target creatures. +DeckHas:Ability$Counters Oracle:Put a +1/+1 counter on each of up to two target creatures. diff --git a/forge-gui/res/cardsfolder/g/glowspore_shaman.txt b/forge-gui/res/cardsfolder/g/glowspore_shaman.txt index 518b808f7c1..c5c3d74e1e7 100644 --- a/forge-gui/res/cardsfolder/g/glowspore_shaman.txt +++ b/forge-gui/res/cardsfolder/g/glowspore_shaman.txt @@ -5,4 +5,5 @@ PT:3/1 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When CARDNAME enters the battlefield, put the top three cards of your library into your graveyard. You may put a land card from your graveyard on top of your library. SVar:TrigMill:DB$ Mill | NumCards$ 3 | Defined$ You | SubAbility$ DBChangeZone SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | OptionalDecider$ You | ChangeType$ Land.YouOwn | ChangeNum$ 1 | Hidden$ True | Optional$ True +DeckHas:Ability$Graveyard Oracle:When Glowspore Shaman enters the battlefield, put the top three cards of your library into your graveyard. You may put a land card from your graveyard on top of your library. diff --git a/forge-gui/res/cardsfolder/g/goblin_banneret.txt b/forge-gui/res/cardsfolder/g/goblin_banneret.txt index 5419f82bfbc..b1bcc1bccd3 100644 --- a/forge-gui/res/cardsfolder/g/goblin_banneret.txt +++ b/forge-gui/res/cardsfolder/g/goblin_banneret.txt @@ -4,4 +4,5 @@ Types:Creature Goblin Soldier PT:1/1 K:Mentor A:AB$ Pump | Cost$ 1 R | NumAtt$ +2 | SpellDescription$ CARDNAME gets +2/+0 until end of turn. +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\n{1}{R}: Goblin Banneret gets +2/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/g/golgari_raiders.txt b/forge-gui/res/cardsfolder/g/golgari_raiders.txt index 2edb4dec836..68b269f346b 100644 --- a/forge-gui/res/cardsfolder/g/golgari_raiders.txt +++ b/forge-gui/res/cardsfolder/g/golgari_raiders.txt @@ -6,4 +6,5 @@ K:Haste K:etbCounter:P1P1:X:no Condition:Undergrowth - CARDNAME enters the battlefield with a +1/+1 counter on it for each creature card in your graveyard. SVar:X:Count$LastStateGraveyard Creature.YouCtrl SVar:NeedsToPlayVar:X GE3 +DeckHas:Ability$Counters Oracle:Haste\nUndergrowth — Golgari Raiders enters the battlefield with a +1/+1 counter on it for each creature card in your graveyard. diff --git a/forge-gui/res/cardsfolder/g/gruesome_menagerie.txt b/forge-gui/res/cardsfolder/g/gruesome_menagerie.txt index 46c3ea0f004..8a28cd52744 100644 --- a/forge-gui/res/cardsfolder/g/gruesome_menagerie.txt +++ b/forge-gui/res/cardsfolder/g/gruesome_menagerie.txt @@ -6,4 +6,5 @@ SVar:DBChoose2:DB$ ChooseCard | Defined$ You | Choices$ Creature.YouOwn+cmcEQ2 | SVar:DBChoose3:DB$ ChooseCard | Defined$ You | Choices$ Creature.YouOwn+cmcEQ3 | ChoiceZone$ Graveyard | Amount$ 1 | SubAbility$ DBReturn | RememberChosen$ True | SpellDescription$ Choose a creature card with converted mana cost 3 in your graveyard. SVar:DBReturn:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Card.IsRemembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:NeedsToPlay:Creature.YouCtrl+inZoneGraveyard+cmcLE3 Oracle:Choose a creature card with converted mana cost 1 in your graveyard, then do the same for creature cards with converted mana costs 2 and 3. Return those cards to the battlefield. diff --git a/forge-gui/res/cardsfolder/g/guildmages_forum.txt b/forge-gui/res/cardsfolder/g/guildmages_forum.txt index 1eb1bca9658..0dfcfc4b524 100644 --- a/forge-gui/res/cardsfolder/g/guildmages_forum.txt +++ b/forge-gui/res/cardsfolder/g/guildmages_forum.txt @@ -2,4 +2,5 @@ Name:Guildmages' Forum Types:Land A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. A:AB$ Mana | Cost$ 1 T | Produced$ Any | AddsCounters$ Card.Creature+MultiColor_P1P1_1 | SpellDescription$ Add one mana of any color. If that mana is spent on a multicolored creature spell, that creature enters the battlefield with an additional +1/+1 counter on it. +DeckHas:Ability$Counters Oracle:{T}: Add {C}.\n{1}, {T}: Add one mana of any color. If that mana is spent on a multicolored creature spell, that creature enters the battlefield with an additional +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/h/haazda_marshal.txt b/forge-gui/res/cardsfolder/h/haazda_marshal.txt index 5eb0f677523..62edb4876d3 100644 --- a/forge-gui/res/cardsfolder/h/haazda_marshal.txt +++ b/forge-gui/res/cardsfolder/h/haazda_marshal.txt @@ -5,4 +5,5 @@ PT:1/1 T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | CheckSVar$ AttackerTest | SVarCompare$ GE2 | NoResolvingCheck$ True | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME and at least two other creatures attack, create a 1/1 white Soldier creature token with lifelink. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink SVar:AttackerTest:Count$Valid Creature.attacking+Other +DeckHas:Ability$Token Oracle:Whenever Haazda Marshal and at least two other creatures attack, create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/h/hammer_dropper.txt b/forge-gui/res/cardsfolder/h/hammer_dropper.txt index d0d0d0a3193..dd2b2f37495 100644 --- a/forge-gui/res/cardsfolder/h/hammer_dropper.txt +++ b/forge-gui/res/cardsfolder/h/hammer_dropper.txt @@ -3,4 +3,5 @@ ManaCost:2 R W Types:Creature Giant Soldier PT:5/2 K:Mentor +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.) diff --git a/forge-gui/res/cardsfolder/h/house_guildmage.txt b/forge-gui/res/cardsfolder/h/house_guildmage.txt index 08847cc9e65..4a0c6f751c1 100644 --- a/forge-gui/res/cardsfolder/h/house_guildmage.txt +++ b/forge-gui/res/cardsfolder/h/house_guildmage.txt @@ -4,4 +4,5 @@ Types:Creature Human Wizard PT:2/2 A:AB$ Pump | Cost$ 1 U T | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN This card doesn't untap during your next untap step. | Permanent$ True | IsCurse$ True | SpellDescription$ Target creature doesn't untap during its controller's next untap step. A:AB$ Surveil | Cost$ 2 B T | Amount$ 2 | SpellDescription$ Surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:{1}{U}, {T}: Target creature doesn't untap during its controller's next untap step.\n{2}{B}, {T}: Surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/i/invert_invent.txt b/forge-gui/res/cardsfolder/i/invert_invent.txt index 9e5803db4e7..63f7d936e87 100644 --- a/forge-gui/res/cardsfolder/i/invert_invent.txt +++ b/forge-gui/res/cardsfolder/i/invert_invent.txt @@ -13,4 +13,5 @@ Types:Instant A:SP$ ChangeZone | Cost$ 4 U R | Origin$ Library | Destination$ Hand | ChangeType$ Instant | ChangeNum$ 1 | SubAbility$ DBChange | SpellDescription$ Search your library for and instant permanent and/or a sorcery card, reveal them, put them into your hand, then shuffle your library. SVar:DBChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Sorcery | ChangeNum$ 1 | Shuffle$ True SVar:RemRandomDeck:True +DeckHints:Type$Instant|Sorcery Oracle:Search your library for an instant card and/or a sorcery card, reveal them, put them into your hand, then shuffle your library. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/i/ironshell_beetle.txt b/forge-gui/res/cardsfolder/i/ironshell_beetle.txt index 39ad66852ba..6cde56e4cc5 100644 --- a/forge-gui/res/cardsfolder/i/ironshell_beetle.txt +++ b/forge-gui/res/cardsfolder/i/ironshell_beetle.txt @@ -4,5 +4,6 @@ Types:Creature Insect PT:1/1 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPut | TriggerDescription$ When CARDNAME enters the battlefield, put a +1/+1 counter on target creature. SVar:TrigPut:DB$PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters SVar:Picture:http://www.wizards.com/global/images/magic/general/ironshell_beetle.jpg Oracle:When Ironshell Beetle enters the battlefield, put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt b/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt index c5fd38febe0..caf403eb29a 100644 --- a/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt +++ b/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt @@ -7,4 +7,5 @@ SVar:TrigToken:DB$Token | TokenAmount$ X | TokenName$ Insect | TokenTypes$ Creat SVar:X:Count$TypeInYourYard.Creature A:AB$ GainLife | Cost$ B G Sac<1/Creature.Other/another creature> | Defined$ You | LifeAmount$ 1 | SubAbility$ DBDraw | SpellDescription$ You gain 1 life and draw a card. SVar:DBDraw:DB$ Draw | NumCards$ 1 +DeckHas:Ability$Token Oracle:Undergrowth — When Izoni, Thousand-Eyed enters the battlefield, create a 1/1 black and green Insect creature token for each creature card in your graveyard.\n{B}{G}, Sacrifice another creature: You gain 1 life and draw a card. diff --git a/forge-gui/res/cardsfolder/k/knight_of_autumn.txt b/forge-gui/res/cardsfolder/k/knight_of_autumn.txt index 907e199df3c..773ea6207c9 100644 --- a/forge-gui/res/cardsfolder/k/knight_of_autumn.txt +++ b/forge-gui/res/cardsfolder/k/knight_of_autumn.txt @@ -7,4 +7,5 @@ SVar:TrigCharm:DB$ Charm | Choices$ DBPump,DBDestroy,DBGainLife SVar:DBPump:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Put two +1/+1 counters on CARDNAME. SVar:DBDestroy:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SpellDescription$ Destroy target artifact or enchantment. SVar:DBGainLife:DB$ GainLife | LifeAmount$ 4 | SpellDescription$ You gain 4 life. +DeckHas:Ability$Counters Oracle:When Knight of Autumn enters the battlefield, choose one —\n• Put two +1/+1 counters on Knight of Autumn.\n• Destroy target artifact or enchantment.\n• You gain 4 life. diff --git a/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt b/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt index 57ab5d3a9fa..374c88202d1 100644 --- a/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt +++ b/forge-gui/res/cardsfolder/l/lazav_the_multifarious.txt @@ -6,4 +6,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigSurveil:DB$ Surveil | Amount$ 1 A:AB$ Clone | Cost$ X | ValidTgts$ Creature.YouOwn | References$ X | TgtZone$ Graveyard | TgtPrompt$ Select target creature card in your graveyard | AddTypes$ Legendary | NewName$ Lazav, the Multifarious | GainThisAbility$ True | SpellDescription$ CARDNAME becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is CARDNAME, it's legendary in addition to it's other types, and it has this ability. SVar:X:Targeted$CardManaCost +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:When Lazav, the Multifarious enters the battlefield, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.)\n{X}: Lazav, the Multifarious becomes a copy of target creature card in your graveyard with converted mana cost X, except its name is Lazav, the Multifarious, it's legendary in addition to its other types, and it has this ability. diff --git a/forge-gui/res/cardsfolder/l/league_guildmage.txt b/forge-gui/res/cardsfolder/l/league_guildmage.txt index 1c07ac501bf..c0cdc4c664c 100644 --- a/forge-gui/res/cardsfolder/l/league_guildmage.txt +++ b/forge-gui/res/cardsfolder/l/league_guildmage.txt @@ -5,4 +5,5 @@ PT:2/2 A:AB$ Draw | Cost$ 3 U T | NumCards$ 1 | SpellDescription$ Draw a card. A:AB$ CopySpellAbility | Cost$ X R T | ValidTgts$ Instant.YouCtrl,Sorcery.YouCtrl | TargetType$ Spell | SpellDescription$ Copy target instant or sorcery spell you control with converted mana cost X. You may choose new targets for the copy. SVar:X:Targeted$CardManaCost +DeckHints:Type$Instant|Sorcery Oracle:{3}{U}, {T}: Draw a card.\n{X}{R}, {T}: Copy target instant or sorcery spell you control with converted mana cost X. You may choose new targets for the copy. diff --git a/forge-gui/res/cardsfolder/l/leapfrog.txt b/forge-gui/res/cardsfolder/l/leapfrog.txt index 7a7ada2f5a2..345db3634bb 100644 --- a/forge-gui/res/cardsfolder/l/leapfrog.txt +++ b/forge-gui/res/cardsfolder/l/leapfrog.txt @@ -4,4 +4,5 @@ Types:Creature Frog PT:3/1 S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Flying | CheckSVar$ X | SVarCompare$ GE1 | Description$ CARDNAME has flying as long as you've cast and instant or sorcery spell this turn. SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl +DeckHints:Type$Instant|Sorcery Oracle:Leapfrog has flying as long as you've cast and instant or sorcery spell this turn. diff --git a/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt b/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt index 693f71a3d99..c9a7aac646e 100644 --- a/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt +++ b/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt @@ -4,4 +4,5 @@ Types:Instant K:Convoke A:SP$ Token | Cost$ X G W W | TokenAmount$ X | References$ X | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Create X 1/1 white Soldier creature tokens with lifelink. SVar:X:Count$xPaid +DeckHas:Ability$Token Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of the creature's color.)\nCreate X 1/1 white Soldier creature tokens with lifelink. diff --git a/forge-gui/res/cardsfolder/m/mephitic_vapors.txt b/forge-gui/res/cardsfolder/m/mephitic_vapors.txt index 20328c8009e..eeca0cc0668 100644 --- a/forge-gui/res/cardsfolder/m/mephitic_vapors.txt +++ b/forge-gui/res/cardsfolder/m/mephitic_vapors.txt @@ -3,4 +3,5 @@ ManaCost:2 B Types:Sorcery A:SP$ PumpAll | Cost$ 2 B | ValidCards$ Creature | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True | Subability$ DBSurveil | SpellDescription$ All creatures get -1/-1 until end of turn. SVar:DBSurveil:DB$ Surveil | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:All creatures get -1/-1 until end of turn.\nSurveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/m/mission_briefing.txt b/forge-gui/res/cardsfolder/m/mission_briefing.txt index 8c0d5ca1156..3fc8640f76e 100644 --- a/forge-gui/res/cardsfolder/m/mission_briefing.txt +++ b/forge-gui/res/cardsfolder/m/mission_briefing.txt @@ -9,5 +9,6 @@ SVar:ReplaceGraveyard:Event$ Moved | ValidCard$ Card.IsRemembered | Origin$ Stac SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:RemAIDeck:True +DeckHas:Ability$Surveil & Ability$Graveyard SVar:Picture:http://www.wizards.com/global/images/magic/general/mission_briefing.jpg Oracle:Surveil 2, then choose an instant or sorcery card in your graveyard. You may cast that card this turn. If that card would be put into your graveyard this turn, exile it instead. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/m/murmuring_mystic.txt b/forge-gui/res/cardsfolder/m/murmuring_mystic.txt index e564cee9162..7947d0ef419 100644 --- a/forge-gui/res/cardsfolder/m/murmuring_mystic.txt +++ b/forge-gui/res/cardsfolder/m/murmuring_mystic.txt @@ -5,4 +5,6 @@ PT:1/5 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you cast an instant or sorcery spell, create a 1/1 blue Bird Illusion creature token with flying. SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenScript$ u_1_1_bird_illusion_flying SVar:BuffedBy:Instant,Sorcery +DeckHints:Ability$Instant|Sorcery +DeckHas:Ability$Token Oracle:Whenever you cast an instant or sorcery spell, create a 1/1 blue Bird Illusion creature token with flying. diff --git a/forge-gui/res/cardsfolder/n/nightveil_sprite.txt b/forge-gui/res/cardsfolder/n/nightveil_sprite.txt index 82043a4765a..bd2c50afe9f 100644 --- a/forge-gui/res/cardsfolder/n/nightveil_sprite.txt +++ b/forge-gui/res/cardsfolder/n/nightveil_sprite.txt @@ -6,4 +6,5 @@ K:Flying T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) SVar:TrigSurveil:DB$ Surveil | Amount$ 1 SVar:HasAttackEffect:TRUE +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flying\nWhenever Nightveil Sprite attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) diff --git a/forge-gui/res/cardsfolder/n/niv_mizzet_parun.txt b/forge-gui/res/cardsfolder/n/niv_mizzet_parun.txt index 5e02fcdb3b0..225b2a575c5 100644 --- a/forge-gui/res/cardsfolder/n/niv_mizzet_parun.txt +++ b/forge-gui/res/cardsfolder/n/niv_mizzet_parun.txt @@ -8,4 +8,5 @@ T:Mode$ Drawn | ValidCard$ Card.YouOwn | TriggerZones$ Battlefield | Execute$ Tr SVar:TrigDealDamage:DB$DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a player casts an instant or sorcery spell, you draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +DeckHints:Type$Instant|Sorcery Oracle:Niv-Mizzet, Parun can't be countered.\nFlying\nWhenever you draw a card, Niv-Mizzet, Parun deals 1 damage to any target.\nWhenever a player casts an instant or sorcery spell, you draw a card. diff --git a/forge-gui/res/cardsfolder/n/notion_rain.txt b/forge-gui/res/cardsfolder/n/notion_rain.txt index 2e49bc7cf74..c932c15d821 100644 --- a/forge-gui/res/cardsfolder/n/notion_rain.txt +++ b/forge-gui/res/cardsfolder/n/notion_rain.txt @@ -4,4 +4,5 @@ Types:Sorcery A:SP$ Surveil | Cost$ 1 U B | Amount$ 2 | SubAbility$ DBDraw | SpellDescription$ Surveil 2, then draw two cards. CARDNAME deals 2 damage to you. SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SubAbility$ DBDamage SVar:DBDamage:DB$ DealDamage | Defined$ You | NumDmg$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Surveil 2, then draw two cards. Rain of Notions deals 2 damage to you. (To surveil 2, look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/p/parhelion_patrol.txt b/forge-gui/res/cardsfolder/p/parhelion_patrol.txt index 35265bd259b..d4ed407ad8a 100644 --- a/forge-gui/res/cardsfolder/p/parhelion_patrol.txt +++ b/forge-gui/res/cardsfolder/p/parhelion_patrol.txt @@ -5,4 +5,5 @@ PT:2/3 K:Flying K:Vigilance K:Mentor +DeckHas:Ability$Counters Oracle:Flying, vigilance\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.) diff --git a/forge-gui/res/cardsfolder/p/pelt_collector.txt b/forge-gui/res/cardsfolder/p/pelt_collector.txt index 1057ed08c4e..56e8b90ad45 100644 --- a/forge-gui/res/cardsfolder/p/pelt_collector.txt +++ b/forge-gui/res/cardsfolder/p/pelt_collector.txt @@ -7,4 +7,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creatu T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl+powerGTX+Other | References$ X | TriggerZones$ Battlefield | Secondary$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than CARDNAME's, put a +1/+1 counter on CARDNAME. SVar:X:Count$CardPower SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters Oracle:Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than Pelt Collector's, put a +1/+1 counter on Pelt Collector.\nAs long as Pelt Collector has three or more +1/+1 counters on it, it has trample. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/p/piston_fist_cyclops.txt b/forge-gui/res/cardsfolder/p/piston_fist_cyclops.txt index 6382caaec7c..c632d6cad7b 100644 --- a/forge-gui/res/cardsfolder/p/piston_fist_cyclops.txt +++ b/forge-gui/res/cardsfolder/p/piston_fist_cyclops.txt @@ -6,4 +6,5 @@ K:Defender S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can attack as though it didn't have defender. | CheckSVar$ X | SVarCompare$ GE1 | Description$ As long as you've cast an instant or sorcery spell this turn, CARDNAME can attack as though it didn't have defender. SVar:X:Count$ThisTurnCast_Instant.YouOwn,Sorcery.YouOwn SVar:BuffedBy:Instant,Sorcery +DeckHints:Type$Instant|Sorcery Oracle:Defender\nAs long as you've cast an instant or sorcery spell this turn, Piston-Fist Cyclops can attack as though it didn't have defender. diff --git a/forge-gui/res/cardsfolder/p/price_of_fame.txt b/forge-gui/res/cardsfolder/p/price_of_fame.txt index 4383c468503..83fd2baf529 100644 --- a/forge-gui/res/cardsfolder/p/price_of_fame.txt +++ b/forge-gui/res/cardsfolder/p/price_of_fame.txt @@ -6,4 +6,5 @@ A:SP$ Destroy | Cost$ 3 B | ValidTgts$ Creature | SubAbility$ DBSurveil | TgtPro SVar:CostReduction:Count$Compare CheckTgt GE1.2.0 SVar:CheckTgt:Targeted$Valid Creature.Legendary SVar:DBSurveil:DB$ Surveil | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:This spell costs {2} less to cast if it targets a legendary creature.\nDestroy target creature.\nSurveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/r/ral_izzet_viceroy.txt b/forge-gui/res/cardsfolder/r/ral_izzet_viceroy.txt index 82e83d9f78b..1383177de97 100644 --- a/forge-gui/res/cardsfolder/r/ral_izzet_viceroy.txt +++ b/forge-gui/res/cardsfolder/r/ral_izzet_viceroy.txt @@ -12,4 +12,6 @@ SVar:TrigSpellCast:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatin SVar:EffSpellCast:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 4 | SubAbility$ EffDraw SVar:EffDraw:DB$ Draw | Defined$ You | NumCards$ 2 SVar:BuffedBy:Instant,Sorcery +DeckHints:Type$Instant|Sorcery +DeckHas:Ability$Graveyard Oracle:[+1]: Look at the top two cards of your library. Put one of them into your hand and the other into your graveyard.\n[-3]: Ral, Izzet Viceroy deals damage to target creature equal to the total number of instant and sorcery cards you own in exile and in your graveyard.\n[-8]: You get an emblem with "Whenever you cast an instant or sorcery spell, this emblem deals 4 damage to any target and you draw two cards." diff --git a/forge-gui/res/cardsfolder/r/rals_staticaster.txt b/forge-gui/res/cardsfolder/r/rals_staticaster.txt index 10dee68d58c..1c179895b30 100644 --- a/forge-gui/res/cardsfolder/r/rals_staticaster.txt +++ b/forge-gui/res/cardsfolder/r/rals_staticaster.txt @@ -7,4 +7,5 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | IsPresent$ Planeswa SVar:TrigPump:DB$ Pump | NumAtt$ X | References$ X SVar:X:Count$InYourHand SVar:BuffedBy:Ral +DeckNeeds:Type$Ral Oracle:Trample (This creature can deal excess combat damage to the player or planeswalker it's attacking.)\nWhenever Ral's Staticaster attacks, if you control a Ral planeswalker, Ral's Staticaster gets +1/+0 for each card in your hand until end of turn. diff --git a/forge-gui/res/cardsfolder/r/rampaging_monument.txt b/forge-gui/res/cardsfolder/r/rampaging_monument.txt index 82bd021bbef..b5b7db7fb21 100644 --- a/forge-gui/res/cardsfolder/r/rampaging_monument.txt +++ b/forge-gui/res/cardsfolder/r/rampaging_monument.txt @@ -7,4 +7,5 @@ K:etbCounter:P1P1:3 T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a multicolored spell, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 SVar:BuffedBy:Card.MultiColor +DeckHas:Ability$Counters Oracle:Trample\nRampaging Monument enters the battlefield with three +1/+1 counters on it.\nWhenever you cast a multicolored spell, put a +1/+1 counter on Rampaging Monument. diff --git a/forge-gui/res/cardsfolder/r/rhizome_lurcher.txt b/forge-gui/res/cardsfolder/r/rhizome_lurcher.txt index cee27cca260..0d374e6d17c 100644 --- a/forge-gui/res/cardsfolder/r/rhizome_lurcher.txt +++ b/forge-gui/res/cardsfolder/r/rhizome_lurcher.txt @@ -5,4 +5,5 @@ PT:2/2 K:etbCounter:P1P1:X:no Condition:Undergrowth - CARDNAME enters the battlefield with a number of +1/+1 counters on it equal to the number of creature cards in your graveyard. SVar:X:Count$TypeInYourYard.Creature SVar:NeedsToPlayVar:X GE1 +DeckHas:Ability$Counters Oracle:Undergrowth — Rhizome Lurcher enters the battlefield with a number of +1/+1 counters on it equal to the number of creature cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/r/runaway_steam_kin.txt b/forge-gui/res/cardsfolder/r/runaway_steam_kin.txt index f43e7afe1e2..5c70f04198e 100644 --- a/forge-gui/res/cardsfolder/r/runaway_steam_kin.txt +++ b/forge-gui/res/cardsfolder/r/runaway_steam_kin.txt @@ -5,4 +5,5 @@ PT:1/1 T:Mode$ SpellCast | ValidCard$ Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.Self+counters_LE2_P1P1 | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a red spell, if CARDNAME has fewer than three +1/+1 counters on it, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 A:AB$ Mana | Cost$ SubCounter<3/P1P1> | Produced$ R | Amount$ 3 | SpellDescription$ Add {R}{R}{R}. +DeckHas:Ability$Counters Oracle:Whenever you cast a red spell, if Runaway Steam-Kin has fewer than three +1/+1 counters on it, put a +1/+1 counter on Runaway Steam-Kin.\nRemove three +1/+1 counters from Runaway Steam-Kin: Add {R}{R}{R}. diff --git a/forge-gui/res/cardsfolder/s/sinister_sabotage.txt b/forge-gui/res/cardsfolder/s/sinister_sabotage.txt index 5dcbd3c772a..26b0076b909 100644 --- a/forge-gui/res/cardsfolder/s/sinister_sabotage.txt +++ b/forge-gui/res/cardsfolder/s/sinister_sabotage.txt @@ -3,4 +3,5 @@ ManaCost:1 U U Types:Instant A:SP$ Counter | Cost$ 1 U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | Subability$ DBSurveil | SpellDescription$ Counter target spell. Surveil 1 (Look at the top card of your library. You may put that card into your graveyard.) SVar:DBSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Counter target spell.\nSurveil 1. (Look at the top card of your library. You may put that card into your graveyard.) diff --git a/forge-gui/res/cardsfolder/s/smelt_ward_minotaur.txt b/forge-gui/res/cardsfolder/s/smelt_ward_minotaur.txt index 8c51a87d9a2..3c563b2f46a 100644 --- a/forge-gui/res/cardsfolder/s/smelt_ward_minotaur.txt +++ b/forge-gui/res/cardsfolder/s/smelt_ward_minotaur.txt @@ -5,5 +5,5 @@ PT:2/3 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast an instant or sorcery spell, target creature an opponent controls can't block this turn. SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True SVar:BuffedBy:Instant,Sorcery -DeckHints:Type$Instant | Sorcery +DeckHints:Type$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell, target creature an opponent controls can't block this turn. diff --git a/forge-gui/res/cardsfolder/s/sprouting_renewal.txt b/forge-gui/res/cardsfolder/s/sprouting_renewal.txt index 133ca46ab57..9f75927afbd 100644 --- a/forge-gui/res/cardsfolder/s/sprouting_renewal.txt +++ b/forge-gui/res/cardsfolder/s/sprouting_renewal.txt @@ -5,4 +5,5 @@ K:Convoke A:SP$ Charm | Cost$ 2 G | Choices$ DBToken,DBDestroy SVar:DBDestroy:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SpellDescription$ Destroy target artifact or enchantment. SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ wg_2_2_elf_knight_vigilance | SpellDescription$ Create a 2/2 green and white Elf Knight creature token with vigilance. +DeckHas:Ability$Token Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.)\nChoose one —\n• Create a 2/2 green and white Elf Knight creature token with vigilance.\n• Destroy target artifact or enchantment. diff --git a/forge-gui/res/cardsfolder/s/sunhome_stalwart.txt b/forge-gui/res/cardsfolder/s/sunhome_stalwart.txt index 108c54611cd..3619e11a263 100644 --- a/forge-gui/res/cardsfolder/s/sunhome_stalwart.txt +++ b/forge-gui/res/cardsfolder/s/sunhome_stalwart.txt @@ -4,4 +4,5 @@ Types:Creature Human Soldier PT:2/2 K:First Strike K:Mentor +DeckHas:Ability$Counters Oracle:First strike\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.) diff --git a/forge-gui/res/cardsfolder/t/tajic_legions_edge.txt b/forge-gui/res/cardsfolder/t/tajic_legions_edge.txt index 4fd9fb0b3a4..dc2adc1103c 100644 --- a/forge-gui/res/cardsfolder/t/tajic_legions_edge.txt +++ b/forge-gui/res/cardsfolder/t/tajic_legions_edge.txt @@ -6,4 +6,5 @@ K:Haste K:Mentor R:Event$ DamageDone | ActiveZones$ Battlefield | Prevent$ True | ValidTarget$ Creature.Other+YouCtrl | IsCombat$ False | Description$ Prevent all noncombat damage that would be dealt to other creatures you control. A:AB$ Pump | Cost$ R W | Defined$ Self | KW$ First Strike | SpellDescription$ CARDNAME gains first strike until end of turn. +DeckHas:Ability$Counters Oracle:Haste\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\nPrevent all noncombat damage that would be dealt to other creatures you control.\n{R}{W}: Tajic, Legion's Edge gains first strike until end of turn. diff --git a/forge-gui/res/cardsfolder/t/thought_erasure.txt b/forge-gui/res/cardsfolder/t/thought_erasure.txt index 02aab8b1c92..57bdc88fe1c 100644 --- a/forge-gui/res/cardsfolder/t/thought_erasure.txt +++ b/forge-gui/res/cardsfolder/t/thought_erasure.txt @@ -3,4 +3,5 @@ ManaCost:U B Types:Sorcery A:SP$ Discard | Cost$ U B | ValidTgts$ Opponent | DiscardValid$ Card.nonLand | NumCards$ 1 | Mode$ RevealYouChoose | Subability$ DBSurveil | SpellDescription$ Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. Surveil 1 (Look at the top card of your library. You may put that card into your graveyard.) SVar:DBSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.\nSurveil 1. (Look at the top card of your library. You may put it into your graveyard.) diff --git a/forge-gui/res/cardsfolder/t/thoughtbound_phantasm.txt b/forge-gui/res/cardsfolder/t/thoughtbound_phantasm.txt index 718268ba991..f2c53932858 100644 --- a/forge-gui/res/cardsfolder/t/thoughtbound_phantasm.txt +++ b/forge-gui/res/cardsfolder/t/thoughtbound_phantasm.txt @@ -6,4 +6,6 @@ K:Defender T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you surveil, put a +1/+1 counter on CARDNAME SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 S:Mode$ Continuous | Affected$ Card.Self+counters_GE3_P1P1 | AddHiddenKeyword$ CARDNAME can attack as though it didn't have defender. | Description$ As long as CARDNAME has three or more +1/+1 counters on it, it can attack +DeckNeeds:Ability$Surveil +DeckHas:Ability$Counters Oracle:Defender\nWhenever you surveil, put a +1/+1 counter on Thoughtbound Phantasm.\nAs long as Thoughtbound Phantasm has three or more +1/+1 counters on it, it can attack as though it didn't have defender. diff --git a/forge-gui/res/cardsfolder/t/thousand_year_storm.txt b/forge-gui/res/cardsfolder/t/thousand_year_storm.txt index 2ca167294a7..e4425747b73 100644 --- a/forge-gui/res/cardsfolder/t/thousand_year_storm.txt +++ b/forge-gui/res/cardsfolder/t/thousand_year_storm.txt @@ -4,4 +4,5 @@ Types:Enchantment T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell, copy it for each other instant and sorcery spell you've cast before it this turn. You may choose new targets for the copies. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ X | References$ X SVar:X:TriggerObjectsCurrentCastSpells$Valid Sorcery.YouCtrl,Instant.YouCtrl/Minus.1 +DeckHints:Type$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell, copy it for each other instant and sorcery spell you've cast before it this turn. You may choose new targets for the copies. diff --git a/forge-gui/res/cardsfolder/t/trostani_discordant.txt b/forge-gui/res/cardsfolder/t/trostani_discordant.txt index 53c3ed895e4..a6c268ead08 100644 --- a/forge-gui/res/cardsfolder/t/trostani_discordant.txt +++ b/forge-gui/res/cardsfolder/t/trostani_discordant.txt @@ -8,4 +8,5 @@ SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ w_1_1_soldier_lifelink T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigGainControl | TriggerDescription$ At the beginning of your end step, each player gains control of all creatures they own. SVar:TrigGainControl:DB$ RepeatEach | RepeatPlayers$ Player | AILogic$ GainControlOwns | RepeatSubAbility$ DBGainControl | SpellDescription$ Each player gains control of all creatures they own. SVar:DBGainControl:DB$ GainControl | AllValid$ Creature.RememberedPlayerOwn | NewController$ Player.IsRemembered +DeckHas:Ability$Token Oracle:Other creatures you control get +1/+1.\nWhen Trostani Discordant enters the battlefield, create two 1/1 white Soldier creature tokens with lifelink.\nAt the beginning of your end step, each player gains control of all creatures they own. diff --git a/forge-gui/res/cardsfolder/t/truefire_captain.txt b/forge-gui/res/cardsfolder/t/truefire_captain.txt index 9686427b472..3c254c3ef0f 100644 --- a/forge-gui/res/cardsfolder/t/truefire_captain.txt +++ b/forge-gui/res/cardsfolder/t/truefire_captain.txt @@ -7,4 +7,5 @@ T:Mode$ DamageDoneOnce | Execute$ TrigDamage | ValidTarget$ Card.Self | TriggerZ SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Player | TgtPrompt$ Select target player | NumDmg$ X | References$ X SVar:X:TriggerCount$DamageAmount SVar:HasCombatEffect:TRUE +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\nWhenever Truefire Captain is dealt damage, it deals that much damage to target player. diff --git a/forge-gui/res/cardsfolder/u/unexplained_disappearance.txt b/forge-gui/res/cardsfolder/u/unexplained_disappearance.txt index 5f90caabb59..761e0b83aea 100644 --- a/forge-gui/res/cardsfolder/u/unexplained_disappearance.txt +++ b/forge-gui/res/cardsfolder/u/unexplained_disappearance.txt @@ -3,4 +3,5 @@ ManaCost:1 U Types:Instant A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Hand | Subability$ DBSurveil | SpellDescription$ Return target creature to its owner's hand. Surveil 1 (Look at the top card of your library. You may put that card into your graveyard.) SVar:DBSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Return target creature to its owner's hand.\nSurveil 1. (Look at the top card of your library. You may put that card into your graveyard.) diff --git a/forge-gui/res/cardsfolder/v/venerated_loxodon.txt b/forge-gui/res/cardsfolder/v/venerated_loxodon.txt index f5add8bf2ce..09f861fd655 100644 --- a/forge-gui/res/cardsfolder/v/venerated_loxodon.txt +++ b/forge-gui/res/cardsfolder/v/venerated_loxodon.txt @@ -5,4 +5,5 @@ PT:4/4 K:Convoke T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounterAll | TriggerDescription$ When CARDNAME enters the battlefield, put a +1/+1 counter on each creature that convoked it. SVar:TrigPutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.convoked | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of the creature's color.)\nWhen Venerated Loxodon enters the battlefield, put a +1/+1 counter on each creature that convoked it. diff --git a/forge-gui/res/cardsfolder/v/vraska_regal_gorgon.txt b/forge-gui/res/cardsfolder/v/vraska_regal_gorgon.txt index af5df6d1ba6..97a352881c4 100644 --- a/forge-gui/res/cardsfolder/v/vraska_regal_gorgon.txt +++ b/forge-gui/res/cardsfolder/v/vraska_regal_gorgon.txt @@ -7,4 +7,5 @@ SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Menace A:AB$ Destroy | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Destroy target creature. A:AB$ PutCounterAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ X | Reference$ X | SpellDescription$ For each creature card in your graveyard, put a +1/+1 counter on each creature you control. SVar:X:Count$ValidGraveyard Creature.YouCtrl +DeckHas:Ability$Counters Oracle:[+2]: Put a +1/+1 counter on up to one target creature. That creature gains menace until end of turn.\n[-3]: Destroy target creature.\n[-10]: For each creature card in your graveyard, put a +1/+1 counter on each creature you control. diff --git a/forge-gui/res/cardsfolder/w/wand_of_vertebrae.txt b/forge-gui/res/cardsfolder/w/wand_of_vertebrae.txt index f110a982d8d..bea9f97917b 100644 --- a/forge-gui/res/cardsfolder/w/wand_of_vertebrae.txt +++ b/forge-gui/res/cardsfolder/w/wand_of_vertebrae.txt @@ -3,4 +3,5 @@ ManaCost:1 Types:Artifact A:AB$ Mill | Cost$ T | Defined$ You | NumCards$ 1 | SpellDescription$ Put the top card of your library into your graveyard. A:AB$ ChangeZone | Cost$ 2 T Exile<1/CARDNAME> | Origin$ Graveyard | Destination$ Library | TargetMin$ 0 | TargetMax$ 5 | Shuffle$ True | TgtPrompt$ Select target card in your graveyard | ValidTgts$ Card.YouCtrl | SpellDescription$ Shuffle up to five target cards from your graveyard into your library. +DeckHas:Ability$Graveyard Oracle:{T}: Put the top card of your library into your graveyard.\n{2}, {T}, Exile Wand of Vertebrae: Shuffle up to five target cards from your graveyard into your library. diff --git a/forge-gui/res/cardsfolder/w/watcher_in_the_mist.txt b/forge-gui/res/cardsfolder/w/watcher_in_the_mist.txt index ba3f6aa313e..e2caac36008 100644 --- a/forge-gui/res/cardsfolder/w/watcher_in_the_mist.txt +++ b/forge-gui/res/cardsfolder/w/watcher_in_the_mist.txt @@ -5,4 +5,5 @@ PT:3/4 K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters the battlefield, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) SVar:TrigSurveil:DB$ Surveil | Defined$ You | Amount$ 2 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flying\nWhen Watcher in the Mist enters the battlefield, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on the top of your library in any order.) diff --git a/forge-gui/res/cardsfolder/w/wee_dragonauts.txt b/forge-gui/res/cardsfolder/w/wee_dragonauts.txt index 029b30cf7d6..ca007c6b11c 100644 --- a/forge-gui/res/cardsfolder/w/wee_dragonauts.txt +++ b/forge-gui/res/cardsfolder/w/wee_dragonauts.txt @@ -6,5 +6,6 @@ K:Flying T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast an instant or sorcery spell, CARDNAME gets +2/+0 until end of turn. SVar:TrigPump:DB$Pump | Defined$ Self | NumAtt$ 2 SVar:BuffedBy:Instant,Sorcery +DeckHints:Type$Instant|Sorcery SVar:Picture:http://www.wizards.com/global/images/magic/general/wee_dragonauts.jpg Oracle:Flying\nWhenever you cast an instant or sorcery spell, Wee Dragonauts gets +2/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/w/whisper_agent.txt b/forge-gui/res/cardsfolder/w/whisper_agent.txt index b681e45523c..8ed6266614a 100644 --- a/forge-gui/res/cardsfolder/w/whisper_agent.txt +++ b/forge-gui/res/cardsfolder/w/whisper_agent.txt @@ -5,4 +5,5 @@ PT:3/2 K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters the battlefield, surveil 1. (Look at the top card of your library. You may put it into your graveyard.) SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil & Ability$Graveyard Oracle:Flash\nWhen Whisper Agent enters the battlefield, surveil 1. (Look at the top card of your library. You may put it into your graveyard.) diff --git a/forge-gui/res/cardsfolder/w/whispering_snitch.txt b/forge-gui/res/cardsfolder/w/whispering_snitch.txt index d14a81ca909..3ae5c96b86e 100644 --- a/forge-gui/res/cardsfolder/w/whispering_snitch.txt +++ b/forge-gui/res/cardsfolder/w/whispering_snitch.txt @@ -5,5 +5,6 @@ PT:1/3 T:Mode$ Surveil | ValidPlayer$ You | TriggerZones$ Battlefield | OnlyFirst$ True | Execute$ TrigDamageAll | TriggerDescription$ Whenever you surveil for the first time each turn, CARDNAME deals 1 damage to each opponent and you gain 1 life. SVar:TrigDamageAll:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ 1 | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 +DeckNeeds:Ability$Surveil DeckHas:Ability$LifeGain Oracle:Whenever you surveil for the first time each turn, Whispering Snitch deals 1 damage to each opponent and you gain 1 life. diff --git a/forge-gui/res/cardsfolder/w/wojek_bodyguard.txt b/forge-gui/res/cardsfolder/w/wojek_bodyguard.txt index 99a850f5738..10290fc1976 100644 --- a/forge-gui/res/cardsfolder/w/wojek_bodyguard.txt +++ b/forge-gui/res/cardsfolder/w/wojek_bodyguard.txt @@ -4,4 +4,5 @@ Types:Creature Human Soldier PT:3/3 K:Mentor K:CARDNAME can't attack or block alone. +DeckHas:Ability$Counters Oracle:Mentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\nWojek Bodyguard can't attack or block alone. diff --git a/forge-gui/res/cardsfolder/w/worldsoul_colossus.txt b/forge-gui/res/cardsfolder/w/worldsoul_colossus.txt index 65cc976eb40..959f30246da 100644 --- a/forge-gui/res/cardsfolder/w/worldsoul_colossus.txt +++ b/forge-gui/res/cardsfolder/w/worldsoul_colossus.txt @@ -5,4 +5,5 @@ PT:0/0 K:Convoke K:etbCounter:P1P1:X SVar:X:Count$xPaid +DeckHas:Ability$Counters Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.)\nWorldsoul Colossus enters the battlefield with X +1/+1 counters on it. From 12583fe80a086517671c77f21bb2ac5a26f6081e Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 12 Oct 2018 09:01:55 +0300 Subject: [PATCH 19/48] - Removed a duplicate DeckHas in Assure // Assemble. --- forge-gui/res/cardsfolder/a/assure_assemble.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/a/assure_assemble.txt b/forge-gui/res/cardsfolder/a/assure_assemble.txt index 092e54f9cc1..255b81014fe 100644 --- a/forge-gui/res/cardsfolder/a/assure_assemble.txt +++ b/forge-gui/res/cardsfolder/a/assure_assemble.txt @@ -4,7 +4,6 @@ Types:Instant AlternateMode:Split A:SP$ PutCounter | Cost$ G/W G/W | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature. It gains indestructible until end of turn. SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Indestructible -DeckHas:Ability$Counters & Ability$Token Oracle:Put a +1/+1 counter on target creature. It gains indestructible until end of turn. ALTERNATE From 7cac1ecad75d741c5f13ba22244d5047b47651fe Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 12 Oct 2018 11:03:25 +0300 Subject: [PATCH 20/48] - Ability$Instant... -> Type$Instant --- forge-gui/res/cardsfolder/b/beamsplitter_mage.txt | 2 +- forge-gui/res/cardsfolder/m/murmuring_mystic.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt b/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt index a83584e2a6c..771b067a897 100644 --- a/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt +++ b/forge-gui/res/cardsfolder/b/beamsplitter_mage.txt @@ -4,5 +4,5 @@ Types:Creature Vedalken Wizard PT:2/2 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | IsSingleTarget$ True | TargetsValid$ Card.Self | CanTargetOtherCondition$ Creature.YouCtrl | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery that targets only CARDNAME, if you control one or more other creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Controller$ You | CopyForEachCanTarget$ Creature.YouCtrl | ChooseOnlyOne$ True -DeckHints:Ability$Instant|Sorcery +DeckHints:Type$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell that targets only Beamsplitter Mage, if you control one or more other creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature. diff --git a/forge-gui/res/cardsfolder/m/murmuring_mystic.txt b/forge-gui/res/cardsfolder/m/murmuring_mystic.txt index 7947d0ef419..76f848425af 100644 --- a/forge-gui/res/cardsfolder/m/murmuring_mystic.txt +++ b/forge-gui/res/cardsfolder/m/murmuring_mystic.txt @@ -5,6 +5,6 @@ PT:1/5 T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you cast an instant or sorcery spell, create a 1/1 blue Bird Illusion creature token with flying. SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenScript$ u_1_1_bird_illusion_flying SVar:BuffedBy:Instant,Sorcery -DeckHints:Ability$Instant|Sorcery +DeckHints:Type$Instant|Sorcery DeckHas:Ability$Token Oracle:Whenever you cast an instant or sorcery spell, create a 1/1 blue Bird Illusion creature token with flying. From bf6a92663fad47ddf65d4ccaebf24aa26cfc1657 Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 12 Oct 2018 12:32:40 +0300 Subject: [PATCH 21/48] - Added Ability$LifeGain hint to several cards. --- forge-gui/res/cardsfolder/d/dawn_of_hope.txt | 2 +- forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt | 2 +- forge-gui/res/cardsfolder/h/haazda_marshal.txt | 2 +- forge-gui/res/cardsfolder/h/hunted_witness.txt | 2 +- forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt | 2 +- forge-gui/res/cardsfolder/l/ledev_champion.txt | 2 +- forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt | 2 +- forge-gui/res/cardsfolder/s/sworn_companions.txt | 2 +- forge-gui/res/cardsfolder/t/trostani_discordant.txt | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/forge-gui/res/cardsfolder/d/dawn_of_hope.txt b/forge-gui/res/cardsfolder/d/dawn_of_hope.txt index b53adb802e6..65c4c6d514d 100644 --- a/forge-gui/res/cardsfolder/d/dawn_of_hope.txt +++ b/forge-gui/res/cardsfolder/d/dawn_of_hope.txt @@ -4,5 +4,5 @@ Types:Enchantment T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigDraw | TriggerDescription$ Whenever you gain life, you may pay {2}. If you do, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 2 | Defined$ You | NumCards$ 1 A:AB$ Token | Cost$ 3 W | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Create a 1/1 white Soldier creature token with lifelink. -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Whenever you gain life, you may pay {2}. If you do, draw a card.\n{3}{W}: Create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt b/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt index 4c998fe93ce..dcb4c3710bb 100644 --- a/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt +++ b/forge-gui/res/cardsfolder/e/emmara_soul_of_the_accord.txt @@ -4,5 +4,5 @@ Types:Legendary Creature Elf Cleric PT:2/2 T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME becomes tapped, create a 1/1 white Soldier creature token with lifelink. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Whenever Emmara, Soul of the Accord becomes tapped, create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/h/haazda_marshal.txt b/forge-gui/res/cardsfolder/h/haazda_marshal.txt index 62edb4876d3..06e8c1bce95 100644 --- a/forge-gui/res/cardsfolder/h/haazda_marshal.txt +++ b/forge-gui/res/cardsfolder/h/haazda_marshal.txt @@ -5,5 +5,5 @@ PT:1/1 T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | CheckSVar$ AttackerTest | SVarCompare$ GE2 | NoResolvingCheck$ True | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME and at least two other creatures attack, create a 1/1 white Soldier creature token with lifelink. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink SVar:AttackerTest:Count$Valid Creature.attacking+Other -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Whenever Haazda Marshal and at least two other creatures attack, create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/h/hunted_witness.txt b/forge-gui/res/cardsfolder/h/hunted_witness.txt index 3f6aa70e840..39f16b0a11d 100644 --- a/forge-gui/res/cardsfolder/h/hunted_witness.txt +++ b/forge-gui/res/cardsfolder/h/hunted_witness.txt @@ -4,6 +4,6 @@ Types:Creature Human PT:1/1 T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, create a 1/1 white Soldier creature token with lifelink. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain SVar:SacMe:1 Oracle:When Hunted Witness dies, create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt b/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt index caf403eb29a..4f92a03e2f1 100644 --- a/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt +++ b/forge-gui/res/cardsfolder/i/izoni_thousand_eyed.txt @@ -7,5 +7,5 @@ SVar:TrigToken:DB$Token | TokenAmount$ X | TokenName$ Insect | TokenTypes$ Creat SVar:X:Count$TypeInYourYard.Creature A:AB$ GainLife | Cost$ B G Sac<1/Creature.Other/another creature> | Defined$ You | LifeAmount$ 1 | SubAbility$ DBDraw | SpellDescription$ You gain 1 life and draw a card. SVar:DBDraw:DB$ Draw | NumCards$ 1 -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Undergrowth — When Izoni, Thousand-Eyed enters the battlefield, create a 1/1 black and green Insect creature token for each creature card in your graveyard.\n{B}{G}, Sacrifice another creature: You gain 1 life and draw a card. diff --git a/forge-gui/res/cardsfolder/l/ledev_champion.txt b/forge-gui/res/cardsfolder/l/ledev_champion.txt index 4f8e53d5f15..761277c4199 100644 --- a/forge-gui/res/cardsfolder/l/ledev_champion.txt +++ b/forge-gui/res/cardsfolder/l/ledev_champion.txt @@ -11,5 +11,5 @@ SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$Valid Creature.YouCtrl SVar:Y:Remembered$Amount A:AB$ Token | Cost$ 3 G W | TokenAmount$ 1 | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Create a 1/1 white Soldier creature token with lifelink. -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Whenever Ledev Champion attacks, you may tap any number of untapped creatures you control. Ledev Champion gets +1/+1 until end of turn for each creature tapped this way.\n{3}{G}{W}: Create a 1/1 white Soldier creature token with lifelink. diff --git a/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt b/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt index c9a7aac646e..9eefe598548 100644 --- a/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt +++ b/forge-gui/res/cardsfolder/m/march_of_the_multitudes.txt @@ -4,5 +4,5 @@ Types:Instant K:Convoke A:SP$ Token | Cost$ X G W W | TokenAmount$ X | References$ X | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Create X 1/1 white Soldier creature tokens with lifelink. SVar:X:Count$xPaid -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of the creature's color.)\nCreate X 1/1 white Soldier creature tokens with lifelink. diff --git a/forge-gui/res/cardsfolder/s/sworn_companions.txt b/forge-gui/res/cardsfolder/s/sworn_companions.txt index e2ed080c0a3..6504302ef29 100644 --- a/forge-gui/res/cardsfolder/s/sworn_companions.txt +++ b/forge-gui/res/cardsfolder/s/sworn_companions.txt @@ -2,5 +2,5 @@ Name:Sworn Companions ManaCost:2 W Types:Sorcery A:SP$ Token | Cost$ 2 W | TokenAmount$ 2 | TokenScript$ w_1_1_soldier_lifelink -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Creature two 1/1 white Soldier creature tokens with lifelink. diff --git a/forge-gui/res/cardsfolder/t/trostani_discordant.txt b/forge-gui/res/cardsfolder/t/trostani_discordant.txt index a6c268ead08..f93ad01c605 100644 --- a/forge-gui/res/cardsfolder/t/trostani_discordant.txt +++ b/forge-gui/res/cardsfolder/t/trostani_discordant.txt @@ -8,5 +8,5 @@ SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ w_1_1_soldier_lifelink T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigGainControl | TriggerDescription$ At the beginning of your end step, each player gains control of all creatures they own. SVar:TrigGainControl:DB$ RepeatEach | RepeatPlayers$ Player | AILogic$ GainControlOwns | RepeatSubAbility$ DBGainControl | SpellDescription$ Each player gains control of all creatures they own. SVar:DBGainControl:DB$ GainControl | AllValid$ Creature.RememberedPlayerOwn | NewController$ Player.IsRemembered -DeckHas:Ability$Token +DeckHas:Ability$Token & Ability$LifeGain Oracle:Other creatures you control get +1/+1.\nWhen Trostani Discordant enters the battlefield, create two 1/1 white Soldier creature tokens with lifelink.\nAt the beginning of your end step, each player gains control of all creatures they own. From 64116fb055d13df33a79210c476b62589f9a0a18 Mon Sep 17 00:00:00 2001 From: pfirpfel Date: Sat, 13 Oct 2018 05:04:50 +0000 Subject: [PATCH 22/48] Chaos draft --- .../item/generation/ChaosBoosterSupplier.java | 26 ++++++++++++ .../main/java/forge/limited/BoosterDraft.java | 40 +++++++++++++++++++ .../java/forge/limited/LimitedPoolType.java | 3 +- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 forge-core/src/main/java/forge/item/generation/ChaosBoosterSupplier.java diff --git a/forge-core/src/main/java/forge/item/generation/ChaosBoosterSupplier.java b/forge-core/src/main/java/forge/item/generation/ChaosBoosterSupplier.java new file mode 100644 index 00000000000..a6dc60d6d83 --- /dev/null +++ b/forge-core/src/main/java/forge/item/generation/ChaosBoosterSupplier.java @@ -0,0 +1,26 @@ +package forge.item.generation; + +import forge.card.CardEdition; +import forge.item.BoosterPack; +import forge.item.PaperCard; + +import java.util.List; + +public class ChaosBoosterSupplier implements IUnOpenedProduct { + private List sets; + + public ChaosBoosterSupplier(List sets) { + this.sets = sets; + } + + @Override + public List get() { + if (sets.size() == 0) { + System.out.println("No chaos boosters left to supply."); + return null; + } + final CardEdition set = sets.remove(0); + final BoosterPack pack = new BoosterPack(set.getCode(), set.getBoosterTemplate()); + return pack.getCards(); + } +} diff --git a/forge-gui/src/main/java/forge/limited/BoosterDraft.java b/forge-gui/src/main/java/forge/limited/BoosterDraft.java index c2fcfe9e3c0..ef22d7b8e76 100644 --- a/forge-gui/src/main/java/forge/limited/BoosterDraft.java +++ b/forge-gui/src/main/java/forge/limited/BoosterDraft.java @@ -17,12 +17,17 @@ */ package forge.limited; +import com.google.common.base.Predicate; import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import forge.StaticData; import forge.card.CardEdition; import forge.deck.CardPool; import forge.deck.Deck; import forge.item.PaperCard; import forge.item.SealedProduct; +import forge.item.generation.ChaosBoosterSupplier; import forge.item.generation.IUnOpenedProduct; import forge.item.generation.UnOpenedProduct; import forge.model.CardBlock; @@ -35,6 +40,7 @@ import forge.util.TextUtil; import forge.util.gui.SGuiChoose; import forge.util.gui.SOptionPane; import forge.util.storage.IStorage; +import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.ArrayUtils; import java.io.File; @@ -168,6 +174,40 @@ public class BoosterDraft implements IBoosterDraft { } break; + case Chaos: + final CardEdition.Collection allEditions = StaticData.instance().getEditions(); + final Iterable chaosDraftEditions = Iterables.filter(allEditions.getOrderedEditions(), new Predicate() { + @Override + public boolean apply(final CardEdition cardEdition) { + boolean isExpansion = cardEdition.getType().equals(CardEdition.Type.EXPANSION); + boolean isCoreSet = cardEdition.getType().equals(CardEdition.Type.CORE); + boolean isReprintSet = cardEdition.getType().equals(CardEdition.Type.REPRINT); + if (isExpansion || isCoreSet || isReprintSet) { + // Only allow sets with 15 cards in booster packs + if (cardEdition.hasBoosterTemplate()) { + final List> slots = cardEdition.getBoosterTemplate().getSlots(); + int boosterSize = 0; + for (Pair slot : slots) { + boosterSize += slot.getRight(); + } + return boosterSize == 15; + } + } + return false; + } + }); + + // Randomize order of sets + List shuffled = Lists.newArrayList(chaosDraftEditions); + Collections.shuffle(shuffled); + + final Supplier> ChaosDraftSupplier = new ChaosBoosterSupplier(shuffled); + + for (int i = 0; i < 3; i++) { + this.product.add(ChaosDraftSupplier); + } + break; + default: throw new NoSuchElementException("Draft for mode " + this.draftFormat + " has not been set up!"); } diff --git a/forge-gui/src/main/java/forge/limited/LimitedPoolType.java b/forge-gui/src/main/java/forge/limited/LimitedPoolType.java index 758d892a8fa..2f52015e1e8 100644 --- a/forge-gui/src/main/java/forge/limited/LimitedPoolType.java +++ b/forge-gui/src/main/java/forge/limited/LimitedPoolType.java @@ -4,7 +4,8 @@ public enum LimitedPoolType { Full("Full Cardpool"), Block("Block / Set"), FantasyBlock("Fantasy Block"), - Custom("Custom Cube"); + Custom("Custom Cube"), + Chaos("Chaos Draft"); private final String displayName; private LimitedPoolType(String name) { From 30831c734371bde118df08ff202f531d961e55f1 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 08:10:06 +0300 Subject: [PATCH 23/48] - Increase the default memory size values for Android Maven project to allow it to compile with the growing code base. --- forge-gui-android/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index cff63a76f66..686f4a26ecc 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -5,8 +5,8 @@ yyyyMMdd-HHmm jar - -Xms128m - -Xmx1024m + -Xms1024m + -Xmx1536m 1.6.16.001 keystore alias From 9c863e53425d25f3a5a0dc3be510886512c5eba9 Mon Sep 17 00:00:00 2001 From: tehdiplomat Date: Sat, 13 Oct 2018 11:34:05 -0400 Subject: [PATCH 24/48] Updating release files --- forge-gui/release-files/ANNOUNCEMENTS.txt | 2 +- forge-gui/release-files/CHANGES.txt | 3 ++- forge-gui/release-files/ISSUES.txt | 6 +----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/forge-gui/release-files/ANNOUNCEMENTS.txt b/forge-gui/release-files/ANNOUNCEMENTS.txt index 973e7e98943..554eaa194c4 100644 --- a/forge-gui/release-files/ANNOUNCEMENTS.txt +++ b/forge-gui/release-files/ANNOUNCEMENTS.txt @@ -1,5 +1,5 @@ #Add one announcement per line -M19 is here! Report your issues in the release thread, and we'll kick off a new release soon with fixes. +GRN is finished! Please let us know if you see any other bugs most especially for the newers cards. [b]Forge now requires Java 8 (or newer). You will not be able to start the game if you are not yet running Java 8.[/b] We have a Discord server for hanging out with Forge devs and other Forge fans. Feel free to [url=https://discord.gg/3v9JCVr]jump on in and say hi[/url]! Online Multiplayer is once again functional! \ No newline at end of file diff --git a/forge-gui/release-files/CHANGES.txt b/forge-gui/release-files/CHANGES.txt index 2040ced2470..d162b6af1d5 100644 --- a/forge-gui/release-files/CHANGES.txt +++ b/forge-gui/release-files/CHANGES.txt @@ -1,5 +1,5 @@ - Guilds of Ravnica - -Most of Guilds of Ravnica has been implemented and is available in this release. We're working hard on getting the last few cards added. +All of Guilds of Ravnica has been implemented and is available in this release. - Token Changes - Some work that streamlines tokens is going on under the hood. This may be the cause of missing/incorrect token images if you notice any, though we don't expect there to be any issues. @@ -9,4 +9,5 @@ Added Randomized Standard Quest World with LDA archetype generated decks as duel In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. - Bug fixes - +Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. diff --git a/forge-gui/release-files/ISSUES.txt b/forge-gui/release-files/ISSUES.txt index 00a6e947bd4..3755d9b8044 100644 --- a/forge-gui/release-files/ISSUES.txt +++ b/forge-gui/release-files/ISSUES.txt @@ -1,7 +1,3 @@ -Online multiplayer functionality has been restored, but is still a Work in Progress. We do have a dedicated developer actively working on the online multiplayer feature. - -"When you pay a cost" trigger for M19 cards don't work 100% correctly yet. We're still working on it. - -Other known issues are here: https://git.cardforge.org/core-developers/forge/issues +Known issues are here: https://git.cardforge.org/core-developers/forge/issues Feel free to report your own there if you have any. \ No newline at end of file From fc6017d073b73e556b3672865444170cff33aca2 Mon Sep 17 00:00:00 2001 From: tehdiplomat Date: Sat, 13 Oct 2018 11:36:40 -0400 Subject: [PATCH 25/48] Update GRN rankings --- forge-gui/res/draft/rankings.txt | 479 +++++++++++++++---------------- 1 file changed, 237 insertions(+), 242 deletions(-) diff --git a/forge-gui/res/draft/rankings.txt b/forge-gui/res/draft/rankings.txt index f5db72c1884..da3b4448a9d 100644 --- a/forge-gui/res/draft/rankings.txt +++ b/forge-gui/res/draft/rankings.txt @@ -3,256 +3,251 @@ #2|Aurelia, Exemplar of Justice|M|GRN #3|Light of the Legion|R|GRN #4|Dream Eater|M|GRN -#5|March of the Multitudes|M|GRN +#5|Izoni, Thousand-Eyed|R|GRN #6|Vraska, Golgari Queen|M|GRN -#7|Assassin's Trophy|R|GRN -#8|Underrealm Lich|M|GRN -#9|Niv-Mizzet, Parun|R|GRN -#10|Trostani Discordant|M|GRN +#7|Niv-Mizzet, Parun|R|GRN +#8|Assassin's Trophy|R|GRN +#9|Trostani Discordant|M|GRN +#10|Underrealm Lich|M|GRN #11|Status Statue|U|GRN -#12|Price of Fame|U|GRN -#13|Conclave Tribunal|U|GRN -#14|Izoni, Thousand-Eyed|R|GRN -#15|Lava Coil|U|GRN -#16|Dawn of Hope|R|GRN -#17|Legion Warboss|R|GRN -#18|Find|R|GRN -#19|Integrity Intervention|U|GRN -#20|Justice Strike|U|GRN -#21|Tajic, Legion's Edge|R|GRN -#22|Pelt Collector|R|GRN -#23|Ral, Izzet Viceroy|M|GRN -#24|Emmara, Soul of the Accord|R|GRN -#25|Swiftblade Vindicator|R|GRN -#26|Assure|R|GRN -#27|Chamber Sentry|R|GRN -#28|Bounty of Might|R|GRN -#29|Nightveil Predator|U|GRN -#30|Venerated Loxodon|R|GRN +#12|Find Finality|R|GRN +#13|March of the Multitudes|M|GRN +#14|Price of Fame|U|GRN +#15|Conclave Tribunal|U|GRN +#16|Nullhide Ferox|M|GRN +#17|Tajic, Legion's Edge|R|GRN +#18|Ral, Izzet Viceroy|M|GRN +#19|Lava Coil|U|GRN +#20|Integrity Intervention|U|GRN +#21|Dawn of Hope|R|GRN +#22|Legion Warboss|R|GRN +#23|Venerated Loxodon|R|GRN +#24|Justice Strike|U|GRN +#25|Pelt Collector|R|GRN +#26|Swiftblade Vindicator|R|GRN +#27|Assure Assemble|R|GRN +#28|Chamber Sentry|R|GRN +#29|Bounty of Might|R|GRN +#30|Nightveil Predator|U|GRN #31|Crackling Drake|U|GRN #32|Etrata, the Silencer|R|GRN -#33|Nullhide Ferox|M|GRN -#34|Golgari Findbroker|U|GRN -#35|Knight of Autumn|R|GRN -#36|Conclave Cavalier|U|GRN -#37|Thief of Sanity|R|GRN -#38|Response|R|GRN -#39|Deafening Clarion|R|GRN -#40|Truefire Captain|U|GRN -#41|Deadly Visit|C|GRN -#42|Midnight Reaper|R|GRN -#43|Lazav, the Multifarious|M|GRN -#44|Boros Challenger|U|GRN -#45|Ritual of Soot|R|GRN -#46|Rampaging Monument|U|GRN -#47|Luminous Bonds|C|GRN -#48|Chemister's Insight|U|GRN -#49|Artful Takedown|C|GRN -#50|Beast Whisperer|R|GRN -#51|Expansion|R|GRN -#52|Affectionate Indrik|U|GRN -#53|Connive|R|GRN -#54|Hatchery Spider|R|GRN -#55|Charnel Troll|R|GRN -#56|Rosemane Centaur|C|GRN -#57|Hypothesizzle|C|GRN -#58|Arclight Phoenix|M|GRN -#59|Swarm Guildmage|U|GRN -#60|House Guildmage|U|GRN -#61|League Guildmage|U|GRN -#62|Legion Guildmage|U|GRN -#63|Glowspore Shaman|U|GRN -#64|Wee Dragonauts|U|GRN -#65|Kraul Harpooner|U|GRN -#66|Gravitic Punch|C|GRN -#67|Dead Weight|C|GRN -#68|District Guide|U|GRN -#69|Command the Storm|C|GRN -#70|Inescapable Blaze|U|GRN -#71|Conclave Guildmage|U|GRN -#72|Ledev Champion|U|GRN -#73|Discovery|U|GRN -#74|Roc Charger|U|GRN -#75|Citywide Bust|R|GRN -#76|Plaguecrafter|U|GRN -#77|Camaraderie|R|GRN -#78|Hired Poisoner|C|GRN -#79|Capture Sphere|C|GRN -#80|Firemind's Research|R|GRN -#81|Quasiduplicate|R|GRN -#82|Arboretum Elemental|U|GRN -#83|Unexplained Disappearance|C|GRN -#84|Sunhome Stalwart|U|GRN -#85|Chromatic Lantern|R|GRN -#86|Goblin Cratermaker|U|GRN -#87|Notion Rain|C|GRN -#88|Invert|U|GRN +#33|Emmara, Soul of the Accord|R|GRN +#34|Beast Whisperer|R|GRN +#35|Golgari Findbroker|U|GRN +#36|Knight of Autumn|R|GRN +#37|Blood Operative|R|GRN +#38|Conclave Cavalier|U|GRN +#39|Thief of Sanity|R|GRN +#40|Charnel Troll|R|GRN +#41|Deafening Clarion|R|GRN +#42|Truefire Captain|U|GRN +#43|Connive Concoct|R|GRN +#44|Hatchery Spider|R|GRN +#45|Quasiduplicate|R|GRN +#46|Response Resurgence|R|GRN +#47|Arclight Phoenix|M|GRN +#48|Midnight Reaper|R|GRN +#49|Lazav, the Multifarious|M|GRN +#50|Ritual of Soot|R|GRN +#51|Boros Challenger|U|GRN +#52|Deadly Visit|C|GRN +#53|Roc Charger|U|GRN +#54|Rampaging Monument|U|GRN +#55|Luminous Bonds|C|GRN +#56|Artful Takedown|C|GRN +#57|Expansion Explosion|R|GRN +#58|Murmuring Mystic|U|GRN +#59|Nightveil Sprite|U|GRN +#60|Swarm Guildmage|U|GRN +#61|House Guildmage|U|GRN +#62|League Guildmage|U|GRN +#63|Legion Guildmage|U|GRN +#64|Glowspore Shaman|U|GRN +#65|Disinformation Campaign|U|GRN +#66|Wee Dragonauts|U|GRN +#67|Discovery Dispersal|U|GRN +#68|Kraul Harpooner|U|GRN +#69|Flower Flourish|U|GRN +#70|Dead Weight|C|GRN +#71|Rosemane Centaur|C|GRN +#72|Hypothesizzle|C|GRN +#73|District Guide|U|GRN +#74|Chemister's Insight|U|GRN +#75|Command the Storm|C|GRN +#76|Inescapable Blaze|U|GRN +#77|Invert Invent|U|GRN +#78|Conclave Guildmage|U|GRN +#79|Affectionate Indrik|U|GRN +#80|Dimir Spybug|U|GRN +#81|Citywide Bust|R|GRN +#82|Plaguecrafter|U|GRN +#83|Camaraderie|R|GRN +#84|Capture Sphere|C|GRN +#85|Firemind's Research|R|GRN +#86|Arboretum Elemental|U|GRN +#87|Sunhome Stalwart|U|GRN +#88|Goblin Cratermaker|U|GRN #89|Erratic Cyclops|R|GRN #90|Citywatch Sphinx|U|GRN #91|Skyknight Legionnaire|C|GRN #92|Watcher in the Mist|C|GRN -#93|Dimir Spybug|U|GRN -#94|Siege Wurm|C|GRN -#95|Risk Factor|R|GRN -#96|Flower|U|GRN -#97|Inspiring Unicorn|U|GRN -#98|Prey Upon|C|GRN -#99|Severed Strands|C|GRN -#100|Kraul Swarm|U|GRN -#101|Demotion|U|GRN -#102|Murmuring Mystic|U|GRN -#103|Healer's Hawk|C|GRN -#104|Direct Current|C|GRN -#105|Nightveil Sprite|U|GRN -#106|Darkblade Agent|C|GRN -#107|Blood Operative|R|GRN -#108|Swathcutter Giant|U|GRN -#109|Loxodon Restorer|C|GRN -#110|Sprouting Renewal|U|GRN -#111|Beacon Bolt|U|GRN -#112|Undercity Uprising|C|GRN -#113|Flight of Equenauts|U|GRN -#114|Experimental Frenzy|R|GRN -#115|Undercity Necrolisk|U|GRN -#116|Selective Snare|U|GRN -#117|Collar the Culprit|C|GRN -#118|Sacred Foundry|R|GRN -#119|Watery Grave|R|GRN -#120|Temple Garden|R|GRN -#121|Overgrown Tomb|R|GRN -#122|Steam Vents|R|GRN -#123|Dimir Informant|C|GRN -#124|Runaway Steam-Kin|R|GRN -#125|Ionize|R|GRN -#126|Garrison Sergeant|C|GRN -#127|Hunted Witness|C|GRN -#128|Disinformation Campaign|U|GRN -#129|Piston-Fist Cyclops|C|GRN -#130|Parhelion Patrol|C|GRN -#131|Join Shields|U|GRN -#132|Gird for Battle|U|GRN -#133|Gatekeeper Gargoyle|U|GRN -#134|Drowned Secrets|R|GRN -#135|Hellkite Whelp|U|GRN -#136|Spinal Centipede|C|GRN -#137|Burglar Rat|C|GRN -#138|Righteous Blow|C|GRN -#139|Golgari Guildgate|C|GRN -#140|Izzet Guildgate|C|GRN -#141|Selesnya Guildgate|C|GRN -#142|Dimir Guildgate|C|GRN -#143|Boros Guildgate|C|GRN -#144|Thought Erasure|U|GRN -#145|Necrotic Wound|U|GRN -#146|Guild Summit|U|GRN -#147|Whispering Snitch|U|GRN -#148|Vivid Revival|R|GRN -#149|Guildmages' Forum|R|GRN -#150|Molderhulk|U|GRN -#151|Gruesome Menagerie|R|GRN -#152|Centaur Peacemaker|C|GRN -#153|Thoughtbound Phantasm|U|GRN -#154|Ochran Assassin|U|GRN -#155|Circuitous Route|U|GRN -#156|Lotleth Giant|U|GRN -#157|Book Devourer|U|GRN -#158|Worldsoul Colossus|U|GRN -#159|Haazda Marshal|U|GRN -#160|Erstwhile Trooper|C|GRN -#161|Might of the Masses|U|GRN -#162|Wild Ceratok|C|GRN -#163|Ironshell Beetle|C|GRN -#164|Smelt-Ward Minotaur|U|GRN -#165|Cosmotronic Wave|C|GRN -#166|Douser of Lights|C|GRN -#167|Sworn Companions|C|GRN -#168|Intrusive Packbeast|C|GRN -#169|Sinister Sabotage|U|GRN -#170|Barging Sergeant|C|GRN -#171|Hammer Dropper|C|GRN -#172|Goblin Electromancer|C|GRN -#173|Sumala Woodshaper|C|GRN -#174|Bounty Agent|R|GRN -#175|Blade Instructor|C|GRN -#176|Gateway Plaza|C|GRN -#177|Disdainful Stroke|C|GRN -#178|Goblin Banneret|U|GRN -#179|Wojek Bodyguard|C|GRN -#180|Enhanced Surveillance|U|GRN -#181|Ledev Guardian|C|GRN -#182|Beamsplitter Mage|U|GRN -#183|Generous Stray|C|GRN -#184|Vernadi Shieldmate|C|GRN -#185|Pitiless Gorgon|C|GRN -#186|Vigorspore Wurm|C|GRN -#187|Pack's Favor|C|GRN -#188|Hitchclaw Recluse|C|GRN -#189|Sure Strike|C|GRN -#190|Rubblebelt Boar|C|GRN -#191|Ornery Goblin|C|GRN -#192|Fire Urchin|C|GRN -#193|Pilfering Imp|U|GRN -#194|Bartizan Bats|C|GRN -#195|Vedalken Mesmerist|C|GRN -#196|Muse Drake|C|GRN -#197|Leapfrog|C|GRN -#198|Skyline Scout|C|GRN -#199|Radical Idea|C|GRN -#200|Moodmark Painter|C|GRN -#201|Fresh-Faced Recruit|C|GRN -#202|Whisper Agent|C|GRN -#203|Golgari Raiders|U|GRN -#204|Mission Briefing|R|GRN -#205|Chance for Glory|M|GRN -#206|Kraul Foragers|C|GRN -#207|Rhizome Lurcher|C|GRN -#208|Electrostatic Field|U|GRN -#209|Street Riot|U|GRN -#210|Fearless Halberdier|C|GRN -#211|Veiled Shade|C|GRN -#212|Child of Night|C|GRN -#213|Wishcoin Crab|C|GRN -#214|Tenth District Guard|C|GRN -#215|Take Heart|C|GRN -#216|Devkarin Dissident|C|GRN -#217|Narcomoeba|R|GRN -#218|Sonic Assault|C|GRN -#219|Wary Okapi|C|GRN -#220|Izzet Locket|C|GRN -#221|Selesnya Locket|C|GRN -#222|Golgari Locket|C|GRN -#223|Dimir Locket|C|GRN -#224|Boros Locket|C|GRN -#225|Passwall Adept|C|GRN -#226|Omnispell Adept|R|GRN -#227|Wand of Vertebrae|U|GRN -#228|Divine Visitation|M|GRN -#229|Mnemonic Betrayal|M|GRN -#230|Urban Utopia|C|GRN -#231|Wall of Mist|C|GRN -#232|Dazzling Lights|C|GRN -#233|Candlelight Vigil|C|GRN -#234|Mausoleum Secrets|R|GRN -#235|Glaive of the Guildpact|U|GRN -#236|Maximize Velocity|C|GRN -#237|Goblin Locksmith|C|GRN -#238|Grappling Sundew|U|GRN -#239|Crushing Canopy|C|GRN -#240|Torch Courier|C|GRN -#241|Maximize Altitude|C|GRN -#242|Never Happened|C|GRN -#243|Thousand-Year Storm|M|GRN -#244|Silent Dart|U|GRN -#245|Portcullis Vine|C|GRN -#246|Mephitic Vapors|C|GRN -#247|Crush Contraband|U|GRN -#248|Barrier of Bones|C|GRN -#249|Devious Cover-Up|C|GRN -#250|Maniacal Rage|C|GRN -#251|Pause for Reflection|C|GRN -#252|Vicious Rumors|C|GRN -#253|Creeping Chill|U|GRN -#254|Unmoored Ego|R|GRN +#93|Siege Wurm|C|GRN +#94|Risk Factor|R|GRN +#95|Kraul Swarm|U|GRN +#96|Demotion|U|GRN +#97|Healer's Hawk|C|GRN +#98|Direct Current|C|GRN +#99|Unexplained Disappearance|C|GRN +#100|Whisper Agent|C|GRN +#101|Notion Rain|C|GRN +#102|Ledev Champion|U|GRN +#103|Beacon Bolt|U|GRN +#104|Flight of Equenauts|U|GRN +#105|Experimental Frenzy|R|GRN +#106|Inspiring Unicorn|U|GRN +#107|Prey Upon|C|GRN +#108|Severed Strands|C|GRN +#109|Hired Poisoner|C|GRN +#110|Selective Snare|U|GRN +#111|Sacred Foundry|R|GRN +#112|Watery Grave|R|GRN +#113|Temple Garden|R|GRN +#114|Overgrown Tomb|R|GRN +#115|Steam Vents|R|GRN +#116|Chromatic Lantern|R|GRN +#117|Runaway Steam-Kin|R|GRN +#118|Ionize|R|GRN +#119|Whispering Snitch|U|GRN +#120|Goblin Banneret|U|GRN +#121|Thoughtbound Phantasm|U|GRN +#122|Swathcutter Giant|U|GRN +#123|Hunted Witness|C|GRN +#124|Enhanced Surveillance|U|GRN +#125|Piston-Fist Cyclops|C|GRN +#126|Parhelion Patrol|C|GRN +#127|Gird for Battle|U|GRN +#128|Undercity Uprising|C|GRN +#129|Gatekeeper Gargoyle|U|GRN +#130|Hellkite Whelp|U|GRN +#131|Undercity Necrolisk|U|GRN +#132|Spinal Centipede|C|GRN +#133|Burglar Rat|C|GRN +#134|Collar the Culprit|C|GRN +#135|Thought Erasure|U|GRN +#136|Necrotic Wound|U|GRN +#137|Hammer Dropper|C|GRN +#138|Dimir Informant|C|GRN +#139|Guild Summit|U|GRN +#140|Vivid Revival|R|GRN +#141|Guildmages' Forum|R|GRN +#142|Molderhulk|U|GRN +#143|Gruesome Menagerie|R|GRN +#144|Centaur Peacemaker|C|GRN +#145|Darkblade Agent|C|GRN +#146|Wojek Bodyguard|C|GRN +#147|Ochran Assassin|U|GRN +#148|Circuitous Route|U|GRN +#149|Loxodon Restorer|C|GRN +#150|Haazda Marshal|U|GRN +#151|Rhizome Lurcher|C|GRN +#152|Might of the Masses|U|GRN +#153|Generous Stray|C|GRN +#154|Wild Ceratok|C|GRN +#155|Ironshell Beetle|C|GRN +#156|Smelt-Ward Minotaur|U|GRN +#157|Rubblebelt Boar|C|GRN +#158|Cosmotronic Wave|C|GRN +#159|Muse Drake|C|GRN +#160|Sworn Companions|C|GRN +#161|Skyline Scout|C|GRN +#162|Righteous Blow|C|GRN +#163|Intrusive Packbeast|C|GRN +#164|Sinister Sabotage|U|GRN +#165|Barging Sergeant|C|GRN +#166|Sonic Assault|C|GRN +#167|Goblin Electromancer|C|GRN +#168|Sumala Woodshaper|C|GRN +#169|Fresh-Faced Recruit|C|GRN +#170|Bounty Agent|R|GRN +#171|Blade Instructor|C|GRN +#172|Gateway Plaza|C|GRN +#173|Disdainful Stroke|C|GRN +#174|Mission Briefing|R|GRN +#175|Lotleth Giant|U|GRN +#176|Book Devourer|U|GRN +#177|Sprouting Renewal|U|GRN +#178|Worldsoul Colossus|U|GRN +#179|Beamsplitter Mage|U|GRN +#180|Vernadi Shieldmate|C|GRN +#181|Pitiless Gorgon|C|GRN +#182|Vigorspore Wurm|C|GRN +#183|Pack's Favor|C|GRN +#184|Hitchclaw Recluse|C|GRN +#185|Sure Strike|C|GRN +#186|Fire Urchin|C|GRN +#187|Pilfering Imp|U|GRN +#188|Douser of Lights|C|GRN +#189|Bartizan Bats|C|GRN +#190|Leapfrog|C|GRN +#191|Take Heart|C|GRN +#192|Devkarin Dissident|C|GRN +#193|Radical Idea|C|GRN +#194|Golgari Raiders|U|GRN +#195|Ledev Guardian|C|GRN +#196|Chance for Glory|M|GRN +#197|Kraul Foragers|C|GRN +#198|Erstwhile Trooper|C|GRN +#199|Street Riot|U|GRN +#200|Ornery Goblin|C|GRN +#201|Gravitic Punch|C|GRN +#202|Child of Night|C|GRN +#203|Dazzling Lights|C|GRN +#204|Tenth District Guard|C|GRN +#205|Moodmark Painter|C|GRN +#206|Izzet Locket|C|GRN +#207|Selesnya Locket|C|GRN +#208|Golgari Locket|C|GRN +#209|Dimir Locket|C|GRN +#210|Boros Locket|C|GRN +#211|Maximize Altitude|C|GRN +#212|Passwall Adept|C|GRN +#213|Garrison Sergeant|C|GRN +#214|Omnispell Adept|R|GRN +#215|Join Shields|U|GRN +#216|Mnemonic Betrayal|M|GRN +#217|Electrostatic Field|U|GRN +#218|Urban Utopia|C|GRN +#219|Portcullis Vine|C|GRN +#220|Fearless Halberdier|C|GRN +#221|Veiled Shade|C|GRN +#222|Vedalken Mesmerist|C|GRN +#223|Wary Okapi|C|GRN +#224|Mausoleum Secrets|R|GRN +#225|Glaive of the Guildpact|U|GRN +#226|Maximize Velocity|C|GRN +#227|Divine Visitation|M|GRN +#228|Devious Cover-Up|C|GRN +#229|Goblin Locksmith|C|GRN +#230|Drowned Secrets|R|GRN +#231|Grappling Sundew|U|GRN +#232|Crushing Canopy|C|GRN +#233|Maniacal Rage|C|GRN +#234|Mephitic Vapors|C|GRN +#235|Wishcoin Crab|C|GRN +#236|Wall of Mist|C|GRN +#237|Candlelight Vigil|C|GRN +#238|Narcomoeba|R|GRN +#239|Never Happened|C|GRN +#240|Thousand-Year Storm|M|GRN +#241|Silent Dart|U|GRN +#242|Torch Courier|C|GRN +#243|Barrier of Bones|C|GRN +#244|Crush Contraband|U|GRN +#245|Wand of Vertebrae|U|GRN +#246|Creeping Chill|U|GRN +#247|Pause for Reflection|C|GRN +#248|Vicious Rumors|C|GRN +#249|Unmoored Ego|R|GRN //Rank|Name|Rarity|Set #1|Chromium, the Mutable|M|M19 #2|Palladia-Mors, the Ruiner|M|M19 From 67c1c1ef1f8e652f6a299928e316cb06437052e8 Mon Sep 17 00:00:00 2001 From: Blacksmith Date: Sat, 13 Oct 2018 15:40:09 +0000 Subject: [PATCH 26/48] Update README.txt for release --- forge-gui/README.txt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/forge-gui/README.txt b/forge-gui/README.txt index 9bfcd4e83ef..6d5adeec3c1 100644 --- a/forge-gui/README.txt +++ b/forge-gui/README.txt @@ -1,6 +1,6 @@ -Forge: 09/29/2018 ver 1.6.16 +Forge: 10/13/2018 ver 1.6.17 -18176 cards in total. +18204 cards in total. -------------- @@ -8,10 +8,10 @@ Release Notes: -------------- - New Cards - -Vigorspore Wurm; Vedalken Mesmerist; Vernadi Shieldmate; Vraska, Regal Gorgon; Vivid Revival; Vraska's Stoneglare; Vicious Rumors; Veiled Shade; Knight of Autumn; Kraul Foragers; Kraul Raider; Kraul Harpooner; Kraul Swarm; Tajic, Legion's Edge; Take Heart; Torch Courier; Truefire Captain; Thoughtbound Phantasm; Tenth District Guard; Thought Erasure; Trostani Discordant; Circuitous Route; Citywatch Sphinx; Citywide Bust; Conclave Tribunal; Collar the Culprit; Connive; Conclave Guildmage; Crackling Drake; Creeping Chill; Centaur Peacemaker; Camaraderie; Capture Sphere; Cosmotronic Wave; Chance for Glory; Command the Storm; Conclave Cavalier; Chamber Sentry; Crush Contraband; Chemister's Insight; Candlelight Vigil; Guildmages' Forum; Gateway Plaza; Golgari Raiders; Gatekeeper Gargoyle; Golgari Locket; Goblin Banneret; Grappling Sundew; Guild Summit; Garrison Sergeant; Gruesome Menagerie; Golgari Findbroker; Glowspore Shaman; Gird for Battle; Goblin Cratermaker; Glaive of the Guildpact; Generous Stray; Gravitic Punch; Goblin Locksmith; Worldsoul Colossus; Wary Okapi; Watcher in the Mist; Wand of Vertebrae; Wild Ceratok; Wojek Bodyguard; Wishcoin Crab; Whisper Agent; Whispering Snitch; Impervious Greatwurm; Izzet Locket; Ionize; Inescapable Blaze; Invert; Integrity; Inspiring Unicorn; Izoni, Thousand-Eyed; Intrusive Packbeast; Douser of Lights; Dawn of Hope; Demotion; Deafening Clarion; Dimir Spybug; Dimir Informant; Doom Whisperer; District Guide; Dream Eater; Divine Visitation; Deadly Visit; Dazzling Lights; Disinformation Campaign; Darkblade Agent; Drowned Secrets; Devkarin Dissident; Direct Current; Devious Cover-Up; Dimir Locket; Justice Strike; Join Shields; Attendant of Vraska; Assure; Affectionate Indrik; Artful Takedown; Assassin's Trophy; Arboretum Elemental; Aurelia, Exemplar of Justice; Arclight Phoenix; Pelt Collector; Precision Bolt; Passwall Adept; Pitiless Gorgon; Price of Fame; Pause for Reflection; Pack's Favor; Parhelion Patrol; Pilfering Imp; Portcullis Vine; Piston-Fist Cyclops; Ral, Caller of Storms; Rhizome Lurcher; Ral's Dispersal; Roc Charger; Ral's Staticaster; Rosemane Centaur; Ral, Izzet Viceroy; Radical Idea; Ritual of Soot; Risk Factor; Runaway Steam-Kin; Rampaging Monument; Response; Rubblebelt Boar; Light of the Legion; Ledev Champion; Lava Coil; Leapfrog; Lotleth Giant; Loxodon Restorer; Ledev Guardian; Legion Warboss; League Guildmage; Legion Guildmage; Heavenly Blademaster; Hired Poisoner; Haazda Marshal; Hatchery Spider; Hunted Witness; House Guildmage; Healer's Hawk; Hammer Dropper; Hypothesizzle; Hellkite Whelp; Niv-Mizzet, Parun; Never Happened; Notion Rain; Necrotic Wound; Nightveil Sprite; Najeela, the Blade-Blossom ; Nullhide Ferox; Nightveil Predator; Smelt-Ward Minotaur; Swarm Guildmage; Sumala Woodshaper; Sonic Assault; Spinal Centipede; Severed Strands; Sunhome Stalwart; Skyline Scout; Swathcutter Giant; Selesnya Locket; Swiftblade Vindicator; Sprouting Renewal; Status; Silent Dart; Sinister Sabotage; Sworn Companions; Street Riot; Blade Instructor; Book Devourer; Barrier of Bones; Blood Operative; Boros Challenger; Burglar Rat; Barging Sergeant; Bartizan Bats; Bounty Agent; Boros Locket; Beast Whisperer; Bounty of Might; Beacon Bolt; Expansion; Electrostatic Field; Etrata, the Silencer; Experimental Frenzy; Erstwhile Trooper; Emmara, Soul of the Accord; Enhanced Surveillance; Erratic Cyclops; Underrealm Lich; Unexplained Disappearance; Urban Utopia; Undercity Uprising; Undercity Necrolisk; Ornery Goblin; Omnispell Adept; Ochran Assassin; Find; Fire Urchin; Flight of Equenauts; Fearless Halberdier; Fresh-Faced Recruit; Firemind's Research; Flower; Molderhulk; Mausoleum Secrets; Moodmark Painter; Maximize Altitude; Murmuring Mystic; March of the Multitudes; Muse Drake; Mephitic Vapors; Maximize Velocity; Midnight Reaper; Quasiduplicate +Venerated Loxodon; Vraska, Golgari Queen; Thief of Sanity; Thousand-Year Storm; Treasure Nabber; Charnel Troll; Coveted Jewel; Cheering Fanatic; Genesis Storm; Geode Golem; Isolated Watchtower; Discovery; Azra Bladeseeker; Aminatou, the Fateshifter; Primordial Mist; Plaguecrafter; Lazav, the Multifarious; Nimbus Champion; Selective Snare; Stadium Vendors; Sentinel Tower; Skull Storm; Beamsplitter Mage; Echo Storm; Unmoored Ego; Fury Storm; Mission Briefing; Mnemonic Betrayal - Guilds of Ravnica - -Most of Guilds of Ravnica has been implemented and is available in this release. We're working hard on getting the last few cards added. +All of Guilds of Ravnica has been implemented and is available in this release. - Token Changes - Some work that streamlines tokens is going on under the hood. This may be the cause of missing/incorrect token images if you notice any, though we don't expect there to be any issues. @@ -21,17 +21,14 @@ Added Randomized Standard Quest World with LDA archetype generated decks as duel In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. - Bug fixes - +Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. ------------- Known Issues: ------------- -Online multiplayer functionality has been restored, but is still a Work in Progress. We do have a dedicated developer actively working on the online multiplayer feature. - -"When you pay a cost" trigger for M19 cards don't work 100% correctly yet. We're still working on it. - -Other known issues are here: https://git.cardforge.org/core-developers/forge/issues +Known issues are here: https://git.cardforge.org/core-developers/forge/issues Feel free to report your own there if you have any. From 34afe75fc0e8319d137519a37791dfbff7977b81 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 18:40:48 +0300 Subject: [PATCH 27/48] - Fixed Drowned Secrets oracle text and description. --- forge-gui/res/cardsfolder/d/drowned_secrets.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/d/drowned_secrets.txt b/forge-gui/res/cardsfolder/d/drowned_secrets.txt index 55e3fdba195..d8e0e2153d0 100644 --- a/forge-gui/res/cardsfolder/d/drowned_secrets.txt +++ b/forge-gui/res/cardsfolder/d/drowned_secrets.txt @@ -1,8 +1,8 @@ Name:Drowned Secrets ManaCost:1 U Types:Enchantment -T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Whenever you cast a blue spell, target player puts the top two cards if their library into their graveyard. +T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Whenever you cast a blue spell, target player puts the top two cards of their library into their graveyard. SVar:TrigMill:DB$Mill | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Select target player SVar:BuffedBy:Card.Blue DeckHas:Ability$Graveyard -Oracle:Whenever you cast a blue spell, target player puts the top two cards if their library into their graveyard. +Oracle:Whenever you cast a blue spell, target player puts the top two cards of their library into their graveyard. From e46b778c506658a946925da9e90ccbd515fa92af Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 18:49:58 +0300 Subject: [PATCH 28/48] - Updating CHANGES.txt. --- forge-gui/release-files/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/forge-gui/release-files/CHANGES.txt b/forge-gui/release-files/CHANGES.txt index d162b6af1d5..5d89dc73c97 100644 --- a/forge-gui/release-files/CHANGES.txt +++ b/forge-gui/release-files/CHANGES.txt @@ -8,6 +8,9 @@ Some work that streamlines tokens is going on under the hood. This may be the ca Added Randomized Standard Quest World with LDA archetype generated decks as duels and standard card pool - this is designed so that there is always a quest world representing the current standard metagame - with a standard cardpool and decks generated using the LDA archetype based deck generation. To access this mode, select the "Random Standard" world in the world selection dropdown. In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. +- Chaos Draft - +Chaos Draft is now available in both desktop and mobile Forge, where each player starts with three boosters belonging to random sets from Magic: the Gathering history (only 15-card booster packs are used). To start a Chaos Draft, choose the appropriate menu item after starting a booster draft. + - Bug fixes - Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. From f462005d99a2ab3171eada73a8fc6cb5ce0b8a80 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 19:48:05 +0300 Subject: [PATCH 29/48] - Minor mistype fix in SurveilEffect. --- .../src/main/java/forge/game/ability/effects/SurveilEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java index 740ce564b33..f93f1765383 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java @@ -18,7 +18,7 @@ public class SurveilEffect extends SpellAbilityEffect { num = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa); } - sb.append(" surveil (").append(num).append(")."); + sb.append(" surveils (").append(num).append(")."); return sb.toString(); } From 129fc85a51e5e557bfff2fd6c795691f8be53b4f Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 20:13:25 +0300 Subject: [PATCH 30/48] - Fixed Sumala Woodshaper not revealing cards to the controller (the "look at" part of DB Dig). --- forge-gui/res/cardsfolder/s/sumala_woodshaper.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/s/sumala_woodshaper.txt b/forge-gui/res/cardsfolder/s/sumala_woodshaper.txt index 26db8431693..d398de4b996 100644 --- a/forge-gui/res/cardsfolder/s/sumala_woodshaper.txt +++ b/forge-gui/res/cardsfolder/s/sumala_woodshaper.txt @@ -3,5 +3,5 @@ ManaCost:2 G W Types:Creature Elf Druid PT:2/1 T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top four cards of your library. You may reveal a creature or enchantment 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$ 4 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Creature,Enchantment | RestRandomOrder$ True +SVar:TrigDig:DB$ Dig | DigNum$ 4 | ChangeNum$ 1 | Optional$ True | ForceRevealToController$ True | ChangeValid$ Creature,Enchantment | RestRandomOrder$ True Oracle:When Sumala Woodshaper enters the battlefield, look at the top four cards of your library. You may reveal a creature or enchantment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. From 59e2e776c482d9f9b7cefdbfa23b39227bf3782b Mon Sep 17 00:00:00 2001 From: Agetian Date: Sat, 13 Oct 2018 21:02:47 +0300 Subject: [PATCH 31/48] - Temporarily revert a change in CostPartMana to avoid breaking Convoke, Improvise, and Delve. --- forge-game/src/main/java/forge/game/cost/CostPartMana.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index 1fd0b568131..32f1ae41f7b 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -21,7 +21,6 @@ import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; import forge.game.mana.ManaConversionMatrix; import forge.game.player.Player; -import forge.game.spellability.AbilityActivated; import forge.game.spellability.SpellAbility; /** @@ -152,9 +151,8 @@ public class CostPartMana extends CostPart { // TODO Auto-generated method stub sa.clearManaPaid(); - boolean isActivated = sa instanceof AbilityActivated; // decision not used here, the whole payment is interactive! - return payer.getController().payManaCost(this, sa, null, cardMatrix, isActivated); + return payer.getController().payManaCost(this, sa, null, cardMatrix, true); } } From 40893683b4ca1941f5278a7009af59f90ab83bc6 Mon Sep 17 00:00:00 2001 From: Sol Date: Sat, 13 Oct 2018 19:46:12 +0000 Subject: [PATCH 32/48] Update sworn_companions.txt --- forge-gui/res/cardsfolder/s/sworn_companions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/s/sworn_companions.txt b/forge-gui/res/cardsfolder/s/sworn_companions.txt index 6504302ef29..e8b5d817986 100644 --- a/forge-gui/res/cardsfolder/s/sworn_companions.txt +++ b/forge-gui/res/cardsfolder/s/sworn_companions.txt @@ -1,6 +1,6 @@ Name:Sworn Companions ManaCost:2 W Types:Sorcery -A:SP$ Token | Cost$ 2 W | TokenAmount$ 2 | TokenScript$ w_1_1_soldier_lifelink +A:SP$ Token | Cost$ 2 W | TokenAmount$ 2 | TokenScript$ w_1_1_soldier_lifelink | SpellDescription$ Creature two 1/1 white Soldier creature tokens with lifelink. DeckHas:Ability$Token & Ability$LifeGain Oracle:Creature two 1/1 white Soldier creature tokens with lifelink. From f7a6c7080d4b58de0de972d9b673b08402546be0 Mon Sep 17 00:00:00 2001 From: Chris H Date: Sat, 13 Oct 2018 19:14:19 -0400 Subject: [PATCH 33/48] Improve flashback zone display --- forge-game/src/main/java/forge/game/zone/PlayerZone.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/zone/PlayerZone.java b/forge-game/src/main/java/forge/game/zone/PlayerZone.java index 0e9b48143b1..762ab38ae4b 100644 --- a/forge-game/src/main/java/forge/game/zone/PlayerZone.java +++ b/forge-game/src/main/java/forge/game/zone/PlayerZone.java @@ -63,6 +63,8 @@ public class PlayerZone extends Zone { return true; } + boolean graveyardCastable = c.hasKeyword(Keyword.FLASHBACK) || + c.hasKeyword(Keyword.RETRACE) || c.hasKeyword(Keyword.JUMP_START); for (final SpellAbility sa : c.getSpellAbilities()) { final ZoneType restrictZone = sa.getRestrictions().getZone(); @@ -76,7 +78,7 @@ public class PlayerZone extends Zone { } if (sa.isSpell() - && (c.hasKeyword(Keyword.FLASHBACK) && PlayerZone.this.is(ZoneType.Graveyard)) + && (graveyardCastable && PlayerZone.this.is(ZoneType.Graveyard)) && restrictZone.equals(ZoneType.Hand)) { return true; } From 92645d19d545a7d225cffc2bab6425f6ca0b4039 Mon Sep 17 00:00:00 2001 From: Agetian Date: Sun, 14 Oct 2018 08:57:06 +0300 Subject: [PATCH 34/48] - Underrealm Lich should not reveal a card going to hand. --- .../src/main/java/forge/game/ability/effects/DigEffect.java | 2 +- forge-gui/res/cardsfolder/u/underrealm_lich.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 365adf0855a..efa91cea1d2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -286,7 +286,7 @@ public class DigEffect extends SpellAbilityEffect { } } - if (!changeValid.isEmpty() && !sa.hasParam("ExileFaceDown")) { + if (!changeValid.isEmpty() && !sa.hasParam("ExileFaceDown") && !sa.hasParam("NoReveal")) { game.getAction().reveal(movedCards, chooser, true, chooser + " picked " + (movedCards.size() == 1 ? "this card" : "these cards") + " from "); } diff --git a/forge-gui/res/cardsfolder/u/underrealm_lich.txt b/forge-gui/res/cardsfolder/u/underrealm_lich.txt index 5a4e13c31c1..31302c0e0b6 100644 --- a/forge-gui/res/cardsfolder/u/underrealm_lich.txt +++ b/forge-gui/res/cardsfolder/u/underrealm_lich.txt @@ -3,7 +3,7 @@ ManaCost:3 B G Types:Creature Zombie Elf Shaman PT:4/3 R:Event$ Draw | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ Dig | Description$ If you would draw a card, instead look at the top three cards of your library, then put one into your hand and the rest into your graveyard. -SVar:Dig:DB$Dig | DigNum$ 3 | ChangeNum$ 1 | ChangeValid$ Card | DestinationZone2$ Graveyard +SVar:Dig:DB$Dig | DigNum$ 3 | ChangeNum$ 1 | ChangeValid$ Card | DestinationZone2$ Graveyard | NoReveal$ True A:AB$ Pump | Cost$ PayLife<4> | Defined$ Self | KW$ Indestructible | SubAbility$ DBTap | SpellDescription$ CARDNAME gains indestructible until end of turn. Tap it. SVar:DBTap:DB$Tap | Defined$ Self Oracle:If you would draw a card, instead look at the top three cards of your library, then put one into your hand and the rest into your graveyard.\nPay 4 life: Underrealm Lich gains indestructible until end of turn. Tap it. From 2e23d1035df139a2cfbfe1022a479ed9849dd179 Mon Sep 17 00:00:00 2001 From: Sol Date: Sun, 14 Oct 2018 12:30:13 +0000 Subject: [PATCH 35/48] Update teferi_hero_of_dominaria.txt --- forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt b/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt index 29919a6d2e4..6d914ba5f2e 100644 --- a/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt +++ b/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt @@ -4,7 +4,7 @@ Types:Legendary Planeswalker Teferi Loyalty:4 A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ You | NumCards$ 1 | SubAbility$ DelTrigUntap | SpellDescription$ Draw a card. At the beginning of the next end step, untap two lands. SVar:DelTrigUntap:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigUntap | TriggerDescription$ At the beginning of the next end step, untap two lands. -SVar:TrigUntap:DB$ Untap | UntapExactly$ True | UntapType$ Land | Amount$ 2 | Defined$ You +SVar:TrigUntap:DB$ Untap | UntapUpTo$ True | UntapType$ Land | Amount$ 2 | Defined$ You A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | Destination$ Library | LibraryPosition$ 2 | IsCurse$ True | SpellDescription$ Put target nonland permanent into its owner's library third from the top. A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem - Teferi, Hero of Dominaria | Image$ emblem_teferi_hero_of_dominaria | Triggers$ TrigDraw | SVars$ EffSpellCast | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Whenever you draw a card, exile target permanent an opponent controls." SVar:TrigDraw:Mode$ Drawn | ValidCard$ Card.YouCtrl | Execute$ EffSpellCast | TriggerDescription$ Whenever you draw a card, exile target permanent an opponent controls. From 0f2ebb9262829d58eafd3ca352f9a87efbcfdfdd Mon Sep 17 00:00:00 2001 From: Sol Date: Mon, 15 Oct 2018 02:02:07 +0000 Subject: [PATCH 36/48] Update forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt --- forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt b/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt index 6d914ba5f2e..48f40466192 100644 --- a/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt +++ b/forge-gui/res/cardsfolder/t/teferi_hero_of_dominaria.txt @@ -2,7 +2,7 @@ Name:Teferi, Hero of Dominaria ManaCost:3 W U Types:Legendary Planeswalker Teferi Loyalty:4 -A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ You | NumCards$ 1 | SubAbility$ DelTrigUntap | SpellDescription$ Draw a card. At the beginning of the next end step, untap two lands. +A:AB$ Draw | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ You | NumCards$ 1 | SubAbility$ DelTrigUntap | SpellDescription$ Draw a card. At the beginning of the next end step, untap up to two lands. SVar:DelTrigUntap:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigUntap | TriggerDescription$ At the beginning of the next end step, untap two lands. SVar:TrigUntap:DB$ Untap | UntapUpTo$ True | UntapType$ Land | Amount$ 2 | Defined$ You A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | Destination$ Library | LibraryPosition$ 2 | IsCurse$ True | SpellDescription$ Put target nonland permanent into its owner's library third from the top. @@ -10,4 +10,4 @@ A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True SVar:TrigDraw:Mode$ Drawn | ValidCard$ Card.YouCtrl | Execute$ EffSpellCast | TriggerDescription$ Whenever you draw a card, exile target permanent an opponent controls. SVar:EffSpellCast:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls SVar:Picture:http://www.wizards.com/global/images/magic/general/teferi_hero_of_dominaria.jpg -Oracle:[+1]: Draw a card. At the beginning of the next end step, untap two lands.\n[-3]: Put target nonland permanent into its owner's library third from the top.\n[-8]: You get an emblem with "Whenever you draw a card, exile target permanent an opponent controls." +Oracle:[+1]: Draw a card. At the beginning of the next end step, untap up to two lands.\n[-3]: Put target nonland permanent into its owner's library third from the top.\n[-8]: You get an emblem with "Whenever you draw a card, exile target permanent an opponent controls." From c8566079599edc2537aaabf932e9753eb9d27a32 Mon Sep 17 00:00:00 2001 From: pfirpfel Date: Mon, 15 Oct 2018 13:25:43 +0200 Subject: [PATCH 37/48] Brawl GRN format update --- forge-gui/res/formats/Casual/Brawl.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/formats/Casual/Brawl.txt b/forge-gui/res/formats/Casual/Brawl.txt index 84972f54ee9..8a2125573a6 100644 --- a/forge-gui/res/formats/Casual/Brawl.txt +++ b/forge-gui/res/formats/Casual/Brawl.txt @@ -3,5 +3,5 @@ Name:Brawl Order:101 Type:Casual Subtype:Commander -Sets:KLD, AER, AKH, W17, HOU, XLN, RIX, DOM, M19 -Banned:Baral, Chief of Compliance;Smuggler's Copter;Sorcerous Spyglass \ No newline at end of file +Sets:XLN, RIX, DOM, M19, GRN +Banned:Sorcerous Spyglass \ No newline at end of file From 2604d339d141ea395d7097016039961d3576016c Mon Sep 17 00:00:00 2001 From: pfirpfel Date: Mon, 15 Oct 2018 13:32:19 +0200 Subject: [PATCH 38/48] Update standard ban list: remove cards that rotated --- forge-gui/res/formats/Sanctioned/Standard.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/formats/Sanctioned/Standard.txt b/forge-gui/res/formats/Sanctioned/Standard.txt index 2093082499f..7413d4d97d2 100644 --- a/forge-gui/res/formats/Sanctioned/Standard.txt +++ b/forge-gui/res/formats/Sanctioned/Standard.txt @@ -4,4 +4,4 @@ Order:101 Subtype:Standard Type:Sanctioned Sets:XLN, RIX, DOM, M19, GRN -Banned: Attune with Aether; Rogue Refiner; Rampaging Ferocidon; Ramunap Ruins; Smuggler's Copter; Aetherworks Marvel; Felidar Guardian +Banned: Rampaging Ferocidon From 107896054555a4f94acc1565be46e6bba2e6741e Mon Sep 17 00:00:00 2001 From: Blacksmith Date: Mon, 15 Oct 2018 15:40:05 +0000 Subject: [PATCH 39/48] Update README.txt for release --- forge-gui/README.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/forge-gui/README.txt b/forge-gui/README.txt index 6d5adeec3c1..ffd1f5926ba 100644 --- a/forge-gui/README.txt +++ b/forge-gui/README.txt @@ -1,4 +1,4 @@ -Forge: 10/13/2018 ver 1.6.17 +Forge: 10/15/2018 ver 1.6.17 18204 cards in total. @@ -20,6 +20,9 @@ Some work that streamlines tokens is going on under the hood. This may be the ca Added Randomized Standard Quest World with LDA archetype generated decks as duels and standard card pool - this is designed so that there is always a quest world representing the current standard metagame - with a standard cardpool and decks generated using the LDA archetype based deck generation. To access this mode, select the "Random Standard" world in the world selection dropdown. In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. +- Chaos Draft - +Chaos Draft is now available in both desktop and mobile Forge, where each player starts with three boosters belonging to random sets from Magic: the Gathering history (only 15-card booster packs are used). To start a Chaos Draft, choose the appropriate menu item after starting a booster draft. + - Bug fixes - Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. From 41287d30c9b8498bac4a89c955846af9d03b554d Mon Sep 17 00:00:00 2001 From: Blacksmith Date: Mon, 15 Oct 2018 15:42:12 +0000 Subject: [PATCH 40/48] [maven-release-plugin] prepare release forge-1.6.17 --- forge-ai/pom.xml | 5 +- forge-core/pom.xml | 5 +- forge-game/pom.xml | 5 +- forge-gui-android/pom.xml | 58 +++----- forge-gui-desktop/pom.xml | 273 ++++++++++++++--------------------- forge-gui-ios/pom.xml | 5 +- forge-gui-mobile-dev/pom.xml | 5 +- forge-gui-mobile/pom.xml | 5 +- forge-gui/pom.xml | 5 +- pom.xml | 13 +- 10 files changed, 150 insertions(+), 229 deletions(-) diff --git a/forge-ai/pom.xml b/forge-ai/pom.xml index 5c2e49733c3..a5ecbb4ea94 100644 --- a/forge-ai/pom.xml +++ b/forge-ai/pom.xml @@ -1,13 +1,12 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-ai diff --git a/forge-core/pom.xml b/forge-core/pom.xml index 43ca41a1bbc..d4e40426300 100644 --- a/forge-core/pom.xml +++ b/forge-core/pom.xml @@ -1,13 +1,12 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-core diff --git a/forge-game/pom.xml b/forge-game/pom.xml index e432898b34c..48d48cf71c1 100644 --- a/forge-game/pom.xml +++ b/forge-game/pom.xml @@ -1,13 +1,12 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-game diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index 686f4a26ecc..ac43f1ac128 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -20,7 +19,7 @@ forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui-android @@ -215,7 +214,7 @@ true true - + ${project.build.directory}/${project.build.finalName}.apk @@ -278,29 +277,22 @@ - - - - - - - + + + + + + + - - + + - - - - + + + + @@ -346,22 +338,16 @@ package - - + + - - + + - + - + diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index c0d6f955b9c..6946e02a7e8 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui-desktop @@ -275,46 +274,38 @@ - + - - - - - - - + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + @@ -437,53 +428,41 @@ - + - - - - - - - - - - + + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + @@ -561,61 +540,41 @@ pre-integration-test - + - - - - - - - + + + + + + + - - - - - @@ -695,54 +654,38 @@ pre-integration-test - + - - - - + + + + - - - - - diff --git a/forge-gui-ios/pom.xml b/forge-gui-ios/pom.xml index 75741f26559..f06901f867a 100644 --- a/forge-gui-ios/pom.xml +++ b/forge-gui-ios/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -13,7 +12,7 @@ forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui-ios diff --git a/forge-gui-mobile-dev/pom.xml b/forge-gui-mobile-dev/pom.xml index 4c6a43115c8..c644e2a87ba 100644 --- a/forge-gui-mobile-dev/pom.xml +++ b/forge-gui-mobile-dev/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui-mobile-dev diff --git a/forge-gui-mobile/pom.xml b/forge-gui-mobile/pom.xml index 7880adfd083..452b69ed10d 100644 --- a/forge-gui-mobile/pom.xml +++ b/forge-gui-mobile/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui-mobile diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml index 3b9d8055d54..663f2a1831b 100644 --- a/forge-gui/pom.xml +++ b/forge-gui/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 forge forge - 1.6.17-SNAPSHOT + 1.6.17 forge-gui diff --git a/pom.xml b/pom.xml index 0c0da905a9d..5f95155e376 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 forge forge pom Forge Parent - 1.6.17-SNAPSHOT + 1.6.17 Forge lets you play the card game Magic: The Gathering against a computer opponent using all of the rules. @@ -176,7 +175,7 @@ scm:git:ssh://git@git.cardforge.org/core-developers/forge.git scm:git:ssh://git@git.cardforge.org/core-developers/forge.git - HEAD + forge-1.6.17 @@ -376,7 +375,7 @@ - + @@ -390,7 +389,7 @@ - + @@ -403,7 +402,7 @@ - + From 16e7d39870c9b8bd1de854461c4b607cc380d93c Mon Sep 17 00:00:00 2001 From: Blacksmith Date: Mon, 15 Oct 2018 15:42:16 +0000 Subject: [PATCH 41/48] [maven-release-plugin] prepare for next development iteration --- forge-ai/pom.xml | 2 +- forge-core/pom.xml | 2 +- forge-game/pom.xml | 2 +- forge-gui-android/pom.xml | 2 +- forge-gui-desktop/pom.xml | 2 +- forge-gui-ios/pom.xml | 2 +- forge-gui-mobile-dev/pom.xml | 2 +- forge-gui-mobile/pom.xml | 2 +- forge-gui/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/forge-ai/pom.xml b/forge-ai/pom.xml index a5ecbb4ea94..b3b53fc120f 100644 --- a/forge-ai/pom.xml +++ b/forge-ai/pom.xml @@ -6,7 +6,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-ai diff --git a/forge-core/pom.xml b/forge-core/pom.xml index d4e40426300..33171490943 100644 --- a/forge-core/pom.xml +++ b/forge-core/pom.xml @@ -6,7 +6,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-core diff --git a/forge-game/pom.xml b/forge-game/pom.xml index 48d48cf71c1..c9659499c2d 100644 --- a/forge-game/pom.xml +++ b/forge-game/pom.xml @@ -6,7 +6,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-game diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index ac43f1ac128..83e876ec6c9 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -19,7 +19,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui-android diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index 6946e02a7e8..6b78bad350c 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -4,7 +4,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui-desktop diff --git a/forge-gui-ios/pom.xml b/forge-gui-ios/pom.xml index f06901f867a..c34c7688255 100644 --- a/forge-gui-ios/pom.xml +++ b/forge-gui-ios/pom.xml @@ -12,7 +12,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui-ios diff --git a/forge-gui-mobile-dev/pom.xml b/forge-gui-mobile-dev/pom.xml index c644e2a87ba..86c59d8ffe0 100644 --- a/forge-gui-mobile-dev/pom.xml +++ b/forge-gui-mobile-dev/pom.xml @@ -4,7 +4,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui-mobile-dev diff --git a/forge-gui-mobile/pom.xml b/forge-gui-mobile/pom.xml index 452b69ed10d..cfaebbc7f52 100644 --- a/forge-gui-mobile/pom.xml +++ b/forge-gui-mobile/pom.xml @@ -4,7 +4,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui-mobile diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml index 663f2a1831b..1af393d28a6 100644 --- a/forge-gui/pom.xml +++ b/forge-gui/pom.xml @@ -4,7 +4,7 @@ forge forge - 1.6.17 + 1.6.18-SNAPSHOT forge-gui diff --git a/pom.xml b/pom.xml index 5f95155e376..f5046bc50ec 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ forge pom Forge Parent - 1.6.17 + 1.6.18-SNAPSHOT Forge lets you play the card game Magic: The Gathering against a computer opponent using all of the rules. @@ -175,7 +175,7 @@ scm:git:ssh://git@git.cardforge.org/core-developers/forge.git scm:git:ssh://git@git.cardforge.org/core-developers/forge.git - forge-1.6.17 + HEAD From 0d8721b651e8d9d0046d62336dea8d8b56a140a4 Mon Sep 17 00:00:00 2001 From: Blacksmith Date: Mon, 15 Oct 2018 15:47:03 +0000 Subject: [PATCH 42/48] Clear out release files in preparation for next release --- forge-gui/README.txt | 94 +---------------------------- forge-gui/release-files/CHANGES.txt | 14 ----- 2 files changed, 1 insertion(+), 107 deletions(-) diff --git a/forge-gui/README.txt b/forge-gui/README.txt index ffd1f5926ba..11b369846f2 100644 --- a/forge-gui/README.txt +++ b/forge-gui/README.txt @@ -1,93 +1 @@ -Forge: 10/15/2018 ver 1.6.17 - -18204 cards in total. - - --------------- -Release Notes: --------------- - -- New Cards - -Venerated Loxodon; Vraska, Golgari Queen; Thief of Sanity; Thousand-Year Storm; Treasure Nabber; Charnel Troll; Coveted Jewel; Cheering Fanatic; Genesis Storm; Geode Golem; Isolated Watchtower; Discovery; Azra Bladeseeker; Aminatou, the Fateshifter; Primordial Mist; Plaguecrafter; Lazav, the Multifarious; Nimbus Champion; Selective Snare; Stadium Vendors; Sentinel Tower; Skull Storm; Beamsplitter Mage; Echo Storm; Unmoored Ego; Fury Storm; Mission Briefing; Mnemonic Betrayal - -- Guilds of Ravnica - -All of Guilds of Ravnica has been implemented and is available in this release. - -- Token Changes - -Some work that streamlines tokens is going on under the hood. This may be the cause of missing/incorrect token images if you notice any, though we don't expect there to be any issues. - -- Random Quest World - -Added Randomized Standard Quest World with LDA archetype generated decks as duels and standard card pool - this is designed so that there is always a quest world representing the current standard metagame - with a standard cardpool and decks generated using the LDA archetype based deck generation. To access this mode, select the "Random Standard" world in the world selection dropdown. -In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. - -- Chaos Draft - -Chaos Draft is now available in both desktop and mobile Forge, where each player starts with three boosters belonging to random sets from Magic: the Gathering history (only 15-card booster packs are used). To start a Chaos Draft, choose the appropriate menu item after starting a booster draft. - -- Bug fixes - -Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. -As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. - -------------- -Known Issues: -------------- - -Known issues are here: https://git.cardforge.org/core-developers/forge/issues - -Feel free to report your own there if you have any. - -------------- -Installation: -------------- - -The Forge archive includes a MANUAL.txt file and we ask that you spend a few minutes reading this file as it contains some information that may prove useful. We do tend to update this file at times and you should quickly read this file and look for new information for each and every new release. Thank you. - -The archive format used for the Forge distribution is ".tar.bz2". There are utilities for Windows, Mac OS and the various *nix's that can be used to extract/decompress these ".tar.bz2" archives. We recommend that you extract/decompress the Forge archive into a new and unused folder. - -Some people use the Windows application 7zip. This utility can be found at http://www.7-zip.org/download.html. Mac users can double click on the archive and the application Archive Utility will launch and extract the archive. Mac users do not need to download a separate utility. - -Once the Forge archive has been decompressed you should then be able to launch Forge by using the included launcher. Launching Forge by double clicking on the forge jar file in the past caused a java heap space error. Forge's memory requirements have increased over time and the launchers increase the java heap space available to Forge. Currently you can launch Forge by double clicking on the forge jar file without a java heap space error but this is likely to change as we add in more sounds, icons, etc. - -- The Mac OS application version - -We haven't been able to distribute the OS X Application version of Forge in sometime. We've recently automated our release tools, and will continue to look in the viability of creating this file now that things are autoamted. - - -- Online Multiplayer - -For local network play you should only need two systems running Forge. One to host and one to join and play. For remote (over the Internet) play you will need to ensure that the port used (36743 by default) is forwarded to the hosting machine. - --------------------- -Active Contributors: --------------------- - -Agetian -Austinio7116 -Churrufli -DrDev -excessum -Gos -Hanmac -Indigo Dragon -Jamin Collins -KrazyTheFox -Luke -Marek14 -mcrawford620 -Meerkov -Myrd -nefigah -OgreBattlecruiser -pfps -Seravy -Sirspud -Sloth -slyfox7777777 -Sol -Swordshine -tjtillman -tojammot -torridus -Xyx -Zuchinni - -(Quest icons used created by Teekatas, from his Legendora set http://raindropmemory.deviantart.com) -(Thanks to the XMage team for permission to use their targeting arrows.) -(Thanks to http://www.freesound.org/browse/ for providing some sound files.) \ No newline at end of file +This file is automatically updated by our release bot on Discord, Blacksmith. It is created from the files present in the 'release-files' directory. Please do not hand-edit this file if using the bot to perform a release, as your changes will be overwritten. \ No newline at end of file diff --git a/forge-gui/release-files/CHANGES.txt b/forge-gui/release-files/CHANGES.txt index 5d89dc73c97..05f0bf1829e 100644 --- a/forge-gui/release-files/CHANGES.txt +++ b/forge-gui/release-files/CHANGES.txt @@ -1,16 +1,2 @@ -- Guilds of Ravnica - -All of Guilds of Ravnica has been implemented and is available in this release. - -- Token Changes - -Some work that streamlines tokens is going on under the hood. This may be the cause of missing/incorrect token images if you notice any, though we don't expect there to be any issues. - -- Random Quest World - -Added Randomized Standard Quest World with LDA archetype generated decks as duels and standard card pool - this is designed so that there is always a quest world representing the current standard metagame - with a standard cardpool and decks generated using the LDA archetype based deck generation. To access this mode, select the "Random Standard" world in the world selection dropdown. -In this world as well as the random duel opponents, there are randomly generated challenges of varying difficulty and of 2 different types. One type pits your standard decks against modern, legacy or vintage opponents, the other gives the AI a standard deck, but with a headstart of one or more cards on the battlefield. - -- Chaos Draft - -Chaos Draft is now available in both desktop and mobile Forge, where each player starts with three boosters belonging to random sets from Magic: the Gathering history (only 15-card booster packs are used). To start a Chaos Draft, choose the appropriate menu item after starting a booster draft. - - Bug fixes - -Gonti (and friends) should be fixed now. Let us know if you see anything wonky with mana pools. As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. From 54832cf79fafa3ad975f84f3ad8775845501ab0f Mon Sep 17 00:00:00 2001 From: Agetian Date: Mon, 15 Oct 2018 19:51:45 +0300 Subject: [PATCH 43/48] - Preparing Forge for Android publish 1.6.17.001 [incremental]. --- forge-gui-android/pom.xml | 2 +- forge-gui-ios/pom.xml | 2 +- forge-gui-mobile/src/forge/Forge.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index 83e876ec6c9..6e925598a72 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -6,7 +6,7 @@ jar -Xms1024m -Xmx1536m - 1.6.16.001 + 1.6.17.001 keystore alias storepass diff --git a/forge-gui-ios/pom.xml b/forge-gui-ios/pom.xml index c34c7688255..3a5a9720a78 100644 --- a/forge-gui-ios/pom.xml +++ b/forge-gui-ios/pom.xml @@ -6,7 +6,7 @@ jar -Xms128m -Xmx2048m - 1.6.16.001 + 1.6.17.001 diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 9c56811a115..ad9e7363cd6 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -34,7 +34,7 @@ import java.util.List; import java.util.Stack; public class Forge implements ApplicationListener { - public static final String CURRENT_VERSION = "1.6.16.001"; + public static final String CURRENT_VERSION = "1.6.17.001"; private static final ApplicationListener app = new Forge(); private static Clipboard clipboard; From ef24c5058c381fb163f50bbb8929cfd0a4081bd5 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Mon, 15 Oct 2018 22:05:13 +0200 Subject: [PATCH 44/48] Epic rework --- .../ability/effects/CopySpellAbilityEffect.java | 15 ++++++++++++++- .../java/forge/game/card/CardFactoryUtil.java | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java index 6d7b25e97d0..26ca842301d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java @@ -167,7 +167,20 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { "Select a spell to copy", ImmutableMap.of()); chosenSA.setActivatingPlayer(controller); for (int i = 0; i < amount; i++) { - copies.add(CardFactory.copySpellAbilityAndPossiblyHost(card, chosenSA.getHostCard(), chosenSA, true)); + SpellAbility copy = CardFactory.copySpellAbilityAndPossiblyHost( + card, chosenSA.getHostCard(), chosenSA, true); + + // extra case for Epic to remove the keyword and the last part of the SpellAbility + if (sa.hasParam("Epic")) { + copy.getHostCard().removeIntrinsicKeyword("Epic"); + SpellAbility sub = copy; + while (sub.getSubAbility() != null) { + sub = sub.getSubAbility(); + } + sub.getParent().setSubAbility(null); + } + + copies.add(copy); } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 6f0b68c466f..3d62dde6fbe 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3759,14 +3759,14 @@ public class CardFactoryUtil { // Epic does modify existing SA, and does not add new one // Add the Epic effect as a subAbility - String dbStr = "DB$ Effect | Triggers$ EpicTrigger | SVars$ EpicCopy | StaticAbilities$ EpicCantBeCast | Duration$ Permanent | Unique$ True"; + String dbStr = "DB$ Effect | Triggers$ EpicTrigger | SVars$ EpicCopy | StaticAbilities$ EpicCantBeCast | Duration$ Permanent"; final AbilitySub newSA = (AbilitySub) AbilityFactory.getAbility(dbStr.toString(), card); card.setSVar("EpicCantBeCast", "Mode$ CantBeCast | ValidCard$ Card | Caster$ You | EffectZone$ Command | Description$ For the rest of the game, you can't cast spells."); card.setSVar("EpicTrigger", "Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ EpicCopy | TriggerDescription$ " + "At the beginning of each of your upkeeps, copy " + card.toString() + " except for its epic ability."); - card.setSVar("EpicCopy", "DB$ CopySpellAbility | Defined$ EffectSource"); + card.setSVar("EpicCopy", "DB$ CopySpellAbility | Defined$ EffectSource | Epic$ True"); final SpellAbility origSA = card.getFirstSpellAbility(); From 1b284e8f3f7ade0d0059d1e0e9cd36fd8ca1abda Mon Sep 17 00:00:00 2001 From: Sol Date: Tue, 16 Oct 2018 01:55:49 +0000 Subject: [PATCH 45/48] Update kraul_harpooner.txt not up to targeting --- forge-gui/res/cardsfolder/k/kraul_harpooner.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/k/kraul_harpooner.txt b/forge-gui/res/cardsfolder/k/kraul_harpooner.txt index 539450d9419..0fde4013fb2 100644 --- a/forge-gui/res/cardsfolder/k/kraul_harpooner.txt +++ b/forge-gui/res/cardsfolder/k/kraul_harpooner.txt @@ -5,6 +5,6 @@ PT:3/2 K:Reach T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters the battlefield, choose up to one target creature with flying you don't control. CARDNAME gets +X/+0 until end of turn, where X is the number of creature cards in your graveyard, then you may have CARDNAME fight that creature. SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ X | References$ X | SubAbility$ DBFight -SVar:DBFight:DB$ Fight | Defined$ Self | ValidTgts$ Creature.withFlying+YouDontCtrl | TgtPrompt$ Select target creature with flying you don't control +SVar:DBFight:DB$ Fight | Defined$ Self | ValidTgts$ Creature.withFlying+YouDontCtrl | TgtPrompt$ Select target creature with flying you don't control | TargetMin$ 0 | TargetMax$ 1 SVar:X:Count$TypeInYourYard.Creature Oracle:Reach\nUndergrowth — When Kraul Harpooner enters the battlefield, choose up to one target creature with flying you don't control. Kraul Harpooner gets +X/+0 until end of turn, where X is the number of creature cards in your graveyard, then you may have Kraul Harpooner fight that creature. From cd74d2a7bf7d85a43805f99ae622ab983e5d959b Mon Sep 17 00:00:00 2001 From: Chris H Date: Mon, 15 Oct 2018 22:18:23 -0400 Subject: [PATCH 46/48] Convert FullCost to PermanentCreature --- .../main/java/forge/game/card/CardFactoryUtil.java | 13 ------------- forge-gui/res/cardsfolder/c/caller_of_the_hunt.txt | 2 +- forge-gui/res/cardsfolder/h/headless_skaab.txt | 2 +- forge-gui/res/cardsfolder/i/imperiosaur.txt | 3 +-- forge-gui/res/cardsfolder/m/makeshift_mauler.txt | 2 +- forge-gui/res/cardsfolder/m/myr_superion.txt | 2 +- forge-gui/res/cardsfolder/r/relentless_skaabs.txt | 2 +- forge-gui/res/cardsfolder/s/skaab_goliath.txt | 2 +- forge-gui/res/cardsfolder/s/skaab_ruinator.txt | 2 +- forge-gui/res/cardsfolder/s/stitched_drake.txt | 2 +- 10 files changed, 9 insertions(+), 23 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 3d62dde6fbe..acbefc4d72d 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -2014,18 +2014,6 @@ public class CardFactoryUtil { inst.createTraits(card, true); } - // AddCost - if (card.hasSVar("FullCost")) { - String k[] = card.getSVar("FullCost").split(":"); - final SpellAbility sa1 = card.getFirstSpellAbility(); - if (sa1 != null && sa1.isSpell()) { - sa1.setPayCosts(new Cost(k[0], sa1.isAbility())); - if (k.length > 1) { - sa1.getMapParams().put("AILogic", k[1]); - } - } - } - // AltCost String altCost = card.getSVar("AltCost"); if (StringUtils.isNotBlank(altCost)) { @@ -2034,7 +2022,6 @@ public class CardFactoryUtil { card.addSpellAbility(makeAltCostAbility(card, altCost, sa1)); } } - } private static ReplacementEffect createETBReplacement(final Card card, ReplacementLayer layer, diff --git a/forge-gui/res/cardsfolder/c/caller_of_the_hunt.txt b/forge-gui/res/cardsfolder/c/caller_of_the_hunt.txt index e973b31e704..84849bc4d9d 100644 --- a/forge-gui/res/cardsfolder/c/caller_of_the_hunt.txt +++ b/forge-gui/res/cardsfolder/c/caller_of_the_hunt.txt @@ -2,8 +2,8 @@ Name:Caller of the Hunt ManaCost:2 G Types:Creature Human PT:*/* +A:SP$ PermanentCreature | Cost$ 2 G ChooseCreatureType<1> | AILogic$ MostProminentOnBattlefield S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of creatures of the chosen type on the battlefield. SVar:X:Count$Valid Creature.ChosenType -SVar:FullCost:2 G ChooseCreatureType<1>:MostProminentOnBattlefield SVar:Picture:http://www.wizards.com/global/images/magic/general/caller_of_the_hunt.jpg Oracle:As an additional cost to cast this spell, choose a creature type.\nCaller of the Hunt's power and toughness are each equal to the number of creatures of the chosen type on the battlefield. diff --git a/forge-gui/res/cardsfolder/h/headless_skaab.txt b/forge-gui/res/cardsfolder/h/headless_skaab.txt index 7d321382402..44f9e3cc5d1 100644 --- a/forge-gui/res/cardsfolder/h/headless_skaab.txt +++ b/forge-gui/res/cardsfolder/h/headless_skaab.txt @@ -3,6 +3,6 @@ ManaCost:2 U Types:Creature Zombie Warrior PT:3/6 K:CARDNAME enters the battlefield tapped. -SVar:FullCost:2 U ExileFromGrave<1/Creature> +A:SP$ PermanentCreature | Cost$ 2 U ExileFromGrave<1/Creature> SVar:Picture:http://www.wizards.com/global/images/magic/general/headless_skaab.jpg Oracle:As an additional cost to cast Headless Skaab, exile a creature card from your graveyard.\nHeadless Skaab enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/i/imperiosaur.txt b/forge-gui/res/cardsfolder/i/imperiosaur.txt index 1ac3fcee99d..53c761e7050 100644 --- a/forge-gui/res/cardsfolder/i/imperiosaur.txt +++ b/forge-gui/res/cardsfolder/i/imperiosaur.txt @@ -2,7 +2,6 @@ Name:Imperiosaur ManaCost:2 G G Types:Creature Dinosaur Text:Spend only mana produced by basic lands to cast CARDNAME. -PT:5/5 -SVar:FullCost:Mana<2 G G\Basic> +A:SP$ PermanentCreature | Cost$ Mana<2 G G\Basic> SVar:Picture:http://resources.wizards.com/magic/cards/fut/en-us/card130634.jpg Oracle:Spend only mana produced by basic lands to cast Imperiosaur. diff --git a/forge-gui/res/cardsfolder/m/makeshift_mauler.txt b/forge-gui/res/cardsfolder/m/makeshift_mauler.txt index 6e15a9ea94c..bf5f2173f5d 100644 --- a/forge-gui/res/cardsfolder/m/makeshift_mauler.txt +++ b/forge-gui/res/cardsfolder/m/makeshift_mauler.txt @@ -2,6 +2,6 @@ Name:Makeshift Mauler ManaCost:3 U Types:Creature Zombie Horror PT:4/5 -SVar:FullCost:3 U ExileFromGrave<1/Creature> +A:SP$ PermanentCreature | Cost$ 3 U ExileFromGrave<1/Creature> SVar:Picture:http://www.wizards.com/global/images/magic/general/makeshift_mauler.jpg Oracle:As an additional cost to cast Makeshift Mauler, exile a creature card from your graveyard. diff --git a/forge-gui/res/cardsfolder/m/myr_superion.txt b/forge-gui/res/cardsfolder/m/myr_superion.txt index 3d9a93a570d..b309044b89f 100644 --- a/forge-gui/res/cardsfolder/m/myr_superion.txt +++ b/forge-gui/res/cardsfolder/m/myr_superion.txt @@ -3,7 +3,7 @@ ManaCost:2 Types:Artifact Creature Myr PT:5/6 Text:Spend only mana produced by creatures to cast CARDNAME. -SVar:FullCost:Mana<2\Creature> +A:SP$ PermanentCreature | Cost$ Mana<2\Creature> SVar:RemRandomDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/myr_superion.jpg Oracle:Spend only mana produced by creatures to cast Myr Superion. diff --git a/forge-gui/res/cardsfolder/r/relentless_skaabs.txt b/forge-gui/res/cardsfolder/r/relentless_skaabs.txt index e487dab907b..6d0879aa058 100644 --- a/forge-gui/res/cardsfolder/r/relentless_skaabs.txt +++ b/forge-gui/res/cardsfolder/r/relentless_skaabs.txt @@ -3,6 +3,6 @@ ManaCost:3 U U Types:Creature Zombie PT:4/4 K:Undying -SVar:FullCost:3 U U ExileFromGrave<1/Creature> +A:SP$ PermanentCreature | Cost$ 3 U U ExileFromGrave<1/Creature> SVar:Picture:http://www.wizards.com/global/images/magic/general/relentless_skaabs.jpg Oracle:As an additional cost to cast Relentless Skaabs, exile a creature card from your graveyard.\nUndying (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.) diff --git a/forge-gui/res/cardsfolder/s/skaab_goliath.txt b/forge-gui/res/cardsfolder/s/skaab_goliath.txt index 9b1f20a26f2..15f63a8a8e3 100644 --- a/forge-gui/res/cardsfolder/s/skaab_goliath.txt +++ b/forge-gui/res/cardsfolder/s/skaab_goliath.txt @@ -3,6 +3,6 @@ ManaCost:5 U Types:Creature Zombie Giant PT:6/9 K:Trample -SVar:FullCost:5 U ExileFromGrave<2/Creature> +A:SP$ PermanentCreature | Cost$ 5 U ExileFromGrave<2/Creature> SVar:Picture:http://www.wizards.com/global/images/magic/general/skaab_goliath.jpg Oracle:As an additional cost to cast Skaab Goliath, exile two creature cards from your graveyard.\nTrample diff --git a/forge-gui/res/cardsfolder/s/skaab_ruinator.txt b/forge-gui/res/cardsfolder/s/skaab_ruinator.txt index f13a8f42cae..38ab2d38e05 100644 --- a/forge-gui/res/cardsfolder/s/skaab_ruinator.txt +++ b/forge-gui/res/cardsfolder/s/skaab_ruinator.txt @@ -3,7 +3,7 @@ ManaCost:1 U U Types:Creature Zombie Horror PT:5/6 K:Flying -SVar:FullCost:1 U U ExileFromGrave<3/Creature> +A:SP$ PermanentCreature | Cost$ 1 U U ExileFromGrave<3/Creature> SVar:AltCost:Cost$ 1 U U ExileFromGrave<3/Creature.Other> | ActivationZone$ Graveyard | Description$ You may cast CARDNAME from your graveyard. SVar:Picture:http://www.wizards.com/global/images/magic/general/skaab_ruinator.jpg Oracle:As an additional cost to cast Skaab Ruinator, exile three creature cards from your graveyard.\nFlying\nYou may cast Skaab Ruinator from your graveyard. diff --git a/forge-gui/res/cardsfolder/s/stitched_drake.txt b/forge-gui/res/cardsfolder/s/stitched_drake.txt index a12f6807393..4330e399a22 100644 --- a/forge-gui/res/cardsfolder/s/stitched_drake.txt +++ b/forge-gui/res/cardsfolder/s/stitched_drake.txt @@ -3,6 +3,6 @@ ManaCost:1 U U Types:Creature Zombie Drake PT:3/4 K:Flying -SVar:FullCost:1 U U ExileFromGrave<1/Creature> +A:SP$ PermanentCreature | Cost$ 1 U U ExileFromGrave<1/Creature> SVar:Picture:http://www.wizards.com/global/images/magic/general/stitched_drake.jpg Oracle:As an additional cost to cast Stitched Drake, exile a creature card from your graveyard.\nFlying From 256bf8e43863781c26553a76e814817c144e011c Mon Sep 17 00:00:00 2001 From: Agetian Date: Tue, 16 Oct 2018 08:19:10 +0300 Subject: [PATCH 47/48] - Added puzzle PS_GRN2. - Improved the implementation of puzzle PS_GRN1. --- forge-gui/res/puzzle/PS_GRN1.pzl | 4 ++-- forge-gui/res/puzzle/PS_GRN2.pzl | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/puzzle/PS_GRN2.pzl diff --git a/forge-gui/res/puzzle/PS_GRN1.pzl b/forge-gui/res/puzzle/PS_GRN1.pzl index 8a189e3af52..c0b3fd3668e 100644 --- a/forge-gui/res/puzzle/PS_GRN1.pzl +++ b/forge-gui/res/puzzle/PS_GRN1.pzl @@ -4,7 +4,7 @@ URL:https://i0.wp.com/www.possibilitystorm.com/wp-content/uploads/2018/10/083.-G Goal:Win Turns:1 Difficulty:Rare -Description:Win this turn. When this puzzle starts, you will be prompted to pay 2 life for Sacred Foundry, you should choose "No" (Sacred Foundry will be placed on the battlefield untapped regardless). +Description:Win this turn. [state] humanlife=20 ailife=5 @@ -12,5 +12,5 @@ turn=1 activeplayer=human activephase=MAIN1 humanhand=Heroic Reinforcements;Aurelia, Exemplar of Justice;Garna, the Bloodflame;Deafening Clarion;Vraska's Contempt -humanbattlefield=Blade Instructor;Goblin Banneret;Barging Sergeant;Angrath, the Flame-Chained|Counters:LOYALTY=5;Sacred Foundry;Sacred Foundry;Sacred Foundry;Sacred Foundry;Dragonskull Summit;Dragonskull Summit +humanbattlefield=Blade Instructor;Goblin Banneret;Barging Sergeant;Angrath, the Flame-Chained|Counters:LOYALTY=5;Sacred Foundry|Set:GRN|NoETBTrigs;Sacred Foundry|Set:GRN|NoETBTrigs;Sacred Foundry|Set:GRN|NoETBTrigs;Sacred Foundry|Set:GRN|NoETBTrigs;Dragonskull Summit;Dragonskull Summit aibattlefield=Josu Vess, Lich Knight;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom;t:Zombie Knight,P:2,T:2,Cost:no cost,Color:B,Types:Creature-Zombie-Knight,Keywords:Menace,Image:b_2_2_zombie_knight_dom diff --git a/forge-gui/res/puzzle/PS_GRN2.pzl b/forge-gui/res/puzzle/PS_GRN2.pzl new file mode 100644 index 00000000000..84bfbcde0d8 --- /dev/null +++ b/forge-gui/res/puzzle/PS_GRN2.pzl @@ -0,0 +1,17 @@ +[metadata] +Name:Possibility Storm - Guilds of Ravnica #02 +URL:https://i1.wp.com/www.possibilitystorm.com/wp-content/uploads/2018/10/084.-GRN2.jpg +Goal:Win +Turns:1 +Difficulty:Rare +Description:Win this turn. Assume you have no instant or sorcery spells left in your library. +[state] +humanlife=20 +ailife=12 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Arclight Phoenix;Sonic Assault;Invert // Invent;Response // Resurgence +humanlibrary=Plains|Set:GRN;Island|Set:GRN;Swamp|Set:GRN;Mountain|Set:GRN;Forest|Set:GRN +humanbattlefield=Runaway Steam-Kin|Counters:P1P1=1|Id:1;Tilonalli's Crown|Attaching:1;Rampaging Monument|Counters:P1P1=3;Sacred Foundry|Set:GRN|NoETBTrigs;Sacred Foundry|Set:GRN|NoETBTrigs;Steam Vents|Set:GRN|NoETBTrigs;Steam Vents|Set:GRN|NoETBTrigs;Izzet Guildgate|Set:GRN;Izzet Guildgate|Set:GRN +aibattlefield=Looming Altisaur;Territorial Allosaurus;Verdant Sun's Avatar;Polyraptor;Emissary of Sunrise|Id:2;Forebear's Blade|Attaching:2 From 6055f9ddc4148c90ca8c59e9a00d46d39dff99fd Mon Sep 17 00:00:00 2001 From: Agetian Date: Tue, 23 Oct 2018 08:11:13 +0300 Subject: [PATCH 48/48] - Added puzzle PS_GRN3. --- forge-gui/res/puzzle/PS_GRN3.pzl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 forge-gui/res/puzzle/PS_GRN3.pzl diff --git a/forge-gui/res/puzzle/PS_GRN3.pzl b/forge-gui/res/puzzle/PS_GRN3.pzl new file mode 100644 index 00000000000..2263c7d4396 --- /dev/null +++ b/forge-gui/res/puzzle/PS_GRN3.pzl @@ -0,0 +1,16 @@ +[metadata] +Name:Possibility Storm - Guilds of Ravnica #03 +URL:https://i0.wp.com/www.possibilitystorm.com/wp-content/uploads/2018/10/085.-GRN3-1.jpg +Goal:Win +Turns:1 +Difficulty:Mythic +Description:Win this turn. +[state] +humanlife=20 +ailife=9 +turn=1 +activeplayer=human +activephase=MAIN1 +humanhand=Justice Strike;Dual Shot;Ashes of the Abhorrent;Silverclad Ferocidons;Hunted Witness +humanbattlefield=Roc Charger|Id:1;Glaive of the Guildpact|Attaching:1;Desecrated Tomb;Pitiless Plunderer;Undercity Necrolisk;Oathsworn Vampire;Boros Guildgate|Set:GRN;Boros Guildgate|Set:GRN;Boros Guildgate|Set:GRN;Boros Guildgate|Set:GRN;Gateway Plaza|NoETBTrigs;Gateway Plaza|NoETBTrigs;Gateway Plaza|NoETBTrigs;Gateway Plaza|NoETBTrigs +aibattlefield=Rekindling Phoenix;Rekindling Phoenix;Aurelia, Exemplar of Justice