From 27b5c920f7d773e9ff278f59bdf8a8c9435792e4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 14 Aug 2020 10:25:47 +0200 Subject: [PATCH] * Offering - Fixed handling of hybrid mana in casting costs of offered creatures (fixes #6961). --- .../abilities/keywords/OfferingTest.java | 64 +++++++++++++++++++ .../abilities/keyword/OfferingAbility.java | 30 +++++++-- .../java/mage/abilities/mana/ManaOptions.java | 5 ++ 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java index ec9d083bb6a..3d4259f2431 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java @@ -75,4 +75,68 @@ public class OfferingTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Akki Drillmaster", 1); } + + + @Test + public void testCastWithBorosRecruit() { + setStrictChooseMode(true); + + // Goblin offering (You may cast this card any time you could cast an instant by sacrificing a Goblin and paying the difference in mana costs between this and the sacrificed Goblin. Mana cost includes color.) + // Whenever Patron of the Akki attacks, creatures you control get +2/+0 until end of turn. + String patron = "Patron of the Akki"; // Creature {4}{R}{R} (5/5) + + addCard(Zone.HAND, playerA, patron, 1); + + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + + // First strike + addCard(Zone.BATTLEFIELD, playerA, "Boros Recruit"); // Creature Goblin {R/W} (1/1) + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, patron); + setChoice(playerA, "Yes"); + addTarget(playerA, "Boros Recruit"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, patron, 1); + + assertGraveyardCount(playerA, "Boros Recruit", 1); + + } + + @Test + public void testCastWithMultipleOptions() { + setStrictChooseMode(true); + + // Goblin offering (You may cast this card any time you could cast an instant by sacrificing a Goblin and paying the difference in mana costs between this and the sacrificed Goblin. Mana cost includes color.) + // Whenever Patron of the Akki attacks, creatures you control get +2/+0 until end of turn. + String patron = "Patron of the Akki"; // Creature {4}{R}{R} (5/5) + + addCard(Zone.HAND, playerA, patron, 1); + + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + // First strike + addCard(Zone.BATTLEFIELD, playerA, "Boros Recruit"); // Creature Goblin {R/W} (1/1) + addCard(Zone.BATTLEFIELD, playerA, "Akki Drillmaster"); // Creature Goblin {2}{R} (2/2) + addCard(Zone.BATTLEFIELD, playerA, "Boggart Ram-Gang"); // Creature Goblin Warrior {R/G}{R/G}{R/G} (3/3) + + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, patron); + setChoice(playerA, "Yes"); + addTarget(playerA, "Boggart Ram-Gang"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertAllCommandsUsed(); + assertPermanentCount(playerA, patron, 1); + + assertGraveyardCount(playerA, "Boggart Ram-Gang", 1); + + } + } diff --git a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java index a13f0671dbf..e03331ac811 100644 --- a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java @@ -3,6 +3,7 @@ package mage.abilities.keyword; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import mage.Mana; import mage.ObjectColor; import mage.abilities.Ability; @@ -11,6 +12,7 @@ import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.costs.mana.ActivationManaAbilityStep; import mage.abilities.costs.mana.AlternateManaPaymentAbility; +import mage.abilities.costs.mana.HybridManaCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl; @@ -96,18 +98,34 @@ public class OfferingAbility extends StaticAbility implements AlternateManaPayme } @Override - public ManaOptions getManaOptions(Ability source, Game game, ManaCost unpaid) { - ManaOptions options = new ManaOptions(); + public ManaOptions getManaOptions(Ability source, Game game, ManaCost unpaid) { + ManaOptions additionalManaOptionsForThisAbility = new ManaOptions(); // Creatures from the offerd type game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game) .stream() .forEach(permanent -> { - options.addMana(permanent.getSpellAbility().getManaCosts().getMana()); - }); + ManaOptions manaOptionsForThisPermanent = new ManaOptions(); + for (ManaCost manaCost : permanent.getSpellAbility().getManaCosts()) { + if (manaCost instanceof HybridManaCost) { + ManaOptions manaOptionsForHybrid = new ManaOptions(); + for (Mana mana : manaCost.getManaOptions()) { + manaOptionsForHybrid.add(mana); + } + manaOptionsForThisPermanent.addMana(manaOptionsForHybrid); + } else { + manaOptionsForThisPermanent.addMana(manaCost.getMana()); + } + } + for(Mana mana : manaOptionsForThisPermanent) { + additionalManaOptionsForThisAbility.add(mana); + } + + } + ); - options.removeDuplicated(); - return options; + additionalManaOptionsForThisAbility.removeDuplicated(); + return additionalManaOptionsForThisAbility; } } diff --git a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java index fc8a7152cf9..360f8a13c0f 100644 --- a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java +++ b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java @@ -310,6 +310,11 @@ public class ManaOptions extends ArrayList { forceManaDeduplication(); } + /** + * Adds the given mana value to all existing options + * + * @param addMana Mana to add to the existing options + */ public void addMana(Mana addMana) { if (isEmpty()) { this.add(new Mana());