diff --git a/Mage.Sets/src/mage/cards/a/AlchemistsVial.java b/Mage.Sets/src/mage/cards/a/AlchemistsVial.java index b991916a7b7..82ec8de7d66 100644 --- a/Mage.Sets/src/mage/cards/a/AlchemistsVial.java +++ b/Mage.Sets/src/mage/cards/a/AlchemistsVial.java @@ -29,7 +29,7 @@ public final class AlchemistsVial extends CardImpl { // When Alchemist's Vial enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); - // {1}, {T}: Sacrifice Alchemist's Vial: Target creature can't attack or block this turn. + // {1}, {T}, Sacrifice Alchemist's Vial: Target creature can't attack or block this turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantAttackBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java index 48a98416221..7be8a1fb834 100644 --- a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java +++ b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java @@ -41,7 +41,7 @@ public final class BushmeatPoacher extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(4); - // {1}, {T}: Sacrifice another creature: You gain life equal to that creature's toughness. Draw a card. + // {1}, {T}, Sacrifice another creature: You gain life equal to that creature's toughness. Draw a card. Ability ability = new SimpleActivatedAbility(new BushmeatPoacherEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); diff --git a/Mage.Sets/src/mage/cards/g/GoldenEgg.java b/Mage.Sets/src/mage/cards/g/GoldenEgg.java index 9a57f085629..0d289270398 100644 --- a/Mage.Sets/src/mage/cards/g/GoldenEgg.java +++ b/Mage.Sets/src/mage/cards/g/GoldenEgg.java @@ -19,7 +19,6 @@ import mage.constants.Zone; import java.util.UUID; /** - * * @author jmharmon */ @@ -32,7 +31,7 @@ public final class GoldenEgg extends CardImpl { // When Golden Egg enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); - // {1}, {T}: Sacrifice Golden Egg: Add one mana of any color. + // {1}, {T}, Sacrifice Golden Egg: Add one mana of any color. Ability ability = new AnyColorManaAbility(new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java index 1034ea33a38..da049ff07a3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java @@ -17,14 +17,21 @@ public class KinnanBonderProdigyTest extends CardTestPlayerBase { @Test public void testSacrificedPermanent() { - addCard(Zone.BATTLEFIELD, playerA, "Forest"); + // Whenever you tap a nonland permanent for mana, add one mana of any type that permanent produced. addCard(Zone.BATTLEFIELD, playerA, kinnan); + // + // {1}, {T}, Sacrifice Golden Egg: Add one mana of any color. addCard(Zone.BATTLEFIELD, playerA, egg); - addCard(Zone.HAND, playerA, hovermyr); + // + addCard(Zone.HAND, playerA, hovermyr); // {2} + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + // sacrifice egg and add additional mana activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},"); + setChoice(playerA, "Red"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); assertAllCommandsUsed(); @@ -36,15 +43,24 @@ public class KinnanBonderProdigyTest extends CardTestPlayerBase { @Test public void testSacrificedToken() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + // Whenever you tap a nonland permanent for mana, add one mana of any type that permanent produced. addCard(Zone.BATTLEFIELD, playerA, kinnan); - addCard(Zone.HAND, playerA, strike); - addCard(Zone.HAND, playerA, hovermyr); + // + // Create a Treasure token. + addCard(Zone.HAND, playerA, strike); // {R} + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + // + addCard(Zone.HAND, playerA, hovermyr); // {2} + // prepare treasure token castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, strike); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}"); + + // sacrifice treasure and add additional mana + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice"); + setChoice(playerA, "Red"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr); + setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); execute(); assertAllCommandsUsed(); diff --git a/Mage/src/main/java/mage/abilities/Ability.java b/Mage/src/main/java/mage/abilities/Ability.java index c4f6cda3509..1af6b5e8f81 100644 --- a/Mage/src/main/java/mage/abilities/Ability.java +++ b/Mage/src/main/java/mage/abilities/Ability.java @@ -494,9 +494,7 @@ public interface Ability extends Controllable, Serializable { boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game); /** - * Returns the object that actually existed while a ability triggered or an - * ability was activated. If not set yet, the current object will be - * retrieved from the game. + * Return source object or LKI from battlefield * * @param game * @return @@ -508,9 +506,9 @@ public interface Ability extends Controllable, Serializable { int getSourceObjectZoneChangeCounter(); /** - * Returns the object that actually existed while a ability triggerd or an - * ability was activated only if it has not changed zone meanwhile. If not - * set yet, the current object will be retrieved from the game. + * Returns exists source object: + * - for not activated ability - returns exists object + * - for activated ability - returns exists object or LKI (if it triggers from non battlefield, e.g. sacrifice cost); * * @param game * @return @@ -518,16 +516,19 @@ public interface Ability extends Controllable, Serializable { MageObject getSourceObjectIfItStillExists(Game game); /** - * Returns the permanent that actually existed while the ability triggerd or - * an ability was activated only if it has not changed zone meanwhile. If - * not set yet, the current permanent if one exists will be retrieved from - * the game and returned. + * See getSourceObjectIfItStillExists for details. Works with Permanent only. * * @param game * @return */ Permanent getSourcePermanentIfItStillExists(Game game); + /** + * Returns source permanent info (actual or from LKI) + * + * @param game + * @return + */ Permanent getSourcePermanentOrLKI(Game game); String getTargetDescription(Targets targets, Game game); diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 84840ecab5d..f5ad920bd60 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -22,7 +22,6 @@ import mage.game.command.Emblem; import mage.game.command.Plane; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentToken; import mage.game.stack.Spell; import mage.game.stack.StackAbility; import mage.players.Player; @@ -374,10 +373,7 @@ public abstract class AbilityImpl implements Ability { // fused spell contains 3 abilities (fused, left, right) // fused cost added to fused ability, so no need cost modification for other parts - boolean needCostModification = true; - if (CardUtil.isFusedPartAbility(this, game)) { - needCostModification = false; - } + boolean needCostModification = !CardUtil.isFusedPartAbility(this, game); //20101001 - 601.2e if (needCostModification && sourceObject != null) { @@ -603,7 +599,7 @@ public abstract class AbilityImpl implements Ability { manaSymbol = "W"; } if (manaSymbol == null) { - throw new UnsupportedOperationException("ManaFilter is not supported: " + this.toString()); + throw new UnsupportedOperationException("ManaFilter is not supported: " + this); } for (int i = 0; i < amountMana; i++) { manaString.append('{').append(manaSymbol).append('}'); @@ -1094,7 +1090,7 @@ public abstract class AbilityImpl implements Ability { } MageObject object = game.getObject(this.sourceId); if (object == null) { // e.g. sacrificed token - logger.warn("Could get no object: " + this.toString()); + logger.warn("Could get no object: " + this); } return new StringBuilder(" activates: ") .append(object != null ? this.formatRule(getModes().getText(), object.getLogName()) : getModes().getText()) @@ -1243,6 +1239,7 @@ public abstract class AbilityImpl implements Ability { public MageObject getSourceObjectIfItStillExists(Game game) { if (getSourceObjectZoneChangeCounter() == 0 || getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) { + // exists or lki from battlefield return game.getObject(getSourceId()); } return null; @@ -1259,15 +1256,11 @@ public abstract class AbilityImpl implements Ability { @Override public Permanent getSourcePermanentOrLKI(Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(getSourceId()); - if (permanent instanceof PermanentToken) { - return permanent; + Permanent permanent = getSourcePermanentIfItStillExists(game); + if (permanent == null) { + permanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, getSourceObjectZoneChangeCounter()); } - if (getSourceObjectZoneChangeCounter() == 0 - || getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) { - return game.getPermanent(getSourceId()); - } - return (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, getSourceObjectZoneChangeCounter()); + return permanent; } @Override diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index 1e17fcaf0cc..786f71249b6 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -71,6 +71,12 @@ public interface Game extends MageItem, Serializable { GameOptions getOptions(); + /** + * Return object or LKI from battlefield + * + * @param objectId + * @return + */ MageObject getObject(UUID objectId); MageObject getBaseObject(UUID objectId);