mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
Different names rework (#8823)
* turn CardChangedName into record * Add CardLists.getDifferentNamesCount * CostDiscard: rename to +WithDifferentNames * CostSacrifice: use getDifferentNamesCount * Refactor DifferentCardNames_
This commit is contained in:
@@ -113,7 +113,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
randomSubset = ability.getActivatingPlayer().getController().orderMoveToZoneList(randomSubset, ZoneType.Graveyard, ability);
|
||||
}
|
||||
return PaymentDecision.card(randomSubset);
|
||||
} else if (type.equals("DifferentNames")) {
|
||||
} else if (type.contains("+WithDifferentNames")) {
|
||||
CardCollection differentNames = new CardCollection();
|
||||
CardCollection discardMe = CardLists.filter(hand, CardPredicates.hasSVar("DiscardMe"));
|
||||
while (c > 0) {
|
||||
|
||||
@@ -43,7 +43,6 @@ import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class AbilityUtils {
|
||||
private final static ImmutableList<String> cmpList = ImmutableList.of("LT", "LE", "EQ", "GE", "GT", "NE");
|
||||
|
||||
@@ -2889,21 +2888,6 @@ public class AbilityUtils {
|
||||
return max;
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("DifferentCardNames_")) {
|
||||
final List<String> crdname = Lists.newArrayList();
|
||||
final String restriction = l[0].substring(19);
|
||||
CardCollection list = CardLists.getValidCards(game.getCardsInGame(), restriction, player, c, ctb);
|
||||
// TODO rewrite with sharesName to respect Spy Kit
|
||||
for (final Card card : list) {
|
||||
String name = card.getName();
|
||||
// CR 201.2b Those objects have different names only if each of them has at least one name and no two objects in that group have a name in common
|
||||
if (!crdname.contains(name) && !name.isEmpty()) {
|
||||
crdname.add(name);
|
||||
}
|
||||
}
|
||||
return doXMath(crdname.size(), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("MostProminentCreatureType")) {
|
||||
String restriction = l[0].split(" ")[1];
|
||||
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, player, c, ctb);
|
||||
@@ -3760,6 +3744,10 @@ public class AbilityUtils {
|
||||
return CardUtil.getColorsFromCards(paidList).countColors();
|
||||
}
|
||||
|
||||
if (string.equals("DifferentCardNames")) {
|
||||
return CardLists.getDifferentNamesCount(paidList);
|
||||
}
|
||||
|
||||
if (string.equals("DifferentColorPair")) {
|
||||
final Set<ColorSet> diffPair = new HashSet<>();
|
||||
for (final Card card : paidList) {
|
||||
|
||||
@@ -965,7 +965,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
String name = state.getName();
|
||||
for (CardChangedName change : this.changedCardNames.values()) {
|
||||
if (change.isOverwrite()) {
|
||||
name = change.getNewName();
|
||||
name = change.newName();
|
||||
}
|
||||
}
|
||||
return alt ? StaticData.instance().getCommonCards().getName(name, true) : name;
|
||||
@@ -980,7 +980,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
for (CardChangedName change : this.changedCardNames.values()) {
|
||||
if (change.isOverwrite()) {
|
||||
result = false;
|
||||
} else if (change.isAddNonLegendaryCreatureNames()) {
|
||||
} else if (change.addNonLegendaryCreatureNames()) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
@@ -1013,6 +1013,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
currentState.getView().updateName(currentState);
|
||||
}
|
||||
|
||||
private record CardChangedName(String newName, boolean addNonLegendaryCreatureNames) {
|
||||
public boolean isOverwrite() {
|
||||
return newName != null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setGamePieceType(GamePieceType gamePieceType) {
|
||||
this.gamePieceType = gamePieceType;
|
||||
this.view.updateGamePieceType(this);
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package forge.game.card;
|
||||
|
||||
public class CardChangedName {
|
||||
|
||||
protected String newName;
|
||||
protected boolean addNonLegendaryCreatureNames = false;
|
||||
|
||||
public CardChangedName(String newName, boolean addNonLegendaryCreatureNames) {
|
||||
this.newName = newName;
|
||||
this.addNonLegendaryCreatureNames = addNonLegendaryCreatureNames;
|
||||
}
|
||||
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return newName != null;
|
||||
}
|
||||
|
||||
public boolean isAddNonLegendaryCreatureNames() {
|
||||
return addNonLegendaryCreatureNames;
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,17 @@ import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.staticability.StaticAbilityTapPowerValue;
|
||||
import forge.util.IterableUtil;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.StreamUtil;
|
||||
import forge.util.collect.FCollectionView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -480,4 +485,26 @@ public class CardLists {
|
||||
// (b) including the last element
|
||||
return isSubsetSum(numList, sum) || isSubsetSum(numList, sum - last);
|
||||
}
|
||||
|
||||
public static int getDifferentNamesCount(Iterable<Card> cardList) {
|
||||
// first part the ones with SpyKit, and already collect them via
|
||||
Map<Boolean, List<Card>> parted = StreamUtil.stream(cardList).collect(Collectors
|
||||
.partitioningBy(Card::hasNonLegendaryCreatureNames, Collector.of(ArrayList::new, (list, c) -> {
|
||||
if (!c.hasNoName() && list.stream().noneMatch(c2 -> c.sharesNameWith(c2))) {
|
||||
list.add(c);
|
||||
}
|
||||
}, (l1, l2) -> {
|
||||
l1.addAll(l2);
|
||||
return l1;
|
||||
})));
|
||||
List<Card> preList = parted.get(Boolean.FALSE);
|
||||
|
||||
// then try to apply the SpyKit ones
|
||||
for (Card c : parted.get(Boolean.TRUE)) {
|
||||
if (preList.stream().noneMatch(c2 -> c.sharesNameWith(c2))) {
|
||||
preList.add(c);
|
||||
}
|
||||
}
|
||||
return preList.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package forge.game.cost;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.*;
|
||||
import forge.game.player.Player;
|
||||
@@ -29,7 +28,6 @@ import forge.util.TextUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The Class CostDiscard.
|
||||
@@ -63,11 +61,20 @@ public class CostDiscard extends CostPartWithList {
|
||||
public Integer getMaxAmountX(SpellAbility ability, Player payer, final boolean effect) {
|
||||
final Card source = ability.getHostCard();
|
||||
String type = this.getType();
|
||||
|
||||
boolean differentNames = false;
|
||||
if (type.contains("+WithDifferentNames")) {
|
||||
type = type.replace("+WithDifferentNames", "");
|
||||
differentNames = true;
|
||||
}
|
||||
CardCollectionView handList = payer.canDiscardBy(ability, effect) ? payer.getCardsIn(ZoneType.Hand) : CardCollection.EMPTY;
|
||||
|
||||
if (!type.equals("Random")) {
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability);
|
||||
}
|
||||
if (differentNames) {
|
||||
return CardLists.getDifferentNamesCount(handList);
|
||||
}
|
||||
return handList.size();
|
||||
}
|
||||
|
||||
@@ -92,7 +99,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
else if (this.getType().equals("LastDrawn")) {
|
||||
sb.append("the last card you drew this turn");
|
||||
}
|
||||
else if (this.getType().equals("DifferentNames")) {
|
||||
else if (this.getType().contains("+WithDifferentNames")) {
|
||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), "Card")).append(" with different names");
|
||||
}
|
||||
else {
|
||||
@@ -145,21 +152,17 @@ public class CostDiscard extends CostPartWithList {
|
||||
final Card c = payer.getLastDrawnCard();
|
||||
return handList.contains(c);
|
||||
}
|
||||
else if (type.equals("DifferentNames")) {
|
||||
Set<String> cardNames = Sets.newHashSet();
|
||||
for (Card c : handList) {
|
||||
if (!c.hasNoName()) {
|
||||
cardNames.add(c.getName());
|
||||
}
|
||||
}
|
||||
return cardNames.size() >= amount;
|
||||
}
|
||||
else {
|
||||
boolean sameName = false;
|
||||
boolean differentNames = false;
|
||||
if (type.contains("+WithSameName")) {
|
||||
sameName = true;
|
||||
type = TextUtil.fastReplace(type, "+WithSameName", "");
|
||||
}
|
||||
if (type.contains("+WithDifferentNames")) {
|
||||
type = type.replace("+WithDifferentNames", "");
|
||||
differentNames = true;
|
||||
}
|
||||
if (type.contains("ChosenColor") && !source.hasChosenColor()) {
|
||||
//color hasn't been chosen yet, so skip getValidCards
|
||||
} else if (!type.equals("Random") && !type.contains("X")) {
|
||||
@@ -173,6 +176,10 @@ public class CostDiscard extends CostPartWithList {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (differentNames) {
|
||||
if (CardLists.getDifferentNamesCount(handList) < amount) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int adjustment = 0;
|
||||
if (source.isInZone(ZoneType.Hand) && payer.equals(source.getOwner())) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package forge.game.cost;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import forge.card.CardType;
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityKey;
|
||||
@@ -31,7 +30,6 @@ import forge.game.zone.ZoneType;
|
||||
import forge.util.Lang;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The Class CostSacrifice.
|
||||
@@ -74,16 +72,7 @@ public class CostSacrifice extends CostPartWithList {
|
||||
}
|
||||
typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability, effect));
|
||||
if (differentNames) {
|
||||
// TODO rewrite with sharesName to respect Spy Kit
|
||||
final Set<String> crdname = Sets.newHashSet();
|
||||
for (final Card card : typeList) {
|
||||
String name = card.getName();
|
||||
// CR 201.2b Those objects have different names only if each of them has at least one name and no two objects in that group have a name in common
|
||||
if (!card.hasNoName()) {
|
||||
crdname.add(name);
|
||||
}
|
||||
}
|
||||
return crdname.size();
|
||||
return CardLists.getDifferentNamesCount(typeList);
|
||||
}
|
||||
return typeList.size();
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ ManaCost:3
|
||||
Types:Artifact
|
||||
A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color.
|
||||
A:AB$ Draw | Cost$ 7 T Sac<1/CARDNAME> | NumCards$ X | SpellDescription$ Draw X cards, where X is the number of differently named lands you control.
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
Oracle:{T}: Add one mana of any color.\n{7}, {T}, Sacrifice this artifact: Draw X cards, where X is the number of differently named lands you control.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 G
|
||||
Types:Sorcery
|
||||
A:SP$ Token | TokenScript$ g_0_1_plant | SubAbility$ DBDraw | SpellDescription$ Create a 0/1 green Plant creature token, then draw cards equal to the number of differently named creature tokens you control.
|
||||
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ X | StackDescription$ None
|
||||
SVar:X:Count$DifferentCardNames_Creature.YouCtrl+token+inZoneBattlefield
|
||||
SVar:X:Count$Valid Creature.YouCtrl+token$DifferentCardNames
|
||||
DeckHas:Ability$Token & Type$Plant
|
||||
DeckHints:Ability$Token
|
||||
Oracle:Create a 0/1 green Plant creature token, then draw cards equal to the number of differently named creature tokens you control.
|
||||
|
||||
@@ -3,5 +3,5 @@ ManaCost:4
|
||||
Types:Artifact Creature Golem
|
||||
PT:*/*
|
||||
S:Mode$ Continuous | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of differently named lands you control.
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
Oracle:Awakened Amalgam's power and toughness are each equal to the number of differently named lands you control.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Eerie Ultimatum
|
||||
ManaCost:W W B B B G G
|
||||
Types:Sorcery
|
||||
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Permanent.YouOwn | ChangeNumDesc$ any number of | ChangeTypeDesc$ permanent cards with different names | DifferentNames$ True | ChangeNum$ X | Hidden$ True | SpellDescription$ Return any number of permanent cards with different names from your graveyard to the battlefield.
|
||||
SVar:X:Count$DifferentCardNames_Permanent.YouOwn+inZoneGraveyard
|
||||
SVar:X:Count$ValidGraveyard Permanent.YouOwn$DifferentCardNames
|
||||
SVar:IsReanimatorCard:TRUE
|
||||
DeckHas:Ability$Graveyard
|
||||
Oracle:Return any number of permanent cards with different names from your graveyard to the battlefield.
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Treefolk Wizard
|
||||
PT:6/6
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters, create a number of 1/1 blue Human Wizard creature tokens equal to the number of differently named lands you control.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ u_1_1_human_wizard
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
A:AB$ Draw | Cost$ 4 G U | NumCards$ Y | SubAbility$ PumpAll | SpellDescription$ Draw a card for each Wizard you control. They each get +1/+1 until end of turn for each card in your hand.
|
||||
SVar:Y:Count$Valid Wizard.YouCtrl
|
||||
SVar:PumpAll:DB$ PumpAll | ValidCards$ Wizard.YouCtrl | NumAtt$ +Z | NumDef$ +Z
|
||||
|
||||
@@ -6,6 +6,6 @@ SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self,Land.Other+YouCtrl | CheckSVar$ X | SVarCompare$ GE7 | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME or another land you control enters, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_zombie | TokenOwner$ You | TokenAmount$ 1
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
DeckHas:Ability$Token
|
||||
Oracle:Field of the Dead enters tapped.\n{T}: Add {C}.\nWhenever Field of the Dead or another land you control enters, if you control seven or more lands with different names, create a 2/2 black Zombie creature token.
|
||||
|
||||
@@ -3,5 +3,5 @@ ManaCost:6 G
|
||||
Types:Creature Fungus Beast
|
||||
PT:5/5
|
||||
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {X} less to cast, where X is the number of differently named lands you control.
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
Oracle:This spell costs {X} less to cast, where X is the number of differently named lands you control.
|
||||
|
||||
@@ -7,7 +7,7 @@ T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefiel
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ r_0_0_a_gremlin | RememberTokens$ True | SubAbility$ DBCounters
|
||||
SVar:DBCounters:DB$ PutCounter | Defined$ Remembered | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$DifferentCardNames_Artifact.YouCtrl+inZoneBattlefield+token
|
||||
SVar:X:Count$Valid Artifact.YouCtrl+token$DifferentCardNames
|
||||
DeckHas:Ability$Token|Counters
|
||||
DeckHints:Type$Artifact & Ability$Token
|
||||
Oracle:Artifact creatures you control have trample.\nAt the beginning of your end step, create a 0/0 red Gremlin artifact creature token. Put X +1/+1 counters on it, where X is the number of differently named artifact tokens you control.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3 B B
|
||||
Types:Enchantment
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ DBWin | TriggerZones$ Battlefield | CheckSVar$ Contractors | SVarCompare$ GE4 | TriggerDescription$ At the beginning of your upkeep, if you control four or more Demons with different names, you win the game.
|
||||
SVar:DBWin:DB$ WinsGame | Defined$ You | ConditionCheckSVar$ Contractors | ConditionSVarCompare$ GE4
|
||||
SVar:Contractors:Count$DifferentCardNames_Demon.YouCtrl+inRealZoneBattlefield
|
||||
SVar:Contractors:Count$Valid Demon.YouCtrl$DifferentCardNames
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, you draw four cards and you lose 4 life.
|
||||
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 4 | SubAbility$ DBLoseLife
|
||||
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 4
|
||||
|
||||
@@ -6,6 +6,6 @@ SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True
|
||||
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
|
||||
A:AB$ ChangeZone | Cost$ 3 T Return<1/CARDNAME> | ChangeType$ Gate | ChangeNum$ 1 | Origin$ Library | Destination$ Battlefield | AILogic$ MazesEnd | SubAbility$ DBWin | SpellDescription$ Search your library for a Gate card, put it onto the battlefield, then shuffle. If you control ten or more Gates with different names, you win the game.
|
||||
SVar:DBWin:DB$ WinsGame | Defined$ You | ConditionCheckSVar$ MazeGate | ConditionSVarCompare$ GE10
|
||||
SVar:MazeGate:Count$DifferentCardNames_Gate.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Gate.YouCtrl$DifferentCardNames
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Maze's End enters tapped.\n{T}: Add {C}.\n{3}, {T}, Return Maze's End to its owner's hand: Search your library for a Gate card, put it onto the battlefield, then shuffle. If you control ten or more Gates with different names, you win the game.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2
|
||||
Types:Artifact
|
||||
A:AB$ ChangeZone | Cost$ 3 T | Origin$ Library | Destination$ Hand | ChangeType$ Land.Basic,Land.Locus,Land.Sphere | ChangeTypeDesc$ basic, Sphere, or Locus land card | SpellDescription$ Search your library for a basic, Sphere, or Locus land card, reveal it, put it into your hand, then shuffle.
|
||||
A:AB$ Animate | Cost$ 3 | CheckSVar$ CountAll | SVarCompare$ GE9 | Power$ 9 | Toughness$ 9 | Types$ Artifact,Creature,Phyrexian,Construct | RemoveCreatureTypes$ True | RemoveAllAbilities$ True | Defined$ Self | Keywords$ Indestructible & Toxic:9 | Duration$ Permanent | SpellDescription$ CARDNAME becomes a 9/9 Phyrexian Construct artifact creature, loses all abilities, and gains indestructible and toxic 9. Activate only if there are nine or more lands with different names among the basic, Sphere, and Locus lands you control.
|
||||
SVar:CountAll:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield+Basic,Sphere.YouCtrl+inZoneBattlefield,Locus.YouCtrl+inZoneBattlefield
|
||||
SVar:CountAll:Count$Valid Land.YouCtrl+Basic,Sphere.YouCtrl,Locus.YouCtrl$DifferentCardNames
|
||||
DeckHas:Type$Phyrexian|Construct|Artifact
|
||||
DeckNeeds:Type$Locus|Sphere
|
||||
Oracle:{3}, {T}: Search your library for a basic, Sphere, or Locus land card, reveal it, put it into your hand, then shuffle.\n{3}: Monument to Perfection becomes a 9/9 Phyrexian Construct artifact creature, loses all abilities, and gains indestructible and toxic 9. Activate only if there are nine or more lands with different names among the basic, Sphere, and Locus lands you control.
|
||||
|
||||
@@ -11,7 +11,7 @@ SVar:TrigExile:DB$ Dig | Defined$ You | DigNum$ X | ChangeNum$ All | Destination
|
||||
SVar:DBEffectYou:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile | Duration$ Permanent
|
||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile | CheckSVar$ Y | Description$ During any turn you attacked with a commander, you may play those cards.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$DifferentCardNames_Permanent.token+YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Permanent.YouCtrl+token$DifferentCardNames
|
||||
SVar:Y:Count$CreaturesAttackedThisTurn Creature.IsCommander+YouCtrl
|
||||
SVar:HasAttackEffect:TRUE
|
||||
Oracle:Flying,deathtouch\nWhen Neriv enters, create two 1/1 red Goblin creature tokens.\nWhenever Neriv attacks, exile a number of cards from the top of your library equal to the number of differently named tokens you control. During any turn you attacked with a commander, you may play those cards.
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:5/5
|
||||
K:Flying
|
||||
R:Event$ Draw | ActiveZones$ Battlefield | ValidPlayer$ You | IsPresent$ Card.YouOwn | PresentZone$ Library | PresentCompare$ EQ0 | ReplaceWith$ AddCounters | Description$ If you would draw a card while your library has no cards in it, instead put five +1/+1 counters on CARDNAME.
|
||||
SVar:AddCounters:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 5 | Defined$ Self
|
||||
A:AB$ Draw | Cost$ 1 U U Discard<3/DifferentNames> | NumCards$ 5 | SpellDescription$ Draw five cards.
|
||||
A:AB$ Draw | Cost$ 1 U U Discard<3/Card+WithDifferentNames> | NumCards$ 5 | SpellDescription$ Draw five cards.
|
||||
AI:RemoveDeck:All
|
||||
Oracle:Flying\nIf you would draw a card while your library has no cards in it, instead put five +1/+1 counters on Ormos, Archive Keeper.\n{1}{U}{U}, Discard three cards with different names: Draw five cards.
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:4/4
|
||||
K:Trample
|
||||
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of combat on your turn, bolster X, where X is the number of differently named artifact tokens you control. (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)
|
||||
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ X | Bolster$ True
|
||||
SVar:X:Count$DifferentCardNames_Artifact.YouCtrl+token+inZoneBattlefield
|
||||
SVar:X:Count$Valid Artifact.YouCtrl+token$DifferentCardNames
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Trample\nAt the beginning of combat on your turn, bolster X, where X is the number of differently named artifact tokens you control. (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)
|
||||
|
||||
@@ -8,6 +8,6 @@ SVar:TrigExile:DB$ Repeat | RepeatSubAbility$ DBExileCleanup | RepeatCheckSVar$
|
||||
SVar:DBExileCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBExile
|
||||
SVar:DBExile:DB$ Dig | Defined$ TriggeredTarget | DigNum$ 4 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$DifferentCardNames_Card.IsRemembered
|
||||
SVar:X:Remembered$DifferentCardNames
|
||||
SVar:Y:Count$RememberedSize
|
||||
Oracle:Flying (This creature can't be blocked except by creatures with flying or reach.)\nWhenever Scalpelexis deals combat damage to a player, that player exiles the top four cards of their library. If two or more of those cards have the same name, repeat this process.
|
||||
|
||||
@@ -6,6 +6,6 @@ SVar:DBChoose:DB$ ChooseCard | Defined$ You | Amount$ 1 | AtRandom$ True | Choic
|
||||
SVar:DBChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | Defined$ ChosenCard | StackDescription$ None | SubAbility$ DBShuffle | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ3
|
||||
SVar:DBShuffle:DB$ Shuffle | Defined$ You | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$DifferentCardNames_Creature.IsRemembered
|
||||
SVar:X:Remembered$DifferentCardNames
|
||||
AI:RemoveDeck:All
|
||||
Oracle:Search your library for three creature cards and reveal them. If you reveal three cards with different names, choose one of them at random and put that card into your hand. Shuffle the rest into your library.
|
||||
|
||||
@@ -7,5 +7,5 @@ K:Hexproof
|
||||
A:AB$ DealDamage | Cost$ 10 Sac<1/CARDNAME> | ValidTgts$ Any | NumDmg$ 3 | ReduceCost$ X | SubAbility$ DBDraw | SpellDescription$ It deals 3 damage to any target. Target player draws three cards and gains 3 life. This ability costs {X} less to activate, where X is the number of differently named lands you control.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 3 | ValidTgts$ Player | SubAbility$ DBGainLife
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ ParentTarget | LifeAmount$ 3
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
Oracle:Flying\nHexproof (This creature can't be the target of spells or abilities your opponents control.)\n{10}, Sacrifice this creature: It deals 3 damage to any target. Target player draws three cards and gains 3 life. This ability costs {X} less to activate, where X is the number of differently named lands you control.
|
||||
|
||||
@@ -6,7 +6,7 @@ SVar:DBConjureAll:DB$ MakeCard | Conjure$ True | Names$ First Little Pig,Second
|
||||
SVar:DBConjureTwo:DB$ MakeCard | Conjure$ True | SpellbookName$ the Three Pigs | Spellbook$ First Little Pig,Second Little Pig,Third Little Pig | SpellbookAmount$ 2 | RememberMade$ True | Zone$ Hand | SubAbility$ DBPutBattlefield
|
||||
SVar:DBPutBattlefield:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Card.IsRemembered | ChangeNum$ 1 | Mandatory$ True | SelectPrompt$ Select a card to put onto the battlefield | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$DifferentCardNames_Boar.YouCtrl+inRealZoneBattlefield
|
||||
SVar:X:Count$Valid Boar.YouCtrl$DifferentCardNames
|
||||
DeckHints:Type$Boar
|
||||
DeckHas:Type$Boar
|
||||
Oracle:If you control three or more Boars with different names, conjure each card from the Three Pigs spellbook onto the battlefield.\nIf you control two or fewer Boars with different names, conjure two cards of your choice from the Three Pigs spellbook into your hand, then put one of them onto the battlefield.
|
||||
|
||||
@@ -6,7 +6,7 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.Y
|
||||
SVar:TrigBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE7 | TrueSubAbility$ DBZombie | FalseSubAbility$ DBPlant
|
||||
SVar:DBPlant:DB$ Token | TokenAmount$ 1 | TokenScript$ g_0_1_plant | TokenOwner$ You
|
||||
SVar:DBZombie:DB$ Token | TokenAmount$ 1 | TokenScript$ b_2_2_zombie | TokenOwner$ You
|
||||
SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield
|
||||
SVar:X:Count$Valid Land.YouCtrl$DifferentCardNames
|
||||
S:Mode$ Continuous | AffectedZone$ Graveyard | Affected$ Land.YouOwn | AddKeyword$ Dredge:2 | Description$ Land cards in your graveyard have dredge 2. (You may return a land card from your graveyard to your hand and mill two cards instead of drawing a card.)
|
||||
DeckHas:Ability$Token & Type$Zombie
|
||||
DeckHints:Ability$Mill
|
||||
|
||||
@@ -113,7 +113,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
}
|
||||
return PaymentDecision.card(randomSubset);
|
||||
}
|
||||
if (discardType.equals("DifferentNames")) {
|
||||
if (discardType.contains("+WithDifferentNames")) {
|
||||
final CardCollection discarded = new CardCollection();
|
||||
while (c > 0) {
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, 1, hand, ability);
|
||||
|
||||
Reference in New Issue
Block a user