diff --git a/Mage.Sets/src/mage/cards/p/PatronOfTheOrochi.java b/Mage.Sets/src/mage/cards/p/PatronOfTheOrochi.java index d874b55b6ce..96af53188b9 100644 --- a/Mage.Sets/src/mage/cards/p/PatronOfTheOrochi.java +++ b/Mage.Sets/src/mage/cards/p/PatronOfTheOrochi.java @@ -33,7 +33,9 @@ public final class PatronOfTheOrochi extends CardImpl { this.power = new MageInt(7); this.toughness = new MageInt(7); - // Snake offering (You may cast this card any time you could cast an instant by sacrificing a Snake and paying the difference in mana costs between this and the sacrificed Snake. Mana cost includes color.) + // Snake offering (You may cast this card any time you could cast an instant + // by sacrificing a Snake and paying the difference in mana costs between this + // and the sacrificed Snake. Mana cost includes color.) this.addAbility(new OfferingAbility(SubType.SNAKE)); // {T}: Untap all Forests and all green creatures. Activate this ability only once each turn. diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java index e61a86eaa6a..d62c453d18a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java @@ -63,4 +63,34 @@ public class CastCommanderTest extends CardTestCommanderDuelBase { assertPowerToughness(playerA, "Silvercoat Lion", 6, 6); } + + @Test + public void testCastPatronOfTheOrochiCommander() { + // Snake offering (You may cast this card any time you could cast an instant + // by sacrificing a Snake and paying the difference in mana costs between this + // and the sacrificed Snake. Mana cost includes color.) + // {T}: Untap all Forests and all green creatures. Activate this ability only once each turn. + addCard(Zone.COMMAND, playerA, "Patron of the Orochi", 1); // Creature {6}{G}{G} 7/7 + + // First strike + addCard(Zone.BATTLEFIELD, playerA, "Coiled Tinviper", 1); // Creature Snake {3} 2/1 + addCard(Zone.BATTLEFIELD, playerA, "Forest", 8); // Cost reduction does not work for getPlayable so you need to have 8 mana available + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Patron of the Orochi"); + setChoice(playerA, "Yes"); + addTarget(playerA, "Coiled Tinviper"); + + setStrictChooseMode(true); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertAllCommandsUsed(); + assertLife(playerA, 40); + assertLife(playerB, 40); + + assertPermanentCount(playerA, "Patron of the Orochi", 1); + assertGraveyardCount(playerA, "Coiled Tinviper", 1); + assertTappedCount("Forest", false, 3); + } } diff --git a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java index 9dbbdb3c030..da1c503eb66 100644 --- a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java @@ -1,7 +1,6 @@ package mage.abilities.keyword; import java.util.UUID; -import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -15,7 +14,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import mage.util.GameLog; /** * 702.46. Offering # 702.46a Offering is a static ability of a card that @@ -128,7 +129,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { return false; } Player player = game.getPlayer(source.getControllerId()); - if (player != null && !game.inCheckPlayableState() + if (player != null && player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) { Target target = new TargetControlledCreaturePermanent(1, 1, filter, true); player.chooseTarget(Outcome.Sacrifice, target, source, game); @@ -139,10 +140,14 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { Permanent offer = game.getPermanent(target.getFirstTarget()); if (offer != null) { UUID activationId = UUID.randomUUID(); - OfferingCostReductionEffect effect = new OfferingCostReductionEffect(spellToCast.getSpellAbility().getId(), new MageObjectReference(offer, game), activationId); + OfferingCostReductionEffect effect = new OfferingCostReductionEffect(activationId); + effect.setTargetPointer(new FixedTarget(offer, game)); game.addEffect(effect, source); game.getState().setValue("offering_ok_" + card.getId(), true); game.getState().setValue("offering_Id_" + card.getId(), activationId); + game.informPlayers(player.getLogName() + " announces to offer " + + offer.getLogName() + " to cast " + + GameLog.getColoredObjectName(spellToCast));// No id name to prevent to offer hand card knowledge after cancel casting return true; } } else { @@ -156,29 +161,22 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { class OfferingCostReductionEffect extends CostModificationEffectImpl { - private final UUID spellAbilityId; private final UUID activationId; - private final MageObjectReference offeredPermanent; - // private final ManaCosts manaCostsToReduce; - OfferingCostReductionEffect(UUID spellAbilityId, MageObjectReference offeredPermanent, UUID activationId) { + OfferingCostReductionEffect(UUID activationId) { super(Duration.OneUse, Outcome.Benefit, CostModificationType.REDUCE_COST); - this.spellAbilityId = spellAbilityId; - this.offeredPermanent = offeredPermanent; this.activationId = activationId; staticText = "mana costs reduction from offering"; } OfferingCostReductionEffect(OfferingCostReductionEffect effect) { super(effect); - this.spellAbilityId = effect.spellAbilityId; - this.offeredPermanent = effect.offeredPermanent; this.activationId = effect.activationId; } @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { - Permanent toOffer = offeredPermanent.getPermanent(game); + Permanent toOffer = game.getPermanent(getTargetPointer().getFirst(game, source)); if (toOffer != null) { toOffer.sacrifice(source.getSourceId(), game); CardUtil.reduceCost((SpellAbility) abilityToModify, toOffer.getSpellAbility().getManaCosts()); @@ -194,15 +192,16 @@ class OfferingCostReductionEffect extends CostModificationEffectImpl { if (game.inCheckPlayableState()) { // Cost modifaction does not work correctly for checking available spells return false; } - if (abilityToModify.getId().equals(spellAbilityId) && abilityToModify instanceof SpellAbility) { + if (abilityToModify.getSourceId().equals(source.getSourceId()) + && abilityToModify instanceof SpellAbility) { Card card = game.getCard(source.getSourceId()); if (card != null) { Object object = game.getState().getValue("offering_Id_" + card.getId()); - if (object != null && object.equals(this.activationId) && offeredPermanent.getPermanent(game) != null) { + if (object != null && object.equals(this.activationId) && getTargetPointer().getFirst(game, source) != null) { return true; } } - // no or other id, this effect is no longer valid + // to target to offer, no correct activation ID this effect is no longer valid this.discard(); } return false;