Merge pull request #2734 from tool4ever/clean23

Update Charm desc when turn restriction is lifted
This commit is contained in:
Anthony Calosa
2023-03-23 18:25:13 +08:00
committed by GitHub
10 changed files with 27 additions and 25 deletions

View File

@@ -35,16 +35,11 @@ import forge.util.TextUtil;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
public class AiCostDecision extends CostDecisionMakerBase { public class AiCostDecision extends CostDecisionMakerBase {
private final SpellAbility ability;
private final Card source;
private final CardCollection discarded; private final CardCollection discarded;
private final CardCollection tapped; private final CardCollection tapped;
public AiCostDecision(Player ai0, SpellAbility sa, final boolean effect) { public AiCostDecision(Player ai0, SpellAbility sa, final boolean effect) {
super(ai0, effect); super(ai0, effect, sa, sa.getHostCard());
ability = sa;
source = ability.getHostCard();
discarded = new CardCollection(); discarded = new CardCollection();
tapped = new CardCollection(); tapped = new CardCollection();

View File

@@ -26,7 +26,7 @@ public class CharmAi extends SpellAbilityAi {
@Override @Override
protected boolean checkApiLogic(Player ai, SpellAbility sa) { protected boolean checkApiLogic(Player ai, SpellAbility sa) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa, false); List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa);
final int num; final int num;
final int min; final int min;

View File

@@ -943,7 +943,6 @@ public class Game {
public GameStage getAge() { public GameStage getAge() {
return age; return age;
} }
public void setAge(GameStage value) { public void setAge(GameStage value) {
age = value; age = value;
} }

View File

@@ -20,7 +20,7 @@ import forge.util.collect.FCollection;
public class CharmEffect extends SpellAbilityEffect { public class CharmEffect extends SpellAbilityEffect {
public static List<AbilitySub> makePossibleOptions(final SpellAbility sa, boolean forDesc) { public static List<AbilitySub> makePossibleOptions(final SpellAbility sa) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
List<String> restriction = null; List<String> restriction = null;
@@ -30,7 +30,7 @@ public class CharmEffect extends SpellAbilityEffect {
List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices")); List<AbilitySub> choices = Lists.newArrayList(sa.getAdditionalAbilityList("Choices"));
if (!forDesc) { if (source.getZone() != null) {
List<AbilitySub> toRemove = Lists.newArrayList(); List<AbilitySub> toRemove = Lists.newArrayList();
for (AbilitySub ch : choices) { for (AbilitySub ch : choices) {
// 603.3c If one of the modes would be illegal, that mode can't be chosen. // 603.3c If one of the modes would be illegal, that mode can't be chosen.
@@ -55,7 +55,7 @@ public class CharmEffect extends SpellAbilityEffect {
public static String makeFormatedDescription(SpellAbility sa) { public static String makeFormatedDescription(SpellAbility sa) {
Card source = sa.getHostCard(); Card source = sa.getHostCard();
List<AbilitySub> list = CharmEffect.makePossibleOptions(sa, true); List<AbilitySub> list = CharmEffect.makePossibleOptions(sa);
final int num; final int num;
boolean additionalDesc = sa.hasParam("AdditionalDescription"); boolean additionalDesc = sa.hasParam("AdditionalDescription");
boolean optional = sa.hasParam("Optional"); boolean optional = sa.hasParam("Optional");
@@ -169,7 +169,7 @@ public class CharmEffect extends SpellAbilityEffect {
//this resets all previous choices //this resets all previous choices
sa.setSubAbility(null); sa.setSubAbility(null);
List<AbilitySub> choices = makePossibleOptions(sa, false); List<AbilitySub> choices = makePossibleOptions(sa);
// Entwine does use all Choices // Entwine does use all Choices
if (sa.isEntwine()) { if (sa.isEntwine()) {

View File

@@ -7119,8 +7119,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
public void resetChosenModeTurn() { public void resetChosenModeTurn() {
boolean updateView = !chosenModesTurn.isEmpty() || !chosenModesTurnStatic.isEmpty();
chosenModesTurn.clear(); chosenModesTurn.clear();
chosenModesTurnStatic.clear(); chosenModesTurnStatic.clear();
if (updateView) {
updateAbilityTextForView();
}
} }
public int getPlaneswalkerAbilityActivated() { public int getPlaneswalkerAbilityActivated() {

View File

@@ -1,15 +1,23 @@
package forge.game.cost; package forge.game.cost;
import forge.game.card.Card;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> { public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
protected final Player player; protected final Player player;
protected final SpellAbility ability;
protected final Card source;
private boolean effect; private boolean effect;
public CostDecisionMakerBase(Player player0, boolean effect0) {
public CostDecisionMakerBase(Player player0, boolean effect0, SpellAbility ability0, Card source0) {
player = player0; player = player0;
effect = effect0; effect = effect0;
ability = ability0;
source = source0;
} }
public Player getPlayer() { return player; } public Player getPlayer() { return player; }
public abstract boolean paysRightAfterDecision(); public abstract boolean paysRightAfterDecision();
public boolean isEffect() { public boolean isEffect() {

View File

@@ -3,6 +3,6 @@ ManaCost:U U B B
Types:Legendary Creature Shapeshifter Types:Legendary Creature Shapeshifter
PT:3/3 PT:3/3
K:Hexproof 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 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. 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 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 | Optional$ True | AddSVars$ LazavCopy | AILogic$ IfDefinedCreatureIsBetter SVar:LazavCopy:DB$ Clone | Defined$ TriggeredCard | NewName$ Lazav, Dimir Mastermind | AddTypes$ Legendary | AddKeywords$ Hexproof | GainThisAbility$ True | Optional$ True | AddSVars$ LazavCopy | AILogic$ IfDefinedCreatureIsBetter
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. 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.

View File

@@ -4,9 +4,9 @@ Types:Legendary Creature Human Wizard
PT:4/1 PT:4/1
K:etbCounter:DREAM:7 K:etbCounter:DREAM:7
K:CARDNAME can't have more than seven dream counters on it. K:CARDNAME can't have more than seven dream counters on it.
A:AB$ Mana | Cost$ SubCounter<1/DREAM> | Produced$ C | SpellDescription$ Add {C}. A:AB$ Mana | Cost$ SubCounter<1/DREAM/NICKNAME> | Produced$ C | SpellDescription$ Add {C}.
A:AB$ PreventDamage | Cost$ SubCounter<1/DREAM> | Defined$ Self | Amount$ 1 | SpellDescription$ Prevent the next 1 damage that would be dealt to CARDNAME this turn. A:AB$ PreventDamage | Cost$ SubCounter<1/DREAM/NICKNAME> | Defined$ Self | Amount$ 1 | SpellDescription$ Prevent the next 1 damage that would be dealt to NICKNAME this turn.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | IsPresent$ Card.Self+startedTheTurnUntapped | TriggerDescription$ At the beginning of your upkeep, if CARDNAME started the turn untapped, put a dream counter on it. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | IsPresent$ Card.Self+startedTheTurnUntapped | TriggerDescription$ At the beginning of your upkeep, if NICKNAME started the turn untapped, put a dream counter on it.
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DREAM | CounterNum$ 1 SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ DREAM | CounterNum$ 1
DeckHas:Ability$Counters DeckHas:Ability$Counters
Oracle:Rasputin Dreamweaver enters the battlefield with seven dream counters on it.\nRemove a dream counter from Rasputin: Add {C}.\nRemove a dream counter from Rasputin: Prevent the next 1 damage that would be dealt to Rasputin this turn.\nAt the beginning of your upkeep, if Rasputin started the turn untapped, put a dream counter on it.\nRasputin can't have more than seven dream counters on it. Oracle:Rasputin Dreamweaver enters the battlefield with seven dream counters on it.\nRemove a dream counter from Rasputin: Add {C}.\nRemove a dream counter from Rasputin: Prevent the next 1 damage that would be dealt to Rasputin this turn.\nAt the beginning of your upkeep, if Rasputin started the turn untapped, put a dream counter on it.\nRasputin can't have more than seven dream counters on it.

View File

@@ -47,20 +47,16 @@ import forge.util.collect.FCollectionView;
public class HumanCostDecision extends CostDecisionMakerBase { public class HumanCostDecision extends CostDecisionMakerBase {
private final PlayerControllerHuman controller; private final PlayerControllerHuman controller;
private final SpellAbility ability;
private final Card source;
private String orString = null; private String orString = null;
private boolean mandatory; private boolean mandatory;
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source) { public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect) {
this(controller, p, sa, effect, source, null); this(controller, p, sa, effect, sa.getHostCard(), null);
} }
public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source, final String orString) { public HumanCostDecision(final PlayerControllerHuman controller, final Player p, final SpellAbility sa, final boolean effect, final Card source, final String orString) {
super(p, effect); super(p, effect, sa, source);
this.controller = controller; this.controller = controller;
ability = sa;
mandatory = sa.getPayCosts().isMandatory(); mandatory = sa.getPayCosts().isMandatory();
this.source = source;
this.orString = orString; this.orString = orString;
} }

View File

@@ -165,7 +165,7 @@ public class HumanPlaySpellAbility {
&& ability.canCastTiming(human) && ability.canCastTiming(human)
&& ability.checkRestrictions(human) && ability.checkRestrictions(human)
&& ability.isLegalAfterStack() && ability.isLegalAfterStack()
&& (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, false, ability.getHostCard()))); && (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, false)));
game.clearTopLibsCast(ability); game.clearTopLibsCast(ability);