From 4eb21594b44a8effdf8aa5d8aed2c2bf3c86c42d Mon Sep 17 00:00:00 2001 From: rory Date: Sun, 10 May 2020 11:34:07 -0700 Subject: [PATCH] Jegantha, the Wellspring --- .../main/java/forge/ai/ComputerUtilMana.java | 2 +- .../java/forge/card/mana/ManaCostShard.java | 9 +++- .../forge/game/mana/ManaCostBeingPaid.java | 3 ++ .../main/java/forge/game/player/Player.java | 17 ++++++ .../game/spellability/AbilityManaPart.java | 53 +++++++++++++++++++ .../upcoming/jegantha_the_wellspring.txt | 7 +++ 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/jegantha_the_wellspring.txt diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 3eaa075f4ea..55e72a71141 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -741,7 +741,7 @@ public class ComputerUtilMana { continue; } - if (thisMana.getManaAbility() != null && !thisMana.getManaAbility().meetsManaRestrictions(saBeingPaidFor)) { + if (thisMana.getManaAbility() != null && !thisMana.getManaAbility().meetsSpellAndShardRestrictions(saBeingPaidFor, shard, thisMana.getColor())) { continue; } diff --git a/forge-core/src/main/java/forge/card/mana/ManaCostShard.java b/forge-core/src/main/java/forge/card/mana/ManaCostShard.java index 8c97c99e5b8..d4533f1abc5 100644 --- a/forge-core/src/main/java/forge/card/mana/ManaCostShard.java +++ b/forge-core/src/main/java/forge/card/mana/ManaCostShard.java @@ -289,13 +289,20 @@ public enum ManaCostShard { return BinaryUtil.bitCount(this.shard & COLORS_SUPERPOSITION) == 2; } + public boolean isGeneric() { + return isOfKind(ManaAtom.GENERIC)|| isOfKind(ManaAtom.IS_X) || this.isSnow() || this.isOr2Generic(); + } public boolean isOr2Generic() { return isOfKind(ManaAtom.OR_2_GENERIC); } + + public boolean isColor(byte colorCode) { + return (colorCode & this.shard) > 0; + } public boolean canBePaidWithManaOfColor(byte colorCode) { return this.isOr2Generic() || ((COLORS_SUPERPOSITION | ManaAtom.COLORLESS) & this.shard) == 0 || - (colorCode & this.shard) > 0; + this.isColor(colorCode); } public boolean isOfKind(int atom) { 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 f3484f6192b..acb70163baf 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java @@ -543,6 +543,9 @@ public class ManaCostBeingPaid { if (shard.isSnow() && !mana.isSnow()) { return false; } + if (mana.isRestricted() && !mana.getManaAbility().meetsManaShardRestrictions(shard, mana.getColor())) { + return false; + } byte color = mana.getColor(); return pool.canPayForShardWithColor(shard, color); 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 76023afa0f3..ab227dc7c97 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -25,6 +25,7 @@ import forge.ImageKeys; import forge.LobbyPlayer; import forge.card.CardType; import forge.card.MagicColor; +import forge.card.mana.ManaCostShard; import forge.game.*; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityKey; @@ -2869,6 +2870,18 @@ public class Player extends GameEntity implements Comparable { cardTypes.retainAll((Collection) c.getPaperCard().getRules().getType().getCoreTypes()); } + + boolean uniqueManaSymbols = true; + for (final Card c : getCardsIn(ZoneType.Library)) { + Set manaSymbols = new HashSet<>(); + for (final ManaCostShard manaSymbol : c.getManaCost()) { + if (manaSymbols.contains(manaSymbol)) { + uniqueManaSymbols = false; + } else { + manaSymbols.add(manaSymbol); + } + } + } int deckSize = getCardsIn(ZoneType.Library).size(); int minSize = game.getMatch().getRules().getGameType().getDeckFormat().getMainRange().getMinimum(); @@ -2886,6 +2899,10 @@ public class Player extends GameEntity implements Comparable { if (uniqueNames) { legalCompanions.add(c); } + } else if (specialRules.equals("UniqueManaSymbols")) { + if (uniqueManaSymbols) { + legalCompanions.add(c); + } } else if (specialRules.equals("DeckSizePlus20")) { // +20 deck size to min deck size if (deckSize >= minSize + 20) { diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 510458a6189..0fe41c1f6d8 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -23,6 +23,7 @@ import com.google.common.collect.Maps; import forge.card.ColorSet; import forge.card.MagicColor; import forge.card.mana.ManaAtom; +import forge.card.mana.ManaCostShard; import forge.game.Game; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityKey; @@ -381,11 +382,63 @@ public class AbilityManaPart implements java.io.Serializable { return true; } } + + if (restriction.equals("CantPayGenericCosts")) { + return true; + } } return false; } + + /** + *

+ * meetsManaShardRestrictions. + *

+ * + * @param shard + * a {@link forge.card.mana.ManaCostShard} object. + * @param color + * the color of mana being paid + * @return a boolean. + */ + public boolean meetsManaShardRestrictions(final ManaCostShard shard, final byte color) { + if (this.manaRestrictions.isEmpty()) { + return true; + } + for (String restriction : this.manaRestrictions.split(",")) { + if (restriction.equals("CantPayGenericCosts")) { + if (shard.isGeneric()) { + if (shard.isOr2Generic() && shard.isColor(color)) { + continue; + } else { + return false; + } + } else { + continue; + } + } + } + return true; + } + + /** + *

+ * meetsSpellAndShardRestrictions. + *

+ * + * @param sa + * a {@link forge.game.spellability.SpellAbility} object. + * @param shard + * a {@link forge.card.mana.ManaCostShard} object. + * @param color + * the color of mana being paid + * @return a boolean. + */ + public boolean meetsSpellAndShardRestrictions(final SpellAbility sa, final ManaCostShard shard, final byte color) { + return this.meetsManaRestrictions(sa) && this.meetsManaShardRestrictions(shard, color); + } /** *

diff --git a/forge-gui/res/cardsfolder/upcoming/jegantha_the_wellspring.txt b/forge-gui/res/cardsfolder/upcoming/jegantha_the_wellspring.txt new file mode 100644 index 00000000000..e661454b03d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/jegantha_the_wellspring.txt @@ -0,0 +1,7 @@ +Name:Jegantha, the Wellspring +ManaCost:4 R/G +Types:Legendary Creature Elemental Elk +PT:5/5 +K:Companion:Special:UniqueManaSymbols:No card in your starting deck has more than one of the same mana symbol in its mana cost. +A:AB$ Mana | Cost$ T | Produced$ W U B R G | RestrictValid$ CantPayGenericCosts | SpellDescription$ Add {W}{U}{B}{R}{G}. This mana can't be spent to pay generic mana costs. +Oracle:Companion — No card in your starting deck has more than one of the same mana symbol in its mana cost. (If this card is your chosen companion, you may cast it once from outside the game.)\n{T}: Add {W}{U}{B}{R}{G}. This mana can't be spent to pay generic mana costs.