mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 10:18:01 +00:00
Doomsday Confluence and support (#4012)
* Doomsday Confluence and support * Clean up * Fix NPE * +AIhint --------- Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.60>
This commit is contained in:
@@ -59,19 +59,21 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
Card source = sa.getHostCard();
|
Card source = sa.getHostCard();
|
||||||
|
|
||||||
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa);
|
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa);
|
||||||
final int num;
|
String numParam = sa.getParamOrDefault("CharmNum", "1");
|
||||||
|
boolean isX = numParam.equals("X");
|
||||||
|
int num = 0;
|
||||||
boolean additionalDesc = sa.hasParam("AdditionalDescription");
|
boolean additionalDesc = sa.hasParam("AdditionalDescription");
|
||||||
boolean optional = sa.hasParam("Optional");
|
boolean optional = sa.hasParam("Optional");
|
||||||
// hotfix for complex cards when using getCardForUi
|
// hotfix for complex cards when using getCardForUi
|
||||||
if (source.getController() == null && additionalDesc && !optional) {
|
if (source.getController() == null && additionalDesc && !optional) {
|
||||||
// using getCardForUi game is not set, so can't guess max charm
|
// using getCardForUi game is not set, so can't guess max charm
|
||||||
num = Integer.MAX_VALUE;
|
num = Integer.MAX_VALUE;
|
||||||
} else {
|
} else if (!isX) {
|
||||||
// fallback needed while ability building
|
// fallback needed while ability building
|
||||||
if (sa.getActivatingPlayer() == null) {
|
if (sa.getActivatingPlayer() == null) {
|
||||||
sa.setActivatingPlayer(source.getController(), true);
|
sa.setActivatingPlayer(source.getController(), true);
|
||||||
}
|
}
|
||||||
num = Math.min(AbilityUtils.calculateAmount(source, sa.getParamOrDefault("CharmNum", "1"), sa), list.size());
|
num = Math.min(AbilityUtils.calculateAmount(source, numParam, sa), list.size());
|
||||||
}
|
}
|
||||||
final int min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num;
|
final int min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num;
|
||||||
|
|
||||||
@@ -85,7 +87,9 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
sb.append(sa.getCostDescription());
|
sb.append(sa.getCostDescription());
|
||||||
sb.append(oppChooses ? "An opponent chooses " : "Choose ");
|
sb.append(oppChooses ? "An opponent chooses " : "Choose ");
|
||||||
|
|
||||||
if (num == min || num == Integer.MAX_VALUE) {
|
if (isX) {
|
||||||
|
sb.append("X");
|
||||||
|
} else if (num == min || num == Integer.MAX_VALUE) {
|
||||||
sb.append(num == 0 ? "up to that many" : Lang.getNumeral(min));
|
sb.append(num == 0 ? "up to that many" : Lang.getNumeral(min));
|
||||||
} else if (min == 0 && num == sa.getParam("Choices").split(",").length) {
|
} else if (min == 0 && num == sa.getParam("Choices").split(",").length) {
|
||||||
sb.append("any number ");
|
sb.append("any number ");
|
||||||
@@ -188,14 +192,17 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
|
|
||||||
|
boolean canRepeat = sa.hasParam("CanRepeatModes");
|
||||||
int num = AbilityUtils.calculateAmount(source, sa.getParamOrDefault("CharmNum", "1"), sa);
|
int num = AbilityUtils.calculateAmount(source, sa.getParamOrDefault("CharmNum", "1"), sa);
|
||||||
final int min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num;
|
final int min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num;
|
||||||
|
|
||||||
// if the amount of choices is smaller than min then they can't be chosen
|
// if the amount of choices is smaller than min then they can't be chosen
|
||||||
|
if (!canRepeat) {
|
||||||
if (min > choices.size()) {
|
if (min > choices.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
num = Math.min(num, choices.size());
|
num = Math.min(num, choices.size());
|
||||||
|
}
|
||||||
|
|
||||||
boolean isOptional = sa.hasParam("Optional");
|
boolean isOptional = sa.hasParam("Optional");
|
||||||
if (isOptional && !activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblWouldYouLikeCharm", CardTranslation.getTranslatedName(source.getName())), null)) {
|
if (isOptional && !activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblWouldYouLikeCharm", CardTranslation.getTranslatedName(source.getName())), null)) {
|
||||||
@@ -219,7 +226,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
|||||||
source.setChosenPlayer(chooser);
|
source.setChosenPlayer(chooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AbilitySub> chosen = chooser.getController().chooseModeForAbility(sa, choices, min, num, sa.hasParam("CanRepeatModes"));
|
List<AbilitySub> chosen = chooser.getController().chooseModeForAbility(sa, choices, min, num, canRepeat);
|
||||||
chainAbilities(sa, chosen);
|
chainAbilities(sa, chosen);
|
||||||
|
|
||||||
// trigger without chosen modes are removed from stack
|
// trigger without chosen modes are removed from stack
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
@@ -65,7 +67,7 @@ public class CleanUpEffect extends SpellAbilityEffect {
|
|||||||
source.setChosenColors(null);
|
source.setChosenColors(null);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("ClearNamedCard")) {
|
if (sa.hasParam("ClearNamedCard")) {
|
||||||
source.setNamedCards(null);
|
source.setNamedCards(Lists.newArrayList());
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Log")) {
|
if (sa.hasParam("Log")) {
|
||||||
source.getController().getGame().fireEvent(new GameEventRandomLog(logMessage));
|
source.getController().getGame().fireEvent(new GameEventRandomLog(logMessage));
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// Set Chosen name
|
// Set Chosen name
|
||||||
if (!hostCard.getNamedCard().isEmpty()) {
|
if (!hostCard.getNamedCard().isEmpty()) {
|
||||||
eff.setNamedCards(hostCard.getNamedCards());
|
eff.setNamedCards(Lists.newArrayList(hostCard.getNamedCards()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// chosen number
|
// chosen number
|
||||||
|
|||||||
@@ -1987,7 +1987,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return hasNamedCard() ? Iterables.getLast(chosenName) : "";
|
return hasNamedCard() ? Iterables.getLast(chosenName) : "";
|
||||||
}
|
}
|
||||||
public final List<String> getNamedCards() {
|
public final List<String> getNamedCards() {
|
||||||
return chosenName == null ? Lists.newArrayList() : chosenName;
|
return chosenName;
|
||||||
}
|
}
|
||||||
public final void setNamedCards(final List<String> s) {
|
public final void setNamedCards(final List<String> s) {
|
||||||
chosenName = s;
|
chosenName = s;
|
||||||
@@ -2000,7 +2000,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNamedCard() {
|
public boolean hasNamedCard() {
|
||||||
return chosenName != null && !chosenName.isEmpty();
|
return !chosenName.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChosenEvenOdd() {
|
public boolean hasChosenEvenOdd() {
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ public final class CardUtil {
|
|||||||
|
|
||||||
newCopy.setChosenType(in.getChosenType());
|
newCopy.setChosenType(in.getChosenType());
|
||||||
newCopy.setChosenType2(in.getChosenType2());
|
newCopy.setChosenType2(in.getChosenType2());
|
||||||
newCopy.setNamedCards(in.getNamedCards());
|
newCopy.setNamedCards(Lists.newArrayList(in.getNamedCards()));
|
||||||
newCopy.setChosenColors(Lists.newArrayList(in.getChosenColors()));
|
newCopy.setChosenColors(Lists.newArrayList(in.getChosenColors()));
|
||||||
if (in.hasChosenNumber()) {
|
if (in.hasChosenNumber()) {
|
||||||
newCopy.setChosenNumber(in.getChosenNumber());
|
newCopy.setChosenNumber(in.getChosenNumber());
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
Name:Braids's Frightful Return
|
Name:Braids's Frightful Return
|
||||||
ManaCost:2 B
|
ManaCost:2 B
|
||||||
Types:Enchantment Saga
|
Types:Enchantment Saga
|
||||||
K:Read ahead:3:DBSacrifice,DBChangeZone,DBSacrificeOpp
|
K:Read ahead:3:ABDiscard,DBChangeZone,DBSacrificeOpp
|
||||||
SVar:DBSacrifice:DB$ Sacrifice | Optional$ True | Defined$ You | RememberSacrificed$ True | SacValid$ Creature | Amount$ 1 | SubAbility$ DBDiscard | SpellDescription$ You may sacrifice a creature. If you do, each opponent discards a card.
|
SVar:ABDiscard:AB$ Discard | Cost$ Sac<1/Creature> | CostDesc$ You may sacrifice a creature. | Mode$ TgtChoose | Defined$ Opponent | SpellDescription$ If you do, each opponent discards a card.
|
||||||
SVar:DBDiscard:DB$ Discard | Mode$ TgtChoose | Defined$ Player.Opponent | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | NumCards$ 1 | SubAbility$ DBCleanup
|
|
||||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Creature.YouOwn | SpellDescription$ Return target creature card from your graveyard to your hand.
|
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Creature.YouOwn | SpellDescription$ Return target creature card from your graveyard to your hand.
|
||||||
SVar:DBSacrificeOpp:DB$ Sacrifice | ValidTgts$ Opponent | Optional$ True | SacValid$ Permanent.nonLand+nonToken | RememberSacrificed$ True | SubAbility$ DBDraw | SpellDescription$ Target opponent may sacrifice a nonland, nontoken permanent. If they don't, they lose 2 life and you draw a card.
|
SVar:DBSacrificeOpp:DB$ Sacrifice | ValidTgts$ Opponent | Optional$ True | SacValid$ Permanent.nonLand+nonToken | RememberSacrificed$ True | SubAbility$ DBDraw | SpellDescription$ Target opponent may sacrifice a nonland, nontoken permanent. If they don't, they lose 2 life and you draw a card.
|
||||||
SVar:DBDraw:DB$ Draw | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBLoseLife
|
SVar:DBDraw:DB$ Draw | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBLoseLife
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ Types:Enchantment Aura
|
|||||||
K:Enchant creature
|
K:Enchant creature
|
||||||
A:SP$ Attach | Cost$ R | ValidTgts$ Creature | AILogic$ Curse
|
A:SP$ Attach | Cost$ R | ValidTgts$ Creature | AILogic$ Curse
|
||||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddToughness$ -1 | Description$ Enchanted creature gets -0/-1 and can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddToughness$ -1 | Description$ Enchanted creature gets -0/-1 and can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
||||||
S:Mode$ CantBlockBy | ValidAttackerRelative$ Creature.powerGEIronclawX | ValidBlocker$ Creature.EnchantedBy | Description$ Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
S:Mode$ CantBlockBy | ValidAttackerRelative$ Creature.powerGEIronclawX | ValidBlocker$ Creature.EnchantedBy | Secondary$ True | Description$ Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
||||||
SVar:IronclawX:Count$CardToughness
|
SVar:IronclawX:Count$CardToughness
|
||||||
Oracle:Enchant creature\nEnchanted creature gets -0/-1.\nEnchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
Oracle:Enchant creature\nEnchanted creature gets -0/-1.\nEnchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
||||||
|
|||||||
11
forge-gui/res/cardsfolder/upcoming/doomsday_confluence.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/doomsday_confluence.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Doomsday Confluence
|
||||||
|
ManaCost:X X B
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Charm | CharmNum$ X | Choices$ DBSac,DBToken,DBDiscard | CanRepeatModes$ True
|
||||||
|
SVar:DBSac:DB$ Sacrifice | Defined$ Player | SacValid$ Creature.nonArtifact | SpellDescription$ Each player sacrifices a nonartifact creature.
|
||||||
|
SVar:DBToken:DB$ Token | TokenScript$ b_3_3_a_dalek_menace | SpellDescription$ Create a 3/3 black Dalek artifact creature token with menace.
|
||||||
|
SVar:DBDiscard:DB$ Discard | Defined$ Opponent | Mode$ TgtChoose | SpellDescription$ Each opponent discards a card.
|
||||||
|
SVar:X:Count$xPaid
|
||||||
|
DeckHas:Ability$Sacrifice|Token|Discard & Type$Artifact|Dalek
|
||||||
|
AI:RemoveDeck:All
|
||||||
|
Oracle:Choose X. You may choose the same mode more than once.\n• Each player sacrifices a nonartifact creature.\n• Create a 3/3 black Dalek artifact creature token with menace.\n• Each opponent discards a card.
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
Name:The Huntsman's Redemption
|
Name:The Huntsman's Redemption
|
||||||
ManaCost:2 G
|
ManaCost:2 G
|
||||||
Types:Enchantment Saga
|
Types:Enchantment Saga
|
||||||
K:Saga:3:DBToken,DBSearch,DBPump
|
K:Saga:3:DBToken,ABSearch,DBPump
|
||||||
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_3_3_beast | TokenOwner$ You | SpellDescription$ Create a 3/3 green Beast creature token.
|
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_3_3_beast | TokenOwner$ You | SpellDescription$ Create a 3/3 green Beast creature token.
|
||||||
SVar:DBSearch:DB$ Sacrifice | SacValid$ Creature | SacMessage$ creature | Optional$ True | RememberSacrificed$ True | SubAbility$ DBChangeZone | SpellDescription$ You may sacrifice a creature. If you do, search your library for a creature or basic land card, reveal it, put it into your hand, then shuffle.
|
SVar:ABSearch:AB$ ChangeZone | Cost$ Sac<1/Creature> | CostDesc$ You may sacrifice a creature. | Origin$ Library | Destination$ Hand | ChangeType$ Land.Basic,Creature | ChangeNum$ 1 | SpellDescription$ If you do, search your library for a creature or basic land card, reveal it, put it into your hand, then shuffle.
|
||||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ConditionDefined$ Remembered | ConditionPresent$ Card | ChangeType$ Land.Basic,Creature | SubAbility$ DBCleanup | ChangeNum$ 1
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
|
||||||
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | NumAtt$ +2 | NumDef$ +2 | TgtPrompt$ Select up to two target creatures | TargetMin$ 0 | TargetMax$ 2 | KW$ Trample | SpellDescription$ Up to two target creatures each get +2/+2 and gain trample until end of turn
|
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | NumAtt$ +2 | NumDef$ +2 | TgtPrompt$ Select up to two target creatures | TargetMin$ 0 | TargetMax$ 2 | KW$ Trample | SpellDescription$ Up to two target creatures each get +2/+2 and gain trample until end of turn
|
||||||
DeckHas:Ability$Token|Sacrifice & Type$Beast
|
DeckHas:Ability$Token|Sacrifice & Type$Beast
|
||||||
Oracle:I — Create a 3/3 green Beast creature token.\nII — You may sacrifice a creature. If you do, search your library for a creature or basic land card, reveal it, put it into your hand, then shuffle.\nIII — Up to two target creatures each get +2/+2 and gain trample until end of turn
|
Oracle:I — Create a 3/3 green Beast creature token.\nII — You may sacrifice a creature. If you do, search your library for a creature or basic land card, reveal it, put it into your hand, then shuffle.\nIII — Up to two target creatures each get +2/+2 and gain trample until end of turn
|
||||||
@@ -2,7 +2,7 @@ Name:Yenna, Redtooth Regent
|
|||||||
ManaCost:2 G W
|
ManaCost:2 G W
|
||||||
Types:Legendary Creature Elf Noble
|
Types:Legendary Creature Elf Noble
|
||||||
PT:4/4
|
PT:4/4
|
||||||
A:AB$ CopyPermanent | Cost$ 2 T | Defined$ Targeted | RememberTokens$ True | NonLegendary$ True | ValidTgts$ Enchantment.YouCtrl+doesNotShareNameWith OtherYourBattlefield | TgtPrompt$ Choose target enchantment you control that doesn't have the same name as another permanent you control. | SorcerySpeed$ True | SubAbility$ DBUntap | SpellDescription$ Choose target enchantment you control that doesn't have the same name as another permanent you control. Create a token that's a copy of it, except it isn't legendary. If the token is an Aura, untap Yenna, Redtooth Regent, then scry 2. Activate only as a sorcery.
|
A:AB$ CopyPermanent | Cost$ 2 T | Defined$ Targeted | RememberTokens$ True | NonLegendary$ True | ValidTgts$ Enchantment.YouCtrl+doesNotShareNameWith OtherYourBattlefield | TgtPrompt$ Choose target enchantment you control that doesn't have the same name as another permanent you control. | SorcerySpeed$ True | SubAbility$ DBUntap | SpellDescription$ Choose target enchantment you control that doesn't have the same name as another permanent you control. Create a token that's a copy of it, except it isn't legendary. If the token is an Aura, untap CARDNAME, then scry 2. Activate only as a sorcery.
|
||||||
SVar:DBUntap:DB$ Untap | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Card.Aura | SubAbility$ DBScry
|
SVar:DBUntap:DB$ Untap | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Card.Aura | SubAbility$ DBScry
|
||||||
SVar:DBScry:DB$ Scry | ScryNum$ 2 | ConditionDefined$ Remembered | ConditionPresent$ Card.Aura | SubAbility$ DBCleanup
|
SVar:DBScry:DB$ Scry | ScryNum$ 2 | ConditionDefined$ Remembered | ConditionPresent$ Card.Aura | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import forge.game.GameActionUtil;
|
|||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
import forge.game.GameEntityViewMap;
|
import forge.game.GameEntityViewMap;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
|
||||||
import forge.game.ability.effects.CharmEffect;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
@@ -101,13 +99,6 @@ public class HumanPlay {
|
|||||||
source.forceTurnFaceUp();
|
source.forceTurnFaceUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getApi() == ApiType.Charm && !CharmEffect.makeChoices(sa)) {
|
|
||||||
// 603.3c If no mode is chosen, the ability is removed from the stack.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sa = AbilityUtils.addSpliceEffects(sa);
|
|
||||||
|
|
||||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||||
if (!req.playAbility(true, false, false)) {
|
if (!req.playAbility(true, false, false)) {
|
||||||
Card rollback = p.getGame().getCardState(source);
|
Card rollback = p.getGame().getCardState(source);
|
||||||
@@ -165,15 +156,6 @@ public class HumanPlay {
|
|||||||
|
|
||||||
source.setSplitStateToPlayAbility(sa);
|
source.setSplitStateToPlayAbility(sa);
|
||||||
|
|
||||||
if (sa.getApi() == ApiType.Charm && !CharmEffect.makeChoices(sa)) {
|
|
||||||
// 603.3c If no mode is chosen, the ability is removed from the stack.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sa.isCopied()) {
|
|
||||||
sa = AbilityUtils.addSpliceEffects(sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||||
req.playAbility(mayChooseNewTargets, true, false);
|
req.playAbility(mayChooseNewTargets, true, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import forge.game.GameActionUtil;
|
|||||||
import forge.game.GameObject;
|
import forge.game.GameObject;
|
||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
|
import forge.game.ability.ApiType;
|
||||||
|
import forge.game.ability.effects.CharmEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardPlayOption;
|
import forge.game.card.CardPlayOption;
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
@@ -53,6 +55,7 @@ import forge.util.Localizer;
|
|||||||
public class HumanPlaySpellAbility {
|
public class HumanPlaySpellAbility {
|
||||||
private final PlayerControllerHuman controller;
|
private final PlayerControllerHuman controller;
|
||||||
private SpellAbility ability;
|
private SpellAbility ability;
|
||||||
|
private boolean needX = true;
|
||||||
|
|
||||||
public HumanPlaySpellAbility(final PlayerControllerHuman controller0, final SpellAbility ability0) {
|
public HumanPlaySpellAbility(final PlayerControllerHuman controller0, final SpellAbility ability0) {
|
||||||
controller = controller0;
|
controller = controller0;
|
||||||
@@ -63,9 +66,25 @@ public class HumanPlaySpellAbility {
|
|||||||
final Player human = ability.getActivatingPlayer();
|
final Player human = ability.getActivatingPlayer();
|
||||||
final Game game = human.getGame();
|
final Game game = human.getGame();
|
||||||
|
|
||||||
// CR 401.5: freeze top library cards until cast/activated so player can't cheat and see the next
|
|
||||||
if (!skipStack) {
|
if (!skipStack) {
|
||||||
|
// CR 401.5: freeze top library cards until cast/activated so player can't cheat and see the next
|
||||||
game.setTopLibsCast();
|
game.setTopLibsCast();
|
||||||
|
|
||||||
|
if (ability.getApi() == ApiType.Charm) {
|
||||||
|
if ("X".equals(ability.getParam("CharmNum"))) {
|
||||||
|
// CR 601.4
|
||||||
|
if (!announceValuesLikeX()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
needX = false;
|
||||||
|
}
|
||||||
|
if (!CharmEffect.makeChoices(ability)) {
|
||||||
|
// 603.3c If no mode is chosen, the ability is removed from the stack.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ability = AbilityUtils.addSpliceEffects(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to rollback
|
// used to rollback
|
||||||
@@ -191,9 +210,7 @@ public class HumanPlaySpellAbility {
|
|||||||
private boolean announceValuesLikeX() {
|
private boolean announceValuesLikeX() {
|
||||||
if (ability.isCopied() || ability.isWrapper()) { return true; } //don't re-announce for spell copies
|
if (ability.isCopied() || ability.isWrapper()) { return true; } //don't re-announce for spell copies
|
||||||
|
|
||||||
boolean needX = true;
|
|
||||||
final Cost cost = ability.getPayCosts();
|
final Cost cost = ability.getPayCosts();
|
||||||
final PlayerController controller = ability.getActivatingPlayer().getController();
|
|
||||||
final Card card = ability.getHostCard();
|
final Card card = ability.getHostCard();
|
||||||
|
|
||||||
// Announcing Requirements like Choosing X or Multikicker
|
// Announcing Requirements like Choosing X or Multikicker
|
||||||
|
|||||||
Reference in New Issue
Block a user