Fix full replacement not reaching caller if chain contains update result (#3281)

This commit is contained in:
tool4ever
2023-06-18 10:06:00 +02:00
committed by GitHub
parent 9ace1978f9
commit eae566a83c
8 changed files with 16 additions and 14 deletions

View File

@@ -1309,7 +1309,14 @@ public class CardProperty {
} }
} }
} else if (property.startsWith("leastPower")) { } else if (property.startsWith("leastPower")) {
final CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES); CardCollectionView cards = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
if (property.contains("ControlledBy")) {
FCollectionView<Player> p = AbilityUtils.getDefinedPlayers(source, property.split("ControlledBy")[1], spellAbility);
cards = CardLists.filterControlledBy(cards, p);
if (!cards.contains(card)) {
return false;
}
}
for (final Card crd : cards) { for (final Card crd : cards) {
if (crd.getNetPower() < card.getNetPower()) { if (crd.getNetPower() < card.getNetPower()) {
return false; return false;

View File

@@ -29,7 +29,6 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import forge.game.CardTraitBase; import forge.game.CardTraitBase;
@@ -251,7 +250,7 @@ public class ReplacementHandler {
// if its updated, try to call event again // if its updated, try to call event again
if (res == ReplacementResult.Updated) { if (res == ReplacementResult.Updated) {
Map<AbilityKey, Object> params = Maps.newHashMap(runParams); Map<AbilityKey, Object> params = AbilityKey.newMap(runParams);
if (params.containsKey(AbilityKey.EffectOnly)) { if (params.containsKey(AbilityKey.EffectOnly)) {
params.put(AbilityKey.EffectOnly, true); params.put(AbilityKey.EffectOnly, true);
@@ -260,15 +259,14 @@ public class ReplacementHandler {
switch (result) { switch (result) {
case NotReplaced: case NotReplaced:
case Updated: { case Updated: {
for (Map.Entry<AbilityKey, Object> e : params.entrySet()) { runParams.putAll(params);
runParams.put(e.getKey(), e.getValue());
}
// effect was updated // effect was updated
runParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated); runParams.put(AbilityKey.ReplacementResult, ReplacementResult.Updated);
break; break;
} }
default: default:
// effect was replaced with something else // effect was replaced with something else
res = result;
runParams.put(AbilityKey.ReplacementResult, result); runParams.put(AbilityKey.ReplacementResult, result);
break; break;
} }

View File

@@ -418,8 +418,6 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
continue; continue;
} }
// System.out.println(c.getName());
// Skip glacial chasm, it's really weird. // Skip glacial chasm, it's really weird.
if (c.getName().equals("Glacial Chasm")) { if (c.getName().equals("Glacial Chasm")) {
System.out.println("Skipping " + c.getName()); System.out.println("Skipping " + c.getName());
@@ -478,7 +476,6 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
AssertJUnit.assertEquals(0, funky.size()); AssertJUnit.assertEquals(0, funky.size());
} }
@Test @Test
public void testPlayRememberedCardsLand() { public void testPlayRememberedCardsLand() {
Game game = initAndCreateGame(); Game game = initAndCreateGame();

View File

@@ -5,7 +5,7 @@ PT:5/5
K:Flying K:Flying
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChoose | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChoose | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or dies, ABILITY
SVar:TrigChoose:DB$ Charm | MinCharmNum$ 1 | CharmNum$ MaxUniqueOpponents | Choices$ TrigDrawDiscard,TrigSacrifice,TrigDmg | AdditionalDescription$ choose one or more. Each mode must target a different player. SVar:TrigChoose:DB$ Charm | MinCharmNum$ 1 | CharmNum$ MaxUniqueOpponents | Choices$ TrigDrawDiscard,TrigSacrifice,TrigDmg | AdditionalDescription$ or more. Each mode must target a different player.
SVar:TrigDrawDiscard:DB$ Draw | ValidTgts$ Opponent | TargetUnique$ True | NumCards$ 3 | SubAbility$ Discard3 | SpellDescription$ Target opponent draws three cards, then discards three cards at random. SVar:TrigDrawDiscard:DB$ Draw | ValidTgts$ Opponent | TargetUnique$ True | NumCards$ 3 | SubAbility$ Discard3 | SpellDescription$ Target opponent draws three cards, then discards three cards at random.
SVar:Discard3:DB$ Discard | Defined$ ParentTarget | Mode$ Random | NumCards$ 3 SVar:Discard3:DB$ Discard | Defined$ ParentTarget | Mode$ Random | NumCards$ 3
SVar:TrigSacrifice:DB$ Sacrifice | ValidTgts$ Opponent | TargetUnique$ True | SacValid$ Artifact.nonToken | SpellDescription$ Target opponent sacrifices a nontoken artifact. | SacMessage$ nontoken artifact SVar:TrigSacrifice:DB$ Sacrifice | ValidTgts$ Opponent | TargetUnique$ True | SacValid$ Artifact.nonToken | SpellDescription$ Target opponent sacrifices a nontoken artifact. | SacMessage$ nontoken artifact

View File

@@ -3,7 +3,7 @@ ManaCost:4 U R
Types:Creature Giant Wizard Types:Creature Giant Wizard
PT:4/4 PT:4/4
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Delirium — When CARDNAME enters the battlefield, ABILITY T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Delirium — When CARDNAME enters the battlefield, ABILITY
SVar:TrigCharm:DB$ Charm | CharmNum$ X | Choices$ DBDealDamage,DBDig | AdditionalDescription$ If there are four or more card types in your graveyard, choose both. SVar:TrigCharm:DB$ Charm | CharmNum$ X | Choices$ DBDealDamage,DBDig | AdditionalDescription$ . If there are four or more card types in your graveyard, choose both.
SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 4 | SpellDescription$ CARDNAME deals 4 damage to any target. SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 4 | SpellDescription$ CARDNAME deals 4 damage to any target.
SVar:DBDig:DB$ Dig | DigNum$ 4 | RestRandomOrder$ True | NoReveal$ True | SpellDescription$ Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order. SVar:DBDig:DB$ Dig | DigNum$ 4 | RestRandomOrder$ True | NoReveal$ True | SpellDescription$ Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order.
SVar:X:Count$Compare Y GE4.2.1 SVar:X:Count$Compare Y GE4.2.1

View File

@@ -1,7 +1,7 @@
Name:Sakashima's Will Name:Sakashima's Will
ManaCost:3 U ManaCost:3 U
Types:Sorcery Types:Sorcery
A:SP$ Charm | Cost$ 3 U | MinCharmNum$ 1 | CharmNum$ X | Choices$ DBControl,DBImprint | AdditionalDescription$ If you control a commander as you cast this spell, you may choose both. A:SP$ Charm | Cost$ 3 U | MinCharmNum$ 1 | CharmNum$ X | Choices$ DBControl,DBImprint | AdditionalDescription$ . If you control a commander as you cast this spell, you may choose both.
SVar:DBControl:DB$ ChooseCard | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Mandatory$ True | Choices$ Creature.TargetedPlayerCtrl | ChoiceTitle$ Choose a creature you control | SubAbility$ DBGainControl | AILogic$ WorstCard | SpellDescription$ Target opponent chooses a creature they control. You gain control of it. SVar:DBControl:DB$ ChooseCard | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Mandatory$ True | Choices$ Creature.TargetedPlayerCtrl | ChoiceTitle$ Choose a creature you control | SubAbility$ DBGainControl | AILogic$ WorstCard | SpellDescription$ Target opponent chooses a creature they control. You gain control of it.
SVar:DBGainControl:DB$ GainControl | Defined$ ChosenCard | NewController$ You | SubAbility$ DBCleanup SVar:DBGainControl:DB$ GainControl | Defined$ ChosenCard | NewController$ You | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True

View File

@@ -1,7 +1,7 @@
Name:Szat's Will Name:Szat's Will
ManaCost:4 B ManaCost:4 B
Types:Instant Types:Instant
A:SP$ Charm | Cost$ 4 B | MinCharmNum$ 1 | CharmNum$ X | Choices$ DBOppSac,DBExile | AdditionalDescription$ If you control a commander as you cast this spell, you may choose both. A:SP$ Charm | Cost$ 4 B | MinCharmNum$ 1 | CharmNum$ X | Choices$ DBOppSac,DBExile | AdditionalDescription$ . If you control a commander as you cast this spell, you may choose both.
SVar:DBOppSac:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBChooseCard | SubAbility$ DBSac | SpellDescription$ Each opponent sacrifices a creature they control with the greatest power. SVar:DBOppSac:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBChooseCard | SubAbility$ DBSac | SpellDescription$ Each opponent sacrifices a creature they control with the greatest power.
SVar:DBChooseCard:DB$ ChooseCard | Defined$ Player.IsRemembered | Choices$ Creature.greatestPowerControlledByRemembered | ChoiceTitle$ Choose a creature you control with the greatest power | Mandatory$ True | RememberChosen$ True SVar:DBChooseCard:DB$ ChooseCard | Defined$ Player.IsRemembered | Choices$ Creature.greatestPowerControlledByRemembered | ChoiceTitle$ Choose a creature you control with the greatest power | Mandatory$ True | RememberChosen$ True
SVar:DBSac:DB$ SacrificeAll | ValidCards$ Card.IsRemembered | SubAbility$ DBCleanup | StackDescription$ None SVar:DBSac:DB$ SacrificeAll | ValidCards$ Card.IsRemembered | SubAbility$ DBCleanup | StackDescription$ None

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Wraith Noble
PT:5/3 PT:5/3
K:Flying K:Flying
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ Whenever CARDNAME attacks, defending player sacrifices a creature with the least power among creatures they control. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ Whenever CARDNAME attacks, defending player sacrifices a creature with the least power among creatures they control.
SVar:TrigSac:DB$ Sacrifice | Defined$ TriggeredDefendingPlayer | SacValid$ Creature.leastPowerControlledBy TriggeredDefendingPlayer SVar:TrigSac:DB$ Sacrifice | Defined$ TriggeredDefendingPlayer | SacValid$ Creature.leastPowerControlledByTriggeredDefendingPlayer
SVar:HasAttackEffect:True SVar:HasAttackEffect:True
DeckHas:Ability$Sacrifice DeckHas:Ability$Sacrifice
Oracle:Flying\nWhenever Witch-king, Bringer of Ruin attacks, defending player sacrifices a creature with the least power among creatures they control. Oracle:Flying\nWhenever Witch-king, Bringer of Ruin attacks, defending player sacrifices a creature with the least power among creatures they control.