Fix AnimateAll / AI check creating unwanted ending commands (#3296)

* Fix AnimateAll / AI check creating unwanted ending commands

* Fix crash with PW

* Clean up

---------

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
This commit is contained in:
tool4ever
2023-06-19 12:39:18 +02:00
committed by GitHub
parent aa4c5e7cde
commit c9425270d3
10 changed files with 18 additions and 31 deletions

View File

@@ -378,7 +378,6 @@ public class AnimateAi extends SpellAbilityAi {
becomeAnimated(copy, card.hasSickness(), sa); becomeAnimated(copy, card.hasSickness(), sa);
return copy; return copy;
} }
private static void becomeAnimated(final Card card, final boolean hasOriginalCardSickness, final SpellAbility sa) { private static void becomeAnimated(final Card card, final boolean hasOriginalCardSickness, final SpellAbility sa) {
// duplicating AnimateEffect.resolve // duplicating AnimateEffect.resolve
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
@@ -485,7 +484,7 @@ public class AnimateAi extends SpellAbilityAi {
AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalColors, AnimateEffectBase.doAnimate(card, sa, power, toughness, types, removeTypes, finalColors,
keywords, removeKeywords, hiddenKeywords, keywords, removeKeywords, hiddenKeywords,
abilities, triggers, replacements, stAbs, abilities, triggers, replacements, stAbs,
timestamp); timestamp, "Permanent");
// check if animate added static Abilities // check if animate added static Abilities
CardTraitChanges traits = card.getChangedCardTraits().get(timestamp, 0); CardTraitChanges traits = card.getChangedCardTraits().get(timestamp, 0);

View File

@@ -7,7 +7,6 @@ import java.util.Map;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import forge.GameCommand;
import forge.card.CardType; import forge.card.CardType;
import forge.card.ColorSet; import forge.card.ColorSet;
import forge.game.Game; import forge.game.Game;
@@ -44,8 +43,6 @@ public class AnimateAllEffect extends AnimateEffectBase {
// Every Animate event needs a unique time stamp // Every Animate event needs a unique time stamp
final long timestamp = game.getNextTimestamp(); final long timestamp = game.getNextTimestamp();
final boolean permanent = "Permanent".equals(sa.getParam("Duration"));
final CardType types = new CardType(true); final CardType types = new CardType(true);
if (sa.hasParam("Types")) { if (sa.hasParam("Types")) {
types.addAll(Arrays.asList(sa.getParam("Types").split(","))); types.addAll(Arrays.asList(sa.getParam("Types").split(",")));
@@ -146,7 +143,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
for (final Card c : list) { for (final Card c : list) {
doAnimate(c, sa, power, toughness, types, removeTypes, finalColors, keywords, removeKeywords, doAnimate(c, sa, power, toughness, types, removeTypes, finalColors, keywords, removeKeywords,
hiddenKeywords, abilities, triggers, replacements, stAbs, timestamp); hiddenKeywords, abilities, triggers, replacements, stAbs, timestamp, sa.getParam("Duration"));
// give sVars // give sVars
if (!sVarsMap.isEmpty() ) { if (!sVarsMap.isEmpty() ) {
@@ -154,21 +151,6 @@ public class AnimateAllEffect extends AnimateEffectBase {
} }
game.fireEvent(new GameEventCardStatsChanged(c)); game.fireEvent(new GameEventCardStatsChanged(c));
if (!permanent) {
final GameCommand unanimate = new GameCommand() {
private static final long serialVersionUID = -5861759814760561373L;
@Override
public void run() {
doUnanimate(c, timestamp);
game.fireEvent(new GameEventCardStatsChanged(c));
}
};
addUntilCommand(sa, unanimate);
}
} }
} }

View File

@@ -26,16 +26,17 @@ public class AnimateEffect extends AnimateEffectBase {
@Override @Override
public void resolve(final SpellAbility sa) { public void resolve(final SpellAbility sa) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
String duration = sa.getParam("Duration");
String animateRemembered = null; String animateRemembered = null;
String animateImprinted = null; String animateImprinted = null;
//if host is not on the battlefield don't apply //if host is not on the battlefield don't apply
if (("UntilHostLeavesPlay".equals(sa.getParam("Duration")) || "UntilLoseControlOfHost".equals(sa.getParam("Duration"))) if (("UntilHostLeavesPlay".equals(duration) || "UntilLoseControlOfHost".equals(duration))
&& !source.isInPlay()) { && !source.isInPlay()) {
return; return;
} }
if ("UntilLoseControlOfHost".equals(sa.getParam("Duration")) && source.getController() != sa.getActivatingPlayer()) { if ("UntilLoseControlOfHost".equals(duration) && source.getController() != sa.getActivatingPlayer()) {
return; return;
} }
@@ -175,7 +176,7 @@ public class AnimateEffect extends AnimateEffectBase {
doAnimate(c, sa, power, toughness, types, removeTypes, finalColors, doAnimate(c, sa, power, toughness, types, removeTypes, finalColors,
keywords, removeKeywords, hiddenKeywords, keywords, removeKeywords, hiddenKeywords,
abilities, triggers, replacements, stAbs, timestamp); abilities, triggers, replacements, stAbs, timestamp, duration);
if (sa.hasParam("Name")) { if (sa.hasParam("Name")) {
c.addChangedName(sa.getParam("Name"), false, timestamp, 0); c.addChangedName(sa.getParam("Name"), false, timestamp, 0);

View File

@@ -49,7 +49,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
final CardType addType, final CardType removeType, final ColorSet colors, final CardType addType, final CardType removeType, final ColorSet colors,
final List<String> keywords, final List<String> removeKeywords, final List<String> hiddenKeywords, final List<String> keywords, final List<String> removeKeywords, final List<String> hiddenKeywords,
List<String> abilities, final List<String> triggers, final List<String> replacements, final List<String> stAbs, List<String> abilities, final List<String> triggers, final List<String> replacements, final List<String> stAbs,
final long timestamp) { final long timestamp, final String duration) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final Game game = source.getGame(); final Game game = source.getGame();
@@ -185,8 +185,8 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect {
addedStaticAbilities, removeAll, removeNonManaAbilities, timestamp, 0); addedStaticAbilities, removeAll, removeNonManaAbilities, timestamp, 0);
} }
if (!"Permanent".equals(sa.getParam("Duration"))) { if (!"Permanent".equals(duration)) {
if ("UntilControllerNextUntap".equals(sa.getParam("Duration"))) { if ("UntilControllerNextUntap".equals(duration)) {
game.getUntap().addUntil(c.getController(), unanimate); game.getUntap().addUntil(c.getController(), unanimate);
} else { } else {
addUntilCommand(sa, unanimate); addUntilCommand(sa, unanimate);

View File

@@ -247,6 +247,9 @@ public class CardDamageHistory {
* @param player * @param player
*/ */
public void registerDamage(int damage, boolean isCombat, Card sourceLKI, GameEntity target, Map<Integer, Card> lkiCache) { public void registerDamage(int damage, boolean isCombat, Card sourceLKI, GameEntity target, Map<Integer, Card> lkiCache) {
if (damage <= 0) {
return;
}
damagedThisGame.add(target); damagedThisGame.add(target);
hasdealtDamagetoAny = true; hasdealtDamagetoAny = true;
if (isCombat && target instanceof Player) { if (isCombat && target instanceof Player) {

View File

@@ -113,6 +113,9 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
for (Integer i : this.column(damaged.getKey()).values()) { for (Integer i : this.column(damaged.getKey()).values()) {
sum += i; sum += i;
} }
if (sum == 0) {
continue;
}
int excess = sum - (damaged.getKey().hasBeenDealtDeathtouchDamage() ? 1 : damaged.getValue()); int excess = sum - (damaged.getKey().hasBeenDealtDeathtouchDamage() ? 1 : damaged.getValue());

View File

@@ -2,6 +2,6 @@ Name:Grow from the Ashes
ManaCost:2 G ManaCost:2 G
Types:Sorcery Types:Sorcery
K:Kicker:2 K:Kicker:2
A:SP$ ChangeZone | Cost$ 2 G | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | Mandatory$ True | SpellDescription$ Search your library for a basic land card, put it onto the battlefield, then shuffle. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle. A:SP$ ChangeZone | Cost$ 2 G | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | SpellDescription$ Search your library for a basic land card, put it onto the battlefield, then shuffle. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle.
SVar:X:Count$Kicked.2.1 SVar:X:Count$Kicked.2.1
Oracle:Kicker {2} (You may pay an additional {2} as you cast this spell.)\nSearch your library for a basic land card, put it onto the battlefield, then shuffle. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle. Oracle:Kicker {2} (You may pay an additional {2} as you cast this spell.)\nSearch your library for a basic land card, put it onto the battlefield, then shuffle. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle.

View File

@@ -3,5 +3,4 @@ ManaCost:2 G
Types:Sorcery Types:Sorcery
A:SP$ ChangeZone | Cost$ 2 G | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | Tapped$ True | SpellDescription$ Search your library for up to X basic land cards, where X is the number of tapped creatures you control, put those cards onto the battlefield tapped, then shuffle. A:SP$ ChangeZone | Cost$ 2 G | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | Tapped$ True | SpellDescription$ Search your library for up to X basic land cards, where X is the number of tapped creatures you control, put those cards onto the battlefield tapped, then shuffle.
SVar:X:Count$Valid Creature.tapped+YouCtrl SVar:X:Count$Valid Creature.tapped+YouCtrl
SVar:NeedsToPlay:Creature.tapped+YouCtrl
Oracle:Search your library for up to X basic land cards, where X is the number of tapped creatures you control, put those cards onto the battlefield tapped, then shuffle. Oracle:Search your library for up to X basic land cards, where X is the number of tapped creatures you control, put those cards onto the battlefield tapped, then shuffle.

View File

@@ -1,7 +1,7 @@
Name:Insidious Dreams Name:Insidious Dreams
ManaCost:3 B ManaCost:3 B
Types:Instant Types:Instant
A:SP$ ChangeZone | Cost$ 3 B Discard<X/Card> | Origin$ Library | Destination$ Library | ChangeType$ Card | ChangeNum$ X | LibraryPosition$ 0 | SpellDescription$ Search your library for X cards, then shuffle and put those cards on top in any order. A:SP$ ChangeZone | Cost$ 3 B Discard<X/Card> | Origin$ Library | Destination$ Library | ChangeType$ Card | ChangeNum$ X | LibraryPosition$ 0 | Mandatory$ True | SpellDescription$ Search your library for X cards, then shuffle and put those cards on top in any order.
SVar:X:Count$xPaid SVar:X:Count$xPaid
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:As an additional cost to cast this spell, discard X cards.\nSearch your library for X cards, then shuffle and put those cards on top in any order. Oracle:As an additional cost to cast this spell, discard X cards.\nSearch your library for X cards, then shuffle and put those cards on top in any order.

View File

@@ -1,7 +1,7 @@
Name:Jaheira's Respite Name:Jaheira's Respite
ManaCost:4 G ManaCost:4 G
Types:Instant Types:Instant
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | AILogic$ Fog | Tapped$ True | SubAbility$ DBFog | SpellDescription$ Search your library for up to X basic land cards, where X is the number of creatures attacking you, put those cards onto the battlefield tapped, then shuffle. Prevent all combat damage that would be dealt this turn. A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ X | Tapped$ True | SubAbility$ DBFog | SpellDescription$ Search your library for up to X basic land cards, where X is the number of creatures attacking you, put those cards onto the battlefield tapped, then shuffle. Prevent all combat damage that would be dealt this turn.
SVar:X:Count$Valid Creature.attackingYou SVar:X:Count$Valid Creature.attackingYou
SVar:DBFog:DB$ Fog SVar:DBFog:DB$ Fog
Oracle:Search your library for up to X basic land cards, where X is the number of creatures attacking you, put those cards onto the battlefield tapped, then shuffle.\nPrevent all combat damage that would be dealt this turn. Oracle:Search your library for up to X basic land cards, where X is the number of creatures attacking you, put those cards onto the battlefield tapped, then shuffle.\nPrevent all combat damage that would be dealt this turn.